extern byte *cf_op_names[];
uns cf_type_size(enum cf_type type, struct cf_user_type *utype);
+byte *cf_interpret_clear(struct cf_item *item, void *ptr);
byte *cf_interpret_line(byte *name, enum cf_operation op, int number, byte **pars);
void cf_init_stack(void);
int cf_check_stack(void);
}
}
-static byte *
-interpret_clear(struct cf_item *item, void *ptr)
+byte *
+cf_interpret_clear(struct cf_item *item, void *ptr)
{
if (item->cls == CC_LIST) {
cf_journal_block(ptr, sizeof(clist));
clist_init(ptr);
} else if (item->cls == CC_DYNAMIC) {
cf_journal_block(ptr, sizeof(void *));
- * (void**) ptr = NULL;
+ uns size = cf_type_size(item->type, item->u.utype);
+ static u64 zero = 0;
+ if (size <= sizeof(zero))
+ *(void**)ptr = (&zero) + 1;
+ else
+ *(void**)ptr = cf_malloc_zero(size) + size;
} else if (item->cls == CC_STATIC && item->type == CT_STRING) {
cf_journal_block(ptr, item->number * sizeof(byte*));
bzero(ptr, item->number * sizeof(byte*));
int taken; // process as many parameters as possible
if (op == OP_CLEAR)
- taken = 0, msg = interpret_clear(item, ptr);
+ taken = 0, msg = cf_interpret_clear(item, ptr);
else if (op == OP_SET)
msg = interpret_set_item(item, number, pars, &taken, ptr, 1);
else if (item->cls == CC_DYNAMIC)
break;
case OP_CLEAR:
taken = 0;
- msg = interpret_clear(item, item->ptr);
+ msg = cf_interpret_clear(item, item->ptr);
break;
case OP_APPEND:
case OP_PREPEND:
}
}
-static void
-replace_null_dary(struct cf_item *item, void **ptr)
-{
- static u64 zero = 0;
- if (*ptr)
- return;
- uns size = cf_type_size(item->type, item->u.utype);
- cf_journal_block(ptr, sizeof(void*));
- if (size <= sizeof(zero))
- *ptr = (&zero) + 1;
- else
- *ptr = cf_malloc_zero(size) + size;
-}
-
static byte *
commit_section(struct cf_section *sec, void *ptr, uns commit_all)
{
log(L_ERROR, "Cannot commit node #%d of list %s: %s", idx, ci->name, err);
return "commit of a list failed";
}
- } else if (ci->cls == CC_DYNAMIC)
- replace_null_dary(ci, ptr + (addr_int_t) ci->ptr);
+ } else if (ci->cls == CC_DYNAMIC) {
+ void **dyn = ptr + (addr_int_t) ci->ptr;
+ if (!*dyn) // replace NULL by an empty array
+ cf_interpret_clear(ci, dyn);
+ }
if (sec->commit) {
/* We have to process the whole tree of sections even if just a few changes
* have been made, because there are dependencies between commit-hooks and
#undef T
struct cf_item;
-struct fastbuf;
byte *cf_find_item(byte *name, struct cf_item *item);
byte *cf_write_item(struct cf_item *item, enum cf_operation op, int number, byte **pars);
/* Debug dumping: conf-dump.c */
+struct fastbuf;
void cf_dump_sections(struct fastbuf *fb);
/* Journaling control: conf-journal.c */