diff -urN v21/Makefile v22/Makefile --- v21/Makefile 2018-09-07 23:03:17.000000000 +0900 +++ v22/Makefile 2018-09-14 21:50:19.000000000 +0900 @@ -1,12 +1,17 @@ CC = gcc CFLAGS += -Wall -CFLAGS += -g +#CFLAGS += -g -DMEM_DBG +CFLAGS += $(DBG) -OBJS = ezyaml.o objs.o +OBJS = ezyaml.o objs.o chain.o mem.o TARG = ezyaml all: $(TARG) +mem.c: chain.h +objs.c: chain.h mem.h +ezyaml.c: objs.h mem.h + ezyaml: $(OBJS) gcc $(CFLAGS) -o $@ $(OBJS) diff -urN v21/chain.c v22/chain.c --- v21/chain.c 1970-01-01 09:00:00.000000000 +0900 +++ v22/chain.c 2018-09-14 21:50:19.000000000 +0900 @@ -0,0 +1,93 @@ +#include "chain.h" + +#define PP(pn) ( (void **)(pn) ) +#define PREV(pn) ( PP(pn)[0] ) +#define NEXT(pn) ( PP(pn)[1] ) + +static chain_pn +prev(chain_pn pn) +{ + return pn ? PREV(pn) : NULL; +} + +static chain_pn +next(chain_pn pn) +{ + return pn ? NEXT(pn) : NULL; +} + +static void +set_prev(chain_pn pn, chain_pn p) +{ + if(pn){ + PREV(pn) = p; + } +} + +static void +set_next(chain_pn pn, chain_pn n) +{ + if(pn){ + NEXT(pn) = n; + } +} + +static void +set_prev_next(chain_pn pn, chain_pn p, chain_pn n) +{ + set_prev(pn, p); + set_next(pn, n); +} + +chain_pn +chain_tail(chain_pn top) +{ + return prev(top); +} + +chain_pn +chain_add_tail(chain_pn top, chain_pn pn) +{ + set_prev_next( pn, chain_tail(top), top ); + + if( next(pn) ){ + set_prev( next(pn), pn ); + }else{ + set_next(pn, pn); + } + + if( prev(pn) ){ + set_next( prev(pn), pn ); + }else{ + set_prev(pn, pn); + } + + return top ? top : pn; /* return top */ +} + +chain_pn +chain_add_top(chain_pn top, chain_pn pn) +{ + chain_add_tail(top, pn); + return pn; /* return top */ +} + +chain_pn +chain_del(chain_pn top, chain_pn pn) +{ + if(pn){ + if( prev(pn) != pn ){ + set_next( prev(pn), next(pn) ); + } + if( next(pn) != pn ){ + set_prev( next(pn), prev(pn) ); + } + if(top == pn){ + top = ( next(pn) != pn ) ? next(pn) : NULL; + } + set_prev_next(pn, NULL, NULL); + } + return top; +} + +/* EOF */ diff -urN v21/chain.h v22/chain.h --- v21/chain.h 1970-01-01 09:00:00.000000000 +0900 +++ v22/chain.h 2018-09-14 21:50:19.000000000 +0900 @@ -0,0 +1,13 @@ +#ifndef __CHAIN_H__ +#define __CHAIN_H__ 1 + +#include + +typedef void *chain_pn; + +chain_pn chain_tail(chain_pn top); +chain_pn chain_add_tail(chain_pn top, chain_pn pn); +chain_pn chain_add_top(chain_pn top, chain_pn pn); +chain_pn chain_del(chain_pn top, chain_pn pn); + +#endif diff -urN v21/ezyaml.c v22/ezyaml.c --- v21/ezyaml.c 2018-09-14 05:09:31.000000000 +0900 +++ v22/ezyaml.c 2018-09-14 21:50:19.000000000 +0900 @@ -1,4 +1,5 @@ #include "objs.h" +#include "mem.h" void err(char *t, char *s) @@ -680,6 +681,9 @@ /* obj --> stderr ... */ obj_del(obj); + + mem_show(); + return 0; } diff -urN v21/mem.c v22/mem.c --- v21/mem.c 1970-01-01 09:00:00.000000000 +0900 +++ v22/mem.c 2018-09-14 21:50:19.000000000 +0900 @@ -0,0 +1,95 @@ +#include +#include +#include +#include "chain.h" + +struct node{ + struct node *prev, *next; + + void *p; + int sz; + char *kind; + const char *filename; + int line; + const char *func; +}; + +static struct node *top = NULL; + +void mem_show(void); + +static void * +alloc(void *p, int sz, char *kind, const char *filename, int line, const char *func) +{ + struct node *nd = malloc( sizeof(*nd) ); + + nd->p = p; + nd->sz = sz; + nd->kind = kind; + + nd->filename = filename; + nd->line = line; + nd->func = func; + + top = chain_add_top(top, nd); + + return p; +} + +void * +mem_malloc(int sz, const char *filename, int line, const char *func) +{ + return alloc( malloc(sz), sz, "malloc", filename, line, func ); +} + +char * +mem_strdup(const char *s, const char *filename, int line, const char *func) +{ + char *p = strdup(s); + return alloc( p, strlen(p)+1, "strdup", filename, line, func ); +} + +char * +mem_strndup(const char *s, int n, const char *filename, int line, const char *func) +{ + char *p = strndup(s, n); + return alloc( p, strlen(p)+1, "strndup", filename, line, func ); +} + +void +mem_free(void *p, const char *filename, int line, const char *func) +{ + struct node *nd = top; + + while(nd){ + if(nd->p == p){ + break; + } + nd = nd->next == top ? NULL : nd->next; + } + if(nd){ + top = chain_del(top, nd); + free(nd); + }else{ + fprintf(stderr, "!!! mem_free( %p, %s, %d, %s() )\n", p, filename, line, func); + mem_show(); + } + + free(p); +} + +void +mem_show(void) +{ + struct node *nd = top; + + fprintf(stderr, "--- show ---\n"); + while(nd){ + fprintf(stderr, "%p %d %s %s %d %s()\n", + nd->p, nd->sz, nd->kind, nd->filename, nd->line, nd->func); + nd = nd->next == top ? NULL : nd->next; + } + fprintf(stderr, "\n"); +} + +/* EOF */ diff -urN v21/mem.h v22/mem.h --- v21/mem.h 1970-01-01 09:00:00.000000000 +0900 +++ v22/mem.h 2018-09-14 21:50:19.000000000 +0900 @@ -0,0 +1,20 @@ +#ifndef __MEM_H__ +#define __MEM_H__ 1 + +void *mem_malloc(int sz, const char *filename, int line, const char *func); +char *mem_strdup(const char *s, const char *filename, int line, const char *func); +char *mem_strndup(const char *s, int n, const char *filename, int line, const char *func); +void mem_free(void *p, const char *filename, int line, const char *func); + +void mem_show(void); + +#ifdef MEM_DBG +#define malloc(sz) mem_malloc(sz, __FILE__, __LINE__, __func__) +#define strdup(s) mem_strdup(s, __FILE__, __LINE__, __func__) +#define strndup(s, n) mem_strndup(s, n, __FILE__, __LINE__, __func__) +#define free(p) mem_free(p, __FILE__, __LINE__, __func__) +#else +#define mem_show() +#endif + +#endif diff -urN v21/objs.c v22/objs.c --- v21/objs.c 2018-09-14 05:09:22.000000000 +0900 +++ v22/objs.c 2018-09-14 21:50:19.000000000 +0900 @@ -1,59 +1,33 @@ #include "objs.h" +#include "chain.h" +#include "mem.h" struct obj * objs_tail(struct objs *objs) { - return objs->top ? objs->top->prev : NULL; + return chain_tail(objs->top); } void objs_append(struct objs *objs, struct obj *obj) { - obj->next = objs->top; - obj->prev = objs_tail(objs); - - if(obj->next){ - obj->next->prev = obj; - }else{ - obj->next = obj; - } - - if(obj->prev){ - obj->prev->next = obj; - }else{ - obj->prev = obj; - } - - if(objs->top == NULL){ - objs->top = obj; - } - + objs->top = chain_add_tail(objs->top, obj); objs->n++; } void objs_insert(struct objs *objs, struct obj *obj) { - objs_append(objs, obj); - objs->top = obj; + objs->top = chain_add_top(objs->top, obj); + objs->n++; } void objs_del_obj(struct objs *objs, struct obj *obj) { + objs->top = chain_del(objs->top, obj); if(obj){ - if(obj->prev != obj){ - obj->prev->next = obj->next; - } - if(obj->next != obj){ - obj->next->prev = obj->prev; - } - if(objs->top == obj){ - objs->top = (obj->next != obj) ? obj->next : NULL; - } objs->n--; - obj->next = obj->prev = NULL; - /* not free obj */ } }