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_SHORT: return POPT_("SHORT");
00208 case POPT_ARG_LONG: return POPT_("LONG");
00209 case POPT_ARG_LONGLONG: return POPT_("LONGLONG");
00210 case POPT_ARG_STRING: return POPT_("STRING");
00211 case POPT_ARG_FLOAT: return POPT_("FLOAT");
00212 case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
00213 case POPT_ARG_MAINCALL: return NULL;
00214 case POPT_ARG_ARGV: return NULL;
00215 default: return POPT_("ARG");
00216 }
00217 }
00218
00226 static char *
00227 singleOptionDefaultValue(size_t lineLength,
00228 const struct poptOption * opt,
00229
00230 const char * translation_domain)
00231
00232
00233 {
00234 const char * defstr = D_(translation_domain, "default");
00235 char * le = malloc(4*lineLength + 1);
00236 char * l = le;
00237
00238 if (le == NULL) return NULL;
00239 *le = '\0';
00240 *le++ = '(';
00241 le = stpcpy(le, defstr);
00242 *le++ = ':';
00243 *le++ = ' ';
00244 if (opt->arg) {
00245 poptArg arg = { .ptr = opt->arg };
00246 switch (poptArgType(opt)) {
00247 case POPT_ARG_VAL:
00248 case POPT_ARG_INT:
00249 le += sprintf(le, "%d", arg.intp[0]);
00250 break;
00251 case POPT_ARG_SHORT:
00252 le += sprintf(le, "%hd", arg.shortp[0]);
00253 break;
00254 case POPT_ARG_LONG:
00255 le += sprintf(le, "%ld", arg.longp[0]);
00256 break;
00257 case POPT_ARG_LONGLONG:
00258 le += sprintf(le, "%lld", arg.longlongp[0]);
00259 break;
00260 case POPT_ARG_FLOAT:
00261 { double aDouble = (double) arg.floatp[0];
00262 le += sprintf(le, "%g", aDouble);
00263 } break;
00264 case POPT_ARG_DOUBLE:
00265 le += sprintf(le, "%g", arg.doublep[0]);
00266 break;
00267 case POPT_ARG_MAINCALL:
00268 le += sprintf(le, "%p", opt->arg);
00269 break;
00270 case POPT_ARG_ARGV:
00271 le += sprintf(le, "%p", opt->arg);
00272 break;
00273 case POPT_ARG_STRING:
00274 { const char * s = arg.argv[0];
00275 if (s == NULL)
00276 le = stpcpy(le, "null");
00277 else {
00278 size_t limit = 4*lineLength - (le - l) - sizeof("\"\")");
00279 size_t slen;
00280 *le++ = '"';
00281 strncpy(le, s, limit); le[limit] = '\0'; le += (slen = strlen(le));
00282 if (slen == limit && s[limit])
00283 le[-1] = le[-2] = le[-3] = '.';
00284 *le++ = '"';
00285 }
00286 } break;
00287 case POPT_ARG_NONE:
00288 default:
00289 l = _free(l);
00290 return NULL;
00291 break;
00292 }
00293 }
00294 *le++ = ')';
00295 *le = '\0';
00296
00297 return l;
00298 }
00299
00307 static void singleOptionHelp(FILE * fp, columns_t columns,
00308 const struct poptOption * opt,
00309 const char * translation_domain)
00310
00311
00312 {
00313 size_t maxLeftCol = columns->cur;
00314 size_t indentLength = maxLeftCol + 5;
00315 size_t lineLength = columns->max - indentLength;
00316 const char * help = D_(translation_domain, opt->descrip);
00317 const char * argDescrip = getArgDescrip(opt, translation_domain);
00318
00319 int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' ');
00320 size_t helpLength;
00321 char * defs = NULL;
00322 char * left;
00323 size_t nb = maxLeftCol + 1;
00324 int displaypad = 0;
00325 int xx;
00326
00327
00328 if (opt->longName) nb += strlen(opt->longName);
00329 if (F_ISSET(opt, TOGGLE)) nb += sizeof("[no]") - 1;
00330 if (argDescrip) nb += strlen(argDescrip);
00331
00332 left = malloc(nb);
00333 if (left == NULL) return;
00334 left[0] = '\0';
00335 left[maxLeftCol] = '\0';
00336
00337 #define prtlong (opt->longName != NULL)
00338 if (!(prtshort || prtlong))
00339 goto out;
00340 if (prtshort && prtlong) {
00341 char *dash = F_ISSET(opt, ONEDASH) ? "-" : "--";
00342 left[0] = '-';
00343 left[1] = opt->shortName;
00344 (void) stpcpy(stpcpy(stpcpy(left+2, ", "), dash), opt->longName);
00345 } else if (prtshort) {
00346 left[0] = '-';
00347 left[1] = opt->shortName;
00348 left[2] = '\0';
00349 } else if (prtlong) {
00350
00351 char *dash = poptArgType(opt) == POPT_ARG_MAINCALL ? ""
00352 : (F_ISSET(opt, ONEDASH) ? "-" : "--");
00353 const char *longName = opt->longName;
00354 const char *toggle;
00355 if (F_ISSET(opt, TOGGLE)) {
00356 toggle = "[no]";
00357 if (longName[0] == 'n' && longName[1] == 'o') {
00358 longName += sizeof("no") - 1;
00359 if (longName[0] == '-')
00360 longName++;
00361 }
00362 } else
00363 toggle = "";
00364 (void) stpcpy(stpcpy(stpcpy(stpcpy(left, " "), dash), toggle), longName);
00365 }
00366 #undef prtlong
00367
00368 if (argDescrip) {
00369 char * le = left + strlen(left);
00370
00371 if (F_ISSET(opt, OPTIONAL))
00372 *le++ = '[';
00373
00374
00375 if (F_ISSET(opt, SHOW_DEFAULT)) {
00376 defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
00377 if (defs) {
00378 char * t = malloc((help ? strlen(help) : 0) +
00379 strlen(defs) + sizeof(" "));
00380 if (t) {
00381 char * te = t;
00382 if (help)
00383 te = stpcpy(te, help);
00384 *te++ = ' ';
00385 strcpy(te, defs);
00386 defs = _free(defs);
00387 defs = t;
00388 }
00389 }
00390 }
00391
00392 if (opt->argDescrip == NULL) {
00393 switch (poptArgType(opt)) {
00394 case POPT_ARG_NONE:
00395 break;
00396 case POPT_ARG_VAL:
00397 #ifdef NOTNOW
00398 { long aLong = opt->val;
00399 int ops = F_ISSET(opt, LOGICALOPS);
00400 int negate = F_ISSET(opt, NOT);
00401
00402
00403 if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L))
00404 break;
00405 *le++ = '[';
00406 switch (ops) {
00407 case POPT_ARGFLAG_OR:
00408 *le++ = '|';
00409 break;
00410 case POPT_ARGFLAG_AND:
00411 *le++ = '&';
00412 break;
00413 case POPT_ARGFLAG_XOR:
00414 *le++ = '^';
00415 break;
00416 default:
00417 break;
00418 }
00419 *le++ = (opt->longName != NULL ? '=' : ' ');
00420 if (negate) *le++ = '~';
00421
00422 le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
00423
00424 *le++ = ']';
00425 }
00426 #endif
00427 break;
00428 case POPT_ARG_INT:
00429 case POPT_ARG_SHORT:
00430 case POPT_ARG_LONG:
00431 case POPT_ARG_LONGLONG:
00432 case POPT_ARG_FLOAT:
00433 case POPT_ARG_DOUBLE:
00434 case POPT_ARG_STRING:
00435 *le++ = (opt->longName != NULL ? '=' : ' ');
00436 le = stpcpy(le, argDescrip);
00437 break;
00438 default:
00439 break;
00440 }
00441 } else {
00442 char *leo;
00443
00444
00445 if (!strchr(" =(", argDescrip[0]))
00446 *le++ = ((poptArgType(opt) == POPT_ARG_MAINCALL) ? ' ' :
00447 (poptArgType(opt) == POPT_ARG_ARGV) ? ' ' : '=');
00448 le = stpcpy(leo = le, argDescrip);
00449
00450
00451 displaypad = (int)((le - leo) - stringDisplayWidth(argDescrip));
00452 }
00453 if (F_ISSET(opt, OPTIONAL))
00454 *le++ = ']';
00455 *le = '\0';
00456 }
00457
00458 if (help)
00459 xx = POPT_fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left);
00460 else {
00461 xx = POPT_fprintf(fp," %s\n", left);
00462 goto out;
00463 }
00464
00465 left = _free(left);
00466 if (defs)
00467 help = defs;
00468
00469 helpLength = strlen(help);
00470 while (helpLength > lineLength) {
00471 const char * ch;
00472 char format[16];
00473
00474 ch = help + lineLength - 1;
00475 while (ch > help && !_isspaceptr(ch))
00476 ch = POPT_prev_char(ch);
00477 if (ch == help) break;
00478 while (ch > (help + 1) && _isspaceptr(ch))
00479 ch = POPT_prev_char (ch);
00480 ch = POPT_next_char(ch);
00481
00482
00483
00484
00485
00486 { char * fmthelp = xstrdup(help);
00487 if (fmthelp) {
00488 fmthelp[ch - help] = '\0';
00489 sprintf(format, "%%s\n%%%ds", (int) indentLength);
00490
00491 xx = POPT_fprintf(fp, format, fmthelp, " ");
00492
00493 free(fmthelp);
00494 }
00495 }
00496
00497 help = ch;
00498 while (_isspaceptr(help) && *help)
00499 help = POPT_next_char(help);
00500 helpLength = strlen(help);
00501 }
00502
00503 if (helpLength) fprintf(fp, "%s\n", help);
00504 help = NULL;
00505
00506 out:
00507
00508 defs = _free(defs);
00509
00510 left = _free(left);
00511 }
00512
00519 static size_t maxArgWidth(const struct poptOption * opt,
00520 const char * translation_domain)
00521
00522 {
00523 size_t max = 0;
00524 size_t len = 0;
00525 const char * argDescrip;
00526
00527 if (opt != NULL)
00528 while (opt->longName || opt->shortName || opt->arg) {
00529 if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) {
00530 if (opt->arg)
00531 len = maxArgWidth(opt->arg, translation_domain);
00532 if (len > max) max = len;
00533 } else if (!F_ISSET(opt, DOC_HIDDEN)) {
00534 len = sizeof(" ")-1;
00535
00536 len += sizeof("-X, ")-1;
00537 if (opt->longName) {
00538 len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1;
00539 len += strlen(opt->longName);
00540 }
00541
00542 argDescrip = getArgDescrip(opt, translation_domain);
00543
00544 if (argDescrip) {
00545
00546
00547 if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1;
00548
00549
00550 len += stringDisplayWidth(argDescrip);
00551 }
00552
00553 if (F_ISSET(opt, OPTIONAL)) len += sizeof("[]")-1;
00554 if (len > max) max = len;
00555 }
00556 opt++;
00557 }
00558
00559 return max;
00560 }
00561
00570 static void itemHelp(FILE * fp,
00571 poptItem items, int nitems,
00572 columns_t columns,
00573 const char * translation_domain)
00574
00575
00576 {
00577 poptItem item;
00578 int i;
00579
00580 if (items != NULL)
00581 for (i = 0, item = items; i < nitems; i++, item++) {
00582 const struct poptOption * opt;
00583 opt = &item->option;
00584 if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN))
00585 singleOptionHelp(fp, columns, opt, translation_domain);
00586 }
00587 }
00588
00597 static void singleTableHelp(poptContext con, FILE * fp,
00598 const struct poptOption * table,
00599 columns_t columns,
00600 const char * translation_domain)
00601
00602
00603 {
00604 const struct poptOption * opt;
00605 const char *sub_transdom;
00606 int xx;
00607
00608 if (table == poptAliasOptions) {
00609 itemHelp(fp, con->aliases, con->numAliases, columns, NULL);
00610 itemHelp(fp, con->execs, con->numExecs, columns, NULL);
00611 return;
00612 }
00613
00614 if (table != NULL)
00615 for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
00616 if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN))
00617 singleOptionHelp(fp, columns, opt, translation_domain);
00618 }
00619
00620 if (table != NULL)
00621 for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
00622 if (poptArgType(opt) != POPT_ARG_INCLUDE_TABLE)
00623 continue;
00624 sub_transdom = getTableTranslationDomain(opt->arg);
00625 if (sub_transdom == NULL)
00626 sub_transdom = translation_domain;
00627
00628
00629 if (opt->arg == poptAliasOptions && !(con->numAliases || con->numExecs))
00630 continue;
00631 if (opt->descrip)
00632 xx = POPT_fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
00633
00634 singleTableHelp(con, fp, opt->arg, columns, sub_transdom);
00635 }
00636 }
00637
00642 static size_t showHelpIntro(poptContext con, FILE * fp)
00643
00644
00645 {
00646 size_t len = (size_t)6;
00647 int xx;
00648
00649 xx = POPT_fprintf(fp, POPT_("Usage:"));
00650 if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
00651 struct optionStackEntry * os = con->optionStack;
00652 const char * fn = (os->argv ? os->argv[0] : NULL);
00653 if (fn == NULL) return len;
00654 if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
00655
00656 fprintf(fp, " %s", fn);
00657 len += strlen(fn) + 1;
00658 }
00659
00660 return len;
00661 }
00662
00663 void poptPrintHelp(poptContext con, FILE * fp, UNUSED(int flags))
00664 {
00665 columns_t columns = calloc((size_t)1, sizeof(*columns));
00666 int xx;
00667
00668 (void) showHelpIntro(con, fp);
00669 if (con->otherHelp)
00670 xx = POPT_fprintf(fp, " %s\n", con->otherHelp);
00671 else
00672 xx = POPT_fprintf(fp, " %s\n", POPT_("[OPTION...]"));
00673
00674 if (columns) {
00675 columns->cur = maxArgWidth(con->options, NULL);
00676 columns->max = maxColumnWidth(fp);
00677 singleTableHelp(con, fp, con->options, columns, NULL);
00678 free(columns);
00679 }
00680 }
00681
00689 static size_t singleOptionUsage(FILE * fp, columns_t columns,
00690 const struct poptOption * opt,
00691 const char *translation_domain)
00692
00693
00694 {
00695 size_t len = sizeof(" []")-1;
00696 const char * argDescrip = getArgDescrip(opt, translation_domain);
00697
00698 int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' ');
00699
00700 #define prtlong (opt->longName != NULL)
00701 if (!(prtshort || prtlong))
00702 return columns->cur;
00703
00704 len = sizeof(" []")-1;
00705 if (prtshort)
00706 len += sizeof("-c")-1;
00707 if (prtlong) {
00708 if (prtshort) len += sizeof("|")-1;
00709 len += (F_ISSET(opt, ONEDASH) ? sizeof("-") : sizeof("--")) - 1;
00710 len += strlen(opt->longName);
00711 }
00712
00713 if (argDescrip) {
00714
00715
00716 if (!strchr(" =(", argDescrip[0])) len += sizeof("=")-1;
00717
00718
00719 len += stringDisplayWidth(argDescrip);
00720 }
00721
00722 if ((columns->cur + len) > columns->max) {
00723 fprintf(fp, "\n ");
00724 columns->cur = (size_t)7;
00725 }
00726
00727 fprintf(fp, " [");
00728 if (prtshort)
00729 fprintf(fp, "-%c", opt->shortName);
00730 if (prtlong)
00731 fprintf(fp, "%s%s%s",
00732 (prtshort ? "|" : ""),
00733 (F_ISSET(opt, ONEDASH) ? "-" : "--"),
00734 opt->longName);
00735 #undef prtlong
00736
00737 if (argDescrip) {
00738
00739 if (!strchr(" =(", argDescrip[0])) fprintf(fp, "=");
00740 fprintf(fp, "%s", argDescrip);
00741 }
00742 fprintf(fp, "]");
00743
00744 return columns->cur + len + 1;
00745 }
00746
00755 static size_t itemUsage(FILE * fp, columns_t columns,
00756 poptItem item, int nitems,
00757 const char * translation_domain)
00758
00759
00760 {
00761 int i;
00762
00763 if (item != NULL)
00764 for (i = 0; i < nitems; i++, item++) {
00765 const struct poptOption * opt;
00766 opt = &item->option;
00767 if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) {
00768 translation_domain = (const char *)opt->arg;
00769 } else
00770 if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) {
00771 columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
00772 }
00773 }
00774
00775 return columns->cur;
00776 }
00777
00781 typedef struct poptDone_s {
00782 int nopts;
00783 int maxopts;
00784
00785 const void ** opts;
00786 } * poptDone;
00787
00798 static size_t singleTableUsage(poptContext con, FILE * fp, columns_t columns,
00799 const struct poptOption * opt,
00800 const char * translation_domain,
00801 poptDone done)
00802
00803
00804 {
00805 if (opt != NULL)
00806 for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
00807 if (poptArgType(opt) == POPT_ARG_INTL_DOMAIN) {
00808 translation_domain = (const char *)opt->arg;
00809 } else
00810 if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE) {
00811 if (done) {
00812 int i = 0;
00813 if (done->opts != NULL)
00814 for (i = 0; i < done->nopts; i++) {
00815 const void * that = done->opts[i];
00816 if (that == NULL || that != opt->arg)
00817 continue;
00818 break;
00819 }
00820
00821 if (opt->arg == NULL || i < done->nopts)
00822 continue;
00823 if (done->opts != NULL && done->nopts < done->maxopts)
00824 done->opts[done->nopts++] = (const void *) opt->arg;
00825 }
00826 columns->cur = singleTableUsage(con, fp, columns, opt->arg,
00827 translation_domain, done);
00828 } else
00829 if ((opt->longName || opt->shortName) && !F_ISSET(opt, DOC_HIDDEN)) {
00830 columns->cur = singleOptionUsage(fp, columns, opt, translation_domain);
00831 }
00832 }
00833
00834 return columns->cur;
00835 }
00836
00845 static size_t showShortOptions(const struct poptOption * opt, FILE * fp,
00846 char * str)
00847
00848
00849
00850 {
00851
00852 size_t nb = (size_t)300;
00853 char * s = (str != NULL ? str : calloc((size_t)1, nb));
00854 size_t len = (size_t)0;
00855
00856 if (s == NULL)
00857 return 0;
00858
00859 if (opt != NULL)
00860 for (; (opt->longName || opt->shortName || opt->arg); opt++) {
00861 if (!F_ISSET(opt, DOC_HIDDEN) && opt->shortName && !poptArgType(opt))
00862 {
00863
00864 if (!strchr(s, opt->shortName) && isprint((int)opt->shortName)
00865 && opt->shortName != ' ')
00866 s[strlen(s)] = opt->shortName;
00867 } else if (poptArgType(opt) == POPT_ARG_INCLUDE_TABLE)
00868 if (opt->arg)
00869 len = showShortOptions(opt->arg, fp, s);
00870 }
00871
00872
00873 if (s != str && *s != '\0') {
00874 fprintf(fp, " [-%s]", s);
00875 len = strlen(s) + sizeof(" [-]")-1;
00876 }
00877
00878 if (s != str)
00879 free(s);
00880
00881 return len;
00882 }
00883
00884 void poptPrintUsage(poptContext con, FILE * fp, UNUSED(int flags))
00885 {
00886 columns_t columns = calloc((size_t)1, sizeof(*columns));
00887 struct poptDone_s done_buf;
00888 poptDone done = &done_buf;
00889
00890 memset(done, 0, sizeof(*done));
00891 done->nopts = 0;
00892 done->maxopts = 64;
00893 if (columns) {
00894 columns->cur = done->maxopts * sizeof(*done->opts);
00895 columns->max = maxColumnWidth(fp);
00896 done->opts = calloc((size_t)1, columns->cur);
00897
00898 if (done->opts != NULL)
00899 done->opts[done->nopts++] = (const void *) con->options;
00900
00901
00902 columns->cur = showHelpIntro(con, fp);
00903 columns->cur += showShortOptions(con->options, fp, NULL);
00904 columns->cur = singleTableUsage(con, fp, columns, con->options, NULL, done);
00905 columns->cur = itemUsage(fp, columns, con->aliases, con->numAliases, NULL);
00906 columns->cur = itemUsage(fp, columns, con->execs, con->numExecs, NULL);
00907
00908 if (con->otherHelp) {
00909 columns->cur += strlen(con->otherHelp) + 1;
00910 if (columns->cur > columns->max) fprintf(fp, "\n ");
00911 fprintf(fp, " %s", con->otherHelp);
00912 }
00913
00914 fprintf(fp, "\n");
00915 if (done->opts != NULL)
00916 free(done->opts);
00917 free(columns);
00918 }
00919 }
00920
00921 void poptSetOtherOptionHelp(poptContext con, const char * text)
00922 {
00923 con->otherHelp = _free(con->otherHelp);
00924 con->otherHelp = xstrdup(text);
00925 }