LCOV - code coverage report
Current view: top level - third_party/popt - poptparse.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 47 135 34.8 %
Date: 2024-04-21 15:09:00 Functions: 2 3 66.7 %

          Line data    Source code
       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           2 : int poptDupArgv(int argc, const char **argv,
      14             :                 int * argcPtr, const char *** argvPtr)
      15             : {
      16           2 :     size_t nb = (argc + 1) * sizeof(*argv);
      17             :     const char ** argv2;
      18             :     char * dst;
      19             :     int i;
      20             : 
      21           2 :     if (argc <= 0 || argv == NULL)   /* XXX can't happen */
      22           0 :         return POPT_ERROR_NOARG;
      23           4 :     for (i = 0; i < argc; i++) {
      24           2 :         if (argv[i] == NULL)
      25           0 :             return POPT_ERROR_NOARG;
      26           2 :         nb += strlen(argv[i]) + 1;
      27             :     }
      28             :         
      29           2 :     dst = malloc(nb);
      30           2 :     if (dst == NULL)                    /* XXX can't happen */
      31           0 :         return POPT_ERROR_MALLOC;
      32           2 :     argv2 = (void *) dst;
      33           2 :     dst += (argc + 1) * sizeof(*argv);
      34           2 :     *dst = '\0';
      35             : 
      36           4 :     for (i = 0; i < argc; i++) {
      37           2 :         argv2[i] = dst;
      38           2 :         dst = stpcpy(dst, argv[i]);
      39           2 :         dst++;  /* trailing NUL */
      40             :     }
      41           2 :     argv2[argc] = NULL;
      42             : 
      43           2 :     if (argvPtr) {
      44           2 :         *argvPtr = argv2;
      45             :     } else {
      46           0 :         free(argv2);
      47           0 :         argv2 = NULL;
      48             :     }
      49           2 :     if (argcPtr)
      50           2 :         *argcPtr = argc;
      51           2 :     return 0;
      52             : }
      53             : 
      54           2 : int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
      55             : {
      56             :     const char * src;
      57           2 :     char quote = '\0';
      58           2 :     int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
      59           2 :     const char ** argv = malloc(sizeof(*argv) * argvAlloced);
      60           2 :     int argc = 0;
      61           2 :     size_t buflen = strlen(s) + 1;
      62           2 :     char * buf, * bufOrig = NULL;
      63           2 :     int rc = POPT_ERROR_MALLOC;
      64             : 
      65           2 :     if (argv == NULL) return rc;
      66           2 :     buf = bufOrig = calloc((size_t)1, buflen);
      67           2 :     if (buf == NULL) {
      68           0 :         free(argv);
      69           0 :         return rc;
      70             :     }
      71           2 :     argv[argc] = buf;
      72             : 
      73          14 :     for (src = s; *src != '\0'; src++) {
      74          12 :         if (quote == *src) {
      75           0 :             quote = '\0';
      76          12 :         } else if (quote != '\0') {
      77           0 :             if (*src == '\\') {
      78           0 :                 src++;
      79           0 :                 if (!*src) {
      80           0 :                     rc = POPT_ERROR_BADQUOTE;
      81           0 :                     goto exit;
      82             :                 }
      83           0 :                 if (*src != quote) *buf++ = '\\';
      84             :             }
      85           0 :             *buf++ = *src;
      86          12 :         } else if (_isspaceptr(src)) {
      87           0 :             if (*argv[argc] != '\0') {
      88           0 :                 buf++, argc++;
      89           0 :                 if (argc == argvAlloced) {
      90           0 :                     argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
      91           0 :                     argv = realloc(argv, sizeof(*argv) * argvAlloced);
      92           0 :                     if (argv == NULL) goto exit;
      93             :                 }
      94           0 :                 argv[argc] = buf;
      95             :             }
      96          12 :         } else switch (*src) {
      97           0 :           case '"':
      98             :           case '\'':
      99           0 :             quote = *src;
     100           0 :             /*@switchbreak@*/ break;
     101           0 :           case '\\':
     102           0 :             src++;
     103           0 :             if (!*src) {
     104           0 :                 rc = POPT_ERROR_BADQUOTE;
     105           0 :                 goto exit;
     106             :             }
     107             :             /*@fallthrough@*/
     108             :           default:
     109          12 :             *buf++ = *src;
     110          12 :             /*@switchbreak@*/ break;
     111             :         }
     112             :     }
     113             : 
     114           2 :     if (strlen(argv[argc])) {
     115           2 :         argc++, buf++;
     116             :     }
     117             : 
     118           2 :     rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
     119             : 
     120           2 : exit:
     121           2 :     if (bufOrig) free(bufOrig);
     122           2 :     if (argv) free(argv);
     123           2 :     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           0 : int poptConfigFileToString(FILE *fp, char ** argstrp,
     132             :                 /*@unused@*/ 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           0 :     size_t argvlen = 0;
     141           0 :     size_t maxlinelen = sizeof(line);
     142             :     size_t linelen;
     143           0 :     size_t maxargvlen = (size_t)480;
     144             : 
     145           0 :     *argstrp = NULL;
     146             : 
     147             :     /*   |   this_is   =   our_line
     148             :      *       p             q      x
     149             :      */
     150             : 
     151           0 :     if (fp == NULL)
     152           0 :         return POPT_ERROR_NULLARG;
     153             : 
     154           0 :     argstr = calloc(maxargvlen, sizeof(*argstr));
     155           0 :     if (argstr == NULL) return POPT_ERROR_MALLOC;
     156             : 
     157           0 :     while (fgets(line, (int)maxlinelen, fp) != NULL) {
     158           0 :         p = line;
     159             : 
     160             :         /* loop until first non-space char or EOL */
     161           0 :         while( *p != '\0' && _isspaceptr(p) )
     162           0 :             p++;
     163             : 
     164           0 :         linelen = strlen(p);
     165           0 :         if (linelen >= maxlinelen-1) {
     166           0 :             free(argstr);
     167           0 :             return POPT_ERROR_OVERFLOW; /* XXX line too long */
     168             :         }
     169             : 
     170           0 :         if (*p == '\0' || *p == '\n') continue; /* line is empty */
     171           0 :         if (*p == '#') continue;                /* comment line */
     172             : 
     173           0 :         q = p;
     174             : 
     175           0 :         while (*q != '\0' && (!_isspaceptr(q)) && *q != '=')
     176           0 :             q++;
     177             : 
     178           0 :         if (_isspaceptr(q)) {
     179             :             /* a space after the name, find next non space */
     180           0 :             *q++='\0';
     181           0 :             while( *q != '\0' && _isspaceptr(q) ) q++;
     182             :         }
     183           0 :         if (*q == '\0') {
     184             :             /* single command line option (ie, no name=val, just name) */
     185           0 :             q[-1] = '\0';               /* kill off newline from fgets() call */
     186           0 :             argvlen += (t = (size_t)(q - p)) + (sizeof(" --")-1);
     187           0 :             if (argvlen >= maxargvlen) {
     188           0 :                 maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
     189           0 :                 argstr = realloc(argstr, maxargvlen);
     190           0 :                 if (argstr == NULL) return POPT_ERROR_MALLOC;
     191             :             }
     192           0 :             strcat(argstr, " --");
     193           0 :             strcat(argstr, p);
     194           0 :             continue;
     195             :         }
     196           0 :         if (*q != '=')
     197           0 :             continue;   /* XXX for now, silently ignore bogus line */
     198             : 
     199             :         /* *q is an equal sign. */
     200           0 :         *q++ = '\0';
     201             : 
     202             :         /* find next non-space letter of value */
     203           0 :         while (*q != '\0' && _isspaceptr(q))
     204           0 :             q++;
     205           0 :         if (*q == '\0')
     206           0 :             continue;   /* XXX silently ignore missing value */
     207             : 
     208             :         /* now, loop and strip all ending whitespace */
     209           0 :         x = p + linelen;
     210           0 :         while (_isspaceptr(--x))
     211           0 :             *x = '\0';  /* null out last char if space (including fgets() NL) */
     212             : 
     213             :         /* rest of line accept */
     214           0 :         t = (size_t)(x - p);
     215           0 :         argvlen += t + (sizeof("' --='")-1);
     216           0 :         if (argvlen >= maxargvlen) {
     217           0 :             maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
     218           0 :             argstr = realloc(argstr, maxargvlen);
     219           0 :             if (argstr == NULL) return POPT_ERROR_MALLOC;
     220             :         }
     221           0 :         strcat(argstr, " --");
     222           0 :         strcat(argstr, p);
     223           0 :         strcat(argstr, "=\"");
     224           0 :         strcat(argstr, q);
     225           0 :         strcat(argstr, "\"");
     226             :     }
     227             : 
     228           0 :     *argstrp = argstr;
     229           0 :     return 0;
     230             : }

Generated by: LCOV version 1.14