📄 usage.c
字号:
case 1: case 0: switch (pOD->optMaxCt) { case 0: fputs( zPreset, option_usage_fp ); break; case NOLIMIT: fputs( zNoLim, option_usage_fp ); break; case 1: break; /* * IF the max is more than one but limited, print "UP TO" message */ default: fprintf( option_usage_fp, zUpTo, pOD->optMaxCt ); break; } break; default: /* * More than one is required. Print the range. */ fprintf( option_usage_fp, zMust, pOD->optMinCt, pOD->optMaxCt ); } if ( NAMED_OPTS( pOptions ) && (pOptions->specOptIdx.default_opt == pOD->optIndex)) fputs( zDefaultOpt, option_usage_fp );}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Figure out where all the initialization files might live. * This requires translating some environment variables and * testing to see if a name is a directory or a file. It's * squishy, but important to tell users how to find these files. */static voidprintInitList( tCC* const* papz, ag_bool* pInitIntro, tCC* pzRc, tCC* pzPN ){ char zPath[ AG_PATH_MAX+1 ]; if (papz == NULL) return; fputs( zPresetIntro, option_usage_fp ); *pInitIntro = AG_FALSE; for (;;) { char const* pzPath = *(papz++); if (pzPath == NULL) break; if (optionMakePath(zPath, (int)sizeof( zPath ), pzPath, pzPN)) pzPath = zPath; /* * Print the name of the "homerc" file. If the "rcfile" name is * not empty, we may or may not print that, too... */ fprintf( option_usage_fp, zPathFmt, pzPath ); if (*pzRc != NUL) { struct stat sb; /* * IF the "homerc" file is a directory, * then append the "rcfile" name. */ if ( (stat( pzPath, &sb ) == 0) && S_ISDIR( sb.st_mode ) ) { fputc( DIRCH, option_usage_fp ); fputs( pzRc, option_usage_fp ); } } fputc( '\n', option_usage_fp ); }}/* * Print the usage information for a single option. */static voidprintOneUsage( tOptions* pOptions, tOptDesc* pOD, arg_types_t* pAT ){ /* * Flag prefix: IF no flags at all, then omit it. If not printable * (not allowed for this option), then blank, else print it. * Follow it with a comma if we are doing GNU usage and long * opts are to be printed too. */ if ((pOptions->fOptSet & OPTPROC_SHORTOPT) == 0) fputs( pAT->pzSpc, option_usage_fp ); else if (! isgraph( pOD->optValue)) { if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) fputc( ' ', option_usage_fp ); fputs( pAT->pzNoF, option_usage_fp ); } else { fprintf( option_usage_fp, " -%c", pOD->optValue ); if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) fputs( ", ", option_usage_fp ); } { char z[ 80 ]; tCC* pzArgType; /* * Determine the argument type string first on its usage, then, * when the option argument is required, base the type string on the * argument type. */ if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NONE) { pzArgType = pAT->pzNo; } else if (pOD->fOptState & OPTST_ARG_OPTIONAL) { pzArgType = pAT->pzOpt; } else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey; break; case OPARG_TYPE_MEMBERSHIP: pzArgType = pAT->pzKeyL; break; case OPARG_TYPE_BOOLEAN: pzArgType = pAT->pzBool; break; case OPARG_TYPE_NUMERIC: pzArgType = pAT->pzNum; break; case OPARG_TYPE_HIERARCHY: pzArgType = pAT->pzNest; break; case OPARG_TYPE_STRING: pzArgType = pAT->pzStr; break; default: goto bogus_desc; break; } snprintf( z, sizeof(z), pAT->pzOptFmt, pzArgType, pOD->pz_Name, (pOD->optMinCt != 0) ? pAT->pzReq : pAT->pzOpt ); fprintf( option_usage_fp, zOptFmtLine, z, pOD->pzText ); switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { case OPARG_TYPE_ENUMERATION: case OPARG_TYPE_MEMBERSHIP: displayEnum = (pOD->pOptProc != NULL) ? AG_TRUE : displayEnum; } } return; bogus_desc: fprintf( stderr, zInvalOptDesc, pOD->pz_Name ); exit( EX_SOFTWARE );}/* * Print out the usage information for just the options. */static voidprintOptionUsage( tOptions* pOpts, int ex_code, tCC* pOptTitle ){ int ct = pOpts->optCt; int optNo = 0; tOptDesc* pOD = pOpts->pOptDesc; int docCt = 0; do { if ((pOD->fOptState & OPTST_OMITTED) != 0) continue; if ((pOD->fOptState & OPTST_DOCUMENT) != 0) { if (ex_code == EXIT_SUCCESS) { fprintf(option_usage_fp, argTypes.pzBrk, pOD->pzText, pOptTitle); docCt++; } continue; } /* * IF this is the first auto-opt maintained option * *AND* we are doing a full help * *AND* there are documentation options * *AND* the last one was not a doc option, * THEN document that the remaining options are not user opts */ if ( (pOpts->presetOptCt == optNo) && (ex_code == EXIT_SUCCESS) && (docCt > 0) && ((pOD[-1].fOptState & OPTST_DOCUMENT) == 0) ) fprintf( option_usage_fp, argTypes.pzBrk, zAuto, pOptTitle ); printOneUsage( pOpts, pOD, &argTypes ); /* * IF we were invoked because of the --help option, * THEN print all the extra info */ if (ex_code == EXIT_SUCCESS) printExtendedUsage( pOpts, pOD, &argTypes ); } while (pOD++, optNo++, (--ct > 0)); fputc( '\n', option_usage_fp );}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROGRAM DETAILS */static voidprintProgramDetails( tOptions* pOptions ){ ag_bool initIntro = AG_TRUE; /* * Display all the places we look for config files */ printInitList( pOptions->papzHomeList, &initIntro, pOptions->pzRcName, pOptions->pzProgPath ); /* * Let the user know about environment variable settings */ if ((pOptions->fOptSet & OPTPROC_ENVIRON) != 0) { if (initIntro) fputs( zPresetIntro, option_usage_fp ); fprintf( option_usage_fp, zExamineFmt, pOptions->pzPROGNAME ); } /* * IF we found an enumeration, * THEN hunt for it again. Call the handler proc with a NULL * option struct pointer. That tells it to display the keywords. */ if (displayEnum) { int ct = pOptions->optCt; int optNo = 0; tOptDesc* pOD = pOptions->pOptDesc; fputc( '\n', option_usage_fp ); fflush( option_usage_fp ); do { switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { case OPARG_TYPE_ENUMERATION: case OPARG_TYPE_MEMBERSHIP: (*(pOD->pOptProc))( NULL, pOD ); } } while (pOD++, optNo++, (--ct > 0)); } /* * If there is a detail string, now is the time for that. */ if (pOptions->pzDetail != NULL) fputs( pOptions->pzDetail, option_usage_fp );}/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * OPTION LINE FORMATTING SETUP * * The "OptFmt" formats receive three arguments: * 1. the type of the option's argument * 2. the long name of the option * 3. "YES" or "no ", depending on whether or not the option must appear * on the command line. * These formats are used immediately after the option flag (if used) has * been printed. * * Set up the formatting for GNU-style output */static intsetGnuOptFmts( tOptions* pOpts, tCC** ppT ){ int flen = 22; *ppT = zNoRq_ShrtTtl; argTypes.pzStr = zGnuStrArg; argTypes.pzReq = zOneSpace; argTypes.pzNum = zGnuNumArg; argTypes.pzKey = zGnuKeyArg; argTypes.pzKeyL = zGnuKeyLArg; argTypes.pzBool = zGnuBoolArg; argTypes.pzNest = zGnuNestArg; argTypes.pzOpt = zGnuOptArg; argTypes.pzNo = zOneSpace; argTypes.pzBrk = zGnuBreak; argTypes.pzNoF = zSixSpaces; argTypes.pzSpc = zThreeSpaces; switch (pOpts->fOptSet & OPTPROC_L_N_S) { case OPTPROC_L_N_S: argTypes.pzOptFmt = zGnuOptFmt; break; case OPTPROC_LONGOPT: argTypes.pzOptFmt = zGnuOptFmt; break; case 0: argTypes.pzOptFmt = zGnuOptFmt + 2; break; case OPTPROC_SHORTOPT: argTypes.pzOptFmt = zShrtGnuOptFmt; zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' '; argTypes.pzOpt = " [arg]"; flen = 8; break; } return flen;}/* * Standard (AutoOpts normal) option line formatting */static intsetStdOptFmts( tOptions* pOpts, tCC** ppT ){ int flen = 0; argTypes.pzStr = zStdStrArg; argTypes.pzReq = zStdReqArg; argTypes.pzNum = zStdNumArg; argTypes.pzKey = zStdKeyArg; argTypes.pzKeyL = zStdKeyLArg; argTypes.pzBool = zStdBoolArg; argTypes.pzNest = zStdNestArg; argTypes.pzOpt = zStdOptArg; argTypes.pzNo = zStdNoArg; argTypes.pzBrk = zStdBreak; argTypes.pzNoF = zFiveSpaces; argTypes.pzSpc = zTwoSpaces; switch (pOpts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) { case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT): *ppT = zNoRq_ShrtTtl; argTypes.pzOptFmt = zNrmOptFmt; flen = 19; break; case OPTPROC_NO_REQ_OPT: *ppT = zNoRq_NoShrtTtl; argTypes.pzOptFmt = zNrmOptFmt; flen = 19; break; case OPTPROC_SHORTOPT: *ppT = zReq_ShrtTtl; argTypes.pzOptFmt = zReqOptFmt; flen = 24; break; case 0: *ppT = zReq_NoShrtTtl; argTypes.pzOptFmt = zReqOptFmt; flen = 24; } return flen;}/*: * Local Variables: * mode: C * c-file-style: "stroustrup" * indent-tabs-mode: nil * End: * end of autoopts/usage.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -