Main Page Modules Data Structures File List Data Fields Globals Related Pages

# popt/popthelp.c

Go to the documentation of this file.

    00001 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
    00002
    00003 /*@-type@*/
    00008 /* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
    00009    file accompanying popt source distributions, available from
    00010    ftp://ftp.rpm.org/pub/rpm/dist. */
    00011
    00012 #include "system.h"
    00013 #include "poptint.h"
    00014
    00023 static void displayArgs(poptContext con,
    00024                 /*@unused@*/ enum poptCallbackReason foo,
    00025                 struct poptOption * key,
    00026                 /*@unused@*/ const char * arg, /*@unused@*/ void * data)
    00027         /*@globals fileSystem@*/
    00028         /*@modifies fileSystem@*/
    00029 {
    00030     if (key->shortName == '?')
    00031         poptPrintHelp(con, stdout, 0);
    00032     else
    00033         poptPrintUsage(con, stdout, 0);
    00034     exit(0);
    00035 }
    00036
    00037 #ifdef  NOTYET
    00038 /*@unchecked@*/
    00039 static int show_option_defaults = 0;
    00040 #endif
    00041
    00045 /*@observer@*/ /*@unchecked@*/
    00046 struct poptOption poptAliasOptions[] = {
    00047     POPT_TABLEEND
    00048 };
    00049
    00053 /*@-castfcnptr@*/
    00054 /*@observer@*/ /*@unchecked@*/
    00055 struct poptOption poptHelpOptions[] = {
    00056   { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
    00057   { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
    00058   { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
    00059 #ifdef  NOTYET
    00060   { "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0,
    00061         N_("Display option defaults in message"), NULL },
    00062 #endif
    00063     POPT_TABLEEND
    00064 } ;
    00065 /*@=castfcnptr@*/
    00066
    00070 /*@observer@*/ /*@null@*/ static const char *const
    00071 getTableTranslationDomain(/*@null@*/ const struct poptOption *table)
    00072         /*@*/
    00073 {
    00074     const struct poptOption *opt;
    00075
    00076     if (table != NULL)
    00077     for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
    00078         if (opt->argInfo == POPT_ARG_INTL_DOMAIN)
    00079             return opt->arg;
    00080     }
    00081     return NULL;
    00082 }
    00083
    00088 /*@observer@*/ /*@null@*/ static const char *const
    00089 getArgDescrip(const struct poptOption * opt,
    00090                 /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */
    00091                 /*@null@*/ const char * translation_domain)
    00092                 /*@=paramuse@*/
    00093         /*@*/
    00094 {
    00095     if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
    00096
    00097     if (opt == (poptHelpOptions + 1) || opt == (poptHelpOptions + 2))
    00098         if (opt->argDescrip) return POPT_(opt->argDescrip);
    00099
    00100     if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
    00101
    00102     switch (opt->argInfo & POPT_ARG_MASK) {
    00103     case POPT_ARG_NONE:         return POPT_("NONE");
    00104 #ifdef  DYING
    00105     case POPT_ARG_VAL:          return POPT_("VAL");
    00106 #else
    00107     case POPT_ARG_VAL:          return NULL;
    00108 #endif
    00109     case POPT_ARG_INT:          return POPT_("INT");
    00110     case POPT_ARG_LONG:         return POPT_("LONG");
    00111     case POPT_ARG_STRING:       return POPT_("STRING");
    00112     case POPT_ARG_FLOAT:        return POPT_("FLOAT");
    00113     case POPT_ARG_DOUBLE:       return POPT_("DOUBLE");
    00114     default:                    return POPT_("ARG");
    00115     }
    00116 }
    00117
    00125 static /*@only@*/ /*@null@*/ char *
    00126 singleOptionDefaultValue(int lineLength,
    00127                 const struct poptOption * opt,
    00128                 /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */
    00129                 /*@null@*/ const char * translation_domain)
    00130                 /*@=paramuse@*/
    00131         /*@*/
    00132 {
    00133     const char * defstr = D_(translation_domain, "default");
    00134     char * le = malloc(4*lineLength + 1);
    00135     char * l = le;
    00136
    00137     if (le == NULL) return NULL;        /* XXX can't happen */
    00138 /*@-boundswrite@*/
    00139     *le = '\0';
    00140     *le++ = '(';
    00141     strcpy(le, defstr); le += strlen(le);
    00142     *le++ = ':';
    00143     *le++ = ' ';
    00144     if (opt->arg)       /* XXX programmer error */
    00145     switch (opt->argInfo & POPT_ARG_MASK) {
    00146     case POPT_ARG_VAL:
    00147     case POPT_ARG_INT:
    00148     {   long aLong = *((int *)opt->arg);
    00149         le += sprintf(le, "%ld", aLong);
    00150     }   break;
    00151     case POPT_ARG_LONG:
    00152     {   long aLong = *((long *)opt->arg);
    00153         le += sprintf(le, "%ld", aLong);
    00154     }   break;
    00155     case POPT_ARG_FLOAT:
    00156     {   double aDouble = *((float *)opt->arg);
    00157         le += sprintf(le, "%g", aDouble);
    00158     }   break;
    00159     case POPT_ARG_DOUBLE:
    00160     {   double aDouble = *((double *)opt->arg);
    00161         le += sprintf(le, "%g", aDouble);
    00162     }   break;
    00163     case POPT_ARG_STRING:
    00164     {   const char * s = *(const char **)opt->arg;
    00165         if (s == NULL) {
    00166             strcpy(le, "null"); le += strlen(le);
    00167         } else {
    00168             size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")");
    00169             *le++ = '"';
    00170             strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le);
    00171             if (slen < strlen(s)) {
    00172                 strcpy(le, "...");      le += strlen(le);
    00173             }
    00174             *le++ = '"';
    00175         }
    00176     }   break;
    00177     case POPT_ARG_NONE:
    00178     default:
    00179         l = _free(l);
    00180         return NULL;
    00181         /*@notreached@*/ break;
    00182     }
    00183     *le++ = ')';
    00184     *le = '\0';
    00185 /*@=boundswrite@*/
    00186
    00187     return l;
    00188 }
    00189
    00197 static void singleOptionHelp(FILE * fp, int maxLeftCol,
    00198                 const struct poptOption * opt,
    00199                 /*@null@*/ const char * translation_domain)
    00200         /*@globals fileSystem @*/
    00201         /*@modifies *fp, fileSystem @*/
    00202 {
    00203     int indentLength = maxLeftCol + 5;
    00204     int lineLength = 79 - indentLength;
    00205     const char * help = D_(translation_domain, opt->descrip);
    00206     const char * argDescrip = getArgDescrip(opt, translation_domain);
    00207     int helpLength;
    00208     char * defs = NULL;
    00209     char * left;
    00210     int nb = maxLeftCol + 1;
    00211
    00212     /* Make sure there's more than enough room in target buffer. */
    00213     if (opt->longName)  nb += strlen(opt->longName);
    00214     if (argDescrip)     nb += strlen(argDescrip);
    00215
    00216 /*@-boundswrite@*/
    00217     left = malloc(nb);
    00218     if (left == NULL) return;   /* XXX can't happen */
    00219     left[0] = '\0';
    00220     left[maxLeftCol] = '\0';
    00221
    00222     if (opt->longName && opt->shortName)
    00223         sprintf(left, "-%c, %s%s", opt->shortName,
    00224                 ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
    00225                 opt->longName);
    00226     else if (opt->shortName != '\0')
    00227         sprintf(left, "-%c", opt->shortName);
    00228     else if (opt->longName)
    00229         sprintf(left, "%s%s",
    00230                 ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
    00231                 opt->longName);
    00232     if (!*left) goto out;
    00233
    00234     if (argDescrip) {
    00235         char * le = left + strlen(left);
    00236
    00237         if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
    00238             *le++ = '[';
    00239
    00240         /* Choose type of output */
    00241         /*@-branchstate@*/
    00242         if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) {
    00243             defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
    00244             if (defs) {
    00245                 char * t = malloc((help ? strlen(help) : 0) +
    00246                                 strlen(defs) + sizeof(" "));
    00247                 if (t) {
    00248                     char * te = t;
    00249                     *te = '\0';
    00250                     if (help) {
    00251                         strcpy(te, help);       te += strlen(te);
    00252                     }
    00253                     *te++ = ' ';
    00254                     strcpy(te, defs);
    00255                     defs = _free(defs);
    00256                 }
    00257                 defs = t;
    00258             }
    00259         }
    00260         /*@=branchstate@*/
    00261
    00262         if (opt->argDescrip == NULL) {
    00263             switch (opt->argInfo & POPT_ARG_MASK) {
    00264             case POPT_ARG_NONE:
    00265                 break;
    00266             case POPT_ARG_VAL:
    00267 #ifdef  NOTNOW  /* XXX pug ugly nerdy output */
    00268             {   long aLong = opt->val;
    00269                 int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS);
    00270                 int negate = (opt->argInfo & POPT_ARGFLAG_NOT);
    00271
    00272                 /* Don't bother displaying typical values */
    00273                 if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L))
    00274                     break;
    00275                 *le++ = '[';
    00276                 switch (ops) {
    00277                 case POPT_ARGFLAG_OR:
    00278                     *le++ = '|';
    00279                     /*@innerbreak@*/ break;
    00280                 case POPT_ARGFLAG_AND:
    00281                     *le++ = '&';
    00282                     /*@innerbreak@*/ break;
    00283                 case POPT_ARGFLAG_XOR:
    00284                     *le++ = '^';
    00285                     /*@innerbreak@*/ break;
    00286                 default:
    00287                     /*@innerbreak@*/ break;
    00288                 }
    00289                 *le++ = '=';
    00290                 if (negate) *le++ = '~';
    00291                 /*@-formatconst@*/
    00292                 le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
    00293                 /*@=formatconst@*/
    00294                 *le++ = ']';
    00295             }
    00296 #endif
    00297                 break;
    00298             case POPT_ARG_INT:
    00299             case POPT_ARG_LONG:
    00300             case POPT_ARG_FLOAT:
    00301             case POPT_ARG_DOUBLE:
    00302             case POPT_ARG_STRING:
    00303                 *le++ = '=';
    00304                 strcpy(le, argDescrip);         le += strlen(le);
    00305                 break;
    00306             default:
    00307                 break;
    00308             }
    00309         } else {
    00310             *le++ = '=';
    00311             strcpy(le, argDescrip);             le += strlen(le);
    00312         }
    00313         if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
    00314             *le++ = ']';
    00315         *le = '\0';
    00316     }
    00317 /*@=boundswrite@*/
    00318
    00319     if (help)
    00320         fprintf(fp,"  %-*s   ", maxLeftCol, left);
    00321     else {
    00322         fprintf(fp,"  %s\n", left);
    00323         goto out;
    00324     }
    00325
    00326     left = _free(left);
    00327     if (defs) {
    00328         help = defs; defs = NULL;
    00329     }
    00330
    00331     helpLength = strlen(help);
    00332 /*@-boundsread@*/
    00333     while (helpLength > lineLength) {
    00334         const char * ch;
    00335         char format[10];
    00336
    00337         ch = help + lineLength - 1;
    00338         while (ch > help && !isspace(*ch)) ch--;
    00339         if (ch == help) break;          /* give up */
    00340         while (ch > (help + 1) && isspace(*ch)) ch--;
    00341         ch++;
    00342
    00343         sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
    00344         /*@-formatconst@*/
    00345         fprintf(fp, format, help, " ");
    00346         /*@=formatconst@*/
    00347         help = ch;
    00348         while (isspace(*help) && *help) help++;
    00349         helpLength = strlen(help);
    00350     }
    00351 /*@=boundsread@*/
    00352
    00353     if (helpLength) fprintf(fp, "%s\n", help);
    00354
    00355 out:
    00356     /*@-dependenttrans@*/
    00357     defs = _free(defs);
    00358     /*@=dependenttrans@*/
    00359     left = _free(left);
    00360 }
    00361
    00366 static int maxArgWidth(const struct poptOption * opt,
    00367                        /*@null@*/ const char * translation_domain)
    00368         /*@*/
    00369 {
    00370     int max = 0;
    00371     int len = 0;
    00372     const char * s;
    00373
    00374     if (opt != NULL)
    00375     while (opt->longName || opt->shortName || opt->arg) {
    00376         if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
    00377             if (opt->arg)       /* XXX program error */
    00378             len = maxArgWidth(opt->arg, translation_domain);
    00379             if (len > max) max = len;
    00380         } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
    00381             len = sizeof("  ")-1;
    00382             if (opt->shortName != '\0') len += sizeof("-X")-1;
    00383             if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1;
    00384             if (opt->longName) {
    00385                 len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH)
    00386                         ? sizeof("-")-1 : sizeof("--")-1);
    00387                 len += strlen(opt->longName);
    00388             }
    00389
    00390             s = getArgDescrip(opt, translation_domain);
    00391             if (s)
    00392                 len += sizeof("=")-1 + strlen(s);
    00393             if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1;
    00394             if (len > max) max = len;
    00395         }
    00396
    00397         opt++;
    00398     }
    00399
    00400     return max;
    00401 }
    00402
    00411 static void itemHelp(FILE * fp,
    00412                 /*@null@*/ poptItem items, int nitems, int left,
    00413                 /*@null@*/ const char * translation_domain)
    00414         /*@globals fileSystem @*/
    00415         /*@modifies *fp, fileSystem @*/
    00416 {
    00417     poptItem item;
    00418     int i;
    00419
    00420     if (items != NULL)
    00421     for (i = 0, item = items; i < nitems; i++, item++) {
    00422         const struct poptOption * opt;
    00423         opt = &item->option;
    00424         if ((opt->longName || opt->shortName) &&
    00425             !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
    00426             singleOptionHelp(fp, left, opt, translation_domain);
    00427     }
    00428 }
    00429
    00438 static void singleTableHelp(poptContext con, FILE * fp,
    00439                 /*@null@*/ const struct poptOption * table, int left,
    00440                 /*@null@*/ const char * translation_domain)
    00441         /*@globals fileSystem @*/
    00442         /*@modifies *fp, fileSystem @*/
    00443 {
    00444     const struct poptOption * opt;
    00445     const char *sub_transdom;
    00446
    00447     if (table == poptAliasOptions) {
    00448         itemHelp(fp, con->aliases, con->numAliases, left, NULL);
    00449         itemHelp(fp, con->execs, con->numExecs, left, NULL);
    00450         return;
    00451     }
    00452
    00453     if (table != NULL)
    00454     for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
    00455         if ((opt->longName || opt->shortName) &&
    00456             !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
    00457             singleOptionHelp(fp, left, opt, translation_domain);
    00458     }
    00459
    00460     if (table != NULL)
    00461     for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
    00462         if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE)
    00463             continue;
    00464         sub_transdom = getTableTranslationDomain(opt->arg);
    00465         if (sub_transdom == NULL)
    00466             sub_transdom = translation_domain;
    00467
    00468         if (opt->descrip)
    00469             fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
    00470
    00471         singleTableHelp(con, fp, opt->arg, left, sub_transdom);
    00472     }
    00473 }
    00474
    00479 static int showHelpIntro(poptContext con, FILE * fp)
    00480         /*@globals fileSystem @*/
    00481         /*@modifies *fp, fileSystem @*/
    00482 {
    00483     int len = 6;
    00484     const char * fn;
    00485
    00486     fprintf(fp, POPT_("Usage:"));
    00487     if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
    00488 /*@-boundsread@*/
    00489         /*@-nullderef@*/        /* LCL: wazzup? */
    00490         fn = con->optionStack->argv[0];
    00491         /*@=nullderef@*/
    00492 /*@=boundsread@*/
    00493         if (fn == NULL) return len;
    00494         if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
    00495         fprintf(fp, " %s", fn);
    00496         len += strlen(fn) + 1;
    00497     }
    00498
    00499     return len;
    00500 }
    00501
    00502 void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
    00503 {
    00504     int leftColWidth;
    00505
    00506     (void) showHelpIntro(con, fp);
    00507     if (con->otherHelp)
    00508         fprintf(fp, " %s\n", con->otherHelp);
    00509     else
    00510         fprintf(fp, " %s\n", POPT_("[OPTION...]"));
    00511
    00512     leftColWidth = maxArgWidth(con->options, NULL);
    00513     singleTableHelp(con, fp, con->options, leftColWidth, NULL);
    00514 }
    00515
    00522 static int singleOptionUsage(FILE * fp, int cursor,
    00523                 const struct poptOption * opt,
    00524                 /*@null@*/ const char *translation_domain)
    00525         /*@globals fileSystem @*/
    00526         /*@modifies *fp, fileSystem @*/
    00527 {
    00528     int len = 4;
    00529     char shortStr[2] = { '\0', '\0' };
    00530     const char * item = shortStr;
    00531     const char * argDescrip = getArgDescrip(opt, translation_domain);
    00532
    00533     if (opt->shortName != '\0' && opt->longName != NULL) {
    00534         len += 2;
    00535         if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
    00536         len += strlen(opt->longName);
    00537     } else if (opt->shortName != '\0') {
    00538         len++;
    00539         shortStr[0] = opt->shortName;
    00540         shortStr[1] = '\0';
    00541     } else if (opt->longName) {
    00542         len += strlen(opt->longName);
    00543         if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
    00544         item = opt->longName;
    00545     }
    00546
    00547     if (len == 4) return cursor;
    00548
    00549     if (argDescrip)
    00550         len += strlen(argDescrip) + 1;
    00551
    00552     if ((cursor + len) > 79) {
    00553         fprintf(fp, "\n       ");
    00554         cursor = 7;
    00555     }
    00556
    00557     if (opt->longName && opt->shortName) {
    00558         fprintf(fp, " [-%c|-%s%s%s%s]",
    00559             opt->shortName, ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "" : "-"),
    00560             opt->longName,
    00561             (argDescrip ? " " : ""),
    00562             (argDescrip ? argDescrip : ""));
    00563     } else {
    00564         fprintf(fp, " [-%s%s%s%s]",
    00565             ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"),
    00566             item,
    00567             (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""),
    00568             (argDescrip ? argDescrip : ""));
    00569     }
    00570
    00571     return cursor + len + 1;
    00572 }
    00573
    00582 static int itemUsage(FILE * fp, int cursor, poptItem item, int nitems,
    00583                 /*@null@*/ const char * translation_domain)
    00584         /*@globals fileSystem @*/
    00585         /*@modifies *fp, fileSystem @*/
    00586 {
    00587     int i;
    00588
    00589     /*@-branchstate@*/          /* FIX: W2DO? */
    00590     if (item != NULL)
    00591     for (i = 0; i < nitems; i++, item++) {
    00592         const struct poptOption * opt;
    00593         opt = &item->option;
    00594         if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
    00595             translation_domain = (const char *)opt->arg;
    00596         } else if ((opt->longName || opt->shortName) &&
    00597                  !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
    00598             cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
    00599         }
    00600     }
    00601     /*@=branchstate@*/
    00602
    00603     return cursor;
    00604 }
    00605
    00609 typedef struct poptDone_s {
    00610     int nopts;
    00611     int maxopts;
    00612     const void ** opts;
    00613 } * poptDone;
    00614
    00625 static int singleTableUsage(poptContext con, FILE * fp, int cursor,
    00626                 /*@null@*/ const struct poptOption * opt,
    00627                 /*@null@*/ const char * translation_domain,
    00628                 /*@null@*/ poptDone done)
    00629         /*@globals fileSystem @*/
    00630         /*@modifies *fp, done, fileSystem @*/
    00631 {
    00632     /*@-branchstate@*/          /* FIX: W2DO? */
    00633     if (opt != NULL)
    00634     for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
    00635         if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
    00636             translation_domain = (const char *)opt->arg;
    00637         } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
    00638             if (done) {
    00639                 int i = 0;
    00640                 for (i = 0; i < done->nopts; i++) {
    00641 /*@-boundsread@*/
    00642                     const void * that = done->opts[i];
    00643 /*@=boundsread@*/
    00644                     if (that == NULL || that != opt->arg)
    00645                         /*@innercontinue@*/ continue;
    00646                     /*@innerbreak@*/ break;
    00647                 }
    00648                 /* Skip if this table has already been processed. */
    00649                 if (opt->arg == NULL || i < done->nopts)
    00650                     continue;
    00651 /*@-boundswrite@*/
    00652                 if (done->nopts < done->maxopts)
    00653                     done->opts[done->nopts++] = (const void *) opt->arg;
    00654 /*@=boundswrite@*/
    00655             }
    00656             cursor = singleTableUsage(con, fp, cursor, opt->arg,
    00657                         translation_domain, done);
    00658         } else if ((opt->longName || opt->shortName) &&
    00659                  !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
    00660             cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
    00661         }
    00662     }
    00663     /*@=branchstate@*/
    00664
    00665     return cursor;
    00666 }
    00667
    00676 static int showShortOptions(const struct poptOption * opt, FILE * fp,
    00677                 /*@null@*/ char * str)
    00678         /*@globals fileSystem @*/
    00679         /*@modifies *str, *fp, fileSystem @*/
    00680 {
    00681     char * s = alloca(300);     /* larger then the ascii set */
    00682
    00683     s[0] = '\0';
    00684     /*@-branchstate@*/          /* FIX: W2DO? */
    00685     if (str == NULL) {
    00686         memset(s, 0, sizeof(s));
    00687         str = s;
    00688     }
    00689     /*@=branchstate@*/
    00690
    00691 /*@-boundswrite@*/
    00692     if (opt != NULL)
    00693     for (; (opt->longName || opt->shortName || opt->arg); opt++) {
    00694         if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
    00695             str[strlen(str)] = opt->shortName;
    00696         else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
    00697             if (opt->arg)       /* XXX program error */
    00698                 (void) showShortOptions(opt->arg, fp, str);
    00699     }
    00700 /*@=boundswrite@*/
    00701
    00702     if (s != str || *s != '\0')
    00703         return 0;
    00704
    00705     fprintf(fp, " [-%s]", s);
    00706     return strlen(s) + 4;
    00707 }
    00708
    00709 void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
    00710 {
    00711     poptDone done = memset(alloca(sizeof(*done)), 0, sizeof(*done));
    00712     int cursor;
    00713
    00714     done->nopts = 0;
    00715     done->maxopts = 64;
    00716     cursor = done->maxopts * sizeof(*done->opts);
    00717 /*@-boundswrite@*/
    00718     done->opts = memset(alloca(cursor), 0, cursor);
    00719     done->opts[done->nopts++] = (const void *) con->options;
    00720 /*@=boundswrite@*/
    00721
    00722     cursor = showHelpIntro(con, fp);
    00723     cursor += showShortOptions(con->options, fp, NULL);
    00724     cursor = singleTableUsage(con, fp, cursor, con->options, NULL, done);
    00725     cursor = itemUsage(fp, cursor, con->aliases, con->numAliases, NULL);
    00726     cursor = itemUsage(fp, cursor, con->execs, con->numExecs, NULL);
    00727
    00728     if (con->otherHelp) {
    00729         cursor += strlen(con->otherHelp) + 1;
    00730         if (cursor > 79) fprintf(fp, "\n       ");
    00731         fprintf(fp, " %s", con->otherHelp);
    00732     }
    00733
    00734     fprintf(fp, "\n");
    00735 }
    00736
    00737 void poptSetOtherOptionHelp(poptContext con, const char * text)
    00738 {
    00739     con->otherHelp = _free(con->otherHelp);
    00740     con->otherHelp = xstrdup(text);
    00741 }
    00742 /*@=type@*/