AJA NTV2 SDK  17.5.0.1242
NTV2 SDK 17.5.0.1242
options_popt.cpp
Go to the documentation of this file.
1 
5 /* This file is a port of the popt library for use with the AJA SDK.
6  * The code for the library was consolidated into a .h and .cpp file
7  * to simplify building demonstration applications. Not all the features
8  * of popt have been tested. Only simple command line parameter parsing
9  * was needed for the SDK, but popt was ported to allow enhancing our
10  * applications with additional functionality as needed.
11 */
12 
13 /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
14  file accompanying popt source distributions, available from
15  ftp://ftp.rpm.org/pub/rpm/dist */
16 
17 /* Here is the contents of the COPYING file:
18 */
19 
20 /*
21 Copyright (c) 1998 Red Hat Software
22 
23 Permission is hereby granted, free of charge, to any person obtaining a copy
24 of this software and associated documentation files (the "Software"), to deal
25 in the Software without restriction, including without limitation the rights
26 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
27 copies of the Software, and to permit persons to whom the Software is
28 furnished to do so, subject to the following conditions:
29 
30 The above copyright notice and this permission notice shall be included in
31 all copies or substantial portions of the Software.
32 
33 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
37 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
38 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
39 
40 Except as contained in this notice, the name of the X Consortium shall not be
41 used in advertising or otherwise to promote the sale, use or other dealings
42 in this Software without prior written authorization from the X Consortium.
43 */
44 
45 #undef MYDEBUG
46 
47 #include "ajabase/system/file_io.h"
48 
49 /* This section handles platform differences
50 */
51 
52 #if defined(AJA_LINUX) || defined (AJA_MAC)
53 
54 #include <stdint.h>
55 #include <sys/ioctl.h>
56 #include <sys/types.h>
57 #include <unistd.h>
58 
59 #define POPT_SYSCONFDIR "."
60 
61 #endif
62 
63 #if defined (AJA_MAC)
64 #pragma GCC diagnostic ignored "-Wunused-const-variable"
65 #endif
66 
67 #if defined(AJA_WINDOWS)
68 
69 #pragma warning (disable:4302)
70 #pragma warning (disable:4311)
71 #pragma warning (disable:4996)
72 
73 #include <BaseTsd.h>
74 #include <io.h>
75 #include <process.h>
76 #include <sys/stat.h>
77 
78 typedef signed __int8 int8_t;
79 typedef signed __int16 int16_t;
80 typedef signed __int32 int32_t;
81 typedef signed __int64 int64_t;
82 typedef unsigned __int8 uint8_t;
83 typedef unsigned __int16 uint16_t;
84 typedef unsigned __int32 uint32_t;
85 typedef unsigned __int64 uint64_t;
86 
87 typedef short uid_t;
88 static uid_t getuid() { return 0; }
89 
90 #define strtoll _strtoi64
91 
92 #define execvp(a, b) _spawnvp(_P_OVERLAY, (a), (b))
93 
94 #define X_OK 0
95 static bool access(char* t, int x) {return true;}
96 
97 #define POPT_SYSCONFDIR "."
98 
99 #define ssize_t SSIZE_T
100 
101 #define open(a, b) _open((a), (b))
102 #define close(a) _close((a))
103 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
104 #define S_IWGRP 0
105 #define S_IWOTH 0
106 
107 /* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */
108 inline char * stpcpy (char *dest, const char * src) {
109  register char *d = dest;
110  register const char *s = src;
111 
112  do
113  *d++ = *s;
114  while (*s++ != '\0');
115  return d - 1;
116 }
117 
118 #else
119 #pragma GCC diagnostic ignored "-Wunused-parameter"
120 #if defined (AJA_LINUX)
121  #pragma GCC diagnostic ignored "-Wmisleading-indentation"
122 #endif
123 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
124 #endif
125 
126 #if defined(AJA_BAREMETAL)
127 static uid_t getuid() { return 0; }
128 #define POPT_SYSCONFDIR "."
129 #define X_OK 0
130 static bool access(char* t, int x) {return true;}
131 #include <limits.h>
132 # undef LLONG_MIN
133 # define LLONG_MIN (-LLONG_MAX-1)
134 # undef LLONG_MAX
135 # define LLONG_MAX __LONG_LONG_MAX__
136 //TODO
137 #define execvp(a, b)
138 #endif
139 
140 /* End of platform differences section
141 */
142 
143 /* This section is from popt's system.h
144 */
145 
146 #include <ctype.h>
147 
148 /* XXX isspace(3) has i18n encoding signednesss issues on Solaris. */
149 #define _isspaceptr(_chp) isspace((int)(*(unsigned char *)(_chp)))
150 
151 #include <errno.h>
152 #include <fcntl.h>
153 #include <limits.h>
154 
155 #include <stdio.h>
156 #include <stdlib.h>
157 #include <string.h>
158 
159 void * xmalloc (size_t size);
160 
161 void * xcalloc (size_t nmemb, size_t size);
162 
163 void * xrealloc (void * ptr, size_t size);
164 
165 char * xstrdup (const char *str);
166 
167 /* Memory allocation via macro defs to get meaningful locations from mtrace() */
168 #define xmalloc(_size) malloc(_size)
169 #define xcalloc(_nmemb, _size) calloc((_nmemb), (_size))
170 #define xrealloc(_ptr, _size) realloc((_ptr), (_size))
171 #define xstrdup(_str) strdup(_str)
172 
173 #include "options_popt.h"
174 
175 /* End of section from popt's system.h
176 */
177 
178 #include <float.h>
179 #include <math.h>
180 
181 /* This section is from poptint.h
182 */
183 
189 static inline void *
190 _free(const void * p)
191 {
192  if (p != NULL) free((void *)p);
193  return NULL;
194 }
195 
196 /* Bit mask macros. */
197 typedef unsigned int __pbm_bits;
198 #define __PBM_NBITS (8 * sizeof (__pbm_bits))
199 #define __PBM_IX(d) ((d) / __PBM_NBITS)
200 #define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS))
201 typedef struct {
202  __pbm_bits bits[1];
203 } pbm_set;
204 #define __PBM_BITS(set) ((set)->bits)
205 
206 #define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits))
207 #define PBM_FREE(s) _free(s);
208 #define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d))
209 #define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d))
210 #define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0)
211 
212 extern void poptJlu32lpair(const void *key, size_t size,
213  uint32_t *pc, uint32_t *pb);
214 
218 typedef const char * poptString;
220 
224 typedef union poptArg_u {
225  void * ptr;
226  int * intp;
227  short * shortp;
228  long * longp;
229  long long * longlongp;
230  float * floatp;
231  double * doublep;
232  const char ** argv;
235 } poptArg;
236 
237 extern unsigned int _poptArgMask;
238 extern unsigned int _poptGroupMask;
239 
240 #define poptArgType(_opt) ((_opt)->argInfo & _poptArgMask)
241 #define poptGroup(_opt) ((_opt)->argInfo & _poptGroupMask)
242 
243 #define F_ISSET(_opt, _FLAG) ((_opt)->argInfo & POPT_ARGFLAG_##_FLAG)
244 #define LF_ISSET(_FLAG) (argInfo & POPT_ARGFLAG_##_FLAG)
245 #define CBF_ISSET(_opt, _FLAG) ((_opt)->argInfo & POPT_CBFLAG_##_FLAG)
246 
250 #define _POPTHELP_MAXLINE ((size_t)79)
251 
252 static struct poptOption poptHelpOptions[] = {
253  { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
254  { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
255  { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
257 } ;
259 
260 /* XXX sick hack to preserve pretense of a popt-1.x ABI. */
261 static struct poptOption poptHelpOptions2[] = {
262  { NULL, '\0', POPT_ARG_INTL_DOMAIN, (void*)"PACKAGE", 0, NULL, NULL},
263  { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
264  { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
265  { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
266  { "", '\0', 0, NULL, 0, N_("Terminate options"), NULL },
268 } ;
269 
271 
272 #define poptSubstituteHelpI18N(opt) \
273  { \
274  if ((&opt) == poptHelpOptions) (opt) = *poptHelpOptionsI18N; \
275  }
276 
277 
279  int argc;
282  int next;
283  char * nextArg;
284  const char * nextCharArg;
286  int stuffed;
287 };
288 
295  const struct poptOption * options;
297  const char * appName;
300  unsigned int flags;
302  int numExecs;
306  int (*maincall) (int argc, const char **argv);
308  const char * execPath;
310  const char * otherHelp;
312 };
313 
314 int POPT_fprintf (FILE* stream, const char *format, ...);
315 
316 const char *POPT_prev_char (const char *str);
317 
318 const char *POPT_next_char (const char *str);
319 
320 #define _(foo) foo
321 
322 #define D_(dom, str) str
323 #define POPT_(foo) foo
324 
325 /* End of section from poptint.h
326 */
327 
328 /* This section is from poptconfig.cpp
329 */
330 
331 #include <sys/stat.h>
332 
341 static int poptGlob(UNUSED(poptContext con), const char * pattern,
342  int * acp, const char *** avp)
343 {
344  const char * pat = pattern;
345  int rc = 0; /* assume success */
346 
347  /* XXX skip the attention marker. */
348  if (pat[0] == '@' && pat[1] != '(')
349  pat++;
350 
351  {
352  if (acp)
353  *acp = 1;
354  if (avp && (*avp = (const char**)calloc((size_t)(1 + 1), sizeof (**avp))) != NULL)
355  (*avp)[0] = xstrdup(pat);
356  }
357 
358  return rc;
359 }
360 
361 int poptSaneFile(const char * fn)
362 {
363  struct stat sb;
364  uid_t uid = getuid();
365 
366  if (stat(fn, &sb) == -1)
367  return 1;
368  if ((uid_t)sb.st_uid != uid)
369  return 0;
370  if (!S_ISREG(sb.st_mode))
371  return 0;
372  if (sb.st_mode & (S_IWGRP|S_IWOTH))
373  return 0;
374  return 1;
375 }
376 
377 int poptReadFile(const char * fn, char ** bp, size_t * nbp, int flags)
378 {
379  AJAFileIO file;
380  char * b = NULL;
381  off_t nb = 0;
382  char * s, * t, * se;
383  int rc = POPT_ERROR_ERRNO; /* assume failure */
384 
385  if (file.Open(fn, eAJAReadOnly, 0) != AJA_STATUS_SUCCESS)
386  goto exit;
387 
388  if ((file.Seek(0, eAJASeekEnd)) != AJA_STATUS_SUCCESS
389  || (nb = file.Tell()) == (off_t)-1
390  || file.Seek(0, eAJASeekSet) != AJA_STATUS_SUCCESS
391  || (b = (char*)calloc(sizeof(*b), (size_t)nb + 1)) == NULL
392  || file.Read((uint8_t *)b, (uint32_t)nb) != (uint32_t)nb)
393  {
394  int oerrno = errno;
395  (void) file.Close();
396  errno = oerrno;
397  goto exit;
398  }
399  if (file.Close() != AJA_STATUS_SUCCESS)
400  goto exit;
401  if (b == NULL) {
402  rc = POPT_ERROR_MALLOC;
403  goto exit;
404  }
405  rc = 0;
406 
407  /* Trim out escaped newlines. */
408  if (flags & POPT_READFILE_TRIMNEWLINES)
409  {
410  for (t = b, s = b, se = b + nb; *s && s < se; s++) {
411  switch (*s) {
412  case '\\':
413  if (s[1] == '\n') {
414  s++;
415  continue;
416  }
417  default:
418  *t++ = *s;
419  break;
420  }
421  }
422  *t++ = '\0';
423  nb = (off_t)(t - b);
424  }
425 
426 exit:
427  if (rc != 0) {
428  if (b)
429  free(b);
430  b = NULL;
431  nb = 0;
432  }
433  if (bp)
434  *bp = b;
435  else if (b)
436  free(b);
437  if (nbp)
438  *nbp = (size_t)nb;
439  return rc;
440 }
441 
448 static int configAppMatch(poptContext con, const char * s)
449 {
450  int rc = 1;
451 
452  if (con->appName == NULL) /* XXX can't happen. */
453  return rc;
454 
455  rc = strcmp(s, con->appName);
456  return rc;
457 }
458 
459 static int poptConfigLine(poptContext con, char * line)
460 {
461  char *b = NULL;
462  size_t nb = 0;
463  char * se = line;
464  const char * appName;
465  const char * entryType;
466  const char * opt;
467  struct poptItem_s item_buf;
468  poptItem item = &item_buf;
469  int i, j;
470  int rc = POPT_ERROR_BADCONFIG;
471 
472  if (con->appName == NULL)
473  goto exit;
474 
475  memset(item, 0, sizeof(*item));
476 
477  appName = se;
478  while (*se != '\0' && !_isspaceptr(se)) se++;
479  if (*se == '\0')
480  goto exit;
481  else
482  *se++ = '\0';
483 
484  if (configAppMatch(con, appName)) goto exit;
485 
486  while (*se != '\0' && _isspaceptr(se)) se++;
487  entryType = se;
488  while (*se != '\0' && !_isspaceptr(se)) se++;
489  if (*se != '\0') *se++ = '\0';
490 
491  while (*se != '\0' && _isspaceptr(se)) se++;
492  if (*se == '\0') goto exit;
493  opt = se;
494  while (*se != '\0' && !_isspaceptr(se)) se++;
495  if (opt[0] == '-' && *se == '\0') goto exit;
496  if (*se != '\0') *se++ = '\0';
497 
498  while (*se != '\0' && _isspaceptr(se)) se++;
499  if (opt[0] == '-' && *se == '\0') goto exit;
500 
501  if (opt[0] == '-' && opt[1] == '-')
502  item->option.longName = opt + 2;
503  else if (opt[0] == '-' && opt[2] == '\0')
504  item->option.shortName = opt[1];
505  else {
506  const char * fn = opt;
507 
508  /* XXX handle globs and directories in fn? */
509  if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0)
510  goto exit;
511  if (b == NULL || nb == 0)
512  goto exit;
513 
514  /* Append remaining text to the interpolated file option text. */
515  if (*se != '\0') {
516  size_t nse = strlen(se) + 1;
517  if ((b = (char*)realloc(b, (nb + nse))) == NULL) /* XXX can't happen */
518  goto exit;
519  (void) stpcpy( stpcpy(&b[nb-1], " "), se);
520  nb += nse;
521  }
522  se = b;
523 
524  /* Use the basename of the path as the long option name. */
525  { const char * longName = strrchr(fn, '/');
526  if (longName != NULL)
527  longName++;
528  else
529  longName = fn;
530  if (longName == NULL) /* XXX can't happen. */
531  goto exit;
532  /* Single character basenames are treated as short options. */
533  if (longName[1] != '\0')
534  item->option.longName = longName;
535  else
536  item->option.shortName = longName[0];
537  }
538  }
539 
540  if (poptParseArgvString(se, &item->argc, &item->argv)) goto exit;
541 
542  item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
543  for (i = 0, j = 0; i < item->argc; i++, j++) {
544  const char * f;
545  if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
546  f = item->argv[i] + sizeof("--POPTdesc=");
547  if (f[0] == '$' && f[1] == '"') f++;
548  item->option.descrip = f;
549  item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
550  j--;
551  } else
552  if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
553  f = item->argv[i] + sizeof("--POPTargs=");
554  if (f[0] == '$' && f[1] == '"') f++;
555  item->option.argDescrip = f;
556  item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
557  item->option.argInfo |= POPT_ARG_STRING;
558  j--;
559  } else
560  if (j != i)
561  item->argv[j] = item->argv[i];
562  }
563  if (j != i) {
564  item->argv[j] = NULL;
565  item->argc = j;
566  }
567 
568  if (!strcmp(entryType, "alias"))
569  rc = poptAddItem(con, item, 0);
570  else if (!strcmp(entryType, "exec"))
571  rc = poptAddItem(con, item, 1);
572 exit:
573  rc = 0; /* XXX for now, always return success */
574  if (b)
575  free(b);
576  return rc;
577 }
578 
579 int poptReadConfigFile(poptContext con, const char * fn)
580 {
581  char * b = NULL, *be;
582  size_t nb = 0;
583  const char *se;
584  char *t, *te;
585  int rc;
586 
587  if ((rc = poptReadFile(fn, &b, &nb, POPT_READFILE_TRIMNEWLINES)) != 0)
588  return (errno == ENOENT ? 0 : rc);
589  if (b == NULL || nb == 0)
590  return POPT_ERROR_BADCONFIG;
591 
592  if ((t = (char*)malloc(nb + 1)) == NULL)
593  goto exit;
594  te = t;
595 
596  be = (b + nb);
597  for (se = b; se < be; se++) {
598  switch (*se) {
599  case '\n':
600  *te = '\0';
601  te = t;
602  while (*te && _isspaceptr(te)) te++;
603  if (*te && *te != '#')
604  poptConfigLine(con, te);
605  break;
606  case '\\':
607  *te = *se++;
608  /* \ at the end of a line does not insert a \n */
609  if (se < be && *se != '\n') {
610  te++;
611  *te++ = *se;
612  }
613  break;
614  default:
615  *te++ = *se;
616  break;
617  }
618  }
619 
620  free(t);
621  rc = 0;
622 
623 exit:
624  if (b)
625  free(b);
626  return rc;
627 }
628 
629 int poptReadConfigFiles(poptContext con, const char * paths)
630 {
631  char * buf = (paths ? xstrdup(paths) : NULL);
632  const char * p;
633  char * pe;
634  int rc = 0; /* assume success */
635 
636  for (p = buf; p != NULL && *p != '\0'; p = pe) {
637  const char ** av = NULL;
638  int ac = 0;
639  int i;
640  int xx;
641 
642  /* locate start of next path element */
643  pe = (char*)strchr(p, ':');
644  if (pe != NULL && *pe == ':')
645  *pe++ = '\0';
646  else
647  pe = (char *) (p + strlen(p));
648 
649  xx = poptGlob(con, p, &ac, &av);
650 
651  /* work-off each resulting file from the path element */
652  for (i = 0; i < ac; i++) {
653  const char * fn = av[i];
654  if (av[i] == NULL) /* XXX can't happen */
655  continue;
656  /* XXX should '@' attention be pushed into poptReadConfigFile? */
657  if (p[0] == '@' && p[1] != '(') {
658  if (fn[0] == '@' && fn[1] != '(')
659  fn++;
660  xx = poptSaneFile(fn);
661  if (!xx && rc == 0)
663  continue;
664  }
665  xx = poptReadConfigFile(con, fn);
666  if (xx && rc == 0)
667  rc = xx;
668  free((void *)av[i]);
669  av[i] = NULL;
670  }
671  free(av);
672  av = NULL;
673  }
674 
675  if (buf)
676  free(buf);
677 
678  return rc;
679 }
680 
682 {
683  static const char _popt_sysconfdir[] = POPT_SYSCONFDIR "/popt";
684  static const char _popt_etc[] = "/etc/popt";
685  char * home;
686  int rc = 0; /* assume success */
687 
688  if (con->appName == NULL) goto exit;
689 
690  if (strcmp(_popt_sysconfdir, _popt_etc)) {
691  rc = poptReadConfigFile(con, _popt_sysconfdir);
692  if (rc) goto exit;
693  }
694 
695  rc = poptReadConfigFile(con, _popt_etc);
696  if (rc) goto exit;
697 
698  if ((home = getenv("HOME"))) {
699  char * fn = (char*)malloc(strlen(home) + 20);
700  if (fn != NULL) {
701  (void) stpcpy(stpcpy(fn, home), "/.popt");
702  rc = poptReadConfigFile(con, fn);
703  free(fn);
704  } else
705  rc = POPT_ERROR_ERRNO;
706  if (rc) goto exit;
707  }
708 
709 exit:
710  return rc;
711 }
712 
715 {
716  return poptFreeContext(con);
717 }
718 
720 poptInit(int argc, const char ** argv,
721  const struct poptOption * options, const char * configPaths)
722 {
723  poptContext con = NULL;
724  const char * argv0;
725 
726  if (argv == NULL || argv[0] == NULL || options == NULL)
727  return con;
728 
729  if ((argv0 = strrchr(argv[0], '/')) != NULL) argv0++;
730  else argv0 = argv[0];
731 
732  con = poptGetContext(argv0, argc, (const char **)argv, options, 0);
733  if (con != NULL&& poptReadConfigFiles(con, configPaths))
734  con = poptFini(con);
735 
736  return con;
737 }
738 
739 /* End of section from poptconfig.cpp
740 */
741 
742 /* This section is from popthelp.cpp
743 */
744 
745 #define POPT_WCHAR_HACK
746 #ifdef POPT_WCHAR_HACK
747 #ifndef AJAMac
748 #include <wchar.h> /* for mbsrtowcs */
749 #endif
750 #endif
751 
761  UNUSED(enum poptCallbackReason foo),
762  struct poptOption * key,
763  UNUSED(const char * arg),
764  UNUSED(void * data))
765 {
766  if (key->shortName == '?')
767  poptPrintHelp(con, stdout, 0);
768  else
769  poptPrintUsage(con, stdout, 0);
770 
771  exit(0);
772 }
773 
779 };
780 
781 typedef struct columns_s {
782  size_t cur;
783  size_t max;
784 } * columns_t;
785 
791 static size_t maxColumnWidth(FILE *fp)
792 {
793  size_t maxcols = _POPTHELP_MAXLINE;
794  return maxcols;
795 }
796 
802 static inline size_t stringDisplayWidth(const char *s)
803 {
804  size_t n = strlen(s);
805 #ifndef AJAMac
806  mbstate_t t;
807 
808  memset ((void *)&t, 0, sizeof (t)); /* In initial state. */
809  /* Determine number of display characters. */
810  n = mbsrtowcs (NULL, &s, n, &t);
811 #endif
812  return n;
813 }
814 
818 static const char *
820 {
821  if (opt != NULL)
822  for (; opt->longName || opt->shortName || opt->arg; opt++) {
823  if (opt->argInfo == POPT_ARG_INTL_DOMAIN)
824  return (const char*)opt->arg;
825  }
826  return NULL;
827 }
828 
833 static const char *
834 getArgDescrip(const struct poptOption * opt,
835  const char * translation_domain)
836 {
837  if (!poptArgType(opt)) return NULL;
838 
839  if (poptArgType(opt) == POPT_ARG_MAINCALL)
840  return opt->argDescrip;
841  if (poptArgType(opt) == POPT_ARG_ARGV)
842  return opt->argDescrip;
843 
844  if (opt->argDescrip) {
845  /* Some strings need popt library, not application, i18n domain. */
846  if (opt == (poptHelpOptions + 1)
847  || opt == (poptHelpOptions + 2)
848  || !strcmp(opt->argDescrip, N_("Help options:"))
849  || !strcmp(opt->argDescrip, N_("Options implemented via popt alias/exec:")))
850  return POPT_(opt->argDescrip);
851 
852  /* Use the application i18n domain. */
853  return D_(translation_domain, opt->argDescrip);
854  }
855 
856  switch (poptArgType(opt)) {
857  case POPT_ARG_NONE: return POPT_("NONE");
858 #ifdef DYING
859  case POPT_ARG_VAL: return POPT_("VAL");
860 #else
861  case POPT_ARG_VAL: return NULL;
862 #endif
863  case POPT_ARG_INT: return POPT_("INT");
864  case POPT_ARG_SHORT: return POPT_("SHORT");
865  case POPT_ARG_LONG: return POPT_("LONG");
866  case POPT_ARG_LONGLONG: return POPT_("LONGLONG");
867  case POPT_ARG_STRING: return POPT_("STRING");
868  case POPT_ARG_FLOAT: return POPT_("FLOAT");
869  case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
870  case POPT_ARG_MAINCALL: return NULL;
871  case POPT_ARG_ARGV: return NULL;
872  default: return POPT_("ARG");
873  }
874 }
875 
883 static char *
884 singleOptionDefaultValue(size_t lineLength,
885  const struct poptOption * opt,
886  const char * translation_domain)
887 {
888  const char * defstr = D_(translation_domain, "default");
889  char * le = (char*)malloc(4*lineLength + 1);
890  char * l = le;
891 
892  if (le == NULL) return NULL; /* XXX can't happen */
893  *le = '\0';
894  *le++ = '(';
895  le = stpcpy(le, defstr);
896  *le++ = ':';
897  *le++ = ' ';
898  if (opt->arg) { /* XXX programmer error */
899  poptArg arg;
900  arg.ptr = opt->arg;
901  switch (poptArgType(opt)) {
902  case POPT_ARG_VAL:
903  case POPT_ARG_INT:
904  le += sprintf(le, "%d", arg.intp[0]);
905  break;
906  case POPT_ARG_SHORT:
907  le += sprintf(le, "%hd", arg.shortp[0]);
908  break;
909  case POPT_ARG_LONG:
910  le += sprintf(le, "%ld", arg.longp[0]);
911  break;
912  case POPT_ARG_LONGLONG:
913  le += sprintf(le, "%lld", arg.longlongp[0]);
914  break;
915  case POPT_ARG_FLOAT:
916  { double aDouble = (double) arg.floatp[0];
917  le += sprintf(le, "%g", aDouble);
918  } break;
919  case POPT_ARG_DOUBLE:
920  le += sprintf(le, "%g", arg.doublep[0]);
921  break;
922  case POPT_ARG_MAINCALL:
923  le += sprintf(le, "%p", opt->arg);
924  break;
925  case POPT_ARG_ARGV:
926  le += sprintf(le, "%p", opt->arg);
927  break;
928  case POPT_ARG_STRING:
929  { const char * s = arg.argv[0];
930  if (s == NULL)
931  le = stpcpy(le, "null");
932  else {
933  size_t limit = 4*lineLength - (le - l) - sizeof("\"\")");
934  size_t slen;
935  *le++ = '"';
936  strncpy(le, s, limit); le[limit] = '\0'; le += (slen = strlen(le));
937  if (slen == limit && s[limit])
938  le[-1] = le[-2] = le[-3] = '.';
939  *le++ = '"';
940  }
941  } break;
942  case POPT_ARG_NONE:
943  default:
944  l = (char*)_free(l);
945  return NULL;
946  break;
947  }
948  }
949  *le++ = ')';
950  *le = '\0';
951 
952  return l;
953 }
954 
962 static void singleOptionHelp(FILE * fp, columns_t columns,
963  const struct poptOption * opt,
964  const char * translation_domain)
965 {
966  size_t maxLeftCol = columns->cur;
967  size_t indentLength = maxLeftCol + 5;
968  size_t lineLength = columns->max - indentLength;
969  const char * help = D_(translation_domain, opt->descrip);
970  const char * argDescrip = getArgDescrip(opt, translation_domain);
971  /* Display shortName iff printable non-space. */
972  int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' ');
973  size_t helpLength;
974  char * defs = NULL;
975  char * left;
976  size_t nb = maxLeftCol + 1;
977  int displaypad = 0;
978 
979  /* Make sure there's more than enough room in target buffer. */
980  if (opt->longName) nb += strlen(opt->longName);
981  if (F_ISSET(opt, TOGGLE)) nb += sizeof("[no]") - 1;
982  if (argDescrip) nb += strlen(argDescrip);
983 
984  left = (char*)malloc(nb);
985  if (left == NULL) return; /* XXX can't happen */
986  left[0] = '\0';
987  left[maxLeftCol] = '\0';
988 
989 #define prtlong (opt->longName != NULL) /* XXX splint needs a clue */
990  if (!(prtshort || prtlong))
991  goto out;
992  if (prtshort && prtlong) {
993  char *dash = F_ISSET(opt, ONEDASH) ? (char*)"-" : (char*)"--";
994  left[0] = '-';
995  left[1] = opt->shortName;
996  (void) stpcpy(stpcpy(stpcpy(left+2, ", "), dash), opt->longName);
997  } else if (prtshort) {
998  left[0] = '-';
999  left[1] = opt->shortName;
1000  left[2] = '\0';
1001  } else if (prtlong) {
1002  /* XXX --long always padded for alignment with/without "-X, ". */
1003  char *dash = poptArgType(opt) == POPT_ARG_MAINCALL ? (char*)""
1004  : (F_ISSET(opt, ONEDASH) ? (char*)"-" : (char*)"--");
1005  const char *longName = opt->longName;
1006  const char *toggle;
1007  if (F_ISSET(opt, TOGGLE)) {
1008  toggle = "[no]";
1009  if (longName[0] == 'n' && longName[1] == 'o') {
1010  longName += sizeof("no") - 1;
1011  if (longName[0] == '-')
1012  longName++;
1013  }
1014  } else
1015  toggle = "";
1016  (void) stpcpy(stpcpy(stpcpy(stpcpy(left, " "), dash), toggle), longName);
1017  }
1018 #undef prtlong
1019 
1020  if (argDescrip) {
1021  char * le = left + strlen(left);
1022 
1023  if (F_ISSET(opt, OPTIONAL))
1024  *le++ = '[';
1025 
1026  /* Choose type of output */
1027  if (F_ISSET(opt, SHOW_DEFAULT)) {
1028  defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
1029  if (defs) {
1030  char * t = (char*)malloc((help ? strlen(help) : 0) +
1031  strlen(defs) + sizeof(" "));
1032  if (t) {
1033  char * te = t;
1034  if (help)
1035  te = stpcpy(te, help);
1036  *te++ = ' ';
1037  strcpy(te, defs);
1038  defs = (char*)_free(defs);
1039  defs = t;
1040  }
1041  }
1042  }
1043 
1044  if (opt->argDescrip == NULL) {
1045  switch (poptArgType(opt)) {
1046  case POPT_ARG_NONE:
1047  break;
1048  case POPT_ARG_VAL:
1049  break;
1050  case POPT_ARG_INT:
1051  case POPT_ARG_SHORT:
1052  case POPT_ARG_LONG:
1053  case POPT_ARG_LONGLONG:
1054  case POPT_ARG_FLOAT:
1055  case POPT_ARG_DOUBLE:
1056  case POPT_ARG_STRING:
1057  *le++ = (opt->longName != NULL ? '=' : ' ');
1058  le = stpcpy(le, argDescrip);
1059  break;
1060  default:
1061  break;
1062  }
1063  } else {
1064  char *leo;
1065 
1066  /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */
1067  if (!strchr(" =(", argDescrip[0]))
1068  *le++ = ((poptArgType(opt) == POPT_ARG_MAINCALL) ? ' ' :
1069  (poptArgType(opt) == POPT_ARG_ARGV) ? ' ' : '=');
1070  le = stpcpy(leo = le, argDescrip);
1071 
1072  /* Adjust for (possible) wide characters. */
1073  displaypad = (int)((le - leo) - stringDisplayWidth(argDescrip));
1074  }
1075  if (F_ISSET(opt, OPTIONAL))
1076  *le++ = ']';
1077  *le = '\0';
1078  }
1079 
1080  if (help)
1081  POPT_fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left);
1082  else {
1083  POPT_fprintf(fp," %s\n", left);
1084  goto out;
1085  }
1086 
1087  left = (char*)_free(left);
1088  if (defs)
1089  help = defs;
1090 
1091  helpLength = strlen(help);
1092  while (helpLength > lineLength) {
1093  const char * ch;
1094  char format[16];
1095 
1096  ch = help + lineLength - 1;
1097  while (ch > help && !_isspaceptr(ch))
1098  ch = POPT_prev_char(ch);
1099  if (ch == help) break; /* give up */
1100  while (ch > (help + 1) && _isspaceptr(ch))
1101  ch = POPT_prev_char (ch);
1102  ch = POPT_next_char(ch);
1103 
1104  /*
1105  * XXX strdup is necessary to add NUL terminator so that an unknown
1106  * no. of (possible) multi-byte characters can be displayed.
1107  */
1108  { char * fmthelp = xstrdup(help);
1109  if (fmthelp) {
1110  fmthelp[ch - help] = '\0';
1111  sprintf(format, "%%s\n%%%ds", (int) indentLength);
1112  POPT_fprintf(fp, format, fmthelp, " ");
1113  free(fmthelp);
1114  }
1115  }
1116 
1117  help = ch;
1118  while (_isspaceptr(help) && *help)
1119  help = POPT_next_char(help);
1120  helpLength = strlen(help);
1121  }
1122 
1123  if (helpLength) fprintf(fp, "%s\n", help);
1124  help = NULL;
1125 
1126 out:
1127  defs = (char*)_free(defs);
1128  left = (char*)_free(left);
1129 }
1130 
1137 static size_t maxArgWidth(const struct poptOption * opt,
1138  const char * translation_domain)
1139 {
1140  size_t max = 0;
1141  size_t len = 0;
1142  const char * argDescrip;
1143 
1144  if (opt != NULL)
1145  while (opt->longName || opt->shortName || opt->arg) {
1146  if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) {
1147  if (opt->arg) /* XXX program error */
1148  len = maxArgWidth((const poptOption*)opt->arg, translation_domain);
1149  if (len > max) max = len;
1150  } else if (!F_ISSET(opt, DOC_HIDDEN)) {
1151  len = sizeof(" ")-1;
1152  /* XXX --long always padded for alignment with/without "-X, ". */
1153  len += sizeof("-X, ")-1;
1154  if (opt->longName) {
1155  len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1;
1156  len += strlen(opt->longName);
1157  }
1158 
1159  argDescrip = getArgDescrip(opt, translation_domain);
1160 
1161  if (argDescrip) {
1162 
1163  /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */
1164  if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1;
1165 
1166  /* Adjust for (possible) wide characters. */
1167  len += stringDisplayWidth(argDescrip);
1168  }
1169 
1170  if (F_ISSET(opt, OPTIONAL)) len += sizeof("[]")-1;
1171  if (len > max) max = len;
1172  }
1173  opt++;
1174  }
1175 
1176  return max;
1177 }
1178 
1187 static void itemHelp(FILE * fp,
1188  poptItem items, int nitems,
1189  columns_t columns,
1190  const char * translation_domain)
1191 {
1192  poptItem item;
1193  int i;
1194 
1195  if (items != NULL)
1196  for (i = 0, item = items; i < nitems; i++, item++) {
1197  const struct poptOption * opt;
1198  opt = &item->option;
1199  if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN))
1200  singleOptionHelp(fp, columns, opt, translation_domain);
1201  }
1202 }
1203 
1212 static void singleTableHelp(poptContext con, FILE * fp,
1213  const struct poptOption * table,
1214  columns_t columns,
1215  const char * translation_domain)
1216 {
1217  const struct poptOption * opt;
1218  const char *sub_transdom;
1219 
1220  if (table == poptAliasOptions) {
1221  itemHelp(fp, con->aliases, con->numAliases, columns, NULL);
1222  itemHelp(fp, con->execs, con->numExecs, columns, NULL);
1223  return;
1224  }
1225 
1226  if (table != NULL)
1227  for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
1228  if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN))
1229  singleOptionHelp(fp, columns, opt, translation_domain);
1230  }
1231 
1232  if (table != NULL)
1233  for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
1234  if (poptArgType(opt) != POPT_ARG_INCLUDE_TABLE)
1235  continue;
1236  sub_transdom = getTableTranslationDomain((const poptOption*)opt->arg);
1237  if (sub_transdom == NULL)
1238  sub_transdom = translation_domain;
1239 
1240  /* If no popt aliases/execs, skip poptAliasOption processing. */
1241  if (opt->arg == poptAliasOptions && !(con->numAliases || con->numExecs))
1242  continue;
1243  if (opt->descrip)
1244  POPT_fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
1245 
1246  singleTableHelp(con, fp, (const poptOption*)opt->arg, columns, sub_transdom);
1247  }
1248 }
1249 
1254 static size_t showHelpIntro(poptContext con, FILE * fp)
1255 {
1256  size_t len = (size_t)6;
1257 
1258  POPT_fprintf(fp, POPT_("Usage:"));
1259  if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
1260  struct optionStackEntry * os = con->optionStack;
1261  const char * fn = (os->argv ? os->argv[0] : NULL);
1262  if (fn == NULL) return len;
1263  if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
1264  /* XXX POPT_fprintf not needed for argv[0] display. */
1265  fprintf(fp, " %s", fn);
1266  len += strlen(fn) + 1;
1267  }
1268 
1269  return len;
1270 }
1271 
1272 void poptPrintHelp(poptContext con, FILE * fp, UNUSED(int flags))
1273 {
1274  columns_t columns = (columns_t)calloc((size_t)1, sizeof(*columns));
1275 
1276  (void) showHelpIntro(con, fp);
1277  if (con->otherHelp)
1278  POPT_fprintf(fp, " %s\n", con->otherHelp);
1279  else
1280  POPT_fprintf(fp, " %s\n", POPT_("[OPTION...]"));
1281 
1282  if (columns) {
1283  columns->cur = maxArgWidth(con->options, NULL);
1284  columns->max = maxColumnWidth(fp);
1285  singleTableHelp(con, fp, con->options, columns, NULL);
1286  free(columns);
1287  }
1288 }
1289 
1297 static size_t singleOptionUsage(FILE * fp, columns_t columns,
1298  const struct poptOption * opt,
1299  const char *translation_domain)
1300 {
1301  size_t len = sizeof(" []")-1;
1302  const char * argDescrip = getArgDescrip(opt, translation_domain);
1303  /* Display shortName iff printable non-space. */
1304  int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' ');
1305 
1306 #define prtlong (opt->longName != NULL) /* XXX splint needs a clue */
1307  if (!(prtshort || prtlong))
1308  return columns->cur;
1309 
1310  len = sizeof(" []")-1;
1311  if (prtshort)
1312  len += sizeof("-c")-1;
1313  if (prtlong) {
1314  if (prtshort) len += sizeof("|")-1;
1315  len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1;
1316  len += strlen(opt->longName);
1317  }
1318 
1319  if (argDescrip) {
1320 
1321  /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */
1322  if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1;
1323 
1324  /* Adjust for (possible) wide characters. */
1325  len += stringDisplayWidth(argDescrip);
1326  }
1327 
1328  if ((columns->cur + len) > columns->max) {
1329  fprintf(fp, "\n ");
1330  columns->cur = (size_t)7;
1331  }
1332 
1333  fprintf(fp, " [");
1334  if (prtshort)
1335  fprintf(fp, "-%c", opt->shortName);
1336  if (prtlong)
1337  fprintf(fp, "%s%s%s",
1338  (prtshort ? "|" : ""),
1339  (F_ISSET(opt, ONEDASH) ? "-" : "--"),
1340  opt->longName);
1341 #undef prtlong
1342 
1343  if (argDescrip) {
1344  /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */
1345  if (!strchr(" =(", argDescrip[0])) fprintf(fp, "=");
1346  fprintf(fp, "%s", argDescrip);
1347  }
1348  fprintf(fp, "]");
1349 
1350  return columns->cur + len + 1;
1351 }
1352 
1361 static size_t itemUsage(FILE * fp, columns_t columns,
1362  poptItem item, int nitems,
1363  const char * translation_domain)
1364 {
1365  int i;
1366 
1367  if (item != NULL)
1368  for (i = 0; i < nitems; i++, item++) {
1369  const struct poptOption * opt;
1370  opt = &item->option;
1371  if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) {
1372  translation_domain = (const char *)opt->arg;
1373  } else
1374  if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) {
1375  columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
1376  }
1377  }
1378 
1379  return columns->cur;
1380 }
1381 
1385 typedef struct poptDone_s {
1386  int nopts;
1387  int maxopts;
1388  const void ** opts;
1389 } * poptDone;
1390 
1401 static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns,
1402  const struct poptOption * opt,
1403  const char * translation_domain,
1404  poptDone done)
1405 {
1406  if (opt != NULL)
1407  for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
1408  if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) {
1409  translation_domain = (const char *)opt->arg;
1410  } else
1411  if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) {
1412  if (done) {
1413  int i = 0;
1414  if (done->opts != NULL)
1415  for (i = 0; i < done->nopts; i++) {
1416  const void * that = done->opts[i];
1417  if (that == NULL || that != opt->arg)
1418  continue;
1419  break;
1420  }
1421  /* Skip if this table has already been processed. */
1422  if (opt->arg == NULL || i < done->nopts)
1423  continue;
1424  if (done->opts != NULL && done->nopts < done->maxopts)
1425  done->opts[done->nopts++] = (const void *) opt->arg;
1426  }
1427  columns->cur = singleTableUsage(con, fp, columns, (const poptOption*)opt->arg,
1428  translation_domain, done);
1429  } else
1430  if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) {
1431  columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
1432  }
1433  }
1434 
1435  return columns->cur;
1436 }
1437 
1446 static size_t showShortOptions(const struct poptOption * opt, FILE * fp,
1447  char * str)
1448 {
1449  /* bufsize larger then the ascii set, lazy allocation on top level call. */
1450  size_t nb = (size_t)300;
1451  char * s = (str != NULL ? str : (char*)calloc((size_t)1, nb));
1452  size_t len = (size_t)0;
1453 
1454  if (s == NULL)
1455  return 0;
1456 
1457  if (opt != NULL)
1458  for (; (opt->longName || opt->shortName || opt->arg); opt++) {
1459  if (!F_ISSET(opt, DOC_HIDDEN) && opt->shortName && !poptArgType(opt))
1460  {
1461  /* Display shortName iff unique printable non-space. */
1462  if (!strchr(s, opt->shortName) && isprint((int)opt->shortName)
1463  && opt->shortName != ' ')
1464  s[strlen(s)] = opt->shortName;
1465  } else if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE)
1466  if (opt->arg) /* XXX program error */
1467  len = showShortOptions((const poptOption*)opt->arg, fp, s);
1468  }
1469 
1470  /* On return to top level, print the short options, return print length. */
1471  if (s != str && *s != '\0') {
1472  fprintf(fp, " [-%s]", s);
1473  len = strlen(s) + sizeof(" [-]")-1;
1474  }
1475  if (s != str)
1476  free(s);
1477  return len;
1478 }
1479 
1480 void poptPrintUsage(poptContext con, FILE * fp, UNUSED(int flags))
1481 {
1482  columns_t columns = (columns_t)calloc((size_t)1, sizeof(*columns));
1483  struct poptDone_s done_buf;
1484  poptDone done = &done_buf;
1485 
1486  memset(done, 0, sizeof(*done));
1487  done->nopts = 0;
1488  done->maxopts = 64;
1489  if (columns) {
1490  columns->cur = done->maxopts * sizeof(*done->opts);
1491  columns->max = maxColumnWidth(fp);
1492  done->opts = (const void**)calloc((size_t)1, columns->cur);
1493  if (done->opts != NULL)
1494  done->opts[done->nopts++] = (const void *) con->options;
1495 
1496  columns->cur = showHelpIntro(con, fp);
1497  columns->cur += showShortOptions(con->options, fp, NULL);
1498  columns->cur = singleTableUsage(con, fp, columns, con->options, NULL, done);
1499  columns->cur = itemUsage(fp, columns, con->aliases, con->numAliases, NULL);
1500  columns->cur = itemUsage(fp, columns, con->execs, con->numExecs, NULL);
1501 
1502  if (con->otherHelp) {
1503  columns->cur += strlen(con->otherHelp) + 1;
1504  if (columns->cur > columns->max) fprintf(fp, "\n ");
1505  fprintf(fp, " %s", con->otherHelp);
1506  }
1507 
1508  fprintf(fp, "\n");
1509  if (done->opts != NULL)
1510  free(done->opts);
1511  free(columns);
1512  }
1513 }
1514 
1515 void poptSetOtherOptionHelp(poptContext con, const char * text)
1516 {
1517  con->otherHelp = (const char*)_free(con->otherHelp);
1518  con->otherHelp = xstrdup(text);
1519 }
1520 
1521 /* End of section from popthelp.cpp
1522 */
1523 
1524 /* This section is from poptint.cpp
1525 */
1526 
1527 #include <stdarg.h>
1528 
1529 /* Any pair of 32 bit hashes can be used. lookup3.c generates pairs, will do. */
1530 #define _JLU3_jlu32lpair 1
1531 #define jlu32lpair poptJlu32lpair
1532 
1533 /* This section is from lookup3.c
1534 */
1535 
1536 /* -------------------------------------------------------------------- */
1537 /*
1538  * lookup3.c, by Bob Jenkins, May 2006, Public Domain.
1539  *
1540  * These are functions for producing 32-bit hashes for hash table lookup.
1541  * jlu32w(), jlu32l(), jlu32lpair(), jlu32b(), _JLU3_MIX(), and _JLU3_FINAL()
1542  * are externally useful functions. Routines to test the hash are included
1543  * if SELF_TEST is defined. You can use this free for any purpose. It's in
1544  * the public domain. It has no warranty.
1545  *
1546  * You probably want to use jlu32l(). jlu32l() and jlu32b()
1547  * hash byte arrays. jlu32l() is is faster than jlu32b() on
1548  * little-endian machines. Intel and AMD are little-endian machines.
1549  * On second thought, you probably want jlu32lpair(), which is identical to
1550  * jlu32l() except it returns two 32-bit hashes for the price of one.
1551  * You could implement jlu32bpair() if you wanted but I haven't bothered here.
1552  *
1553  * If you want to find a hash of, say, exactly 7 integers, do
1554  * a = i1; b = i2; c = i3;
1555  * _JLU3_MIX(a,b,c);
1556  * a += i4; b += i5; c += i6;
1557  * _JLU3_MIX(a,b,c);
1558  * a += i7;
1559  * _JLU3_FINAL(a,b,c);
1560  * then use c as the hash value. If you have a variable size array of
1561  * 4-byte integers to hash, use jlu32w(). If you have a byte array (like
1562  * a character string), use jlu32l(). If you have several byte arrays, or
1563  * a mix of things, see the comments above jlu32l().
1564  *
1565  * Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
1566  * then mix those integers. This is fast (you can do a lot more thorough
1567  * mixing with 12*3 instructions on 3 integers than you can with 3 instructions
1568  * on 1 byte), but shoehorning those bytes into integers efficiently is messy.
1569 */
1570 /* -------------------------------------------------------------------- */
1571 
1572 static const union _dbswap {
1573  const uint32_t ui;
1574  const unsigned char uc[4];
1575 } endian = { 0x11223344 };
1576 # define HASH_LITTLE_ENDIAN (endian.uc[0] == (unsigned char) 0x44)
1577 # define HASH_BIG_ENDIAN (endian.uc[0] == (unsigned char) 0x11)
1578 
1579 #ifndef ROTL32
1580 # define ROTL32(x, s) (((x) << (s)) | ((x) >> (32 - (s))))
1581 #endif
1582 
1583 /* NOTE: The _size parameter should be in bytes. */
1584 #define _JLU3_INIT(_h, _size) (0xdeadbeef + ((uint32_t)(_size)) + (_h))
1585 
1586 /* -------------------------------------------------------------------- */
1587 /*
1588  * _JLU3_MIX -- mix 3 32-bit values reversibly.
1589  *
1590  * This is reversible, so any information in (a,b,c) before _JLU3_MIX() is
1591  * still in (a,b,c) after _JLU3_MIX().
1592  *
1593  * If four pairs of (a,b,c) inputs are run through _JLU3_MIX(), or through
1594  * _JLU3_MIX() in reverse, there are at least 32 bits of the output that
1595  * are sometimes the same for one pair and different for another pair.
1596  * This was tested for:
1597  * * pairs that differed by one bit, by two bits, in any combination
1598  * of top bits of (a,b,c), or in any combination of bottom bits of
1599  * (a,b,c).
1600  * * "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
1601  * the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
1602  * is commonly produced by subtraction) look like a single 1-bit
1603  * difference.
1604  * * the base values were pseudorandom, all zero but one bit set, or
1605  * all zero plus a counter that starts at zero.
1606  *
1607  * Some k values for my "a-=c; a^=ROTL32(c,k); c+=b;" arrangement that
1608  * satisfy this are
1609  * 4 6 8 16 19 4
1610  * 9 15 3 18 27 15
1611  * 14 9 3 7 17 3
1612  * Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
1613  * for "differ" defined as + with a one-bit base and a two-bit delta. I
1614  * used http://burtleburtle.net/bob/hash/avalanche.html to choose
1615  * the operations, constants, and arrangements of the variables.
1616  *
1617  * This does not achieve avalanche. There are input bits of (a,b,c)
1618  * that fail to affect some output bits of (a,b,c), especially of a. The
1619  * most thoroughly mixed value is c, but it doesn't really even achieve
1620  * avalanche in c.
1621  *
1622  * This allows some parallelism. Read-after-writes are good at doubling
1623  * the number of bits affected, so the goal of mixing pulls in the opposite
1624  * direction as the goal of parallelism. I did what I could. Rotates
1625  * seem to cost as much as shifts on every machine I could lay my hands
1626  * on, and rotates are much kinder to the top and bottom bits, so I used
1627  * rotates.
1628  */
1629 /* -------------------------------------------------------------------- */
1630 #define _JLU3_MIX(a,b,c) \
1631 { \
1632  a -= c; a ^= ROTL32(c, 4); c += b; \
1633  b -= a; b ^= ROTL32(a, 6); a += c; \
1634  c -= b; c ^= ROTL32(b, 8); b += a; \
1635  a -= c; a ^= ROTL32(c,16); c += b; \
1636  b -= a; b ^= ROTL32(a,19); a += c; \
1637  c -= b; c ^= ROTL32(b, 4); b += a; \
1638 }
1639 
1640 /* -------------------------------------------------------------------- */
1664 /* -------------------------------------------------------------------- */
1665 #define _JLU3_FINAL(a,b,c) \
1666 { \
1667  c ^= b; c -= ROTL32(b,14); \
1668  a ^= c; a -= ROTL32(c,11); \
1669  b ^= a; b -= ROTL32(a,25); \
1670  c ^= b; c -= ROTL32(b,16); \
1671  a ^= c; a -= ROTL32(c,4); \
1672  b ^= a; b -= ROTL32(a,14); \
1673  c ^= b; c -= ROTL32(b,24); \
1674 }
1675 
1676 #if defined(_JLU3_jlu32lpair)
1677 
1693 void jlu32lpair(const void *key, size_t size, uint32_t *pc, uint32_t *pb)
1694 {
1695  union { const void *ptr; size_t i; } u;
1696  uint32_t a = _JLU3_INIT(*pc, size);
1697  uint32_t b = a;
1698  uint32_t c = a;
1699 
1700  if (key == NULL)
1701  goto exit;
1702 
1703  c += *pb; /* Add the secondary hash. */
1704 
1705  u.ptr = key;
1706  if (HASH_LITTLE_ENDIAN && ((u.i & 0x3) == 0)) {
1707  const uint32_t *k = (const uint32_t *)key; /* read 32-bit chunks */
1708 
1709  /*-- all but last block: aligned reads and affect 32 bits of (a,b,c) */
1710  while (size > (size_t)12) {
1711  a += k[0];
1712  b += k[1];
1713  c += k[2];
1714  _JLU3_MIX(a,b,c);
1715  size -= 12;
1716  k += 3;
1717  }
1718  /*------------------------- handle the last (probably partial) block */
1719  /*
1720  * "k[2]&0xffffff" actually reads beyond the end of the string, but
1721  * then masks off the part it's not allowed to read. Because the
1722  * string is aligned, the masked-off tail is in the same word as the
1723  * rest of the string. Every machine with memory protection I've seen
1724  * does it on word boundaries, so is OK with this. But VALGRIND will
1725  * still catch it and complain. The masking trick does make the hash
1726  * noticably faster for short strings (like English words).
1727  */
1728  switch (size) {
1729  case 12: c += k[2]; b+=k[1]; a+=k[0]; break;
1730  case 11: c += k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
1731  case 10: c += k[2]&0xffff; b+=k[1]; a+=k[0]; break;
1732  case 9: c += k[2]&0xff; b+=k[1]; a+=k[0]; break;
1733  case 8: b += k[1]; a+=k[0]; break;
1734  case 7: b += k[1]&0xffffff; a+=k[0]; break;
1735  case 6: b += k[1]&0xffff; a+=k[0]; break;
1736  case 5: b += k[1]&0xff; a+=k[0]; break;
1737  case 4: a += k[0]; break;
1738  case 3: a += k[0]&0xffffff; break;
1739  case 2: a += k[0]&0xffff; break;
1740  case 1: a += k[0]&0xff; break;
1741  case 0: goto exit;
1742  }
1743 
1744  } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
1745  const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
1746  const uint8_t *k8;
1747 
1748  /*----------- all but last block: aligned reads and different mixing */
1749  while (size > (size_t)12) {
1750  a += k[0] + (((uint32_t)k[1])<<16);
1751  b += k[2] + (((uint32_t)k[3])<<16);
1752  c += k[4] + (((uint32_t)k[5])<<16);
1753  _JLU3_MIX(a,b,c);
1754  size -= 12;
1755  k += 6;
1756  }
1757 
1758  /*------------------------- handle the last (probably partial) block */
1759  k8 = (const uint8_t *)k;
1760  switch (size) {
1761  case 12:
1762  c += k[4]+(((uint32_t)k[5])<<16);
1763  b += k[2]+(((uint32_t)k[3])<<16);
1764  a += k[0]+(((uint32_t)k[1])<<16);
1765  break;
1766  case 11:
1767  c += ((uint32_t)k8[10])<<16;
1768  case 10:
1769  c += k[4];
1770  b += k[2]+(((uint32_t)k[3])<<16);
1771  a += k[0]+(((uint32_t)k[1])<<16);
1772  break;
1773  case 9:
1774  c += k8[8];
1775  case 8:
1776  b += k[2]+(((uint32_t)k[3])<<16);
1777  a += k[0]+(((uint32_t)k[1])<<16);
1778  break;
1779  case 7:
1780  b += ((uint32_t)k8[6])<<16;
1781  case 6:
1782  b += k[2];
1783  a += k[0]+(((uint32_t)k[1])<<16);
1784  break;
1785  case 5:
1786  b += k8[4];
1787  case 4:
1788  a += k[0]+(((uint32_t)k[1])<<16);
1789  break;
1790  case 3:
1791  a += ((uint32_t)k8[2])<<16;
1792  case 2:
1793  a += k[0];
1794  break;
1795  case 1:
1796  a += k8[0];
1797  break;
1798  case 0:
1799  goto exit;
1800  }
1801 
1802  } else { /* need to read the key one byte at a time */
1803  const uint8_t *k = (const uint8_t *)key;
1804 
1805  /*----------- all but the last block: affect some 32 bits of (a,b,c) */
1806  while (size > (size_t)12) {
1807  a += k[0];
1808  a += ((uint32_t)k[1])<<8;
1809  a += ((uint32_t)k[2])<<16;
1810  a += ((uint32_t)k[3])<<24;
1811  b += k[4];
1812  b += ((uint32_t)k[5])<<8;
1813  b += ((uint32_t)k[6])<<16;
1814  b += ((uint32_t)k[7])<<24;
1815  c += k[8];
1816  c += ((uint32_t)k[9])<<8;
1817  c += ((uint32_t)k[10])<<16;
1818  c += ((uint32_t)k[11])<<24;
1819  _JLU3_MIX(a,b,c);
1820  size -= 12;
1821  k += 12;
1822  }
1823 
1824  /*---------------------------- last block: affect all 32 bits of (c) */
1825  switch (size) {
1826  case 12: c += ((uint32_t)k[11])<<24;
1827  case 11: c += ((uint32_t)k[10])<<16;
1828  case 10: c += ((uint32_t)k[9])<<8;
1829  case 9: c += k[8];
1830  case 8: b += ((uint32_t)k[7])<<24;
1831  case 7: b += ((uint32_t)k[6])<<16;
1832  case 6: b += ((uint32_t)k[5])<<8;
1833  case 5: b += k[4];
1834  case 4: a += ((uint32_t)k[3])<<24;
1835  case 3: a += ((uint32_t)k[2])<<16;
1836  case 2: a += ((uint32_t)k[1])<<8;
1837  case 1: a += k[0];
1838  break;
1839  case 0:
1840  goto exit;
1841  }
1842  }
1843 
1844  _JLU3_FINAL(a,b,c);
1845 
1846 exit:
1847  *pc = c;
1848  *pb = b;
1849  return;
1850 }
1851 #endif /* defined(_JLU3_jlu32lpair) */
1852 
1853 /* End of section from lookup3.c
1854 */
1855 
1856 static const unsigned char utf8_skip_data[256] = {
1857  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1858  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1859  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1860  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1861  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1862  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1863  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
1864  3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
1865 };
1866 
1867 const char *
1868 POPT_prev_char (const char *str)
1869 {
1870  const char *p = str;
1871 
1872  while (1) {
1873  p--;
1874  if (((unsigned)*p & 0xc0) != (unsigned)0x80)
1875  return p;
1876  }
1877 }
1878 
1879 const char *
1880 POPT_next_char (const char *str)
1881 {
1882  const char *p = str;
1883 
1884  while (*p != '\0') {
1885  p++;
1886  if (((unsigned)*p & 0xc0) != (unsigned)0x80)
1887  break;
1888  }
1889  return p;
1890 }
1891 
1892 #if !defined(POPT_fprintf) /* XXX lose all the goop ... */
1893 
1894 int
1895 POPT_fprintf (FILE * stream, const char * format, ...)
1896 {
1897  char * b = NULL;
1898  int rc;
1899  va_list ap;
1900 
1901  size_t nb = (size_t)1;
1902 
1903  /* HACK: add +1 to the realloc no. of bytes "just in case". */
1904  /* XXX Likely unneeded, the issues wrto vsnprintf(3) return b0rkage have
1905  * to do with whether the final '\0' is counted (or not). The code
1906  * below already adds +1 for the (possibly already counted) trailing NUL.
1907  */
1908  while ((b = (char*)realloc(b, nb+1)) != NULL) {
1909  va_start(ap, format);
1910  rc = vsnprintf(b, nb, format, ap);
1911  va_end(ap);
1912  if (rc > -1) { /* glibc 2.1 */
1913  if ((size_t)rc < nb)
1914  break;
1915  nb = (size_t)(rc + 1); /* precise buffer length known */
1916  } else /* glibc 2.0 */
1917  nb += (nb < (size_t)100 ? (size_t)100 : nb);
1918  }
1919 
1920  rc = 0;
1921  if (b != NULL) {
1922  rc = fprintf(stream, "%s", b);
1923  free (b);
1924  }
1925 
1926  return rc;
1927 }
1928 
1929 #endif /* !defined(POPT_fprintf) */
1930 
1931 /* End of section from poptint.cpp
1932 */
1933 
1934 /* This section is from poptparse.cpp
1935 */
1936 
1937 #define POPT_ARGV_ARRAY_GROW_DELTA 5
1938 
1939 int poptDupArgv(int argc, const char **argv,
1940  int * argcPtr, const char *** argvPtr)
1941 {
1942  size_t nb = (argc + 1) * sizeof(*argv);
1943  const char ** argv2;
1944  char * dst;
1945  int i;
1946 
1947  if (argc <= 0 || argv == NULL) /* XXX can't happen */
1948  return POPT_ERROR_NOARG;
1949  for (i = 0; i < argc; i++) {
1950  if (argv[i] == NULL)
1951  return POPT_ERROR_NOARG;
1952  nb += strlen(argv[i]) + 1;
1953  }
1954 
1955  dst = (char*)malloc(nb);
1956  if (dst == NULL) /* XXX can't happen */
1957  return POPT_ERROR_MALLOC;
1958  argv2 = (const char **) dst;
1959  dst += (argc + 1) * sizeof(*argv);
1960  *dst = '\0';
1961 
1962  for (i = 0; i < argc; i++) {
1963  argv2[i] = dst;
1964  dst = stpcpy(dst, argv[i]);
1965  dst++; /* trailing NUL */
1966  }
1967  argv2[argc] = NULL;
1968 
1969  if (argvPtr) {
1970  *argvPtr = argv2;
1971  } else {
1972  free(argv2);
1973  argv2 = NULL;
1974  }
1975  if (argcPtr)
1976  *argcPtr = argc;
1977  return 0;
1978 }
1979 
1980 int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
1981 {
1982  const char * src;
1983  char quote = '\0';
1984  int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
1985  const char ** argv = (const char**)malloc(sizeof(*argv) * argvAlloced);
1986  int argc = 0;
1987  size_t buflen = strlen(s) + 1;
1988  char * buf, * bufOrig = NULL;
1989  int rc = POPT_ERROR_MALLOC;
1990 
1991  if (argv == NULL) return rc;
1992  buf = bufOrig = (char*)calloc((size_t)1, buflen);
1993  if (buf == NULL) {
1994  free(argv);
1995  return rc;
1996  }
1997  argv[argc] = buf;
1998 
1999  for (src = s; *src != '\0'; src++) {
2000  if (quote == *src) {
2001  quote = '\0';
2002  } else if (quote != '\0') {
2003  if (*src == '\\') {
2004  src++;
2005  if (!*src) {
2006  rc = POPT_ERROR_BADQUOTE;
2007  goto exit;
2008  }
2009  if (*src != quote) *buf++ = '\\';
2010  }
2011  *buf++ = *src;
2012  } else if (_isspaceptr(src)) {
2013  if (*argv[argc] != '\0') {
2014  buf++, argc++;
2015  if (argc == argvAlloced) {
2016  argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
2017  argv = (const char**)realloc(argv, sizeof(*argv) * argvAlloced);
2018  if (argv == NULL) goto exit;
2019  }
2020  argv[argc] = buf;
2021  }
2022  } else switch (*src) {
2023  case '"':
2024  case '\'':
2025  quote = *src;
2026  break;
2027  case '\\':
2028  src++;
2029  if (!*src) {
2030  rc = POPT_ERROR_BADQUOTE;
2031  goto exit;
2032  }
2033  default:
2034  *buf++ = *src;
2035  break;
2036  }
2037  }
2038 
2039  if (strlen(argv[argc])) {
2040  argc++, buf++;
2041  }
2042 
2043  rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
2044 
2045 exit:
2046  if (bufOrig) free(bufOrig);
2047  if (argv) free(argv);
2048  return rc;
2049 }
2050 
2051 /* still in the dev stage.
2052  * return values, perhaps 1== file erro
2053  * 2== line to long
2054  * 3== umm.... more?
2055  */
2056 int poptConfigFileToString(FILE *fp, char ** argstrp,
2057  UNUSED(int flags))
2058 {
2059  char line[999];
2060  char * argstr;
2061  char * p;
2062  char * q;
2063  char * x;
2064  size_t t;
2065  size_t argvlen = 0;
2066  size_t maxlinelen = sizeof(line);
2067  size_t linelen;
2068  size_t maxargvlen = (size_t)480;
2069 
2070  *argstrp = NULL;
2071 
2072  /* | this_is = our_line
2073  * p q x
2074  */
2075 
2076  if (fp == NULL)
2077  return POPT_ERROR_NULLARG;
2078 
2079  argstr = (char*)calloc(maxargvlen, sizeof(*argstr));
2080  if (argstr == NULL) return POPT_ERROR_MALLOC;
2081 
2082  while (fgets(line, (int)maxlinelen, fp) != NULL) {
2083  p = line;
2084 
2085  /* loop until first non-space char or EOL */
2086  while( *p != '\0' && _isspaceptr(p) )
2087  p++;
2088 
2089  linelen = strlen(p);
2090  if (linelen >= maxlinelen-1) {
2091  free(argstr);
2092  return POPT_ERROR_OVERFLOW; /* XXX line too long */
2093  }
2094 
2095  if (*p == '\0' || *p == '\n') continue; /* line is empty */
2096  if (*p == '#') continue; /* comment line */
2097 
2098  q = p;
2099 
2100  while (*q != '\0' && (!_isspaceptr(q)) && *q != '=')
2101  q++;
2102 
2103  if (_isspaceptr(q)) {
2104  /* a space after the name, find next non space */
2105  *q++='\0';
2106  while( *q != '\0' && _isspaceptr(q) ) q++;
2107  }
2108  if (*q == '\0') {
2109  /* single command line option (ie, no name=val, just name) */
2110  q[-1] = '\0'; /* kill off newline from fgets() call */
2111  argvlen += (t = (size_t)(q - p)) + (sizeof(" --")-1);
2112  if (argvlen >= maxargvlen) {
2113  maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
2114  argstr = (char*)realloc(argstr, maxargvlen);
2115  if (argstr == NULL) return POPT_ERROR_MALLOC;
2116  }
2117  strcat(argstr, " --");
2118  strcat(argstr, p);
2119  continue;
2120  }
2121  if (*q != '=')
2122  continue; /* XXX for now, silently ignore bogus line */
2123 
2124  /* *q is an equal sign. */
2125  *q++ = '\0';
2126 
2127  /* find next non-space letter of value */
2128  while (*q != '\0' && _isspaceptr(q))
2129  q++;
2130  if (*q == '\0')
2131  continue; /* XXX silently ignore missing value */
2132 
2133  /* now, loop and strip all ending whitespace */
2134  x = p + linelen;
2135  while (_isspaceptr(--x))
2136  *x = '\0'; /* null out last char if space (including fgets() NL) */
2137 
2138  /* rest of line accept */
2139  t = (size_t)(x - p);
2140  argvlen += t + (sizeof("' --='")-1);
2141  if (argvlen >= maxargvlen) {
2142  maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
2143  argstr = (char*)realloc(argstr, maxargvlen);
2144  if (argstr == NULL) return POPT_ERROR_MALLOC;
2145  }
2146  strcat(argstr, " --");
2147  strcat(argstr, p);
2148  strcat(argstr, "=\"");
2149  strcat(argstr, q);
2150  strcat(argstr, "\"");
2151  }
2152 
2153  *argstrp = argstr;
2154  return 0;
2155 }
2156 
2157 /* End of section from poptparse.cpp
2158 */
2159 
2160 /* The rest of the file is from popt.cpp
2161 */
2162 
2163 #ifdef MYDEBUG
2164 int _popt_debug = 0;
2165 #endif
2166 
2169 
2170 void poptSetExecPath(poptContext con, const char * path, int allowAbsolute)
2171 {
2172  con->execPath = (const char*)_free(con->execPath);
2173  con->execPath = xstrdup(path);
2174  con->execAbsolute = allowAbsolute;
2175  return;
2176 }
2177 
2178 static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt)
2179 {
2180  if (opt != NULL)
2181  for (; opt->longName || opt->shortName || opt->arg; opt++) {
2182  poptArg arg;
2183  arg.ptr = opt->arg;
2184  if (arg.ptr)
2185  switch (poptArgType(opt)) {
2186  case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
2187  poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
2188  invokeCallbacksPRE(con, (const poptOption*)arg.ptr);
2189  break;
2190  case POPT_ARG_CALLBACK: /* Perform callback. */
2191  if (!CBF_ISSET(opt, PRE))
2192  break;
2193  arg.cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip);
2194  break;
2195  }
2196  }
2197 }
2198 
2199 static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt)
2200 {
2201  if (opt != NULL)
2202  for (; opt->longName || opt->shortName || opt->arg; opt++) {
2203  poptArg arg;
2204  arg.ptr = opt->arg;
2205  if (arg.ptr)
2206  switch (poptArgType(opt)) {
2207  case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
2208  poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
2209  invokeCallbacksPOST(con, (const poptOption*)arg.ptr);
2210  break;
2211  case POPT_ARG_CALLBACK: /* Perform callback. */
2212  if (!CBF_ISSET(opt, POST))
2213  break;
2214  arg.cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip);
2215  break;
2216  }
2217  }
2218 }
2219 
2221  const struct poptOption * opt,
2222  const struct poptOption * myOpt,
2223  const void * myData, int shorty)
2224 {
2225  const struct poptOption * cbopt = NULL;
2226  poptArg cbarg;
2227  cbarg.ptr = NULL;
2228 
2229  if (opt != NULL)
2230  for (; opt->longName || opt->shortName || opt->arg; opt++) {
2231  poptArg arg;
2232  arg.ptr = opt->arg;
2233  switch (poptArgType(opt)) {
2234  case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
2235  poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
2236  if (opt->arg != NULL)
2237  invokeCallbacksOPTION(con, (const poptOption*)opt->arg, myOpt, myData, shorty);
2238  break;
2239  case POPT_ARG_CALLBACK: /* Save callback info. */
2240  if (CBF_ISSET(opt, SKIPOPTION))
2241  break;
2242  cbopt = opt;
2243  cbarg.ptr = opt->arg;
2244  break;
2245  default: /* Perform callback on matching option. */
2246  if (cbopt == NULL || cbarg.cb == NULL)
2247  break;
2248  if ((myOpt->shortName && opt->shortName && shorty &&
2249  myOpt->shortName == opt->shortName)
2250  || (myOpt->longName != NULL && opt->longName != NULL &&
2251  !strcmp(myOpt->longName, opt->longName)))
2252  { const void *cbData = (cbopt->descrip ? cbopt->descrip : myData);
2253  cbarg.cb(con, POPT_CALLBACK_REASON_OPTION,
2254  myOpt, con->os->nextArg, cbData);
2255  /* Terminate (unless explcitly continuing). */
2256  if (!CBF_ISSET(cbopt, CONTINUE))
2257  return;
2258  }
2259  break;
2260  }
2261  }
2262 }
2263 
2264 poptContext poptGetContext(const char * name, int argc, const char ** argv,
2265  const struct poptOption * options, unsigned int flags)
2266 {
2267  poptContext con = (poptContext)malloc(sizeof(*con));
2268 
2269  if (con == NULL) return NULL; /* XXX can't happen */
2270  memset(con, 0, sizeof(*con));
2271 
2272  con->os = con->optionStack;
2273  con->os->argc = argc;
2274  con->os->argv = argv;
2275  con->os->argb = NULL;
2276 
2277  if (!(flags & POPT_CONTEXT_KEEP_FIRST))
2278  con->os->next = 1; /* skip argv[0] */
2279 
2280  con->leftovers = (poptArgv)calloc( (size_t)(argc + 1), sizeof(*con->leftovers) );
2281  con->options = options;
2282  con->aliases = NULL;
2283  con->numAliases = 0;
2284  con->flags = flags;
2285  con->execs = NULL;
2286  con->numExecs = 0;
2287  con->finalArgvAlloced = argc * 2;
2288  con->finalArgv = (poptArgv)calloc( (size_t)con->finalArgvAlloced, sizeof(*con->finalArgv) );
2289  con->execAbsolute = 1;
2290  con->arg_strip = NULL;
2291 
2292  if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER"))
2294 
2295  if (name)
2296  con->appName = xstrdup(name);
2297 
2298  invokeCallbacksPRE(con, con->options);
2299 
2300  return con;
2301 }
2302 
2303 static void cleanOSE(struct optionStackEntry *os)
2304 {
2305  os->nextArg = (char*)_free(os->nextArg);
2306  os->argv = (poptArgv)_free(os->argv);
2307  os->argb = (pbm_set*)PBM_FREE(os->argb);
2308 }
2309 
2311 {
2312  int i;
2313 
2314  if (con == NULL) return;
2315  while (con->os > con->optionStack) {
2316  cleanOSE(con->os--);
2317  }
2318  con->os->argb = (pbm_set*)PBM_FREE(con->os->argb);
2319  con->os->currAlias = NULL;
2320  con->os->nextCharArg = NULL;
2321  con->os->nextArg = NULL;
2322  con->os->next = 1; /* skip argv[0] */
2323 
2324  con->numLeftovers = 0;
2325  con->nextLeftover = 0;
2326  con->restLeftover = 0;
2327  con->doExec = NULL;
2328 
2329  if (con->finalArgv != NULL)
2330  for (i = 0; i < con->finalArgvCount; i++) {
2331  con->finalArgv[i] = (poptString)_free(con->finalArgv[i]);
2332  }
2333 
2334  con->finalArgvCount = 0;
2335  con->arg_strip = (pbm_set*)PBM_FREE(con->arg_strip);
2336  return;
2337 }
2338 
2339 /* Only one of longName, shortName should be set, not both. */
2340 static int handleExec(poptContext con,
2341  const char * longName, char shortName)
2342 {
2343  poptItem item;
2344  int i;
2345 
2346  if (con->execs == NULL || con->numExecs <= 0) /* XXX can't happen */
2347  return 0;
2348 
2349  for (i = con->numExecs - 1; i >= 0; i--) {
2350  item = con->execs + i;
2351  if (longName && !(item->option.longName &&
2352  !strcmp(longName, item->option.longName)))
2353  continue;
2354  else if (shortName != item->option.shortName)
2355  continue;
2356  break;
2357  }
2358  if (i < 0) return 0;
2359 
2360 
2361  if (con->flags & POPT_CONTEXT_NO_EXEC)
2362  return 1;
2363 
2364  if (con->doExec == NULL) {
2365  con->doExec = con->execs + i;
2366  return 1;
2367  }
2368 
2369  /* We already have an exec to do; remember this option for next
2370  time 'round */
2371  if ((con->finalArgvCount + 1) >= (con->finalArgvAlloced)) {
2372  con->finalArgvAlloced += 10;
2373  con->finalArgv = (poptArgv)realloc(con->finalArgv,
2374  sizeof(*con->finalArgv) * con->finalArgvAlloced);
2375  }
2376 
2377  i = con->finalArgvCount++;
2378  if (con->finalArgv != NULL) /* XXX can't happen */
2379  { char *s = (char*)malloc((longName ? strlen(longName) : 0) + sizeof("--"));
2380  if (s != NULL) { /* XXX can't happen */
2381  con->finalArgv[i] = s;
2382  *s++ = '-';
2383  if (longName)
2384  s = stpcpy( stpcpy(s, "-"), longName);
2385  else
2386  *s++ = shortName;
2387  *s = '\0';
2388  } else
2389  con->finalArgv[i] = NULL;
2390  }
2391 
2392  return 1;
2393 }
2394 
2402 static int
2403 longOptionStrcmp(const struct poptOption * opt,
2404  const char * longName, size_t longNameLen)
2405 {
2406  const char * optLongName = opt->longName;
2407  int rc;
2408 
2409  if (optLongName == NULL || longName == NULL) /* XXX can't heppen */
2410  return 0;
2411 
2412  if (F_ISSET(opt, TOGGLE)) {
2413  if (optLongName[0] == 'n' && optLongName[1] == 'o') {
2414  optLongName += sizeof("no") - 1;
2415  if (optLongName[0] == '-')
2416  optLongName++;
2417  }
2418  if (longName[0] == 'n' && longName[1] == 'o') {
2419  longName += sizeof("no") - 1;
2420  longNameLen -= sizeof("no") - 1;
2421  if (longName[0] == '-') {
2422  longName++;
2423  longNameLen--;
2424  }
2425  }
2426  }
2427  rc = (int)(strlen(optLongName) == longNameLen);
2428  if (rc)
2429  rc = (int)(strncmp(optLongName, longName, longNameLen) == 0);
2430  return rc;
2431 }
2432 
2433 /* Only one of longName, shortName may be set at a time */
2434 static int handleAlias(poptContext con,
2435  const char * longName, size_t longNameLen,
2436  char shortName,
2437  const char * nextArg)
2438 {
2439  poptItem item = con->os->currAlias;
2440  int rc;
2441  int i;
2442 
2443  if (item) {
2444  if (longName && item->option.longName != NULL
2445  && longOptionStrcmp(&item->option, longName, longNameLen))
2446  return 0;
2447  else
2448  if (shortName && shortName == item->option.shortName)
2449  return 0;
2450  }
2451 
2452  if (con->aliases == NULL || con->numAliases <= 0) /* XXX can't happen */
2453  return 0;
2454 
2455  for (i = con->numAliases - 1; i >= 0; i--) {
2456  item = con->aliases + i;
2457  if (longName) {
2458  if (item->option.longName == NULL)
2459  continue;
2460  if (!longOptionStrcmp(&item->option, longName, longNameLen))
2461  continue;
2462  } else if (shortName != item->option.shortName)
2463  continue;
2464  break;
2465  }
2466  if (i < 0) return 0;
2467 
2468  if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH)
2469  return POPT_ERROR_OPTSTOODEEP;
2470 
2471  if (longName == NULL && nextArg != NULL && *nextArg != '\0')
2472  con->os->nextCharArg = nextArg;
2473 
2474  con->os++;
2475  con->os->next = 0;
2476  con->os->stuffed = 0;
2477  con->os->nextArg = NULL;
2478  con->os->nextCharArg = NULL;
2479  con->os->currAlias = con->aliases + i;
2480  { const char ** av;
2481  int ac = con->os->currAlias->argc;
2482  /* Append --foo=bar arg to alias argv array (if present). */
2483  if (longName && nextArg != NULL && *nextArg != '\0') {
2484  av = (const char**)malloc((ac + 1 + 1) * sizeof(*av));
2485  if (av != NULL) { /* XXX won't happen. */
2486  for (i = 0; i < ac; i++) {
2487  av[i] = con->os->currAlias->argv[i];
2488  }
2489  av[ac++] = nextArg;
2490  av[ac] = NULL;
2491  } else /* XXX revert to old popt behavior if malloc fails. */
2492  av = con->os->currAlias->argv;
2493  } else
2494  av = con->os->currAlias->argv;
2495  rc = poptDupArgv(ac, av, &con->os->argc, &con->os->argv);
2496  if (av != NULL && av != con->os->currAlias->argv)
2497  free(av);
2498  }
2499  con->os->argb = NULL;
2500 
2501  return (rc ? rc : 1);
2502 }
2503 
2509 static
2510 const char * findProgramPath(const char * argv0)
2511 {
2512  char *path = NULL, *s = NULL, *se;
2513  char *t = NULL;
2514 
2515  if (argv0 == NULL) return NULL; /* XXX can't happen */
2516 
2517  /* If there is a / in argv[0], it has to be an absolute path. */
2518  /* XXX Hmmm, why not if (argv0[0] == '/') ... instead? */
2519  if (strchr(argv0, '/'))
2520  return xstrdup(argv0);
2521 
2522  if ((path = getenv("PATH")) == NULL || (path = xstrdup(path)) == NULL)
2523  return NULL;
2524 
2525  /* The return buffer in t is big enough for any path. */
2526  if ((t = (char*)malloc(strlen(path) + strlen(argv0) + sizeof("/"))) != NULL)
2527  for (s = path; s && *s; s = se) {
2528 
2529  /* Snip PATH element into [s,se). */
2530  if ((se = strchr(s, ':')))
2531  *se++ = '\0';
2532 
2533  /* Append argv0 to PATH element. */
2534  (void) stpcpy(stpcpy(stpcpy(t, s), "/"), argv0);
2535 
2536  /* If file is executable, bingo! */
2537  if (!access(t, X_OK))
2538  break;
2539  }
2540 
2541  /* If no executable was found in PATH, return NULL. */
2542  if (!(s && *s) && t != NULL)
2543  t = (char*)_free(t);
2544  path = (char*)_free(path);
2545 
2546  return t;
2547 }
2548 
2549 static int execCommand(poptContext con)
2550 {
2551  poptItem item = con->doExec;
2552  poptArgv argv = NULL;
2553  int argc = 0;
2554  int ec = POPT_ERROR_ERRNO;
2555 
2556  if (item == NULL) /*XXX can't happen*/
2557  return POPT_ERROR_NOARG;
2558 
2559  if (item->argv == NULL || item->argc < 1 ||
2560  (!con->execAbsolute && strchr(item->argv[0], '/')))
2561  return POPT_ERROR_NOARG;
2562 
2563  argv = (poptArgv)malloc(sizeof(*argv) *
2564  (6 + item->argc + con->numLeftovers + con->finalArgvCount));
2565  if (argv == NULL) return POPT_ERROR_MALLOC;
2566 
2567  if (!strchr(item->argv[0], '/') && con->execPath != NULL) {
2568  char *s = (char *)malloc(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/"));
2569  if (s)
2570  (void)stpcpy(stpcpy(stpcpy(s, con->execPath), "/"), item->argv[0]);
2571 
2572  argv[argc] = s;
2573  } else
2574  argv[argc] = findProgramPath(item->argv[0]);
2575  if (argv[argc++] == NULL) {
2576  ec = POPT_ERROR_NOARG;
2577  goto exit;
2578  }
2579 
2580  if (item->argc > 1) {
2581  memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1));
2582  argc += (item->argc - 1);
2583  }
2584 
2585  if (con->finalArgv != NULL && con->finalArgvCount > 0) {
2586  memcpy(argv + argc, con->finalArgv,
2587  sizeof(*argv) * con->finalArgvCount);
2588  argc += con->finalArgvCount;
2589  }
2590 
2591  if (con->leftovers != NULL && con->numLeftovers > 0) {
2592  memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers);
2593  argc += con->numLeftovers;
2594  }
2595 
2596  argv[argc] = NULL;
2597 
2598  execvp(argv[0], (char *const *)argv);
2599 
2600 exit:
2601  if (argv) {
2602  if (argv[0])
2603  free((void *)argv[0]);
2604  free(argv);
2605  }
2606  return ec;
2607 }
2608 
2609 static const struct poptOption *
2610 findOption(const struct poptOption * opt,
2611  const char * longName, size_t longNameLen,
2612  char shortName,
2613  poptCallbackType * callback,
2614  const void ** callbackData,
2615  unsigned int argInfo)
2616 {
2617  const struct poptOption * cb = NULL;
2618  poptArg cbarg;
2619  cbarg.ptr = NULL;
2620 
2621  /* This happens when a single - is given */
2622  if (LF_ISSET(ONEDASH) && !shortName && (longName && *longName == '\0'))
2623  shortName = '-';
2624 
2625  for (; opt->longName || opt->shortName || opt->arg; opt++) {
2626  poptArg arg;
2627  arg.ptr = opt->arg;
2628 
2629  switch (poptArgType(opt)) {
2630  case POPT_ARG_INCLUDE_TABLE: /* Recurse on included sub-tables. */
2631  { const struct poptOption * opt2;
2632 
2633  poptSubstituteHelpI18N(arg.opt); /* XXX side effects */
2634  if (arg.ptr == NULL) continue; /* XXX program error */
2635 // opt2 = findOption(arg.opt, longName, longNameLen, shortName, callback,
2636 // callbackData, argInfo);
2637  opt2 = findOption((const struct poptOption*)arg.ptr, longName, longNameLen, shortName, callback,
2638  callbackData, argInfo);
2639  if (opt2 == NULL) continue;
2640  /* Sub-table data will be inheirited if no data yet. */
2641  if (callback && *callback
2642  && callbackData && *callbackData == NULL)
2643  *callbackData = opt->descrip;
2644  return opt2;
2645  } break;
2646  case POPT_ARG_CALLBACK:
2647  cb = opt;
2648  cbarg.ptr = opt->arg;
2649  continue;
2650  break;
2651  default:
2652  break;
2653  }
2654 
2655  if (longName != NULL && opt->longName != NULL &&
2656  (!LF_ISSET(ONEDASH) || F_ISSET(opt, ONEDASH)) &&
2657  longOptionStrcmp(opt, longName, longNameLen))
2658  {
2659  break;
2660  } else if (shortName && shortName == opt->shortName) {
2661  break;
2662  }
2663  }
2664 
2665  if (opt->longName == NULL && !opt->shortName)
2666  return NULL;
2667 
2668  if (callback)
2669  *callback = (cb ? cbarg.cb : NULL);
2670  if (callbackData)
2671  *callbackData = (cb && !CBF_ISSET(cb, INC_DATA) ? cb->descrip : NULL);
2672 
2673  return opt;
2674 }
2675 
2676 static const char * findNextArg(poptContext con,
2677  unsigned argx, int delete_arg)
2678 {
2679  struct optionStackEntry * os = con->os;
2680  const char * arg;
2681 
2682  do {
2683  int i;
2684  arg = NULL;
2685  while (os->next == os->argc && os > con->optionStack) os--;
2686  if (os->next == os->argc && os == con->optionStack) break;
2687  if (os->argv != NULL)
2688  for (i = os->next; i < os->argc; i++) {
2689  if (os->argb && PBM_ISSET(i, os->argb))
2690  continue;
2691  if (*os->argv[i] == '-')
2692  continue;
2693  if (--argx > 0)
2694  continue;
2695  arg = os->argv[i];
2696  if (delete_arg) {
2697  if (os->argb == NULL) os->argb = (pbm_set*)PBM_ALLOC(os->argc);
2698  if (os->argb != NULL) /* XXX can't happen */
2699  PBM_SET(i, os->argb);
2700  }
2701  break;
2702  }
2703  if (os > con->optionStack) os--;
2704  } while (arg == NULL);
2705  return arg;
2706 }
2707 
2708 static const char *
2709 expandNextArg(poptContext con, const char * s)
2710 {
2711  const char * a = NULL;
2712  char *t, *te;
2713  size_t tn = strlen(s) + 1;
2714  char c;
2715 
2716  te = t = (char*)malloc(tn);
2717  if (t == NULL) return NULL; /* XXX can't happen */
2718  *t = '\0';
2719  while ((c = *s++) != '\0') {
2720  switch (c) {
2721  case '!':
2722  if (!(s[0] == '#' && s[1] == ':' && s[2] == '+'))
2723  break;
2724  /* XXX Make sure that findNextArg deletes only next arg. */
2725  if (a == NULL) {
2726  if ((a = findNextArg(con, 1U, 1)) == NULL)
2727  break;
2728  }
2729  s += sizeof("#:+") - 1;
2730 
2731  tn += strlen(a);
2732  { size_t pos = (size_t) (te - t);
2733  if ((t = (char*)realloc(t, tn)) == NULL) /* XXX can't happen */
2734  return NULL;
2735  te = stpcpy(t + pos, a);
2736  }
2737  continue;
2738  break;
2739  default:
2740  break;
2741  }
2742  *te++ = c;
2743  }
2744  *te++ = '\0';
2745  /* If the new string is longer than needed, shorten. */
2746  if ((t + tn) > te) {
2747  if ((te = (char*)realloc(t, (size_t)(te - t))) == NULL)
2748  free(t);
2749  t = te;
2750  }
2751  return t;
2752 }
2753 
2754 static void poptStripArg(poptContext con, int which)
2755 {
2756  if (con->arg_strip == NULL)
2757  con->arg_strip = (pbm_set*)PBM_ALLOC(con->optionStack[0].argc);
2758  if (con->arg_strip != NULL) /* XXX can't happen */
2759  PBM_SET(which, con->arg_strip);
2760  return;
2761 }
2762 
2763 unsigned int _poptBitsN = _POPT_BITS_N;
2764 unsigned int _poptBitsM = _POPT_BITS_M;
2765 unsigned int _poptBitsK = _POPT_BITS_K;
2766 
2767 static int _poptBitsNew(poptBits *bitsp)
2768 {
2769  if (bitsp == NULL)
2770  return POPT_ERROR_NULLARG;
2771 
2772  /* XXX handle negated initialization. */
2773  if (*bitsp == NULL) {
2774  if (_poptBitsN == 0) {
2777  }
2778  if (_poptBitsM == 0U) _poptBitsM = (3 * _poptBitsN) / 2;
2779  if (_poptBitsK == 0U || _poptBitsK > 32U) _poptBitsK = _POPT_BITS_K;
2780  *bitsp = (poptBits)PBM_ALLOC(_poptBitsM-1);
2781  }
2782  return 0;
2783 }
2784 
2785 int poptBitsAdd(poptBits bits, const char * s)
2786 {
2787  size_t ns = (s ? strlen(s) : 0);
2788  uint32_t h0 = 0;
2789  uint32_t h1 = 0;
2790 
2791  if (bits == NULL || ns == 0)
2792  return POPT_ERROR_NULLARG;
2793 
2794  poptJlu32lpair(s, ns, &h0, &h1);
2795 
2796  for (ns = 0; ns < (size_t)_poptBitsK; ns++) {
2797  uint32_t h = h0 + (uint32_t)ns * h1;
2798  uint32_t ix = (h % _poptBitsM);
2799  PBM_SET(ix, bits);
2800  }
2801  return 0;
2802 }
2803 
2804 int poptBitsChk(poptBits bits, const char * s)
2805 {
2806  size_t ns = (s ? strlen(s) : 0);
2807  uint32_t h0 = 0;
2808  uint32_t h1 = 0;
2809  int rc = 1;
2810 
2811  if (bits == NULL || ns == 0)
2812  return POPT_ERROR_NULLARG;
2813 
2814  poptJlu32lpair(s, ns, &h0, &h1);
2815 
2816  for (ns = 0; ns < (size_t)_poptBitsK; ns++) {
2817  uint32_t h = h0 + (uint32_t)ns * h1;
2818  uint32_t ix = (h % _poptBitsM);
2819  if (PBM_ISSET(ix, bits))
2820  continue;
2821  rc = 0;
2822  break;
2823  }
2824  return rc;
2825 }
2826 
2828 {
2829  static size_t nbw = (__PBM_NBITS/8);
2830  size_t nw = (__PBM_IX(_poptBitsM-1) + 1);
2831 
2832  if (bits == NULL)
2833  return POPT_ERROR_NULLARG;
2834  memset(bits, 0, nw * nbw);
2835  return 0;
2836 }
2837 
2838 int poptBitsDel(poptBits bits, const char * s)
2839 {
2840  size_t ns = (s ? strlen(s) : 0);
2841  uint32_t h0 = 0;
2842  uint32_t h1 = 0;
2843 
2844  if (bits == NULL || ns == 0)
2845  return POPT_ERROR_NULLARG;
2846 
2847  poptJlu32lpair(s, ns, &h0, &h1);
2848 
2849  for (ns = 0; ns < (size_t)_poptBitsK; ns++) {
2850  uint32_t h = h0 + (uint32_t)ns * h1;
2851  uint32_t ix = (h % _poptBitsM);
2852  PBM_CLR(ix, bits);
2853  }
2854  return 0;
2855 }
2856 
2858 {
2859  __pbm_bits *abits;
2860  __pbm_bits *bbits;
2861  __pbm_bits rc = 0;
2862  size_t nw = (__PBM_IX(_poptBitsM-1) + 1);
2863  size_t i;
2864 
2865  if (ap == NULL || b == NULL || _poptBitsNew(ap))
2866  return POPT_ERROR_NULLARG;
2867  abits = __PBM_BITS(*ap);
2868  bbits = __PBM_BITS(b);
2869 
2870  for (i = 0; i < nw; i++) {
2871  abits[i] &= bbits[i];
2872  rc |= abits[i];
2873  }
2874  return (rc ? 1 : 0);
2875 }
2876 
2878 {
2879  __pbm_bits *abits;
2880  __pbm_bits *bbits;
2881  __pbm_bits rc = 0;
2882  size_t nw = (__PBM_IX(_poptBitsM-1) + 1);
2883  size_t i;
2884 
2885  if (ap == NULL || b == NULL || _poptBitsNew(ap))
2886  return POPT_ERROR_NULLARG;
2887  abits = __PBM_BITS(*ap);
2888  bbits = __PBM_BITS(b);
2889 
2890  for (i = 0; i < nw; i++) {
2891  abits[i] |= bbits[i];
2892  rc |= abits[i];
2893  }
2894  return (rc ? 1 : 0);
2895 }
2896 
2898 {
2899  const char ** av;
2900  int rc = 0;
2901 
2902  if (con == NULL || ap == NULL || _poptBitsNew(ap) ||
2903  con->leftovers == NULL || con->numLeftovers == con->nextLeftover)
2904  return POPT_ERROR_NULLARG;
2905 
2906  /* some apps like [like RPM ;-) ] need this NULL terminated */
2907  con->leftovers[con->numLeftovers] = NULL;
2908 
2909  for (av = con->leftovers + con->nextLeftover; *av != NULL; av++) {
2910  if ((rc = poptBitsAdd(*ap, *av)) != 0)
2911  break;
2912  }
2913  return rc;
2914 }
2915 
2917  UNUSED(unsigned int argInfo), const char * s)
2918 {
2919  char *tbuf = NULL;
2920  char *t, *te;
2921  int rc = 0;
2922 
2923  if (bitsp == NULL || s == NULL || *s == '\0' || _poptBitsNew(bitsp))
2924  return POPT_ERROR_NULLARG;
2925 
2926  /* Parse comma separated attributes. */
2927  te = tbuf = xstrdup(s);
2928  while ((t = te) != NULL && *t) {
2929  while (*te != '\0' && *te != ',')
2930  te++;
2931  if (*te != '\0')
2932  *te++ = '\0';
2933  /* XXX Ignore empty strings. */
2934  if (*t == '\0')
2935  continue;
2936  /* XXX Permit negated attributes. caveat emptor: false negatives. */
2937  if (*t == '!') {
2938  t++;
2939  if ((rc = poptBitsChk(*bitsp, t)) > 0)
2940  rc = poptBitsDel(*bitsp, t);
2941  } else
2942  rc = poptBitsAdd(*bitsp, t);
2943  if (rc)
2944  break;
2945  }
2946  tbuf = (char*)_free(tbuf);
2947  return rc;
2948 }
2949 
2950 int poptSaveString(const char *** argvp,
2951  UNUSED(unsigned int argInfo), const char * val)
2952 {
2953  int argc = 0;
2954 
2955  if (argvp == NULL || val == NULL)
2956  return POPT_ERROR_NULLARG;
2957 
2958  /* XXX likely needs an upper bound on argc. */
2959  if (*argvp != NULL)
2960  while ((*argvp)[argc] != NULL)
2961  argc++;
2962 
2963  if ((*argvp = (const char**)xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp))) != NULL) {
2964  (*argvp)[argc++] = xstrdup(val);
2965  (*argvp)[argc ] = NULL;
2966  }
2967  return 0;
2968 }
2969 
2970 int poptSaveLongLong(long long * arg, unsigned int argInfo, long long aLongLong)
2971 {
2972  if (arg == NULL )
2973  return POPT_ERROR_NULLARG;
2974 
2975  if (aLongLong != 0 && LF_ISSET(RANDOM)) {
2976  /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
2977  return POPT_ERROR_BADOPERATION;
2978  }
2979  if (LF_ISSET(NOT))
2980  aLongLong = ~aLongLong;
2981  switch (LF_ISSET(LOGICALOPS)) {
2982  case 0:
2983  *arg = aLongLong;
2984  break;
2985  case POPT_ARGFLAG_OR:
2986  *(unsigned long long *)arg |= (unsigned long long)aLongLong;
2987  break;
2988  case POPT_ARGFLAG_AND:
2989  *(unsigned long long *)arg &= (unsigned long long)aLongLong;
2990  break;
2991  case POPT_ARGFLAG_XOR:
2992  *(unsigned long long *)arg ^= (unsigned long long)aLongLong;
2993  break;
2994  default:
2995  return POPT_ERROR_BADOPERATION;
2996  break;
2997  }
2998  return 0;
2999 }
3000 
3001 int poptSaveLong(long * arg, unsigned int argInfo, long aLong)
3002 {
3003  /* XXX Check alignment, may fail on funky platforms. */
3004  if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
3005  return POPT_ERROR_NULLARG;
3006 
3007  if (aLong != 0 && LF_ISSET(RANDOM)) {
3008  /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
3009  return POPT_ERROR_BADOPERATION;
3010  }
3011  if (LF_ISSET(NOT))
3012  aLong = ~aLong;
3013  switch (LF_ISSET(LOGICALOPS)) {
3014  case 0: *arg = aLong; break;
3015  case POPT_ARGFLAG_OR: *(unsigned long *)arg |= (unsigned long)aLong; break;
3016  case POPT_ARGFLAG_AND: *(unsigned long *)arg &= (unsigned long)aLong; break;
3017  case POPT_ARGFLAG_XOR: *(unsigned long *)arg ^= (unsigned long)aLong; break;
3018  default:
3019  return POPT_ERROR_BADOPERATION;
3020  break;
3021  }
3022  return 0;
3023 }
3024 
3025 int poptSaveInt(int * arg, unsigned int argInfo, long aLong)
3026 {
3027  /* XXX Check alignment, may fail on funky platforms. */
3028  if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
3029  return POPT_ERROR_NULLARG;
3030 
3031  if (aLong != 0 && LF_ISSET(RANDOM)) {
3032  /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
3033  return POPT_ERROR_BADOPERATION;
3034  }
3035  if (LF_ISSET(NOT))
3036  aLong = ~aLong;
3037  switch (LF_ISSET(LOGICALOPS)) {
3038  case 0: *arg = (int) aLong; break;
3039  case POPT_ARGFLAG_OR: *(unsigned int *)arg |= (unsigned int) aLong; break;
3040  case POPT_ARGFLAG_AND: *(unsigned int *)arg &= (unsigned int) aLong; break;
3041  case POPT_ARGFLAG_XOR: *(unsigned int *)arg ^= (unsigned int) aLong; break;
3042  default:
3043  return POPT_ERROR_BADOPERATION;
3044  break;
3045  }
3046  return 0;
3047 }
3048 
3049 int poptSaveShort(short * arg, unsigned int argInfo, long aLong)
3050 {
3051  /* XXX Check alignment, may fail on funky platforms. */
3052  if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
3053  return POPT_ERROR_NULLARG;
3054 
3055  if (aLong != 0 && LF_ISSET(RANDOM)) {
3056  /* XXX avoid adding POPT_ERROR_UNIMPLEMENTED to minimize i18n churn. */
3057  return POPT_ERROR_BADOPERATION;
3058  }
3059  if (LF_ISSET(NOT))
3060  aLong = ~aLong;
3061  switch (LF_ISSET(LOGICALOPS)) {
3062  case 0: *arg = (short) aLong;
3063  break;
3064  case POPT_ARGFLAG_OR: *(unsigned short *)arg |= (unsigned short) aLong;
3065  break;
3066  case POPT_ARGFLAG_AND: *(unsigned short *)arg &= (unsigned short) aLong;
3067  break;
3068  case POPT_ARGFLAG_XOR: *(unsigned short *)arg ^= (unsigned short) aLong;
3069  break;
3070  default: return POPT_ERROR_BADOPERATION;
3071  break;
3072  }
3073  return 0;
3074 }
3075 
3082 static unsigned int poptArgInfo(poptContext con, const struct poptOption * opt)
3083 {
3084  unsigned int argInfo = opt->argInfo;
3085 
3086  if (con->os->argv != NULL && con->os->next > 0 && opt->longName != NULL)
3087  if (LF_ISSET(TOGGLE)) {
3088  const char * longName = con->os->argv[con->os->next-1];
3089  while (*longName == '-') longName++;
3090  /* XXX almost good enough but consider --[no]nofoo corner cases. */
3091  if (longName[0] != opt->longName[0] || longName[1] != opt->longName[1])
3092  {
3093  if (!LF_ISSET(XOR)) { /* XXX dont toggle with XOR */
3094  /* Toggle POPT_BIT_SET <=> POPT_BIT_CLR. */
3095  if (LF_ISSET(LOGICALOPS))
3096  argInfo ^= (POPT_ARGFLAG_OR|POPT_ARGFLAG_AND);
3097  argInfo ^= POPT_ARGFLAG_NOT;
3098  }
3099  }
3100  }
3101  return argInfo;
3102 }
3103 
3111 static int poptParseInteger(long long * llp,
3112  UNUSED(unsigned int argInfo),
3113  const char * val)
3114 {
3115  if (val) {
3116  char *end = NULL;
3117  *llp = strtoll(val, &end, 0);
3118 
3119  /* XXX parse scaling suffixes here. */
3120 
3121  if (!(end && *end == '\0'))
3122  return POPT_ERROR_BADNUMBER;
3123  } else
3124  *llp = 0;
3125  return 0;
3126 }
3127 
3134 static int poptSaveArg(poptContext con, const struct poptOption * opt)
3135 {
3136  poptArg arg;
3137  arg.ptr = opt->arg;
3138  int rc = 0; /* assume success */
3139 
3140  switch (poptArgType(opt)) {
3141  case POPT_ARG_BITSET:
3142  /* XXX memory leak, application is responsible for free. */
3143  rc = poptSaveBits((poptBits*)arg.ptr, opt->argInfo, con->os->nextArg);
3144  break;
3145  case POPT_ARG_ARGV:
3146  /* XXX memory leak, application is responsible for free. */
3147  rc = poptSaveString((const char***)arg.ptr, opt->argInfo, con->os->nextArg);
3148  break;
3149  case POPT_ARG_STRING:
3150  /* XXX memory leak, application is responsible for free. */
3151  arg.argv[0] = (con->os->nextArg) ? xstrdup(con->os->nextArg) : NULL;
3152  break;
3153 
3154  case POPT_ARG_INT:
3155  case POPT_ARG_SHORT:
3156  case POPT_ARG_LONG:
3157  case POPT_ARG_LONGLONG:
3158  { unsigned int argInfo = poptArgInfo(con, opt);
3159  long long aNUM = 0;
3160 
3161  if ((rc = poptParseInteger(&aNUM, argInfo, con->os->nextArg)) != 0)
3162  break;
3163 
3164  switch (poptArgType(opt)) {
3165  case POPT_ARG_LONGLONG:
3166 /* XXX let's not demand C99 compiler flags for <limits.h> quite yet. */
3167  rc = !(aNUM == LLONG_MIN || aNUM == LLONG_MAX)
3168  ? poptSaveLongLong(arg.longlongp, argInfo, aNUM)
3170  break;
3171  case POPT_ARG_LONG:
3172  rc = !(aNUM < (long long)LONG_MIN || aNUM > (long long)LONG_MAX)
3173  ? poptSaveLong(arg.longp, argInfo, (long)aNUM)
3175  break;
3176  case POPT_ARG_INT:
3177  rc = !(aNUM < (long long)INT_MIN || aNUM > (long long)INT_MAX)
3178  ? poptSaveInt(arg.intp, argInfo, (long)aNUM)
3180  break;
3181  case POPT_ARG_SHORT:
3182  rc = !(aNUM < (long long)SHRT_MIN || aNUM > (long long)SHRT_MAX)
3183  ? poptSaveShort(arg.shortp, argInfo, (long)aNUM)
3185  break;
3186  }
3187  } break;
3188 
3189  case POPT_ARG_FLOAT:
3190  case POPT_ARG_DOUBLE:
3191  { char *end = NULL;
3192  double aDouble = 0.0;
3193 
3194  if (con->os->nextArg) {
3195  int saveerrno = errno;
3196  errno = 0;
3197  aDouble = strtod(con->os->nextArg, &end);
3198  if (errno == ERANGE) {
3199  rc = POPT_ERROR_OVERFLOW;
3200  break;
3201  }
3202  errno = saveerrno;
3203  if (*end != '\0') {
3204  rc = POPT_ERROR_BADNUMBER;
3205  break;
3206  }
3207  }
3208 
3209  switch (poptArgType(opt)) {
3210  case POPT_ARG_DOUBLE:
3211  arg.doublep[0] = aDouble;
3212  break;
3213  case POPT_ARG_FLOAT:
3214 #define POPT_ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a))
3215  if ((FLT_MIN - POPT_ABS(aDouble)) > DBL_EPSILON
3216  || (POPT_ABS(aDouble) - FLT_MAX) > DBL_EPSILON)
3217  rc = POPT_ERROR_OVERFLOW;
3218  else
3219  arg.floatp[0] = (float) aDouble;
3220  break;
3221  }
3222  } break;
3223  case POPT_ARG_MAINCALL:
3224  con->maincall = (int (*)(int,const char **))opt->arg;
3225  break;
3226  default:
3227  fprintf(stdout, POPT_("option type (%u) not implemented in popt\n"),
3228  poptArgType(opt));
3229  exit(EXIT_FAILURE);
3230  break;
3231  }
3232  return rc;
3233 }
3234 
3235 /* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
3237 {
3238  const struct poptOption * opt = NULL;
3239  int done = 0;
3240 
3241  if (con == NULL)
3242  return -1;
3243  while (!done) {
3244  const char * origOptString = NULL;
3245  poptCallbackType cb = NULL;
3246  const void * cbData = NULL;
3247  const char * longArg = NULL;
3248  int canstrip = 0;
3249  int shorty = 0;
3250 
3251  while (!con->os->nextCharArg && con->os->next == con->os->argc
3252  && con->os > con->optionStack) {
3253  cleanOSE(con->os--);
3254  }
3255  if (!con->os->nextCharArg && con->os->next == con->os->argc) {
3256  invokeCallbacksPOST(con, con->options);
3257 
3258  if (con->maincall) {
3259  (void) (*con->maincall) (con->finalArgvCount, con->finalArgv);
3260  return -1;
3261  }
3262 
3263  if (con->doExec) return execCommand(con);
3264  return -1;
3265  }
3266 
3267  /* Process next long option */
3268  if (!con->os->nextCharArg) {
3269  const char * optString;
3270  size_t optStringLen;
3271  int thisopt;
3272 
3273  if (con->os->argb && PBM_ISSET(con->os->next, con->os->argb)) {
3274  con->os->next++;
3275  continue;
3276  }
3277  thisopt = con->os->next;
3278  if (con->os->argv != NULL) /* XXX can't happen */
3279  origOptString = con->os->argv[con->os->next++];
3280 
3281  if (origOptString == NULL) /* XXX can't happen */
3282  return POPT_ERROR_BADOPT;
3283 
3284  if (con->restLeftover || *origOptString != '-' ||
3285  (*origOptString == '-' && origOptString[1] == '\0'))
3286  {
3287  if (con->flags & POPT_CONTEXT_POSIXMEHARDER)
3288  con->restLeftover = 1;
3289  if (con->flags & POPT_CONTEXT_ARG_OPTS) {
3290  con->os->nextArg = xstrdup(origOptString);
3291  return 0;
3292  }
3293  if (con->leftovers != NULL) /* XXX can't happen */
3294  con->leftovers[con->numLeftovers++] = origOptString;
3295  continue;
3296  }
3297 
3298  /* Make a copy we can hack at */
3299  optString = origOptString;
3300 
3301  if (optString[0] == '\0')
3302  return POPT_ERROR_BADOPT;
3303 
3304  if (optString[1] == '-' && !optString[2]) {
3305  con->restLeftover = 1;
3306  continue;
3307  } else {
3308  const char *oe;
3309  unsigned int argInfo = 0;
3310 
3311  optString++;
3312  if (*optString == '-')
3313  optString++;
3314  else
3316 
3317  /* Check for "--long=arg" option. */
3318  for (oe = optString; *oe && *oe != '='; oe++)
3319  {};
3320  optStringLen = (size_t)(oe - optString);
3321  if (*oe == '=')
3322  longArg = oe + 1;
3323 
3324  /* XXX aliases with arg substitution need "--alias=arg" */
3325  if (handleAlias(con, optString, optStringLen, '\0', longArg)) {
3326  longArg = NULL;
3327  continue;
3328  }
3329 
3330  if (handleExec(con, optString, '\0'))
3331  continue;
3332 
3333  opt = findOption(con->options, optString, optStringLen, '\0', &cb, &cbData,
3334  argInfo);
3335  if (!opt && !LF_ISSET(ONEDASH))
3336  return POPT_ERROR_BADOPT;
3337  }
3338 
3339  if (!opt) {
3340  con->os->nextCharArg = origOptString + 1;
3341  longArg = NULL;
3342  } else {
3343  if (con->os == con->optionStack && F_ISSET(opt, STRIP))
3344  {
3345  canstrip = 1;
3346  poptStripArg(con, thisopt);
3347  }
3348  shorty = 0;
3349  }
3350  }
3351 
3352  /* Process next short option */
3353  if (con->os->nextCharArg) {
3354  const char * nextCharArg = con->os->nextCharArg;
3355 
3356  con->os->nextCharArg = NULL;
3357 
3358  if (handleAlias(con, NULL, 0, *nextCharArg, nextCharArg + 1))
3359  continue;
3360 
3361  if (handleExec(con, NULL, *nextCharArg)) {
3362  /* Restore rest of short options for further processing */
3363  nextCharArg++;
3364  if (*nextCharArg != '\0')
3365  con->os->nextCharArg = nextCharArg;
3366  continue;
3367  }
3368 
3369  opt = findOption(con->options, NULL, 0, *nextCharArg, &cb,
3370  &cbData, 0);
3371  if (!opt)
3372  return POPT_ERROR_BADOPT;
3373  shorty = 1;
3374 
3375  nextCharArg++;
3376  if (*nextCharArg != '\0')
3377  con->os->nextCharArg = nextCharArg + (int)(*nextCharArg == '=');
3378  }
3379 
3380  if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */
3381  if (opt->arg && poptArgType(opt) == POPT_ARG_NONE) {
3382  unsigned int argInfo = poptArgInfo(con, opt);
3383  if (poptSaveInt((int *)opt->arg, argInfo, 1L))
3384  return POPT_ERROR_BADOPERATION;
3385  } else if (poptArgType(opt) == POPT_ARG_VAL) {
3386  if (opt->arg) {
3387  unsigned int argInfo = poptArgInfo(con, opt);
3388  if (poptSaveInt((int *)opt->arg, argInfo, (long)opt->val))
3389  return POPT_ERROR_BADOPERATION;
3390  }
3391  } else if (poptArgType(opt) != POPT_ARG_NONE) {
3392  int rc;
3393 
3394  con->os->nextArg = (char*)_free(con->os->nextArg);
3395  if (longArg) {
3396  longArg = expandNextArg(con, longArg);
3397  con->os->nextArg = (char *) longArg;
3398  } else if (con->os->nextCharArg) {
3399  longArg = expandNextArg(con, con->os->nextCharArg);
3400  con->os->nextArg = (char *) longArg;
3401  con->os->nextCharArg = NULL;
3402  } else {
3403  while (con->os->next == con->os->argc &&
3404  con->os > con->optionStack)
3405  {
3406  cleanOSE(con->os--);
3407  }
3408  if (con->os->next == con->os->argc) {
3409  if (!F_ISSET(opt, OPTIONAL))
3410  return POPT_ERROR_NOARG;
3411  con->os->nextArg = NULL;
3412  } else {
3413 
3414  /*
3415  * Make sure this isn't part of a short arg or the
3416  * result of an alias expansion.
3417  */
3418  if (con->os == con->optionStack
3419  && F_ISSET(opt, STRIP) && canstrip)
3420  {
3421  poptStripArg(con, con->os->next);
3422  }
3423 
3424  if (con->os->argv != NULL) { /* XXX can't happen */
3425  if (F_ISSET(opt, OPTIONAL) &&
3426  con->os->argv[con->os->next][0] == '-') {
3427  con->os->nextArg = NULL;
3428  } else {
3429  /* XXX watchout: subtle side-effects live here. */
3430  longArg = con->os->argv[con->os->next++];
3431  longArg = expandNextArg(con, longArg);
3432  con->os->nextArg = (char *) longArg;
3433  }
3434  }
3435  }
3436  }
3437  longArg = NULL;
3438 
3439  /* Save the option argument through a (*opt->arg) pointer. */
3440  if (opt->arg != NULL && (rc = poptSaveArg(con, opt)) != 0)
3441  return rc;
3442  }
3443 
3444  if (cb)
3445  invokeCallbacksOPTION(con, con->options, opt, cbData, shorty);
3446  else if (opt->val && (poptArgType(opt) != POPT_ARG_VAL))
3447  done = 1;
3448 
3449  if ((con->finalArgvCount + 2) >= (con->finalArgvAlloced)) {
3450  con->finalArgvAlloced += 10;
3451  con->finalArgv = (poptArgv)realloc(con->finalArgv,
3452  sizeof(*con->finalArgv) * con->finalArgvAlloced);
3453  }
3454 
3455  if (con->finalArgv != NULL)
3456  { char *s = (char*)malloc((opt->longName ? strlen(opt->longName) : 0) + sizeof("--"));
3457  if (s != NULL) { /* XXX can't happen */
3458  con->finalArgv[con->finalArgvCount++] = s;
3459  *s++ = '-';
3460  if (opt->longName) {
3461  if (!F_ISSET(opt, ONEDASH))
3462  *s++ = '-';
3463  s = stpcpy(s, opt->longName);
3464  } else {
3465  *s++ = opt->shortName;
3466  *s = '\0';
3467  }
3468  } else
3469  con->finalArgv[con->finalArgvCount++] = NULL;
3470  }
3471 
3472  if (opt->arg && poptArgType(opt) == POPT_ARG_NONE);
3473  else if (poptArgType(opt) == POPT_ARG_VAL);
3474  else if (poptArgType(opt) != POPT_ARG_NONE) {
3475  if (con->finalArgv != NULL && con->os->nextArg != NULL)
3476  con->finalArgv[con->finalArgvCount++] =
3477  xstrdup(con->os->nextArg);
3478  }
3479  }
3480 
3481  return (opt ? opt->val : -1); /* XXX can't happen */
3482 }
3483 
3485 {
3486  char * ret = NULL;
3487  if (con) {
3488  ret = con->os->nextArg;
3489  con->os->nextArg = NULL;
3490  }
3491  return ret;
3492 }
3493 
3494 const char * poptGetArg(poptContext con)
3495 {
3496  const char * ret = NULL;
3497  if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers)
3498  ret = con->leftovers[con->nextLeftover++];
3499  return ret;
3500 }
3501 
3502 const char * poptPeekArg(poptContext con)
3503 {
3504  const char * ret = NULL;
3505  if (con && con->leftovers != NULL && con->nextLeftover < con->numLeftovers)
3506  ret = con->leftovers[con->nextLeftover];
3507  return ret;
3508 }
3509 
3510 const char ** poptGetArgs(poptContext con)
3511 {
3512  if (con == NULL ||
3513  con->leftovers == NULL || con->numLeftovers == con->nextLeftover)
3514  return NULL;
3515 
3516  /* some apps like [like RPM ;-) ] need this NULL terminated */
3517  con->leftovers[con->numLeftovers] = NULL;
3518 
3519  return (con->leftovers + con->nextLeftover);
3520 }
3521 
3522 static
3523 poptItem poptFreeItems(poptItem items, int nitems)
3524 {
3525  if (items != NULL) {
3526  poptItem item = items;
3527  while (--nitems >= 0) {
3528  item->option.longName = (const char*)_free(item->option.longName);
3529  item->option.descrip = (const char*)_free(item->option.descrip);
3530  item->option.argDescrip = (const char*)_free(item->option.argDescrip);
3531  item->argv = (const char**)_free(item->argv);
3532  item++;
3533  }
3534  items = (poptItem)_free(items);
3535  }
3536  return NULL;
3537 }
3538 
3540 {
3541  if (con == NULL) return con;
3542  poptResetContext(con);
3543  con->os->argb = (pbm_set*)_free(con->os->argb);
3544 
3545  con->aliases = poptFreeItems(con->aliases, con->numAliases);
3546  con->numAliases = 0;
3547 
3548  con->execs = poptFreeItems(con->execs, con->numExecs);
3549  con->numExecs = 0;
3550 
3551  con->leftovers = (poptArgv)_free(con->leftovers);
3552  con->finalArgv = (poptArgv)_free(con->finalArgv);
3553  con->appName = (const char*)_free(con->appName);
3554  con->otherHelp = (const char*)_free(con->otherHelp);
3555  con->execPath = (const char*)_free(con->execPath);
3556  con->arg_strip = (pbm_set*)PBM_FREE(con->arg_strip);
3557 
3558  con = (poptContext)_free(con);
3559  return con;
3560 }
3561 
3562 int poptAddAlias(poptContext con, struct poptAlias alias,
3563  UNUSED(int flags))
3564 {
3565  struct poptItem_s item_buf;
3566  poptItem item = &item_buf;
3567  memset(item, 0, sizeof(*item));
3568  item->option.longName = alias.longName;
3569  item->option.shortName = alias.shortName;
3570  item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
3571  item->option.arg = 0;
3572  item->option.val = 0;
3573  item->option.descrip = NULL;
3574  item->option.argDescrip = NULL;
3575  item->argc = alias.argc;
3576  item->argv = alias.argv;
3577  return poptAddItem(con, item, 0);
3578 }
3579 
3580 int poptAddItem(poptContext con, poptItem newItem, int flags)
3581 {
3582  poptItem * items, item;
3583  int * nitems;
3584 
3585  switch (flags) {
3586  case 1:
3587  items = &con->execs;
3588  nitems = &con->numExecs;
3589  break;
3590  case 0:
3591  items = &con->aliases;
3592  nitems = &con->numAliases;
3593  break;
3594  default:
3595  return 1;
3596  break;
3597  }
3598 
3599  *items = (poptItem)realloc((*items), ((*nitems) + 1) * sizeof(**items));
3600  if ((*items) == NULL)
3601  return 1;
3602 
3603  item = (*items) + (*nitems);
3604 
3605  item->option.longName =
3606  (newItem->option.longName ? xstrdup(newItem->option.longName) : NULL);
3607  item->option.shortName = newItem->option.shortName;
3608  item->option.argInfo = newItem->option.argInfo;
3609  item->option.arg = newItem->option.arg;
3610  item->option.val = newItem->option.val;
3611  item->option.descrip =
3612  (newItem->option.descrip ? xstrdup(newItem->option.descrip) : NULL);
3613  item->option.argDescrip =
3614  (newItem->option.argDescrip ? xstrdup(newItem->option.argDescrip) : NULL);
3615  item->argc = newItem->argc;
3616  item->argv = newItem->argv;
3617 
3618  (*nitems)++;
3619 
3620  return 0;
3621 }
3622 
3623 const char * poptBadOption(poptContext con, unsigned int flags)
3624 {
3625  struct optionStackEntry * os = NULL;
3626 
3627  if (con != NULL)
3628  os = (flags & POPT_BADOPTION_NOALIAS) ? con->optionStack : con->os;
3629 
3630  return (os != NULL && os->argv != NULL ? os->argv[os->next - 1] : NULL);
3631 }
3632 
3633 const char * poptStrerror(const int error)
3634 {
3635  switch (error) {
3636  case POPT_ERROR_NOARG:
3637  return POPT_("missing argument");
3638  case POPT_ERROR_BADOPT:
3639  return POPT_("unknown option");
3641  return POPT_("mutually exclusive logical operations requested");
3642  case POPT_ERROR_NULLARG:
3643  return POPT_("opt->arg should not be NULL");
3645  return POPT_("aliases nested too deeply");
3646  case POPT_ERROR_BADQUOTE:
3647  return POPT_("error in parameter quoting");
3648  case POPT_ERROR_BADNUMBER:
3649  return POPT_("invalid numeric value");
3650  case POPT_ERROR_OVERFLOW:
3651  return POPT_("number too large or too small");
3652  case POPT_ERROR_MALLOC:
3653  return POPT_("memory allocation failed");
3654  case POPT_ERROR_BADCONFIG:
3655  return POPT_("config file failed sanity test");
3656  case POPT_ERROR_ERRNO:
3657  return strerror(errno);
3658  default:
3659  return POPT_("unknown error");
3660  }
3661 }
3662 
3663 int poptStuffArgs(poptContext con, const char ** argv)
3664 {
3665  int argc;
3666  int rc;
3667 
3668  if ((con->os - con->optionStack) == POPT_OPTION_DEPTH)
3669  return POPT_ERROR_OPTSTOODEEP;
3670 
3671  for (argc = 0; argv[argc]; argc++)
3672  {};
3673 
3674  con->os++;
3675  con->os->next = 0;
3676  con->os->nextArg = NULL;
3677  con->os->nextCharArg = NULL;
3678  con->os->currAlias = NULL;
3679  rc = poptDupArgv(argc, argv, &con->os->argc, &con->os->argv);
3680  con->os->argb = NULL;
3681  con->os->stuffed = 1;
3682 
3683  return rc;
3684 }
3685 
3687 {
3688  return (con->os->argv ? con->os->argv[0] : "");
3689 }
3690 
3691 int poptStrippedArgv(poptContext con, int argc, char ** argv)
3692 {
3693  int numargs = argc;
3694  int j = 1;
3695  int i;
3696 
3697  if (con->arg_strip)
3698  for (i = 1; i < argc; i++) {
3699  if (PBM_ISSET(i, con->arg_strip))
3700  numargs--;
3701  }
3702 
3703  for (i = 1; i < argc; i++) {
3704  if (con->arg_strip && PBM_ISSET(i, con->arg_strip))
3705  continue;
3706  argv[j] = (j < numargs) ? argv[i] : NULL;
3707  j++;
3708  }
3709 
3710  return numargs;
3711 }
poptContext_s::aliases
poptItem aliases
Definition: options_popt.cpp:298
poptSetExecPath
void poptSetExecPath(poptContext con, const char *path, int allowAbsolute)
Definition: options_popt.cpp:2170
poptContext_s::finalArgvCount
int finalArgvCount
Definition: options_popt.cpp:304
itemHelp
static void itemHelp(FILE *fp, poptItem items, int nitems, columns_t columns, const char *translation_domain)
Definition: options_popt.cpp:1187
optionStackEntry::argc
int argc
Definition: options_popt.cpp:279
optionStackEntry::next
int next
Definition: options_popt.cpp:282
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail2::end
end_tag end(T &&...)
poptItem_s::option
struct poptOption option
Definition: options_popt.h:172
stringDisplayWidth
static size_t stringDisplayWidth(const char *s)
Definition: options_popt.cpp:802
poptSaneFile
int poptSaneFile(const char *fn)
Definition: options_popt.cpp:361
poptArg_u::longp
long * longp
Definition: options_popt.cpp:228
poptStuffArgs
int poptStuffArgs(poptContext con, const char **argv)
Definition: options_popt.cpp:3663
findProgramPath
static const char * findProgramPath(const char *argv0)
Definition: options_popt.cpp:2510
poptDone_s
Definition: options_popt.cpp:1385
POPT_ARG_SHORT
#define POPT_ARG_SHORT
Definition: options_popt.h:76
POPT_ERROR_BADOPT
#define POPT_ERROR_BADOPT
Definition: options_popt.h:122
POPT_CONTEXT_ARG_OPTS
#define POPT_CONTEXT_ARG_OPTS
Definition: options_popt.h:144
PBM_ALLOC
#define PBM_ALLOC(d)
Definition: options_popt.cpp:206
poptCallbackReason
poptCallbackReason
Definition: options_popt.h:197
_dbswap
Definition: options_popt.cpp:1572
poptSetOtherOptionHelp
void poptSetOtherOptionHelp(poptContext con, const char *text)
Definition: options_popt.cpp:1515
eAJASeekEnd
@ eAJASeekEnd
Definition: file_io.h:49
POPT_fprintf
int POPT_fprintf(FILE *stream, const char *format,...)
Definition: options_popt.cpp:1895
poptOption
Definition: options_popt.h:148
_poptArgMask
unsigned int _poptArgMask
Definition: options_popt.cpp:2167
poptSaveShort
int poptSaveShort(short *arg, unsigned int argInfo, long aLong)
Definition: options_popt.cpp:3049
configAppMatch
static int configAppMatch(poptContext con, const char *s)
Definition: options_popt.cpp:448
getTableTranslationDomain
static const char * getTableTranslationDomain(const struct poptOption *opt)
Definition: options_popt.cpp:819
poptContext_s::execAbsolute
int execAbsolute
Definition: options_popt.cpp:309
POPT_ARGFLAG_NOT
#define POPT_ARGFLAG_NOT
Definition: options_popt.h:95
POPT_ERROR_MALLOC
#define POPT_ERROR_MALLOC
Definition: options_popt.h:130
utf8_skip_data
static const unsigned char utf8_skip_data[256]
Definition: options_popt.cpp:1856
poptItem_s::argc
int argc
Definition: options_popt.h:173
columns_s::cur
size_t cur
Definition: options_popt.cpp:782
NULL
#define NULL
Definition: ntv2caption608types.h:19
AJA_STATUS_SUCCESS
@ AJA_STATUS_SUCCESS
Definition: types.h:381
poptResetContext
void poptResetContext(poptContext con)
Definition: options_popt.cpp:2310
poptArgInfo
static unsigned int poptArgInfo(poptContext con, const struct poptOption *opt)
Definition: options_popt.cpp:3082
poptArgType
#define poptArgType(_opt)
Definition: options_popt.cpp:240
xrealloc
#define xrealloc(_ptr, _size)
Definition: options_popt.cpp:170
POPT_ARGV_ARRAY_GROW_DELTA
#define POPT_ARGV_ARRAY_GROW_DELTA
Definition: options_popt.cpp:1937
poptFreeItems
static poptItem poptFreeItems(poptItem items, int nitems)
Definition: options_popt.cpp:3523
poptPrintHelp
void poptPrintHelp(poptContext con, FILE *fp, int flags __attribute__((__unused__)))
Definition: options_popt.cpp:1272
poptGetArg
const char * poptGetArg(poptContext con)
Definition: options_popt.cpp:3494
poptConfigFileToString
int poptConfigFileToString(FILE *fp, char **argstrp, int flags __attribute__((__unused__)))
Definition: options_popt.cpp:2056
POPT_CONTEXT_NO_EXEC
#define POPT_CONTEXT_NO_EXEC
Definition: options_popt.h:141
poptContext_s::execs
poptItem execs
Definition: options_popt.cpp:301
POPT_ARGFLAG_XOR
#define POPT_ARGFLAG_XOR
Definition: options_popt.h:94
poptSaveArg
static int poptSaveArg(poptContext con, const struct poptOption *opt)
Definition: options_popt.cpp:3134
poptOption::descrip
const char * descrip
Definition: options_popt.h:154
poptBitsClr
int poptBitsClr(poptBits bits)
Definition: options_popt.cpp:2827
singleOptionHelp
static void singleOptionHelp(FILE *fp, columns_t columns, const struct poptOption *opt, const char *translation_domain)
Definition: options_popt.cpp:962
poptArg_u::doublep
double * doublep
Definition: options_popt.cpp:231
poptBits
struct poptBits_s * poptBits
poptSaveBits
int poptSaveBits(poptBits *bitsp, unsigned int argInfo __attribute__((__unused__)), const char *s)
Definition: options_popt.cpp:2916
prtlong
#define prtlong
poptStrerror
const char * poptStrerror(const int error)
Definition: options_popt.cpp:3633
_poptGroupMask
unsigned int _poptGroupMask
Definition: options_popt.cpp:2168
POPT_ARG_INCLUDE_TABLE
#define POPT_ARG_INCLUDE_TABLE
Definition: options_popt.h:60
POPT_ARG_FLOAT
#define POPT_ARG_FLOAT
Definition: options_popt.h:70
POPT_ERROR_ERRNO
#define POPT_ERROR_ERRNO
Definition: options_popt.h:125
POPT_CALLBACK_REASON_OPTION
@ POPT_CALLBACK_REASON_OPTION
Definition: options_popt.h:200
PBM_ISSET
#define PBM_ISSET(d, s)
Definition: options_popt.cpp:210
singleTableHelp
static void singleTableHelp(poptContext con, FILE *fp, const struct poptOption *table, columns_t columns, const char *translation_domain)
Definition: options_popt.cpp:1212
optionStackEntry::argb
pbm_set * argb
Definition: options_popt.cpp:281
poptReadFile
int poptReadFile(const char *fn, char **bp, size_t *nbp, int flags)
Definition: options_popt.cpp:377
POPT_ARG_CALLBACK
#define POPT_ARG_CALLBACK
Definition: options_popt.h:61
poptArgv
poptString * poptArgv
Definition: options_popt.cpp:219
POPT_ARG_INTL_DOMAIN
#define POPT_ARG_INTL_DOMAIN
Definition: options_popt.h:65
eAJAReadOnly
@ eAJAReadOnly
Definition: file_io.h:31
POPT_ARG_MAINCALL
#define POPT_ARG_MAINCALL
Definition: options_popt.h:74
poptGetOptArg
char * poptGetOptArg(poptContext con)
Definition: options_popt.cpp:3484
_dbswap::uc
const unsigned char uc[4]
Definition: options_popt.cpp:1574
POPT_CONTEXT_KEEP_FIRST
#define POPT_CONTEXT_KEEP_FIRST
Definition: options_popt.h:142
poptSubstituteHelpI18N
#define poptSubstituteHelpI18N(opt)
Definition: options_popt.cpp:272
jlu32lpair
#define jlu32lpair
Definition: options_popt.cpp:1531
nlohmann::json_abiNLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON_v3_11_NLOHMANN_JSON_VERSION_PATCH::detail::void
j template void())
Definition: json.hpp:4893
POPT_ARG_INT
#define POPT_ARG_INT
Definition: options_popt.h:58
poptPeekArg
const char * poptPeekArg(poptContext con)
Definition: options_popt.cpp:3502
handleExec
static int handleExec(poptContext con, const char *longName, char shortName)
Definition: options_popt.cpp:2340
POPT_next_char
const char * POPT_next_char(const char *str)
Definition: options_popt.cpp:1880
poptAlias::argv
const char ** argv
Definition: options_popt.h:165
poptContext_s
Definition: options_popt.cpp:289
singleTableUsage
static size_t singleTableUsage(poptContext con, FILE *fp, columns_t columns, const struct poptOption *opt, const char *translation_domain, poptDone done)
Definition: options_popt.cpp:1401
poptContext_s::numLeftovers
int numLeftovers
Definition: options_popt.cpp:293
HASH_LITTLE_ENDIAN
#define HASH_LITTLE_ENDIAN
Definition: options_popt.cpp:1576
AJAFileIO::Open
AJAStatus Open(const std::string &fileName, const int flags, const int properties)
Definition: file_io.cpp:201
POPT_ERROR_NULLARG
#define POPT_ERROR_NULLARG
Definition: options_popt.h:129
POPT_ARGFLAG_DOC_HIDDEN
#define POPT_ARGFLAG_DOC_HIDDEN
Definition: options_popt.h:86
POPT_GROUP_MASK
#define POPT_GROUP_MASK
Definition: options_popt.h:80
poptAlias::shortName
char shortName
Definition: options_popt.h:163
PBM_SET
#define PBM_SET(d, s)
Definition: options_popt.cpp:208
poptArg_u::longlongp
long long * longlongp
Definition: options_popt.cpp:229
POPT_ARG_DOUBLE
#define POPT_ARG_DOUBLE
Definition: options_popt.h:71
xmalloc
#define xmalloc(_size)
Definition: options_popt.cpp:168
process.h
Declares the AJAProcess class.
_POPT_BITS_N
#define _POPT_BITS_N
Definition: options_popt.h:599
poptStrippedArgv
int poptStrippedArgv(poptContext con, int argc, char **argv)
Definition: options_popt.cpp:3691
poptAlias::longName
const char * longName
Definition: options_popt.h:162
poptOption::longName
const char * longName
Definition: options_popt.h:149
poptAliasOptions
struct poptOption poptAliasOptions[]
Definition: options_popt.cpp:777
poptHelpOptions
static struct poptOption poptHelpOptions[]
Definition: options_popt.cpp:252
_JLU3_FINAL
#define _JLU3_FINAL(a, b, c)
Definition: options_popt.cpp:1665
poptGetInvocationName
const char * poptGetInvocationName(poptContext con)
Definition: options_popt.cpp:3686
optionStackEntry
Definition: options_popt.cpp:278
poptOption::argInfo
unsigned int argInfo
Definition: options_popt.h:151
poptBitsUnion
int poptBitsUnion(poptBits *ap, const poptBits b)
Definition: options_popt.cpp:2877
_poptBitsM
unsigned int _poptBitsM
Definition: options_popt.cpp:2764
POPT_CALLBACK_REASON_POST
@ POPT_CALLBACK_REASON_POST
Definition: options_popt.h:199
optionStackEntry::argv
poptArgv argv
Definition: options_popt.cpp:280
AJAFileIO::Seek
AJAStatus Seek(const int64_t distance, const AJAFileSetFlag flag) const
Definition: file_io.cpp:545
poptReadDefaultConfig
int poptReadDefaultConfig(poptContext con, int useEnv __attribute__((__unused__)))
Definition: options_popt.cpp:681
poptString
const typedef char * poptString
Definition: options_popt.cpp:218
poptGlob
static int poptGlob(poptContext con __attribute__((__unused__)), const char *pattern, int *acp, const char ***avp)
Definition: options_popt.cpp:341
poptDupArgv
int poptDupArgv(int argc, const char **argv, int *argcPtr, const char ***argvPtr)
Definition: options_popt.cpp:1939
poptContext_s::options
const struct poptOption * options
Definition: options_popt.cpp:295
poptBitsAdd
int poptBitsAdd(poptBits bits, const char *s)
Definition: options_popt.cpp:2785
POPT_ARG_ARGV
#define POPT_ARG_ARGV
Definition: options_popt.h:75
getArgDescrip
static const char * getArgDescrip(const struct poptOption *opt, const char *translation_domain)
Definition: options_popt.cpp:834
poptContext_s::arg_strip
pbm_set * arg_strip
Definition: options_popt.cpp:311
columns_s
Definition: options_popt.cpp:781
poptOption::arg
void * arg
Definition: options_popt.h:152
poptContext_s::leftovers
poptArgv leftovers
Definition: options_popt.cpp:292
POPT_ABS
#define POPT_ABS(a)
poptInit
poptContext poptInit(int argc, const char **argv, const struct poptOption *options, const char *configPaths)
Definition: options_popt.cpp:720
__PBM_IX
#define __PBM_IX(d)
Definition: options_popt.cpp:199
POPT_ARG_BITSET
#define POPT_ARG_BITSET
Definition: options_popt.h:77
optionStackEntry::nextCharArg
const char * nextCharArg
Definition: options_popt.cpp:284
showShortOptions
static size_t showShortOptions(const struct poptOption *opt, FILE *fp, char *str)
Definition: options_popt.cpp:1446
displayArgs
void displayArgs(poptContext con, enum poptCallbackReason foo __attribute__((__unused__)), struct poptOption *key, const char *arg __attribute__((__unused__)), void *data __attribute__((__unused__)))
Definition: options_popt.cpp:760
poptOption::shortName
char shortName
Definition: options_popt.h:150
POPT_ERROR_BADQUOTE
#define POPT_ERROR_BADQUOTE
Definition: options_popt.h:124
poptContext_s::numExecs
int numExecs
Definition: options_popt.cpp:302
poptContext_s::execPath
const char * execPath
Definition: options_popt.cpp:308
handleAlias
static int handleAlias(poptContext con, const char *longName, size_t longNameLen, char shortName, const char *nextArg)
Definition: options_popt.cpp:2434
POPT_ARG_VAL
#define POPT_ARG_VAL
Definition: options_popt.h:69
PBM_FREE
#define PBM_FREE(s)
Definition: options_popt.cpp:207
POPT_ERROR_BADOPERATION
#define POPT_ERROR_BADOPERATION
Definition: options_popt.h:128
options_popt.h
POPT_BADOPTION_NOALIAS
#define POPT_BADOPTION_NOALIAS
Definition: options_popt.h:136
poptAlias::argc
int argc
Definition: options_popt.h:164
poptHelpOptionsI18N
struct poptOption * poptHelpOptionsI18N
Definition: options_popt.cpp:270
optionStackEntry::currAlias
poptItem currAlias
Definition: options_popt.cpp:285
poptAlias
Definition: options_popt.h:161
poptStripArg
static void poptStripArg(poptContext con, int which)
Definition: options_popt.cpp:2754
poptContext_s::restLeftover
int restLeftover
Definition: options_popt.cpp:296
poptFreeContext
poptContext poptFreeContext(poptContext con)
Definition: options_popt.cpp:3539
poptBitsChk
int poptBitsChk(poptBits bits, const char *s)
Definition: options_popt.cpp:2804
poptAddItem
int poptAddItem(poptContext con, poptItem newItem, int flags)
Definition: options_popt.cpp:3580
__PBM_NBITS
#define __PBM_NBITS
Definition: options_popt.cpp:198
PBM_CLR
#define PBM_CLR(d, s)
Definition: options_popt.cpp:209
pbm_set
Definition: options_popt.cpp:201
poptConfigLine
static int poptConfigLine(poptContext con, char *line)
Definition: options_popt.cpp:459
columns_s::max
size_t max
Definition: options_popt.cpp:783
_JLU3_INIT
#define _JLU3_INIT(_h, _size)
Definition: options_popt.cpp:1584
poptDone
struct poptDone_s * poptDone
poptItem_s
Definition: options_popt.h:171
POPT_ARGFLAG_OR
#define POPT_ARGFLAG_OR
Definition: options_popt.h:90
singleOptionUsage
static size_t singleOptionUsage(FILE *fp, columns_t columns, const struct poptOption *opt, const char *translation_domain)
Definition: options_popt.cpp:1297
poptBits_s
Definition: options_popt.h:595
invokeCallbacksPOST
static void invokeCallbacksPOST(poptContext con, const struct poptOption *opt)
Definition: options_popt.cpp:2199
CBF_ISSET
#define CBF_ISSET(_opt, _FLAG)
Definition: options_popt.cpp:245
POPT_CONTEXT_POSIXMEHARDER
#define POPT_CONTEXT_POSIXMEHARDER
Definition: options_popt.h:143
poptOption::argDescrip
const char * argDescrip
Definition: options_popt.h:155
POPT_READFILE_TRIMNEWLINES
#define POPT_READFILE_TRIMNEWLINES
Definition: options_popt.h:383
POPT_ARG_MASK
#define POPT_ARG_MASK
Definition: options_popt.h:79
expandNextArg
static const char * expandNextArg(poptContext con, const char *s)
Definition: options_popt.cpp:2709
POPT_ERROR_NOARG
#define POPT_ERROR_NOARG
Definition: options_popt.h:121
poptArg_u::opt
poptOption opt
Definition: options_popt.cpp:234
poptContext_s::doExec
poptItem doExec
Definition: options_popt.cpp:307
poptContext_s::flags
unsigned int flags
Definition: options_popt.cpp:300
endian
static const union _dbswap endian
_POPT_BITS_K
#define _POPT_BITS_K
Definition: options_popt.h:601
poptDone_s::maxopts
int maxopts
Definition: options_popt.cpp:1387
_poptBitsNew
static int _poptBitsNew(poptBits *bitsp)
Definition: options_popt.cpp:2767
poptContext_s::otherHelp
const char * otherHelp
Definition: options_popt.cpp:310
_poptBitsK
unsigned int _poptBitsK
Definition: options_popt.cpp:2765
poptDone_s::nopts
int nopts
Definition: options_popt.cpp:1386
poptContext_s::finalArgvAlloced
int finalArgvAlloced
Definition: options_popt.cpp:305
invokeCallbacksPRE
static void invokeCallbacksPRE(poptContext con, const struct poptOption *opt)
Definition: options_popt.cpp:2178
poptContext
struct poptContext_s * poptContext
Definition: options_popt.h:193
_free
static void * _free(const void *p)
Definition: options_popt.cpp:190
poptGetArgs
const char ** poptGetArgs(poptContext con)
Definition: options_popt.cpp:3510
poptAddAlias
int poptAddAlias(poptContext con, struct poptAlias alias, int flags __attribute__((__unused__)))
Definition: options_popt.cpp:3562
maxArgWidth
static size_t maxArgWidth(const struct poptOption *opt, const char *translation_domain)
Definition: options_popt.cpp:1137
_isspaceptr
#define _isspaceptr(_chp)
Definition: options_popt.cpp:149
POPT_prev_char
const char * POPT_prev_char(const char *str)
Definition: options_popt.cpp:1868
poptJlu32lpair
void poptJlu32lpair(const void *key, size_t size, uint32_t *pc, uint32_t *pb)
Definition: options_popt.cpp:1693
poptContext_s::numAliases
int numAliases
Definition: options_popt.cpp:299
AJAFileIO::Read
uint32_t Read(uint8_t *pBuffer, const uint32_t length)
Definition: file_io.cpp:328
file_io.h
Declares the AJAFileIO class.
poptGetContext
poptContext poptGetContext(const char *name, int argc, const char **argv, const struct poptOption *options, unsigned int flags)
Definition: options_popt.cpp:2264
poptSaveInt
int poptSaveInt(int *arg, unsigned int argInfo, long aLong)
Definition: options_popt.cpp:3025
maxColumnWidth
static size_t maxColumnWidth(FILE *fp)
Definition: options_popt.cpp:791
poptContext_s::nextLeftover
int nextLeftover
Definition: options_popt.cpp:294
poptPrintUsage
void poptPrintUsage(poptContext con, FILE *fp, int flags __attribute__((__unused__)))
Definition: options_popt.cpp:1480
POPT_
#define POPT_(foo)
Definition: options_popt.cpp:323
_POPT_BITS_M
#define _POPT_BITS_M
Definition: options_popt.h:600
poptItem_s::argv
const char ** argv
Definition: options_popt.h:174
cleanOSE
static void cleanOSE(struct optionStackEntry *os)
Definition: options_popt.cpp:2303
poptArg_u::shortp
short * shortp
Definition: options_popt.cpp:227
poptGetNextOpt
int poptGetNextOpt(poptContext con)
Definition: options_popt.cpp:3236
columns_t
struct columns_s * columns_t
optionStackEntry::stuffed
int stuffed
Definition: options_popt.cpp:286
findNextArg
static const char * findNextArg(poptContext con, unsigned argx, int delete_arg)
Definition: options_popt.cpp:2676
POPT_CALLBACK_REASON_PRE
@ POPT_CALLBACK_REASON_PRE
Definition: options_popt.h:198
__pbm_bits
unsigned int __pbm_bits
Definition: options_popt.cpp:197
_dbswap::ui
const uint32_t ui
Definition: options_popt.cpp:1573
_poptBitsN
unsigned int _poptBitsN
Definition: options_popt.cpp:2763
poptArg_u
Definition: options_popt.cpp:224
UNUSED
#define UNUSED(x)
Definition: options_popt.h:207
F_ISSET
#define F_ISSET(_opt, _FLAG)
Definition: options_popt.cpp:243
POPT_ERROR_BADNUMBER
#define POPT_ERROR_BADNUMBER
Definition: options_popt.h:126
poptHelpOptionsAutoHelp
struct poptOption * poptHelpOptionsAutoHelp
Definition: options_popt.cpp:258
AJAFileIO::Close
AJAStatus Close()
Definition: file_io.cpp:281
POPT_TABLEEND
#define POPT_TABLEEND
Definition: options_popt.h:215
longOptionStrcmp
static int longOptionStrcmp(const struct poptOption *opt, const char *longName, size_t longNameLen)
Definition: options_popt.cpp:2403
optionStackEntry::nextArg
char * nextArg
Definition: options_popt.cpp:283
poptSaveLongLong
int poptSaveLongLong(long long *arg, unsigned int argInfo, long long aLongLong)
Definition: options_popt.cpp:2970
poptContext_s::optionStack
struct optionStackEntry optionStack[10]
Definition: options_popt.cpp:290
poptReadConfigFiles
int poptReadConfigFiles(poptContext con, const char *paths)
Definition: options_popt.cpp:629
AJAFileIO::Tell
int64_t Tell()
Definition: file_io.cpp:503
poptArg_u::argv
const char ** argv
Definition: options_popt.cpp:232
poptParseInteger
static int poptParseInteger(long long *llp, unsigned int argInfo __attribute__((__unused__)), const char *val)
Definition: options_popt.cpp:3111
_JLU3_MIX
#define _JLU3_MIX(a, b, c)
Definition: options_popt.cpp:1630
AJAFileIO
Definition: file_io.h:64
POPT_ARG_LONG
#define POPT_ARG_LONG
Definition: options_popt.h:59
poptContext_s::os
struct optionStackEntry * os
Definition: options_popt.cpp:291
poptArg_u::floatp
float * floatp
Definition: options_popt.cpp:230
singleOptionDefaultValue
static char * singleOptionDefaultValue(size_t lineLength, const struct poptOption *opt, const char *translation_domain)
Definition: options_popt.cpp:884
poptDone_s::opts
const void ** opts
Definition: options_popt.cpp:1388
xstrdup
#define xstrdup(_str)
Definition: options_popt.cpp:171
poptBitsDel
int poptBitsDel(poptBits bits, const char *s)
Definition: options_popt.cpp:2838
poptContext_s::appName
const char * appName
Definition: options_popt.cpp:297
POPT_ARG_LONGLONG
#define POPT_ARG_LONGLONG
Definition: options_popt.h:72
poptSaveLong
int poptSaveLong(long *arg, unsigned int argInfo, long aLong)
Definition: options_popt.cpp:3001
poptFini
poptContext poptFini(poptContext con)
Definition: options_popt.cpp:714
POPT_ARGFLAG_AND
#define POPT_ARGFLAG_AND
Definition: options_popt.h:92
__PBM_BITS
#define __PBM_BITS(set)
Definition: options_popt.cpp:204
eAJASeekSet
@ eAJASeekSet
Definition: file_io.h:47
POPT_OPTION_DEPTH
#define POPT_OPTION_DEPTH
Definition: options_popt.h:51
poptBadOption
const char * poptBadOption(poptContext con, unsigned int flags)
Definition: options_popt.cpp:3623
itemUsage
static size_t itemUsage(FILE *fp, columns_t columns, poptItem item, int nitems, const char *translation_domain)
Definition: options_popt.cpp:1361
poptArg_u::cb
poptCallbackType cb
Definition: options_popt.cpp:233
invokeCallbacksOPTION
static void invokeCallbacksOPTION(poptContext con, const struct poptOption *opt, const struct poptOption *myOpt, const void *myData, int shorty)
Definition: options_popt.cpp:2220
poptContext_s::maincall
int(* maincall)(int argc, const char **argv)
Definition: options_popt.cpp:306
poptOption::val
int val
Definition: options_popt.h:153
poptSaveString
int poptSaveString(const char ***argvp, unsigned int argInfo __attribute__((__unused__)), const char *val)
Definition: options_popt.cpp:2950
showHelpIntro
static size_t showHelpIntro(poptContext con, FILE *fp)
Definition: options_popt.cpp:1254
poptContext_s::finalArgv
poptArgv finalArgv
Definition: options_popt.cpp:303
poptArg
union poptArg_u poptArg
poptItem
struct poptItem_s * poptItem
POPT_ARG_STRING
#define POPT_ARG_STRING
Definition: options_popt.h:57
poptCallbackType
void(* poptCallbackType)(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, const void *data)
Definition: options_popt.h:241
POPT_ERROR_BADCONFIG
#define POPT_ERROR_BADCONFIG
Definition: options_popt.h:131
POPT_ARGFLAG_ONEDASH
#define POPT_ARGFLAG_ONEDASH
Definition: options_popt.h:85
poptArg_u::intp
int * intp
Definition: options_popt.cpp:226
_POPTHELP_MAXLINE
#define _POPTHELP_MAXLINE
Definition: options_popt.cpp:250
execCommand
static int execCommand(poptContext con)
Definition: options_popt.cpp:2549
findOption
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: options_popt.cpp:2610
N_
#define N_(foo)
Definition: options_popt.h:214
POPT_ARG_NONE
#define POPT_ARG_NONE
Definition: options_popt.h:56
poptBitsIntersect
int poptBitsIntersect(poptBits *ap, const poptBits b)
Definition: options_popt.cpp:2857
poptParseArgvString
int poptParseArgvString(const char *s, int *argcPtr, const char ***argvPtr)
Definition: options_popt.cpp:1980
D_
#define D_(dom, str)
Definition: options_popt.cpp:322
POPT_ERROR_OPTSTOODEEP
#define POPT_ERROR_OPTSTOODEEP
Definition: options_popt.h:123
poptBitsArgs
int poptBitsArgs(poptContext con, poptBits *ap)
Definition: options_popt.cpp:2897
poptArg_u::ptr
void * ptr
Definition: options_popt.cpp:225
poptHelpOptions2
static struct poptOption poptHelpOptions2[]
Definition: options_popt.cpp:261
xcalloc
#define xcalloc(_nmemb, _size)
Definition: options_popt.cpp:169
LF_ISSET
#define LF_ISSET(_FLAG)
Definition: options_popt.cpp:244
POPT_ERROR_OVERFLOW
#define POPT_ERROR_OVERFLOW
Definition: options_popt.h:127
poptReadConfigFile
int poptReadConfigFile(poptContext con, const char *fn)
Definition: options_popt.cpp:579