From be6edf50c4e76662cd80eab9d60182f2e4f02d24 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 23 Oct 2001 14:16:22 +0000 Subject: Add popt for parsing commandline options (This used to be commit df34e11d84a6fe89dc6654eb10de0a49383e1dea) --- source3/popt/poptparse.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 source3/popt/poptparse.c (limited to 'source3/popt/poptparse.c') diff --git a/source3/popt/poptparse.c b/source3/popt/poptparse.c new file mode 100644 index 0000000000..8f00769be9 --- /dev/null +++ b/source3/popt/poptparse.c @@ -0,0 +1,102 @@ +/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.redhat.com/pub/code/popt */ + +#include "system.h" + +#define POPT_ARGV_ARRAY_GROW_DELTA 5 + +int poptDupArgv(int argc, const char **argv, + int * argcPtr, const char *** argvPtr) +{ + size_t nb = (argc + 1) * sizeof(*argv); + const char ** argv2; + char * dst; + int i; + + for (i = 0; i < argc; i++) { + if (argv[i] == NULL) + return POPT_ERROR_NOARG; + nb += strlen(argv[i]) + 1; + } + + dst = malloc(nb); + argv2 = (void *) dst; + dst += (argc + 1) * sizeof(*argv); + + for (i = 0; i < argc; i++) { + argv2[i] = dst; + dst += strlen(strcpy(dst, argv[i])) + 1; + } + argv2[argc] = NULL; + + *argvPtr = argv2; + *argcPtr = argc; + return 0; +} + +int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) +{ + const char * src; + char quote = '\0'; + int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; + const char ** argv = malloc(sizeof(*argv) * argvAlloced); + int argc = 0; + int buflen = strlen(s) + 1; + char *buf0 = calloc(buflen, 1); + char *buf = buf0; + + argv[argc] = buf; + + for (src = s; *src; src++) { + if (quote == *src) { + quote = '\0'; + } else if (quote) { + if (*src == '\\') { + src++; + if (!*src) { + free(argv); + free(buf0); + return POPT_ERROR_BADQUOTE; + } + if (*src != quote) *buf++ = '\\'; + } + *buf++ = *src; + } else if (isspace(*src)) { + if (*argv[argc]) { + buf++, argc++; + if (argc == argvAlloced) { + argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; + argv = realloc(argv, sizeof(*argv) * argvAlloced); + } + argv[argc] = buf; + } + } else switch (*src) { + case '"': + case '\'': + quote = *src; + break; + case '\\': + src++; + if (!*src) { + free(argv); + free(buf0); + return POPT_ERROR_BADQUOTE; + } + /*@fallthrough@*/ + default: + *buf++ = *src; + break; + } + } + + if (strlen(argv[argc])) { + argc++, buf++; + } + + (void) poptDupArgv(argc, argv, argcPtr, argvPtr); + + free(argv); + free(buf0); + return 0; +} -- cgit From dc64af1d2ee478254b57c323795736e85d2aed92 Mon Sep 17 00:00:00 2001 From: James Peach Date: Wed, 17 May 2006 00:04:09 +0000 Subject: r15654: Update our internal copy of popt to that distributed with the RPM 4.2 source code. (This used to be commit 9559886a92b1fdd33d380bf0100dcddb12477ff2) --- source3/popt/poptparse.c | 165 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 145 insertions(+), 20 deletions(-) (limited to 'source3/popt/poptparse.c') diff --git a/source3/popt/poptparse.c b/source3/popt/poptparse.c index 8f00769be9..537ec44398 100644 --- a/source3/popt/poptparse.c +++ b/source3/popt/poptparse.c @@ -1,11 +1,16 @@ -/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING +/** \ingroup popt + * \file popt/poptparse.c + */ + +/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING file accompanying popt source distributions, available from - ftp://ftp.redhat.com/pub/code/popt */ + ftp://ftp.rpm.org/pub/rpm/dist. */ #include "system.h" #define POPT_ARGV_ARRAY_GROW_DELTA 5 +/*@-boundswrite@*/ int poptDupArgv(int argc, const char **argv, int * argcPtr, const char *** argvPtr) { @@ -14,6 +19,8 @@ int poptDupArgv(int argc, const char **argv, char * dst; int i; + if (argc <= 0 || argv == NULL) /* XXX can't happen */ + return POPT_ERROR_NOARG; for (i = 0; i < argc; i++) { if (argv[i] == NULL) return POPT_ERROR_NOARG; @@ -21,20 +28,32 @@ int poptDupArgv(int argc, const char **argv, } dst = malloc(nb); + if (dst == NULL) /* XXX can't happen */ + return POPT_ERROR_MALLOC; argv2 = (void *) dst; dst += (argc + 1) * sizeof(*argv); + /*@-branchstate@*/ for (i = 0; i < argc; i++) { argv2[i] = dst; dst += strlen(strcpy(dst, argv[i])) + 1; } + /*@=branchstate@*/ argv2[argc] = NULL; - *argvPtr = argv2; - *argcPtr = argc; + if (argvPtr) { + *argvPtr = argv2; + } else { + free(argv2); + argv2 = NULL; + } + if (argcPtr) + *argcPtr = argc; return 0; } +/*@=boundswrite@*/ +/*@-bounds@*/ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) { const char * src; @@ -43,31 +62,32 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) const char ** argv = malloc(sizeof(*argv) * argvAlloced); int argc = 0; int buflen = strlen(s) + 1; - char *buf0 = calloc(buflen, 1); - char *buf = buf0; + char * buf = memset(alloca(buflen), 0, buflen); + int rc = POPT_ERROR_MALLOC; + if (argv == NULL) return rc; argv[argc] = buf; - for (src = s; *src; src++) { + for (src = s; *src != '\0'; src++) { if (quote == *src) { quote = '\0'; - } else if (quote) { + } else if (quote != '\0') { if (*src == '\\') { src++; if (!*src) { - free(argv); - free(buf0); - return POPT_ERROR_BADQUOTE; + rc = POPT_ERROR_BADQUOTE; + goto exit; } if (*src != quote) *buf++ = '\\'; } *buf++ = *src; } else if (isspace(*src)) { - if (*argv[argc]) { + if (*argv[argc] != '\0') { buf++, argc++; if (argc == argvAlloced) { argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; argv = realloc(argv, sizeof(*argv) * argvAlloced); + if (argv == NULL) goto exit; } argv[argc] = buf; } @@ -75,18 +95,17 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) case '"': case '\'': quote = *src; - break; + /*@switchbreak@*/ break; case '\\': src++; if (!*src) { - free(argv); - free(buf0); - return POPT_ERROR_BADQUOTE; + rc = POPT_ERROR_BADQUOTE; + goto exit; } /*@fallthrough@*/ default: *buf++ = *src; - break; + /*@switchbreak@*/ break; } } @@ -94,9 +113,115 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) argc++, buf++; } - (void) poptDupArgv(argc, argv, argcPtr, argvPtr); + rc = poptDupArgv(argc, argv, argcPtr, argvPtr); + +exit: + if (argv) free(argv); + return rc; +} +/*@=bounds@*/ + +/* still in the dev stage. + * return values, perhaps 1== file erro + * 2== line to long + * 3== umm.... more? + */ +int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ int flags) +{ + char line[999]; + char * argstr; + char * p; + char * q; + char * x; + int t; + int argvlen = 0; + size_t maxlinelen = sizeof(line); + size_t linelen; + int maxargvlen = 480; + int linenum = 0; + + *argstrp = NULL; + + /* | this_is = our_line + * p q x + */ + + if (fp == NULL) + return POPT_ERROR_NULLARG; + + argstr = calloc(maxargvlen, sizeof(*argstr)); + if (argstr == NULL) return POPT_ERROR_MALLOC; + + while (fgets(line, (int)maxlinelen, fp) != NULL) { + linenum++; + p = line; + + /* loop until first non-space char or EOL */ + while( *p != '\0' && isspace(*p) ) + p++; + + linelen = strlen(p); + if (linelen >= maxlinelen-1) + return POPT_ERROR_OVERFLOW; /* XXX line too long */ + + if (*p == '\0' || *p == '\n') continue; /* line is empty */ + if (*p == '#') continue; /* comment line */ + + q = p; + + while (*q != '\0' && (!isspace(*q)) && *q != '=') + q++; + + if (isspace(*q)) { + /* a space after the name, find next non space */ + *q++='\0'; + while( *q != '\0' && isspace((int)*q) ) q++; + } + if (*q == '\0') { + /* single command line option (ie, no name=val, just name) */ + q[-1] = '\0'; /* kill off newline from fgets() call */ + argvlen += (t = q - p) + (sizeof(" --")-1); + if (argvlen >= maxargvlen) { + maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; + argstr = realloc(argstr, maxargvlen); + if (argstr == NULL) return POPT_ERROR_MALLOC; + } + strcat(argstr, " --"); + strcat(argstr, p); + continue; + } + if (*q != '=') + continue; /* XXX for now, silently ignore bogus line */ + + /* *q is an equal sign. */ + *q++ = '\0'; + + /* find next non-space letter of value */ + while (*q != '\0' && isspace(*q)) + q++; + if (*q == '\0') + continue; /* XXX silently ignore missing value */ + + /* now, loop and strip all ending whitespace */ + x = p + linelen; + while (isspace(*--x)) + *x = 0; /* null out last char if space (including fgets() NL) */ + + /* rest of line accept */ + t = x - p; + argvlen += t + (sizeof("' --='")-1); + if (argvlen >= maxargvlen) { + maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; + argstr = realloc(argstr, maxargvlen); + if (argstr == NULL) return POPT_ERROR_MALLOC; + } + strcat(argstr, " --"); + strcat(argstr, p); + strcat(argstr, "=\""); + strcat(argstr, q); + strcat(argstr, "\""); + } - free(argv); - free(buf0); + *argstrp = argstr; return 0; } -- cgit From 70faa40a2dc67344d530dec8d12186cdf177ee4a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Jul 2007 18:47:40 +0000 Subject: r24048: Fix the C++ warnings in our version of popt (This used to be commit fd3683c1b3d89a47d59643b0f5751726cb2c89f9) --- source3/popt/poptparse.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/popt/poptparse.c') diff --git a/source3/popt/poptparse.c b/source3/popt/poptparse.c index 537ec44398..b03deef085 100644 --- a/source3/popt/poptparse.c +++ b/source3/popt/poptparse.c @@ -27,10 +27,10 @@ int poptDupArgv(int argc, const char **argv, nb += strlen(argv[i]) + 1; } - dst = malloc(nb); + dst = (char *)malloc(nb); if (dst == NULL) /* XXX can't happen */ return POPT_ERROR_MALLOC; - argv2 = (void *) dst; + argv2 = (const char **) dst; dst += (argc + 1) * sizeof(*argv); /*@-branchstate@*/ @@ -59,10 +59,10 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) const char * src; char quote = '\0'; int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA; - const char ** argv = malloc(sizeof(*argv) * argvAlloced); + const char ** argv = (const char **)malloc(sizeof(*argv) * argvAlloced); int argc = 0; int buflen = strlen(s) + 1; - char * buf = memset(alloca(buflen), 0, buflen); + char * buf = (char*)memset(alloca(buflen), 0, buflen); int rc = POPT_ERROR_MALLOC; if (argv == NULL) return rc; @@ -86,7 +86,7 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr) buf++, argc++; if (argc == argvAlloced) { argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA; - argv = realloc(argv, sizeof(*argv) * argvAlloced); + argv = (const char **)realloc(argv, sizeof(*argv) * argvAlloced); if (argv == NULL) goto exit; } argv[argc] = buf; @@ -149,7 +149,7 @@ int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ int flags) if (fp == NULL) return POPT_ERROR_NULLARG; - argstr = calloc(maxargvlen, sizeof(*argstr)); + argstr = (char *)calloc(maxargvlen, sizeof(*argstr)); if (argstr == NULL) return POPT_ERROR_MALLOC; while (fgets(line, (int)maxlinelen, fp) != NULL) { @@ -183,7 +183,7 @@ int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ int flags) argvlen += (t = q - p) + (sizeof(" --")-1); if (argvlen >= maxargvlen) { maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; - argstr = realloc(argstr, maxargvlen); + argstr = (char *)realloc(argstr, maxargvlen); if (argstr == NULL) return POPT_ERROR_MALLOC; } strcat(argstr, " --"); @@ -212,7 +212,7 @@ int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ int flags) argvlen += t + (sizeof("' --='")-1); if (argvlen >= maxargvlen) { maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2; - argstr = realloc(argstr, maxargvlen); + argstr = (char *)realloc(argstr, maxargvlen); if (argstr == NULL) return POPT_ERROR_MALLOC; } strcat(argstr, " --"); -- cgit