double *list;
};
+static struct sub_sect_1 sec1 = { {}, "Charlie", "WBAFC", { 0, -1}, DYN_ALLOC(double, 3, 1e4, -1e-4, 8) };
+
static byte *
init_sec_1(struct sub_sect_1 *s)
{
+ if (s == &sec1) { // this is a static variable; skip clearing
+ DYN_LEN(sec1.list) = 3; // XXX: fix for the bug in DYN_ALLOC()
+ return NULL;
+ }
s->name = "unknown";
s->level = "default";
s->confidence[0] = 5;
static byte **str2 = DYN_ALLOC(byte *, 2, "Alice", "Bob");
static u64 u1 = 0xCafeBeefDeadC00ll;
static double d1 = -1.1;
-static struct sub_sect_1 sec1 = { {}, "Charlie", "WBAFC", { 0, -1} };
static struct clist secs;
static time_t t1, t2;
static u32 ip;
{
for (uns i=0; i<5; i++)
{
- struct sub_sect_1 *s = cf_malloc(sizeof(struct sub_sect_1));
- cf_init_section("slaves", &cf_sec_1, s);
+ struct sub_sect_1 *s = xmalloc(sizeof(struct sub_sect_1)); // XXX: cannot by cf_malloc(), because it's deleted when cf_reload()'ed
+ cf_init_section("slaves", &cf_sec_1, s, 1);
s->confidence[1] = i;
clist_add_tail(&secs, &s->n);
}
}
static struct cf_section cf_top = {
- CF_COMMIT(init_top),
+ CF_INIT(init_top),
CF_COMMIT(commit_top),
CF_ITEMS {
CF_UNS("nr1", &nr1),
if (optind < argc)
usage();
+ //cf_reload("non-existent file");
+
struct fastbuf *out = bfdopen(1, 1<<14);
cf_dump_sections(out);
bclose(out);
#include "lib/clists.h"
#include "lib/fastbuf.h"
#include "lib/chartype.h"
+#include "lib/lfs.h"
#include <stdlib.h>
#include <string.h>
}
void
-cf_init_section(byte *name, struct cf_section *sec, void *ptr)
+cf_init_section(byte *name, struct cf_section *sec, void *ptr, uns do_bzero)
{
- if (sec->size)
+ if (do_bzero) {
+ ASSERT(sec->size);
bzero(ptr, sec->size);
+ }
for (uns i=0; sec->cfg[i].cls; i++)
if (sec->cfg[i].cls == CC_SECTION)
- cf_init_section(sec->cfg[i].name, sec->cfg[i].u.sec, ptr + (addr_int_t) sec->cfg[i].ptr);
+ cf_init_section(sec->cfg[i].name, sec->cfg[i].u.sec, ptr + (addr_int_t) sec->cfg[i].ptr, 0);
else if (sec->cfg[i].cls == CC_LIST)
clist_init(sec->cfg[i].ptr);
if (sec->init) {
return;
sections.flags |= SEC_FLAG_UNKNOWN;
sections.size = 0; // size of allocated array used to be stored here
- cf_init_section("top-level", §ions, NULL);
+ cf_init_section("top-level", §ions, NULL, 0);
}
static int
while (number > 0)
{
void *node = cf_malloc(sec->size);
- cf_init_section(item->name, sec, node);
+ cf_init_section(item->name, sec, node, 1);
add_to_list(ptr, node, op);
int taken;
/* If the node contains any dynamic attribute at the end, we suppress
else if (item->cls == CC_LIST)
{
stack[level].base_ptr = cf_malloc(item->u.sec->size);
- cf_init_section(item->name, item->u.sec, stack[level].base_ptr);
+ cf_init_section(item->name, item->u.sec, stack[level].base_ptr, 1);
stack[level].list = ptr;
stack[level].item = item;
stack[level].op |= (op & OP_MASK) < OP_REMOVE ? OP_2ND : OP_1ST;
if (pure_op == OP_EDIT)
st->base_ptr = st->list;
else if (pure_op == OP_AFTER || pure_op == OP_BEFORE)
- cf_init_section(st->item->name, st->sec, st->base_ptr);
+ cf_init_section(st->item->name, st->sec, st->base_ptr, 1);
else
ASSERT(0);
if (op & OP_OPEN) { // stay at the same recursion level
/* Parsing multiple files */
+static struct fastbuf *
+bopen_safe(byte *name)
+{
+ int fd = sh_open(name, O_RDONLY);
+ if (fd < 0) {
+ log(L_ERROR, "Cannot open %s", name);
+ return NULL;
+ }
+ return bopen(name, O_RDONLY, 1<<14);
+}
+
static byte *
parse_fastbuf(byte *name_fb, struct fastbuf *fb, uns depth)
{
msg = "Too many nested files";
goto error;
}
- struct fastbuf *new_fb = bopen(pars[0], O_RDONLY, 1<<14);
+ struct fastbuf *new_fb = bopen_safe(pars[0]);
+ if (!new_fb) {
+ msg = "Cannot open file";
+ goto error;
+ }
uns ll = line_num;
msg = parse_fastbuf(pars[0], new_fb, depth+1);
bclose(new_fb);
load_file(byte *file)
{
init_stack();
- struct fastbuf *fb = bopen(file, O_RDONLY, 1<<14);
+ struct fastbuf *fb = bopen_safe(file);
+ if (!fb)
+ return 1;
byte *msg = parse_fastbuf(file, fb, 0);
bclose(fb);
int err = !!msg || done_stack();
/* Debug dumping */
-#include "fastbuf.h"
-
static void
spaces(struct fastbuf *fb, uns nr)
{
* dynamically allocated nodes of link lists or for filling global variables
* that are run-time dependent). The commit-hook should perform sanity
* checks and postprocess the parsed values. Commit-hooks must call
- * cf_journal_block() too. */
+ * cf_journal_block() too. Caveat! init-hooks for static sections must not
+ * use cf_malloc() but normal xmalloc(). */
struct cf_section;
struct cf_item {
// length of a dynamic array
#define DYN_ALLOC(type,len,val...) (type[]) { (type)len, ##val } + 1
// creates a static instance of a dynamic array
+ // FIXME: overcast doesn't work for the double type
/* Memory allocation */
struct mempool;
/* Declaration */
void cf_declare_section(byte *name, struct cf_section *sec, uns allow_unknown);
-void cf_init_section(byte *name, struct cf_section *sec, void *ptr);
+void cf_init_section(byte *name, struct cf_section *sec, void *ptr, uns do_bzero);
/* Safe reloading and loading of configuration files */
extern byte *cf_def_file;