diff options
-rw-r--r-- | src/grecs.hin | 16 | ||||
-rw-r--r-- | src/tree.c | 11 |
2 files changed, 18 insertions, 9 deletions
diff --git a/src/grecs.hin b/src/grecs.hin index 48e2937..812834f 100644 --- a/src/grecs.hin +++ b/src/grecs.hin @@ -97,12 +97,16 @@ enum grecs_data_type { grecs_type_null }; -#define GRECS_DFLT 0x00 -#define GRECS_AGGR 0x01 -#define GRECS_MULT 0x02 -#define GRECS_INAC 0x04 -#define GRECS_LIST 0x08 -#define GRECS_HIDDEN 0x10 +#define GRECS_DFLT 0x00 /* Default keyword flags */ +#define GRECS_AGGR 0x01 /* Multiple entries aggregate */ +#define GRECS_MULT 0x02 /* Statement can appear multiple times */ +#define GRECS_INAC 0x04 /* Inactive keyword */ +#define GRECS_LIST 0x08 /* Value is a list of declared type */ +#define GRECS_HIDDEN 0x10 /* Hidden keyword: don't display in help output */ +#define GRECS_CONST 0x20 /* For string types: initial value is constant, + don't try to free it before assigning new value. + This flag is cleared after the first assignment. + */ enum grecs_callback_command { grecs_callback_section_begin, @@ -546,7 +546,7 @@ string_to_sockaddr(struct grecs_sockaddr *sp, const char *string, int grecs_string_convert(void *target, enum grecs_data_type type, - const char *string, grecs_locus_t const *locus) + const char *string, grecs_locus_t const *locus) { switch (type) { case grecs_type_void: @@ -556,7 +556,7 @@ grecs_string_convert(void *target, enum grecs_data_type type, break; case grecs_type_string: - *(const char**)target = grecs_strdup(string); + *(char**)target = grecs_strdup(string); break; case grecs_type_short: @@ -824,10 +824,15 @@ grecs_process_ident(struct grecs_keyword *kwp, grecs_value_t *value, grecs_list_append(list, ptr); } *(struct grecs_list**)target = list; - } else + } else { + if (kwp->type == grecs_type_string + && !(kwp->flags & GRECS_CONST)) + free(*(char**)target); grecs_string_convert(target, kwp->type, value->v.string, &value->locus); + } + kwp->flags &= ~GRECS_CONST; } |