source: trunk/third/ORBit/popt/poptparse.c @ 15271

Revision 15271, 2.4 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r15270, which included commits to RCS files with non-trunk default branches.
Line 
1/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
2   file accompanying popt source distributions, available from
3   ftp://ftp.redhat.com/pub/code/popt */
4
5#include "system.h"
6#include "poptint.h"
7
8#define POPT_ARGV_ARRAY_GROW_DELTA 5
9
10int poptDupArgv(int argc, const char **argv,
11                int * argcPtr, const char *** argvPtr)
12{
13    size_t nb = (argc + 1) * sizeof(*argv);
14    const char ** argv2;
15    char * dst;
16    int i;
17
18    for (i = 0; i < argc; i++) {
19        if (argv[i] == NULL)
20            return POPT_ERROR_NOARG;
21        nb += strlen(argv[i]) + 1;
22    }
23       
24    dst = malloc(nb);
25    argv2 = (void *) dst;
26    dst += (argc + 1) * sizeof(*argv);
27
28    for (i = 0; i < argc; i++) {
29        argv2[i] = dst;
30        dst += strlen(strcpy(dst, argv[i])) + 1;
31    }
32    argv2[argc] = NULL;
33
34    *argvPtr = argv2;
35    *argcPtr = argc;
36    return 0;
37}
38
39int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
40{
41    const char * src;
42    char quote = '\0';
43    int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
44    const char ** argv = malloc(sizeof(*argv) * argvAlloced);
45    int argc = 0;
46    int buflen = strlen(s) + 1;
47    char * buf = memset(alloca(buflen), 0, buflen);
48
49    argv[argc] = buf;
50
51    for (src = s; *src; src++) {
52        if (quote == *src) {
53            quote = '\0';
54        } else if (quote) {
55            if (*src == '\\') {
56                src++;
57                if (!*src) {
58                    free(argv);
59                    return POPT_ERROR_BADQUOTE;
60                }
61                if (*src != quote) *buf++ = '\\';
62            }
63            *buf++ = *src;
64        } else if (isspace(*src)) {
65            if (*argv[argc]) {
66                buf++, argc++;
67                if (argc == argvAlloced) {
68                    argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
69                    argv = realloc(argv, sizeof(*argv) * argvAlloced);
70                }
71                argv[argc] = buf;
72            }
73        } else switch (*src) {
74          case '"':
75          case '\'':
76            quote = *src;
77            break;
78          case '\\':
79            src++;
80            if (!*src) {
81                free(argv);
82                return POPT_ERROR_BADQUOTE;
83            }
84            /*@fallthrough@*/
85          default:
86            *buf++ = *src;
87            break;
88        }
89    }
90
91    if (strlen(argv[argc])) {
92        argc++, buf++;
93    }
94
95#if 0
96    {   char * dst = malloc((argc + 1) * sizeof(*argv) + (buf - argv[0]));
97        const char ** argv2 = (void *) dst;
98        int i;
99
100        dst += (argc + 1) * sizeof(*argv);
101        memcpy(argv2, argv, argc * sizeof(*argv));
102        argv2[argc] = NULL;
103        memcpy(dst, argv[0], buf - argv[0]);
104
105        for (i = 0; i < argc; i++)
106            argv2[i] = dst + (argv[i] - argv[0]);
107
108        *argvPtr = argv2;
109        *argcPtr = argc;
110    }
111#else
112    (void) poptDupArgv(argc, argv, argcPtr, argvPtr);
113#endif
114
115    free(argv);
116
117    return 0;
118}
Note: See TracBrowser for help on using the repository browser.