X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Firssi%2Fsrc%2Flib-popt%2Fpoptparse.c;fp=apps%2Firssi%2Fsrc%2Flib-popt%2Fpoptparse.c;h=eb2a6721633f9d931722fa22239e1e7aeca9736e;hb=23c5df1c8b0bfe539d3fa65802186e6e09e044aa;hp=0000000000000000000000000000000000000000;hpb=0f9738ce962b8498bbed0a75d5fb6fa127e3577f;p=silc.git diff --git a/apps/irssi/src/lib-popt/poptparse.c b/apps/irssi/src/lib-popt/poptparse.c new file mode 100644 index 00000000..eb2a6721 --- /dev/null +++ b/apps/irssi/src/lib-popt/poptparse.c @@ -0,0 +1,98 @@ +/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING + file accompanying popt source distributions, available from + ftp://ftp.redhat.com/pub/code/popt */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +#include "popt.h" + +static const int poptArgvArrayGrowDelta = 5; + +int poptParseArgvString(const char * s, int * argcPtr, char *** argvPtr) { + char * buf, * bufStart, * dst; + const char * src; + char quote = '\0'; + int argvAlloced = poptArgvArrayGrowDelta; + char ** argv = malloc(sizeof(*argv) * argvAlloced); + char ** argv2; + int argc = 0; + int i, buflen; + + buflen = strlen(s) + 1; + bufStart = buf = malloc(buflen); + memset(buf, '\0', buflen); + + src = s; + argv[argc] = buf; + + while (*src) { + if (quote == *src) { + quote = '\0'; + } else if (quote) { + if (*src == '\\') { + src++; + if (!*src) { + free(argv); + free(bufStart); + return POPT_ERROR_BADQUOTE; + } + if (*src != quote) *buf++ = '\\'; + } + *buf++ = *src; + } else if (isspace(*src)) { + if (*argv[argc]) { + buf++, argc++; + if (argc == argvAlloced) { + argvAlloced += poptArgvArrayGrowDelta; + argv = realloc(argv, sizeof(*argv) * argvAlloced); + } + argv[argc] = buf; + } + } else switch (*src) { + case '"': + case '\'': + quote = *src; + break; + case '\\': + src++; + if (!*src) { + free(argv); + free(bufStart); + return POPT_ERROR_BADQUOTE; + } + /* fallthrough */ + default: + *buf++ = *src; + } + + src++; + } + + if (strlen(argv[argc])) { + argc++, buf++; + } + + dst = malloc(argc * sizeof(*argv) + (buf - bufStart)); + argv2 = (void *) dst; + dst += argc * sizeof(*argv); + memcpy(argv2, argv, argc * sizeof(*argv)); + memcpy(dst, bufStart, buf - bufStart); + + for (i = 0; i < argc; i++) { + argv2[i] = dst + (argv[i] - bufStart); + } + + free(argv); + + *argvPtr = argv2; + *argcPtr = argc; + + free(bufStart); + return 0; +}