void cmd_ln_print_help_r(cmd_ln_t *cmdln, FILE *fp, arg_t const* defn) { if (defn == NULL) return; fprintf(fp, "Arguments list definition:\n"); arg_dump_r(cmdln, fp, defn, 1); }
cmd_ln_t * cmd_ln_parse_r(cmd_ln_t *inout_cmdln, const arg_t * defn, int32 argc, char *argv[], int strict) { int32 i, j, n, argstart; hash_table_t *defidx = NULL; cmd_ln_t *cmdln; /* Construct command-line object */ if (inout_cmdln == NULL) { cmdln = ckd_calloc(1, sizeof(*cmdln)); cmdln->refcount = 1; } else cmdln = inout_cmdln; /* Build a hash table for argument definitions */ defidx = hash_table_new(50, 0); if (defn) { for (n = 0; defn[n].name; n++) { void *v; v = hash_table_enter(defidx, defn[n].name, (void *)&defn[n]); if (strict && (v != &defn[n])) { E_ERROR("Duplicate argument name in definition: %s\n", defn[n].name); goto error; } } } else { /* No definitions. */ n = 0; } /* Allocate memory for argument values */ if (cmdln->ht == NULL) cmdln->ht = hash_table_new(n, 0 /* argument names are case-sensitive */ ); /* skip argv[0] if it doesn't start with dash */ argstart = 0; if (argc > 0 && argv[0][0] != '-') { argstart = 1; } /* Parse command line arguments (name-value pairs) */ for (j = argstart; j < argc; j += 2) { arg_t *argdef; cmd_ln_val_t *val; void *v; if (hash_table_lookup(defidx, argv[j], &v) < 0) { if (strict) { E_ERROR("Unknown argument name '%s'\n", argv[j]); goto error; } else if (defn == NULL) v = NULL; else continue; } argdef = v; /* Enter argument value */ if (j + 1 >= argc) { cmd_ln_print_help_r(cmdln, stderr, defn); E_ERROR("Argument value for '%s' missing\n", argv[j]); goto error; } if (argdef == NULL) val = cmd_ln_val_init(ARG_STRING, argv[j + 1]); else { if ((val = cmd_ln_val_init(argdef->type, argv[j + 1])) == NULL) { cmd_ln_print_help_r(cmdln, stderr, defn); E_ERROR("Bad argument value for %s: %s\n", argv[j], argv[j + 1]); goto error; } } #import "OpenEarsStaticAnalysisToggle.h" #ifdef STATICANALYZEDEPENDENCIES #define __clang_analyzer__ 1 #endif #if !defined(__clang_analyzer__) || defined(STATICANALYZEDEPENDENCIES) #undef __clang_analyzer__ if ((v = hash_table_enter(cmdln->ht, argv[j], (void *)val)) != (void *)val) { if (strict) { cmd_ln_val_free(val); E_ERROR("Duplicate argument name in arguments: %s\n", argdef->name); goto error; } else { v = hash_table_replace(cmdln->ht, argv[j], (void *)val); cmd_ln_val_free((cmd_ln_val_t *)v); } } } #endif /* Fill in default values, if any, for unspecified arguments */ for (i = 0; i < n; i++) { cmd_ln_val_t *val; void *v; if (hash_table_lookup(cmdln->ht, defn[i].name, &v) < 0) { if ((val = cmd_ln_val_init(defn[i].type, defn[i].deflt)) == NULL) { E_ERROR ("Bad default argument value for %s: %s\n", defn[i].name, defn[i].deflt); goto error; } hash_table_enter(cmdln->ht, defn[i].name, (void *)val); } } /* Check for required arguments; exit if any missing */ j = 0; for (i = 0; i < n; i++) { if (defn[i].type & ARG_REQUIRED) { void *v; if (hash_table_lookup(cmdln->ht, defn[i].name, &v) != 0) E_ERROR("Missing required argument %s\n", defn[i].name); } } if (j > 0) { cmd_ln_print_help_r(cmdln, stderr, defn); goto error; } if (strict && argc == 1) { E_ERROR("No arguments given, available options are:\n"); cmd_ln_print_help_r(cmdln, stderr, defn); if (defidx) hash_table_free(defidx); if (inout_cmdln == NULL) cmd_ln_free_r(cmdln); return NULL; } #ifndef _WIN32_WCE if(verbose_cmuclmtk == 1 || verbose_pocketsphinx == 1) { /* Set up logging. We need to do this earlier because we want to dump * the information to the configured log, not to the stderr. */ if (cmd_ln_exists_r(cmdln, "-logfn") && cmd_ln_str_r(cmdln, "-logfn")) err_set_logfile(cmd_ln_str_r(cmdln, "-logfn")); /* Echo command line */ E_INFO("Parsing command line:\n"); for (i = 0; i < argc; i++) { if (argv[i][0] == '-') E_INFOCONT("\\\n\t"); E_INFOCONT("%s ", argv[i]); } E_INFOCONT("\n\n"); fflush(stderr); /* Print configuration */ E_INFOCONT("Current configuration:\n"); arg_dump_r(cmdln, err_get_logfp(), defn, 0); } #endif hash_table_free(defidx); return cmdln; error: if (defidx) hash_table_free(defidx); if (inout_cmdln == NULL) cmd_ln_free_r(cmdln); E_ERROR("Failed to parse arguments list\n"); return NULL; }