static cfg_opt_t *cfg_getopt_array(cfg_opt_t *rootopts, int cfg_flags, const char *name) { unsigned int i; cfg_opt_t *opts = rootopts; assert(rootopts && name); while(name && *name) { cfg_t *seccfg; char *secname; size_t len = strcspn(name, "|"); if(name[len] == 0 /*len == strlen(name)*/) /* no more subsections */ break; if(len) { cfg_opt_t *secopt; secname = strndup(name, len); secopt = cfg_getopt_array(opts, cfg_flags, secname); free(secname); if(secopt == 0) { /*fprintf(stderr, "section not found\n");*/ return 0; } if(secopt->type != CFGT_SEC) { /*fprintf(stderr, "not a section!\n");*/ return 0; } if(!is_set(CFGF_MULTI, secopt->flags) && (seccfg = cfg_opt_getnsec(secopt, 0)) != 0) opts = seccfg->opts; else opts = secopt->subopts; if(opts == 0) { /*fprintf(stderr, "section have no subopts!?\n");*/ return 0; } } name += len; name += strspn(name, "|"); } for(i = 0; opts[i].name; i++) { if(is_set(CFGF_NOCASE, cfg_flags)) { if(strcasecmp(opts[i].name, name) == 0) return &opts[i]; } else { if(strcmp(opts[i].name, name) == 0) return &opts[i]; } } return 0; }
DLLIMPORT cfg_validate_callback_t cfg_set_validate_func(cfg_t *cfg, const char *name, cfg_validate_callback_t vf) { cfg_opt_t *opt = cfg_getopt_array(cfg->opts, cfg->flags, name); cfg_validate_callback_t oldvf; assert(opt); oldvf = opt->validcb; opt->validcb = vf; return oldvf; }