00001
00002
00007
00008
00009
00010
00011 #include "system.h"
00012
00013 #define POPT_USE_TIOCGWINSZ
00014 #ifdef POPT_USE_TIOCGWINSZ
00015 #include <sys/ioctl.h>
00016 #endif
00017
00018 #define POPT_WCHAR_HACK
00019 #ifdef POPT_WCHAR_HACK
00020 #include <wchar.h>
00021
00022 #endif
00023 #include "poptint.h"
00024
00025
00026
00035
00036 static void displayArgs(poptContext con,
00037 enum poptCallbackReason foo,
00038 struct poptOption * key,
00039 const char * arg, void * data)
00040
00041
00042 {
00043 if (key->shortName == '?')
00044 poptPrintHelp(con, stdout, 0);
00045 else
00046 poptPrintUsage(con, stdout, 0);
00047 con = poptFreeContext(con);
00048 exit(0);
00049 }
00050
00051 #ifdef NOTYET
00052
00053 static int show_option_defaults = 0;
00054 #endif
00055
00059
00060 struct poptOption poptAliasOptions[] = {
00061 POPT_TABLEEND
00062 };
00063
00067
00068
00069 struct poptOption poptHelpOptions[] = {
00070 { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
00071 { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
00072 { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
00073 POPT_TABLEEND
00074 } ;
00075
00076
00077 static struct poptOption poptHelpOptions2[] = {
00078
00079 { NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL},
00080
00081 { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
00082 { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
00083 { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
00084 #ifdef NOTYET
00085 { "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0,
00086 N_("Display option defaults in message"), NULL },
00087 #endif
00088 POPT_TABLEEND
00089 } ;
00090
00091
00092 struct poptOption * poptHelpOptionsI18N = poptHelpOptions2;
00093
00094
00095 #define _POPTHELP_MAXLINE ((size_t)79)
00096
00097 typedef struct columns_s {
00098 size_t cur;
00099 size_t max;
00100 } * columns_t;
00101
00107 static size_t maxColumnWidth(FILE *fp)
00108
00109 {
00110 size_t maxcols = _POPTHELP_MAXLINE;
00111 #if defined(TIOCGWINSZ)
00112 struct winsize ws;
00113 int fdno = fileno(fp ? fp : stdout);
00114
00115 if (fdno >= 0 && !ioctl(fdno, TIOCGWINSZ, &ws)
00116 && ws.ws_col > maxcols && ws.ws_col < 256)
00117 maxcols = ws.ws_col - 1;
00118 #endif
00119 return maxcols;
00120 }
00121
00125 static const char *
00126 getTableTranslationDomain( const struct poptOption *table)
00127
00128 {
00129 const struct poptOption *opt;
00130
00131 if (table != NULL)
00132 for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
00133 if (opt->argInfo == POPT_ARG_INTL_DOMAIN)
00134 return opt->arg;
00135 }
00136 return NULL;
00137 }
00138
00143 static const char *
00144 getArgDescrip(const struct poptOption * opt,
00145
00146 const char * translation_domain)
00147
00148
00149 {
00150 if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
00151
00152 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_MAINCALL)
00153 return opt->argDescrip;
00154
00155 if (opt->argDescrip) {
00156
00157 if (opt == (poptHelpOptions + 1)
00158 || opt == (poptHelpOptions + 2)
00159 || !strcmp(opt->argDescrip,N_("Help options:"))
00160 || !strcmp(opt->argDescrip,N_("Options implemented via popt alias/exec:")))
00161 return POPT_(opt->argDescrip);
00162
00163
00164 return D_(translation_domain, opt->argDescrip);
00165 }
00166
00167 switch (opt->argInfo & POPT_ARG_MASK) {
00168 case POPT_ARG_NONE: return POPT_("NONE");
00169 #ifdef DYING
00170 case POPT_ARG_VAL: return POPT_("VAL");
00171 #else
00172 case POPT_ARG_VAL: return NULL;
00173 #endif
00174 case POPT_ARG_INT: return POPT_("INT");
00175 case POPT_ARG_LONG: return POPT_("LONG");
00176 case POPT_ARG_STRING: return POPT_("STRING");
00177 case POPT_ARG_FLOAT: return POPT_("FLOAT");
00178 case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
00179 case POPT_ARG_MAINCALL: return NULL;
00180 default: return POPT_("ARG");
00181 }
00182 }
00183
00191 static char *
00192 singleOptionDefaultValue(size_t lineLength,
00193 const struct poptOption * opt,
00194
00195 const char * translation_domain)
00196
00197
00198 {
00199 const char * defstr = D_(translation_domain, "default");
00200 char * le = malloc(4*lineLength + 1);
00201 char * l = le;
00202
00203 if (le == NULL) return NULL;
00204
00205 *le = '\0';
00206 *le++ = '(';
00207 strcpy(le, defstr); le += strlen(le);
00208 *le++ = ':';
00209 *le++ = ' ';
00210 if (opt->arg)
00211 switch (opt->argInfo & POPT_ARG_MASK) {
00212 case POPT_ARG_VAL:
00213 case POPT_ARG_INT:
00214 { long aLong = *((int *)opt->arg);
00215 le += sprintf(le, "%ld", aLong);
00216 } break;
00217 case POPT_ARG_LONG:
00218 { long aLong = *((long *)opt->arg);
00219 le += sprintf(le, "%ld", aLong);
00220 } break;
00221 case POPT_ARG_FLOAT:
00222 { double aDouble = *((float *)opt->arg);
00223 le += sprintf(le, "%g", aDouble);
00224 } break;
00225 case POPT_ARG_DOUBLE:
00226 { double aDouble = *((double *)opt->arg);
00227 le += sprintf(le, "%g", aDouble);
00228 } break;
00229 case POPT_ARG_MAINCALL:
00230 le += sprintf(le, "%p", opt->arg);
00231 break;
00232 case POPT_ARG_STRING:
00233 { const char * s = *(const char **)opt->arg;
00234 if (s == NULL) {
00235 strcpy(le, "null"); le += strlen(le);
00236 } else {
00237 size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")");
00238 *le++ = '"';
00239 strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le);
00240 if (slen < strlen(s)) {
00241 strcpy(le, "..."); le += strlen(le);
00242 }
00243 *le++ = '"';
00244 }
00245 } break;
00246 case POPT_ARG_NONE:
00247 default:
00248 l = _free(l);
00249 return NULL;
00250 break;
00251 }
00252 *le++ = ')';
00253 *le = '\0';
00254
00255
00256 return l;
00257 }
00258
00266 static void singleOptionHelp(FILE * fp, columns_t columns,
00267 const struct poptOption * opt,
00268 const char * translation_domain)
00269
00270
00271 {
00272 size_t maxLeftCol = columns->cur;
00273 size_t indentLength = maxLeftCol + 5;
00274 size_t lineLength = columns->max - indentLength;
00275 const char * help = D_(translation_domain, opt->descrip);
00276 const char * argDescrip = getArgDescrip(opt, translation_domain);
00277 size_t helpLength;
00278 char * defs = NULL;
00279 char * left;
00280 size_t nb = maxLeftCol + 1;
00281 int displaypad = 0;
00282
00283
00284 if (opt->longName) nb += strlen(opt->longName);
00285 if (argDescrip) nb += strlen(argDescrip);
00286
00287
00288 left = malloc(nb);
00289 if (left == NULL) return;
00290 left[0] = '\0';
00291 left[maxLeftCol] = '\0';
00292
00293 if (opt->longName && opt->shortName)
00294 sprintf(left, "-%c, %s%s", opt->shortName,
00295 ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
00296 opt->longName);
00297 else if (opt->shortName != '\0')
00298 sprintf(left, "-%c", opt->shortName);
00299 else if (opt->longName)
00300 sprintf(left, "%s%s",
00301 ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_MAINCALL ? "" :
00302 ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--")),
00303 opt->longName);
00304 if (!*left) goto out;
00305
00306 if (argDescrip) {
00307 char * le = left + strlen(left);
00308
00309 if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
00310 *le++ = '[';
00311
00312
00313
00314 if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) {
00315 defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
00316 if (defs) {
00317 char * t = malloc((help ? strlen(help) : 0) +
00318 strlen(defs) + sizeof(" "));
00319 if (t) {
00320 char * te = t;
00321 *te = '\0';
00322 if (help) {
00323 strcpy(te, help); te += strlen(te);
00324 }
00325 *te++ = ' ';
00326 strcpy(te, defs);
00327 defs = _free(defs);
00328 }
00329 defs = t;
00330 }
00331 }
00332
00333
00334 if (opt->argDescrip == NULL) {
00335 switch (opt->argInfo & POPT_ARG_MASK) {
00336 case POPT_ARG_NONE:
00337 break;
00338 case POPT_ARG_VAL:
00339 #ifdef NOTNOW
00340 { long aLong = opt->val;
00341 int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS);
00342 int negate = (opt->argInfo & POPT_ARGFLAG_NOT);
00343
00344
00345 if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L))
00346 break;
00347 *le++ = '[';
00348 switch (ops) {
00349 case POPT_ARGFLAG_OR:
00350 *le++ = '|';
00351 break;
00352 case POPT_ARGFLAG_AND:
00353 *le++ = '&';
00354 break;
00355 case POPT_ARGFLAG_XOR:
00356 *le++ = '^';
00357 break;
00358 default:
00359 break;
00360 }
00361 *le++ = (opt->longName != NULL ? '=' : ' ');
00362 if (negate) *le++ = '~';
00363
00364 le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
00365
00366 *le++ = ']';
00367 }
00368 #endif
00369 break;
00370 case POPT_ARG_INT:
00371 case POPT_ARG_LONG:
00372 case POPT_ARG_FLOAT:
00373 case POPT_ARG_DOUBLE:
00374 case POPT_ARG_STRING:
00375 *le++ = (opt->longName != NULL ? '=' : ' ');
00376 strcpy(le, argDescrip); le += strlen(le);
00377 break;
00378 default:
00379 break;
00380 }
00381 } else {
00382 size_t lelen;
00383
00384 *le++ = ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_MAINCALL)
00385 ? ' ' : '=';
00386 strcpy(le, argDescrip);
00387 lelen = strlen(le);
00388 le += lelen;
00389
00390 #ifdef POPT_WCHAR_HACK
00391 { const char * scopy = argDescrip;
00392 mbstate_t t;
00393 size_t n;
00394
00395 memset ((void *)&t, 0, sizeof (t));
00396
00397 n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t);
00398
00399 displaypad = (int) (lelen-n);
00400 }
00401 #endif
00402 }
00403 if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
00404 *le++ = ']';
00405 *le = '\0';
00406 }
00407
00408
00409 if (help)
00410 fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left);
00411 else {
00412 fprintf(fp," %s\n", left);
00413 goto out;
00414 }
00415
00416 left = _free(left);
00417
00418 if (defs) {
00419 help = defs;
00420 }
00421
00422 helpLength = strlen(help);
00423
00424 while (helpLength > lineLength) {
00425 const char * ch;
00426 char format[16];
00427
00428 ch = help + lineLength - 1;
00429 while (ch > help && !isspace(*ch)) ch--;
00430 if (ch == help) break;
00431 while (ch > (help + 1) && isspace(*ch)) ch--;
00432 ch++;
00433
00434 sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), (int) indentLength);
00435
00436 fprintf(fp, format, help, " ");
00437
00438 help = ch;
00439 while (isspace(*help) && *help) help++;
00440 helpLength = strlen(help);
00441 }
00442
00443
00444
00445 if (helpLength) fprintf(fp, "%s\n", help);
00446 help = NULL;
00447
00448 out:
00449
00450 defs = _free(defs);
00451
00452 left = _free(left);
00453 }
00454
00461 static size_t maxArgWidth(const struct poptOption * opt,
00462 const char * translation_domain)
00463
00464 {
00465 size_t max = 0;
00466 size_t len = 0;
00467 const char * s;
00468
00469 if (opt != NULL)
00470 while (opt->longName || opt->shortName || opt->arg) {
00471 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
00472 if (opt->arg)
00473 len = maxArgWidth(opt->arg, translation_domain);
00474 if (len > max) max = len;
00475 } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
00476 len = sizeof(" ")-1;
00477 if (opt->shortName != '\0') len += sizeof("-X")-1;
00478 if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1;
00479 if (opt->longName) {
00480 len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH)
00481 ? sizeof("-")-1 : sizeof("--")-1);
00482 len += strlen(opt->longName);
00483 }
00484
00485 s = getArgDescrip(opt, translation_domain);
00486
00487 #ifdef POPT_WCHAR_HACK
00488
00489 if (s) {
00490 const char * scopy = s;
00491 mbstate_t t;
00492 size_t n;
00493
00494
00495 memset ((void *)&t, 0, sizeof (t));
00496
00497
00498 n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t);
00499 len += sizeof("=")-1 + n;
00500 }
00501 #else
00502 if (s)
00503 len += sizeof("=")-1 + strlen(s);
00504 #endif
00505
00506 if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1;
00507 if (len > max) max = len;
00508 }
00509
00510 opt++;
00511 }
00512
00513 return max;
00514 }
00515
00524 static void itemHelp(FILE * fp,
00525 poptItem items, int nitems,
00526 columns_t columns,
00527 const char * translation_domain)
00528
00529
00530 {
00531 poptItem item;
00532 int i;
00533
00534 if (items != NULL)
00535 for (i = 0, item = items; i < nitems; i++, item++) {
00536 const struct poptOption * opt;
00537 opt = &item->option;
00538 if ((opt->longName || opt->shortName) &&
00539 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
00540 singleOptionHelp(fp, columns, opt, translation_domain);
00541 }
00542 }
00543
00552 static void singleTableHelp(poptContext con, FILE * fp,
00553 const struct poptOption * table,
00554 columns_t columns,
00555 const char * translation_domain)
00556
00557
00558 {
00559 const struct poptOption * opt;
00560 const char *sub_transdom;
00561
00562 if (table == poptAliasOptions) {
00563 itemHelp(fp, con->aliases, con->numAliases, columns, NULL);
00564 itemHelp(fp, con->execs, con->numExecs, columns, NULL);
00565 return;
00566 }
00567
00568 if (table != NULL)
00569 for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
00570 if ((opt->longName || opt->shortName) &&
00571 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
00572 singleOptionHelp(fp, columns, opt, translation_domain);
00573 }
00574
00575 if (table != NULL)
00576 for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
00577 if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE)
00578 continue;
00579 sub_transdom = getTableTranslationDomain(opt->arg);
00580 if (sub_transdom == NULL)
00581 sub_transdom = translation_domain;
00582
00583 if (opt->descrip)
00584 POPT_fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
00585
00586 singleTableHelp(con, fp, opt->arg, columns, sub_transdom);
00587 }
00588 }
00589
00594 static size_t showHelpIntro(poptContext con, FILE * fp)
00595
00596
00597 {
00598 size_t len = (size_t)6;
00599 const char * fn;
00600
00601 fprintf(fp, POPT_("Usage:"));
00602 if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
00603
00604
00605 fn = con->optionStack->argv[0];
00606
00607
00608 if (fn == NULL) return len;
00609 if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
00610 fprintf(fp, " %s", fn);
00611 len += strlen(fn) + 1;
00612 }
00613
00614 return len;
00615 }
00616
00617 void poptPrintHelp(poptContext con, FILE * fp, int flags)
00618 {
00619 columns_t columns = memset(alloca(sizeof(*columns)), 0, sizeof(*columns));
00620
00621 (void) showHelpIntro(con, fp);
00622 if (con->otherHelp)
00623 fprintf(fp, " %s\n", con->otherHelp);
00624 else
00625 fprintf(fp, " %s\n", POPT_("[OPTION...]"));
00626
00627 columns->cur = maxArgWidth(con->options, NULL);
00628 columns->max = maxColumnWidth(fp);
00629 singleTableHelp(con, fp, con->options, columns, NULL);
00630 }
00631
00639 static size_t singleOptionUsage(FILE * fp, columns_t columns,
00640 const struct poptOption * opt,
00641 const char *translation_domain)
00642
00643
00644 {
00645 size_t len = (size_t)4;
00646 char shortStr[2] = { '\0', '\0' };
00647 const char * item = shortStr;
00648 const char * argDescrip = getArgDescrip(opt, translation_domain);
00649 int bingo = 0;
00650
00651 if (opt->shortName != '\0' && opt->longName != NULL) {
00652 len += 2;
00653 if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
00654 len += strlen(opt->longName);
00655 bingo++;
00656 } else if (opt->shortName != '\0') {
00657 len++;
00658 shortStr[0] = opt->shortName;
00659 shortStr[1] = '\0';
00660 bingo++;
00661 } else if (opt->longName) {
00662 len += strlen(opt->longName);
00663 if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
00664 item = opt->longName;
00665 bingo++;
00666 }
00667
00668 if (!bingo) return columns->cur;
00669
00670 #ifdef POPT_WCHAR_HACK
00671
00672 if (argDescrip) {
00673 const char * scopy = argDescrip;
00674 mbstate_t t;
00675 size_t n;
00676
00677
00678 memset ((void *)&t, 0, sizeof (t));
00679
00680
00681 n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t);
00682 len += sizeof("=")-1 + n;
00683 }
00684 #else
00685 if (argDescrip)
00686 len += sizeof("=")-1 + strlen(argDescrip);
00687 #endif
00688
00689 if ((columns->cur + len) > columns->max) {
00690 fprintf(fp, "\n ");
00691 columns->cur = (size_t)7;
00692 }
00693
00694 if (opt->longName && opt->shortName) {
00695 fprintf(fp, " [-%c|-%s%s%s%s]",
00696 opt->shortName, ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "" : "-"),
00697 opt->longName,
00698 (argDescrip ? " " : ""),
00699 (argDescrip ? argDescrip : ""));
00700 } else {
00701 fprintf(fp, " [-%s%s%s%s]",
00702 ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"),
00703 item,
00704 (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""),
00705 (argDescrip ? argDescrip : ""));
00706 }
00707
00708 return columns->cur + len + 1;
00709 }
00710
00719 static size_t itemUsage(FILE * fp, columns_t columns,
00720 poptItem item, int nitems,
00721 const char * translation_domain)
00722
00723
00724 {
00725 int i;
00726
00727
00728 if (item != NULL)
00729 for (i = 0; i < nitems; i++, item++) {
00730 const struct poptOption * opt;
00731 opt = &item->option;
00732 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
00733 translation_domain = (const char *)opt->arg;
00734 } else if ((opt->longName || opt->shortName) &&
00735 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
00736 columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
00737 }
00738 }
00739
00740
00741 return columns->cur;
00742 }
00743
00747 typedef struct poptDone_s {
00748 int nopts;
00749 int maxopts;
00750 const void ** opts;
00751 } * poptDone;
00752
00763 static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns,
00764 const struct poptOption * opt,
00765 const char * translation_domain,
00766 poptDone done)
00767
00768
00769 {
00770
00771 if (opt != NULL)
00772 for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
00773 if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
00774 translation_domain = (const char *)opt->arg;
00775 } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
00776 if (done) {
00777 int i = 0;
00778 for (i = 0; i < done->nopts; i++) {
00779
00780 const void * that = done->opts[i];
00781
00782 if (that == NULL || that != opt->arg)
00783 continue;
00784 break;
00785 }
00786
00787 if (opt->arg == NULL || i < done->nopts)
00788 continue;
00789
00790 if (done->nopts < done->maxopts)
00791 done->opts[done->nopts++] = (const void *) opt->arg;
00792
00793 }
00794 columns->cur = singleTableUsage(con, fp, columns, opt->arg,
00795 translation_domain, done);
00796 } else if ((opt->longName || opt->shortName) &&
00797 !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
00798 columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
00799 }
00800 }
00801
00802
00803 return columns->cur;
00804 }
00805
00814 static size_t showShortOptions(const struct poptOption * opt, FILE * fp,
00815 char * str)
00816
00817
00818
00819 {
00820
00821 size_t nb = (size_t)300;
00822 char * s = (str != NULL ? str : calloc(1, nb));
00823 size_t len = (size_t)0;
00824
00825 if (s == NULL)
00826 return 0;
00827
00828
00829 if (opt != NULL)
00830 for (; (opt->longName || opt->shortName || opt->arg); opt++) {
00831 if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
00832 s[strlen(s)] = opt->shortName;
00833 else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
00834 if (opt->arg)
00835 len = showShortOptions(opt->arg, fp, s);
00836 }
00837
00838
00839
00840 if (s != str && *s != '\0') {
00841 fprintf(fp, " [-%s]", s);
00842 len = strlen(s) + sizeof(" [-]")-1;
00843 }
00844 if (s != str)
00845 free(s);
00846 return len;
00847 }
00848
00849 void poptPrintUsage(poptContext con, FILE * fp, int flags)
00850 {
00851 columns_t columns = memset(alloca(sizeof(*columns)), 0, sizeof(*columns));
00852 struct poptDone_s done_buf;
00853 poptDone done = &done_buf;
00854
00855 memset(done, 0, sizeof(*done));
00856 done->nopts = 0;
00857 done->maxopts = 64;
00858 columns->cur = done->maxopts * sizeof(*done->opts);
00859 columns->max = maxColumnWidth(fp);
00860
00861 done->opts = calloc(1, columns->cur);
00862
00863 done->opts[done->nopts++] = (const void *) con->options;
00864
00865
00866
00867 columns->cur = showHelpIntro(con, fp);
00868 columns->cur += showShortOptions(con->options, fp, NULL);
00869 columns->cur = singleTableUsage(con, fp, columns, con->options, NULL, done);
00870 columns->cur = itemUsage(fp, columns, con->aliases, con->numAliases, NULL);
00871 columns->cur = itemUsage(fp, columns, con->execs, con->numExecs, NULL);
00872
00873 if (con->otherHelp) {
00874 columns->cur += strlen(con->otherHelp) + 1;
00875 if (columns->cur > columns->max) fprintf(fp, "\n ");
00876 fprintf(fp, " %s", con->otherHelp);
00877 }
00878
00879 fprintf(fp, "\n");
00880 free(done->opts);
00881 }
00882
00883 void poptSetOtherOptionHelp(poptContext con, const char * text)
00884 {
00885 con->otherHelp = _free(con->otherHelp);
00886 con->otherHelp = xstrdup(text);
00887 }