📄 makeshell.c
字号:
} for (;;) { int ch = fgetc( fp ); switch (ch) { case '\n': nlHoldCt++; break; case '\'': while (nlHoldCt > 0) { fputc( '\n', stdout ); nlHoldCt--; } fputs( "'\\''", stdout ); break; case EOF: goto endCharLoop; default: while (nlHoldCt > 0) { fputc( '\n', stdout ); nlHoldCt--; } fputc( ch, stdout ); break; } } endCharLoop:; fputs( "'\n\n", stdout ); close( pipeFd[0] );#endif}static voidemitUsage( tOptions* pOpts ){ char zTimeBuf[ AO_NAME_SIZE ]; /* * First, switch stdout to the output file name. * Then, change the program name to the one defined * by the definitions (rather than the current * executable name). Down case the upper cased name. */ if (pzLeader != NULL) fputs( pzLeader, stdout ); { tSCC zStdout[] = "stdout"; tCC* pzOutName; { time_t curTime = time( NULL ); struct tm* pTime = localtime( &curTime ); strftime(zTimeBuf, AO_NAME_SIZE, "%A %B %e, %Y at %r %Z", pTime ); } if (HAVE_OPT( SCRIPT )) pzOutName = OPT_ARG( SCRIPT ); else pzOutName = zStdout; if ((pzLeader == NULL) && (pzShell != NULL)) printf( "#! %s\n", pzShell ); printf( zPreamble, zStartMarker, pzOutName, zTimeBuf ); } /* * Get a copy of the original program name in lower case */ { char* pzPN = zTimeBuf; tCC* pz = pOpts->pzPROGNAME; for (;;) { if ((*pzPN++ = tolower( *pz++ )) == '\0') break; } } printf( zEndPreamble, pOpts->pzPROGNAME ); pOpts->pzProgPath = pOpts->pzProgName = zTimeBuf; textToVariable( pOpts, TT_LONGUSAGE, NULL ); textToVariable( pOpts, TT_USAGE, NULL ); { tOptDesc* pOptDesc = pOpts->pOptDesc; int optionCt = pOpts->optCt; for (;;) { if (pOptDesc->pOptProc == optionPrintVersion) { textToVariable( pOpts, TT_VERSION, pOptDesc ); break; } if (--optionCt <= 0) break; pOptDesc++; } }}static voidemitSetup( tOptions* pOpts ){ tOptDesc* pOptDesc = pOpts->pOptDesc; int optionCt = pOpts->presetOptCt; char const* pzFmt; char const* pzDefault; for (;optionCt > 0; pOptDesc++, --optionCt) { char zVal[16]; /* * Options that are either usage documentation or are compiled out * are not to be processed. */ if (SKIP_OPT(pOptDesc) || (pOptDesc->pz_NAME == NULL)) continue; if (pOptDesc->optMaxCt > 1) pzFmt = zMultiDef; else pzFmt = zSingleDef; /* * IF this is an enumeration/bitmask option, then convert the value * to a string before printing the default value. */ switch (OPTST_GET_ARGTYPE(pOptDesc->fOptState)) { case OPARG_TYPE_ENUMERATION: (*(pOptDesc->pOptProc))( (tOptions*)2UL, pOptDesc ); pzDefault = pOptDesc->optArg.argString; break; /* * Numeric and membership bit options are just printed as a number. */ case OPARG_TYPE_NUMERIC: snprintf( zVal, sizeof( zVal ), "%d", (int)pOptDesc->optArg.argInt ); pzDefault = zVal; break; case OPARG_TYPE_MEMBERSHIP: snprintf( zVal, sizeof( zVal ), "%lu", (unsigned long)pOptDesc->optArg.argIntptr ); pzDefault = zVal; break; case OPARG_TYPE_BOOLEAN: pzDefault = (pOptDesc->optArg.argBool) ? "true" : "false"; break; default: if (pOptDesc->optArg.argString == NULL) { if (pzFmt == zSingleDef) pzFmt = zSingleNoDef; pzDefault = NULL; } else pzDefault = pOptDesc->optArg.argString; } printf( pzFmt, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pzDefault ); }}static voidprintOptionAction( tOptions* pOpts, tOptDesc* pOptDesc ){ if (pOptDesc->pOptProc == optionPrintVersion) printf( zTextExit, pOpts->pzPROGNAME, "VERSION" ); else if (pOptDesc->pOptProc == optionPagedUsage) printf( zPagedUsageExit, pOpts->pzPROGNAME ); else if (pOptDesc->pOptProc == optionLoadOpt) { printf( zCmdFmt, "echo 'Warning: Cannot load options files' >&2" ); printf( zCmdFmt, "OPT_ARG_NEEDED=YES" ); } else if (pOptDesc->pz_NAME == NULL) { if (pOptDesc->pOptProc == NULL) { printf( zCmdFmt, "echo 'Warning: Cannot save options files' " ">&2" ); printf( zCmdFmt, "OPT_ARG_NEEDED=OK" ); } else printf( zTextExit, pOpts->pzPROGNAME, "LONGUSAGE" ); } else { if (pOptDesc->optMaxCt == 1) printf( zSingleArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); else { if ((unsigned)pOptDesc->optMaxCt < NOLIMIT) printf( zCountTest, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pOptDesc->optMaxCt ); printf( zMultiArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); } /* * Fix up the args. */ if (OPTST_GET_ARGTYPE(pOptDesc->fOptState) == OPARG_TYPE_NONE) { printf( zCantArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); } else if (pOptDesc->fOptState & OPTST_ARG_OPTIONAL) { printf( zMayArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); } else { fputs( zMustArg, stdout ); } } fputs( zOptionEndSelect, stdout );}static voidprintOptionInaction( tOptions* pOpts, tOptDesc* pOptDesc ){ if (pOptDesc->pOptProc == optionLoadOpt) { printf( zCmdFmt, "echo 'Warning: Cannot suppress the loading of " "options files' >&2" ); } else if (pOptDesc->optMaxCt == 1) printf( zNoSingleArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx ); else printf( zNoMultiArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx ); printf( zCmdFmt, "OPT_ARG_NEEDED=NO" ); fputs( zOptionEndSelect, stdout );}static voidemitFlag( tOptions* pOpts ){ tOptDesc* pOptDesc = pOpts->pOptDesc; int optionCt = pOpts->optCt; fputs( zOptionCase, stdout ); for (;optionCt > 0; pOptDesc++, --optionCt) { if (SKIP_OPT(pOptDesc)) continue; if (isprint( pOptDesc->optValue )) { printf( zOptionFlag, pOptDesc->optValue ); printOptionAction( pOpts, pOptDesc ); } } printf( zOptionUnknown, "flag", pOpts->pzPROGNAME );}/* * Emit the match text for a long option */static voidemitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ){ tOptDesc* pOD = pOpts->pOptDesc; int oCt = pOpts->optCt; int min = 1; char zName[ 256 ]; char* pz = zName; for (;;) { int matchCt = 0; /* * Omit the current option, Documentation opts and compiled out opts. */ if ((pOD == pCurOpt) || SKIP_OPT(pOD)){ if (--oCt <= 0) break; pOD++; continue; } /* * Check each character of the name case insensitively. * They must not be the same. They cannot be, because it would * not compile correctly if they were. */ while ( toupper( pOD->pz_Name[matchCt] ) == toupper( pzMatchName[matchCt] )) matchCt++; if (matchCt > min) min = matchCt; /* * Check the disablement name, too. */ if (pOD->pz_DisableName != NULL) { matchCt = 0; while ( toupper( pOD->pz_DisableName[matchCt] ) == toupper( pzMatchName[matchCt] )) matchCt++; if (matchCt > min) min = matchCt; } if (--oCt <= 0) break; pOD++; } /* * IF the 'min' is all or one short of the name length, * THEN the entire string must be matched. */ if ( (pzMatchName[min ] == NUL) || (pzMatchName[min+1] == NUL) ) printf( zOptionFullName, pzMatchName ); else { int matchCt = 0; for (; matchCt <= min; matchCt++) *pz++ = pzMatchName[matchCt]; for (;;) { *pz = NUL; printf( zOptionPartName, zName ); *pz++ = pzMatchName[matchCt++]; if (pzMatchName[matchCt] == NUL) { *pz = NUL; printf( zOptionFullName, zName ); break; } } }}/* * Emit GNU-standard long option handling code */static voidemitLong( tOptions* pOpts ){ tOptDesc* pOD = pOpts->pOptDesc; int ct = pOpts->optCt; fputs( zOptionCase, stdout ); /* * do each option, ... */ do { /* * Documentation & compiled-out options */ if (SKIP_OPT(pOD)) continue; emitMatchExpr( pOD->pz_Name, pOD, pOpts ); printOptionAction( pOpts, pOD ); /* * Now, do the same thing for the disablement version of the option. */ if (pOD->pz_DisableName != NULL) { emitMatchExpr( pOD->pz_DisableName, pOD, pOpts ); printOptionInaction( pOpts, pOD ); } } while (pOD++, --ct > 0); printf( zOptionUnknown, "option", pOpts->pzPROGNAME );}static voidopenOutput( char const* pzFile ){ FILE* fp; char* pzData = NULL; struct stat stbf; do { char* pzScan; size_t sizeLeft; /* * IF we cannot stat the file, * THEN assume we are creating a new file. * Skip the loading of the old data. */ if (stat( pzFile, &stbf ) != 0) break; /* * The file must be a regular file */ if (! S_ISREG( stbf.st_mode )) { fprintf( stderr, zNotFile, pzFile ); exit( EXIT_FAILURE ); } pzData = AGALOC(stbf.st_size + 1, "file data"); fp = fopen( pzFile, "r" FOPEN_BINARY_FLAG ); sizeLeft = (unsigned)stbf.st_size; pzScan = pzData; /* * Read in all the data as fast as our OS will let us. */ for (;;) { int inct = fread( (void*)pzScan, (size_t)1, sizeLeft, fp); if (inct == 0) break; pzScan += inct; sizeLeft -= inct; if (sizeLeft == 0) break; } /* * NUL-terminate the leader and look for the trailer */ *pzScan = '\0'; fclose( fp ); pzScan = strstr( pzData, zStartMarker ); if (pzScan == NULL) { pzTrailer = pzData; break; } *(pzScan++) = NUL; pzScan = strstr( pzScan, zTrailerMarker ); if (pzScan == NULL) { pzTrailer = pzData; break; } /* * Check to see if the data contains * our marker. If it does, then we will skip over it */ pzTrailer = pzScan + sizeof( zTrailerMarker ) - 1; pzLeader = pzData; } while (AG_FALSE); freopen( pzFile, "w" FOPEN_BINARY_FLAG, stdout );}/*=export_func genshelloptUsage * private: * what: The usage function for the genshellopt generated program * * arg: + tOptions* + pOpts + program options descriptor + * arg: + int + exitCode + usage text type to produce + * * doc: * This function is used to create the usage strings for the option * processing shell script code. Two child processes are spawned * each emitting the usage text in either the short (error exit) * style or the long style. The generated program will capture this * and create shell script variables containing the two types of text.=*/voidgenshelloptUsage( tOptions* pOpts, int exitCode ){#if defined(__windows__) && !defined(__CYGWIN__) optionUsage( pOpts, exitCode );#else /* * IF not EXIT_SUCCESS, * THEN emit the short form of usage. */ if (exitCode != EXIT_SUCCESS) optionUsage( pOpts, exitCode ); fflush( stderr ); fflush( stdout ); option_usage_fp = stdout; /* * First, print our usage */ switch (fork()) { case -1: optionUsage( pOpts, EXIT_FAILURE ); /*NOTREACHED*/ _exit( EXIT_FAILURE ); case 0: pagerState = PAGER_STATE_CHILD; optionUsage( pOpts, EXIT_SUCCESS ); /*NOTREACHED*/ _exit( EXIT_FAILURE ); default: { int sts; wait( &sts ); } } /* * Generate the pzProgName, since optionProcess() normally * gets it from the command line */ { char* pz; AGDUPSTR( pz, pShellParseOptions->pzPROGNAME, "program name" ); pShellParseOptions->pzProgName = pz; while (*pz != NUL) { *pz = tolower( *pz ); pz++; } } /* * Separate the makeshell usage from the client usage */ fprintf( option_usage_fp, zGenshell, pShellParseOptions->pzProgName ); fflush( option_usage_fp ); /* * Now, print the client usage. */ switch (fork()) { case 0: pagerState = PAGER_STATE_CHILD; /*FALLTHROUGH*/ case -1: optionUsage( pShellParseOptions, EXIT_FAILURE ); default: { int sts; wait( &sts ); } } exit( EXIT_SUCCESS );#endif}/* * Local Variables: * mode: C * c-file-style: "stroustrup" * indent-tabs-mode: nil * End: * end of autoopts/makeshell.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -