usage.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. /*
  2. * usage.c $Id: usage.c,v 4.11 2006/03/25 19:24:57 bkorb Exp $
  3. * Time-stamp: "2006-02-04 13:35:26 bkorb"
  4. *
  5. * This module implements the default usage procedure for
  6. * Automated Options. It may be overridden, of course.
  7. *
  8. * Sort options:
  9. --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \
  10. --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \
  11. --spac=2 --input=usage.c
  12. */
  13. /*
  14. * Automated Options copyright 1992-2006 Bruce Korb
  15. *
  16. * Automated Options is free software.
  17. * You may redistribute it and/or modify it under the terms of the
  18. * GNU General Public License, as published by the Free Software
  19. * Foundation; either version 2, or (at your option) any later version.
  20. *
  21. * Automated Options is distributed in the hope that it will be useful,
  22. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  23. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  24. * GNU General Public License for more details.
  25. *
  26. * You should have received a copy of the GNU General Public License
  27. * along with Automated Options. See the file "COPYING". If not,
  28. * write to: The Free Software Foundation, Inc.,
  29. * 51 Franklin Street, Fifth Floor,
  30. * Boston, MA 02110-1301, USA.
  31. *
  32. * As a special exception, Bruce Korb gives permission for additional
  33. * uses of the text contained in his release of AutoOpts.
  34. *
  35. * The exception is that, if you link the AutoOpts library with other
  36. * files to produce an executable, this does not by itself cause the
  37. * resulting executable to be covered by the GNU General Public License.
  38. * Your use of that executable is in no way restricted on account of
  39. * linking the AutoOpts library code into it.
  40. *
  41. * This exception does not however invalidate any other reasons why
  42. * the executable file might be covered by the GNU General Public License.
  43. *
  44. * This exception applies only to the code released by Bruce Korb under
  45. * the name AutoOpts. If you copy code from other sources under the
  46. * General Public License into a copy of AutoOpts, as the General Public
  47. * License permits, the exception does not apply to the code that you add
  48. * in this way. To avoid misleading anyone as to the status of such
  49. * modified files, you must delete this exception notice from them.
  50. *
  51. * If you write modifications of your own for AutoOpts, it is your choice
  52. * whether to permit this exception to apply to your modifications.
  53. * If you do not wish that, delete this exception notice.
  54. */
  55. #define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)
  56. static arg_types_t argTypes;
  57. FILE* option_usage_fp = NULL;
  58. static char zOptFmtLine[ 16 ];
  59. static ag_bool displayEnum;
  60. /* = = = START-STATIC-FORWARD = = = */
  61. /* static forward declarations maintained by :mkfwd */
  62. static ag_bool
  63. checkGNUUsage( tOptions* pOpts );
  64. static void
  65. printExtendedUsage(
  66. tOptions* pOptions,
  67. tOptDesc* pOD,
  68. arg_types_t* pAT );
  69. static void
  70. printInitList(
  71. tCC** papz,
  72. ag_bool* pInitIntro,
  73. tCC* pzRc,
  74. tCC* pzPN );
  75. static void
  76. printOneUsage(
  77. tOptions* pOptions,
  78. tOptDesc* pOD,
  79. arg_types_t* pAT );
  80. static void
  81. printOptionUsage(
  82. tOptions* pOpts,
  83. int ex_code,
  84. tCC* pOptTitle );
  85. static void
  86. printProgramDetails( tOptions* pOptions );
  87. static int
  88. setGnuOptFmts( tOptions* pOpts, tCC** ppT );
  89. static int
  90. setStdOptFmts( tOptions* pOpts, tCC** ppT );
  91. /* = = = END-STATIC-FORWARD = = = */
  92. /*
  93. * Figure out if we should try to format usage text sort-of like
  94. * the way many GNU programs do.
  95. */
  96. static ag_bool
  97. checkGNUUsage( tOptions* pOpts )
  98. {
  99. char* pz = getenv( "AUTOOPTS_USAGE" );
  100. if (pz == NULL)
  101. ;
  102. else if (streqvcmp( pz, "gnu" ) == 0)
  103. pOpts->fOptSet |= OPTPROC_GNUUSAGE;
  104. else if (streqvcmp( pz, "autoopts" ) == 0)
  105. pOpts->fOptSet &= ~OPTPROC_GNUUSAGE;
  106. return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? AG_TRUE : AG_FALSE;
  107. }
  108. /*=export_func optionOnlyUsage
  109. *
  110. * what: Print usage text for just the options
  111. * arg: + tOptions* + pOpts + program options descriptor +
  112. * arg: + int + ex_code + exit code for calling exit(3) +
  113. *
  114. * doc:
  115. * This routine will print only the usage for each option.
  116. * This function may be used when the emitted usage must incorporate
  117. * information not available to AutoOpts.
  118. =*/
  119. void
  120. optionOnlyUsage(
  121. tOptions* pOpts,
  122. int ex_code )
  123. {
  124. tCC* pOptTitle;
  125. /*
  126. * Determine which header and which option formatting strings to use
  127. */
  128. if (checkGNUUsage(pOpts)) {
  129. (void)setGnuOptFmts( pOpts, &pOptTitle );
  130. }
  131. else {
  132. (void)setStdOptFmts( pOpts, &pOptTitle );
  133. }
  134. printOptionUsage( pOpts, ex_code, pOptTitle );
  135. }
  136. /*=export_func optionUsage
  137. * private:
  138. *
  139. * what: Print usage text
  140. * arg: + tOptions* + pOptions + program options descriptor +
  141. * arg: + int + exitCode + exit code for calling exit(3) +
  142. *
  143. * doc:
  144. * This routine will print usage in both GNU-standard and AutoOpts-expanded
  145. * formats. The descriptor specifies the default, but AUTOOPTS_USAGE will
  146. * over-ride this, providing the value of it is set to either "gnu" or
  147. * "autoopts". This routine will @strong{not} return.
  148. =*/
  149. void
  150. optionUsage(
  151. tOptions* pOptions,
  152. int exitCode )
  153. {
  154. displayEnum = AG_FALSE;
  155. /*
  156. * Paged usage will preset option_usage_fp to an output file.
  157. * If it hasn't already been set, then set it to standard output
  158. * on successful exit (help was requested), otherwise error out.
  159. */
  160. if (option_usage_fp == NULL)
  161. option_usage_fp = (exitCode != EXIT_SUCCESS) ? stderr : stdout;
  162. fprintf( option_usage_fp, pOptions->pzUsageTitle, pOptions->pzProgName );
  163. {
  164. tCC* pOptTitle;
  165. /*
  166. * Determine which header and which option formatting strings to use
  167. */
  168. if (checkGNUUsage(pOptions)) {
  169. int flen = setGnuOptFmts( pOptions, &pOptTitle );
  170. sprintf( zOptFmtLine, zFmtFmt, flen );
  171. fputc( '\n', option_usage_fp );
  172. }
  173. else {
  174. int flen = setStdOptFmts( pOptions, &pOptTitle );
  175. sprintf( zOptFmtLine, zFmtFmt, flen );
  176. /*
  177. * When we exit with EXIT_SUCCESS and the first option is a doc
  178. * option, we do *NOT* want to emit the column headers.
  179. * Otherwise, we do.
  180. */
  181. if ( (exitCode != EXIT_SUCCESS)
  182. || ((pOptions->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) )
  183. fputs( pOptTitle, option_usage_fp );
  184. }
  185. printOptionUsage( pOptions, exitCode, pOptTitle );
  186. }
  187. /*
  188. * Describe the mechanics of denoting the options
  189. */
  190. switch (pOptions->fOptSet & OPTPROC_L_N_S) {
  191. case OPTPROC_L_N_S: fputs( zFlagOkay, option_usage_fp ); break;
  192. case OPTPROC_SHORTOPT: break;
  193. case OPTPROC_LONGOPT: fputs( zNoFlags, option_usage_fp ); break;
  194. case 0: fputs( zOptsOnly, option_usage_fp ); break;
  195. }
  196. if ((pOptions->fOptSet & OPTPROC_NUM_OPT) != 0) {
  197. fputs( zNumberOpt, option_usage_fp );
  198. }
  199. if ((pOptions->fOptSet & OPTPROC_REORDER) != 0) {
  200. fputs( zReorder, option_usage_fp );
  201. }
  202. if (pOptions->pzExplain != NULL)
  203. fputs( pOptions->pzExplain, option_usage_fp );
  204. /*
  205. * IF the user is asking for help (thus exiting with SUCCESS),
  206. * THEN see what additional information we can provide.
  207. */
  208. if (exitCode == EXIT_SUCCESS)
  209. printProgramDetails( pOptions );
  210. if (pOptions->pzBugAddr != NULL)
  211. fprintf( option_usage_fp, zPlsSendBugs, pOptions->pzBugAddr );
  212. fflush( option_usage_fp );
  213. exit( exitCode );
  214. }
  215. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  216. *
  217. * PER OPTION TYPE USAGE INFORMATION
  218. */
  219. static void
  220. printExtendedUsage(
  221. tOptions* pOptions,
  222. tOptDesc* pOD,
  223. arg_types_t* pAT )
  224. {
  225. /*
  226. * IF there are option conflicts or dependencies,
  227. * THEN print them here.
  228. */
  229. if ( (pOD->pOptMust != NULL)
  230. || (pOD->pOptCant != NULL) ) {
  231. fputs( zTabHyp, option_usage_fp );
  232. /*
  233. * DEPENDENCIES:
  234. */
  235. if (pOD->pOptMust != NULL) {
  236. const int* pOptNo = pOD->pOptMust;
  237. fputs( zReqThese, option_usage_fp );
  238. for (;;) {
  239. fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
  240. *pOptNo ].pz_Name );
  241. if (*++pOptNo == NO_EQUIVALENT)
  242. break;
  243. }
  244. if (pOD->pOptCant != NULL)
  245. fputs( zTabHypAnd, option_usage_fp );
  246. }
  247. /*
  248. * CONFLICTS:
  249. */
  250. if (pOD->pOptCant != NULL) {
  251. const int* pOptNo = pOD->pOptCant;
  252. fputs( zProhib, option_usage_fp );
  253. for (;;) {
  254. fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
  255. *pOptNo ].pz_Name );
  256. if (*++pOptNo == NO_EQUIVALENT)
  257. break;
  258. }
  259. }
  260. }
  261. /*
  262. * IF there is a disablement string
  263. * THEN print the disablement info
  264. */
  265. if (pOD->pz_DisableName != NULL )
  266. fprintf( option_usage_fp, zDis, pOD->pz_DisableName );
  267. /*
  268. * IF the numeric option has a special callback,
  269. * THEN call it, requesting the range or other special info
  270. */
  271. if ( (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC)
  272. && (pOD->pOptProc != NULL)
  273. && (pOD->pOptProc != optionNumericVal) ) {
  274. (*(pOD->pOptProc))( pOptions, NULL );
  275. }
  276. /*
  277. * IF the option defaults to being enabled,
  278. * THEN print that out
  279. */
  280. if (pOD->fOptState & OPTST_INITENABLED)
  281. fputs( zEnab, option_usage_fp );
  282. /*
  283. * IF the option is in an equivalence class
  284. * AND not the designated lead
  285. * THEN print equivalence and leave it at that.
  286. */
  287. if ( (pOD->optEquivIndex != NO_EQUIVALENT)
  288. && (pOD->optEquivIndex != pOD->optActualIndex ) ) {
  289. fprintf( option_usage_fp, zAlt,
  290. pOptions->pOptDesc[ pOD->optEquivIndex ].pz_Name );
  291. return;
  292. }
  293. /*
  294. * IF this particular option can NOT be preset
  295. * AND some form of presetting IS allowed,
  296. * THEN advise that this option may not be preset.
  297. */
  298. if ( ((pOD->fOptState & OPTST_NO_INIT) != 0)
  299. && ( (pOptions->papzHomeList != NULL)
  300. || (pOptions->pzPROGNAME != NULL)
  301. ) )
  302. fputs( zNoPreset, option_usage_fp );
  303. /*
  304. * Print the appearance requirements.
  305. */
  306. if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP)
  307. fputs( zMembers, option_usage_fp );
  308. else switch (pOD->optMinCt) {
  309. case 1:
  310. case 0:
  311. switch (pOD->optMaxCt) {
  312. case 0: fputs( zPreset, option_usage_fp ); break;
  313. case NOLIMIT: fputs( zNoLim, option_usage_fp ); break;
  314. case 1: break;
  315. /*
  316. * IF the max is more than one but limited, print "UP TO" message
  317. */
  318. default: fprintf( option_usage_fp, zUpTo, pOD->optMaxCt ); break;
  319. }
  320. break;
  321. default:
  322. /*
  323. * More than one is required. Print the range.
  324. */
  325. fprintf( option_usage_fp, zMust, pOD->optMinCt, pOD->optMaxCt );
  326. }
  327. if ( NAMED_OPTS( pOptions )
  328. && (pOptions->specOptIdx.default_opt == pOD->optIndex))
  329. fputs( zDefaultOpt, option_usage_fp );
  330. }
  331. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  332. *
  333. * Figure out where all the initialization files might live.
  334. * This requires translating some environment variables and
  335. * testing to see if a name is a directory or a file. It's
  336. * squishy, but important to tell users how to find these files.
  337. */
  338. static void
  339. printInitList(
  340. tCC** papz,
  341. ag_bool* pInitIntro,
  342. tCC* pzRc,
  343. tCC* pzPN )
  344. {
  345. char zPath[ MAXPATHLEN+1 ];
  346. if (papz == NULL)
  347. return;
  348. fputs( zPresetIntro, option_usage_fp );
  349. *pInitIntro = AG_FALSE;
  350. for (;;) {
  351. const char* pzPath = *(papz++);
  352. if (pzPath == NULL)
  353. break;
  354. if (optionMakePath( zPath, sizeof( zPath ), pzPath, pzPN ))
  355. pzPath = zPath;
  356. /*
  357. * Print the name of the "homerc" file. If the "rcfile" name is
  358. * not empty, we may or may not print that, too...
  359. */
  360. fprintf( option_usage_fp, zPathFmt, pzPath );
  361. if (*pzRc != NUL) {
  362. struct stat sb;
  363. /*
  364. * IF the "homerc" file is a directory,
  365. * then append the "rcfile" name.
  366. */
  367. if ( (stat( pzPath, &sb ) == 0)
  368. && S_ISDIR( sb.st_mode ) ) {
  369. fputc( '/', option_usage_fp );
  370. fputs( pzRc, option_usage_fp );
  371. }
  372. }
  373. fputc( '\n', option_usage_fp );
  374. }
  375. }
  376. /*
  377. * Print the usage information for a single option.
  378. */
  379. static void
  380. printOneUsage(
  381. tOptions* pOptions,
  382. tOptDesc* pOD,
  383. arg_types_t* pAT )
  384. {
  385. /*
  386. * Flag prefix: IF no flags at all, then omit it. If not printable
  387. * (not allowed for this option), then blank, else print it.
  388. * Follow it with a comma if we are doing GNU usage and long
  389. * opts are to be printed too.
  390. */
  391. if ((pOptions->fOptSet & OPTPROC_SHORTOPT) == 0)
  392. fputs( pAT->pzSpc, option_usage_fp );
  393. else if (! isgraph( pOD->optValue)) {
  394. if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
  395. == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
  396. fputc( ' ', option_usage_fp );
  397. fputs( pAT->pzNoF, option_usage_fp );
  398. } else {
  399. fprintf( option_usage_fp, " -%c", pOD->optValue );
  400. if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
  401. == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
  402. fputs( ", ", option_usage_fp );
  403. }
  404. {
  405. char z[ 80 ];
  406. tCC* pzArgType;
  407. /*
  408. * Determine the argument type string first on its usage, then,
  409. * when the option argument is required, base the type string on the
  410. * argument type.
  411. */
  412. if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NONE) {
  413. pzArgType = pAT->pzNo;
  414. } else if (pOD->fOptState & OPTST_ARG_OPTIONAL) {
  415. pzArgType = pAT->pzOpt;
  416. } else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
  417. case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey; break;
  418. case OPARG_TYPE_MEMBERSHIP: pzArgType = pAT->pzKeyL; break;
  419. case OPARG_TYPE_BOOLEAN: pzArgType = pAT->pzBool; break;
  420. case OPARG_TYPE_NUMERIC: pzArgType = pAT->pzNum; break;
  421. case OPARG_TYPE_HIERARCHY: pzArgType = pAT->pzNest; break;
  422. case OPARG_TYPE_STRING: pzArgType = pAT->pzStr; break;
  423. default: goto bogus_desc; break;
  424. }
  425. snprintf( z, sizeof(z), pAT->pzOptFmt, pzArgType, pOD->pz_Name,
  426. (pOD->optMinCt != 0) ? pAT->pzReq : pAT->pzOpt );
  427. fprintf( option_usage_fp, zOptFmtLine, z, pOD->pzText );
  428. switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
  429. case OPARG_TYPE_ENUMERATION:
  430. case OPARG_TYPE_MEMBERSHIP:
  431. displayEnum = (pOD->pOptProc != NULL) ? AG_TRUE : displayEnum;
  432. }
  433. }
  434. return;
  435. bogus_desc:
  436. fprintf( stderr, zInvalOptDesc, pOD->pz_Name );
  437. exit( EXIT_FAILURE );
  438. }
  439. /*
  440. * Print out the usage information for just the options.
  441. */
  442. static void
  443. printOptionUsage(
  444. tOptions* pOpts,
  445. int ex_code,
  446. tCC* pOptTitle )
  447. {
  448. int ct = pOpts->optCt;
  449. int optNo = 0;
  450. tOptDesc* pOD = pOpts->pOptDesc;
  451. int docCt = 0;
  452. do {
  453. if ((pOD->fOptState & OPTST_OMITTED) != 0)
  454. continue;
  455. if ((pOD->fOptState & OPTST_DOCUMENT) != 0) {
  456. if (ex_code == EXIT_SUCCESS) {
  457. fprintf(option_usage_fp, argTypes.pzBrk, pOD->pzText,
  458. pOptTitle);
  459. docCt++;
  460. }
  461. continue;
  462. }
  463. /*
  464. * IF this is the first auto-opt maintained option
  465. * *AND* we are doing a full help
  466. * *AND* there are documentation options
  467. * *AND* the last one was not a doc option,
  468. * THEN document that the remaining options are not user opts
  469. */
  470. if ( (pOpts->presetOptCt == optNo)
  471. && (ex_code == EXIT_SUCCESS)
  472. && (docCt > 0)
  473. && ((pOD[-1].fOptState & OPTST_DOCUMENT) == 0) )
  474. fprintf( option_usage_fp, argTypes.pzBrk, zAuto, pOptTitle );
  475. printOneUsage( pOpts, pOD, &argTypes );
  476. /*
  477. * IF we were invoked because of the --help option,
  478. * THEN print all the extra info
  479. */
  480. if (ex_code == EXIT_SUCCESS)
  481. printExtendedUsage( pOpts, pOD, &argTypes );
  482. } while (pOD++, optNo++, (--ct > 0));
  483. fputc( '\n', option_usage_fp );
  484. }
  485. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  486. *
  487. * PROGRAM DETAILS
  488. */
  489. static void
  490. printProgramDetails( tOptions* pOptions )
  491. {
  492. ag_bool initIntro = AG_TRUE;
  493. /*
  494. * Display all the places we look for config files
  495. */
  496. printInitList( pOptions->papzHomeList, &initIntro,
  497. pOptions->pzRcName, pOptions->pzProgPath );
  498. /*
  499. * Let the user know about environment variable settings
  500. */
  501. if ((pOptions->fOptSet & OPTPROC_ENVIRON) != 0) {
  502. if (initIntro)
  503. fputs( zPresetIntro, option_usage_fp );
  504. fprintf( option_usage_fp, zExamineFmt, pOptions->pzPROGNAME );
  505. }
  506. /*
  507. * IF we found an enumeration,
  508. * THEN hunt for it again. Call the handler proc with a NULL
  509. * option struct pointer. That tells it to display the keywords.
  510. */
  511. if (displayEnum) {
  512. int ct = pOptions->optCt;
  513. int optNo = 0;
  514. tOptDesc* pOD = pOptions->pOptDesc;
  515. fputc( '\n', option_usage_fp );
  516. fflush( option_usage_fp );
  517. do {
  518. switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
  519. case OPARG_TYPE_ENUMERATION:
  520. case OPARG_TYPE_MEMBERSHIP:
  521. (*(pOD->pOptProc))( NULL, pOD );
  522. }
  523. } while (pOD++, optNo++, (--ct > 0));
  524. }
  525. /*
  526. * If there is a detail string, now is the time for that.
  527. */
  528. if (pOptions->pzDetail != NULL)
  529. fputs( pOptions->pzDetail, option_usage_fp );
  530. }
  531. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  532. *
  533. * OPTION LINE FORMATTING SETUP
  534. *
  535. * The "OptFmt" formats receive three arguments:
  536. * 1. the type of the option's argument
  537. * 2. the long name of the option
  538. * 3. "YES" or "no ", depending on whether or not the option must appear
  539. * on the command line.
  540. * These formats are used immediately after the option flag (if used) has
  541. * been printed.
  542. *
  543. * Set up the formatting for GNU-style output
  544. */
  545. static int
  546. setGnuOptFmts( tOptions* pOpts, tCC** ppT )
  547. {
  548. int flen = 22;
  549. *ppT = zNoRq_ShrtTtl;
  550. argTypes.pzStr = zGnuStrArg;
  551. argTypes.pzReq = zOneSpace;
  552. argTypes.pzNum = zGnuNumArg;
  553. argTypes.pzKey = zGnuKeyArg;
  554. argTypes.pzKeyL = zGnuKeyLArg;
  555. argTypes.pzBool = zGnuBoolArg;
  556. argTypes.pzNest = zGnuNestArg;
  557. argTypes.pzOpt = zGnuOptArg;
  558. argTypes.pzNo = zOneSpace;
  559. argTypes.pzBrk = zGnuBreak;
  560. argTypes.pzNoF = zSixSpaces;
  561. argTypes.pzSpc = zThreeSpaces;
  562. switch (pOpts->fOptSet & OPTPROC_L_N_S) {
  563. case OPTPROC_L_N_S: argTypes.pzOptFmt = zGnuOptFmt; break;
  564. case OPTPROC_LONGOPT: argTypes.pzOptFmt = zGnuOptFmt; break;
  565. case 0: argTypes.pzOptFmt = zGnuOptFmt + 2; break;
  566. case OPTPROC_SHORTOPT:
  567. argTypes.pzOptFmt = zShrtGnuOptFmt;
  568. zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' ';
  569. argTypes.pzOpt = " [arg]";
  570. flen = 8;
  571. break;
  572. }
  573. return flen;
  574. }
  575. /*
  576. * Standard (AutoOpts normal) option line formatting
  577. */
  578. static int
  579. setStdOptFmts( tOptions* pOpts, tCC** ppT )
  580. {
  581. int flen = 0;
  582. argTypes.pzStr = zStdStrArg;
  583. argTypes.pzReq = zStdReqArg;
  584. argTypes.pzNum = zStdNumArg;
  585. argTypes.pzKey = zStdKeyArg;
  586. argTypes.pzKeyL = zStdKeyLArg;
  587. argTypes.pzBool = zStdBoolArg;
  588. argTypes.pzNest = zStdNestArg;
  589. argTypes.pzOpt = zStdOptArg;
  590. argTypes.pzNo = zStdNoArg;
  591. argTypes.pzBrk = zStdBreak;
  592. argTypes.pzNoF = zFiveSpaces;
  593. argTypes.pzSpc = zTwoSpaces;
  594. switch (pOpts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) {
  595. case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT):
  596. *ppT = zNoRq_ShrtTtl;
  597. argTypes.pzOptFmt = zNrmOptFmt;
  598. flen = 19;
  599. break;
  600. case OPTPROC_NO_REQ_OPT:
  601. *ppT = zNoRq_NoShrtTtl;
  602. argTypes.pzOptFmt = zNrmOptFmt;
  603. flen = 19;
  604. break;
  605. case OPTPROC_SHORTOPT:
  606. *ppT = zReq_ShrtTtl;
  607. argTypes.pzOptFmt = zReqOptFmt;
  608. flen = 24;
  609. break;
  610. case 0:
  611. *ppT = zReq_NoShrtTtl;
  612. argTypes.pzOptFmt = zReqOptFmt;
  613. flen = 24;
  614. }
  615. return flen;
  616. }
  617. /*:
  618. * Local Variables:
  619. * mode: C
  620. * c-file-style: "stroustrup"
  621. * tab-width: 4
  622. * indent-tabs-mode: nil
  623. * End:
  624. * end of autoopts/usage.c */