Annotation of embedaddon/rsync/popt/poptparse.c, revision 1.1.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>