Simplify item management

This commit is contained in:
Přemysl Eric Janouch 2017-05-24 19:32:18 +02:00
parent 5314815132
commit 383c9d8fd2
Signed by: p
GPG Key ID: B715679E3A361BE6
1 changed files with 8 additions and 27 deletions

29
ell.c
View File

@ -69,8 +69,7 @@ format (const char *format, ...) {
struct buffer { struct buffer {
char *s; ///< Buffer data char *s; ///< Buffer data
size_t alloc; ///< Number of bytes allocated size_t alloc, len; ///< Number of bytes allocated and used
size_t len; ///< Number of bytes used
bool memory_failure; ///< Memory allocation failed bool memory_failure; ///< Memory allocation failed
}; };
@ -101,7 +100,7 @@ buffer_append_c (struct buffer *self, char c) {
return buffer_append (self, &c, 1); return buffer_append (self, &c, 1);
} }
// --- Data types -------------------------------------------------------------- // --- Data items --------------------------------------------------------------
enum item_type { ITEM_STRING, ITEM_LIST }; enum item_type { ITEM_STRING, ITEM_LIST };
@ -110,27 +109,15 @@ struct item {
struct item *next; ///< Next item on the list/stack struct item *next; ///< Next item on the list/stack
struct item *head; ///< The head of the list struct item *head; ///< The head of the list
size_t len; ///< Length of the string (sans '\0') size_t len; ///< Length of "value" (sans '\0')
char value[]; ///< The null-terminated string value char value[]; ///< The null-terminated string value
}; };
const char *
item_type_to_str (enum item_type type) {
switch (type) {
case ITEM_STRING: return "string";
case ITEM_LIST: return "list";
}
abort ();
}
// --- Item management ---------------------------------------------------------
static void item_free_list (struct item *); static void item_free_list (struct item *);
static struct item *new_clone_list (const struct item *); static struct item *new_clone_list (const struct item *);
static void static void
item_free (struct item *item) { item_free (struct item *item) {
if (item->type == ITEM_LIST)
item_free_list (item->head); item_free_list (item->head);
free (item); free (item);
} }
@ -146,21 +133,16 @@ item_free_list (struct item *item) {
static struct item * static struct item *
new_clone (const struct item *item) { new_clone (const struct item *item) {
size_t size = sizeof *item + 1; size_t size = sizeof *item + item->len + 1;
if (item->type == ITEM_STRING)
size += item->len;
struct item *clone = malloc (size); struct item *clone = malloc (size);
if (!clone) if (!clone)
return NULL; return NULL;
memcpy (clone, item, size); memcpy (clone, item, size);
if (item->type == ITEM_LIST && clone->head) { if (clone->head && !(clone->head = new_clone_list (clone->head))) {
if (!(clone->head = new_clone_list (clone->head))) {
free (clone); free (clone);
return NULL; return NULL;
} }
}
clone->next = NULL; clone->next = NULL;
return clone; return clone;
} }
@ -187,7 +169,6 @@ new_string (const char *s, size_t len) {
item->type = ITEM_STRING; item->type = ITEM_STRING;
item->len = len; item->len = len;
memcpy (item->value, s, len); memcpy (item->value, s, len);
item->value[len] = '\0';
return item; return item;
} }