#ifndef OSCAM_CONF_H #define OSCAM_CONF_H #define MAXLINESIZE 16384 enum opt_types { OPT_UNKNOWN = 0, OPT_INT8, OPT_UINT8, OPT_INT32, OPT_UINT32, OPT_STRING, OPT_SSTRING, OPT_HEX_ARRAY, OPT_FUNC, OPT_FUNC_EXTRA, OPT_SAVE_FUNC, OPT_FIXUP_FUNC, }; struct config_list { enum opt_types opt_type; char *config_name; size_t var_offset; unsigned int str_size; union { int8_t d_int8; uint8_t d_uint8; int32_t d_int32; uint32_t d_uint32; char *d_char; long d_extra; uint32_t array_size; } def; union { void (*process_fn)(const char *token, char *value, void *setting, FILE *config_file); void (*process_fn_extra)(const char *token, char *value, void *setting, long extra, FILE *config_file); bool (*should_save_fn)(void *var); void (*fixup_fn)(void *var); } ops; void (*free_value)(void *setting); }; #define DEF_OPT_INT8(__name, __var_ofs, __default) \ { \ .opt_type = OPT_INT8, \ .config_name = __name, \ .var_offset = __var_ofs, \ .def.d_int8 = __default \ } #define DEF_OPT_UINT8(__name, __var_ofs, __default) \ { \ .opt_type = OPT_UINT8, \ .config_name = __name, \ .var_offset = __var_ofs, \ .def.d_uint8 = __default \ } #define DEF_OPT_INT32(__name, __var_ofs, __default) \ { \ .opt_type = OPT_INT32, \ .config_name = __name, \ .var_offset = __var_ofs, \ .def.d_int32 = __default \ } #define DEF_OPT_UINT32(__name, __var_ofs, __default) \ { \ .opt_type = OPT_UINT32, \ .config_name = __name, \ .var_offset = __var_ofs, \ .def.d_uint32 = __default \ } #define DEF_OPT_STR(__name, __var_ofs, __default) \ { \ .opt_type = OPT_STRING, \ .config_name = __name, \ .var_offset = __var_ofs, \ .def.d_char = __default \ } #define DEF_OPT_SSTR(__name, __var_ofs, __default, __str_size) \ { \ .opt_type = OPT_SSTRING, \ .config_name = __name, \ .var_offset = __var_ofs, \ .str_size = __str_size, \ .def.d_char = __default \ } #define DEF_OPT_HEX(__name, __var_ofs, __array_size) \ { \ .opt_type = OPT_HEX_ARRAY, \ .config_name = __name, \ .var_offset = __var_ofs, \ .def.array_size = __array_size \ } #define DEF_OPT_FUNC(__name, __var_ofs, __process_fn, ...) \ { \ .opt_type = OPT_FUNC, \ .config_name = __name, \ .var_offset = __var_ofs, \ .ops.process_fn = __process_fn, \ ##__VA_ARGS__ \ } #define DEF_OPT_FUNC_X(__name, __var_ofs, __process_fn_extra, __extra, ...) \ { \ .opt_type = OPT_FUNC_EXTRA, \ .config_name = __name, \ .var_offset = __var_ofs, \ .ops.process_fn_extra = __process_fn_extra, \ .def.d_extra = __extra, \ ##__VA_ARGS__ \ } #define DEF_OPT_SAVE_FUNC(__fn) \ { \ .opt_type = OPT_SAVE_FUNC, \ .ops.should_save_fn = __fn \ } #define DEF_OPT_FIXUP_FUNC(__fn) \ { \ .opt_type = OPT_FIXUP_FUNC, \ .ops.fixup_fn = __fn \ } #define DEF_LAST_OPT \ { \ .opt_type = OPT_UNKNOWN \ } struct config_sections { const char *section; const struct config_list *config; }; int32_t strToIntVal(char *value, int32_t defaultvalue); uint32_t strToUIntVal(char *value, uint32_t defaultvalue); void fprintf_conf(FILE *f, const char *varname, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))); int config_list_parse(const struct config_list *clist, const char *token, char *value, void *config_data); void config_list_save_ex(FILE *f, const struct config_list *clist, void *config_data, int save_all, bool (*check_func)(const struct config_list *clist, void *config_data, const char *setting) ); static inline void config_list_save(FILE *f, const struct config_list *clist, void *config_data, int save_all) { config_list_save_ex(f, clist, config_data, save_all, NULL); } void config_list_apply_fixups(const struct config_list *clist, void *var); bool config_list_should_be_saved(const struct config_list *clist, void *var); void config_list_set_defaults(const struct config_list *clist, void *config_data); void config_list_free_values(const struct config_list *clist, void *config_data); void config_list_gc_values(const struct config_list *clist, void *config_data); int config_section_is_active(const struct config_sections *sec); const struct config_sections *config_find_section(const struct config_sections *conf, char *section_name); void config_sections_save(const struct config_sections *conf, FILE *f, void *var); void config_sections_set_defaults(const struct config_sections *conf, void *var); void config_sections_free(const struct config_sections *conf, void *var); void config_set_value(const struct config_sections *conf, char *section, const char *token, char *value, void *var); FILE *open_config_file(const char *conf_filename); FILE *open_config_file_or_die(const char *conf_filename); FILE *create_config_file(const char *conf_filename); bool flush_config_file(FILE *f, const char *conf_filename); #endif