Index: configure.in ================================================================== --- configure.in +++ configure.in @@ -1,7 +1,7 @@ AC_REVISION($Revision $) -AC_INIT(libconfig, 0.0.3) +AC_INIT(libconfig, 0.0.4) AC_CONFIG_HEADER(config.h) dnl Checks for programs. AC_PROG_CC AC_PROG_MAKE_SET Index: libconfig.c ================================================================== --- libconfig.c +++ libconfig.c @@ -36,10 +36,11 @@ #include #endif struct lc_varhandler_st *varhandlers = NULL; lc_err_t lc_errno = LC_ERR_NONE; +int lc_optind = 0; static int lc_process_var_string(void *data, const char *value) { char **dataval; dataval = data; @@ -269,13 +270,35 @@ static int lc_process_cmdline(int argc, char **argv) { struct lc_varhandler_st *handler = NULL; char *cmdarg = NULL, *cmdoptarg = NULL; char *lastcomponent_handler = NULL; + char **newargv = NULL; + char *usedargv = NULL; int cmdargidx = 0; + int newargvidx = 0; int retval = 0, chkretval = 0; int ch = 0; + + /* Allocate "argc + 1" (+1 for the NULL terminator) elements. */ + newargv = malloc((argc + 1) * sizeof(*newargv)); + if (newargv == NULL) { + lc_errno = LC_ERR_ENOMEM; + return(-1); + } + newargv[newargvidx++] = argv[0]; + newargv[argc] = NULL; + + /* Allocate space to indicate which arguments have been used. */ + usedargv = malloc(argc * sizeof(*usedargv)); + if (usedargv == NULL) { + lc_errno = LC_ERR_ENOMEM; + return(-1); + } + for (cmdargidx = 0; cmdargidx < argc; cmdargidx++) { + usedargv[cmdargidx] = 0; + } for (cmdargidx = 1; cmdargidx < argc; cmdargidx++) { cmdarg = argv[cmdargidx]; /* Make sure we have an argument here. */ @@ -285,10 +308,16 @@ /* If the argument isn't an option, abort. */ if (cmdarg[0] != '-') { continue; } + + /* Setup a pointer in the new array for the actual argument. */ + newargv[newargvidx++] = cmdarg; + usedargv[cmdargidx] = 1; + + /* Then shift the argument past the '-' so we can ignore it. */ *cmdarg++; /* Handle long options. */ if (cmdarg[0] == '-') { *cmdarg++; @@ -312,16 +341,26 @@ handler->type == LC_VAR_UNKNOWN) { continue; } /* Find the last part of the variable and compare it with - the option being processed. */ - lastcomponent_handler = strrchr(handler->var, '.'); - if (lastcomponent_handler == NULL) { - lastcomponent_handler = handler->var; + the option being processed, if a wildcard is given. */ + if (handler->var[0] == '*' && handler->var[1] == '.') { + lastcomponent_handler = strrchr(handler->var, '.'); + if (lastcomponent_handler == NULL) { + lastcomponent_handler = handler->var; + } else { + *lastcomponent_handler++; + } } else { - *lastcomponent_handler++; + /* Disallow use of the fully qualified name + since there was no sectionstart portion + we cannot allow it to handle children of it. */ + if (strchr(cmdarg, '.') != NULL) { + continue; + } + lastcomponent_handler = handler->var; } /* Ignore this handler if they don't match. */ if (strcasecmp(lastcomponent_handler, cmdarg) != 0) { continue; @@ -335,10 +374,12 @@ PRINTERR("Argument required."); lc_errno = LC_ERR_BADFORMAT; return(-1); } cmdoptarg = argv[cmdargidx]; + newargv[newargvidx++] = cmdoptarg; + usedargv[cmdargidx] = 1; } chkretval = lc_handle(handler, handler->var, NULL, cmdoptarg, LC_FLAGS_CMDLINE); if (chkretval < 0) { retval = -1; @@ -377,10 +418,12 @@ PRINTERR("Argument required."); lc_errno = LC_ERR_BADFORMAT; return(-1); } cmdoptarg = argv[cmdargidx]; + newargv[newargvidx++] = cmdoptarg; + usedargv[cmdargidx] = 1; } chkretval = lc_handle(handler, handler->var, NULL, cmdoptarg, LC_FLAGS_CMDLINE); if (chkretval < 0) { retval = -1; @@ -395,10 +438,26 @@ return(-1); } } } } + + if (retval >= 0) { + lc_optind = newargvidx; + for (cmdargidx = 1; cmdargidx < argc; cmdargidx++) { + if (usedargv[cmdargidx] != 0) { + continue; + } + + cmdarg = argv[cmdargidx]; + + newargv[newargvidx++] = cmdarg; + } + for (cmdargidx = 1; cmdargidx < argc; cmdargidx++) { + argv[cmdargidx] = newargv[cmdargidx]; + } + } return(retval); } Index: libconfig.h.in ================================================================== --- libconfig.h.in +++ libconfig.h.in @@ -53,11 +53,11 @@ LC_ERR_INVSECTION, LC_ERR_INVDATA, LC_ERR_BADFORMAT, LC_ERR_CANTOPEN, LC_ERR_CALLBACK, - LC_ERR_ENOMEM + LC_ERR_ENOMEM } lc_err_t; __BLANK_LINE__ int lc_process(int argc, char **argv, const char *appname, lc_conf_type_t type, const char *extra); @@ -70,8 +70,12 @@ !define LC_CBRET_IGNORESECTION (255) !define LC_CBRET_OKAY (0) !define LC_CBRET_ERROR (-1) +__BLANK_LINE__ + +extern int lc_optind; + __BLANK_LINE__ !endif Index: test-lc.c ================================================================== --- test-lc.c +++ test-lc.c @@ -32,10 +32,11 @@ int main(int argc, char **argv) { char *joeval = NULL; long long xval = -1; int onoff = -1; int lcpret = -1; + int i = 0; lc_err_t errs; lc_register_var("Section", LC_VAR_SECTION, NULL, 0); lc_register_var("Somesection", LC_VAR_SECTION, NULL, 0); lc_register_var("Section.Test", LC_VAR_STRING, &joeval, 'j'); @@ -55,8 +56,11 @@ } else { PRINTERR("joeval = \"(null)\""); } PRINTERR("xval = %lli", xval); PRINTERR("onoff = %i", onoff); + for (i = lc_optind; i < argc; i++) { + PRINTERR("argv[%i] = \"%s\"", i, argv[i]); + } return(0); }