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 UNUSED(enum poptCallbackReason foo),
00038 struct poptOption * key,
00039 UNUSED(const char * arg),
00040 UNUSED(void * data))
00041
00042
00043 {
00044 if (key->shortName == '?')
00045 poptPrintHelp(con, stdout, 0);
00046 else
00047 poptPrintUsage(con, stdout, 0);
00048
00049 #if !defined(__LCLINT__)
00050 con = poptFreeContext(con);
00051 #endif
00052 exit(0);
00053 }
00054
00055 #ifdef NOTYET
00056
00057 static int show_option_defaults = 0;
00058 #endif
00059
00063
00064 struct poptOption poptAliasOptions[] = {
00065 POPT_TABLEEND
00066 };
00067
00071
00072
00073 struct poptOption poptHelpOptions[] = {
00074 { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
00075 { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
00076 { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
00077 POPT_TABLEEND
00078 } ;
00079
00080
00081 static struct poptOption poptHelpOptions2[] = {
00082
00083 { NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL},
00084
00085 { NULL, '\0', POPT_ARG_CALLBACK, (void *)displayArgs, 0, NULL, NULL },
00086 { "help", '?', 0, NULL, (int)'?', N_("Show this help message"), NULL },
00087 { "usage", '\0', 0, NULL, (int)'u', N_("Display brief usage message"), NULL },
00088 #ifdef NOTYET
00089 { "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0,
00090 N_("Display option defaults in message"), NULL },
00091 #endif
00092 { "", '\0', 0, NULL, 0, N_("Terminate options"), NULL },
00093 POPT_TABLEEND
00094 } ;
00095
00096
00097 struct poptOption * poptHelpOptionsI18N = poptHelpOptions2;
00098
00099
00100 #define _POPTHELP_MAXLINE ((size_t)79)
00101
00102 typedef struct columns_s {
00103 size_t cur;
00104 size_t max;
00105 } * columns_t;
00106
00112 static size_t maxColumnWidth(FILE *fp)
00113
00114 {
00115 size_t maxcols = _POPTHELP_MAXLINE;
00116 #if defined(TIOCGWINSZ)
00117 struct winsize ws;
00118 int fdno = fileno(fp ? fp : stdout);
00119
00120 memset(&ws, 0, sizeof(ws));
00121 if (fdno >= 0 && !ioctl(fdno, (unsigned long)TIOCGWINSZ, &ws)) {
00122 size_t ws_col = (size_t)ws.ws_col;
00123 if (ws_col > maxcols && ws_col < (size_t)256)
00124 maxcols = ws_col - 1;
00125 }
00126 #endif
00127 return maxcols;
00128 }
00129
00135 static inline size_t stringDisplayWidth(const char *s)
00136
00137 {
00138 size_t n = strlen(s);
00139 #ifdef POPT_WCHAR_HACK
00140 mbstate_t t;
00141
00142 memset ((void *)&t, 0, sizeof (t));
00143
00144 n = mbsrtowcs (NULL, &s, n, &t);
00145 #else
00146 n = 0;
00147 for (; *s; s = POPT_next_char(s));
00148 n++;
00149 #endif
00150
00151 return n;
00152 }
00153
00157 static const char *
00158 getTableTranslationDomain( const struct poptOption *opt)
00159
00160 {
00161 if (opt != NULL)
00162 for (; opt->longName || opt->shortName || opt->arg; opt++) {
00163 if (opt->argInfo == POPT_ARG_INTL_DOMAIN)
00164 return opt->arg;
00165 }
00166 return NULL;
00167 }
00168
00173 static const char *
00174 getArgDescrip(const struct poptOption * opt,
00175
00176 const char * translation_domain)
00177
00178
00179 {
00180 if (!poptArgType(opt)) return NULL;
00181
00182 if (poptArgType(opt) == POPT_ARG_MAINCALL)
00183 return opt->argDescrip;
00184 if (poptArgType(opt) == POPT_ARG_ARGV)
00185 return opt->argDescrip;
00186
00187 if (opt->argDescrip) {
00188
00189 if (opt == (poptHelpOptions + 1)
00190 || opt == (poptHelpOptions + 2)
00191 || !strcmp(opt->argDescrip, N_("Help options:"))
00192 || !strcmp(opt->argDescrip, N_("Options implemented via popt alias/exec:")))
00193 return POPT_(opt->argDescrip);
00194
00195
00196 return D_(translation_domain, opt->argDescrip);
00197 }
00198
00199 switch (poptArgType(opt)) {
00200 case POPT_ARG_NONE: return POPT_("NONE");
00201 #ifdef DYING
00202 case POPT_ARG_VAL: return POPT_("VAL");
00203 #else
00204 case POPT_ARG_VAL: return NULL;
00205 #endif
00206 case POPT_ARG_INT: return POPT_("INT");
00207 case POPT_ARG_LONG: return POPT_("LONG");
00208 case POPT_ARG_LONGLONG: return POPT_("LONGLONG");
00209 case POPT_ARG_STRING: return POPT_("STRING");
00210 case POPT_ARG_FLOAT: return POPT_("FLOAT");
00211 case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
00212 case POPT_ARG_MAINCALL: return NULL;
00213 case POPT_ARG_ARGV: return NULL;
00214 default: return POPT_("ARG");
00215 }
00216 }
00217
00225 static char *
00226 singleOptionDefaultValue(size_t lineLength,
00227 const struct poptOption * opt,
00228
00229 const char * translation_domain)
00230
00231
00232 {
00233 const char * defstr = D_(translation_domain, "default");
00234 char * le = malloc(4*lineLength + 1);
00235 char * l = le;
00236
00237 if (le == NULL) return NULL;
00238 *le = '\0';
00239 *le++ = '(';
00240 le = stpcpy(le, defstr);
00241 *le++ = ':';
00242 *le++ = ' ';
00243 if (opt->arg) {
00244 poptArg arg = { .ptr = opt->arg };
00245 switch (poptArgType(opt)) {
00246 case POPT_ARG_VAL:
00247 case POPT_ARG_INT:
00248 le += sprintf(le, "%d", arg.intp[0]);
00249 break;
00250 case POPT_ARG_LONG:
00251 le += sprintf(le, "%ld", arg.longp[0]);
00252 break;
00253 case POPT_ARG_LONGLONG:
00254 le += sprintf(le, "%lld", arg.longlongp[0]);
00255 break;
00256 case POPT_ARG_FLOAT:
00257 { double aDouble = (double) arg.floatp[0];
00258 le += sprintf(le, "%g", aDouble);
00259 } break;
00260 case POPT_ARG_DOUBLE:
00261 le += sprintf(le, "%g", arg.doublep[0]);
00262 break;
00263 case POPT_ARG_MAINCALL:
00264 le += sprintf(le, "%p", opt->arg);
00265 break;
00266 case POPT_ARG_ARGV:
00267 le += sprintf(le, "%p", opt->arg);
00268 break;
00269 case POPT_ARG_STRING:
00270 { const char * s = arg.argv[0];
00271 if (s == NULL)
00272 le = stpcpy(le, "null");
00273 else {
00274 size_t limit = 4*lineLength - (le - l) - sizeof("\"\")");
00275 size_t slen;
00276 *le++ = '"';
00277 strncpy(le, s, limit); le[limit] = '\0'; le += (slen = strlen(le));
00278 if (slen == limit && s[limit])
00279 le[-1] = le[-2] = le[-3] = '.';
00280 *le++ = '"';
00281 }
00282 } break;
00283 case POPT_ARG_NONE:
00284 default:
00285 l = _free(l);
00286 return NULL;
00287 break;
00288 }
00289 }
00290 *le++ = ')';
00291 *le = '\0';
00292
00293 return l;
00294 }
00295
00303 static void singleOptionHelp(FILE * fp, columns_t columns,
00304 const struct poptOption * opt,
00305 const char * translation_domain)
00306
00307
00308 {
00309 size_t maxLeftCol = columns->cur;
00310 size_t indentLength = maxLeftCol + 5;
00311 size_t lineLength = columns->max - indentLength;
00312 const char * help = D_(translation_domain, opt->descrip);
00313 const char * argDescrip = getArgDescrip(opt, translation_domain);
00314
00315 int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' ');
00316 size_t helpLength;
00317 char * defs = NULL;
00318 char * left;
00319 size_t nb = maxLeftCol + 1;
00320 int displaypad = 0;
00321 int xx;
00322
00323
00324 if (opt->longName) nb += strlen(opt->longName);
00325 if (F_ISSET(opt, TOGGLE)) nb += sizeof("[no]") - 1;
00326 if (argDescrip) nb += strlen(argDescrip);
00327
00328 left = malloc(nb);
00329 if (left == NULL) return;
00330 left[0] = '\0';
00331 left[maxLeftCol] = '\0';
00332
00333 #define prtlong (opt->longName != NULL)
00334 if (!(prtshort || prtlong))
00335 goto out;
00336 if (prtshort && prtlong) {
00337 char *dash = F_ISSET(opt, ONEDASH) ? "-" : "--";
00338 left[0] = '-';
00339 left[1] = opt->shortName;
00340 (void) stpcpy(stpcpy(stpcpy(left+2, ", "), dash), opt->longName);
00341 } else if (prtshort) {
00342 left[0] = '-';
00343 left[1] = opt->shortName;
00344 left[2] = '\0';
00345 } else if (prtlong) {
00346
00347 char *dash = poptArgType(opt) == POPT_ARG_MAINCALL ? ""
00348 : (F_ISSET(opt, ONEDASH) ? "-" : "--");
00349 const char *longName = opt->longName;
00350 const char *toggle;
00351 if (F_ISSET(opt, TOGGLE)) {
00352 toggle = "[no]";
00353 if (longName[0] == 'n' && longName[1] == 'o') {
00354 longName += sizeof("no") - 1;
00355 if (longName[0] == '-')
00356 longName++;
00357 }
00358 } else
00359 toggle = "";
00360 (void) stpcpy(stpcpy(stpcpy(stpcpy(left, " "), dash), toggle), longName);
00361 }
00362 #undef prtlong
00363
00364 if (argDescrip) {
00365 char * le = left + strlen(left);
00366
00367 if (F_ISSET(opt, OPTIONAL))
00368 *le++ = '[';
00369
00370
00371 if (F_ISSET(opt, SHOW_DEFAULT)) {
00372 defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
00373 if (defs) {
00374 char * t = malloc((help ? strlen(help) : 0) +
00375 strlen(defs) + sizeof(" "));
00376 if (t) {
00377 char * te = t;
00378 if (help)
00379 te = stpcpy(te, help);
00380 *te++ = ' ';
00381 strcpy(te, defs);
00382 defs = _free(defs);
00383 defs = t;
00384 }
00385 }
00386 }
00387
00388 if (opt->argDescrip == NULL) {
00389 switch (poptArgType(opt)) {
00390 case POPT_ARG_NONE:
00391 break;
00392 case POPT_ARG_VAL:
00393 #ifdef NOTNOW
00394 { long aLong = opt->val;
00395 int ops = F_ISSET(opt, LOGICALOPS);
00396 int negate = F_ISSET(opt, NOT);
00397
00398
00399 if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L))
00400 break;
00401 *le++ = '[';
00402 switch (ops) {
00403 case POPT_ARGFLAG_OR:
00404 *le++ = '|';
00405 break;
00406 case POPT_ARGFLAG_AND:
00407 *le++ = '&';
00408 break;
00409 case POPT_ARGFLAG_XOR:
00410 *le++ = '^';
00411 break;
00412 default:
00413 break;
00414 }
00415 *le++ = (opt->longName != NULL ? '=' : ' ');
00416 if (negate) *le++ = '~';
00417
00418 le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
00419
00420 *le++ = ']';
00421 }
00422 #endif
00423 break;
00424 case POPT_ARG_INT:
00425 case POPT_ARG_LONG:
00426 case POPT_ARG_LONGLONG:
00427 case POPT_ARG_FLOAT:
00428 case POPT_ARG_DOUBLE:
00429 case POPT_ARG_STRING:
00430 *le++ = (opt->longName != NULL ? '=' : ' ');
00431 le = stpcpy(le, argDescrip);
00432 break;
00433 default:
00434 break;
00435 }
00436 } else {
00437 char *leo;
00438
00439
00440 if (!strchr(" =(", argDescrip[0]))
00441 *le++ = ((poptArgType(opt) == POPT_ARG_MAINCALL) ? ' ' :
00442 (poptArgType(opt) == POPT_ARG_ARGV) ? ' ' : '=');
00443 le = stpcpy(leo = le, argDescrip);
00444
00445
00446 displaypad = (int)((le - leo) - stringDisplayWidth(argDescrip));
00447 }
00448 if (F_ISSET(opt, OPTIONAL))
00449 *le++ = ']';
00450 *le = '\0';
00451 }
00452
00453 if (help)
00454 xx = POPT_fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left);
00455 else {
00456 xx = POPT_fprintf(fp," %s\n", left);
00457 goto out;
00458 }
00459
00460 left = _free(left);
00461 if (defs)
00462 help = defs;
00463
00464 helpLength = strlen(help);
00465 while (helpLength > lineLength) {
00466 const char * ch;
00467 char format[16];
00468
00469 ch = help + lineLength - 1;
00470 while (ch > help && !_isspaceptr(ch))
00471 ch = POPT_prev_char(ch);
00472 if (ch == help) break;
00473 while (ch > (help + 1) && _isspaceptr(ch))
00474 ch = POPT_prev_char (ch);
00475 ch = POPT_next_char(ch);
00476
00477
00478
00479
00480
00481 { char * fmthelp = xstrdup(help);
00482 if (fmthelp) {
00483 fmthelp[ch - help] = '\0';
00484 sprintf(format, "%%s\n%%%ds", (int) indentLength);
00485
00486 xx = POPT_fprintf(fp, format, fmthelp, " ");
00487
00488 free(fmthelp);
00489 }
00490 }
00491
00492 help = ch;
00493 while (_isspaceptr(help) && *help)
00494 help = POPT_next_char(help);
00495 helpLength = strlen(help);
00496 }
00497
00498 if (helpLength) fprintf(fp, "%s\n", help);
00499 help = NULL;
00500
00501 out:
00502
00503 defs = _free(defs);
00504
00505 left = _free(left);
00506 }
00507
00514 static size_t maxArgWidth(const struct poptOption * opt,
00515 const char * translation_domain)
00516
00517 {
00518 size_t max = 0;
00519 size_t len = 0;
00520 const char * argDescrip;
00521
00522 if (opt != NULL)
00523 while (opt->longName || opt->shortName || opt->arg) {
00524 if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) {
00525 if (opt->arg)
00526 len = maxArgWidth(opt->arg, translation_domain);
00527 if (len > max) max = len;
00528 } else if (!F_ISSET(opt, DOC_HIDDEN)) {
00529 len = sizeof(" ")-1;
00530
00531 len += sizeof("-X, ")-1;
00532 if (opt->longName) {
00533 len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1;
00534 len += strlen(opt->longName);
00535 }
00536
00537 argDescrip = getArgDescrip(opt, translation_domain);
00538
00539 if (argDescrip) {
00540
00541
00542 if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1;
00543
00544
00545 len += stringDisplayWidth(argDescrip);
00546 }
00547
00548 if (F_ISSET(opt, OPTIONAL)) len += sizeof("[]")-1;
00549 if (len > max) max = len;
00550 }
00551 opt++;
00552 }
00553
00554 return max;
00555 }
00556
00565 static void itemHelp(FILE * fp,
00566 poptItem items, int nitems,
00567 columns_t columns,
00568 const char * translation_domain)
00569
00570
00571 {
00572 poptItem item;
00573 int i;
00574
00575 if (items != NULL)
00576 for (i = 0, item = items; i < nitems; i++, item++) {
00577 const struct poptOption * opt;
00578 opt = &item->option;
00579 if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN))
00580 singleOptionHelp(fp, columns, opt, translation_domain);
00581 }
00582 }
00583
00592 static void singleTableHelp(poptContext con, FILE * fp,
00593 const struct poptOption * table,
00594 columns_t columns,
00595 const char * translation_domain)
00596
00597
00598 {
00599 const struct poptOption * opt;
00600 const char *sub_transdom;
00601 int xx;
00602
00603 if (table == poptAliasOptions) {
00604 itemHelp(fp, con->aliases, con->numAliases, columns, NULL);
00605 itemHelp(fp, con->execs, con->numExecs, columns, NULL);
00606 return;
00607 }
00608
00609 if (table != NULL)
00610 for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
00611 if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN))
00612 singleOptionHelp(fp, columns, opt, translation_domain);
00613 }
00614
00615 if (table != NULL)
00616 for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
00617 if (poptArgType(opt) != POPT_ARG_INCLUDE_TABLE)
00618 continue;
00619 sub_transdom = getTableTranslationDomain(opt->arg);
00620 if (sub_transdom == NULL)
00621 sub_transdom = translation_domain;
00622
00623
00624 if (opt->arg == poptAliasOptions && !(con->numAliases || con->numExecs))
00625 continue;
00626 if (opt->descrip)
00627 xx = POPT_fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
00628
00629 singleTableHelp(con, fp, opt->arg, columns, sub_transdom);
00630 }
00631 }
00632
00637 static size_t showHelpIntro(poptContext con, FILE * fp)
00638
00639
00640 {
00641 size_t len = (size_t)6;
00642 int xx;
00643
00644 xx = POPT_fprintf(fp, POPT_("Usage:"));
00645 if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
00646 struct optionStackEntry * os = con->optionStack;
00647 const char * fn = (os->argv ? os->argv[0] : NULL);
00648 if (fn == NULL) return len;
00649 if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
00650
00651 fprintf(fp, " %s", fn);
00652 len += strlen(fn) + 1;
00653 }
00654
00655 return len;
00656 }
00657
00658 void poptPrintHelp(poptContext con, FILE * fp, UNUSED(int flags))
00659 {
00660 columns_t columns = calloc((size_t)1, sizeof(*columns));
00661 int xx;
00662
00663 (void) showHelpIntro(con, fp);
00664 if (con->otherHelp)
00665 xx = POPT_fprintf(fp, " %s\n", con->otherHelp);
00666 else
00667 xx = POPT_fprintf(fp, " %s\n", POPT_("[OPTION...]"));
00668
00669 if (columns) {
00670 columns->cur = maxArgWidth(con->options, NULL);
00671 columns->max = maxColumnWidth(fp);
00672 singleTableHelp(con, fp, con->options, columns, NULL);
00673 free(columns);
00674 }
00675 }
00676
00684 static size_t singleOptionUsage(FILE * fp, columns_t columns,
00685 const struct poptOption * opt,
00686 const char *translation_domain)
00687
00688
00689 {
00690 size_t len = sizeof(" []")-1;
00691 const char * argDescrip = getArgDescrip(opt, translation_domain);
00692
00693 int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' ');
00694
00695 #define prtlong (opt->longName != NULL)
00696 if (!(prtshort || prtlong))
00697 return columns->cur;
00698
00699 len = sizeof(" []")-1;
00700 if (prtshort)
00701 len += sizeof("-c")-1;
00702 if (prtlong) {
00703 if (prtshort) len += sizeof("|")-1;
00704 len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1;
00705 len += strlen(opt->longName);
00706 }
00707
00708 if (argDescrip) {
00709
00710
00711 if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1;
00712
00713
00714 len += stringDisplayWidth(argDescrip);
00715 }
00716
00717 if ((columns->cur + len) > columns->max) {
00718 fprintf(fp, "\n ");
00719 columns->cur = (size_t)7;
00720 }
00721
00722 fprintf(fp, " [");
00723 if (prtshort)
00724 fprintf(fp, "-%c", opt->shortName);
00725 if (prtlong)
00726 fprintf(fp, "%s%s%s",
00727 (prtshort ? "|" : ""),
00728 (F_ISSET(opt, ONEDASH) ? "-" : "--"),
00729 opt->longName);
00730 #undef prtlong
00731
00732 if (argDescrip) {
00733
00734 if (!strchr(" =(", argDescrip[0])) fprintf(fp, "=");
00735 fprintf(fp, "%s", argDescrip);
00736 }
00737 fprintf(fp, "]");
00738
00739 return columns->cur + len + 1;
00740 }
00741
00750 static size_t itemUsage(FILE * fp, columns_t columns,
00751 poptItem item, int nitems,
00752 const char * translation_domain)
00753
00754
00755 {
00756 int i;
00757
00758 if (item != NULL)
00759 for (i = 0; i < nitems; i++, item++) {
00760 const struct poptOption * opt;
00761 opt = &item->option;
00762 if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) {
00763 translation_domain = (const char *)opt->arg;
00764 } else
00765 if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) {
00766 columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
00767 }
00768 }
00769
00770 return columns->cur;
00771 }
00772
00776 typedef struct poptDone_s {
00777 int nopts;
00778 int maxopts;
00779
00780 const void ** opts;
00781 } * poptDone;
00782
00793 static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns,
00794 const struct poptOption * opt,
00795 const char * translation_domain,
00796 poptDone done)
00797
00798
00799 {
00800 if (opt != NULL)
00801 for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
00802 if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) {
00803 translation_domain = (const char *)opt->arg;
00804 } else
00805 if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) {
00806 if (done) {
00807 int i = 0;
00808 if (done->opts != NULL)
00809 for (i = 0; i < done->nopts; i++) {
00810 const void * that = done->opts[i];
00811 if (that == NULL || that != opt->arg)
00812 continue;
00813 break;
00814 }
00815
00816 if (opt->arg == NULL || i < done->nopts)
00817 continue;
00818 if (done->opts != NULL && done->nopts < done->maxopts)
00819 done->opts[done->nopts++] = (const void *) opt->arg;
00820 }
00821 columns->cur = singleTableUsage(con, fp, columns, opt->arg,
00822 translation_domain, done);
00823 } else
00824 if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) {
00825 columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
00826 }
00827 }
00828
00829 return columns->cur;
00830 }
00831
00840 static size_t showShortOptions(const struct poptOption * opt, FILE * fp,
00841 char * str)
00842
00843
00844
00845 {
00846
00847 size_t nb = (size_t)300;
00848 char * s = (str != NULL ? str : calloc((size_t)1, nb));
00849 size_t len = (size_t)0;
00850
00851 if (s == NULL)
00852 return 0;
00853
00854 if (opt != NULL)
00855 for (; (opt->longName || opt->shortName || opt->arg); opt++) {
00856 if (!F_ISSET(opt, DOC_HIDDEN) && opt->shortName && !poptArgType(opt))
00857 {
00858
00859 if (!strchr(s, opt->shortName) && isprint((int)opt->shortName)
00860 && opt->shortName != ' ')
00861 s[strlen(s)] = opt->shortName;
00862 } else if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE)
00863 if (opt->arg)
00864 len = showShortOptions(opt->arg, fp, s);
00865 }
00866
00867
00868 if (s != str && *s != '\0') {
00869 fprintf(fp, " [-%s]", s);
00870 len = strlen(s) + sizeof(" [-]")-1;
00871 }
00872
00873 if (s != str)
00874 free(s);
00875
00876 return len;
00877 }
00878
00879 void poptPrintUsage(poptContext con, FILE * fp, UNUSED(int flags))
00880 {
00881 columns_t columns = calloc((size_t)1, sizeof(*columns));
00882 struct poptDone_s done_buf;
00883 poptDone done = &done_buf;
00884
00885 memset(done, 0, sizeof(*done));
00886 done->nopts = 0;
00887 done->maxopts = 64;
00888 if (columns) {
00889 columns->cur = done->maxopts * sizeof(*done->opts);
00890 columns->max = maxColumnWidth(fp);
00891 done->opts = calloc((size_t)1, columns->cur);
00892
00893 if (done->opts != NULL)
00894 done->opts[done->nopts++] = (const void *) con->options;
00895
00896
00897 columns->cur = showHelpIntro(con, fp);
00898 columns->cur += showShortOptions(con->options, fp, NULL);
00899 columns->cur = singleTableUsage(con, fp, columns, con->options, NULL, done);
00900 columns->cur = itemUsage(fp, columns, con->aliases, con->numAliases, NULL);
00901 columns->cur = itemUsage(fp, columns, con->execs, con->numExecs, NULL);
00902
00903 if (con->otherHelp) {
00904 columns->cur += strlen(con->otherHelp) + 1;
00905 if (columns->cur > columns->max) fprintf(fp, "\n ");
00906 fprintf(fp, " %s", con->otherHelp);
00907 }
00908
00909 fprintf(fp, "\n");
00910 if (done->opts != NULL)
00911 free(done->opts);
00912 free(columns);
00913 }
00914 }
00915
00916 void poptSetOtherOptionHelp(poptContext con, const char * text)
00917 {
00918 con->otherHelp = _free(con->otherHelp);
00919 con->otherHelp = xstrdup(text);
00920 }