static int VerifyGamepadType(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) { GamepadType type = GetGamepadTypeValue(value); if(type == 0) { cfg_error(cfg, "Gamepad type must be snes or nes"); return -1; } *(long int *)result = type; return 0; }
static int cfg_validate_port(cfg_t *cfg, cfg_opt_t *opt) { unsigned int port = cfg_opt_getnint(opt, cfg_opt_size(opt) - 1); if (port > USHRT_MAX) { cfg_error(cfg, "Invalid %s: %s", opt->name, port); return -1; } return 0; }
static int cfg_validate_hostname(cfg_t *cfg, cfg_opt_t *opt) { const char *host = cfg_opt_getnstr(opt, cfg_opt_size(opt) - 1); if (strspn(host, "qwertyuiopasdfghjklzxcvbnm.-_1234567890QWERTYUIOPASDFGHJKLZXCVBNM") != strlen(host)) { cfg_error(cfg, "Invalid %s: %s", opt->name, host); return -1; } return 0; }
/** * Check if the given opt value is non-negative */ static gint cf_validate_num(cfg_t *cfg, cfg_opt_t *opt) { gint value = cfg_opt_getnint(opt, 0); if (value < 0) { cfg_error(cfg, "'%s' in section '%s' must be a non-negative value", cfg_opt_name(opt), cfg_name(cfg)); return -1; } return 0; }
static gint cf_validate_num_zero(cfg_t *cfg, cfg_opt_t *opt) { gint value = cfg_opt_getnint(opt, 0); if (value < 0) { cfg_error(cfg, "'%s' in section '%s' cannot be a negative " "value.", cfg_opt_name(opt), cfg_name(cfg)); return -1; } return 0; }
static int grok_config(char *path) { uint i; struct cfg_comp *config; if (!path) return 0; config = cfg_parse_file(path); if (!config) return 0; for (i = 0; i < config->vars; i++) { struct cfg_var *v = config->vlist[i]; if (!v->value) cfg_error(config, v, "No value for option '%s'", v->key); if (grok_common_var(config, v)) continue; if (!strcmp(v->key, "port")) { default_port = (unsigned short)strtoul(v->value, NULL, 0); continue; } cfg_warn(config, v, "Unrecognized variable\n"); } for (i = 0; i < config->nested; i++) { struct cfg_comp *c = config->nest[i]; if (!prefixcmp(c->name, "daemon")) { grok_daemon_compound(c); continue; } } /* * if we're supposed to kill a running daemon, ignore * parsing and post-processing nodes. We avoid memory * fragmentation by releasing the config memory before * allocating memory for the nodes. */ if (!killing) { node_grok_config(config); } cfg_destroy_compound(config); if (!killing) { post_process_nodes(); } return 1; }
DLLIMPORT int cfg_include(cfg_t *cfg, cfg_opt_t *opt, int argc, const char **argv) { opt = NULL; if(argc != 1) { cfg_error(cfg, _("wrong number of arguments to cfg_include()")); return 1; } return cfg_lexer_include(cfg, argv[0]); }
int cfg_validate_path(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) { LOG_TRACEME struct stat sb; if (!str_path_isabs(value)) { cfg_error(cfg, "Invalid absolute path for %s = '%s'", opt->name, value); return -1; } if (lstat(value, &sb) == -1) { cfg_error(cfg, "File does not exist for %s = '%s'", opt->name, value); return -1; } *(const char **) result = (const char *) value; return 0; }
// // E_SetDialect // // Changes the parser dialect. This setting applies upward on the include // stack, so including a file that does not explicitly set its own dialect will // cause it to be treated as the same dialect as the including file. // int E_SetDialect(cfg_t *cfg, cfg_opt_t *opt, int argc, const char **argv) { int dialect; if(argc != 1) { cfg_error(cfg, "wrong number of args to setdialect()\n"); return 1; } dialect = E_StrToNumLinear(dialectNames, CFG_NUMDIALECTS, argv[0]); if(dialect == CFG_NUMDIALECTS) { cfg_error(cfg, "invalid libConfuse dialect %s\n", argv[0]); return 1; } cfg_lexer_set_dialect((cfg_dialect_t)dialect); return 0; }
// // edf_enable // // Enables a builtin option from within EDF. // static int edf_enable(cfg_t *cfg, cfg_opt_t *opt, int argc, const char **argv) { int idx; if(argc != 1) { cfg_error(cfg, "wrong number of args to enable()\n"); return 1; } if((idx = E_EnableNumForName(argv[0], edf_enables)) == -1) { cfg_error(cfg, "unknown enable value '%s'\n", argv[0]); return 1; } edf_enables[idx].enabled = 1; return 0; }
int validate_unsigned_int(cfg_t *cfg, cfg_opt_t *opt) { int value = cfg_opt_getnint(opt, cfg_opt_size(opt) - 1); if(value < 0) { cfg_error(cfg, "integer option '%s' must be positive in section '%s'", opt->name, cfg->name); return -1; } return 0; }
config_setting_t *_cfg_lookup(cfg_t *cfg, const char *path, u4_t flags) { config_setting_t *setting; if ((setting = config_lookup(&cfg->config, path)) == NULL) { if (config_error_line(&cfg->config)) cfg_error(&cfg->config, "cfg_string"); if (!(flags & CFG_REQUIRED)) return NULL; lprintf("%s: lookup parameter not found: %s\n", cfg->filename, path); panic("cfg_string"); } return setting; }
static int validate_require_nonnegative(cfg_t *cfg, cfg_opt_t *opt) { if (opt->type == CFGT_INT) { long int value = cfg_opt_getnint(opt, cfg_opt_size(opt) - 1); if (value < 0) { cfg_error(cfg, "Value for option %s can't be negative in %s section \"%s\"", opt->name, cfg->name, cfg_title(cfg)); return -1; } } else if (opt->type == CFGT_FLOAT) { double value = cfg_opt_getnfloat(opt, cfg_opt_size(opt) - 1); if (value < 0.0) { cfg_error(cfg, "Value for option %s can't be negative in %s section \"%s\"", opt->name, cfg->name, cfg_title(cfg)); return -1; } } return 0; }
static int cfg_parse_MCH(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) { if (strcasecmp(value, "VADATECH") == 0) *(long int *)result = 0; else if (strcasecmp(value, "NAT") == 0) *(long int *)result = 1; else { cfg_error(cfg, "Invalid MCH: %s", value); return -1; } return 0; }
static int cfg_next(char **item,char **value) { char *this; if (last_item) { *item = last_item; *value = last_value; last_item = NULL; return 1; } *value = NULL; if (!(*item = cfg_get_token())) return 0; if (!strcmp(*item,"=")) cfg_error("Syntax error"); if (!(this = cfg_get_token())) return 1; if (strcmp(this,"=")) { cfg_return_token(this); return 1; } if (!(*value = cfg_get_token())) cfg_error("Value expected at EOF"); if (!strcmp(*value,"=")) cfg_error("Syntax error after %s",*item); return 1; }
const char *cfg_string(const char *name, const char **val, u4_t flags) { const char *str; if (!config_lookup_string(&cfg, name, &str)) { if (config_error_line(&cfg)) cfg_error("cfg_string"); if (!(flags & CFG_REQUIRED)) return NULL; lprintf("kiwi.cfg: required parameter not found: %s\n", name); panic("cfg_string"); } if (flags & CFG_PRINT) lprintf("kiwi.cfg: %s = %s\n", name, str); if (val) *val = str; return str; }
int cfg_bool(const char *name, int *val, u4_t flags) { int num; if (!config_lookup_bool(&cfg, name, &num)) { if (config_error_line(&cfg)) cfg_error("cfg_bool"); if (!(flags & CFG_REQUIRED)) return 0; lprintf("kiwi.cfg: required parameter not found: %s\n", name); panic("cfg_bool"); } if (flags & CFG_PRINT) lprintf("kiwi.cfg: %s = %s\n", name, num? "true":"false"); if (val) *val = num; return num; }
double _cfg_float(cfg_t *cfg, const char *name, double *val, u4_t flags) { double num; if (!config_lookup_float(&cfg->config, name, &num)) { if (config_error_line(&cfg->config)) cfg_error(&cfg->config, "cfg_float"); if (!(flags & CFG_REQUIRED)) return 0; lprintf("%s: required parameter not found: %s\n", cfg->filename, name); panic("cfg_float"); } if (flags & CFG_PRINT) lprintf("%s: %s = %f\n", cfg->filename, name, num); if (val) *val = num; return num; }
// // E_IncludePrev // // Includes the next WAD lump on the lumpinfo hash chain of the same // name as the current lump being processed (to the user, this is // the "previous" lump of that name). Enables recursive inclusion // of like-named lumps to enable cascading behavior. // int E_IncludePrev(cfg_t *cfg, cfg_opt_t *opt, int argc, const char **argv) { int i; lumpinfo_t **lumpinfo = wGlobalDir.getLumpInfo(); // haleyjd 03/18/10: deprecation warning E_EDFLoggedWarning(0, "Warning: include_prev is deprecated\n"); if(argc != 0) { cfg_error(cfg, "wrong number of args to include_prev()\n"); return 1; } if(!cfg->filename) { cfg_error(cfg, "include_prev: cfg_t filename is undefined\n"); return 1; } if((i = cfg_lexer_source_type(cfg)) < 0) { cfg_error(cfg, "include_prev: cannot call from file\n"); return 1; } // Go down the hash chain and look for the next lump of the same // name within the global namespace. while((i = lumpinfo[i]->namehash.next) >= 0) { if(lumpinfo[i]->li_namespace == lumpinfo_t::ns_global && !strncasecmp(lumpinfo[i]->name, cfg->filename, 8)) { return E_OpenAndCheckInclude(cfg, cfg->filename, i); } } // it is not an error if no such lump is found return 0; }
// // E_ColorStrCB // // Accepts either a palette index or an RGB triplet, which will be // matched to the closest color in the game palette. // int E_ColorStrCB(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) { char *endptr; *(int *)result = (int)strtol(value, &endptr, 0); if(*endptr != '\0') { AutoPalette pal(wGlobalDir); int r, g, b; if(sscanf(value, "%d %d %d", &r, &g, &b) != 3) { if(cfg) { cfg_error(cfg, "invalid color triplet for option '%s'\n", opt->name); } return -1; } *(int *)result = V_FindBestColor(pal.get(), r, g, b); } else if(errno == ERANGE) { if(cfg) { cfg_error(cfg, "integer value for option '%s' is out of range\n", opt->name); } return -1; } return 0; }
// // E_UserInclude // // Like stdinclude, but checks to see if the file exists before parsing it. // If it doesn't exist, it's not an error. // haleyjd 03/14/06 // int E_UserInclude(cfg_t *cfg, cfg_opt_t *opt, int argc, const char **argv) { const char *filename; if(argc != 1) { cfg_error(cfg, "wrong number of args to userinclude()\n"); return 1; } filename = E_BuildDefaultFn(argv[0]); return !access(filename, R_OK) ? E_OpenAndCheckInclude(cfg, filename, -1) : 0; }
/* value parsing callback * * VALUE must be "yes", "no" or "maybe", and the corresponding results * are the integers 1, 2 and 3. */ int cb_verify_ask(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) { if(strcmp(value, "yes") == 0) *(long int *)result = 1; else if(strcmp(value, "no") == 0) *(long int *)result = 2; else if(strcmp(value, "maybe") == 0) *(long int *)result = 3; else { cfg_error(cfg, "Invalid value for option %s: %s", opt->name, value); return -1; } return 0; }
// // edf_ifenabledany // // haleyjd 09/06/05: Exactly as above, but uses OR logic. // static int edf_ifenabledany(cfg_t *cfg, cfg_opt_t *opt, int argc, const char **argv) { int i, idx; bool enabled = false; if(argc < 1) { cfg_error(cfg, "wrong number of args to ifenabledany()\n"); return 1; } for(i = 0; i < argc; ++i) { if((idx = E_EnableNumForName(argv[i], edf_enables)) == -1) { cfg_error(cfg, "invalid enable value '%s'\n", argv[i]); return 1; } // use OR logic: the block will be evaluated if ANY // option is enabled // use short circuit for efficiency if((enabled = enabled || edf_enables[idx].enabled)) break; } // no options were enabled: skip the block if(!enabled) { // force libConfuse to look for an endif function cfg->flags |= CFGF_LOOKFORFUNC; cfg->lookfor = "endif"; } return 0; }
/* parse values for the auto-create-bookmark option */ int conf_parse_acb(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) { if(strcmp(value, "yes") == 0) *(int *)result = ACB_YES; else if(strcmp(value, "no") == 0) *(int *)result = ACB_NO; else if(strcmp(value, "ask") == 0) *(int *)result = ACB_ASK; else { cfg_error(cfg, "invalid value for option '%s': %s", cfg_opt_name(opt), value); return -1; } return 0; }
// // bex_include // // 12/12/03: New include function that allows EDF to queue // DeHackEd/BEX files for later processing. This helps to // integrate BEX features such as string editing into the // EDF/BEX superlanguage. // // This function interprets paths relative to the current // file. // static int bex_include(cfg_t *cfg, cfg_opt_t *opt, int argc, const char **argv) { char *currentpath; char *filename = NULL; // haleyjd 03/18/10: deprecation warning E_EDFLoggedWarning(0, "Warning: bexinclude is deprecated. " "Please use a GFS or DEHACKED lump instead.\n"); if(argc != 1) { cfg_error(cfg, "wrong number of args to bexinclude()\n"); return 1; } if(!cfg->filename) { cfg_error(cfg, "bexinclude: cfg_t filename is undefined\n"); return 1; } if(cfg_lexer_source_type(cfg) >= 0) { cfg_error(cfg, "bexinclude: cannot call from a wad lump\n"); return 1; } currentpath = (char *)(Z_Alloca(strlen(cfg->filename) + 1)); M_GetFilePath(cfg->filename, currentpath, strlen(cfg->filename) + 1); filename = M_SafeFilePath(currentpath, argv[0]); // queue the file for later processing D_QueueDEH(filename, 0); return 0; }
static int cb_validate_virtual(cfg_t *cfg, cfg_opt_t *opt) { unsigned int i; for (i = 0; i < cfg_size(cfg, "virtual-package"); i++) { cfg_t *sec = cfg_opt_getnsec(opt, i); if (cfg_getstr(sec, "targets") == 0) { cfg_error(cfg, "targets must be set for " "virtual-package %s", cfg_title(sec)); return -1; } } return 0; }
void identify_image(char *label,char *options) { identify = label; opt = options; if (verbose>=2) printf("identify_image: id='%s' opt='%s'\n", label, options); idefault = !!strchr(opt,'D'); if (idefault) identify = ""; cfg_init(cf_identify); if (cfg_parse(cf_identify)) cfg_error("Syntax error"); if (idefault && first) { printf("%s\n", dflt ? dflt : first); exit(0); } die("No image found for \"%s\"",label); }
// // E_SpriteFrameCB // // libConfuse value-parsing callback function for sprite frame values. // Allows use of characters A through ], corresponding to the actual // sprite lump names (implemented by popular demand ;) // // This function is also called explicitly by E_ProcessCmpState. // When this is done, the cfg and opt parameters are set to NULL, // and will not be used. // int E_SpriteFrameCB(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) { if(strlen(value) == 1 && value[0] >= 'A' && value[0] <= ']') { *(int *)result = value[0] - 'A'; } else { char *endptr; *(int *)result = strtol(value, &endptr, 0); if(*endptr != '\0') { if(cfg) { cfg_error(cfg, "invalid integer value for option '%s'\n", opt->name); } return -1; } if(errno == ERANGE) { if(cfg) { cfg_error(cfg, "integer value for option '%s' is out of range\n", opt->name); } return -1; } } return 0; }
static int cb_syslog_facility(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) { if(strcasecmp(value, "auth") == 0) *(service_type_t *)result = LOG_AUTH; else if(strcasecmp(value, "authpriv") == 0) *(service_type_t *)result = LOG_AUTHPRIV; else if(strcasecmp(value, "cron") == 0) *(service_type_t *)result = LOG_CRON; else if(strcasecmp(value, "daemon") == 0) *(service_type_t *)result = LOG_DAEMON; else if(strcasecmp(value, "ftp") == 0) *(service_type_t *)result = LOG_FTP; else if(strcasecmp(value, "kern") == 0) *(service_type_t *)result = LOG_KERN; else if(strcasecmp(value, "local0") == 0) *(service_type_t *)result = LOG_LOCAL0; else if(strcasecmp(value, "local1") == 0) *(service_type_t *)result = LOG_LOCAL1; else if(strcasecmp(value, "local2") == 0) *(service_type_t *)result = LOG_LOCAL2; else if(strcasecmp(value, "local3") == 0) *(service_type_t *)result = LOG_LOCAL3; else if(strcasecmp(value, "local4") == 0) *(service_type_t *)result = LOG_LOCAL4; else if(strcasecmp(value, "local5") == 0) *(service_type_t *)result = LOG_LOCAL5; else if(strcasecmp(value, "local6") == 0) *(service_type_t *)result = LOG_LOCAL6; else if(strcasecmp(value, "local7") == 0) *(service_type_t *)result = LOG_LOCAL7; else if(strcasecmp(value, "lpr") == 0) *(service_type_t *)result = LOG_LPR; else if(strcasecmp(value, "mail") == 0) *(service_type_t *)result = LOG_MAIL; else if(strcasecmp(value, "news") == 0) *(service_type_t *)result = LOG_NEWS; else if(strcasecmp(value, "syslog") == 0) *(service_type_t *)result = LOG_SYSLOG; else if(strcasecmp(value, "user") == 0) *(service_type_t *)result = LOG_USER; else if(strcasecmp(value, "uucp") == 0) *(service_type_t *)result = LOG_UUCP; else { cfg_error(cfg, "Invalid value for option %s: %s", opt->name, value); return GA_BAD; } return GA_GOOD; }
static int cb_answer(cfg_t *cfg, cfg_opt_t *opt, const char *value, void *result) { if(strcasecmp(value, "no") == 0) *(answer_t *)result = NO; else if(strcasecmp(value, "yes") == 0) *(answer_t *)result = YES; else if(strcasecmp(value, "optional") == 0) *(answer_t *)result = OPTIONAL; else if(strcasecmp(value, "maybe") == 0) *(answer_t *)result = MAYBE; else { cfg_error(cfg, "Invalid value for option %s: %s", opt->name, value); return GA_BAD; } return GA_GOOD; }