cfparser: allow both abs and relative pointers
authorMarko Kreen <markokr@gmail.com>
Sun, 19 Apr 2009 08:39:35 +0000 (11:39 +0300)
committerMarko Kreen <markokr@gmail.com>
Mon, 20 Apr 2009 06:56:19 +0000 (09:56 +0300)
usual/cfparser.c
usual/cfparser.h

index 919a461fa9b3dcaae9d3649a4fd25d637afb5cc7..44317244a5d30b10b2a887be6b6d2255bd17c99a 100644 (file)
@@ -143,6 +143,18 @@ struct LoaderCtx {
        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;
@@ -150,7 +162,9 @@ static bool fill_defaults(struct LoaderCtx *ctx)
        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;
        }
@@ -170,8 +184,6 @@ static bool load_handler(void *arg, enum CfKeyType ktype, const char *key, const
                                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);
@@ -183,7 +195,9 @@ static bool load_handler(void *arg, enum CfKeyType ktype, const char *key, const
                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);
index e383aa1742458f9034be105fe15a50db464178e6..558e6bdd35504882372e632b97af3c9b667b2827 100644 (file)
@@ -44,10 +44,15 @@ typedef bool (*cf_setter_f)(void *dst_p, const char *value);
 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;
@@ -61,4 +66,18 @@ bool cf_set_int(void *dst, const char *value);
 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