/* required for NULL */ #include #include #include #include #include "pad.h" static PAD *padlist; static int free_item(ITEM *item) { LIST *list, *next; if (item->name != NULL) G_free(item->name); for (list = item->list; list != NULL; list = next) { next = list->next; if (list->value) G_free(list->value); G_free(list); } G_free(item); return 0; } static ITEM *new_item(PAD *pad, const char *name) { ITEM *item; item = (ITEM *) G_malloc((size_t) sizeof(ITEM)); if (item == NULL) return (ITEM *) NULL; item->name = G_store(name); if (item->name == NULL) { G_free(item); return (ITEM *) NULL; } item->list = NULL; item->next = pad->items; if (item->next != NULL) item->next->prev = item; item->prev = NULL; pad->items = item; return item; } static int remove_value(ITEM *item, const char *value) { LIST **p = &item->list; LIST *l = *p; for (l = *p; l; l = *p) { if (value && l->value && !strcmp(value, l->value)) { *p = l->next; if (l->value) G_free (l->value); G_free (l); } else p = &l->next; } return 0; } int append_item(PAD *pad, const char *name, const char *value, int replace) { ITEM *item; LIST *cur, *prev; LIST *list; if (pad == NULL) return 0; /* allocate a list struct and put value into it */ list = (LIST *) G_malloc((size_t) sizeof(LIST)); if (list == NULL) return 0; list->next = NULL; list->value = G_store(value); if (list->value == NULL) { G_free(list); return 0; } /* find the named item for the current pad */ item = find_item(pad, name); if (item == NULL) item = new_item(pad, name); if (item == NULL) return 0; /* remove any existing occurences of the value */ if (replace) remove_value(item, value); /* add the LIST at the end of the item LIST */ prev = NULL; for (cur = item->list; cur != NULL; cur = cur->next) prev = cur; if (prev == NULL) item->list = list; else prev->next = list; return 1; } int delete_item(PAD *pad, const char *name) { ITEM *item; item = find_item(pad, name); if (item == NULL) return 0; if (item->prev == NULL) pad->items = item->next; else item->prev->next = item->next; if (item->next != NULL) item->next->prev = item->prev; /* free the item */ free_item(item); return 1; } ITEM *find_item(PAD *pad, const char *name) { ITEM *item; if (pad != NULL) for (item = pad->items; item != NULL; item = item->next) if (strcmp(name, item->name) == 0) return item; return (ITEM *) NULL; } PAD *pad_list(void) { return padlist; } static int delink_pad(PAD *pad) { if (pad == NULL) return 1; if (pad->prev == NULL) padlist = pad->next; else pad->prev->next = pad->next; if (pad->next != NULL) pad->next->prev = pad->prev; return 0; } int create_pad(const char *name) { PAD *pad; pad = (PAD *) G_malloc((size_t) sizeof(PAD)); if (pad == NULL) return 0; pad->name = G_store(name); if (pad->name == NULL) { G_free(pad); return 0; } pad->items = NULL; pad->next = padlist; if (pad->next != NULL) pad->next->prev = pad; pad->prev = NULL; padlist = pad; return 1; } int delete_pad(PAD *pad) { ITEM *item, *next; if (pad == NULL) return 0; delink_pad(pad); /* free the items */ for (item = pad->items; item != NULL; item = next) { next = item->next; free_item(item); } G_free(pad); return 1; } PAD *find_pad(const char *name) { PAD *pad; for (pad = padlist; pad != NULL; pad = pad->next) if (strcmp(name, pad->name) == 0) return pad; return (PAD *) NULL; } int invent_pad(char *name) { static int i = 0; do sprintf(name, "%d", ++i); while (find_pad(name) != NULL); return 0; }