diff options
author | jbj <jbj> | 2010-06-18 01:20:16 +0000 |
---|---|---|
committer | jbj <jbj> | 2010-06-18 01:20:16 +0000 |
commit | 538140fa782b6c27b91ad88cccd354794e020576 (patch) | |
tree | efdfaae68f0c98dd8eb5f8dfc022ac63343ac214 /poptparse.c | |
parent | c940cc67340a08779ed69a4de427192e607a9ccf (diff) | |
download | libpopt-538140fa782b6c27b91ad88cccd354794e020576.tar.gz |
- fix: rescusitate --enable-build-gcov AutoFu.
- start rewriting/simplifying argv routines.
Diffstat (limited to 'poptparse.c')
-rw-r--r-- | poptparse.c | 120 |
1 files changed, 64 insertions, 56 deletions
diff --git a/poptparse.c b/poptparse.c index 4ceb279..23733f5 100644 --- a/poptparse.c +++ b/poptparse.c @@ -8,12 +8,26 @@ #include "system.h" +#include <poptint.h> + #if defined(HAVE_ASSERT_H) #include <assert.h> #else #define assert(_x) #endif +static const char ** poptArgvFree(/*@only@*/ const char ** av) +{ +#if !defined(SUPPORT_CONTIGUOUS_ARGV) + int i; + if (av) + for (i = 0; av[i]; i++) + av[i] = _free(av[i]); +#endif + av = _free(av); + return NULL; +} + #define POPT_ARGV_ARRAY_GROW_DELTA 5 int poptDupArgv(int argc, const char **argv, @@ -56,17 +70,10 @@ assert(dst); /* XXX can't happen */ } argv2[argc] = NULL; - if (argvPtr) { + if (argvPtr) *argvPtr = argv2; - } else { -#if !defined(SUPPORT_CONTIGUOUS_ARGV) - if (argv2) - for (i = 0; i < argc; i++) - if (argv2[i]) free((void *)argv2[i]); /* XXX _free */ -#endif - free((void *)argv2); /* XXX _free */ - argv2 = NULL; - } + else + argv2 = poptArgvFree(argv2); if (argcPtr) *argcPtr = argc; return 0; @@ -74,77 +81,79 @@ assert(dst); /* XXX can't happen */ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) { - const char * src; + const char * se; char quote = '\0'; - int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; + size_t argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; const char ** argv = xmalloc(sizeof(*argv) * argvAlloced); int argc = 0; - size_t buflen = strlen(s) + 1; - char * buf, * bufOrig = NULL; + size_t ns = strlen(s); + char * t = NULL; + char * te; int rc = POPT_ERROR_MALLOC; assert(argv); /* XXX can't happen */ if (argv == NULL) return rc; - buf = bufOrig = xcalloc((size_t)1, buflen); -assert(buf); /* XXX can't happen */ - if (buf == NULL) { - free(argv); /* XXX _free */ + te = t = xcalloc((size_t)1, ns + 1); +assert(te); /* XXX can't happen */ + if (te == NULL) { + argv = _free(argv); return rc; } - argv[argc] = buf; + argv[argc] = te; - for (src = s; *src != '\0'; src++) { - if (quote == *src) { + for (se = s; *se != '\0'; se++) { + if (quote == *se) { quote = '\0'; } else if (quote != '\0') { - if (*src == '\\') { - src++; - if (!*src) { + if (*se == '\\') { + se++; + if (*se == '\0') { rc = POPT_ERROR_BADQUOTE; goto exit; } - if (*src != quote) *buf++ = '\\'; + if (*se != quote) *te++ = '\\'; } - *buf++ = *src; - } else if (_isspaceptr(src)) { + *te++ = *se; + } else if (_isspaceptr(se)) { if (*argv[argc] != '\0') { - buf++, argc++; + te++, argc++; if (argc == argvAlloced) { argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; argv = xrealloc(argv, sizeof(*argv) * argvAlloced); assert(argv); /* XXX can't happen */ if (argv == NULL) goto exit; } - argv[argc] = buf; + argv[argc] = te; } - } else switch (*src) { + } else + switch (*se) { case '"': case '\'': - quote = *src; + quote = *se; /*@switchbreak@*/ break; case '\\': - src++; - if (!*src) { + se++; + if (*se == '\0') { rc = POPT_ERROR_BADQUOTE; goto exit; } /*@fallthrough@*/ default: - *buf++ = *src; + *te++ = *se; /*@switchbreak@*/ break; } } if (strlen(argv[argc])) { - argc++, buf++; + argc++, te++; } rc = poptDupArgv(argc, argv, argcPtr, argvPtr); exit: - if (bufOrig) free(bufOrig); /* XXX _free */ - if (argv) free(argv); /* XXX _free */ + t = _free(t); + argv = _free(argv); return rc; } @@ -156,15 +165,13 @@ exit: int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ UNUSED(int flags)) { - char line[8192]; /* XXX configurable? */ + size_t nline = 8192; /* XXX configurable? */ + char * line = alloca(nline); char * argstr; - char * p; char * q; char * x; size_t t; size_t argvlen = 0; - size_t maxlinelen = sizeof(line); - size_t linelen; size_t maxargvlen = (size_t)480; if (argstrp) @@ -182,23 +189,24 @@ assert(argstr); /* XXX can't happen */ if (argstr == NULL) return POPT_ERROR_MALLOC; argstr[0] = '\0'; - while (fgets(line, (int)maxlinelen, fp) != NULL) { - p = line; + while (fgets(line, (int)nline, fp) != NULL) { + char * l = line; + size_t nl; /* loop until first non-space char or EOL */ - while( *p != '\0' && _isspaceptr(p) ) - p++; + while( *l != '\0' && _isspaceptr(l) ) + l++; - linelen = strlen(p); - if (linelen >= maxlinelen-1) { - free(argstr); /* XXX _free */ + nl = strlen(l); + if (nl >= nline-1) { + argstr = _free(argstr); return POPT_ERROR_OVERFLOW; /* XXX line too long */ } - if (*p == '\0' || *p == '\n') continue; /* line is empty */ - if (*p == '#') continue; /* comment line */ + if (*l == '\0' || *l == '\n') continue; /* line is empty */ + if (*l == '#') continue; /* comment line */ - q = p; + q = l; while (*q != '\0' && (!_isspaceptr(q)) && *q != '=') q++; @@ -211,7 +219,7 @@ assert(argstr); /* XXX can't happen */ if (*q == '\0') { /* single command line option (ie, no name=val, just name) */ q[-1] = '\0'; /* kill off newline from fgets() call */ - argvlen += (t = (size_t)(q - p)) + (sizeof(" --")-1); + argvlen += (t = (size_t)(q - l)) + (sizeof(" --")-1); if (argvlen >= maxargvlen) { maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; argstr = xrealloc(argstr, maxargvlen); @@ -219,7 +227,7 @@ assert(argstr); /* XXX can't happen */ if (argstr == NULL) return POPT_ERROR_MALLOC; } strcat(argstr, " --"); /* XXX stpcpy */ - strcat(argstr, p); /* XXX stpcpy */ + strcat(argstr, l); /* XXX stpcpy */ continue; } if (*q != '=') @@ -235,12 +243,12 @@ assert(argstr); /* XXX can't happen */ continue; /* XXX silently ignore missing value */ /* now, loop and strip all ending whitespace */ - x = p + linelen; + x = l + nl; while (_isspaceptr(--x)) *x = '\0'; /* null out last char if space (including fgets() NL) */ /* rest of line accept */ - t = (size_t)(x - p); + t = (size_t)(x - l); argvlen += t + (sizeof("' --='")-1); if (argvlen >= maxargvlen) { maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; @@ -249,7 +257,7 @@ assert(argstr); /* XXX can't happen */ if (argstr == NULL) return POPT_ERROR_MALLOC; } strcat(argstr, " --"); /* XXX stpcpy */ - strcat(argstr, p); /* XXX stpcpy */ + strcat(argstr, l); /* XXX stpcpy */ strcat(argstr, "=\""); /* XXX stpcpy */ strcat(argstr, q); /* XXX stpcpy */ strcat(argstr, "\""); /* XXX stpcpy */ |