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 if (argc <= 0 || argv == NULL)
00022 return POPT_ERROR_NOARG;
00023 for (i = 0; i < argc; i++) {
00024 if (argv[i] == NULL)
00025 return POPT_ERROR_NOARG;
00026 nb += strlen(argv[i]) + 1;
00027 }
00028
00029 dst = malloc(nb);
00030 if (dst == NULL)
00031 return POPT_ERROR_MALLOC;
00032 argv2 = (void *) dst;
00033 dst += (argc + 1) * sizeof(*argv);
00034
00035
00036 for (i = 0; i < argc; i++) {
00037 argv2[i] = dst;
00038 dst += strlen(strcpy(dst, argv[i])) + 1;
00039 }
00040
00041 argv2[argc] = NULL;
00042
00043 if (argvPtr) {
00044 *argvPtr = argv2;
00045 } else {
00046 free(argv2);
00047 argv2 = NULL;
00048 }
00049 if (argcPtr)
00050 *argcPtr = argc;
00051 return 0;
00052 }
00053
00054 int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
00055 {
00056 const char * src;
00057 char quote = '\0';
00058 int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
00059 const char ** argv = malloc(sizeof(*argv) * argvAlloced);
00060 int argc = 0;
00061 int buflen = strlen(s) + 1;
00062 char * buf = memset(alloca(buflen), 0, buflen);
00063 int rc = POPT_ERROR_MALLOC;
00064
00065 if (argv == NULL) return rc;
00066 argv[argc] = buf;
00067
00068 for (src = s; *src != '\0'; src++) {
00069 if (quote == *src) {
00070 quote = '\0';
00071 } else if (quote != '\0') {
00072 if (*src == '\\') {
00073 src++;
00074 if (!*src) {
00075 rc = POPT_ERROR_BADQUOTE;
00076 goto exit;
00077 }
00078 if (*src != quote) *buf++ = '\\';
00079 }
00080 *buf++ = *src;
00081 } else if (isspace(*src)) {
00082 if (*argv[argc] != '\0') {
00083 buf++, argc++;
00084 if (argc == argvAlloced) {
00085 argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
00086 argv = realloc(argv, sizeof(*argv) * argvAlloced);
00087 if (argv == NULL) goto exit;
00088 }
00089 argv[argc] = buf;
00090 }
00091 } else switch (*src) {
00092 case '"':
00093 case '\'':
00094 quote = *src;
00095 break;
00096 case '\\':
00097 src++;
00098 if (!*src) {
00099 rc = POPT_ERROR_BADQUOTE;
00100 goto exit;
00101 }
00102
00103 default:
00104 *buf++ = *src;
00105 break;
00106 }
00107 }
00108
00109 if (strlen(argv[argc])) {
00110 argc++, buf++;
00111 }
00112
00113 rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
00114
00115 exit:
00116 if (argv) free(argv);
00117 return rc;
00118 }