memlist.c
字号:
/* These routines represent handling of struct memory_list. *//* $Id: memlist.c,v 1.15 2003/11/26 13:39:40 miciah Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdarg.h>#include <stdlib.h>#include "elinks.h"#include "util/error.h"#include "util/memlist.h"#include "util/memory.h"/* * memory_list is used to track information about all allocated memory * belonging to something. Then we can free it when we won't need it * anymore, but the one who allocated it won't be able to get control * back in order to free it himself. */#define ML_SIZE(n) (sizeof(struct memory_list) + (n) * sizeof(void *))/* Create a memory list. If p is NULL or allocation fails, it will * returns NULL. * It always stops at first NULL element. */#ifdef DEBUG_MEMLISTstruct memory_list *debug_getml(unsigned char *file, int line, void *p, ...)#elsestruct memory_list *getml(void *p, ...)#endif{ struct memory_list *ml; va_list ap; void *q; int n = 1; /* If first element is NULL, there's no need to allocate memory, so * just return. */ if (!p) return NULL; /* How many elements ? */ va_start(ap, p); while ((q = va_arg(ap, void *))) n++; va_end(ap); /* Allocate space for memory list. */ ml = mem_alloc(ML_SIZE(n)); if (!ml) return NULL; /* First element. */ ml->n = 1; ml->p[0] = p; /* Next ones. */ va_start(ap, p); while ((q = va_arg(ap, void *))) ml->p[ml->n++] = q; va_end(ap); /* The end. */ return ml;}/* Add elements to a memory list. * If memory list exists, it enlarges it, else it creates it. * if there's no elements or first element is NULL, it does nothing. * It always stops at first NULL element. */#ifdef DEBUG_MEMLISTvoiddebug_add_to_ml(unsigned char *file, int line, struct memory_list **ml, ...)#elsevoidadd_to_ml(struct memory_list **ml, ...)#endif{ va_list ap; void *q; int n = 0; /* How many new elements ? */ va_start(ap, ml); while ((q = va_arg(ap, void *))) n++; va_end(ap); /* None, so just return. */ if (!n) {#ifdef DEBUG_MEMLIST errline = line, errfile = file; elinks_error("add_to_ml(%p, NULL, ...)", ml);#endif return; } if (!*ml) { /* If getml() wasn't called before or returned NULL, * then we create it. */ *ml = mem_alloc(ML_SIZE(n)); if (!*ml) return; (*ml)->n = 0; } else { /* Enlarge existing ml. */ struct memory_list *nml; nml = mem_realloc(*ml, ML_SIZE(n + (*ml)->n)); if (!nml) return; *ml = nml; } /* Set ml with new elements and update count. */ va_start(ap, ml); while ((q = va_arg(ap, void *))) (*ml)->p[(*ml)->n++] = q; va_end(ap);}#ifdef DEBUG_MEMLISTvoiddebug_add_one_to_ml(unsigned char *file, int line, struct memory_list **ml, void *p)#elsevoidadd_one_to_ml(struct memory_list **ml, void *p)#endif{ /* None, so just return. */ if (!p) {#ifdef DEBUG_MEMLIST errline = line, errfile = file; elinks_error("add_one_to_ml(%p, NULL)", ml);#endif return; } if (!*ml) { /* If getml() wasn't called before or returned NULL, * then we create it. */ *ml = mem_alloc(ML_SIZE(1)); if (!*ml) return; (*ml)->n = 0; } else { /* Enlarge existing ml. */ struct memory_list *nml; nml = mem_realloc(*ml, ML_SIZE(1 + (*ml)->n)); if (!nml) return; *ml = nml; } /* Set ml with new element and update count. */ (*ml)->p[(*ml)->n++] = p;}/* Free elements and memory list. * It returns safely if passed a NULL pointer. */voidfreeml(struct memory_list *ml){ int i; if (!ml) return; for (i = 0; i < ml->n; i++) mem_free(ml->p[i]); mem_free(ml);}#undef ML_SIZE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -