| version 1.12, 2001/12/05 23:58:48 |
version 1.13, 2001/12/08 18:23:52 |
|
|
| |
|
| |
|
| static int cfg_cmdline_get_next_opt(const CFG_CONTEXT con); |
static int cfg_cmdline_get_next_opt(const CFG_CONTEXT con); |
| |
static int process_currents(const CFG_CONTEXT con, int *ret_val, int *arg_used); |
| static void free_currents(const CFG_CONTEXT con); |
static void free_currents(const CFG_CONTEXT con); |
| static int set_currents(const CFG_CONTEXT con); |
static int set_currents(const CFG_CONTEXT con); |
| static int search_cur_opt_idx(const CFG_CONTEXT con); |
static int search_cur_opt_idx(const CFG_CONTEXT con); |
| Line 19 static int store_single_arg(const int ty |
|
| Line 20 static int store_single_arg(const int ty |
|
| |
|
| static int cfg_cmdline_get_next_opt(const CFG_CONTEXT con) |
static int cfg_cmdline_get_next_opt(const CFG_CONTEXT con) |
| { |
{ |
| register int opt_idx; |
/* register int opt_idx; */ |
| register int arg_used; |
register int ret; |
| |
int arg_used, ret_val; |
| |
|
| register int opt_data_type, opt_f_multi, opt_f_multi_sep; |
/* register int opt_data_type, opt_f_multi, opt_f_multi_sep; */ |
| |
|
| while (1) { |
while (1) { |
| |
|
| Line 34 static int cfg_cmdline_get_next_opt(cons |
|
| Line 36 static int cfg_cmdline_get_next_opt(cons |
|
| break; |
break; |
| |
|
| /* Finished? */ |
/* Finished? */ |
| if (con->argv[con->cur_idx] == NULL) |
if ((con->argc != 0 && con->cur_idx > con->argc) |
| |
|| con->argv[con->cur_idx] == NULL) |
| break; |
break; |
| |
|
| if (con->cur_opt_type & CFG_SHORT_OPTIONS) { |
if (con->cur_opt_type & CFG_SHORT_OPTIONS) { |
| Line 52 static int cfg_cmdline_get_next_opt(cons |
|
| Line 55 static int cfg_cmdline_get_next_opt(cons |
|
| } |
} |
| } |
} |
| else { |
else { |
| |
register int leftover_init = 0; |
| |
|
| |
/* Test if previous argument was leftover and also there is not |
| |
advanced leftovers initializations set in context flags. */ |
| |
if (! (con->flags & CFG_ADVANCED_LEFTOVERS) |
| |
&& con->cur_opt_type == CFG_NONE_OPTION |
| |
&& con->cur_opt == NULL && con->cur_arg != NULL |
| |
&& con->argv[con->cur_idx - 1] != NULL |
| |
&& ! strcmp(con->cur_arg, con->argv[con->cur_idx - 1])) |
| |
leftover_init = 1; |
| |
|
| free_currents(con); |
free_currents(con); |
| |
|
| if (! strdyn_compare(con->line_stop_str, con->argv[con->cur_idx])) |
if (! strdyn_compare(con->line_stop_str, con->argv[con->cur_idx])) |
| return CFG_ERROR_STOP_STR_FOUND; |
return CFG_ERROR_STOP_STR_FOUND; |
| |
|
| if (set_currents(con) == 0) |
/* Skip option analyze in set_currents(), count it as leftover. */ |
| return CFG_ERROR_NOMEM; |
if (leftover_init) { |
| |
con->cur_opt_type = CFG_NONE_OPTION; |
| |
con->cur_opt = NULL; |
| |
if ((con->cur_arg = strdup(con->argv[con->cur_idx])) == NULL) |
| |
return CFG_ERROR_NOMEM; |
| |
} |
| |
else { |
| |
if (set_currents(con) == 0) |
| |
return CFG_ERROR_NOMEM; |
| |
} |
| } |
} |
| |
|
| opt_idx = search_cur_opt_idx(con); |
ret = process_currents(con, &ret_val, &arg_used); |
| |
|
| #if defined(DEBUG) && DEBUG |
if (ret != CFG_OK) |
| fprintf(stderr, "--\nDEBUG|%d|%s|%s|%s|%d|flags=%x[", |
return ret; |
| con->cur_idx, con->argv[con->cur_idx], |
|
| con->cur_opt == NULL ? "[NULL]" : con->cur_opt, |
|
| con->cur_arg == NULL ? "[NULL]" : con->cur_arg, |
|
| opt_idx, con->cur_opt_type); |
|
| |
|
| if (con->cur_opt_type & CFG_LONG_OPTION) |
|
| fputs("-LONG-", stderr); |
|
| if (con->cur_opt_type & CFG_SHORT_OPTION) |
|
| fputs("-SHORT-", stderr); |
|
| if (con->cur_opt_type & CFG_SHORT_OPTIONS) |
|
| fputs("-SHORTS-", stderr); |
|
| if (con->cur_opt_type & CFG_LONG_SEPINIT) |
|
| fputs("-SEPINIT-", stderr); |
|
| |
|
| fputs("]\n", stderr); |
if (arg_used) { |
| #endif |
if (! (con->cur_opt_type & CFG_LONG_SEPINIT) |
| |
&& !(con->cur_opt_type & CFG_SHORT_OPTIONS) |
| |
&& !(con->cur_opt_type == CFG_NONE_OPTION)) |
| |
{ |
| |
/* puts("[1] argument used, moving cur_idx"); */ |
| |
con->cur_idx_tmp++; |
| |
} |
| |
|
| if (opt_idx < 0) |
if (con->cur_opt_type & CFG_SHORT_OPTIONS) |
| return CFG_ERROR_UNKNOWN; |
con->cur_opt_type -= CFG_SHORT_OPTIONS; |
| |
} |
| |
|
| if ( ! (con->flags & CFG_IGNORE_MULTI) |
if (! (con->cur_opt_type & CFG_SHORT_OPTIONS)) { |
| && ! (con->options[opt_idx].type & CFG_MULTI)) { |
/* puts("[2] moving cur_idx"); */ |
| int ret = 0; |
con->cur_idx_tmp++; |
| |
|
| ret = add_to_used_opt_idx(con, opt_idx); |
|
| |
|
| if (ret < 0) |
|
| return CFG_ERROR_NOMEM; |
|
| else if (ret > 0) |
|
| return CFG_ERROR_MULTI; |
|
| } |
} |
| |
|
| /* Setting others opt_XXX constants according to opt_idx. */ |
if (ret_val > 0) |
| /* opt_data_type - option data type, opt_f_XXX - option flags */ |
return ret_val; |
| opt_data_type = con->options[opt_idx].type & CFG_DATA_TYPE_MASK; |
|
| opt_f_multi = con->options[opt_idx].type & CFG_MULTI; |
|
| opt_f_multi_sep = con->options[opt_idx].type & |
|
| (CFG_MULTI_SEPARATED & ~CFG_MULTI); |
|
| |
|
| switch (opt_data_type) { |
|
| default: |
|
| return CFG_ERROR_INTERNAL; |
|
| break; |
|
| |
|
| /* Boolean data type. */ |
} |
| |
|
| case CFG_BOOLEAN: |
return CFG_OK; |
| if (con->cur_opt_type & CFG_LONG_SEPINIT |
} |
| && con->cur_arg != NULL) |
|
| return CFG_ERROR_NOTALLOWEDARG; |
|
| |
|
| if (con->options[opt_idx].value != NULL) |
static int process_currents(const CFG_CONTEXT con, int *ret_val, int *arg_used) |
| (*((int *) con->options[opt_idx].value))++; |
{ |
| break; |
register int opt_idx; |
| |
register int opt_data_type, opt_f_multi, opt_f_multi_sep; |
| |
|
| /* Numeric (int, long, float and double) data types. */ |
*ret_val = 0; |
| |
if (arg_used != NULL) |
| |
*arg_used = 0; |
| |
|
| case CFG_INT: |
opt_idx = search_cur_opt_idx(con); |
| case CFG_UINT: |
|
| case CFG_LONG: |
|
| case CFG_ULONG: |
|
| case CFG_FLOAT: |
|
| case CFG_DOUBLE: |
|
| |
|
| if (con->cur_arg == NULL) |
#if defined(DEBUG) && DEBUG |
| return CFG_ERR_NOARG; |
fprintf(stderr, "%s|%d|%s|%s|%s|%d|flags=%x[", |
| |
con->type == CFG_LINE ? "cmdline" : "cfgfile", |
| |
con->type == CFG_LINE ? con->cur_idx : 0, |
| |
con->type == CFG_LINE ? con->argv[con->cur_idx] : "N/A", |
| |
con->cur_opt == NULL ? "[NULL]" : con->cur_opt, |
| |
con->cur_arg == NULL ? "[NULL]" : con->cur_arg, |
| |
opt_idx, con->cur_opt_type); |
| |
|
| |
if (con->cur_opt_type & CFG_LONG_OPTION) |
| |
fputs("-LONG-", stderr); |
| |
if (con->cur_opt_type & CFG_SHORT_OPTION) |
| |
fputs("-SHORT-", stderr); |
| |
if (con->cur_opt_type & CFG_SHORT_OPTIONS) |
| |
fputs("-SHORTS-", stderr); |
| |
if (con->cur_opt_type & CFG_LONG_SEPINIT) |
| |
fputs("-SEPINIT-", stderr); |
| |
|
| { |
fputs("]\n", stderr); |
| register int ret; |
#endif |
| |
|
| if (opt_f_multi) { |
if (opt_idx < 0) |
| char **add; |
return CFG_ERROR_UNKNOWN; |
| char *static_add[2] = { NULL, NULL }; |
|
| |
|
| if (opt_f_multi_sep) { |
|
| add = strdyn_explode_ar(con->cur_arg, |
|
| con->multi_separator); |
|
| if (add == NULL) |
|
| return CFG_ERROR_NOMEM; |
|
| } |
|
| else { |
|
| add = static_add; |
|
| add[0] = con->cur_arg; |
|
| } |
|
| |
|
| ret = store_multi_arg(opt_data_type, |
|
| (const char **) add, |
|
| con->options[opt_idx].value); |
|
| |
|
| if (add != static_add) |
if ( ! (con->flags & CFG_IGNORE_MULTI) |
| strdyn_free((char **) add); |
&& ! (con->options[opt_idx].type & CFG_MULTI)) { |
| } |
int ret = 0; |
| else |
|
| ret = store_single_arg(opt_data_type, con->cur_arg, |
ret = add_to_used_opt_idx(con, opt_idx); |
| con->options[opt_idx].value); |
|
| |
if (ret < 0) |
| |
return CFG_ERROR_NOMEM; |
| |
else if (ret > 0) |
| |
return CFG_ERROR_MULTI; |
| |
} |
| |
|
| if (ret != CFG_OK) |
/* Setting others opt_XXX constants according to *opt_idx. */ |
| return ret; |
/* opt_data_type - option data type, opt_f_XXX - option flags */ |
| } |
opt_data_type = con->options[opt_idx].type & CFG_DATA_TYPE_MASK; |
| |
opt_f_multi = con->options[opt_idx].type & CFG_MULTI; |
| |
opt_f_multi_sep = con->options[opt_idx].type & |
| |
(CFG_MULTI_SEPARATED & ~CFG_MULTI); |
| |
|
| |
switch (opt_data_type) { |
| |
default: |
| |
return CFG_ERROR_INTERNAL; |
| |
break; |
| |
|
| arg_used = 1; |
/* Boolean data type. */ |
| break; |
|
| |
|
| /* String data type. */ |
case CFG_BOOLEAN: |
| |
if (con->cur_opt_type & CFG_LONG_SEPINIT |
| |
&& con->cur_arg != NULL) |
| |
return CFG_ERROR_NOTALLOWEDARG; |
| |
|
| case CFG_STRING: |
if (con->options[opt_idx].value != NULL) |
| |
(*((int *) con->options[opt_idx].value))++; |
| |
break; |
| |
|
| if (con->cur_arg == NULL) |
/* Numeric (int, long, float and double) data types. */ |
| return CFG_ERR_NOARG; |
|
| |
|
| if (con->options[opt_idx].value != NULL) { |
case CFG_INT: |
| if (opt_f_multi) { |
case CFG_UINT: |
| register char ***p; |
case CFG_LONG: |
| p = (char ***) con->options[opt_idx].value; |
case CFG_ULONG: |
| |
case CFG_FLOAT: |
| if (opt_f_multi_sep) { |
case CFG_DOUBLE: |
| register char **ar; |
|
| |
|
| ar = strdyn_explode_ar(con->cur_arg, |
|
| con->multi_separator); |
|
| if (ar == NULL) |
|
| return CFG_ERROR_NOMEM; |
|
| |
|
| if ((*p = strdyn_add_ar(*p, ar)) == NULL) |
|
| return CFG_ERROR_NOMEM; |
|
| |
|
| strdyn_free(ar); |
|
| } |
|
| else { |
|
| if ((*p = strdyn_add(*p, con->cur_arg)) == NULL) |
|
| return CFG_ERROR_NOMEM; |
|
| } |
|
| } |
|
| else |
|
| *((char **) con->options[opt_idx].value) = |
|
| strdup(con->cur_arg); |
|
| } |
|
| |
|
| arg_used = 1; |
if (con->cur_arg == NULL) |
| break; |
return CFG_ERR_NOARG; |
| } |
|
| |
|
| if (arg_used) { |
|
| if (! (con->cur_opt_type & CFG_LONG_SEPINIT) |
|
| && !(con->cur_opt_type & CFG_SHORT_OPTIONS) |
|
| && !(con->cur_opt_type == CFG_NONE_OPTION)) |
|
| { |
{ |
| /* puts("[1] argument used, moving cur_idx"); */ |
register int ret; |
| con->cur_idx_tmp++; |
|
| |
if (opt_f_multi) { |
| |
char **add; |
| |
char *static_add[2] = {NULL, NULL}; |
| |
|
| |
if (opt_f_multi_sep) { |
| |
add = strdyn_explode_ar(con->cur_arg, |
| |
con->multi_vals_separator); |
| |
if (add == NULL) |
| |
return CFG_ERROR_NOMEM; |
| |
} |
| |
else { |
| |
add = static_add; |
| |
add[0] = con->cur_arg; |
| |
} |
| |
|
| |
ret = store_multi_arg(opt_data_type, |
| |
(const char **) add, |
| |
con->options[opt_idx].value); |
| |
|
| |
if (add != static_add) |
| |
strdyn_free((char **) add); |
| |
} |
| |
else |
| |
ret = store_single_arg(opt_data_type, con->cur_arg, |
| |
con->options[opt_idx].value); |
| |
|
| |
if (ret != CFG_OK) |
| |
return ret; |
| } |
} |
| |
|
| if (con->cur_opt_type & CFG_SHORT_OPTIONS) |
if (arg_used != NULL) |
| con->cur_opt_type -= CFG_SHORT_OPTIONS; |
*arg_used = 1; |
| } |
break; |
| |
|
| if (! (con->cur_opt_type & CFG_SHORT_OPTIONS)) { |
/* String data type. */ |
| /* puts("[2] moving cur_idx"); */ |
|
| con->cur_idx_tmp++; |
case CFG_STRING: |
| } |
|
| |
if (con->cur_arg == NULL) |
| |
return CFG_ERR_NOARG; |
| |
|
| |
if (con->options[opt_idx].value != NULL) { |
| |
if (opt_f_multi) { |
| |
register char ***p; |
| |
p = (char ***) con->options[opt_idx].value; |
| |
|
| |
if (opt_f_multi_sep) { |
| |
register char **ar; |
| |
|
| if (con->options[opt_idx].val != 0) |
ar = strdyn_explode_ar(con->cur_arg, |
| return con->options[opt_idx].val; |
con->multi_vals_separator); |
| |
if (ar == NULL) |
| |
return CFG_ERROR_NOMEM; |
| |
|
| |
if ((*p = strdyn_add_ar(*p, ar)) == NULL) |
| |
return CFG_ERROR_NOMEM; |
| |
|
| |
strdyn_free(ar); |
| |
} |
| |
else { |
| |
if ((*p = strdyn_add(*p, con->cur_arg)) == NULL) |
| |
return CFG_ERROR_NOMEM; |
| |
} |
| |
} |
| |
else |
| |
*((char **) con->options[opt_idx].value) = |
| |
strdup(con->cur_arg); |
| |
} |
| |
|
| |
if (arg_used != NULL) |
| |
*arg_used = 1; |
| |
break; |
| } |
} |
| |
|
| |
/* if (con->options[opt_idx].val != 0) */ |
| |
*ret_val = con->options[opt_idx].val; |
| |
|
| return CFG_OK; |
return CFG_OK; |
| } |
} |
| |
|
| Line 379 static int search_cur_opt_idx(const CFG_ |
|
| Line 427 static int search_cur_opt_idx(const CFG_ |
|
| i++) |
i++) |
| { |
{ |
| |
|
| if ((con->cur_opt_type & CFG_LONG_OPTION && con->cur_opt != NULL |
if (con->type == CFG_CMDLINE) { |
| && con->options[i].cmdline_long_name != NULL |
if ((con->cur_opt_type & CFG_LONG_OPTION && con->cur_opt != NULL |
| && ! strcmp(con->cur_opt, |
&& con->options[i].cmdline_long_name != NULL |
| con->options[i].cmdline_long_name)) |
&& ! strcmp(con->cur_opt, |
| || (con->cur_opt_type & CFG_SHORT_OPTION && |
con->options[i].cmdline_long_name)) |
| con->cur_opt[0] == con->options[i].cmdline_short_name) |
|| (con->cur_opt_type & CFG_SHORT_OPTION && |
| || (con->cur_opt_type == CFG_NONE_OPTION && |
con->cur_opt[0] == con->options[i].cmdline_short_name) |
| con->options[i].type & CFG_LEFTOVER_ARGS)) |
|| (con->cur_opt_type == CFG_NONE_OPTION && |
| |
con->options[i].type & CFG_LEFTOVER_ARGS)) |
| |
|
| |
return i; |
| |
} |
| |
else { /* con->type == CFG_CFGFILE */ |
| |
if (con->cur_opt != NULL |
| |
&& con->options[i].cfgfile_name != NULL |
| |
&& ! strcmp(con->cur_opt, con->options[i].cfgfile_name)) |
| |
|
| return i; |
return i; |
| |
} |
| } |
} |
| |
|
| return -1; |
return -1; |
| } |
} |
| |
|
| |
/* |
| |
* Size of realloc() step for used_opt member of cfg_context structure. |
| |
* Value must be grater than 0. |
| |
*/ |
| |
|
| #ifdef CFG_USED_OPT_IDX_STEP |
#ifdef CFG_USED_OPT_IDX_STEP |
| # undef CFG_USED_OPT_IDX_STEP |
# undef CFG_USED_OPT_IDX_STEP |
| #endif |
#endif |
| |
|
| #if defined(DEBUG) && DEBUG |
#if defined(DEBUG) && DEBUG |
| # define CFG_USED_OPT_IDX_STEP (1) /* Must be greater than 0. */ |
# define CFG_USED_OPT_IDX_STEP (1) |
| #else |
#else |
| # define CFG_USED_OPT_IDX_STEP (10) |
# define CFG_USED_OPT_IDX_STEP (10) |
| #endif |
#endif |