tOptions* pShellParseOptions = NULL;
static char const zStartMarker[] =
"# # # # # # # # # # -- do not modify this marker --\n#\n"
"# DO NOT EDIT THIS SECTION";
static char const zPreamble[] =
"%s OF %s\n#\n"
"# From here to the next `-- do not modify this marker --',\n"
"# the text has been generated %s\n";
static char const zEndPreamble[] =
"# From the %s option definitions\n#\n";
static char const zMultiDef[] = "\n"
"if test -z \"${%1$s_%2$s}\"\n"
"then\n"
" %1$s_%2$s_CT=0\n"
"else\n"
" %1$s_%2$s_CT=1\n"
" %1$s_%2$s_1=\"${%1$s_%2$s}\"\n"
"fi\n"
"export %1$s_%2$s_CT";
static char const zSingleDef[] = "\n"
"%1$s_%2$s=\"${%1$s_%2$s-'%3$s'}\"\n"
"%1$s_%2$s_set=false\n"
"export %1$s_%2$s\n";
static char const zSingleNoDef[] = "\n"
"%1$s_%2$s=\"${%1$s_%2$s}\"\n"
"%1$s_%2$s_set=false\n"
"export %1$s_%2$s\n";
static char const zLoopCase[] = "\n"
"OPT_PROCESS=true\n"
"OPT_ARG=\"$1\"\n\n"
"while ${OPT_PROCESS} && [ $# -gt 0 ]\ndo\n"
" OPT_ELEMENT=''\n"
" OPT_ARG_VAL=''\n\n"
" case \"${OPT_ARG}\" in\n"
" -- )\n"
" OPT_PROCESS=false\n"
" shift\n"
" ;;\n\n";
static char const zLoopOnly[] = "\n"
"OPT_ARG=\"$1\"\n\n"
"while [ $# -gt 0 ]\ndo\n"
" OPT_ELEMENT=''\n"
" OPT_ARG_VAL=''\n\n"
" OPT_ARG=\"${1}\"\n";
static char const zLongSelection[] =
" --* )\n";
static char const zFlagSelection[] =
" -* )\n";
static char const zEndSelection[] =
" ;;\n\n";
static char const zNoSelection[] =
" * )\n"
" OPT_PROCESS=false\n"
" ;;\n"
" esac\n\n";
static char const zLoopEnd[] =
" if [ -n \"${OPT_ARG_VAL}\" ]\n"
" then\n"
" eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n"
" export %1$s_${OPT_NAME}${OPT_ELEMENT}\n"
" fi\n"
"done\n\n"
"unset OPT_PROCESS || :\n"
"unset OPT_ELEMENT || :\n"
"unset OPT_ARG || :\n"
"unset OPT_ARG_NEEDED || :\n"
"unset OPT_NAME || :\n"
"unset OPT_CODE || :\n"
"unset OPT_ARG_VAL || :\n%2$s";
static char const zTrailerMarker[] = "\n"
"# # # # # # # # # #\n#\n"
"# END OF AUTOMATED OPTION PROCESSING\n"
"#\n# # # # # # # # # # -- do not modify this marker --\n";
static char const zOptionCase[] =
" case \"${OPT_CODE}\" in\n";
static char const zOptionPartName[] =
" '%s' | \\\n";
static char const zOptionFullName[] =
" '%s' )\n";
static char const zOptionFlag[] =
" '%c' )\n";
static char const zOptionEndSelect[] =
" ;;\n\n";
static char const zOptionUnknown[] =
" * )\n"
" echo Unknown %s: \"${OPT_CODE}\" >&2\n"
" echo \"$%s_USAGE_TEXT\"\n"
" exit 1\n"
" ;;\n"
" esac\n\n";
static char const zTextExit[] =
" echo \"$%s_%s_TEXT\"\n"
" exit 0\n";
static char const zPagedUsageExit[] =
" echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n"
" exit 0\n";
static char const zCmdFmt[] =
" %s\n";
static char const zCountTest[] =
" if [ $%1$s_%2$s_CT -ge %3$d ] ; then\n"
" echo Error: more than %3$d %2$s options >&2\n"
" echo \"$%1$s_USAGE_TEXT\"\n"
" exit 1 ; fi\n";
static char const zMultiArg[] =
" %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1`\n"
" OPT_ELEMENT=\"_${%1$s_%2$s_CT}\"\n"
" OPT_NAME='%2$s'\n";
static char const zSingleArg[] =
" if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
" echo Error: duplicate %2$s option >&2\n"
" echo \"$%1$s_USAGE_TEXT\"\n"
" exit 1 ; fi\n"
" %1$s_%2$s_set=true\n"
" OPT_NAME='%2$s'\n";
static char const zNoMultiArg[] =
" %1$s_%2$s_CT=0\n"
" OPT_ELEMENT=''\n"
" %1$s_%2$s='%3$s'\n"
" export %1$s_%2$s\n"
" OPT_NAME='%2$s'\n";
static char const zNoSingleArg[] =
" if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
" echo Error: duplicate %2$s option >&2\n"
" echo \"$%1$s_USAGE_TEXT\"\n"
" exit 1 ; fi\n"
" %1$s_%2$s_set=true\n"
" %1$s_%2$s='%3$s'\n"
" export %1$s_%2$s\n"
" OPT_NAME='%2$s'\n";
static char const zMayArg[] =
" eval %1$s_%2$s${OPT_ELEMENT}=true\n"
" export %1$s_%2$s${OPT_ELEMENT}\n"
" OPT_ARG_NEEDED=OK\n";
static char const zMustArg[] =
" OPT_ARG_NEEDED=YES\n";
static char const zCantArg[] =
" eval %1$s_%2$s${OPT_ELEMENT}=true\n"
" export %1$s_%2$s${OPT_ELEMENT}\n"
" OPT_ARG_NEEDED=NO\n";
static char const zLongOptInit[] =
" OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n"
" shift\n"
" OPT_ARG=\"$1\"\n\n"
" case \"${OPT_CODE}\" in *=* )\n"
" OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n"
" OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\n";
static char const zLongOptArg[] =
" case \"${OPT_ARG_NEEDED}\" in\n"
" NO )\n"
" OPT_ARG_VAL=''\n"
" ;;\n\n"
" YES )\n"
" if [ -z \"${OPT_ARG_VAL}\" ]\n"
" then\n"
" if [ $# -eq 0 ]\n"
" then\n"
" echo No argument provided for ${OPT_NAME} option >&2\n"
" echo \"$%s_USAGE_TEXT\"\n"
" exit 1\n"
" fi\n\n"
" OPT_ARG_VAL=\"${OPT_ARG}\"\n"
" shift\n"
" OPT_ARG=\"$1\"\n"
" fi\n"
" ;;\n\n"
" OK )\n"
" if [ -z \"${OPT_ARG_VAL}\" ] && [ $# -gt 0 ]\n"
" then\n"
" case \"${OPT_ARG}\" in -* ) ;; * )\n"
" OPT_ARG_VAL=\"${OPT_ARG}\"\n"
" shift\n"
" OPT_ARG=\"$1\" ;; esac\n"
" fi\n"
" ;;\n"
" esac\n";
static char const zFlagOptInit[] =
" OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n"
" OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\n";
static char const zFlagOptArg[] =
" case \"${OPT_ARG_NEEDED}\" in\n"
" NO )\n"
" if [ -n \"${OPT_ARG}\" ]\n"
" then\n"
" OPT_ARG=-\"${OPT_ARG}\"\n"
" else\n"
" shift\n"
" OPT_ARG=\"$1\"\n"
" fi\n"
" ;;\n\n"
" YES )\n"
" if [ -n \"${OPT_ARG}\" ]\n"
" then\n"
" OPT_ARG_VAL=\"${OPT_ARG}\"\n\n"
" else\n"
" if [ $# -eq 0 ]\n"
" then\n"
" echo No argument provided for ${OPT_NAME} option >&2\n"
" echo \"$%s_USAGE_TEXT\"\n"
" exit 1\n"
" fi\n"
" shift\n"
" OPT_ARG_VAL=\"$1\"\n"
" fi\n\n"
" shift\n"
" OPT_ARG=\"$1\"\n"
" ;;\n\n"
" OK )\n"
" if [ -n \"${OPT_ARG}\" ]\n"
" then\n"
" OPT_ARG_VAL=\"${OPT_ARG}\"\n"
" shift\n"
" OPT_ARG=\"$1\"\n\n"
" else\n"
" shift\n"
" if [ $# -gt 0 ]\n"
" then\n"
" case \"$1\" in -* ) ;; * )\n"
" OPT_ARG_VAL=\"$1\"\n"
" shift ;; esac\n"
" OPT_ARG=\"$1\"\n"
" fi\n"
" fi\n"
" ;;\n"
" esac\n";
tSCC* pzShell = NULL;
static char* pzLeader = NULL;
static char* pzTrailer = NULL;
static void
textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD );
static void
emitUsage( tOptions* pOpts );
static void
emitSetup( tOptions* pOpts );
static void
printOptionAction( tOptions* pOpts, tOptDesc* pOptDesc );
static void
printOptionInaction( tOptions* pOpts, tOptDesc* pOptDesc );
static void
emitFlag( tOptions* pOpts );
static void
emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts );
static void
emitLong( tOptions* pOpts );
static void
openOutput( char const* pzFile );
void
optionParseShell( tOptions* pOpts )
{
if (HAVE_OPT( SHELL ))
pzShell = OPT_ARG( SHELL );
else if (! ENABLED_OPT( SHELL ))
pzShell = NULL;
else if ((pzShell = getenv( "SHELL" )),
pzShell == NULL)
pzShell = "/bin/sh";
if (HAVE_OPT( SCRIPT ))
openOutput( OPT_ARG( SCRIPT ));
emitUsage( pOpts );
emitSetup( pOpts );
switch (pOpts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) {
case OPTPROC_LONGOPT:
fputs( zLoopCase, stdout );
fputs( zLongSelection, stdout );
fputs( zLongOptInit, stdout );
emitLong( pOpts );
printf( zLongOptArg, pOpts->pzPROGNAME );
fputs( zEndSelection, stdout );
fputs( zNoSelection, stdout );
break;
case 0:
fputs( zLoopOnly, stdout );
fputs( zLongOptInit, stdout );
emitLong( pOpts );
printf( zLongOptArg, pOpts->pzPROGNAME );
break;
case OPTPROC_SHORTOPT:
fputs( zLoopCase, stdout );
fputs( zFlagSelection, stdout );
fputs( zFlagOptInit, stdout );
emitFlag( pOpts );
printf( zFlagOptArg, pOpts->pzPROGNAME );
fputs( zEndSelection, stdout );
fputs( zNoSelection, stdout );
break;
case OPTPROC_LONGOPT|OPTPROC_SHORTOPT:
fputs( zLoopCase, stdout );
fputs( zLongSelection, stdout );
fputs( zLongOptInit, stdout );
emitLong( pOpts );
printf( zLongOptArg, pOpts->pzPROGNAME );
fputs( zEndSelection, stdout );
fputs( zFlagSelection, stdout );
fputs( zFlagOptInit, stdout );
emitFlag( pOpts );
printf( zFlagOptArg, pOpts->pzPROGNAME );
fputs( zEndSelection, stdout );
fputs( zNoSelection, stdout );
break;
}
printf( zLoopEnd, pOpts->pzPROGNAME, zTrailerMarker );
if ((pzTrailer != NULL) && (*pzTrailer != '\0'))
fputs( pzTrailer, stdout );
else if (ENABLED_OPT( SHELL ))
printf( "\nenv | grep '^%s_'\n", pOpts->pzPROGNAME );
fflush( stdout );
fchmod( STDOUT_FILENO, 0755 );
fclose( stdout );
}
static void
textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD )
{
# define _TT_(n) tSCC z ## n [] = #n;
TEXTTO_TABLE
# undef _TT_
# define _TT_(n) z ## n ,
static char const* apzTTNames[] = { TEXTTO_TABLE };
# undef _TT_
#if ! defined(HAVE_WORKING_FORK)
printf( "%1$s_%2$s_TEXT='no %2$s text'\n",
pOpts->pzPROGNAME, apzTTNames[ whichVar ]);
#else
int nlHoldCt = 0;
int pipeFd[2];
FILE* fp;
printf( "%s_%s_TEXT='", pOpts->pzPROGNAME, apzTTNames[ whichVar ]);
fflush( stdout );
if (pipe( pipeFd ) != 0) {
fprintf( stderr, zBadPipe, errno, strerror( errno ));
exit( EXIT_FAILURE );
}
switch (fork()) {
case -1:
fprintf( stderr, zForkFail, errno, strerror(errno), pOpts->pzProgName);
exit( EXIT_FAILURE );
break;
case 0:
dup2( pipeFd[1], STDERR_FILENO );
dup2( pipeFd[1], STDOUT_FILENO );
close( pipeFd[0] );
switch (whichVar) {
case TT_LONGUSAGE:
(*(pOpts->pUsageProc))( pOpts, EXIT_SUCCESS );
exit( EXIT_FAILURE );
case TT_USAGE:
(*(pOpts->pUsageProc))( pOpts, EXIT_FAILURE );
exit( EXIT_FAILURE );
case TT_VERSION:
if (pOD->fOptState & OPTST_ALLOC_ARG) {
AGFREE(pOD->optArg.argString);
pOD->fOptState &= ~OPTST_ALLOC_ARG;
}
pOD->optArg.argString = "c";
optionPrintVersion( pOpts, pOD );
default:
exit( EXIT_FAILURE );
}
default:
close( pipeFd[1] );
fp = fdopen( pipeFd[0], "r" FOPEN_BINARY_FLAG );
}
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 void
emitUsage( tOptions* pOpts )
{
char zTimeBuf[ AO_NAME_SIZE ];
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 );
}
{
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 void
emitSetup( tOptions* pOpts )
{
tOptDesc* pOptDesc = pOpts->pOptDesc;
int optionCt = pOpts->presetOptCt;
char const* pzFmt;
char const* pzDefault;
for (;optionCt > 0; pOptDesc++, --optionCt) {
char zVal[16];
if (SKIP_OPT(pOptDesc) || (pOptDesc->pz_NAME == NULL))
continue;
if (pOptDesc->optMaxCt > 1)
pzFmt = zMultiDef;
else pzFmt = zSingleDef;
switch (OPTST_GET_ARGTYPE(pOptDesc->fOptState)) {
case OPARG_TYPE_ENUMERATION:
(*(pOptDesc->pOptProc))(OPTPROC_EMIT_SHELL, pOptDesc );
pzDefault = pOptDesc->optArg.argString;
break;
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 void
printOptionAction( 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 );
}
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 void
printOptionInaction( 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 void
emitFlag( tOptions* pOpts )
{
tOptDesc* pOptDesc = pOpts->pOptDesc;
int optionCt = pOpts->optCt;
fputs( zOptionCase, stdout );
for (;optionCt > 0; pOptDesc++, --optionCt) {
if (SKIP_OPT(pOptDesc))
continue;
if (IS_GRAPHIC_CHAR(pOptDesc->optValue)) {
printf( zOptionFlag, pOptDesc->optValue );
printOptionAction( pOpts, pOptDesc );
}
}
printf( zOptionUnknown, "flag", pOpts->pzPROGNAME );
}
static void
emitMatchExpr( 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;
if ((pOD == pCurOpt) || SKIP_OPT(pOD)){
if (--oCt <= 0)
break;
pOD++;
continue;
}
while ( toupper( pOD->pz_Name[matchCt] )
== toupper( pzMatchName[matchCt] ))
matchCt++;
if (matchCt > min)
min = matchCt;
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 ( (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;
}
}
}
}
static void
emitLong( tOptions* pOpts )
{
tOptDesc* pOD = pOpts->pOptDesc;
int ct = pOpts->optCt;
fputs( zOptionCase, stdout );
do {
if (SKIP_OPT(pOD))
continue;
emitMatchExpr( pOD->pz_Name, pOD, pOpts );
printOptionAction( pOpts, pOD );
if (pOD->pz_DisableName != NULL) {
emitMatchExpr( pOD->pz_DisableName, pOD, pOpts );
printOptionInaction( pOpts, pOD );
}
} while (pOD++, --ct > 0);
printf( zOptionUnknown, "option", pOpts->pzPROGNAME );
}
static void
openOutput( char const* pzFile )
{
FILE* fp;
char* pzData = NULL;
struct stat stbf;
do {
char* pzScan;
size_t sizeLeft;
if (stat( pzFile, &stbf ) != 0)
break;
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;
for (;;) {
int inct = fread( (void*)pzScan, (size_t)1, sizeLeft, fp);
if (inct == 0)
break;
pzScan += inct;
sizeLeft -= inct;
if (sizeLeft == 0)
break;
}
*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;
}
pzTrailer = pzScan + sizeof( zTrailerMarker ) - 1;
pzLeader = pzData;
} while (AG_FALSE);
freopen( pzFile, "w" FOPEN_BINARY_FLAG, stdout );
}
void
genshelloptUsage( tOptions* pOpts, int exitCode )
{
#if ! defined(HAVE_WORKING_FORK)
optionUsage( pOpts, exitCode );
#else
if (exitCode != EXIT_SUCCESS)
optionUsage( pOpts, exitCode );
fflush( stderr );
fflush( stdout );
option_usage_fp = stdout;
switch (fork()) {
case -1:
optionUsage( pOpts, EXIT_FAILURE );
_exit( EXIT_FAILURE );
case 0:
pagerState = PAGER_STATE_CHILD;
optionUsage( pOpts, EXIT_SUCCESS );
_exit( EXIT_FAILURE );
default:
{
int sts;
wait( &sts );
}
}
{
char* pz;
AGDUPSTR( pz, pShellParseOptions->pzPROGNAME, "program name" );
pShellParseOptions->pzProgName = pz;
while (*pz != NUL) {
*pz = tolower( *pz );
pz++;
}
}
fprintf( option_usage_fp, zGenshell, pShellParseOptions->pzProgName );
fflush( option_usage_fp );
switch (fork()) {
case 0:
pagerState = PAGER_STATE_CHILD;
case -1:
optionUsage( pShellParseOptions, EXIT_FAILURE );
default:
{
int sts;
wait( &sts );
}
}
exit( EXIT_SUCCESS );
#endif
}