00001
00005
00006
00007
00008
00009 #include "system.h"
00010
00011 #define POPT_ARGV_ARRAY_GROW_DELTA 5
00012
00013 int poptDupArgv(int argc, const char **argv,
00014 int * argcPtr, const char *** argvPtr)
00015 {
00016 size_t nb = (argc + 1) * sizeof(*argv);
00017 const char ** argv2;
00018 char * dst;
00019 int i;
00020
00021 for (i = 0; i < argc; i++) {
00022 if (argv[i] == NULL)
00023 return POPT_ERROR_NOARG;
00024 nb += strlen(argv[i]) + 1;
00025 }
00026
00027 dst = malloc(nb);
00028 argv2 = (void *) dst;
00029 dst += (argc + 1) * sizeof(*argv);
00030
00031 for (i = 0; i < argc; i++) {
00032 argv2[i] = dst;
00033 dst += strlen(strcpy(dst, argv[i])) + 1;
00034 }
00035 argv2[argc] = NULL;
00036
00037 *argvPtr = argv2;
00038 *argcPtr = argc;
00039 return 0;
00040 }
00041
00042 int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
00043 {
00044 const char * src;
00045 char quote = '\0';
00046 int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
00047 const char ** argv = malloc(sizeof(*argv) * argvAlloced);
00048 int argc = 0;
00049 int buflen = strlen(s) + 1;
00050 char * buf = memset(alloca(buflen), 0, buflen);
00051
00052 argv[argc] = buf;
00053
00054 for (src = s; *src; src++) {
00055 if (quote == *src) {
00056 quote = '\0';
00057 } else if (quote) {
00058 if (*src == '\\') {
00059 src++;
00060 if (!*src) {
00061 free(argv);
00062 return POPT_ERROR_BADQUOTE;
00063 }
00064 if (*src != quote) *buf++ = '\\';
00065 }
00066 *buf++ = *src;
00067 } else if (isspace(*src)) {
00068 if (*argv[argc]) {
00069 buf++, argc++;
00070 if (argc == argvAlloced) {
00071 argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
00072 argv = realloc(argv, sizeof(*argv) * argvAlloced);
00073 }
00074 argv[argc] = buf;
00075 }
00076 } else switch (*src) {
00077 case '"':
00078 case '\'':
00079 quote = *src;
00080 break;
00081 case '\\':
00082 src++;
00083 if (!*src) {
00084 free(argv);
00085 return POPT_ERROR_BADQUOTE;
00086 }
00087
00088 default:
00089 *buf++ = *src;
00090 break;
00091 }
00092 }
00093
00094 if (strlen(argv[argc])) {
00095 argc++, buf++;
00096 }
00097
00098 (void) poptDupArgv(argc, argv, argcPtr, argvPtr);
00099
00100 free(argv);
00101
00102 return 0;
00103 }