67 #pragma warning (disable: 4996 4018)
105 parse_options(
cmd_ln_t *,
const arg_t *, int32,
char* [], int32);
112 arg_strlen(
const arg_t * defn, int32 * namelen, int32 * deflen)
116 *namelen = *deflen = 0;
117 for (i = 0; defn[i].name; i++) {
118 l = strlen(defn[i].name);
123 l = strlen(defn[i].deflt);
125 l = strlen(
"(null)");
136 cmp_name(
const void *a,
const void *b)
139 ((* (
arg_t**) a)->name,
140 (* (
arg_t**) b)->name));
143 static arg_t const **
144 arg_sort(
const arg_t * defn, int32 n)
150 for (i = 0; i < n; ++i)
152 qsort(pos, n,
sizeof(
arg_t *), cmp_name);
158 strnappend(
char **dest,
size_t *dest_allocation,
159 const char *source,
size_t n)
161 size_t source_len, required_allocation;
163 if (dest == NULL || dest_allocation == NULL)
165 if (*dest == NULL && *dest_allocation != 0)
168 return *dest_allocation;
170 source_len = strlen(source);
171 if (n && n < source_len)
174 required_allocation = (*dest ? strlen(*dest) : 0) + source_len + 1;
175 if (*dest_allocation < required_allocation) {
176 if (*dest_allocation == 0) {
177 *dest = (
char *)
ckd_calloc(required_allocation * 2, 1);
179 *dest = (
char *)
ckd_realloc(*dest, required_allocation * 2);
181 *dest_allocation = required_allocation * 2;
184 strncat(*dest, source, source_len);
186 return *dest_allocation;
190 strappend(
char **dest,
size_t *dest_allocation,
193 return strnappend(dest, dest_allocation, source, 0);
197 arg_resolve_env(
const char *str)
199 char *resolved_str = NULL;
203 const char *i = str, *j;
210 strnappend(&resolved_str, &alloced, i, j - i);
213 j = strchr(i + 2,
')');
215 if (j - (i + 2) < 100) {
216 strncpy(env_name, i + 2, j - (i + 2));
217 env_name[j - (i + 2)] =
'\0';
218 #if !defined(_WIN32_WCE)
219 env_val = getenv(env_name);
221 strappend(&resolved_str, &alloced, env_val);
230 strnappend(&resolved_str, &alloced, i, j - i);
234 strappend(&resolved_str, &alloced, i);
242 arg_dump_r(
cmd_ln_t *cmdln, FILE *fp,
const arg_t * defn, int32 doc)
247 int32 namelen, deflen;
252 if (defn == NULL || fp == NULL)
256 n = arg_strlen(defn, &namelen, &deflen);
258 namelen = namelen & 0xfffffff8;
259 deflen = deflen & 0xfffffff8;
261 fprintf(fp,
"[NAME]");
262 for (l = strlen(
"[NAME]"); l < namelen; l += 8)
264 fprintf(fp,
"\t[DEFLT]");
265 for (l = strlen(
"[DEFLT]"); l < deflen; l += 8)
269 fprintf(fp,
"\t[DESCR]\n");
272 fprintf(fp,
"\t[VALUE]\n");
276 pos = arg_sort(defn, n);
277 for (i = 0; i < n; i++) {
278 fprintf(fp,
"%s", pos[i]->name);
279 for (l = strlen(pos[i]->name); l < namelen; l += 8)
284 fprintf(fp,
"%s", pos[i]->deflt);
285 l = strlen(pos[i]->deflt);
289 for (; l < deflen; l += 8)
295 fprintf(fp,
"%s", pos[i]->doc);
300 switch (pos[i]->type) {
303 fprintf(fp,
"%ld", vp->i);
307 fprintf(fp,
"%e", vp->fl);
312 fprintf(fp,
"%s", (
char *)vp->ptr);
315 array = (
char const**)vp->ptr;
317 for (l = 0; array[l] != 0; l++) {
318 fprintf(fp,
"%s,", array[l]);
323 fprintf(fp,
"%s", vp->i ?
"yes" :
"no");
326 E_ERROR(
"Unknown argument type: %d\n", pos[i]->type);
339 parse_string_list(
const char *str)
353 result = (
char **)
ckd_calloc(count + 1,
sizeof(
char *));
355 for (i = 0; i < count; i++) {
356 for (j = 0; p[j] !=
',' && p[j] != 0; j++);
357 result[i] = (
char *)
ckd_calloc(j + 1,
sizeof(
char));
358 strncpy( result[i], p, j);
365 cmd_ln_val_init(
int t,
const char *name,
const char *str)
373 memset(&val, 0,
sizeof(val));
377 e_str = arg_resolve_env(str);
382 if (sscanf(e_str,
"%ld", &val.i) != 1)
387 if (e_str == NULL || e_str[0] == 0)
393 if ((e_str[0] ==
'y') || (e_str[0] ==
't') ||
394 (e_str[0] ==
'Y') || (e_str[0] ==
'T') || (e_str[0] ==
'1')) {
397 else if ((e_str[0] ==
'n') || (e_str[0] ==
'f') ||
398 (e_str[0] ==
'N') || (e_str[0] ==
'F') |
403 E_ERROR(
"Unparsed boolean value '%s'\n", str);
412 val.ptr = parse_string_list(e_str);
415 E_ERROR(
"Unknown argument type: %d\n", t);
425 memcpy(v, &val,
sizeof(val));
438 parse_options(
cmd_ln_t *cmdln,
const arg_t *defn, int32 argc,
char* argv[], int32 strict)
444 if (new_cmdln == NULL) {
446 for (i = 0; i < argc; ++i)
453 if (new_cmdln == cmdln) {
456 new_cmdln->f_argv = (
char **)
ckd_realloc(new_cmdln->f_argv,
457 (new_cmdln->f_argc + argc)
458 *
sizeof(*new_cmdln->f_argv));
459 memcpy(new_cmdln->f_argv + new_cmdln->f_argc, argv,
460 argc *
sizeof(*argv));
462 new_cmdln->f_argc += argc;
466 new_cmdln->f_argc = argc;
467 new_cmdln->f_argv = argv;
478 char ** array = (
char **)val->val.ptr;
480 for (i = 0; array[i] != NULL; i++) {
500 const char *default_argfn,
508 if ((argc == 2) && (strcmp(argv[1],
"help") == 0)) {
513 if ((argc == 2) && (argv[1][0] !=
'-'))
515 else if (argc == 1) {
517 E_INFO(
"Looking for default argument file: %s\n", default_argfn);
519 if ((fp = fopen(default_argfn,
"r")) == NULL) {
520 E_INFO(
"Can't find default argument file %s.\n",
533 E_INFO(
"Parsing command lines from file %s\n", str);
536 E_INFOCONT(
"\t%s argument-list, or\n", argv[0]);
537 E_INFOCONT(
"\t%s [argument-file] (default file: . %s)\n\n",
538 argv[0], default_argfn);
558 int32 i, j, n, argstart;
563 if (inout_cmdln == NULL) {
573 for (n = 0; defn[n].name; n++) {
577 if (strict && (v != &defn[n])) {
578 E_ERROR(
"Duplicate argument name in definition: %s\n", defn[n].name);
589 if (cmdln->ht == NULL)
595 if (argc > 0 && argv[0][0] !=
'-') {
600 for (j = argstart; j < argc; j += 2) {
607 E_ERROR(
"Unknown argument name '%s'\n", argv[j]);
610 else if (defn == NULL)
620 E_ERROR(
"Argument value for '%s' missing\n", argv[j]);
625 val = cmd_ln_val_init(
ARG_STRING, argv[j], argv[j + 1]);
627 if ((val = cmd_ln_val_init(argdef->type, argv[j], argv[j + 1])) == NULL) {
629 E_ERROR(
"Bad argument value for %s: %s\n", argv[j],
639 cmd_ln_val_free(val);
640 E_ERROR(
"Duplicate argument name in arguments: %s\n",
652 for (i = 0; i < n; i++) {
657 if ((val = cmd_ln_val_init(defn[i].type, defn[i].name, defn[i].deflt)) == NULL) {
659 (
"Bad default argument value for %s: %s\n",
660 defn[i].name, defn[i].deflt);
669 for (i = 0; i < n; i++) {
673 E_ERROR(
"Missing required argument %s\n", defn[i].name);
681 if (strict && argc == 1) {
682 E_ERROR(
"No arguments given, available options are:\n");
686 if (inout_cmdln == NULL)
702 if (inout_cmdln == NULL)
704 E_ERROR(
"Failed to parse arguments list\n");
712 const char *arg, *val;
716 va_start(args, strict);
718 while ((arg = va_arg(args,
const char *))) {
720 val = va_arg(args,
const char*);
722 E_ERROR(
"Number of arguments must be even!\n");
730 f_argv = (
char**)
ckd_calloc(f_argc,
sizeof(*f_argv));
731 va_start(args, strict);
733 while ((arg = va_arg(args,
const char *))) {
736 val = va_arg(args,
const char*);
742 return parse_options(inout_cmdln, defn, f_argc, f_argv, strict);
753 E_ERROR(
"Failed to parse arguments list, forced exit\n");
757 if (global_cmdln == NULL) {
758 global_cmdln = cmdln;
770 int arg_max_length = 512;
775 const char separator[] =
" \t\r\n";
777 if ((file = fopen(filename,
"r")) == NULL) {
778 E_ERROR(
"Cannot open configuration file %s for reading\n",
785 for (; ch != EOF && strchr(separator, ch); ch = fgetc(file)) ;
797 f_argv = (
char **)
ckd_calloc(argv_size,
sizeof(
char *));
799 str = (
char* )
ckd_calloc(arg_max_length + 1,
sizeof(
char));
804 if (len == 0 && argc % 2 == 0) {
807 for (ch = fgetc(file); ch != EOF && ch !=
'\n'; ch = fgetc(file)) ;
809 for (ch = fgetc(file); ch != EOF && strchr(separator, ch); ch = fgetc(file)) ;
818 if (ch ==
'"' || ch ==
'\'') {
822 E_ERROR(
"Nesting quotations is not supported!\n");
829 else if (ch == EOF || (!quoting && strchr(separator, ch))) {
831 if (argc >= argv_size) {
834 (
char **)
ckd_realloc(f_argv, argv_size * 2 *
sizeof(
char *)))) {
849 E_WARN(
"Unclosed quotation, having EOF close it...\n");
852 for (; ch != EOF && strchr(separator, ch); ch = fgetc(file)) ;
861 if (len >= arg_max_length) {
864 if ((tmp_str = (
char *)
ckd_realloc(str, (1 + arg_max_length * 2) *
sizeof(
char))) == NULL) {
885 for (ch = 0; ch < argc; ++ch)
891 return parse_options(inout_cmdln, defn, argc, f_argv, strict);
904 if (global_cmdln == NULL) {
905 global_cmdln = cmdln;
915 fprintf(fp,
"Arguments list definition:\n");
916 arg_dump_r(cmdln, fp, defn, TRUE);
924 fprintf(fp,
"Current configuration:\n");
925 arg_dump_r(cmdln, fp, defn, FALSE);
942 E_ERROR(
"Unknown argument: %s\n", name);
955 return (
char const *)val->ptr;
965 return (
char const **)val->ptr;
994 E_ERROR(
"Unknown argument: %s\n", name);
1006 val = cmd_ln_val_init(
ARG_STRING, name, str);
1020 E_ERROR(
"Unknown argument: %s\n", name);
1032 E_ERROR(
"Unknown argument: %s\n", name);
1050 if (--cmdln->refcount > 0)
1051 return cmdln->refcount;
1059 for (gn = entries; gn; gn = gnode_next(gn)) {
1068 if (cmdln->f_argv) {
1070 for (i = 0; i < cmdln->f_argc; ++i) {
1074 cmdln->f_argv = NULL;
1085 global_cmdln = NULL;
SPHINXBASE_EXPORT long cmd_ln_int_r(cmd_ln_t *cmdln, char const *name)
Retrieve an integer from a command-line object.
SPHINXBASE_EXPORT int32 cmd_ln_parse_file(const arg_t *defn, char const *filename, int32 strict)
Parse an arguments file by deliminating on " \r\t\n" and putting each tokens into an argv[] for cmd_l...
#define REQARG_BOOLEAN
Required boolean argument.
#define REQARG_INTEGER
Required integer argument.
SPHINXBASE_EXPORT anytype_t * cmd_ln_access_r(cmd_ln_t *cmdln, char const *name)
Access the generic type union for a command line argument.
SPHINXBASE_EXPORT const char ** cmd_ln_str_list_r(cmd_ln_t *cmdln, char const *name)
Retrieve an array of strings from a command-line object.
#define E_INFO(...)
Print logging information to standard error stream.
SPHINXBASE_EXPORT double cmd_ln_float_r(cmd_ln_t *cmdln, char const *name)
Retrieve a floating-point number from a command-line object.
SPHINXBASE_EXPORT const char * cmd_ln_str_r(cmd_ln_t *cmdln, char const *name)
Retrieve a string from a command-line object.
SPHINXBASE_EXPORT int32 hash_table_lookup(hash_table_t *h, const char *key, void **val)
Look up a key in a hash table and optionally return the associated value.
SPHINXBASE_EXPORT void cmd_ln_set_int_r(cmd_ln_t *cmdln, char const *name, long iv)
Set an integer in a command-line object.
SPHINXBASE_EXPORT hash_table_t * hash_table_new(int32 size, int32 casearg)
Allocate a new hash table for a given expected size.
SPHINXBASE_EXPORT glist_t hash_table_tolist(hash_table_t *h, int32 *count)
Build a glist of valid hash_entry_t pointers from the given hash table.
#define ARG_REQUIRED
Bit indicating a required argument.
SPHINXBASE_EXPORT cmd_ln_t * cmd_ln_parse_r(cmd_ln_t *inout_cmdln, arg_t const *defn, int32 argc, char *argv[], int32 strict)
Parse a list of strings into argumetns.
SPHINXBASE_EXPORT int32 strcmp_nocase(const char *str1, const char *str2)
(FIXME! The implementation is incorrect!) Case insensitive string compare.
#define ARG_STRING_LIST
Boolean (true/false) argument (optional).
SPHINXBASE_EXPORT void * hash_table_replace(hash_table_t *h, const char *key, void *val)
Add a new entry with given key and value to hash table h.
A note by ARCHAN at 20050510: Technically what we use is so-called "hash table with buckets" which is...
Miscellaneous useful string functions.
#define REQARG_FLOATING
Required floating point argument.
SPHINXBASE_EXPORT int cmd_ln_free_r(cmd_ln_t *cmdln)
Release a command-line argument set and all associated strings.
SPHINXBASE_EXPORT int cmd_ln_exists_r(cmd_ln_t *cmdln, char const *name)
Re-entrant version of cmd_ln_exists().
SPHINXBASE_EXPORT void hash_table_free(hash_table_t *h)
Free the specified hash table; the caller is responsible for freeing the key strings pointed to by th...
A node in a generic list.
SPHINXBASE_EXPORT void cmd_ln_print_help_r(cmd_ln_t *cmdln, FILE *fp, const arg_t *defn)
Print a help message listing the valid argument names, and the associated attributes as given in defn...
#define ARG_STRING
String argument (optional).
SPHINXBASE_EXPORT void cmd_ln_print_values_r(cmd_ln_t *cmdln, FILE *fp, const arg_t *defn)
Print current configuration values and defaults.
void * val
Key-length; the key string does not have to be a C-style NULL terminated string; it can have arbitrar...
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
#define REQARG_STRING
Required string argument.
#define gnode_ptr(g)
Head of a list of gnodes.
SPHINXBASE_EXPORT cmd_ln_t * cmd_ln_get(void)
Retrieve the global cmd_ln_t object used by non-re-entrant functions.
#define cmd_ln_print_help(f, d)
Print a help message listing the valid argument names, and the associated attributes as given in defn...
SPHINXBASE_EXPORT cmd_ln_t * cmd_ln_init(cmd_ln_t *inout_cmdln, arg_t const *defn, int32 strict,...)
Create a cmd_ln_t from NULL-terminated list of arguments.
#define E_INFOCONT(...)
Continue printing the information to standard error stream.
#define ckd_salloc(ptr)
Macro for ckd_salloc
Implementation of logging routines.
Locale-independent implementation of case swapping operation.
Command-line and other configurationparsing and handling.
SPHINXBASE_EXPORT void * hash_table_enter(hash_table_t *h, const char *key, void *val)
Try to add a new entry with given key and associated value to hash table h.
SPHINXBASE_EXPORT void glist_free(glist_t g)
Free the given generic list; user-defined data contained within is not automatically freed.
#define ARG_BOOLEAN
Boolean (true/false) argument (optional).
SPHINXBASE_EXPORT void cmd_ln_appl_exit(void)
Finalization routine corresponding to cmd_ln_appl_enter().
#define E_ERROR(...)
Print error message to error log.
SPHINXBASE_EXPORT void cmd_ln_set_float_r(cmd_ln_t *cmdln, char const *name, double fv)
Set a floating-point number in a command-line object.
SPHINXBASE_EXPORT cmd_ln_t * cmd_ln_parse_file_r(cmd_ln_t *inout_cmdln, arg_t const *defn, char const *filename, int32 strict)
Parse an arguments file by deliminating on " \r\t\n" and putting each tokens into an argv[] for cmd_l...
#define ARG_FLOATING
Floating point argument (optional).
#define ckd_realloc(ptr, sz)
Macro for ckd_realloc
Sphinx's memory allocation/deallocation routines.
SPHINXBASE_EXPORT int32 cmd_ln_parse(const arg_t *defn, int32 argc, char *argv[], int32 strict)
Non-reentrant version of cmd_ln_parse().
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
SPHINXBASE_EXPORT void cmd_ln_set_str_r(cmd_ln_t *cmdln, char const *name, char const *str)
Set a string in a command-line object.
SPHINXBASE_EXPORT void cmd_ln_appl_enter(int argc, char *argv[], char const *default_argfn, const arg_t *defn)
Old application initialization routine for Sphinx3 code.
#define ARG_INTEGER
Integer argument (optional).
SPHINXBASE_EXPORT void cmd_ln_free(void)
Free the global command line, if any exists.
SPHINXBASE_EXPORT void cmd_ln_set_str_extra_r(cmd_ln_t *cmdln, char const *name, char const *str)
Set a string in a command-line object even if it is not present in argument description.
Hash table implementation.
SPHINXBASE_EXPORT double atof_c(char const *str)
Locale independent version of atof().
#define E_WARN(...)
Print warning message to error log.
SPHINXBASE_EXPORT FILE * err_get_logfp(void)
Get the current logging filehandle.
SPHINXBASE_EXPORT cmd_ln_t * cmd_ln_retain(cmd_ln_t *cmdln)
Retain ownership of a command-line argument set.