popt  1.16
poptparse.c
Go to the documentation of this file.
1 
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) {
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  /*@switchbreak@*/ 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  /*@switchbreak@*/ 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@*/ 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 }
stpcpy
static char * stpcpy(char *dest, const char *src)
Definition: system.h:69
POPT_ARGV_ARRAY_GROW_DELTA
#define POPT_ARGV_ARRAY_GROW_DELTA
Definition: poptparse.c:11
POPT_ERROR_NULLARG
#define POPT_ERROR_NULLARG
Definition: popt.h:101
poptConfigFileToString
int poptConfigFileToString(FILE *fp, char **argstrp, int flags)
Definition: poptparse.c:131
POPT_ERROR_NOARG
#define POPT_ERROR_NOARG
Definition: popt.h:93
POPT_ERROR_OVERFLOW
#define POPT_ERROR_OVERFLOW
Definition: popt.h:99
poptParseArgvString
int poptParseArgvString(const char *s, int *argcPtr, const char ***argvPtr)
Definition: poptparse.c:54
poptDupArgv
int poptDupArgv(int argc, const char **argv, int *argcPtr, const char ***argvPtr)
Definition: poptparse.c:13
UNUSED
#define UNUSED(x)
Definition: system.h:105
system.h
POPT_ERROR_MALLOC
#define POPT_ERROR_MALLOC
Definition: popt.h:102
_isspaceptr
#define _isspaceptr(_chp)
Definition: system.h:21
POPT_ERROR_BADQUOTE
#define POPT_ERROR_BADQUOTE
Definition: popt.h:96

Generated for popt by  doxygen 1.8.17