Simplify item management
This commit is contained in:
parent
5314815132
commit
383c9d8fd2
29
ell.c
29
ell.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue