popt  1.16
popt.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 #undef MYDEBUG
10 
11 #include "system.h"
12 
13 #if defined(__LCLINT__)
14 /*@-declundef -exportheader @*/
15 extern long long int strtoll(const char *nptr, /*@null@*/ char **endptr,
16  int base)
17  /*@modifies *endptr@*/;
18 /*@=declundef =exportheader @*/
19 #endif
20 
21 #ifdef HAVE_FLOAT_H
22 #include <float.h>
23 #endif
24 #include <math.h>
25 
26 #include "poptint.h"
27 
28 #ifdef MYDEBUG
29 /*@unchecked@*/
30 int _popt_debug = 0;
31 #endif
32 
33 /*@unchecked@*/
34 unsigned int _poptArgMask = POPT_ARG_MASK;
35 /*@unchecked@*/
37 
38 #if !defined(HAVE_STRERROR) && !defined(__LCLINT__)
39 static char * strerror(int errno)
40 {
41  extern int sys_nerr;
42  extern char * sys_errlist[];
43 
44  if ((0 <= errno) && (errno < sys_nerr))
45  return sys_errlist[errno];
46  else
47  return POPT_("unknown errno");
48 }
49 #endif
50 
51 #ifdef MYDEBUG
52 /*@unused@*/
53 static void prtcon(const char *msg, poptContext con)
54 {
55  if (msg) fprintf(stderr, "%s", msg);
56  fprintf(stderr, "\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n",
57  con, con->os,
58  (con->os->nextCharArg ? con->os->nextCharArg : ""),
59  (con->os->nextArg ? con->os->nextArg : ""),
60  con->os->next,
61  (con->os->argv && con->os->argv[con->os->next]
62  ? con->os->argv[con->os->next] : ""));
63 }
64 #endif
65 
66 void poptSetExecPath(poptContext con, const char * path, int allowAbsolute)
67 {
68  con->execPath = _free(con->execPath);
69  con->execPath = xstrdup(path);
70  con->execAbsolute = allowAbsolute;
71  return;
72 }
73 
74 static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt)
75  /*@globals internalState@*/
76  /*@modifies internalState@*/
77 {
78  if (opt != NULL)
79  for (; opt->longName || opt->shortName || opt->arg; opt++) {
80  poptArg arg = { .ptr = opt->arg };
81  if (arg.ptr)
82  switch (poptArgType(opt)) {
83  case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
84  poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
85  invokeCallbacksPRE(con, arg.opt);
86  /*@switchbreak@*/ break;
87  case POPT_ARG_CALLBACK: /* Perform callback. */
88  if (!CBF_ISSET(opt, PRE))
89  /*@switchbreak@*/ break;
90 /*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */
91  arg.cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip);
92 /*@=noeffectuncon @*/
93  /*@switchbreak@*/ break;
94  }
95  }
96 }
97 
98 static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt)
99  /*@globals internalState@*/
100  /*@modifies internalState@*/
101 {
102  if (opt != NULL)
103  for (; opt->longName || opt->shortName || opt->arg; opt++) {
104  poptArg arg = { .ptr = opt->arg };
105  if (arg.ptr)
106  switch (poptArgType(opt)) {
107  case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
108  poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
109  invokeCallbacksPOST(con, arg.opt);
110  /*@switchbreak@*/ break;
111  case POPT_ARG_CALLBACK: /* Perform callback. */
112  if (!CBF_ISSET(opt, POST))
113  /*@switchbreak@*/ break;
114 /*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */
115  arg.cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip);
116 /*@=noeffectuncon @*/
117  /*@switchbreak@*/ break;
118  }
119  }
120 }
121 
123  const struct poptOption * opt,
124  const struct poptOption * myOpt,
125  /*@null@*/ const void * myData, int shorty)
126  /*@globals internalState@*/
127  /*@modifies internalState@*/
128 {
129  const struct poptOption * cbopt = NULL;
130  poptArg cbarg = { .ptr = NULL };
131 
132  if (opt != NULL)
133  for (; opt->longName || opt->shortName || opt->arg; opt++) {
134  poptArg arg = { .ptr = opt->arg };
135  switch (poptArgType(opt)) {
136  case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
137  poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
138  if (opt->arg != NULL)
139  invokeCallbacksOPTION(con, opt->arg, myOpt, myData, shorty);
140  /*@switchbreak@*/ break;
141  case POPT_ARG_CALLBACK: /* Save callback info. */
142  if (CBF_ISSET(opt, SKIPOPTION))
143  /*@switchbreak@*/ break;
144  cbopt = opt;
145  cbarg.ptr = opt->arg;
146  /*@switchbreak@*/ break;
147  default: /* Perform callback on matching option. */
148  if (cbopt == NULL || cbarg.cb == NULL)
149  /*@switchbreak@*/ break;
150  if ((myOpt->shortName && opt->shortName && shorty &&
151  myOpt->shortName == opt->shortName)
152  || (myOpt->longName != NULL && opt->longName != NULL &&
153  !strcmp(myOpt->longName, opt->longName)))
154  { const void *cbData = (cbopt->descrip ? cbopt->descrip : myData);
155 /*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */
156  cbarg.cb(con, POPT_CALLBACK_REASON_OPTION,
157  myOpt, con->os->nextArg, cbData);
158 /*@=noeffectuncon @*/
159  /* Terminate (unless explcitly continuing). */
160  if (!CBF_ISSET(cbopt, CONTINUE))
161  return;
162  }
163  /*@switchbreak@*/ break;
164  }
165  }
166 }
167 
168 poptContext poptGetContext(const char * name, int argc, const char ** argv,
169  const struct poptOption * options, unsigned int flags)
170 {
171  poptContext con = malloc(sizeof(*con));
172 
173  if (con == NULL) return NULL; /* XXX can't happen */
174  memset(con, 0, sizeof(*con));
175 
176  con->os = con->optionStack;
177  con->os->argc = argc;
178 /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */
179  con->os->argv = argv;
180 /*@=dependenttrans =assignexpose@*/
181  con->os->argb = NULL;
182 
183  if (!(flags & POPT_CONTEXT_KEEP_FIRST))
184  con->os->next = 1; /* skip argv[0] */
185 
186  con->leftovers = calloc( (size_t)(argc + 1), sizeof(*con->leftovers) );
187 /*@-dependenttrans -assignexpose@*/ /* FIX: W2DO? */
188  con->options = options;
189 /*@=dependenttrans =assignexpose@*/
190  con->aliases = NULL;
191  con->numAliases = 0;
192  con->flags = flags;
193  con->execs = NULL;
194  con->numExecs = 0;
195  con->finalArgvAlloced = argc * 2;
196  con->finalArgv = calloc( (size_t)con->finalArgvAlloced, sizeof(*con->finalArgv) );
197  con->execAbsolute = 1;
198  con->arg_strip = NULL;
199 
200  if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER"))
202 
203  if (name)
204  con->appName = xstrdup(name);
205 
206  invokeCallbacksPRE(con, con->options);
207 
208  return con;
209 }
210 
211 static void cleanOSE(/*@special@*/ struct optionStackEntry *os)
212  /*@uses os @*/
213  /*@releases os->nextArg, os->argv, os->argb @*/
214  /*@modifies os @*/
215 {
216  os->nextArg = _free(os->nextArg);
217  os->argv = _free(os->argv);
218  os->argb = PBM_FREE(os->argb);
219 }
220 
222 {
223  int i;
224 
225  if (con == NULL) return;
226  while (con->os > con->optionStack) {
227  cleanOSE(con->os--);
228  }
229  con->os->argb = PBM_FREE(con->os->argb);
230  con->os->currAlias = NULL;
231  con->os->nextCharArg = NULL;
232  con->os->nextArg = NULL;
233  con->os->next = 1; /* skip argv[0] */
234 
235  con->numLeftovers = 0;
236  con->nextLeftover = 0;
237  con->restLeftover = 0;
238  con->doExec = NULL;
239 
240  if (con->finalArgv != NULL)
241  for (i = 0; i < con->finalArgvCount; i++) {
242 /*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */
243  con->finalArgv[i] = _free(con->finalArgv[i]);
244 /*@=unqualifiedtrans@*/
245  }
246 
247  con->finalArgvCount = 0;
248  con->arg_strip = PBM_FREE(con->arg_strip);
249 /*@-nullstate@*/ /* FIX: con->finalArgv != NULL */
250  return;
251 /*@=nullstate@*/
252 }
253 
254 /* Only one of longName, shortName should be set, not both. */
255 static int handleExec(/*@special@*/ poptContext con,
256  /*@null@*/ const char * longName, char shortName)
257  /*@uses con->execs, con->numExecs, con->flags, con->doExec,
258  con->finalArgv, con->finalArgvAlloced, con->finalArgvCount @*/
259  /*@modifies con @*/
260 {
261  poptItem item;
262  int i;
263 
264  if (con->execs == NULL || con->numExecs <= 0) /* XXX can't happen */
265  return 0;
266 
267  for (i = con->numExecs - 1; i >= 0; i--) {
268  item = con->execs + i;
269  if (longName && !(item->option.longName &&
270  !strcmp(longName, item->option.longName)))
271  continue;
272  else if (shortName != item->option.shortName)
273  continue;
274  break;
275  }
276  if (i < 0) return 0;
277 
278 
279  if (con->flags & POPT_CONTEXT_NO_EXEC)
280  return 1;
281 
282  if (con->doExec == NULL) {
283  con->doExec = con->execs + i;
284  return 1;
285  }
286 
287  /* We already have an exec to do; remember this option for next
288  time 'round */
289  if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) {
290  con->finalArgvAlloced += 10;
291  con->finalArgv = realloc(con->finalArgv,
292  sizeof(*con->finalArgv) * con->finalArgvAlloced);
293  }
294 
295  i = con->finalArgvCount++;
296  if (con->finalArgv != NULL) /* XXX can't happen */
297  { char *s = malloc((longName ? strlen(longName) : 0) + sizeof("--"));
298  if (s != NULL) { /* XXX can't happen */
299  con->finalArgv[i] = s;
300  *s++ = '-';
301  if (longName)
302  s = stpcpy( stpcpy(s, "-"), longName);
303  else
304  *s++ = shortName;
305  *s = '\0';
306  } else
307  con->finalArgv[i] = NULL;
308  }
309 
310  return 1;
311 }
312 
320 static int
321 longOptionStrcmp(const struct poptOption * opt,
322  /*@null@*/ const char * longName, size_t longNameLen)
323  /*@*/
324 {
325  const char * optLongName = opt->longName;
326  int rc;
327 
328  if (optLongName == NULL || longName == NULL) /* XXX can't heppen */
329  return 0;
330 
331  if (F_ISSET(opt, TOGGLE)) {
332  if (optLongName[0] == 'n' && optLongName[1] == 'o') {
333  optLongName += sizeof("no") - 1;
334  if (optLongName[0] == '-')
335  optLongName++;
336  }
337  if (longName[0] == 'n' && longName[1] == 'o') {
338  longName += sizeof("no") - 1;
339  longNameLen -= sizeof("no") - 1;
340  if (longName[0] == '-') {
341  longName++;
342  longNameLen--;
343  }
344  }
345  }
346  rc = (int)(strlen(optLongName) == longNameLen);
347  if (rc)
348  rc = (int)(strncmp(optLongName, longName, longNameLen) == 0);
349  return rc;
350 }
351 
352 /* Only one of longName, shortName may be set at a time */
353 static int handleAlias(/*@special@*/ poptContext con,
354  /*@null@*/ const char * longName, size_t longNameLen,
355  char shortName,
356  /*@exposed@*/ /*@null@*/ const char * nextArg)
357  /*@uses con->aliases, con->numAliases, con->optionStack, con->os,
358  con->os->currAlias, con->os->currAlias->option.longName @*/
359  /*@modifies con @*/
360 {
361  poptItem item = con->os->currAlias;
362  int rc;
363  int i;
364 
365  if (item) {
366  if (longName && item->option.longName != NULL
367  && longOptionStrcmp(&item->option, longName, longNameLen))
368  return 0;
369  else
370  if (shortName && shortName == item->option.shortName)
371  return 0;
372  }
373 
374  if (con->aliases == NULL || con->numAliases <= 0) /* XXX can't happen */
375  return 0;
376 
377  for (i = con->numAliases - 1; i >= 0; i--) {
378  item = con->aliases + i;
379  if (longName) {
380  if (item->option.longName == NULL)
381  continue;
382  if (!longOptionStrcmp(&item->option, longName, longNameLen))
383  continue;
384  } else if (shortName != item->option.shortName)
385  continue;
386  break;
387  }
388  if (i < 0) return 0;
389 
390  if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH)
391  return POPT_ERROR_OPTSTOODEEP;
392 
393  if (longName == NULL && nextArg != NULL && *nextArg != '\0')
394  con->os->nextCharArg = nextArg;
395 
396  con->os++;
397  con->os->next = 0;
398  con->os->stuffed = 0;
399  con->os->nextArg = NULL;
400  con->os->nextCharArg = NULL;
401  con->os->currAlias = con->aliases + i;
402  { const char ** av;
403  int ac = con->os->currAlias->argc;
404  /* Append --foo=bar arg to alias argv array (if present). */
405  if (longName && nextArg != NULL && *nextArg != '\0') {
406  av = malloc((ac + 1 + 1) * sizeof(*av));
407  if (av != NULL) { /* XXX won't happen. */
408  for (i = 0; i < ac; i++) {
409  av[i] = con->os->currAlias->argv[i];
410  }
411  av[ac++] = nextArg;
412  av[ac] = NULL;
413  } else /* XXX revert to old popt behavior if malloc fails. */
414  av = con->os->currAlias->argv;
415  } else
416  av = con->os->currAlias->argv;
417  rc = poptDupArgv(ac, av, &con->os->argc, &con->os->argv);
418  if (av != NULL && av != con->os->currAlias->argv)
419  free(av);
420  }
421  con->os->argb = NULL;
422 
423  return (rc ? rc : 1);
424 }
425 
431 static /*@null@*/
432 const char * findProgramPath(/*@null@*/ const char * argv0)
433  /*@*/
434 {
435  char *path = NULL, *s = NULL, *se;
436  char *t = NULL;
437 
438  if (argv0 == NULL) return NULL; /* XXX can't happen */
439 
440  /* If there is a / in argv[0], it has to be an absolute path. */
441  /* XXX Hmmm, why not if (argv0[0] == '/') ... instead? */
442  if (strchr(argv0, '/'))
443  return xstrdup(argv0);
444 
445  if ((path = getenv("PATH")) == NULL || (path = xstrdup(path)) == NULL)
446  return NULL;
447 
448  /* The return buffer in t is big enough for any path. */
449  if ((t = malloc(strlen(path) + strlen(argv0) + sizeof("/"))) != NULL)
450  for (s = path; s && *s; s = se) {
451 
452  /* Snip PATH element into [s,se). */
453  if ((se = strchr(s, ':')))
454  *se++ = '\0';
455 
456  /* Append argv0 to PATH element. */
457  (void) stpcpy(stpcpy(stpcpy(t, s), "/"), argv0);
458 
459  /* If file is executable, bingo! */
460  if (!access(t, X_OK))
461  break;
462  }
463 
464  /* If no executable was found in PATH, return NULL. */
465 /*@-compdef@*/
466  if (!(s && *s) && t != NULL)
467  t = _free(t);
468 /*@=compdef@*/
469 /*@-modobserver -observertrans -usedef @*/
470  path = _free(path);
471 /*@=modobserver =observertrans =usedef @*/
472 
473  return t;
474 }
475 
476 static int execCommand(poptContext con)
477  /*@globals internalState @*/
478  /*@modifies internalState @*/
479 {
480  poptItem item = con->doExec;
481  poptArgv argv = NULL;
482  int argc = 0;
483  int rc;
484  int ec = POPT_ERROR_ERRNO;
485 
486  if (item == NULL) /*XXX can't happen*/
487  return POPT_ERROR_NOARG;
488 
489  if (item->argv == NULL || item->argc < 1 ||
490  (!con->execAbsolute && strchr(item->argv[0], '/')))
491  return POPT_ERROR_NOARG;
492 
493  argv = malloc(sizeof(*argv) *
494  (6 + item->argc + con->numLeftovers + con->finalArgvCount));
495  if (argv == NULL) return POPT_ERROR_MALLOC;
496 
497  if (!strchr(item->argv[0], '/') && con->execPath != NULL) {
498  char *s = malloc(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/"));
499  if (s)
500  (void)stpcpy(stpcpy(stpcpy(s, con->execPath), "/"), item->argv[0]);
501 
502  argv[argc] = s;
503  } else
504  argv[argc] = findProgramPath(item->argv[0]);
505  if (argv[argc++] == NULL) {
506  ec = POPT_ERROR_NOARG;
507  goto exit;
508  }
509 
510  if (item->argc > 1) {
511  memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1));
512  argc += (item->argc - 1);
513  }
514 
515  if (con->finalArgv != NULL && con->finalArgvCount > 0) {
516  memcpy(argv + argc, con->finalArgv,
517  sizeof(*argv) * con->finalArgvCount);
518  argc += con->finalArgvCount;
519  }
520 
521  if (con->leftovers != NULL && con->numLeftovers > 0) {
522  memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers);
523  argc += con->numLeftovers;
524  }
525 
526  argv[argc] = NULL;
527 
528 #if defined(hpux) || defined(__hpux)
529  rc = setresgid(getgid(), getgid(),-1);
530  if (rc) goto exit;
531  rc = setresuid(getuid(), getuid(),-1);
532  if (rc) goto exit;
533 #else
534 /*
535  * XXX " ... on BSD systems setuid() should be preferred over setreuid()"
536  * XXX sez' Timur Bakeyev <mc@bat.ru>
537  * XXX from Norbert Warmuth <nwarmuth@privat.circular.de>
538  */
539 #if defined(HAVE_SETUID)
540  rc = setgid(getgid());
541  if (rc) goto exit;
542  rc = setuid(getuid());
543  if (rc) goto exit;
544 #elif defined (HAVE_SETREUID)
545  rc = setregid(getgid(), getgid());
546  if (rc) goto exit;
547  rc = setreuid(getuid(), getuid());
548  if (rc) goto exit;
549 #else
550  ; /* Can't drop privileges */
551 #endif
552 #endif
553 
554 #ifdef MYDEBUG
555 if (_popt_debug)
556  { poptArgv avp;
557  fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc);
558  for (avp = argv; *avp; avp++)
559  fprintf(stderr, " '%s'", *avp);
560  fprintf(stderr, "\n");
561  }
562 #endif
563 
564 /*@-nullstate@*/
565  rc = execvp(argv[0], (char *const *)argv);
566 /*@=nullstate@*/
567 
568 exit:
569  if (argv) {
570  if (argv[0])
571  free((void *)argv[0]);
572  free(argv);
573  }
574  return ec;
575 }
576 
577 /*@observer@*/ /*@null@*/
578 static const struct poptOption *
579 findOption(const struct poptOption * opt,
580  /*@null@*/ const char * longName, size_t longNameLen,
581  char shortName,
582  /*@null@*/ /*@out@*/ poptCallbackType * callback,
583  /*@null@*/ /*@out@*/ const void ** callbackData,
584  unsigned int argInfo)
585  /*@modifies *callback, *callbackData */
586 {
587  const struct poptOption * cb = NULL;
588  poptArg cbarg = { .ptr = NULL };
589 
590  /* This happens when a single - is given */
591  if (LF_ISSET(ONEDASH) && !shortName && (longName && *longName == '\0'))
592  shortName = '-';
593 
594  for (; opt->longName || opt->shortName || opt->arg; opt++) {
595  poptArg arg = { .ptr = opt->arg };
596 
597  switch (poptArgType(opt)) {
598  case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
599  { const struct poptOption * opt2;
600 
601  poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
602  if (arg.ptr == NULL) continue; /* XXX program error */
603  opt2 = findOption(arg.opt, longName, longNameLen, shortName, callback,
604  callbackData, argInfo);
605  if (opt2 == NULL) continue;
606  /* Sub-table data will be inheirited if no data yet. */
607 /*@-observertrans -dependenttrans @*/
608  if (callback && *callback
609  && callbackData && *callbackData == NULL)
610  *callbackData = opt->descrip;
611 /*@=observertrans =dependenttrans @*/
612  return opt2;
613  } /*@notreached@*/ /*@switchbreak@*/ break;
614  case POPT_ARG_CALLBACK:
615  cb = opt;
616  cbarg.ptr = opt->arg;
617  continue;
618  /*@notreached@*/ /*@switchbreak@*/ break;
619  default:
620  /*@switchbreak@*/ break;
621  }
622 
623  if (longName != NULL && opt->longName != NULL &&
624  (!LF_ISSET(ONEDASH) || F_ISSET(opt, ONEDASH)) &&
625  longOptionStrcmp(opt, longName, longNameLen))
626  {
627  break;
628  } else if (shortName && shortName == opt->shortName) {
629  break;
630  }
631  }
632 
633  if (opt->longName == NULL && !opt->shortName)
634  return NULL;
635 
636 /*@-modobserver -mods @*/
637  if (callback)
638  *callback = (cb ? cbarg.cb : NULL);
639  if (callbackData)
640 /*@-observertrans -dependenttrans @*/
641  *callbackData = (cb && !CBF_ISSET(cb, INC_DATA) ? cb->descrip : NULL);
642 /*@=observertrans =dependenttrans @*/
643 /*@=modobserver =mods @*/
644 
645  return opt;
646 }
647 
648 static const char * findNextArg(/*@special@*/ poptContext con,
649  unsigned argx, int delete_arg)
650  /*@uses con->optionStack, con->os,
651  con->os->next, con->os->argb, con->os->argc, con->os->argv @*/
652  /*@modifies con @*/
653 {
654  struct optionStackEntry * os = con->os;
655  const char * arg;
656 
657  do {
658  int i;
659  arg = NULL;
660  while (os->next == os->argc && os > con->optionStack) os--;
661  if (os->next == os->argc && os == con->optionStack) break;
662  if (os->argv != NULL)
663  for (i = os->next; i < os->argc; i++) {
664 /*@-sizeoftype@*/
665  if (os->argb && PBM_ISSET(i, os->argb))
666  /*@innercontinue@*/ continue;
667  if (*os->argv[i] == '-')
668  /*@innercontinue@*/ continue;
669  if (--argx > 0)
670  /*@innercontinue@*/ continue;
671  arg = os->argv[i];
672  if (delete_arg) {
673  if (os->argb == NULL) os->argb = PBM_ALLOC(os->argc);
674  if (os->argb != NULL) /* XXX can't happen */
675  PBM_SET(i, os->argb);
676  }
677  /*@innerbreak@*/ break;
678 /*@=sizeoftype@*/
679  }
680  if (os > con->optionStack) os--;
681  } while (arg == NULL);
682  return arg;
683 }
684 
685 static /*@only@*/ /*@null@*/ const char *
686 expandNextArg(/*@special@*/ poptContext con, const char * s)
687  /*@uses con->optionStack, con->os,
688  con->os->next, con->os->argb, con->os->argc, con->os->argv @*/
689  /*@modifies con @*/
690 {
691  const char * a = NULL;
692  char *t, *te;
693  size_t tn = strlen(s) + 1;
694  char c;
695 
696  te = t = malloc(tn);
697  if (t == NULL) return NULL; /* XXX can't happen */
698  *t = '\0';
699  while ((c = *s++) != '\0') {
700  switch (c) {
701 #if 0 /* XXX can't do this */
702  case '\\': /* escape */
703  c = *s++;
704  /*@switchbreak@*/ break;
705 #endif
706  case '!':
707  if (!(s[0] == '#' && s[1] == ':' && s[2] == '+'))
708  /*@switchbreak@*/ break;
709  /* XXX Make sure that findNextArg deletes only next arg. */
710  if (a == NULL) {
711  if ((a = findNextArg(con, 1U, 1)) == NULL)
712  /*@switchbreak@*/ break;
713  }
714  s += sizeof("#:+") - 1;
715 
716  tn += strlen(a);
717  { size_t pos = (size_t) (te - t);
718  if ((t = realloc(t, tn)) == NULL) /* XXX can't happen */
719  return NULL;
720  te = stpcpy(t + pos, a);
721  }
722  continue;
723  /*@notreached@*/ /*@switchbreak@*/ break;
724  default:
725  /*@switchbreak@*/ break;
726  }
727  *te++ = c;
728  }
729  *te++ = '\0';
730  /* If the new string is longer than needed, shorten. */
731  if ((t + tn) > te) {
732 /*@-usereleased@*/ /* XXX splint can't follow the pointers. */
733  if ((te = realloc(t, (size_t)(te - t))) == NULL)
734  free(t);
735  t = te;
736 /*@=usereleased@*/
737  }
738  return t;
739 }
740 
741 static void poptStripArg(/*@special@*/ poptContext con, int which)
742  /*@uses con->optionStack @*/
743  /*@defines con->arg_strip @*/
744  /*@modifies con @*/
745 {
746 /*@-compdef -sizeoftype -usedef @*/
747  if (con->arg_strip == NULL)
748  con->arg_strip = PBM_ALLOC(con->optionStack[0].argc);
749  if (con->arg_strip != NULL) /* XXX can't happen */
750  PBM_SET(which, con->arg_strip);
751  return;
752 /*@=compdef =sizeoftype =usedef @*/
753 }
754 
755 /*@unchecked@*/
756 unsigned int _poptBitsN = _POPT_BITS_N;
757 /*@unchecked@*/
758 unsigned int _poptBitsM = _POPT_BITS_M;
759 /*@unchecked@*/
760 unsigned int _poptBitsK = _POPT_BITS_K;
761 
762 /*@-sizeoftype@*/
763 static int _poptBitsNew(/*@null@*/ poptBits *bitsp)
764  /*@globals _poptBitsN, _poptBitsM, _poptBitsK @*/
765  /*@modifies *bitsp, _poptBitsN, _poptBitsM, _poptBitsK @*/
766 {
767  if (bitsp == NULL)
768  return POPT_ERROR_NULLARG;
769 
770  /* XXX handle negated initialization. */
771  if (*bitsp == NULL) {
772  if (_poptBitsN == 0) {
775  }
776  if (_poptBitsM == 0U) _poptBitsM = (3 * _poptBitsN) / 2;
777  if (_poptBitsK == 0U || _poptBitsK > 32U) _poptBitsK = _POPT_BITS_K;
778  *bitsp = PBM_ALLOC(_poptBitsM-1);
779  }
780 /*@-nullstate@*/
781  return 0;
782 /*@=nullstate@*/
783 }
784 
785 int poptBitsAdd(poptBits bits, const char * s)
786 {
787  size_t ns = (s ? strlen(s) : 0);
788  uint32_t h0 = 0;
789  uint32_t h1 = 0;
790 
791  if (bits == NULL || ns == 0)
792  return POPT_ERROR_NULLARG;
793 
794  poptJlu32lpair(s, ns, &h0, &h1);
795 
796  for (ns = 0; ns < (size_t)_poptBitsK; ns++) {
797  uint32_t h = h0 + ns * h1;
798  uint32_t ix = (h % _poptBitsM);
799  PBM_SET(ix, bits);
800  }
801  return 0;
802 }
803 
804 int poptBitsChk(poptBits bits, const char * s)
805 {
806  size_t ns = (s ? strlen(s) : 0);
807  uint32_t h0 = 0;
808  uint32_t h1 = 0;
809  int rc = 1;
810 
811  if (bits == NULL || ns == 0)
812  return POPT_ERROR_NULLARG;
813 
814  poptJlu32lpair(s, ns, &h0, &h1);
815 
816  for (ns = 0; ns < (size_t)_poptBitsK; ns++) {
817  uint32_t h = h0 + ns * h1;
818  uint32_t ix = (h % _poptBitsM);
819  if (PBM_ISSET(ix, bits))
820  continue;
821  rc = 0;
822  break;
823  }
824  return rc;
825 }
826 
828 {
829  static size_t nbw = (__PBM_NBITS/8);
830  size_t nw = (__PBM_IX(_poptBitsM-1) + 1);
831 
832  if (bits == NULL)
833  return POPT_ERROR_NULLARG;
834  memset(bits, 0, nw * nbw);
835  return 0;
836 }
837 
838 int poptBitsDel(poptBits bits, const char * s)
839 {
840  size_t ns = (s ? strlen(s) : 0);
841  uint32_t h0 = 0;
842  uint32_t h1 = 0;
843 
844  if (bits == NULL || ns == 0)
845  return POPT_ERROR_NULLARG;
846 
847  poptJlu32lpair(s, ns, &h0, &h1);
848 
849  for (ns = 0; ns < (size_t)_poptBitsK; ns++) {
850  uint32_t h = h0 + ns * h1;
851  uint32_t ix = (h % _poptBitsM);
852  PBM_CLR(ix, bits);
853  }
854  return 0;
855 }
856 
858 {
859  __pbm_bits *abits;
860  __pbm_bits *bbits;
861  __pbm_bits rc = 0;
862  size_t nw = (__PBM_IX(_poptBitsM-1) + 1);
863  size_t i;
864 
865  if (ap == NULL || b == NULL || _poptBitsNew(ap))
866  return POPT_ERROR_NULLARG;
867  abits = __PBM_BITS(*ap);
868  bbits = __PBM_BITS(b);
869 
870  for (i = 0; i < nw; i++) {
871  abits[i] &= bbits[i];
872  rc |= abits[i];
873  }
874  return (rc ? 1 : 0);
875 }
876 
877 int poptBitsUnion(poptBits *ap, const poptBits b)
878 {
879  __pbm_bits *abits;
880  __pbm_bits *bbits;
881  __pbm_bits rc = 0;
882  size_t nw = (__PBM_IX(_poptBitsM-1) + 1);
883  size_t i;
884 
885  if (ap == NULL || b == NULL || _poptBitsNew(ap))
886  return POPT_ERROR_NULLARG;
887  abits = __PBM_BITS(*ap);
888  bbits = __PBM_BITS(b);
889 
890  for (i = 0; i < nw; i++) {
891  abits[i] |= bbits[i];
892  rc |= abits[i];
893  }
894  return (rc ? 1 : 0);
895 }
896 
898 {
899  const char ** av;
900  int rc = 0;
901 
902  if (con == NULL || ap == NULL || _poptBitsNew(ap) ||
903  con->leftovers == NULL || con->numLeftovers == con->nextLeftover)
904  return POPT_ERROR_NULLARG;
905 
906  /* some apps like [like RPM ;-) ] need this NULL terminated */
907  con->leftovers[con->numLeftovers] = NULL;
908 
909  for (av = con->leftovers + con->nextLeftover; *av != NULL; av++) {
910  if ((rc = poptBitsAdd(*ap, *av)) != 0)
911  break;
912  }
913 /*@-nullstate@*/
914  return rc;
915 /*@=nullstate@*/
916 }
917 
918 int poptSaveBits(poptBits * bitsp,
919  /*@unused@*/ UNUSED(unsigned int argInfo), const char * s)
920 {
921  char *tbuf = NULL;
922  char *t, *te;
923  int rc = 0;
924 
925  if (bitsp == NULL || s == NULL || *s == '\0' || _poptBitsNew(bitsp))
926  return POPT_ERROR_NULLARG;
927 
928  /* Parse comma separated attributes. */
929  te = tbuf = xstrdup(s);
930  while ((t = te) != NULL && *t) {
931  while (*te != '\0' && *te != ',')
932  te++;
933  if (*te != '\0')
934  *te++ = '\0';
935  /* XXX Ignore empty strings. */
936  if (*t == '\0')
937  continue;
938  /* XXX Permit negated attributes. caveat emptor: false negatives. */
939  if (*t == '!') {
940  t++;
941  if ((rc = poptBitsChk(*bitsp, t)) > 0)
942  rc = poptBitsDel(*bitsp, t);
943  } else
944  rc = poptBitsAdd(*bitsp, t);
945  if (rc)
946  break;
947  }
948  tbuf = _free(tbuf);
949  return rc;
950 }
951 /*@=sizeoftype@*/
952 
953 int poptSaveString(const char *** argvp,
954  /*@unused@*/ UNUSED(unsigned int argInfo), const char * val)
955 {
956  int argc = 0;
957 
958  if (argvp == NULL || val == NULL)
959  return POPT_ERROR_NULLARG;
960 
961  /* XXX likely needs an upper bound on argc. */
962  if (*argvp != NULL)
963  while ((*argvp)[argc] != NULL)
964  argc++;
965 
966 /*@-unqualifiedtrans -nullstate@*/ /* XXX no annotation for (*argvp) */
967  if ((*argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp))) != NULL) {
968  (*argvp)[argc++] = xstrdup(val);
969  (*argvp)[argc ] = NULL;
970  }
971  return 0;
972 /*@=unqualifiedtrans =nullstate@*/
973 }
974 
975 /*@unchecked@*/
976 static unsigned int seed = 0;
977 
978 int poptSaveLongLong(long long * arg, unsigned int argInfo, long long aLongLong)
979 {
980  if (arg == NULL
981 #ifdef NOTYET
982  /* XXX Check alignment, may fail on funky platforms. */
983  || (((unsigned long long)arg) & (sizeof(*arg)-1))
984 #endif
985  )
986  return POPT_ERROR_NULLARG;
987 
988  if (aLongLong != 0 && LF_ISSET(RANDOM)) {
989 #if defined(HAVE_SRANDOM)
990  if (!seed) {
991  srandom((unsigned)getpid());
992  srandom((unsigned)random());
993  }
994  aLongLong = (long long)(random() % (aLongLong > 0 ? aLongLong : -aLongLong));
995  aLongLong++;
996 #else
997  /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
999 #endif
1000  }
1001  if (LF_ISSET(NOT))
1002  aLongLong = ~aLongLong;
1003  switch (LF_ISSET(LOGICALOPS)) {
1004  case 0:
1005  *arg = aLongLong;
1006  break;
1007  case POPT_ARGFLAG_OR:
1008  *(unsigned long long *)arg |= (unsigned long long)aLongLong;
1009  break;
1010  case POPT_ARGFLAG_AND:
1011  *(unsigned long long *)arg &= (unsigned long long)aLongLong;
1012  break;
1013  case POPT_ARGFLAG_XOR:
1014  *(unsigned long long *)arg ^= (unsigned long long)aLongLong;
1015  break;
1016  default:
1017  return POPT_ERROR_BADOPERATION;
1018  /*@notreached@*/ break;
1019  }
1020  return 0;
1021 }
1022 
1023 int poptSaveLong(long * arg, unsigned int argInfo, long aLong)
1024 {
1025  /* XXX Check alignment, may fail on funky platforms. */
1026  if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
1027  return POPT_ERROR_NULLARG;
1028 
1029  if (aLong != 0 && LF_ISSET(RANDOM)) {
1030 #if defined(HAVE_SRANDOM)
1031  if (!seed) {
1032  srandom((unsigned)getpid());
1033  srandom((unsigned)random());
1034  }
1035  aLong = random() % (aLong > 0 ? aLong : -aLong);
1036  aLong++;
1037 #else
1038  /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
1039  return POPT_ERROR_BADOPERATION;
1040 #endif
1041  }
1042  if (LF_ISSET(NOT))
1043  aLong = ~aLong;
1044  switch (LF_ISSET(LOGICALOPS)) {
1045  case 0: *arg = aLong; break;
1046  case POPT_ARGFLAG_OR: *(unsigned long *)arg |= (unsigned long)aLong; break;
1047  case POPT_ARGFLAG_AND: *(unsigned long *)arg &= (unsigned long)aLong; break;
1048  case POPT_ARGFLAG_XOR: *(unsigned long *)arg ^= (unsigned long)aLong; break;
1049  default:
1050  return POPT_ERROR_BADOPERATION;
1051  /*@notreached@*/ break;
1052  }
1053  return 0;
1054 }
1055 
1056 int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong)
1057 {
1058  /* XXX Check alignment, may fail on funky platforms. */
1059  if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
1060  return POPT_ERROR_NULLARG;
1061 
1062  if (aLong != 0 && LF_ISSET(RANDOM)) {
1063 #if defined(HAVE_SRANDOM)
1064  if (!seed) {
1065  srandom((unsigned)getpid());
1066  srandom((unsigned)random());
1067  }
1068  aLong = random() % (aLong > 0 ? aLong : -aLong);
1069  aLong++;
1070 #else
1071  /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
1072  return POPT_ERROR_BADOPERATION;
1073 #endif
1074  }
1075  if (LF_ISSET(NOT))
1076  aLong = ~aLong;
1077  switch (LF_ISSET(LOGICALOPS)) {
1078  case 0: *arg = (int) aLong; break;
1079  case POPT_ARGFLAG_OR: *(unsigned int *)arg |= (unsigned int) aLong; break;
1080  case POPT_ARGFLAG_AND: *(unsigned int *)arg &= (unsigned int) aLong; break;
1081  case POPT_ARGFLAG_XOR: *(unsigned int *)arg ^= (unsigned int) aLong; break;
1082  default:
1083  return POPT_ERROR_BADOPERATION;
1084  /*@notreached@*/ break;
1085  }
1086  return 0;
1087 }
1088 
1089 int poptSaveShort(/*@null@*/ short * arg, unsigned int argInfo, long aLong)
1090 {
1091  /* XXX Check alignment, may fail on funky platforms. */
1092  if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
1093  return POPT_ERROR_NULLARG;
1094 
1095  if (aLong != 0 && LF_ISSET(RANDOM)) {
1096 #if defined(HAVE_SRANDOM)
1097  if (!seed) {
1098  srandom((unsigned)getpid());
1099  srandom((unsigned)random());
1100  }
1101  aLong = random() % (aLong > 0 ? aLong : -aLong);
1102  aLong++;
1103 #else
1104  /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
1105  return POPT_ERROR_BADOPERATION;
1106 #endif
1107  }
1108  if (LF_ISSET(NOT))
1109  aLong = ~aLong;
1110  switch (LF_ISSET(LOGICALOPS)) {
1111  case 0: *arg = (short) aLong;
1112  break;
1113  case POPT_ARGFLAG_OR: *(unsigned short *)arg |= (unsigned short) aLong;
1114  break;
1115  case POPT_ARGFLAG_AND: *(unsigned short *)arg &= (unsigned short) aLong;
1116  break;
1117  case POPT_ARGFLAG_XOR: *(unsigned short *)arg ^= (unsigned short) aLong;
1118  break;
1119  default: return POPT_ERROR_BADOPERATION;
1120  /*@notreached@*/ break;
1121  }
1122  return 0;
1123 }
1124 
1131 static unsigned int poptArgInfo(poptContext con, const struct poptOption * opt)
1132  /*@*/
1133 {
1134  unsigned int argInfo = opt->argInfo;
1135 
1136  if (con->os->argv != NULL && con->os->next > 0 && opt->longName != NULL)
1137  if (LF_ISSET(TOGGLE)) {
1138  const char * longName = con->os->argv[con->os->next-1];
1139  while (*longName == '-') longName++;
1140  /* XXX almost good enough but consider --[no]nofoo corner cases. */
1141  if (longName[0] != opt->longName[0] || longName[1] != opt->longName[1])
1142  {
1143  if (!LF_ISSET(XOR)) { /* XXX dont toggle with XOR */
1144  /* Toggle POPT_BIT_SET <=> POPT_BIT_CLR. */
1145  if (LF_ISSET(LOGICALOPS))
1146  argInfo ^= (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND);
1147  argInfo ^= POPT_ARGFLAG_NOT;
1148  }
1149  }
1150  }
1151  return argInfo;
1152 }
1153 
1161 static int poptParseInteger(long long * llp,
1162  /*@unused@*/ UNUSED(unsigned int argInfo),
1163  /*@null@*/ const char * val)
1164  /*@modifies *llp @*/
1165 {
1166  if (val) {
1167  char *end = NULL;
1168  *llp = strtoll(val, &end, 0);
1169 
1170  /* XXX parse scaling suffixes here. */
1171 
1172  if (!(end && *end == '\0'))
1173  return POPT_ERROR_BADNUMBER;
1174  } else
1175  *llp = 0;
1176  return 0;
1177 }
1178 
1185 static int poptSaveArg(poptContext con, const struct poptOption * opt)
1186  /*@globals fileSystem, internalState @*/
1187  /*@modifies con, fileSystem, internalState @*/
1188 {
1189  poptArg arg = { .ptr = opt->arg };
1190  int rc = 0; /* assume success */
1191 
1192  switch (poptArgType(opt)) {
1193  case POPT_ARG_BITSET:
1194  /* XXX memory leak, application is responsible for free. */
1195  rc = poptSaveBits(arg.ptr, opt->argInfo, con->os->nextArg);
1196  /*@switchbreak@*/ break;
1197  case POPT_ARG_ARGV:
1198  /* XXX memory leak, application is responsible for free. */
1199  rc = poptSaveString(arg.ptr, opt->argInfo, con->os->nextArg);
1200  /*@switchbreak@*/ break;
1201  case POPT_ARG_STRING:
1202  /* XXX memory leak, application is responsible for free. */
1203  arg.argv[0] = (con->os->nextArg) ? xstrdup(con->os->nextArg) : NULL;
1204  /*@switchbreak@*/ break;
1205 
1206  case POPT_ARG_INT:
1207  case POPT_ARG_SHORT:
1208  case POPT_ARG_LONG:
1209  case POPT_ARG_LONGLONG:
1210  { unsigned int argInfo = poptArgInfo(con, opt);
1211  long long aNUM = 0;
1212 
1213  if ((rc = poptParseInteger(&aNUM, argInfo, con->os->nextArg)) != 0)
1214  break;
1215 
1216  switch (poptArgType(opt)) {
1217  case POPT_ARG_LONGLONG:
1218 /* XXX let's not demand C99 compiler flags for <limits.h> quite yet. */
1219 #if !defined(LLONG_MAX)
1220 # define LLONG_MAX 9223372036854775807LL
1221 # define LLONG_MIN (-LLONG_MAX - 1LL)
1222 #endif
1223  rc = !(aNUM == LLONG_MIN || aNUM == LLONG_MAX)
1224  ? poptSaveLongLong(arg.longlongp, argInfo, aNUM)
1226  /*@innerbreak@*/ break;
1227  case POPT_ARG_LONG:
1228  rc = !(aNUM < (long long)LONG_MIN || aNUM > (long long)LONG_MAX)
1229  ? poptSaveLong(arg.longp, argInfo, (long)aNUM)
1231  /*@innerbreak@*/ break;
1232  case POPT_ARG_INT:
1233  rc = !(aNUM < (long long)INT_MIN || aNUM > (long long)INT_MAX)
1234  ? poptSaveInt(arg.intp, argInfo, (long)aNUM)
1236  /*@innerbreak@*/ break;
1237  case POPT_ARG_SHORT:
1238  rc = !(aNUM < (long long)SHRT_MIN || aNUM > (long long)SHRT_MAX)
1239  ? poptSaveShort(arg.shortp, argInfo, (long)aNUM)
1241  /*@innerbreak@*/ break;
1242  }
1243  } /*@switchbreak@*/ break;
1244 
1245  case POPT_ARG_FLOAT:
1246  case POPT_ARG_DOUBLE:
1247  { char *end = NULL;
1248  double aDouble = 0.0;
1249 
1250  if (con->os->nextArg) {
1251 /*@-mods@*/
1252  int saveerrno = errno;
1253  errno = 0;
1254  aDouble = strtod(con->os->nextArg, &end);
1255  if (errno == ERANGE) {
1256  rc = POPT_ERROR_OVERFLOW;
1257  break;
1258  }
1259  errno = saveerrno;
1260 /*@=mods@*/
1261  if (*end != '\0') {
1262  rc = POPT_ERROR_BADNUMBER;
1263  break;
1264  }
1265  }
1266 
1267  switch (poptArgType(opt)) {
1268  case POPT_ARG_DOUBLE:
1269  arg.doublep[0] = aDouble;
1270  /*@innerbreak@*/ break;
1271  case POPT_ARG_FLOAT:
1272 #if !defined(DBL_EPSILON) && !defined(__LCLINT__)
1273 #define DBL_EPSILON 2.2204460492503131e-16
1274 #endif
1275 #define POPT_ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a))
1276  if ((FLT_MIN - POPT_ABS(aDouble)) > DBL_EPSILON
1277  || (POPT_ABS(aDouble) - FLT_MAX) > DBL_EPSILON)
1278  rc = POPT_ERROR_OVERFLOW;
1279  else
1280  arg.floatp[0] = (float) aDouble;
1281  /*@innerbreak@*/ break;
1282  }
1283  } /*@switchbreak@*/ break;
1284  case POPT_ARG_MAINCALL:
1285 /*@-assignexpose -type@*/
1286  con->maincall = opt->arg;
1287 /*@=assignexpose =type@*/
1288  /*@switchbreak@*/ break;
1289  default:
1290  fprintf(stdout, POPT_("option type (%u) not implemented in popt\n"),
1291  poptArgType(opt));
1292  exit(EXIT_FAILURE);
1293  /*@notreached@*/ /*@switchbreak@*/ break;
1294  }
1295  return rc;
1296 }
1297 
1298 /* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
1300 {
1301  const struct poptOption * opt = NULL;
1302  int done = 0;
1303 
1304  if (con == NULL)
1305  return -1;
1306  while (!done) {
1307  const char * origOptString = NULL;
1308  poptCallbackType cb = NULL;
1309  const void * cbData = NULL;
1310  const char * longArg = NULL;
1311  int canstrip = 0;
1312  int shorty = 0;
1313 
1314  while (!con->os->nextCharArg && con->os->next == con->os->argc
1315  && con->os > con->optionStack) {
1316  cleanOSE(con->os--);
1317  }
1318  if (!con->os->nextCharArg && con->os->next == con->os->argc) {
1319  invokeCallbacksPOST(con, con->options);
1320 
1321  if (con->maincall) {
1322  /*@-noeffectuncon @*/
1323  (void) (*con->maincall) (con->finalArgvCount, con->finalArgv);
1324  /*@=noeffectuncon @*/
1325  return -1;
1326  }
1327 
1328  if (con->doExec) return execCommand(con);
1329  return -1;
1330  }
1331 
1332  /* Process next long option */
1333  if (!con->os->nextCharArg) {
1334  const char * optString;
1335  size_t optStringLen;
1336  int thisopt;
1337 
1338 /*@-sizeoftype@*/
1339  if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) {
1340  con->os->next++;
1341  continue;
1342  }
1343 /*@=sizeoftype@*/
1344  thisopt = con->os->next;
1345  if (con->os->argv != NULL) /* XXX can't happen */
1346  origOptString = con->os->argv[con->os->next++];
1347 
1348  if (origOptString == NULL) /* XXX can't happen */
1349  return POPT_ERROR_BADOPT;
1350 
1351  if (con->restLeftover || *origOptString != '-' ||
1352  (*origOptString == '-' && origOptString[1] == '\0'))
1353  {
1354  if (con->flags & POPT_CONTEXT_POSIXMEHARDER)
1355  con->restLeftover = 1;
1356  if (con->flags & POPT_CONTEXT_ARG_OPTS) {
1357  con->os->nextArg = xstrdup(origOptString);
1358  return 0;
1359  }
1360  if (con->leftovers != NULL) /* XXX can't happen */
1361  con->leftovers[con->numLeftovers++] = origOptString;
1362  continue;
1363  }
1364 
1365  /* Make a copy we can hack at */
1366  optString = origOptString;
1367 
1368  if (optString[0] == '\0')
1369  return POPT_ERROR_BADOPT;
1370 
1371  if (optString[1] == '-' && !optString[2]) {
1372  con->restLeftover = 1;
1373  continue;
1374  } else {
1375  const char *oe;
1376  unsigned int argInfo = 0;
1377 
1378  optString++;
1379  if (*optString == '-')
1380  optString++;
1381  else
1382  argInfo |= POPT_ARGFLAG_ONEDASH;
1383 
1384  /* Check for "--long=arg" option. */
1385  for (oe = optString; *oe && *oe != '='; oe++)
1386  {};
1387  optStringLen = (size_t)(oe - optString);
1388  if (*oe == '=')
1389  longArg = oe + 1;
1390 
1391  /* XXX aliases with arg substitution need "--alias=arg" */
1392  if (handleAlias(con, optString, optStringLen, '\0', longArg)) {
1393  longArg = NULL;
1394  continue;
1395  }
1396 
1397  if (handleExec(con, optString, '\0'))
1398  continue;
1399 
1400  opt = findOption(con->options, optString, optStringLen, '\0', &cb, &cbData,
1401  argInfo);
1402  if (!opt && !LF_ISSET(ONEDASH))
1403  return POPT_ERROR_BADOPT;
1404  }
1405 
1406  if (!opt) {
1407  con->os->nextCharArg = origOptString + 1;
1408  longArg = NULL;
1409  } else {
1410  if (con->os == con->optionStack && F_ISSET(opt, STRIP))
1411  {
1412  canstrip = 1;
1413  poptStripArg(con, thisopt);
1414  }
1415  shorty = 0;
1416  }
1417  }
1418 
1419  /* Process next short option */
1420  if (con->os->nextCharArg) {
1421  const char * nextCharArg = con->os->nextCharArg;
1422 
1423  con->os->nextCharArg = NULL;
1424 
1425  if (handleAlias(con, NULL, 0, *nextCharArg, nextCharArg + 1))
1426  continue;
1427 
1428  if (handleExec(con, NULL, *nextCharArg)) {
1429  /* Restore rest of short options for further processing */
1430  nextCharArg++;
1431  if (*nextCharArg != '\0')
1432  con->os->nextCharArg = nextCharArg;
1433  continue;
1434  }
1435 
1436  opt = findOption(con->options, NULL, 0, *nextCharArg, &cb,
1437  &cbData, 0);
1438  if (!opt)
1439  return POPT_ERROR_BADOPT;
1440  shorty = 1;
1441 
1442  nextCharArg++;
1443  if (*nextCharArg != '\0')
1444  con->os->nextCharArg = nextCharArg + (int)(*nextCharArg == '=');
1445  }
1446 
1447  if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */
1448  if (opt->arg && poptArgType(opt) == POPT_ARG_NONE) {
1449  unsigned int argInfo = poptArgInfo(con, opt);
1450  if (poptSaveInt((int *)opt->arg, argInfo, 1L))
1451  return POPT_ERROR_BADOPERATION;
1452  } else if (poptArgType(opt) == POPT_ARG_VAL) {
1453  if (opt->arg) {
1454  unsigned int argInfo = poptArgInfo(con, opt);
1455  if (poptSaveInt((int *)opt->arg, argInfo, (long)opt->val))
1456  return POPT_ERROR_BADOPERATION;
1457  }
1458  } else if (poptArgType(opt) != POPT_ARG_NONE) {
1459  int rc;
1460 
1461  con->os->nextArg = _free(con->os->nextArg);
1462  if (longArg) {
1463  longArg = expandNextArg(con, longArg);
1464  con->os->nextArg = (char *) longArg;
1465  } else if (con->os->nextCharArg) {
1466  longArg = expandNextArg(con, con->os->nextCharArg);
1467  con->os->nextArg = (char *) longArg;
1468  con->os->nextCharArg = NULL;
1469  } else {
1470  while (con->os->next == con->os->argc &&
1471  con->os > con->optionStack)
1472  {
1473  cleanOSE(con->os--);
1474  }
1475  if (con->os->next == con->os->argc) {
1476  if (!F_ISSET(opt, OPTIONAL))
1477  return POPT_ERROR_NOARG;
1478  con->os->nextArg = NULL;
1479  } else {
1480 
1481  /*
1482  * Make sure this isn't part of a short arg or the
1483  * result of an alias expansion.
1484  */
1485  if (con->os == con->optionStack
1486  && F_ISSET(opt, STRIP) && canstrip)
1487  {
1488  poptStripArg(con, con->os->next);
1489  }
1490 
1491  if (con->os->argv != NULL) { /* XXX can't happen */
1492  if (F_ISSET(opt, OPTIONAL) &&
1493  con->os->argv[con->os->next][0] == '-') {
1494  con->os->nextArg = NULL;
1495  } else {
1496  /* XXX watchout: subtle side-effects live here. */
1497  longArg = con->os->argv[con->os->next++];
1498  longArg = expandNextArg(con, longArg);
1499  con->os->nextArg = (char *) longArg;
1500  }
1501  }
1502  }
1503  }
1504  longArg = NULL;
1505 
1506  /* Save the option argument through a (*opt->arg) pointer. */
1507  if (opt->arg != NULL && (rc = poptSaveArg(con, opt)) != 0)
1508  return rc;
1509  }
1510 
1511  if (cb)
1512  invokeCallbacksOPTION(con, con->options, opt, cbData, shorty);
1513  else if (opt->val && (poptArgType(opt) != POPT_ARG_VAL))
1514  done = 1;
1515 
1516  if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) {
1517  con->finalArgvAlloced += 10;
1518  con->finalArgv = realloc(con->finalArgv,
1519  sizeof(*con->finalArgv) * con->finalArgvAlloced);
1520  }
1521 
1522  if (con->finalArgv != NULL)
1523  { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + sizeof("--"));
1524  if (s != NULL) { /* XXX can't happen */
1525  con->finalArgv[con->finalArgvCount++] = s;
1526  *s++ = '-';
1527  if (opt->longName) {
1528  if (!F_ISSET(opt, ONEDASH))
1529  *s++ = '-';
1530  s = stpcpy(s, opt->longName);
1531  } else {
1532  *s++ = opt->shortName;
1533  *s = '\0';
1534  }
1535  } else
1536  con->finalArgv[con->finalArgvCount++] = NULL;
1537  }
1538 
1539  if (opt->arg && poptArgType(opt) == POPT_ARG_NONE)
1540  /*@-ifempty@*/ ; /*@=ifempty@*/
1541  else if (poptArgType(opt) == POPT_ARG_VAL)
1542  /*@-ifempty@*/ ; /*@=ifempty@*/
1543  else if (poptArgType(opt) != POPT_ARG_NONE) {
1544  if (con->finalArgv != NULL && con->os->nextArg != NULL)
1545  con->finalArgv[con->finalArgvCount++] =
1546  xstrdup(con->os->nextArg);
1547  }
1548  }
1549 
1550  return (opt ? opt->val : -1); /* XXX can't happen */
1551 }
1552 
1554 {
1555  char * ret = NULL;
1556  if (con) {
1557  ret = con->os->nextArg;
1558  con->os->nextArg = NULL;
1559  }
1560  return ret;
1561 }
1562 
1563 const char * poptGetArg(poptContext con)
1564 {
1565  const char * ret = NULL;
1566  if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers)
1567  ret = con->leftovers[con->nextLeftover++];
1568  return ret;
1569 }
1570 
1571 const char * poptPeekArg(poptContext con)
1572 {
1573  const char * ret = NULL;
1574  if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers)
1575  ret = con->leftovers[con->nextLeftover];
1576  return ret;
1577 }
1578 
1579 const char ** poptGetArgs(poptContext con)
1580 {
1581  if (con == NULL ||
1582  con->leftovers == NULL || con->numLeftovers == con->nextLeftover)
1583  return NULL;
1584 
1585  /* some apps like [like RPM ;-) ] need this NULL terminated */
1586  con->leftovers[con->numLeftovers] = NULL;
1587 
1588 /*@-nullret -nullstate @*/ /* FIX: typedef double indirection. */
1589  return (con->leftovers + con->nextLeftover);
1590 /*@=nullret =nullstate @*/
1591 }
1592 
1593 static /*@null@*/
1594 poptItem poptFreeItems(/*@only@*/ /*@null@*/ poptItem items, int nitems)
1595  /*@modifies items @*/
1596 {
1597  if (items != NULL) {
1598  poptItem item = items;
1599  while (--nitems >= 0) {
1600 /*@-modobserver -observertrans -dependenttrans@*/
1601  item->option.longName = _free(item->option.longName);
1602  item->option.descrip = _free(item->option.descrip);
1603  item->option.argDescrip = _free(item->option.argDescrip);
1604 /*@=modobserver =observertrans =dependenttrans@*/
1605  item->argv = _free(item->argv);
1606  item++;
1607  }
1608  items = _free(items);
1609  }
1610  return NULL;
1611 }
1612 
1614 {
1615  if (con == NULL) return con;
1616  poptResetContext(con);
1617  con->os->argb = _free(con->os->argb);
1618 
1619  con->aliases = poptFreeItems(con->aliases, con->numAliases);
1620  con->numAliases = 0;
1621 
1622  con->execs = poptFreeItems(con->execs, con->numExecs);
1623  con->numExecs = 0;
1624 
1625  con->leftovers = _free(con->leftovers);
1626  con->finalArgv = _free(con->finalArgv);
1627  con->appName = _free(con->appName);
1628  con->otherHelp = _free(con->otherHelp);
1629  con->execPath = _free(con->execPath);
1630  con->arg_strip = PBM_FREE(con->arg_strip);
1631 
1632  con = _free(con);
1633  return con;
1634 }
1635 
1636 int poptAddAlias(poptContext con, struct poptAlias alias,
1637  /*@unused@*/ UNUSED(int flags))
1638 {
1639  struct poptItem_s item_buf;
1640  poptItem item = &item_buf;
1641  memset(item, 0, sizeof(*item));
1642  item->option.longName = alias.longName;
1643  item->option.shortName = alias.shortName;
1644  item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
1645  item->option.arg = 0;
1646  item->option.val = 0;
1647  item->option.descrip = NULL;
1648  item->option.argDescrip = NULL;
1649  item->argc = alias.argc;
1650  item->argv = alias.argv;
1651  return poptAddItem(con, item, 0);
1652 }
1653 
1654 int poptAddItem(poptContext con, poptItem newItem, int flags)
1655 {
1656  poptItem * items, item;
1657  int * nitems;
1658 
1659  switch (flags) {
1660  case 1:
1661  items = &con->execs;
1662  nitems = &con->numExecs;
1663  break;
1664  case 0:
1665  items = &con->aliases;
1666  nitems = &con->numAliases;
1667  break;
1668  default:
1669  return 1;
1670  /*@notreached@*/ break;
1671  }
1672 
1673  *items = realloc((*items), ((*nitems) + 1) * sizeof(**items));
1674  if ((*items) == NULL)
1675  return 1;
1676 
1677  item = (*items) + (*nitems);
1678 
1679  item->option.longName =
1680  (newItem->option.longName ? xstrdup(newItem->option.longName) : NULL);
1681  item->option.shortName = newItem->option.shortName;
1682  item->option.argInfo = newItem->option.argInfo;
1683  item->option.arg = newItem->option.arg;
1684  item->option.val = newItem->option.val;
1685  item->option.descrip =
1686  (newItem->option.descrip ? xstrdup(newItem->option.descrip) : NULL);
1687  item->option.argDescrip =
1688  (newItem->option.argDescrip ? xstrdup(newItem->option.argDescrip) : NULL);
1689  item->argc = newItem->argc;
1690  item->argv = newItem->argv;
1691 
1692  (*nitems)++;
1693 
1694  return 0;
1695 }
1696 
1697 const char * poptBadOption(poptContext con, unsigned int flags)
1698 {
1699  struct optionStackEntry * os = NULL;
1700 
1701  if (con != NULL)
1702  os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os;
1703 
1704  return (os != NULL && os->argv != NULL ? os->argv[os->next - 1] : NULL);
1705 }
1706 
1707 const char * poptStrerror(const int error)
1708 {
1709  switch (error) {
1710  case POPT_ERROR_NOARG:
1711  return POPT_("missing argument");
1712  case POPT_ERROR_BADOPT:
1713  return POPT_("unknown option");
1715  return POPT_("mutually exclusive logical operations requested");
1716  case POPT_ERROR_NULLARG:
1717  return POPT_("opt->arg should not be NULL");
1719  return POPT_("aliases nested too deeply");
1720  case POPT_ERROR_BADQUOTE:
1721  return POPT_("error in parameter quoting");
1722  case POPT_ERROR_BADNUMBER:
1723  return POPT_("invalid numeric value");
1724  case POPT_ERROR_OVERFLOW:
1725  return POPT_("number too large or too small");
1726  case POPT_ERROR_MALLOC:
1727  return POPT_("memory allocation failed");
1728  case POPT_ERROR_BADCONFIG:
1729  return POPT_("config file failed sanity test");
1730  case POPT_ERROR_ERRNO:
1731  return strerror(errno);
1732  default:
1733  return POPT_("unknown error");
1734  }
1735 }
1736 
1737 int poptStuffArgs(poptContext con, const char ** argv)
1738 {
1739  int argc;
1740  int rc;
1741 
1742  if ((con->os - con->optionStack) == POPT_OPTION_DEPTH)
1743  return POPT_ERROR_OPTSTOODEEP;
1744 
1745  for (argc = 0; argv[argc]; argc++)
1746  {};
1747 
1748  con->os++;
1749  con->os->next = 0;
1750  con->os->nextArg = NULL;
1751  con->os->nextCharArg = NULL;
1752  con->os->currAlias = NULL;
1753  rc = poptDupArgv(argc, argv, &con->os->argc, &con->os->argv);
1754  con->os->argb = NULL;
1755  con->os->stuffed = 1;
1756 
1757  return rc;
1758 }
1759 
1761 {
1762  return (con->os->argv ? con->os->argv[0] : "");
1763 }
1764 
1765 int poptStrippedArgv(poptContext con, int argc, char ** argv)
1766 {
1767  int numargs = argc;
1768  int j = 1;
1769  int i;
1770 
1771 /*@-sizeoftype@*/
1772  if (con->arg_strip)
1773  for (i = 1; i < argc; i++) {
1774  if (PBM_ISSET(i, con->arg_strip))
1775  numargs--;
1776  }
1777 
1778  for (i = 1; i < argc; i++) {
1779  if (con->arg_strip && PBM_ISSET(i, con->arg_strip))
1780  continue;
1781  argv[j] = (j < numargs) ? argv[i] : NULL;
1782  j++;
1783  }
1784 /*@=sizeoftype@*/
1785 
1786  return numargs;
1787 }
pbm_set * arg_strip
Definition: poptint.h:149
poptItem execs
Definition: poptint.h:133
char shortName
Definition: popt.h:152
static const char * expandNextArg(poptContext con, const char *s)
Definition: popt.c:686
void * ptr
Definition: poptint.h:65
static void invokeCallbacksOPTION(poptContext con, const struct poptOption *opt, const struct poptOption *myOpt, const void *myData, int shorty)
Definition: popt.c:122
const char * longName
Definition: popt.h:151
#define POPT_CONTEXT_ARG_OPTS
Definition: popt.h:127
const char ** poptGetArgs(poptContext con)
Return remaining arguments.
Definition: popt.c:1579
A popt alias argument for poptAddAlias().
Definition: popt.h:149
#define POPT_ARG_SHORT
Definition: popt.h:46
poptItem aliases
Definition: poptint.h:129
poptArgv finalArgv
Definition: poptint.h:136
#define POPT_ERROR_BADQUOTE
Definition: popt.h:103
poptArgv argv
Definition: poptint.h:102
#define poptArgType(_opt)
Definition: poptint.h:86
int poptSaveBits(poptBits *bitsp, unsigned int argInfo, const char *s)
Save a string into a bit set (experimental).
Definition: popt.c:918
const char * poptGetInvocationName(poptContext con)
Return argv[0] from context.
Definition: popt.c:1760
#define POPT_ARG_LONGLONG
Definition: popt.h:42
char * poptGetOptArg(poptContext con)
Return next option argument (if any).
Definition: popt.c:1553
#define POPT_ERROR_ERRNO
Definition: popt.h:104
#define poptSubstituteHelpI18N(opt)
Definition: poptint.h:94
#define PBM_ALLOC(d)
Definition: poptint.h:41
#define POPT_BADOPTION_NOALIAS
Definition: popt.h:117
short * shortp
Definition: poptint.h:67
static poptItem poptFreeItems(poptItem items, int nitems)
Definition: popt.c:1594
int poptBitsClr(poptBits bits)
Definition: popt.c:827
poptItem currAlias
Definition: poptint.h:111
#define POPT_ARG_ARGV
Definition: popt.h:45
static char * stpcpy(char *dest, const char *src)
Definition: system.h:69
A popt alias or exec argument for poptAddItem().
Definition: popt.h:162
int poptBitsArgs(poptContext con, poptBits *ap)
Definition: popt.c:897
const char * argDescrip
Definition: popt.h:143
unsigned int __pbm_bits
Definition: poptint.h:29
unsigned int argInfo
Definition: popt.h:136
const char * poptBadOption(poptContext con, unsigned int flags)
Return the option which caused the most recent error.
Definition: popt.c:1697
const char ** argv
Definition: popt.h:155
const char ** argv
Definition: poptint.h:72
#define POPT_ERROR_NULLARG
Definition: popt.h:108
#define POPT_ERROR_BADCONFIG
Definition: popt.h:110
static int _poptBitsNew(poptBits *bitsp)
Definition: popt.c:763
long long * longlongp
Definition: poptint.h:69
void poptJlu32lpair(const void *key, size_t size, uint32_t *pc, uint32_t *pb)
void * arg
Definition: popt.h:138
#define POPT_ERROR_BADOPERATION
Definition: popt.h:107
#define POPT_CONTEXT_NO_EXEC
Definition: popt.h:124
#define DBL_EPSILON
poptCallbackType cb
Definition: poptint.h:73
#define PBM_CLR(d, s)
Definition: poptint.h:44
struct poptOption option
Definition: popt.h:163
int(* maincall)(int argc, const char **argv)
Definition: poptint.h:140
unsigned int _poptBitsM
Definition: popt.c:758
poptContext poptGetContext(const char *name, int argc, const char **argv, const struct poptOption *options, unsigned int flags)
Initialize popt context.
Definition: popt.c:168
poptOption opt
Definition: poptint.h:75
void poptResetContext(poptContext con)
Reinitialize popt context.
Definition: popt.c:221
#define POPT_ERROR_BADOPT
Definition: popt.h:101
#define UNUSED(x)
Definition: system.h:101
const char * poptGetArg(poptContext con)
Return next argument.
Definition: popt.c:1563
#define POPT_CONTEXT_POSIXMEHARDER
Definition: popt.h:126
int numAliases
Definition: poptint.h:130
#define LLONG_MAX
int poptSaveShort(short *arg, unsigned int argInfo, long aLong)
Save a short integer, performing logical operation with value.
Definition: popt.c:1089
unsigned int _poptGroupMask
Definition: popt.c:36
unsigned int _poptBitsK
Definition: popt.c:760
#define POPT_ARG_DOUBLE
Definition: popt.h:41
int poptGetNextOpt(poptContext con)
Return value of next option found.
Definition: popt.c:1299
#define POPT_ERROR_BADNUMBER
Definition: popt.h:105
#define POPT_ARGFLAG_AND
Definition: popt.h:65
#define POPT_ARG_INCLUDE_TABLE
Definition: popt.h:24
#define LLONG_MIN
int poptDupArgv(int argc, const char **argv, int *argcPtr, const char ***argvPtr)
Duplicate an argument array.
Definition: poptparse.c:13
#define POPT_ARG_NONE
Definition: popt.h:20
#define POPT_ERROR_OPTSTOODEEP
Definition: popt.h:102
static int poptParseInteger(long long *llp, unsigned int argInfo, const char *val)
Parse an integer expression.
Definition: popt.c:1161
struct optionStackEntry optionStack[POPT_OPTION_DEPTH]
Definition: poptint.h:116
static void invokeCallbacksPOST(poptContext con, const struct poptOption *opt)
Definition: popt.c:98
int poptBitsChk(poptBits bits, const char *s)
Definition: popt.c:804
int poptAddAlias(poptContext con, struct poptAlias alias, int flags)
Add alias to context.
Definition: popt.c:1636
#define POPT_ARG_MAINCALL
Definition: popt.h:44
struct optionStackEntry * os
Definition: poptint.h:118
#define PBM_ISSET(d, s)
Definition: poptint.h:45
pbm_set * argb
Definition: poptint.h:104
static int handleAlias(poptContext con, const char *longName, size_t longNameLen, char shortName, const char *nextArg)
Definition: popt.c:353
char shortName
Definition: popt.h:135
static int handleExec(poptContext con, const char *longName, char shortName)
Definition: popt.c:255
int numLeftovers
Definition: poptint.h:121
float * floatp
Definition: poptint.h:70
void(* poptCallbackType)(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, const void *data)
Table callback prototype.
Definition: popt.h:241
const char * longName
Definition: popt.h:134
const struct poptOption * options
Definition: poptint.h:124
static unsigned int poptArgInfo(poptContext con, const struct poptOption *opt)
Return argInfo field, handling POPT_ARGFLAG_TOGGLE overrides.
Definition: popt.c:1131
void * xrealloc(void *ptr, size_t size)
A union to simplify opt->arg access without casting.
Definition: poptint.h:63
int val
Definition: popt.h:139
#define CBF_ISSET(_opt, _FLAG)
Definition: poptint.h:91
const char ** argv
Definition: popt.h:166
int nextLeftover
Definition: poptint.h:122
int poptStuffArgs(poptContext con, const char **argv)
Add arguments to context.
Definition: popt.c:1737
const char * appName
Definition: poptint.h:127
poptItem doExec
Definition: poptint.h:142
const char * poptStrerror(const int error)
Return formatted error string for popt failure.
Definition: popt.c:1707
#define POPT_ARGFLAG_DOC_HIDDEN
Definition: popt.h:59
int finalArgvCount
Definition: poptint.h:137
poptString * poptArgv
Definition: poptint.h:56
int argc
Definition: popt.h:153
#define POPT_(foo)
Definition: poptint.h:218
int poptBitsIntersect(poptBits *ap, const poptBits b)
Definition: popt.c:857
static const char * findNextArg(poptContext con, unsigned argx, int delete_arg)
Definition: popt.c:648
int poptSaveInt(int *arg, unsigned int argInfo, long aLong)
Save an integer, performing logical operation with value.
Definition: popt.c:1056
#define PBM_SET(d, s)
Definition: poptint.h:43
#define POPT_ARG_INT
Definition: popt.h:22
char * nextArg
Definition: poptint.h:107
unsigned int _poptArgMask
Definition: popt.c:34
#define PBM_FREE(s)
Definition: poptint.h:42
#define POPT_ARG_FLOAT
Definition: popt.h:40
int execAbsolute
Definition: poptint.h:145
#define POPT_ARG_LONG
Definition: popt.h:23
int restLeftover
Definition: poptint.h:125
#define _POPT_BITS_N
Definition: popt.h:696
#define _POPT_BITS_M
Definition: popt.h:697
int poptStrippedArgv(poptContext con, int argc, char **argv)
Shuffle argv pointers to remove stripped args, returns new argc.
Definition: popt.c:1765
int argc
Definition: popt.h:164
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: poptint.h:20
static const char * findProgramPath(const char *argv0)
Return absolute path to executable by searching PATH.
Definition: popt.c:432
#define F_ISSET(_opt, _FLAG)
Definition: poptint.h:89
int poptSaveString(const char ***argvp, unsigned int argInfo, const char *val)
Add a string to an argv array.
Definition: popt.c:953
#define POPT_ARGFLAG_OR
Definition: popt.h:63
static void invokeCallbacksPRE(poptContext con, const struct poptOption *opt)
Definition: popt.c:74
int poptBitsDel(poptBits bits, const char *s)
Definition: popt.c:838
#define POPT_ARG_CALLBACK
Definition: popt.h:25
#define POPT_ERROR_OVERFLOW
Definition: popt.h:106
poptContext poptFreeContext(poptContext con)
Destroy context.
Definition: popt.c:1613
static int longOptionStrcmp(const struct poptOption *opt, const char *longName, size_t longNameLen)
Compare long option for equality, adjusting for POPT_ARGFLAG_TOGGLE.
Definition: popt.c:321
#define POPT_OPTION_DEPTH
Definition: popt.h:14
#define POPT_ARGFLAG_XOR
Definition: popt.h:67
char * xstrdup(const char *str)
unsigned int _poptBitsN
Definition: popt.c:756
#define _POPT_BITS_K
Definition: popt.h:698
static int poptSaveArg(poptContext con, const struct poptOption *opt)
Save the option argument through the (*opt->arg) pointer.
Definition: popt.c:1185
int * intp
Definition: poptint.h:66
void poptSetExecPath(poptContext con, const char *path, int allowAbsolute)
Limit search for executables.
Definition: popt.c:66
unsigned int flags
Definition: poptint.h:131
static int execCommand(poptContext con)
Definition: popt.c:476
const char * nextCharArg
Definition: poptint.h:109
int numExecs
Definition: poptint.h:134
#define POPT_CONTEXT_KEEP_FIRST
Definition: popt.h:125
const char * poptPeekArg(poptContext con)
Peek at current argument.
Definition: popt.c:1571
#define POPT_ABS(a)
#define POPT_ARG_BITSET
Definition: popt.h:47
#define __PBM_BITS(set)
Definition: poptint.h:39
int poptAddItem(poptContext con, poptItem newItem, int flags)
Add alias/exec item to context.
Definition: popt.c:1654
int poptBitsUnion(poptBits *ap, const poptBits b)
Definition: popt.c:877
static const struct poptOption * findOption(const struct poptOption *opt, const char *longName, size_t longNameLen, char shortName, poptCallbackType *callback, const void **callbackData, unsigned int argInfo)
Definition: popt.c:579
const char * execPath
Definition: poptint.h:144
double * doublep
Definition: poptint.h:71
const char * otherHelp
Definition: poptint.h:147
#define POPT_ARGFLAG_NOT
Definition: popt.h:68
int poptSaveLong(long *arg, unsigned int argInfo, long aLong)
Save a long, performing logical operation with value.
Definition: popt.c:1023
#define __PBM_IX(d)
Definition: poptint.h:32
#define __PBM_NBITS
Definition: poptint.h:31
poptArgv leftovers
Definition: poptint.h:120
#define POPT_ARG_STRING
Definition: popt.h:21
#define POPT_ERROR_MALLOC
Definition: popt.h:109
const char * descrip
Definition: popt.h:141
int finalArgvAlloced
Definition: poptint.h:138
int poptSaveLongLong(long long *arg, unsigned int argInfo, long long aLongLong)
Save a long long, performing logical operation with value.
Definition: popt.c:978
#define POPT_ARGFLAG_ONEDASH
Definition: popt.h:58
#define LF_ISSET(_FLAG)
Definition: poptint.h:90
#define POPT_ARG_MASK
Definition: popt.h:49
#define POPT_ERROR_NOARG
Definition: popt.h:100
static void poptStripArg(poptContext con, int which)
Definition: popt.c:741
long * longp
Definition: poptint.h:68
static unsigned int seed
Definition: popt.c:976
int poptBitsAdd(poptBits bits, const char *s)
Definition: popt.c:785
static char * strerror(int errno)
Definition: popt.c:39
static void cleanOSE(struct optionStackEntry *os)
Definition: popt.c:211
#define POPT_GROUP_MASK
Definition: popt.h:50
#define POPT_ARG_VAL
Definition: popt.h:39

Generated for popt by  doxygen 1.8.13