"Fossies" - the Fresh Open Source Software Archive

Member "popt-1.18/src/poptparse.c" (16 Apr 2020, 5258 Bytes) of package /linux/misc/popt-1.18.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "poptparse.c" see the Fossies "Dox" file reference documentation.

    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 #define POPT_ARGV_ARRAY_GROW_DELTA 5
   12 
   13 int poptDupArgv(int argc, const char **argv,
   14         int * argcPtr, const char *** argvPtr)
   15 {
   16     size_t nb = (argc + 1) * sizeof(*argv);
   17     const char ** argv2;
   18     char * dst;
   19     int i;
   20 
   21     if (argc <= 0 || argv == NULL)  /* XXX can't happen */
   22     return POPT_ERROR_NOARG;
   23     for (i = 0; i < argc; i++) {
   24     if (argv[i] == NULL)
   25         return POPT_ERROR_NOARG;
   26     nb += strlen(argv[i]) + 1;
   27     }
   28     
   29     dst = malloc(nb);
   30     if (dst == NULL)            /* XXX can't happen */
   31     return POPT_ERROR_MALLOC;
   32     argv2 = (void *) dst;
   33     dst += (argc + 1) * sizeof(*argv);
   34     *dst = '\0';
   35 
   36     for (i = 0; i < argc; i++) {
   37     argv2[i] = dst;
   38     dst = stpcpy(dst, argv[i]);
   39     dst++;  /* trailing NUL */
   40     }
   41     argv2[argc] = NULL;
   42 
   43     if (argvPtr) {
   44     *argvPtr = argv2;
   45     } else {
   46     free(argv2);
   47     argv2 = NULL;
   48     }
   49     if (argcPtr)
   50     *argcPtr = argc;
   51     return 0;
   52 }
   53 
   54 int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
   55 {
   56     const char * src;
   57     char quote = '\0';
   58     int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
   59     const char ** argv = malloc(sizeof(*argv) * argvAlloced);
   60     int argc = 0;
   61     size_t buflen = strlen(s) + 1;
   62     char * buf, * bufOrig = NULL;
   63     int rc = POPT_ERROR_MALLOC;
   64 
   65     if (argv == NULL) return rc;
   66     buf = bufOrig = calloc((size_t)1, buflen);
   67     if (buf == NULL) {
   68     free(argv);
   69     return rc;
   70     }
   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 (_isspaceptr(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         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         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 (bufOrig) free(bufOrig);
  122     if (argv) free(argv);
  123     return rc;
  124 }
  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,
  132         UNUSED(int flags))
  133 {
  134     char line[999];
  135     char * argstr;
  136     char * p;
  137     char * q;
  138     char * x;
  139     size_t t;
  140     size_t argvlen = 0;
  141     size_t maxlinelen = sizeof(line);
  142     size_t linelen;
  143     size_t maxargvlen = (size_t)480;
  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     p = line;
  159 
  160     /* loop until first non-space char or EOL */
  161     while( *p != '\0' && _isspaceptr(p) )
  162         p++;
  163 
  164     linelen = strlen(p);
  165     if (linelen >= maxlinelen-1) {
  166         free(argstr);
  167         return POPT_ERROR_OVERFLOW; /* XXX line too long */
  168     }
  169 
  170     if (*p == '\0' || *p == '\n') continue; /* line is empty */
  171     if (*p == '#') continue;        /* comment line */
  172 
  173     q = p;
  174 
  175     while (*q != '\0' && (!_isspaceptr(q)) && *q != '=')
  176         q++;
  177 
  178     if (_isspaceptr(q)) {
  179         /* a space after the name, find next non space */
  180         *q++='\0';
  181         while( *q != '\0' && _isspaceptr(q) ) q++;
  182     }
  183     if (*q == '\0') {
  184         /* single command line option (ie, no name=val, just name) */
  185         q[-1] = '\0';       /* kill off newline from fgets() call */
  186         argvlen += (t = (size_t)(q - p)) + (sizeof(" --")-1);
  187         if (argvlen >= maxargvlen) {
  188         maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
  189         argstr = realloc(argstr, maxargvlen);
  190         if (argstr == NULL) return POPT_ERROR_MALLOC;
  191         }
  192         strcat(argstr, " --");
  193         strcat(argstr, p);
  194         continue;
  195     }
  196     if (*q != '=')
  197         continue;   /* XXX for now, silently ignore bogus line */
  198         
  199     /* *q is an equal sign. */
  200     *q++ = '\0';
  201 
  202     /* find next non-space letter of value */
  203     while (*q != '\0' && _isspaceptr(q))
  204         q++;
  205     if (*q == '\0')
  206         continue;   /* XXX silently ignore missing value */
  207 
  208     /* now, loop and strip all ending whitespace */
  209     x = p + linelen;
  210     while (_isspaceptr(--x))
  211         *x = '\0';  /* null out last char if space (including fgets() NL) */
  212 
  213     /* rest of line accept */
  214     t = (size_t)(x - p);
  215     argvlen += t + (sizeof("' --='")-1);
  216     if (argvlen >= maxargvlen) {
  217         maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
  218         argstr = realloc(argstr, maxargvlen);
  219         if (argstr == NULL) return POPT_ERROR_MALLOC;
  220     }
  221     strcat(argstr, " --");
  222     strcat(argstr, p);
  223     strcat(argstr, "=\"");
  224     strcat(argstr, q);
  225     strcat(argstr, "\"");
  226     }
  227 
  228     *argstrp = argstr;
  229     return 0;
  230 }