usage.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339
  1. /*
  2. * \file usage.c
  3. *
  4. * This module implements the default usage procedure for
  5. * Automated Options. It may be overridden, of course.
  6. *
  7. * @addtogroup autoopts
  8. * @{
  9. */
  10. /*
  11. * Sort options:
  12. --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \
  13. --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \
  14. --spac=2 --input=usage.c
  15. */
  16. /*
  17. * This file is part of AutoOpts, a companion to AutoGen.
  18. * AutoOpts is free software.
  19. * AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
  20. *
  21. * AutoOpts is available under any one of two licenses. The license
  22. * in use must be one of these two and the choice is under the control
  23. * of the user of the license.
  24. *
  25. * The GNU Lesser General Public License, version 3 or later
  26. * See the files "COPYING.lgplv3" and "COPYING.gplv3"
  27. *
  28. * The Modified Berkeley Software Distribution License
  29. * See the file "COPYING.mbsd"
  30. *
  31. * These files have the following sha256 sums:
  32. *
  33. * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3
  34. * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3
  35. * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd
  36. */
  37. #define GRAPH_CH(_ch) \
  38. ((((unsigned)_ch) <= 0x7E) && (((unsigned)_ch) > ' '))
  39. /* = = = START-STATIC-FORWARD = = = */
  40. static unsigned int
  41. parse_usage_flags(ao_flag_names_t const * fnt, char const * txt);
  42. static inline bool
  43. do_gnu_usage(tOptions * pOpts);
  44. static inline bool
  45. skip_misuse_usage(tOptions * pOpts);
  46. static void
  47. print_offer_usage(tOptions * opts);
  48. static void
  49. print_usage_details(tOptions * opts, int exit_code);
  50. static void
  51. print_one_paragraph(char const * text, bool plain, FILE * fp);
  52. static void
  53. prt_conflicts(tOptions * opts, tOptDesc * od);
  54. static void
  55. prt_one_vendor(tOptions * opts, tOptDesc * od,
  56. arg_types_t * argtp, char const * usefmt);
  57. static void
  58. prt_vendor_opts(tOptions * opts, char const * title);
  59. static void
  60. prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title);
  61. static void
  62. prt_ini_list(char const * const * papz, char const * ini_file,
  63. char const * path_nm);
  64. static void
  65. prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at);
  66. static void
  67. prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at);
  68. static void
  69. prt_opt_usage(tOptions * opts, int ex_code, char const * title);
  70. static void
  71. prt_prog_detail(tOptions * opts);
  72. static int
  73. setGnuOptFmts(tOptions * opts, char const ** ptxt);
  74. static int
  75. setStdOptFmts(tOptions * opts, char const ** ptxt);
  76. /* = = = END-STATIC-FORWARD = = = */
  77. /**
  78. * Parse the option usage flags string. Any parsing problems yield
  79. * a zero (no flags set) result. This function is internal to
  80. * set_usage_flags().
  81. *
  82. * @param[in] fnt Flag Name Table - maps a name to a mask
  83. * @param[in] txt the text to process. If NULL, then
  84. * getenv("AUTOOPTS_USAGE") is used.
  85. * @returns a bit mask indicating which \a fnt entries were found.
  86. */
  87. static unsigned int
  88. parse_usage_flags(ao_flag_names_t const * fnt, char const * txt)
  89. {
  90. unsigned int res = 0;
  91. /*
  92. * The text may be passed in. If not, use the environment variable.
  93. */
  94. if (txt == NULL) {
  95. txt = getenv("AUTOOPTS_USAGE");
  96. if (txt == NULL)
  97. return 0;
  98. }
  99. txt = SPN_WHITESPACE_CHARS(txt);
  100. if (*txt == NUL)
  101. return 0;
  102. /*
  103. * search the string for table entries. We must understand everything
  104. * we see in the string, or we give up on it.
  105. */
  106. for (;;) {
  107. int ix = 0;
  108. for (;;) {
  109. if (strneqvcmp(txt, fnt[ix].fnm_name, (int)fnt[ix].fnm_len) == 0)
  110. break;
  111. if (++ix >= AOUF_COUNT)
  112. return 0;
  113. }
  114. /*
  115. * Make sure we have a full match. Look for whitespace,
  116. * a comma, or a NUL byte.
  117. */
  118. if (! IS_END_LIST_ENTRY_CHAR(txt[fnt[ix].fnm_len]))
  119. return 0;
  120. res |= 1U << ix;
  121. txt = SPN_WHITESPACE_CHARS(txt + fnt[ix].fnm_len);
  122. switch (*txt) {
  123. case NUL:
  124. return res;
  125. case ',':
  126. txt = SPN_WHITESPACE_CHARS(txt + 1);
  127. /* Something must follow the comma */
  128. default:
  129. continue;
  130. }
  131. }
  132. }
  133. /**
  134. * Set option usage flags. Any parsing problems yield no changes to options.
  135. * Three different bits may be fiddled: \a OPTPROC_GNUUSAGE, \a OPTPROC_MISUSE
  136. * and \a OPTPROC_COMPUTE.
  137. *
  138. * @param[in] flg_txt text to parse. If NULL, then the AUTOOPTS_USAGE
  139. * environment variable is parsed.
  140. * @param[in,out] opts the program option descriptor
  141. */
  142. LOCAL void
  143. set_usage_flags(tOptions * opts, char const * flg_txt)
  144. {
  145. # define _aof_(_n, _f) { sizeof(#_n)-1, _f, #_n },
  146. static ao_flag_names_t const fn_table[AOUF_COUNT] = {
  147. AOFLAG_TABLE
  148. };
  149. # undef _aof_
  150. /*
  151. * the flag word holds a bit for each selected table entry.
  152. */
  153. unsigned int flg = parse_usage_flags(fn_table, flg_txt);
  154. if (flg == 0) return;
  155. /*
  156. * Ensure we do not have conflicting selections
  157. */
  158. {
  159. static unsigned int const form_mask =
  160. AOUF_gnu | AOUF_autoopts;
  161. static unsigned int const misuse_mask =
  162. AOUF_no_misuse_usage | AOUF_misuse_usage;
  163. if ( ((flg & form_mask) == form_mask)
  164. || ((flg & misuse_mask) == misuse_mask) )
  165. return;
  166. }
  167. /*
  168. * Now fiddle the fOptSet bits, based on settings.
  169. * The OPTPROC_LONGOPT bit is immutable, thus if it is set,
  170. * then fnm points to a mask off mask.
  171. */
  172. {
  173. ao_flag_names_t const * fnm = fn_table;
  174. for (;;) {
  175. if ((flg & 1) != 0) {
  176. if ((fnm->fnm_mask & OPTPROC_LONGOPT) != 0)
  177. opts->fOptSet &= fnm->fnm_mask;
  178. else opts->fOptSet |= fnm->fnm_mask;
  179. }
  180. flg >>= 1;
  181. if (flg == 0)
  182. break;
  183. fnm++;
  184. }
  185. }
  186. }
  187. /*
  188. * Figure out if we should try to format usage text sort-of like
  189. * the way many GNU programs do.
  190. */
  191. static inline bool
  192. do_gnu_usage(tOptions * pOpts)
  193. {
  194. return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? true : false;
  195. }
  196. /*
  197. * Figure out if we should try to format usage text sort-of like
  198. * the way many GNU programs do.
  199. */
  200. static inline bool
  201. skip_misuse_usage(tOptions * pOpts)
  202. {
  203. return (pOpts->fOptSet & OPTPROC_MISUSE) ? true : false;
  204. }
  205. /*=export_func optionOnlyUsage
  206. *
  207. * what: Print usage text for just the options
  208. * arg: + tOptions * + pOpts + program options descriptor +
  209. * arg: + int + ex_code + exit code for calling exit(3) +
  210. *
  211. * doc:
  212. * This routine will print only the usage for each option.
  213. * This function may be used when the emitted usage must incorporate
  214. * information not available to AutoOpts.
  215. =*/
  216. void
  217. optionOnlyUsage(tOptions * pOpts, int ex_code)
  218. {
  219. char const * pOptTitle = NULL;
  220. set_usage_flags(pOpts, NULL);
  221. if ((ex_code != EXIT_SUCCESS) &&
  222. skip_misuse_usage(pOpts))
  223. return;
  224. /*
  225. * Determine which header and which option formatting strings to use
  226. */
  227. if (do_gnu_usage(pOpts))
  228. (void)setGnuOptFmts(pOpts, &pOptTitle);
  229. else
  230. (void)setStdOptFmts(pOpts, &pOptTitle);
  231. prt_opt_usage(pOpts, ex_code, pOptTitle);
  232. fflush(option_usage_fp);
  233. if (ferror(option_usage_fp) != 0)
  234. fserr_exit(pOpts->pzProgName, zwriting, (option_usage_fp == stderr)
  235. ? zstderr_name : zstdout_name);
  236. }
  237. /**
  238. * Print a message suggesting how to get help.
  239. *
  240. * @param[in] opts the program options
  241. */
  242. static void
  243. print_offer_usage(tOptions * opts)
  244. {
  245. char help[24];
  246. if (HAS_opt_usage_t(opts)) {
  247. int ix = opts->presetOptCt;
  248. tOptDesc * od = opts->pOptDesc + ix;
  249. while (od->optUsage != AOUSE_HELP) {
  250. if (++ix >= opts->optCt)
  251. ao_bug(zmissing_help_msg);
  252. od++;
  253. }
  254. switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) {
  255. case OPTPROC_SHORTOPT:
  256. help[0] = '-';
  257. help[1] = od->optValue;
  258. help[2] = NUL;
  259. break;
  260. case OPTPROC_LONGOPT:
  261. case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT):
  262. help[0] = help[1] = '-';
  263. strncpy(help + 2, od->pz_Name, 20);
  264. break;
  265. case 0:
  266. strncpy(help, od->pz_Name, 20);
  267. break;
  268. }
  269. } else {
  270. switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) {
  271. case OPTPROC_SHORTOPT:
  272. strcpy(help, "-h");
  273. break;
  274. case OPTPROC_LONGOPT:
  275. case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT):
  276. strcpy(help, "--help");
  277. break;
  278. case 0:
  279. strcpy(help, "help");
  280. break;
  281. }
  282. }
  283. fprintf(option_usage_fp, zoffer_usage_fmt, opts->pzProgName, help);
  284. }
  285. /**
  286. * Print information about each option.
  287. *
  288. * @param[in] opts the program options
  289. * @param[in] exit_code whether or not there was a usage error reported.
  290. * used to select full usage versus abbreviated.
  291. */
  292. static void
  293. print_usage_details(tOptions * opts, int exit_code)
  294. {
  295. {
  296. char const * pOptTitle = NULL;
  297. int flen;
  298. /*
  299. * Determine which header and which option formatting strings to use
  300. */
  301. if (do_gnu_usage(opts)) {
  302. flen = setGnuOptFmts(opts, &pOptTitle);
  303. sprintf(line_fmt_buf, zFmtFmt, flen);
  304. fputc(NL, option_usage_fp);
  305. } else {
  306. flen = setStdOptFmts(opts, &pOptTitle);
  307. sprintf(line_fmt_buf, zFmtFmt, flen);
  308. /*
  309. * When we exit with EXIT_SUCCESS and the first option is a doc
  310. * option, we do *NOT* want to emit the column headers.
  311. * Otherwise, we do.
  312. */
  313. if ( (exit_code != EXIT_SUCCESS)
  314. || ((opts->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) )
  315. fputs(pOptTitle, option_usage_fp);
  316. }
  317. flen = 4 - ((flen + 15) / 8);
  318. if (flen > 0)
  319. tab_skip_ct = flen;
  320. prt_opt_usage(opts, exit_code, pOptTitle);
  321. }
  322. /*
  323. * Describe the mechanics of denoting the options
  324. */
  325. switch (opts->fOptSet & OPTPROC_L_N_S) {
  326. case OPTPROC_L_N_S: fputs(zFlagOkay, option_usage_fp); break;
  327. case OPTPROC_SHORTOPT: break;
  328. case OPTPROC_LONGOPT: fputs(zNoFlags, option_usage_fp); break;
  329. case 0: fputs(zOptsOnly, option_usage_fp); break;
  330. }
  331. if ((opts->fOptSet & OPTPROC_NUM_OPT) != 0)
  332. fputs(zNumberOpt, option_usage_fp);
  333. if ((opts->fOptSet & OPTPROC_REORDER) != 0)
  334. fputs(zReorder, option_usage_fp);
  335. if (opts->pzExplain != NULL)
  336. fputs(opts->pzExplain, option_usage_fp);
  337. /*
  338. * IF the user is asking for help (thus exiting with SUCCESS),
  339. * THEN see what additional information we can provide.
  340. */
  341. if (exit_code == EXIT_SUCCESS)
  342. prt_prog_detail(opts);
  343. /*
  344. * Give bug notification preference to the packager information
  345. */
  346. if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL))
  347. fputs(opts->pzPackager, option_usage_fp);
  348. else if (opts->pzBugAddr != NULL)
  349. fprintf(option_usage_fp, zPlsSendBugs, opts->pzBugAddr);
  350. fflush(option_usage_fp);
  351. if (ferror(option_usage_fp) != 0)
  352. fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stderr)
  353. ? zstderr_name : zstdout_name);
  354. }
  355. static void
  356. print_one_paragraph(char const * text, bool plain, FILE * fp)
  357. {
  358. if (plain) {
  359. #ifdef ENABLE_NLS
  360. #ifdef HAVE_LIBINTL_H
  361. #ifdef DEBUG_ENABLED
  362. #undef gettext
  363. #endif
  364. char * buf = dgettext("libopts", text);
  365. if (buf == text)
  366. text = gettext(text);
  367. #endif /* HAVE_LIBINTL_H */
  368. #endif /* ENABLE_NLS */
  369. fputs(text, fp);
  370. }
  371. else {
  372. char const * t = optionQuoteString(text, LINE_SPLICE);
  373. fprintf(fp, PUTS_FMT, t);
  374. AGFREE(t);
  375. }
  376. }
  377. /*=export_func optionPrintParagraphs
  378. * private:
  379. *
  380. * what: Print a paragraph of usage text
  381. * arg: + char const * + text + a block of text that has bee i18n-ed +
  382. * arg: + bool + plain + false -> wrap text in fputs() +
  383. * arg: + FILE * + fp + the stream file pointer for output +
  384. *
  385. * doc:
  386. * This procedure is called in two contexts: when a full or short usage text
  387. * has been provided for display, and when autogen is assembling a list of
  388. * translatable texts in the optmain.tlib template. In the former case, \a
  389. * plain is set to \a true, otherwise \a false.
  390. *
  391. * Anything less than 256 characters in size is printed as a single unit.
  392. * Otherwise, paragraphs are detected. A paragraph break is defined as just
  393. * before a non-empty line preceded by two newlines or a line that starts
  394. * with at least one space character but fewer than 8 space characters.
  395. * Lines indented with tabs or more than 7 spaces are considered continuation
  396. * lines.
  397. *
  398. * If 'plain' is true, we are emitting text for a user to see. So, if it is
  399. * true and NLS is not enabled, then just write the whole thing at once.
  400. =*/
  401. void
  402. optionPrintParagraphs(char const * text, bool plain, FILE * fp)
  403. {
  404. size_t len = strlen(text);
  405. char * buf;
  406. #ifndef ENABLE_NLS
  407. if (plain || (len < 256))
  408. #else
  409. if (len < 256)
  410. #endif
  411. {
  412. print_one_paragraph(text, plain, fp);
  413. return;
  414. }
  415. AGDUPSTR(buf, text, "ppara");
  416. text = buf;
  417. for (;;) {
  418. char * scan;
  419. if (len < 256) {
  420. done:
  421. print_one_paragraph(buf, plain, fp);
  422. break;
  423. }
  424. scan = buf;
  425. try_longer:
  426. scan = strchr(scan, NL);
  427. if (scan == NULL)
  428. goto done;
  429. if ((scan - buf) < 40) {
  430. scan++;
  431. goto try_longer;
  432. }
  433. scan++;
  434. if ((! isspace((int)*scan)) || (*scan == HT))
  435. /*
  436. * line starts with tab or non-whitespace --> continuation
  437. */
  438. goto try_longer;
  439. if (*scan == NL) {
  440. /*
  441. * Double newline -> paragraph break
  442. * Include all newlines in current paragraph.
  443. */
  444. while (*++scan == NL) /*continue*/;
  445. } else {
  446. char * p = scan;
  447. int sp_ct = 0;
  448. while (*p == ' ') {
  449. if (++sp_ct >= 8) {
  450. /*
  451. * Too many spaces --> continuation line
  452. */
  453. scan = p;
  454. goto try_longer;
  455. }
  456. p++;
  457. }
  458. }
  459. /*
  460. * "scan" points to the first character of a paragraph or the
  461. * terminating NUL byte.
  462. */
  463. {
  464. char svch = *scan;
  465. *scan = NUL;
  466. print_one_paragraph(buf, plain, fp);
  467. len -= scan - buf;
  468. if (len <= 0)
  469. break;
  470. *scan = svch;
  471. buf = scan;
  472. }
  473. }
  474. AGFREE(text);
  475. }
  476. /*=export_func optionUsage
  477. * private:
  478. *
  479. * what: Print usage text
  480. * arg: + tOptions * + opts + program options descriptor +
  481. * arg: + int + exitCode + exit code for calling exit(3) +
  482. *
  483. * doc:
  484. * This routine will print usage in both GNU-standard and AutoOpts-expanded
  485. * formats. The descriptor specifies the default, but AUTOOPTS_USAGE will
  486. * over-ride this, providing the value of it is set to either "gnu" or
  487. * "autoopts". This routine will @strong{not} return.
  488. *
  489. * If "exitCode" is "AO_EXIT_REQ_USAGE" (normally 64), then output will to
  490. * to stdout and the actual exit code will be "EXIT_SUCCESS".
  491. =*/
  492. void
  493. optionUsage(tOptions * opts, int usage_exit_code)
  494. {
  495. int exit_code = (usage_exit_code == AO_EXIT_REQ_USAGE)
  496. ? EXIT_SUCCESS : usage_exit_code;
  497. displayEnum = false;
  498. set_usage_flags(opts, NULL);
  499. /*
  500. * Paged usage will preset option_usage_fp to an output file.
  501. * If it hasn't already been set, then set it to standard output
  502. * on successful exit (help was requested), otherwise error out.
  503. *
  504. * Test the version before obtaining pzFullUsage or pzShortUsage.
  505. * These fields do not exist before revision 30.
  506. */
  507. {
  508. char const * pz;
  509. if (exit_code == EXIT_SUCCESS) {
  510. pz = (opts->structVersion >= 30 * 4096)
  511. ? opts->pzFullUsage : NULL;
  512. if (option_usage_fp == NULL)
  513. option_usage_fp = print_exit ? stderr : stdout;
  514. } else {
  515. pz = (opts->structVersion >= 30 * 4096)
  516. ? opts->pzShortUsage : NULL;
  517. if (option_usage_fp == NULL)
  518. option_usage_fp = stderr;
  519. }
  520. if (((opts->fOptSet & OPTPROC_COMPUTE) == 0) && (pz != NULL)) {
  521. if ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
  522. optionPrintParagraphs(pz, true, option_usage_fp);
  523. else
  524. fputs(pz, option_usage_fp);
  525. goto flush_and_exit;
  526. }
  527. }
  528. fprintf(option_usage_fp, opts->pzUsageTitle, opts->pzProgName);
  529. if ((exit_code == EXIT_SUCCESS) ||
  530. (! skip_misuse_usage(opts)))
  531. print_usage_details(opts, usage_exit_code);
  532. else
  533. print_offer_usage(opts);
  534. flush_and_exit:
  535. fflush(option_usage_fp);
  536. if (ferror(option_usage_fp) != 0)
  537. fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stdout)
  538. ? zstdout_name : zstderr_name);
  539. option_exits(exit_code);
  540. }
  541. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  542. * PER OPTION TYPE USAGE INFORMATION
  543. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  544. /**
  545. * print option conflicts.
  546. *
  547. * @param opts the program option descriptor
  548. * @param od the option descriptor
  549. */
  550. static void
  551. prt_conflicts(tOptions * opts, tOptDesc * od)
  552. {
  553. const int * opt_no;
  554. fputs(zTabHyp + tab_skip_ct, option_usage_fp);
  555. /*
  556. * REQUIRED:
  557. */
  558. if (od->pOptMust != NULL) {
  559. opt_no = od->pOptMust;
  560. if (opt_no[1] == NO_EQUIVALENT) {
  561. fprintf(option_usage_fp, zReqOne,
  562. opts->pOptDesc[*opt_no].pz_Name);
  563. } else {
  564. fputs(zReqThese, option_usage_fp);
  565. for (;;) {
  566. fprintf(option_usage_fp, zTabout + tab_skip_ct,
  567. opts->pOptDesc[*opt_no].pz_Name);
  568. if (*++opt_no == NO_EQUIVALENT)
  569. break;
  570. }
  571. }
  572. if (od->pOptCant != NULL)
  573. fputs(zTabHypAnd + tab_skip_ct, option_usage_fp);
  574. }
  575. /*
  576. * CONFLICTS:
  577. */
  578. if (od->pOptCant == NULL)
  579. return;
  580. opt_no = od->pOptCant;
  581. if (opt_no[1] == NO_EQUIVALENT) {
  582. fprintf(option_usage_fp, zProhibOne,
  583. opts->pOptDesc[*opt_no].pz_Name);
  584. return;
  585. }
  586. fputs(zProhib, option_usage_fp);
  587. for (;;) {
  588. fprintf(option_usage_fp, zTabout + tab_skip_ct,
  589. opts->pOptDesc[*opt_no].pz_Name);
  590. if (*++opt_no == NO_EQUIVALENT)
  591. break;
  592. }
  593. }
  594. /**
  595. * Print the usage information for a single vendor option.
  596. *
  597. * @param[in] opts the program option descriptor
  598. * @param[in] od the option descriptor
  599. * @param[in] argtp names of the option argument types
  600. * @param[in] usefmt format for primary usage line
  601. */
  602. static void
  603. prt_one_vendor(tOptions * opts, tOptDesc * od,
  604. arg_types_t * argtp, char const * usefmt)
  605. {
  606. prt_preamble(opts, od, argtp);
  607. {
  608. char z[ 80 ];
  609. char const * pzArgType;
  610. /*
  611. * Determine the argument type string first on its usage, then,
  612. * when the option argument is required, base the type string on the
  613. * argument type.
  614. */
  615. if (od->fOptState & OPTST_ARG_OPTIONAL) {
  616. pzArgType = argtp->pzOpt;
  617. } else switch (OPTST_GET_ARGTYPE(od->fOptState)) {
  618. case OPARG_TYPE_NONE: pzArgType = argtp->pzNo; break;
  619. case OPARG_TYPE_ENUMERATION: pzArgType = argtp->pzKey; break;
  620. case OPARG_TYPE_FILE: pzArgType = argtp->pzFile; break;
  621. case OPARG_TYPE_MEMBERSHIP: pzArgType = argtp->pzKeyL; break;
  622. case OPARG_TYPE_BOOLEAN: pzArgType = argtp->pzBool; break;
  623. case OPARG_TYPE_NUMERIC: pzArgType = argtp->pzNum; break;
  624. case OPARG_TYPE_HIERARCHY: pzArgType = argtp->pzNest; break;
  625. case OPARG_TYPE_STRING: pzArgType = argtp->pzStr; break;
  626. case OPARG_TYPE_TIME: pzArgType = argtp->pzTime; break;
  627. default: goto bogus_desc;
  628. }
  629. pzArgType = SPN_WHITESPACE_CHARS(pzArgType);
  630. if (*pzArgType == NUL)
  631. snprintf(z, sizeof(z), "%s", od->pz_Name);
  632. else
  633. snprintf(z, sizeof(z), "%s=%s", od->pz_Name, pzArgType);
  634. fprintf(option_usage_fp, usefmt, z, od->pzText);
  635. switch (OPTST_GET_ARGTYPE(od->fOptState)) {
  636. case OPARG_TYPE_ENUMERATION:
  637. case OPARG_TYPE_MEMBERSHIP:
  638. displayEnum = (od->pOptProc != NULL) ? true : displayEnum;
  639. }
  640. }
  641. return;
  642. bogus_desc:
  643. fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name);
  644. ao_bug(zbad_arg_type_msg);
  645. }
  646. /**
  647. * Print the long options processed with "-W". These options will be the
  648. * ones that do *not* have flag characters.
  649. *
  650. * @param opts the program option descriptor
  651. * @param title the title for the options
  652. */
  653. static void
  654. prt_vendor_opts(tOptions * opts, char const * title)
  655. {
  656. static unsigned int const not_vended_mask =
  657. OPTST_NO_USAGE_MASK | OPTST_DOCUMENT;
  658. static char const vfmtfmt[] = "%%-%us %%s\n";
  659. char vfmt[sizeof(vfmtfmt)];
  660. /*
  661. * Only handle client specified options. The "vendor option" follows
  662. * "presetOptCt", so we won't loop/recurse indefinitely.
  663. */
  664. int ct = opts->presetOptCt;
  665. tOptDesc * od = opts->pOptDesc;
  666. fprintf(option_usage_fp, zTabout + tab_skip_ct, zVendOptsAre);
  667. {
  668. size_t nmlen = 0;
  669. do {
  670. size_t l;
  671. if ( ((od->fOptState & not_vended_mask) != 0)
  672. || GRAPH_CH(od->optValue))
  673. continue;
  674. l = strlen(od->pz_Name);
  675. if (l > nmlen) nmlen = l;
  676. } while (od++, (--ct > 0));
  677. snprintf(vfmt, sizeof(vfmt), vfmtfmt, (unsigned int)nmlen + 4);
  678. }
  679. if (tab_skip_ct > 0)
  680. tab_skip_ct--;
  681. ct = opts->presetOptCt;
  682. od = opts->pOptDesc;
  683. do {
  684. if ( ((od->fOptState & not_vended_mask) != 0)
  685. || GRAPH_CH(od->optValue))
  686. continue;
  687. prt_one_vendor(opts, od, &argTypes, vfmt);
  688. prt_extd_usage(opts, od, title);
  689. } while (od++, (--ct > 0));
  690. /* no need to restore "tab_skip_ct" - options are done now */
  691. }
  692. /**
  693. * Print extended usage. Usage/help was requested.
  694. *
  695. * @param opts the program option descriptor
  696. * @param od the option descriptor
  697. * @param title the title for the options
  698. */
  699. static void
  700. prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title)
  701. {
  702. if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0)
  703. && (od->optActualValue == VENDOR_OPTION_VALUE)) {
  704. prt_vendor_opts(opts, title);
  705. return;
  706. }
  707. /*
  708. * IF there are option conflicts or dependencies,
  709. * THEN print them here.
  710. */
  711. if ((od->pOptMust != NULL) || (od->pOptCant != NULL))
  712. prt_conflicts(opts, od);
  713. /*
  714. * IF there is a disablement string
  715. * THEN print the disablement info
  716. */
  717. if (od->pz_DisableName != NULL )
  718. fprintf(option_usage_fp, zDis + tab_skip_ct, od->pz_DisableName);
  719. /*
  720. * Check for argument types that have callbacks with magical properties
  721. */
  722. switch (OPTST_GET_ARGTYPE(od->fOptState)) {
  723. case OPARG_TYPE_NUMERIC:
  724. /*
  725. * IF the numeric option has a special callback,
  726. * THEN call it, requesting the range or other special info
  727. */
  728. if ( (od->pOptProc != NULL)
  729. && (od->pOptProc != optionNumericVal) ) {
  730. (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
  731. }
  732. break;
  733. case OPARG_TYPE_FILE:
  734. (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
  735. break;
  736. }
  737. /*
  738. * IF the option defaults to being enabled,
  739. * THEN print that out
  740. */
  741. if (od->fOptState & OPTST_INITENABLED)
  742. fputs(zEnab + tab_skip_ct, option_usage_fp);
  743. /*
  744. * IF the option is in an equivalence class
  745. * AND not the designated lead
  746. * THEN print equivalence and leave it at that.
  747. */
  748. if ( (od->optEquivIndex != NO_EQUIVALENT)
  749. && (od->optEquivIndex != od->optActualIndex ) ) {
  750. fprintf(option_usage_fp, zalt_opt + tab_skip_ct,
  751. opts->pOptDesc[ od->optEquivIndex ].pz_Name);
  752. return;
  753. }
  754. /*
  755. * IF this particular option can NOT be preset
  756. * AND some form of presetting IS allowed,
  757. * AND it is not an auto-managed option (e.g. --help, et al.)
  758. * THEN advise that this option may not be preset.
  759. */
  760. if ( ((od->fOptState & OPTST_NO_INIT) != 0)
  761. && ( (opts->papzHomeList != NULL)
  762. || (opts->pzPROGNAME != NULL)
  763. )
  764. && (od->optIndex < opts->presetOptCt)
  765. )
  766. fputs(zNoPreset + tab_skip_ct, option_usage_fp);
  767. /*
  768. * Print the appearance requirements.
  769. */
  770. if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_MEMBERSHIP)
  771. fputs(zMembers + tab_skip_ct, option_usage_fp);
  772. else switch (od->optMinCt) {
  773. case 1:
  774. case 0:
  775. switch (od->optMaxCt) {
  776. case 0: fputs(zPreset + tab_skip_ct, option_usage_fp); break;
  777. case NOLIMIT: fputs(zNoLim + tab_skip_ct, option_usage_fp); break;
  778. case 1: break;
  779. /*
  780. * IF the max is more than one but limited, print "UP TO" message
  781. */
  782. default:
  783. fprintf(option_usage_fp, zUpTo + tab_skip_ct, od->optMaxCt); break;
  784. }
  785. break;
  786. default:
  787. /*
  788. * More than one is required. Print the range.
  789. */
  790. fprintf(option_usage_fp, zMust + tab_skip_ct,
  791. od->optMinCt, od->optMaxCt);
  792. }
  793. if ( NAMED_OPTS(opts)
  794. && (opts->specOptIdx.default_opt == od->optIndex))
  795. fputs(zDefaultOpt + tab_skip_ct, option_usage_fp);
  796. }
  797. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  798. /**
  799. * Figure out where all the initialization files might live. This requires
  800. * translating some environment variables and testing to see if a name is a
  801. * directory or a file. It's squishy, but important to tell users how to
  802. * find these files.
  803. *
  804. * @param[in] papz search path
  805. * @param[out] ini_file an output buffer of AG_PATH_MAX+1 bytes
  806. * @param[in] path_nm the name of the file we're hunting for
  807. */
  808. static void
  809. prt_ini_list(char const * const * papz, char const * ini_file,
  810. char const * path_nm)
  811. {
  812. char pth_buf[AG_PATH_MAX+1];
  813. fputs(zPresetIntro, option_usage_fp);
  814. for (;;) {
  815. char const * path = *(papz++);
  816. char const * nm_buf = pth_buf;
  817. if (path == NULL)
  818. break;
  819. /*
  820. * Ignore any invalid paths
  821. */
  822. if (! optionMakePath(pth_buf, (int)sizeof(pth_buf), path, path_nm))
  823. nm_buf = path;
  824. /*
  825. * Expand paths that are relative to the executable or installation
  826. * directories. Leave alone paths that use environment variables.
  827. */
  828. else if ((*path == '$')
  829. && ((path[1] == '$') || (path[1] == '@')))
  830. path = nm_buf;
  831. /*
  832. * Print the name of the "homerc" file. If the "rcfile" name is
  833. * not empty, we may or may not print that, too...
  834. */
  835. fprintf(option_usage_fp, zPathFmt, path);
  836. if (*ini_file != NUL) {
  837. struct stat sb;
  838. /*
  839. * IF the "homerc" file is a directory,
  840. * then append the "rcfile" name.
  841. */
  842. if ((stat(nm_buf, &sb) == 0) && S_ISDIR(sb.st_mode)) {
  843. fputc(DIRCH, option_usage_fp);
  844. fputs(ini_file, option_usage_fp);
  845. }
  846. }
  847. fputc(NL, option_usage_fp);
  848. }
  849. }
  850. /**
  851. * Print the usage line preamble text
  852. *
  853. * @param opts the program option descriptor
  854. * @param od the option descriptor
  855. * @param at names of the option argument types
  856. */
  857. static void
  858. prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at)
  859. {
  860. /*
  861. * Flag prefix: IF no flags at all, then omit it. If not printable
  862. * (not allowed for this option), then blank, else print it.
  863. * Follow it with a comma if we are doing GNU usage and long
  864. * opts are to be printed too.
  865. */
  866. if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0)
  867. fputs(at->pzSpc, option_usage_fp);
  868. else if (! GRAPH_CH(od->optValue)) {
  869. if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
  870. == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
  871. fputc(' ', option_usage_fp);
  872. fputs(at->pzNoF, option_usage_fp);
  873. } else {
  874. fprintf(option_usage_fp, " -%c", od->optValue);
  875. if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
  876. == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
  877. fputs(", ", option_usage_fp);
  878. }
  879. }
  880. /**
  881. * Print the usage information for a single option.
  882. *
  883. * @param opts the program option descriptor
  884. * @param od the option descriptor
  885. * @param at names of the option argument types
  886. */
  887. static void
  888. prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at)
  889. {
  890. prt_preamble(opts, od, at);
  891. {
  892. char z[80];
  893. char const * atyp;
  894. /*
  895. * Determine the argument type string first on its usage, then,
  896. * when the option argument is required, base the type string on the
  897. * argument type.
  898. */
  899. if (od->fOptState & OPTST_ARG_OPTIONAL) {
  900. atyp = at->pzOpt;
  901. } else switch (OPTST_GET_ARGTYPE(od->fOptState)) {
  902. case OPARG_TYPE_NONE: atyp = at->pzNo; break;
  903. case OPARG_TYPE_ENUMERATION: atyp = at->pzKey; break;
  904. case OPARG_TYPE_FILE: atyp = at->pzFile; break;
  905. case OPARG_TYPE_MEMBERSHIP: atyp = at->pzKeyL; break;
  906. case OPARG_TYPE_BOOLEAN: atyp = at->pzBool; break;
  907. case OPARG_TYPE_NUMERIC: atyp = at->pzNum; break;
  908. case OPARG_TYPE_HIERARCHY: atyp = at->pzNest; break;
  909. case OPARG_TYPE_STRING: atyp = at->pzStr; break;
  910. case OPARG_TYPE_TIME: atyp = at->pzTime; break;
  911. default: goto bogus_desc;
  912. }
  913. #ifdef _WIN32
  914. if (at->pzOptFmt == zGnuOptFmt)
  915. snprintf(z, sizeof(z), "--%s%s", od->pz_Name, atyp);
  916. else if (at->pzOptFmt == zGnuOptFmt + 2)
  917. snprintf(z, sizeof(z), "%s%s", od->pz_Name, atyp);
  918. else
  919. #endif
  920. snprintf(z, sizeof(z), at->pzOptFmt, atyp, od->pz_Name,
  921. (od->optMinCt != 0) ? at->pzReq : at->pzOpt);
  922. fprintf(option_usage_fp, line_fmt_buf, z, od->pzText);
  923. switch (OPTST_GET_ARGTYPE(od->fOptState)) {
  924. case OPARG_TYPE_ENUMERATION:
  925. case OPARG_TYPE_MEMBERSHIP:
  926. displayEnum = (od->pOptProc != NULL) ? true : displayEnum;
  927. }
  928. }
  929. return;
  930. bogus_desc:
  931. fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name);
  932. option_exits(EX_SOFTWARE);
  933. }
  934. /**
  935. * Print out the usage information for just the options.
  936. */
  937. static void
  938. prt_opt_usage(tOptions * opts, int ex_code, char const * title)
  939. {
  940. int ct = opts->optCt;
  941. int optNo = 0;
  942. tOptDesc * od = opts->pOptDesc;
  943. int docCt = 0;
  944. do {
  945. /*
  946. * no usage --> disallowed on command line (OPTST_NO_COMMAND), or
  947. * deprecated -- strongly discouraged (OPTST_DEPRECATED), or
  948. * compiled out of current object code (OPTST_OMITTED)
  949. */
  950. if ((od->fOptState & OPTST_NO_USAGE_MASK) != 0) {
  951. /*
  952. * IF this is a compiled-out option
  953. * *AND* usage was requested with "omitted-usage"
  954. * *AND* this is NOT abbreviated usage
  955. * THEN display this option.
  956. */
  957. if ( (od->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
  958. && (od->pz_Name != NULL)
  959. && (ex_code == EXIT_SUCCESS)) {
  960. char const * why_pz =
  961. (od->pzText == NULL) ? zDisabledWhy : od->pzText;
  962. prt_preamble(opts, od, &argTypes);
  963. fprintf(option_usage_fp, zDisabledOpt, od->pz_Name, why_pz);
  964. }
  965. continue;
  966. }
  967. if ((od->fOptState & OPTST_DOCUMENT) != 0) {
  968. if (ex_code == EXIT_SUCCESS) {
  969. fprintf(option_usage_fp, argTypes.pzBrk, od->pzText,
  970. title);
  971. docCt++;
  972. }
  973. continue;
  974. }
  975. /* Skip name only options when we have a vendor option */
  976. if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0)
  977. && (! GRAPH_CH(od->optValue)))
  978. continue;
  979. /*
  980. * IF this is the first auto-opt maintained option
  981. * *AND* we are doing a full help
  982. * *AND* there are documentation options
  983. * *AND* the last one was not a doc option,
  984. * THEN document that the remaining options are not user opts
  985. */
  986. if ((docCt > 0) && (ex_code == EXIT_SUCCESS)) {
  987. if (opts->presetOptCt == optNo) {
  988. if ((od[-1].fOptState & OPTST_DOCUMENT) == 0)
  989. fprintf(option_usage_fp, argTypes.pzBrk, zAuto, title);
  990. } else if ((ct == 1) &&
  991. (opts->fOptSet & OPTPROC_VENDOR_OPT))
  992. fprintf(option_usage_fp, argTypes.pzBrk, zVendIntro, title);
  993. }
  994. prt_one_usage(opts, od, &argTypes);
  995. /*
  996. * IF we were invoked because of the --help option,
  997. * THEN print all the extra info
  998. */
  999. if (ex_code == EXIT_SUCCESS)
  1000. prt_extd_usage(opts, od, title);
  1001. } while (od++, optNo++, (--ct > 0));
  1002. fputc(NL, option_usage_fp);
  1003. }
  1004. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  1005. /**
  1006. * Print program details.
  1007. * @param[in] opts the program option descriptor
  1008. */
  1009. static void
  1010. prt_prog_detail(tOptions * opts)
  1011. {
  1012. bool need_intro = (opts->papzHomeList == NULL);
  1013. /*
  1014. * Display all the places we look for config files, if we have
  1015. * a list of directories to search.
  1016. */
  1017. if (! need_intro)
  1018. prt_ini_list(opts->papzHomeList, opts->pzRcName, opts->pzProgPath);
  1019. /*
  1020. * Let the user know about environment variable settings
  1021. */
  1022. if ((opts->fOptSet & OPTPROC_ENVIRON) != 0) {
  1023. if (need_intro)
  1024. fputs(zPresetIntro, option_usage_fp);
  1025. fprintf(option_usage_fp, zExamineFmt, opts->pzPROGNAME);
  1026. }
  1027. /*
  1028. * IF we found an enumeration,
  1029. * THEN hunt for it again. Call the handler proc with a NULL
  1030. * option struct pointer. That tells it to display the keywords.
  1031. */
  1032. if (displayEnum) {
  1033. int ct = opts->optCt;
  1034. int optNo = 0;
  1035. tOptDesc * od = opts->pOptDesc;
  1036. fputc(NL, option_usage_fp);
  1037. fflush(option_usage_fp);
  1038. do {
  1039. switch (OPTST_GET_ARGTYPE(od->fOptState)) {
  1040. case OPARG_TYPE_ENUMERATION:
  1041. case OPARG_TYPE_MEMBERSHIP:
  1042. (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
  1043. }
  1044. } while (od++, optNo++, (--ct > 0));
  1045. }
  1046. /*
  1047. * If there is a detail string, now is the time for that.
  1048. */
  1049. if (opts->pzDetail != NULL)
  1050. fputs(opts->pzDetail, option_usage_fp);
  1051. }
  1052. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  1053. *
  1054. * OPTION LINE FORMATTING SETUP
  1055. *
  1056. * The "OptFmt" formats receive three arguments:
  1057. * 1. the type of the option's argument
  1058. * 2. the long name of the option
  1059. * 3. "YES" or "no ", depending on whether or not the option must appear
  1060. * on the command line.
  1061. * These formats are used immediately after the option flag (if used) has
  1062. * been printed.
  1063. *
  1064. * Set up the formatting for GNU-style output
  1065. */
  1066. static int
  1067. setGnuOptFmts(tOptions * opts, char const ** ptxt)
  1068. {
  1069. static char const zOneSpace[] = " ";
  1070. int flen = 22;
  1071. *ptxt = zNoRq_ShrtTtl;
  1072. argTypes.pzStr = zGnuStrArg;
  1073. argTypes.pzReq = zOneSpace;
  1074. argTypes.pzNum = zGnuNumArg;
  1075. argTypes.pzKey = zGnuKeyArg;
  1076. argTypes.pzKeyL = zGnuKeyLArg;
  1077. argTypes.pzTime = zGnuTimeArg;
  1078. argTypes.pzFile = zGnuFileArg;
  1079. argTypes.pzBool = zGnuBoolArg;
  1080. argTypes.pzNest = zGnuNestArg;
  1081. argTypes.pzOpt = zGnuOptArg;
  1082. argTypes.pzNo = zOneSpace;
  1083. argTypes.pzBrk = zGnuBreak;
  1084. argTypes.pzNoF = zSixSpaces;
  1085. argTypes.pzSpc = zThreeSpaces;
  1086. switch (opts->fOptSet & OPTPROC_L_N_S) {
  1087. case OPTPROC_L_N_S: argTypes.pzOptFmt = zGnuOptFmt; break;
  1088. case OPTPROC_LONGOPT: argTypes.pzOptFmt = zGnuOptFmt; break;
  1089. case 0: argTypes.pzOptFmt = zGnuOptFmt + 2; break;
  1090. case OPTPROC_SHORTOPT:
  1091. argTypes.pzOptFmt = zShrtGnuOptFmt;
  1092. zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' ';
  1093. argTypes.pzOpt = " [arg]";
  1094. flen = 8;
  1095. break;
  1096. }
  1097. return flen;
  1098. }
  1099. /*
  1100. * Standard (AutoOpts normal) option line formatting
  1101. */
  1102. static int
  1103. setStdOptFmts(tOptions * opts, char const ** ptxt)
  1104. {
  1105. int flen = 0;
  1106. argTypes.pzStr = zStdStrArg;
  1107. argTypes.pzReq = zStdReqArg;
  1108. argTypes.pzNum = zStdNumArg;
  1109. argTypes.pzKey = zStdKeyArg;
  1110. argTypes.pzKeyL = zStdKeyLArg;
  1111. argTypes.pzTime = zStdTimeArg;
  1112. argTypes.pzFile = zStdFileArg;
  1113. argTypes.pzBool = zStdBoolArg;
  1114. argTypes.pzNest = zStdNestArg;
  1115. argTypes.pzOpt = zStdOptArg;
  1116. argTypes.pzNo = zStdNoArg;
  1117. argTypes.pzBrk = zStdBreak;
  1118. argTypes.pzNoF = zFiveSpaces;
  1119. argTypes.pzSpc = zTwoSpaces;
  1120. switch (opts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) {
  1121. case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT):
  1122. *ptxt = zNoRq_ShrtTtl;
  1123. argTypes.pzOptFmt = zNrmOptFmt;
  1124. flen = 19;
  1125. break;
  1126. case OPTPROC_NO_REQ_OPT:
  1127. *ptxt = zNoRq_NoShrtTtl;
  1128. argTypes.pzOptFmt = zNrmOptFmt;
  1129. flen = 19;
  1130. break;
  1131. case OPTPROC_SHORTOPT:
  1132. *ptxt = zReq_ShrtTtl;
  1133. argTypes.pzOptFmt = zReqOptFmt;
  1134. flen = 24;
  1135. break;
  1136. case 0:
  1137. *ptxt = zReq_NoShrtTtl;
  1138. argTypes.pzOptFmt = zReqOptFmt;
  1139. flen = 24;
  1140. }
  1141. return flen;
  1142. }
  1143. /** @}
  1144. *
  1145. * Local Variables:
  1146. * mode: C
  1147. * c-file-style: "stroustrup"
  1148. * indent-tabs-mode: nil
  1149. * End:
  1150. * end of autoopts/usage.c */