void *top_arg;
};
+static void *get_dest(struct LoaderCtx *ctx, const struct CfKey *k)
+{
+ char *dst;
+ if (k->flags & CF_VAL_REL) {
+ if (!ctx->target)
+ return NULL;
+ dst = (char *)ctx->target + k->key_ofs;
+ } else
+ dst = (char *)k->key_ofs;
+ return dst;
+}
+
static bool fill_defaults(struct LoaderCtx *ctx)
{
const struct CfKey *k;
for (k = ctx->cur_sect->key_list; k->key_name; k++) {
if (!k->def_value)
continue;
- dst = (char *)ctx->target + k->key_ofs;
+ dst = get_dest(ctx, k);
+ if (!dst)
+ return false;
if (!k->set_fn(dst, k->def_value))
return false;
}
continue;
ctx->cur_sect = s;
ctx->target = s->create_target_fn(ctx->top_arg);
- if (!ctx->target)
- return false;
return fill_defaults(ctx);
}
log_error("load_init_file: unknown section: %s", key);
for (k = ctx->cur_sect->key_list; k->key_name; k++) {
if (strcmp(k->key_name, key) != 0)
continue;
- dst = (char *)ctx->target + k->key_ofs;
+ dst = get_dest(ctx, k);
+ if (!dst)
+ return false;
return k->set_fn(dst, val);
}
log_error("load_init_file: unknown key: %s", key);
struct CfKey {
const char *key_name;
cf_setter_f set_fn;
- unsigned key_ofs;
+ int flags;
+ uintptr_t key_ofs;
const char *def_value;
};
+/* abs or relative pointer */
+#define CF_VAL_REL 1
+#define CF_VAL_ABS 2
+
struct CfSect {
const char *sect_name;
cf_create_target_f create_target_fn;
bool cf_set_time_usec(void *dst, const char *value);
bool cf_set_time_double(void *dst, const char *value);
+/* before using them do: #define CF_REL_BASE struct Foo */
+#define CF_REL_INT(x) cf_set_int, CF_VAL_REL, offsetof(CF_REL_BASE, x)
+#define CF_REL_STR(x) cf_set_str, CF_VAL_REL, offsetof(CF_REL_BASE, x)
+#define CF_REL_BOOL(x) cf_set_int, CF_VAL_REL, offsetof(CF_REL_BASE, x)
+#define CF_REL_TIME_USEC(x) cf_set_time_usec, CF_VAL_REL, offsetof(CF_REL_BASE, x)
+#define CF_REL_TIME_DOUBLE(x) cf_set_time_double, CF_VAL_REL, offsetof(CF_REL_BASE, x)
+/* later: #undef CF_REL_BASE */
+
+#define CF_ABS_INT(x) cf_set_int, CF_VAL_ABS, (uintptr_t)&(x)
+#define CF_ABS_STR(x) cf_set_str, CF_VAL_ABS, (uintptr_t)&(x)
+#define CF_ABS_BOOL(x) cf_set_int, CF_VAL_ABS, (uintptr_t)&(x)
+#define CF_ABS_TIME_USEC(x) cf_set_time_usec, CF_VAL_ABS, (uintptr_t)&(x)
+#define CF_ABS_TIME_DOUBLE(x) cf_set_time_double, CF_VAL_ABS, (uintptr_t)&(x)
+
#endif