Annotation of embedaddon/rsync/popt/poptparse.c, revision 1.1
1.1 ! misho 1: /** \ingroup popt
! 2: * \file popt/poptparse.c
! 3: */
! 4:
! 5: /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
! 6: file accompanying popt source distributions, available from
! 7: ftp://ftp.rpm.org/pub/rpm/dist. */
! 8:
! 9: #include "system.h"
! 10:
! 11: #include "poptint.h"
! 12:
! 13: #define POPT_ARGV_ARRAY_GROW_DELTA 5
! 14:
! 15: /*@-boundswrite@*/
! 16: int poptDupArgv(int argc, const char **argv,
! 17: int * argcPtr, const char *** argvPtr)
! 18: {
! 19: size_t nb = (argc + 1) * sizeof(*argv);
! 20: const char ** argv2;
! 21: char * dst;
! 22: int i;
! 23:
! 24: if (argc <= 0 || argv == NULL) /* XXX can't happen */
! 25: return POPT_ERROR_NOARG;
! 26: for (i = 0; i < argc; i++) {
! 27: if (argv[i] == NULL)
! 28: return POPT_ERROR_NOARG;
! 29: nb += strlen(argv[i]) + 1;
! 30: }
! 31:
! 32: dst = malloc(nb);
! 33: if (dst == NULL) /* XXX can't happen */
! 34: return POPT_ERROR_MALLOC;
! 35: argv2 = (void *) dst;
! 36: dst += (argc + 1) * sizeof(*argv);
! 37:
! 38: /*@-branchstate@*/
! 39: for (i = 0; i < argc; i++) {
! 40: argv2[i] = dst;
! 41: dst += strlcpy(dst, argv[i], nb) + 1;
! 42: }
! 43: /*@=branchstate@*/
! 44: argv2[argc] = NULL;
! 45:
! 46: if (argvPtr) {
! 47: *argvPtr = argv2;
! 48: } else {
! 49: free(argv2);
! 50: argv2 = NULL;
! 51: }
! 52: if (argcPtr)
! 53: *argcPtr = argc;
! 54: return 0;
! 55: }
! 56: /*@=boundswrite@*/
! 57:
! 58: /*@-bounds@*/
! 59: int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
! 60: {
! 61: const char * src;
! 62: char quote = '\0';
! 63: int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
! 64: const char ** argv = malloc(sizeof(*argv) * argvAlloced);
! 65: int argc = 0;
! 66: int buflen = strlen(s) + 1;
! 67: char * buf = memset(alloca(buflen), 0, buflen);
! 68: int rc = POPT_ERROR_MALLOC;
! 69:
! 70: if (argv == NULL) return rc;
! 71: argv[argc] = buf;
! 72:
! 73: for (src = s; *src != '\0'; src++) {
! 74: if (quote == *src) {
! 75: quote = '\0';
! 76: } else if (quote != '\0') {
! 77: if (*src == '\\') {
! 78: src++;
! 79: if (!*src) {
! 80: rc = POPT_ERROR_BADQUOTE;
! 81: goto exit;
! 82: }
! 83: if (*src != quote) *buf++ = '\\';
! 84: }
! 85: *buf++ = *src;
! 86: } else if (isSpace(src)) {
! 87: if (*argv[argc] != '\0') {
! 88: buf++, argc++;
! 89: if (argc == argvAlloced) {
! 90: argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
! 91: argv = realloc(argv, sizeof(*argv) * argvAlloced);
! 92: if (argv == NULL) goto exit;
! 93: }
! 94: argv[argc] = buf;
! 95: }
! 96: } else switch (*src) {
! 97: case '"':
! 98: case '\'':
! 99: quote = *src;
! 100: /*@switchbreak@*/ break;
! 101: case '\\':
! 102: src++;
! 103: if (!*src) {
! 104: rc = POPT_ERROR_BADQUOTE;
! 105: goto exit;
! 106: }
! 107: /*@fallthrough@*/
! 108: default:
! 109: *buf++ = *src;
! 110: /*@switchbreak@*/ break;
! 111: }
! 112: }
! 113:
! 114: if (strlen(argv[argc])) {
! 115: argc++, buf++;
! 116: }
! 117:
! 118: rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
! 119:
! 120: exit:
! 121: if (argv) free(argv);
! 122: return rc;
! 123: }
! 124: /*@=bounds@*/
! 125:
! 126: /* still in the dev stage.
! 127: * return values, perhaps 1== file erro
! 128: * 2== line to long
! 129: * 3== umm.... more?
! 130: */
! 131: int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ UNUSED(int flags))
! 132: {
! 133: char line[999];
! 134: char * argstr;
! 135: char * p;
! 136: char * q;
! 137: char * x;
! 138: int t;
! 139: int argvlen = 0;
! 140: size_t maxlinelen = sizeof(line);
! 141: size_t linelen;
! 142: int maxargvlen = 480;
! 143: int linenum = 0;
! 144:
! 145: *argstrp = NULL;
! 146:
! 147: /* | this_is = our_line
! 148: * p q x
! 149: */
! 150:
! 151: if (fp == NULL)
! 152: return POPT_ERROR_NULLARG;
! 153:
! 154: argstr = calloc(maxargvlen, sizeof(*argstr));
! 155: if (argstr == NULL) return POPT_ERROR_MALLOC;
! 156:
! 157: while (fgets(line, (int)maxlinelen, fp) != NULL) {
! 158: linenum++;
! 159: p = line;
! 160:
! 161: /* loop until first non-space char or EOL */
! 162: while( *p != '\0' && isSpace(p) )
! 163: p++;
! 164:
! 165: linelen = strlen(p);
! 166: if (linelen >= maxlinelen-1) {
! 167: free(argstr);
! 168: return POPT_ERROR_OVERFLOW; /* XXX line too long */
! 169: }
! 170:
! 171: if (*p == '\0' || *p == '\n') continue; /* line is empty */
! 172: if (*p == '#') continue; /* comment line */
! 173:
! 174: q = p;
! 175:
! 176: while (*q != '\0' && (!isSpace(q)) && *q != '=')
! 177: q++;
! 178:
! 179: if (isSpace(q)) {
! 180: /* a space after the name, find next non space */
! 181: *q++='\0';
! 182: while( *q != '\0' && isSpace(q) ) q++;
! 183: }
! 184: if (*q == '\0') {
! 185: /* single command line option (ie, no name=val, just name) */
! 186: q[-1] = '\0'; /* kill off newline from fgets() call */
! 187: argvlen += (t = q - p) + (sizeof(" --")-1);
! 188: if (argvlen >= maxargvlen) {
! 189: maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
! 190: argstr = realloc(argstr, maxargvlen);
! 191: if (argstr == NULL) return POPT_ERROR_MALLOC;
! 192: }
! 193: strlcat(argstr, " --", maxargvlen);
! 194: strlcat(argstr, p, maxargvlen);
! 195: continue;
! 196: }
! 197: if (*q != '=')
! 198: continue; /* XXX for now, silently ignore bogus line */
! 199:
! 200: /* *q is an equal sign. */
! 201: *q++ = '\0';
! 202:
! 203: /* find next non-space letter of value */
! 204: while (*q != '\0' && isSpace(q))
! 205: q++;
! 206: if (*q == '\0')
! 207: continue; /* XXX silently ignore missing value */
! 208:
! 209: /* now, loop and strip all ending whitespace */
! 210: x = p + linelen;
! 211: while (isSpace(--x))
! 212: *x = 0; /* null out last char if space (including fgets() NL) */
! 213:
! 214: /* rest of line accept */
! 215: t = x - p;
! 216: argvlen += t + (sizeof("' --='")-1);
! 217: if (argvlen >= maxargvlen) {
! 218: maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
! 219: argstr = realloc(argstr, maxargvlen);
! 220: if (argstr == NULL) return POPT_ERROR_MALLOC;
! 221: }
! 222: strlcat(argstr, " --", maxargvlen);
! 223: strlcat(argstr, p, maxargvlen);
! 224: strlcat(argstr, "=\"", maxargvlen);
! 225: strlcat(argstr, q, maxargvlen);
! 226: strlcat(argstr, "\"", maxargvlen);
! 227: }
! 228:
! 229: *argstrp = argstr;
! 230: return 0;
! 231: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>