📄 popthelp.c
字号:
/*@null@*/ UNUSED(const char * translation_domain)) /*@*/{ size_t max = 0; size_t len = 0; const char * s; if (opt != NULL) while (opt->longName || opt->shortName || opt->arg) { if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { if (opt->arg) /* XXX program error */ len = maxArgWidth(opt->arg, translation_domain); if (len > max) max = len; } else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { len = sizeof(" ")-1; if (opt->shortName != '\0') len += sizeof("-X")-1; if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1; if (opt->longName) { len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? sizeof("-")-1 : sizeof("--")-1); len += strlen(opt->longName); } s = getArgDescrip(opt, translation_domain);#ifdef POPT_WCHAR_HACK /* XXX Calculate no. of display characters. */ if (s) { const char * scopy = s; mbstate_t t; size_t n;/*@-boundswrite@*/ memset ((void *)&t, '\0', sizeof (t)); /* In initial state. *//*@=boundswrite@*/ /* Determine number of characters. */ n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t); len += sizeof("=")-1 + n; }#else if (s) len += sizeof("=")-1 + strlen(s);#endif if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1; if (len > max) max = len; } opt++; } return max;}/** * Display popt alias and exec help. * @param fp output file handle * @param items alias/exec array * @param nitems no. of alias/exec entries * @param left largest argument display width * @param translation_domain translation domain */static void itemHelp(FILE * fp, /*@null@*/ poptItem items, int nitems, size_t left, /*@null@*/ UNUSED(const char * translation_domain)) /*@globals fileSystem @*/ /*@modifies *fp, fileSystem @*/{ poptItem item; int i; if (items != NULL) for (i = 0, item = items; i < nitems; i++, item++) { const struct poptOption * opt; opt = &item->option; if ((opt->longName || opt->shortName) && !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) singleOptionHelp(fp, left, opt, translation_domain); }}/** * Display help text for a table of options. * @param con context * @param fp output file handle * @param table option(s) * @param left largest argument display width * @param translation_domain translation domain */static void singleTableHelp(poptContext con, FILE * fp, /*@null@*/ const struct poptOption * table, size_t left, /*@null@*/ UNUSED(const char * translation_domain)) /*@globals fileSystem @*/ /*@modifies *fp, fileSystem @*/{ const struct poptOption * opt; const char *sub_transdom; if (table == poptAliasOptions) { itemHelp(fp, con->aliases, con->numAliases, left, NULL); itemHelp(fp, con->execs, con->numExecs, left, NULL); return; } if (table != NULL) for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) { if ((opt->longName || opt->shortName) && !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) singleOptionHelp(fp, left, opt, translation_domain); } if (table != NULL) for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) { if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE) continue; sub_transdom = getTableTranslationDomain(opt->arg); if (sub_transdom == NULL) sub_transdom = translation_domain; if (opt->descrip) fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip)); singleTableHelp(con, fp, opt->arg, left, sub_transdom); }}/** * @param con context * @param fp output file handle */static int showHelpIntro(poptContext con, FILE * fp) /*@globals fileSystem @*/ /*@modifies *fp, fileSystem @*/{ int len = 6; const char * fn; fprintf(fp, POPT_("Usage:")); if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {/*@-boundsread@*/ /*@-nullderef -type@*/ /* LCL: wazzup? */ fn = con->optionStack->argv[0]; /*@=nullderef =type@*//*@=boundsread@*/ if (fn == NULL) return len; if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1; fprintf(fp, " %s", fn); len += strlen(fn) + 1; } return len;}void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags)){ size_t leftColWidth; (void) showHelpIntro(con, fp); if (con->otherHelp) fprintf(fp, " %s\n", con->otherHelp); else fprintf(fp, " %s\n", POPT_("[OPTION...]")); leftColWidth = maxArgWidth(con->options, NULL); singleTableHelp(con, fp, con->options, leftColWidth, NULL);}/** * Display usage text for an option. * @param fp output file handle * @param cursor current display position * @param opt option(s) * @param translation_domain translation domain */static size_t singleOptionUsage(FILE * fp, size_t cursor, const struct poptOption * opt, /*@null@*/ const char *translation_domain) /*@globals fileSystem @*/ /*@modifies *fp, fileSystem @*/{ size_t len = 4; char shortStr[2] = { '\0', '\0' }; const char * item = shortStr; const char * argDescrip = getArgDescrip(opt, translation_domain); if (opt->shortName != '\0' && opt->longName != NULL) { len += 2; if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++; len += strlen(opt->longName); } else if (opt->shortName != '\0') { len++; shortStr[0] = opt->shortName; shortStr[1] = '\0'; } else if (opt->longName) { len += strlen(opt->longName); if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++; item = opt->longName; } if (len == 4) return cursor;#ifdef POPT_WCHAR_HACK /* XXX Calculate no. of display characters. */ if (argDescrip) { const char * scopy = argDescrip; mbstate_t t; size_t n;/*@-boundswrite@*/ memset ((void *)&t, '\0', sizeof (t)); /* In initial state. *//*@=boundswrite@*/ /* Determine number of characters. */ n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t); len += sizeof("=")-1 + n; }#else if (argDescrip) len += sizeof("=")-1 + strlen(argDescrip);#endif if ((cursor + len) > 79) { fprintf(fp, "\n "); cursor = 7; } if (opt->longName && opt->shortName) { fprintf(fp, " [-%c|-%s%s%s%s]", opt->shortName, ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "" : "-"), opt->longName, (argDescrip ? " " : ""), (argDescrip ? argDescrip : "")); } else { fprintf(fp, " [-%s%s%s%s]", ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"), item, (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""), (argDescrip ? argDescrip : "")); } return cursor + len + 1;}/** * Display popt alias and exec usage. * @param fp output file handle * @param cursor current display position * @param item alias/exec array * @param nitems no. of ara/exec entries * @param translation_domain translation domain */static size_t itemUsage(FILE * fp, size_t cursor, /*@null@*/ poptItem item, int nitems, /*@null@*/ UNUSED(const char * translation_domain)) /*@globals fileSystem @*/ /*@modifies *fp, fileSystem @*/{ int i; /*@-branchstate@*/ /* FIX: W2DO? */ if (item != NULL) for (i = 0; i < nitems; i++, item++) { const struct poptOption * opt; opt = &item->option; if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) { translation_domain = (const char *)opt->arg; } else if ((opt->longName || opt->shortName) && !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { cursor = singleOptionUsage(fp, cursor, opt, translation_domain); } } /*@=branchstate@*/ return cursor;}/** * Keep track of option tables already processed. */typedef struct poptDone_s { int nopts; int maxopts; const void ** opts;} * poptDone;/** * Display usage text for a table of options. * @param con context * @param fp output file handle * @param cursor current display position * @param opt option(s) * @param translation_domain translation domain * @param done tables already processed * @return */static size_t singleTableUsage(poptContext con, FILE * fp, size_t cursor, /*@null@*/ const struct poptOption * opt, /*@null@*/ UNUSED(const char * translation_domain), /*@null@*/ poptDone done) /*@globals fileSystem @*/ /*@modifies *fp, done, fileSystem @*/{ /*@-branchstate@*/ /* FIX: W2DO? */ if (opt != NULL) for (; (opt->longName || opt->shortName || opt->arg) ; opt++) { if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) { translation_domain = (const char *)opt->arg; } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { if (done) { int i = 0; for (i = 0; i < done->nopts; i++) {/*@-boundsread@*/ const void * that = done->opts[i];/*@=boundsread@*/ if (that == NULL || that != opt->arg) /*@innercontinue@*/ continue; /*@innerbreak@*/ break; } /* Skip if this table has already been processed. */ if (opt->arg == NULL || i < done->nopts) continue;/*@-boundswrite@*/ if (done->nopts < done->maxopts) done->opts[done->nopts++] = (const void *) opt->arg;/*@=boundswrite@*/ } cursor = singleTableUsage(con, fp, cursor, opt->arg, translation_domain, done); } else if ((opt->longName || opt->shortName) && !(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) { cursor = singleOptionUsage(fp, cursor, opt, translation_domain); } } /*@=branchstate@*/ return cursor;}/** * Return concatenated short options for display. * @todo Sub-tables should be recursed. * @param opt option(s) * @param fp output file handle * @retval str concatenation of short options * @return length of display string */static int showShortOptions(const struct poptOption * opt, FILE * fp, /*@null@*/ char * str) /*@globals fileSystem @*/ /*@modifies *str, *fp, fileSystem @*/ /*@requires maxRead(str) >= 0 @*/{ /* bufsize larger then the ascii set, lazy alloca on top level call. */ char * s = (str != NULL ? str : memset(alloca(300), 0, 300)); int len = 0; if (s == NULL) return 0;/*@-boundswrite@*/ if (opt != NULL) for (; (opt->longName || opt->shortName || opt->arg); opt++) { if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK)) s[strlen(s)] = opt->shortName; else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) if (opt->arg) /* XXX program error */ len = showShortOptions(opt->arg, fp, s); } /*@=boundswrite@*/ /* On return to top level, print the short options, return print length. */ if (s == str && *s != '\0') { fprintf(fp, " [-%s]", s); len = strlen(s) + sizeof(" [-]")-1; } return len;}void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags)){ poptDone done = memset(alloca(sizeof(*done)), 0, sizeof(*done)); size_t cursor; done->nopts = 0; done->maxopts = 64; cursor = done->maxopts * sizeof(*done->opts);/*@-boundswrite@*/ done->opts = memset(alloca(cursor), 0, cursor); /*@-keeptrans@*/ done->opts[done->nopts++] = (const void *) con->options; /*@=keeptrans@*//*@=boundswrite@*/ cursor = showHelpIntro(con, fp); cursor += showShortOptions(con->options, fp, NULL); cursor = singleTableUsage(con, fp, cursor, con->options, NULL, done); cursor = itemUsage(fp, cursor, con->aliases, con->numAliases, NULL); cursor = itemUsage(fp, cursor, con->execs, con->numExecs, NULL); if (con->otherHelp) { cursor += strlen(con->otherHelp) + 1; if (cursor > 79) fprintf(fp, "\n "); fprintf(fp, " %s", con->otherHelp); } fprintf(fp, "\n");}void poptSetOtherOptionHelp(poptContext con, const char * text){ con->otherHelp = _free(con->otherHelp); con->otherHelp = xstrdup(text);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -