popt  1.13
popthelp.c
Go to the documentation of this file.
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2 
7 /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
8  file accompanying popt source distributions, available from
9  ftp://ftp.rpm.org/pub/rpm/dist. */
10 
11 #include "system.h"
12 
13 #define POPT_USE_TIOCGWINSZ
14 #ifdef POPT_USE_TIOCGWINSZ
15 #include <sys/ioctl.h>
16 #endif
17 
18 #define POPT_WCHAR_HACK
19 #ifdef POPT_WCHAR_HACK
20 #include <wchar.h> /* for mbsrtowcs */
21 /*@access mbstate_t @*/
22 #endif
23 
24 
25 #include "poptint.h"
26 
27 /*@access poptContext@*/
28 
37 /*@exits@*/
38 static void displayArgs(poptContext con,
39  /*@unused@*/ enum poptCallbackReason foo,
40  struct poptOption * key,
41  /*@unused@*/ const char * arg, /*@unused@*/ void * data)
42  /*@globals fileSystem@*/
43  /*@modifies con, fileSystem@*/
44 {
45  if (key->shortName == '?')
46  poptPrintHelp(con, stdout, 0);
47  else
48  poptPrintUsage(con, stdout, 0);
49 
50 /*@i@*/ con = poptFreeContext(con); /* XXX keep valgrind happy */
51  exit(0);
52 }
53 
54 #ifdef NOTYET
55 /*@unchecked@*/
56 static int show_option_defaults = 0;
57 #endif
58 
62 /*@observer@*/ /*@unchecked@*/
65 };
66 
70 /*@-castfcnptr@*/
71 /*@observer@*/ /*@unchecked@*/
73  { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
74  { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
75  { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
77 } ;
78 
79 /*@observer@*/ /*@unchecked@*/
80 static struct poptOption poptHelpOptions2[] = {
81 /*@-readonlytrans@*/
82  { NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL},
83 /*@=readonlytrans@*/
84  { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
85  { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
86  { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
87 #ifdef NOTYET
88  { "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0,
89  N_("Display option defaults in message"), NULL },
90 #endif
92 } ;
93 
94 /*@observer@*/ /*@unchecked@*/
96 /*@=castfcnptr@*/
97 
98 #define _POPTHELP_MAXLINE ((size_t)79)
99 
100 typedef struct columns_s {
101  size_t cur;
102  size_t max;
103 } * columns_t;
104 
110 static size_t maxColumnWidth(FILE *fp)
111  /*@*/
112 {
113  size_t maxcols = _POPTHELP_MAXLINE;
114 #if defined(TIOCGWINSZ)
115  struct winsize ws;
116  int fdno = fileno(fp ? fp : stdout);
117 
118  memset(&ws, 0, sizeof(ws));
119  if (fdno >= 0 && !ioctl(fdno, TIOCGWINSZ, &ws)
120  && (size_t)ws.ws_col > maxcols && ws.ws_col < 256)
121  maxcols = ws.ws_col - 1;
122 #endif
123  return maxcols;
124 }
125 
129 /*@observer@*/ /*@null@*/ static const char *
130 getTableTranslationDomain(/*@null@*/ const struct poptOption *table)
131  /*@*/
132 {
133  const struct poptOption *opt;
134 
135  if (table != NULL)
136  for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
137  if (opt->argInfo == POPT_ARG_INTL_DOMAIN)
138  return opt->arg;
139  }
140  return NULL;
141 }
142 
147 /*@observer@*/ /*@null@*/ static const char *
148 getArgDescrip(const struct poptOption * opt,
149  /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */
150  /*@null@*/ const char * translation_domain)
151  /*@=paramuse@*/
152  /*@*/
153 {
154  if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
155 
156  if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_MAINCALL)
157  return opt->argDescrip;
158 
159  if (opt->argDescrip) {
160  /* Some strings need popt library, not application, i18n domain. */
161  if (opt == (poptHelpOptions + 1)
162  || opt == (poptHelpOptions + 2)
163  || !strcmp(opt->argDescrip,N_("Help options:"))
164  || !strcmp(opt->argDescrip,N_("Options implemented via popt alias/exec:")))
165  return POPT_(opt->argDescrip);
166 
167  /* Use the application i18n domain. */
168  return D_(translation_domain, opt->argDescrip);
169  }
170 
171  switch (opt->argInfo & POPT_ARG_MASK) {
172  case POPT_ARG_NONE: return POPT_("NONE");
173 #ifdef DYING
174  case POPT_ARG_VAL: return POPT_("VAL");
175 #else
176  case POPT_ARG_VAL: return NULL;
177 #endif
178  case POPT_ARG_INT: return POPT_("INT");
179  case POPT_ARG_LONG: return POPT_("LONG");
180  case POPT_ARG_STRING: return POPT_("STRING");
181  case POPT_ARG_FLOAT: return POPT_("FLOAT");
182  case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
183  case POPT_ARG_MAINCALL: return NULL;
184  default: return POPT_("ARG");
185  }
186 }
187 
195 static /*@only@*/ /*@null@*/ char *
196 singleOptionDefaultValue(size_t lineLength,
197  const struct poptOption * opt,
198  /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */
199  /*@null@*/ const char * translation_domain)
200  /*@=paramuse@*/
201  /*@*/
202 {
203  const char * defstr = D_(translation_domain, "default");
204  char * le = malloc(4*lineLength + 1);
205  char * l = le;
206 
207  if (le == NULL) return NULL; /* XXX can't happen */
208  *le = '\0';
209  *le++ = '(';
210  strcpy(le, defstr); le += strlen(le);
211  *le++ = ':';
212  *le++ = ' ';
213  if (opt->arg) /* XXX programmer error */
214  switch (opt->argInfo & POPT_ARG_MASK) {
215  case POPT_ARG_VAL:
216  case POPT_ARG_INT:
217  { long aLong = *((int *)opt->arg);
218  le += sprintf(le, "%ld", aLong);
219  } break;
220  case POPT_ARG_LONG:
221  { long aLong = *((long *)opt->arg);
222  le += sprintf(le, "%ld", aLong);
223  } break;
224  case POPT_ARG_FLOAT:
225  { double aDouble = *((float *)opt->arg);
226  le += sprintf(le, "%g", aDouble);
227  } break;
228  case POPT_ARG_DOUBLE:
229  { double aDouble = *((double *)opt->arg);
230  le += sprintf(le, "%g", aDouble);
231  } break;
232  case POPT_ARG_MAINCALL:
233  le += sprintf(le, "%p", opt->arg);
234  break;
235  case POPT_ARG_STRING:
236  { const char * s = *(const char **)opt->arg;
237  if (s == NULL) {
238  strcpy(le, "null"); le += strlen(le);
239  } else {
240  size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")");
241  *le++ = '"';
242  strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le);
243  if (slen < strlen(s)) {
244  strcpy(le, "..."); le += strlen(le);
245  }
246  *le++ = '"';
247  }
248  } break;
249  case POPT_ARG_NONE:
250  default:
251  l = _free(l);
252  return NULL;
253  /*@notreached@*/ break;
254  }
255  *le++ = ')';
256  *le = '\0';
257 
258  return l;
259 }
260 
268 static void singleOptionHelp(FILE * fp, columns_t columns,
269  const struct poptOption * opt,
270  /*@null@*/ const char * translation_domain)
271  /*@globals fileSystem @*/
272  /*@modifies fp, fileSystem @*/
273 {
274  size_t maxLeftCol = columns->cur;
275  size_t indentLength = maxLeftCol + 5;
276  size_t lineLength = columns->max - indentLength;
277  const char * help = D_(translation_domain, opt->descrip);
278  const char * argDescrip = getArgDescrip(opt, translation_domain);
279  size_t helpLength;
280  char * defs = NULL;
281  char * left;
282  size_t nb = maxLeftCol + 1;
283  int displaypad = 0;
284 
285  /* Make sure there's more than enough room in target buffer. */
286  if (opt->longName) nb += strlen(opt->longName);
287  if (argDescrip) nb += strlen(argDescrip);
288 
289  left = malloc(nb);
290  if (left == NULL) return; /* XXX can't happen */
291  left[0] = '\0';
292  left[maxLeftCol] = '\0';
293 
294  if (opt->longName && opt->shortName)
295  sprintf(left, "-%c, %s%s", opt->shortName,
296  ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
297  opt->longName);
298  else if (opt->shortName != '\0')
299  sprintf(left, "-%c", opt->shortName);
300  else if (opt->longName)
301  sprintf(left, "%s%s",
302  ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_MAINCALL ? "" :
303  ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--")),
304  opt->longName);
305  if (!*left) goto out;
306 
307  if (argDescrip) {
308  char * le = left + strlen(left);
309 
310  if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
311  *le++ = '[';
312 
313  /* Choose type of output */
314  if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) {
315  defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
316  if (defs) {
317  char * t = malloc((help ? strlen(help) : 0) +
318  strlen(defs) + sizeof(" "));
319  if (t) {
320  char * te = t;
321  *te = '\0';
322  if (help) {
323  strcpy(te, help); te += strlen(te);
324  }
325  *te++ = ' ';
326  strcpy(te, defs);
327  defs = _free(defs);
328  }
329  defs = t;
330  }
331  }
332 
333  if (opt->argDescrip == NULL) {
334  switch (opt->argInfo & POPT_ARG_MASK) {
335  case POPT_ARG_NONE:
336  break;
337  case POPT_ARG_VAL:
338 #ifdef NOTNOW /* XXX pug ugly nerdy output */
339  { long aLong = opt->val;
340  int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS);
341  int negate = (opt->argInfo & POPT_ARGFLAG_NOT);
342 
343  /* Don't bother displaying typical values */
344  if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L))
345  break;
346  *le++ = '[';
347  switch (ops) {
348  case POPT_ARGFLAG_OR:
349  *le++ = '|';
350  /*@innerbreak@*/ break;
351  case POPT_ARGFLAG_AND:
352  *le++ = '&';
353  /*@innerbreak@*/ break;
354  case POPT_ARGFLAG_XOR:
355  *le++ = '^';
356  /*@innerbreak@*/ break;
357  default:
358  /*@innerbreak@*/ break;
359  }
360  *le++ = (opt->longName != NULL ? '=' : ' ');
361  if (negate) *le++ = '~';
362  /*@-formatconst@*/
363  le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
364  /*@=formatconst@*/
365  *le++ = ']';
366  }
367 #endif
368  break;
369  case POPT_ARG_INT:
370  case POPT_ARG_LONG:
371  case POPT_ARG_FLOAT:
372  case POPT_ARG_DOUBLE:
373  case POPT_ARG_STRING:
374  *le++ = (opt->longName != NULL ? '=' : ' ');
375  strcpy(le, argDescrip); le += strlen(le);
376  break;
377  default:
378  break;
379  }
380  } else {
381  size_t lelen;
382 
383  *le++ = ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_MAINCALL)
384  ? ' ' : '=';
385  strcpy(le, argDescrip);
386  lelen = strlen(le);
387  le += lelen;
388 
389 #ifdef POPT_WCHAR_HACK
390  { const char * scopy = argDescrip;
391  mbstate_t t;
392  size_t n;
393 
394  memset ((void *)&t, 0, sizeof (t)); /* In initial state. */
395  /* Determine number of characters. */
396  n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t);
397 
398  displaypad = (int) (lelen-n);
399  }
400 #endif
401  }
402  if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
403  *le++ = ']';
404  *le = '\0';
405  }
406 
407  if (help)
408  fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left);
409  else {
410  fprintf(fp," %s\n", left);
411  goto out;
412  }
413 
414  left = _free(left);
415  if (defs) {
416  help = defs;
417  }
418 
419  helpLength = strlen(help);
420  while (helpLength > lineLength) {
421  const char * ch;
422  char format[16];
423 
424  ch = help + lineLength - 1;
425  while (ch > help && !_isspaceptr(ch))
426  ch = POPT_prev_char (ch);
427  if (ch == help) break; /* give up */
428  while (ch > (help + 1) && _isspaceptr(ch))
429  ch = POPT_prev_char (ch);
430  ch = POPT_next_char(ch);
431 
432  sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), (int) indentLength);
433  /*@-formatconst@*/
434  fprintf(fp, format, help, " ");
435  /*@=formatconst@*/
436  help = ch;
437  while (_isspaceptr(help) && *help)
438  help = POPT_next_char(help);
439  helpLength = strlen(help);
440  }
441 
442  if (helpLength) fprintf(fp, "%s\n", help);
443  help = NULL;
444 
445 out:
446  /*@-dependenttrans@*/
447  defs = _free(defs);
448  /*@=dependenttrans@*/
449  left = _free(left);
450 }
451 
458 static size_t maxArgWidth(const struct poptOption * opt,
459  /*@null@*/ const char * translation_domain)
460  /*@*/
461 {
462  size_t max = 0;
463  size_t len = 0;
464  const char * s;
465 
466  if (opt != NULL)
467  while (opt->longName || opt->shortName || opt->arg) {
468  if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
469  if (opt->arg) /* XXX program error */
470  len = maxArgWidth(opt->arg, translation_domain);
471  if (len > max) max = len;
472  } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
473  len = sizeof(" ")-1;
474  if (opt->shortName != '\0') len += sizeof("-X")-1;
475  if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1;
476  if (opt->longName) {
477  len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH)
478  ? sizeof("-")-1 : sizeof("--")-1);
479  len += strlen(opt->longName);
480  }
481 
482  s = getArgDescrip(opt, translation_domain);
483 
484 #ifdef POPT_WCHAR_HACK
485  /* XXX Calculate no. of display characters. */
486  if (s) {
487  const char * scopy = s;
488  mbstate_t t;
489  size_t n;
490 
491  memset ((void *)&t, 0, sizeof (t)); /* In initial state. */
492  /* Determine number of characters. */
493  n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t);
494  len += sizeof("=")-1 + n;
495  }
496 #else
497  if (s)
498  len += sizeof("=")-1 + strlen(s);
499 #endif
500 
501  if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1;
502  if (len > max) max = len;
503  }
504 
505  opt++;
506  }
507 
508  return max;
509 }
510 
519 static void itemHelp(FILE * fp,
520  /*@null@*/ poptItem items, int nitems,
521  columns_t columns,
522  /*@null@*/ const char * translation_domain)
523  /*@globals fileSystem @*/
524  /*@modifies fp, fileSystem @*/
525 {
526  poptItem item;
527  int i;
528 
529  if (items != NULL)
530  for (i = 0, item = items; i < nitems; i++, item++) {
531  const struct poptOption * opt;
532  opt = &item->option;
533  if ((opt->longName || opt->shortName) &&
535  singleOptionHelp(fp, columns, opt, translation_domain);
536  }
537 }
538 
547 static void singleTableHelp(poptContext con, FILE * fp,
548  /*@null@*/ const struct poptOption * table,
549  columns_t columns,
550  /*@null@*/ const char * translation_domain)
551  /*@globals fileSystem @*/
552  /*@modifies fp, columns->cur, fileSystem @*/
553 {
554  const struct poptOption * opt;
555  const char *sub_transdom;
556 
557  if (table == poptAliasOptions) {
558  itemHelp(fp, con->aliases, con->numAliases, columns, NULL);
559  itemHelp(fp, con->execs, con->numExecs, columns, NULL);
560  return;
561  }
562 
563  if (table != NULL)
564  for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
565  if ((opt->longName || opt->shortName) &&
567  singleOptionHelp(fp, columns, opt, translation_domain);
568  }
569 
570  if (table != NULL)
571  for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
573  continue;
574  sub_transdom = getTableTranslationDomain(opt->arg);
575  if (sub_transdom == NULL)
576  sub_transdom = translation_domain;
577 
578  if (opt->descrip)
579  fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
580 
581  singleTableHelp(con, fp, opt->arg, columns, sub_transdom);
582  }
583 }
584 
589 static size_t showHelpIntro(poptContext con, FILE * fp)
590  /*@globals fileSystem @*/
591  /*@modifies *fp, fileSystem @*/
592 {
593  size_t len = (size_t)6;
594  const char * fn;
595 
596  fprintf(fp, POPT_("Usage:"));
597  if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
598 /*@-type@*/ /* LCL: wazzup? */
599  fn = con->optionStack->argv[0];
600 /*@=type@*/
601  if (fn == NULL) return len;
602  if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
603  fprintf(fp, " %s", fn);
604  len += strlen(fn) + 1;
605  }
606 
607  return len;
608 }
609 
610 void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
611 {
612  columns_t columns = calloc(1, sizeof(*columns));
613 
614  (void) showHelpIntro(con, fp);
615  if (con->otherHelp)
616  fprintf(fp, " %s\n", con->otherHelp);
617  else
618  fprintf(fp, " %s\n", POPT_("[OPTION...]"));
619 
620  if (columns) {
621  columns->cur = maxArgWidth(con->options, NULL);
622  columns->max = maxColumnWidth(fp);
623  singleTableHelp(con, fp, con->options, columns, NULL);
624  free(columns);
625  }
626 }
627 
635 static size_t singleOptionUsage(FILE * fp, columns_t columns,
636  const struct poptOption * opt,
637  /*@null@*/ const char *translation_domain)
638  /*@globals fileSystem @*/
639  /*@modifies fp, columns->cur, fileSystem @*/
640 {
641  size_t len = (size_t)4;
642  char shortStr[2] = { '\0', '\0' };
643  const char * item = shortStr;
644  const char * argDescrip = getArgDescrip(opt, translation_domain);
645  int bingo = 0;
646 
647  if (opt->shortName != '\0' && opt->longName != NULL) {
648  len += 2;
649  if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
650  len += strlen(opt->longName);
651  bingo++;
652  } else if (opt->shortName != '\0') {
653  len++;
654  shortStr[0] = opt->shortName;
655  shortStr[1] = '\0';
656  bingo++;
657  } else if (opt->longName) {
658  len += strlen(opt->longName);
659  if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
660  item = opt->longName;
661  bingo++;
662  }
663 
664  if (!bingo) return columns->cur;
665 
666 #ifdef POPT_WCHAR_HACK
667  /* XXX Calculate no. of display characters. */
668  if (argDescrip) {
669  const char * scopy = argDescrip;
670  mbstate_t t;
671  size_t n;
672 
673  memset ((void *)&t, 0, sizeof (t)); /* In initial state. */
674  /* Determine number of characters. */
675  n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t);
676  len += sizeof("=")-1 + n;
677  }
678 #else
679  if (argDescrip)
680  len += sizeof("=")-1 + strlen(argDescrip);
681 #endif
682 
683  if ((columns->cur + len) > columns->max) {
684  fprintf(fp, "\n ");
685  columns->cur = (size_t)7;
686  }
687 
688  if (opt->longName && opt->shortName) {
689  fprintf(fp, " [-%c|-%s%s%s%s]",
690  opt->shortName, ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "" : "-"),
691  opt->longName,
692  (argDescrip ? " " : ""),
693  (argDescrip ? argDescrip : ""));
694  } else {
695  fprintf(fp, " [-%s%s%s%s]",
696  ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"),
697  item,
698  (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""),
699  (argDescrip ? argDescrip : ""));
700  }
701 
702  return columns->cur + len + 1;
703 }
704 
713 static size_t itemUsage(FILE * fp, columns_t columns,
714  /*@null@*/ poptItem item, int nitems,
715  /*@null@*/ const char * translation_domain)
716  /*@globals fileSystem @*/
717  /*@modifies fp, columns->cur, fileSystem @*/
718 {
719  int i;
720 
721  if (item != NULL)
722  for (i = 0; i < nitems; i++, item++) {
723  const struct poptOption * opt;
724  opt = &item->option;
725  if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
726  translation_domain = (const char *)opt->arg;
727  } else if ((opt->longName || opt->shortName) &&
728  !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
729  columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
730  }
731  }
732 
733  return columns->cur;
734 }
735 
739 typedef struct poptDone_s {
740  int nopts;
741  int maxopts;
742 /*@null@*/
743  const void ** opts;
744 } * poptDone;
745 
756 static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns,
757  /*@null@*/ const struct poptOption * opt,
758  /*@null@*/ const char * translation_domain,
759  /*@null@*/ poptDone done)
760  /*@globals fileSystem @*/
761  /*@modifies fp, columns->cur, done, fileSystem @*/
762 {
763  if (opt != NULL)
764  for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
765  if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
766  translation_domain = (const char *)opt->arg;
767  } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
768  if (done) {
769  int i = done->nopts;
770  if (done->opts != NULL)
771  for (i = 0; i < done->nopts; i++) {
772  const void * that = done->opts[i];
773  if (that == NULL || that != opt->arg)
774  /*@innercontinue@*/ continue;
775  /*@innerbreak@*/ break;
776  }
777  /* Skip if this table has already been processed. */
778  if (opt->arg == NULL || i < done->nopts)
779  continue;
780  if (done->opts != NULL && done->nopts < done->maxopts)
781  done->opts[done->nopts++] = (const void *) opt->arg;
782  }
783  columns->cur = singleTableUsage(con, fp, columns, opt->arg,
784  translation_domain, done);
785  } else if ((opt->longName || opt->shortName) &&
786  !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
787  columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
788  }
789  }
790 
791  return columns->cur;
792 }
793 
802 static size_t showShortOptions(const struct poptOption * opt, FILE * fp,
803  /*@null@*/ char * str)
804  /*@globals fileSystem @*/
805  /*@modifies str, *fp, fileSystem @*/
806  /*@requires maxRead(str) >= 0 @*/
807 {
808  /* bufsize larger then the ascii set, lazy allocation on top level call. */
809  size_t nb = (size_t)300;
810  char * s = (str != NULL ? str : calloc(1, nb));
811  size_t len = (size_t)0;
812 
813  if (s == NULL)
814  return 0;
815 
816  if (opt != NULL)
817  for (; (opt->longName || opt->shortName || opt->arg); opt++) {
818  if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
819  s[strlen(s)] = opt->shortName;
820  else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
821  if (opt->arg) /* XXX program error */
822  len = showShortOptions(opt->arg, fp, s);
823  }
824 
825  /* On return to top level, print the short options, return print length. */
826  if (s != str && *s != '\0') {
827  fprintf(fp, " [-%s]", s);
828  len = strlen(s) + sizeof(" [-]")-1;
829  }
830 /*@-temptrans@*/ /* LCL: local s, not str arg, is being freed. */
831  if (s != str)
832  free(s);
833 /*@=temptrans@*/
834  return len;
835 }
836 
837 void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
838 {
839  columns_t columns = calloc(1, sizeof(*columns));
840  struct poptDone_s done_buf;
841  poptDone done = &done_buf;
842 
843  memset(done, 0, sizeof(*done));
844  done->nopts = 0;
845  done->maxopts = 64;
846  if (columns) {
847  columns->cur = done->maxopts * sizeof(*done->opts);
848  columns->max = maxColumnWidth(fp);
849  done->opts = calloc(1, columns->cur);
850  /*@-keeptrans@*/
851  if (done->opts != NULL)
852  done->opts[done->nopts++] = (const void *) con->options;
853  /*@=keeptrans@*/
854 
855  columns->cur = showHelpIntro(con, fp);
856  columns->cur += showShortOptions(con->options, fp, NULL);
857  columns->cur = singleTableUsage(con, fp, columns, con->options, NULL, done);
858  columns->cur = itemUsage(fp, columns, con->aliases, con->numAliases, NULL);
859  columns->cur = itemUsage(fp, columns, con->execs, con->numExecs, NULL);
860 
861  if (con->otherHelp) {
862  columns->cur += strlen(con->otherHelp) + 1;
863  if (columns->cur > columns->max) fprintf(fp, "\n ");
864  fprintf(fp, " %s", con->otherHelp);
865  }
866 
867  fprintf(fp, "\n");
868  if (done->opts != NULL)
869  free(done->opts);
870  free(columns);
871  }
872 }
873 
874 void poptSetOtherOptionHelp(poptContext con, const char * text)
875 {
876  con->otherHelp = _free(con->otherHelp);
877  con->otherHelp = xstrdup(text);
878 }

Generated for popt by  doxygen 1.8.1.2