diff options
Diffstat (limited to 'sntp/libopts/makeshell.c')
-rw-r--r-- | sntp/libopts/makeshell.c | 624 |
1 files changed, 325 insertions, 299 deletions
diff --git a/sntp/libopts/makeshell.c b/sntp/libopts/makeshell.c index 8447d45..7b9b6cd 100644 --- a/sntp/libopts/makeshell.c +++ b/sntp/libopts/makeshell.c @@ -1,74 +1,52 @@ -/* - * $Id: makeshell.c,v 4.20 2007/02/04 17:44:12 bkorb Exp $ - * Time-stamp: "2007-01-27 06:05:45 bkorb" +/** + * \file makeshell.c + * + * Time-stamp: "2011-04-20 11:06:57 bkorb" * * This module will interpret the options set in the tOptions * structure and create a Bourne shell script capable of parsing them. - */ - -/* - * Automated Options copyright 1992-2007 Bruce Korb * - * Automated Options is free software. - * You may redistribute it and/or modify it under the terms of the - * GNU General Public License, as published by the Free Software - * Foundation; either version 2, or (at your option) any later version. + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved * - * Automated Options is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. * - * You should have received a copy of the GNU General Public License - * along with Automated Options. See the file "COPYING". If not, - * write to: The Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" * - * As a special exception, Bruce Korb gives permission for additional - * uses of the text contained in his release of AutoOpts. + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" * - * The exception is that, if you link the AutoOpts library with other - * files to produce an executable, this does not by itself cause the - * resulting executable to be covered by the GNU General Public License. - * Your use of that executable is in no way restricted on account of - * linking the AutoOpts library code into it. + * These files have the following md5sums: * - * This exception does not however invalidate any other reasons why - * the executable file might be covered by the GNU General Public License. - * - * This exception applies only to the code released by Bruce Korb under - * the name AutoOpts. If you copy code from other sources under the - * General Public License into a copy of AutoOpts, as the General Public - * License permits, the exception does not apply to the code that you add - * in this way. To avoid misleading anyone as to the status of such - * modified files, you must delete this exception notice from them. - * - * If you write modifications of your own for AutoOpts, it is your choice - * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice. + * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3 + * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3 + * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd */ -tOptions* pShellParseOptions = NULL; +tOptions * optionParseShellOptions = NULL; /* * * * * * * * * * * * * * * * * * * * * * * Setup Format Strings */ -tSCC zStartMarker[] = +static char const zStartMarker[] = "# # # # # # # # # # -- do not modify this marker --\n#\n" "# DO NOT EDIT THIS SECTION"; -tSCC zPreamble[] = +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"; -tSCC zEndPreamble[] = +static char const zEndPreamble[] = "# From the %s option definitions\n#\n"; -tSCC zMultiDef[] = "\n" +static char const zMultiDef[] = "\n" "if test -z \"${%1$s_%2$s}\"\n" "then\n" " %1$s_%2$s_CT=0\n" @@ -78,12 +56,12 @@ tSCC zMultiDef[] = "\n" "fi\n" "export %1$s_%2$s_CT"; -tSCC zSingleDef[] = "\n" +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"; -tSCC zSingleNoDef[] = "\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"; @@ -96,7 +74,7 @@ tSCC zSingleNoDef[] = "\n" * all options are named options (loop only) * regular, marked option processing. */ -tSCC zLoopCase[] = "\n" +static char const zLoopCase[] = "\n" "OPT_PROCESS=true\n" "OPT_ARG=\"$1\"\n\n" "while ${OPT_PROCESS} && [ $# -gt 0 ]\ndo\n" @@ -111,7 +89,7 @@ tSCC zLoopCase[] = "\n" " shift\n" " ;;\n\n"; -tSCC zLoopOnly[] = "\n" +static char const zLoopOnly[] = "\n" "OPT_ARG=\"$1\"\n\n" "while [ $# -gt 0 ]\ndo\n" " OPT_ELEMENT=''\n" @@ -126,16 +104,16 @@ tSCC zLoopOnly[] = "\n" * then we must have selectors for each acceptable option * type (long option, flag character and non-option) */ -tSCC zLongSelection[] = +static char const zLongSelection[] = " --* )\n"; -tSCC zFlagSelection[] = +static char const zFlagSelection[] = " -* )\n"; -tSCC zEndSelection[] = +static char const zEndSelection[] = " ;;\n\n"; -tSCC zNoSelection[] = +static char const zNoSelection[] = " * )\n" " OPT_PROCESS=false\n" " ;;\n" @@ -145,7 +123,7 @@ tSCC zNoSelection[] = * * LOOP END */ -tSCC zLoopEnd[] = +static char const zLoopEnd[] = " if [ -n \"${OPT_ARG_VAL}\" ]\n" " then\n" " eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n" @@ -160,7 +138,7 @@ tSCC zLoopEnd[] = "unset OPT_CODE || :\n" "unset OPT_ARG_VAL || :\n%2$s"; -tSCC zTrailerMarker[] = "\n" +static char const zTrailerMarker[] = "\n" "# # # # # # # # # #\n#\n" "# END OF AUTOMATED OPTION PROCESSING\n" "#\n# # # # # # # # # # -- do not modify this marker --\n"; @@ -169,22 +147,22 @@ tSCC zTrailerMarker[] = "\n" * * OPTION SELECTION */ -tSCC zOptionCase[] = +static char const zOptionCase[] = " case \"${OPT_CODE}\" in\n"; -tSCC zOptionPartName[] = +static char const zOptionPartName[] = " '%s' | \\\n"; -tSCC zOptionFullName[] = +static char const zOptionFullName[] = " '%s' )\n"; -tSCC zOptionFlag[] = +static char const zOptionFlag[] = " '%c' )\n"; -tSCC zOptionEndSelect[] = +static char const zOptionEndSelect[] = " ;;\n\n"; -tSCC zOptionUnknown[] = +static char const zOptionUnknown[] = " * )\n" " echo Unknown %s: \"${OPT_CODE}\" >&2\n" " echo \"$%s_USAGE_TEXT\"\n" @@ -198,29 +176,29 @@ tSCC zOptionUnknown[] = * * Formats for emitting the text for handling particular options */ -tSCC zTextExit[] = +static char const zTextExit[] = " echo \"$%s_%s_TEXT\"\n" " exit 0\n"; -tSCC zPagedUsageExit[] = +static char const zPagedUsageExit[] = " echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n" " exit 0\n"; -tSCC zCmdFmt[] = +static char const zCmdFmt[] = " %s\n"; -tSCC zCountTest[] = +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"; -tSCC zMultiArg[] = +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"; -tSCC zSingleArg[] = +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" @@ -228,14 +206,14 @@ tSCC zSingleArg[] = " %1$s_%2$s_set=true\n" " OPT_NAME='%2$s'\n"; -tSCC zNoMultiArg[] = +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"; -tSCC zNoSingleArg[] = +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" @@ -245,15 +223,15 @@ tSCC zNoSingleArg[] = " export %1$s_%2$s\n" " OPT_NAME='%2$s'\n"; -tSCC zMayArg[] = +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"; -tSCC zMustArg[] = +static char const zMustArg[] = " OPT_ARG_NEEDED=YES\n"; -tSCC zCantArg[] = +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"; @@ -264,7 +242,7 @@ tSCC zCantArg[] = * * Formats for emitting the text for handling long option types */ -tSCC zLongOptInit[] = +static char const zLongOptInit[] = " OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n" " shift\n" " OPT_ARG=\"$1\"\n\n" @@ -272,7 +250,7 @@ tSCC zLongOptInit[] = " OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n" " OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\n"; -tSCC zLongOptArg[] = +static char const zLongOptArg[] = " case \"${OPT_ARG_NEEDED}\" in\n" " NO )\n" " OPT_ARG_VAL=''\n" @@ -308,11 +286,11 @@ tSCC zLongOptArg[] = * * Formats for emitting the text for handling flag option types */ -tSCC zFlagOptInit[] = +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"; -tSCC zFlagOptArg[] = +static char const zFlagOptArg[] = " case \"${OPT_ARG_NEEDED}\" in\n" " NO )\n" " if [ -n \"${OPT_ARG}\" ]\n" @@ -364,33 +342,35 @@ static char* pzLeader = NULL; static char* pzTrailer = NULL; /* = = = START-STATIC-FORWARD = = = */ -/* static forward declarations maintained by :mkfwd */ static void -textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD ); +emit_var_text(char const * prog, char const * var, int fdin); + +static void +textToVariable(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD); static void -emitUsage( tOptions* pOpts ); +emitUsage(tOptions* pOpts); static void -emitSetup( tOptions* pOpts ); +emitSetup(tOptions* pOpts); static void -printOptionAction( tOptions* pOpts, tOptDesc* pOptDesc ); +printOptionAction(tOptions* pOpts, tOptDesc* pOptDesc); static void -printOptionInaction( tOptions* pOpts, tOptDesc* pOptDesc ); +printOptionInaction(tOptions* pOpts, tOptDesc* pOptDesc); static void -emitFlag( tOptions* pOpts ); +emitFlag(tOptions* pOpts); static void -emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ); +emitMatchExpr(tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts); static void -emitLong( tOptions* pOpts ); +emitLong(tOptions* pOpts); static void -openOutput( char const* pzFile ); +openOutput(char const* pzFile); /* = = = END-STATIC-FORWARD = = = */ /*=export_func optionParseShell @@ -403,146 +383,205 @@ openOutput( char const* pzFile ); * Emit a shell script that will parse the command line options. =*/ void -optionParseShell( tOptions* pOpts ) +optionParseShell(tOptions* pOpts) { /* * Check for our SHELL option now. * IF the output file contains the "#!" magic marker, * it will override anything we do here. */ - if (HAVE_OPT( SHELL )) - pzShell = OPT_ARG( SHELL ); + if (HAVE_GENSHELL_OPT(SHELL)) + pzShell = GENSHELL_OPT_ARG(SHELL); - else if (! ENABLED_OPT( SHELL )) + else if (! ENABLED_GENSHELL_OPT(SHELL)) pzShell = NULL; - else if ((pzShell = getenv( "SHELL" )), + else if ((pzShell = getenv("SHELL")), pzShell == NULL) - pzShell = "/bin/sh"; + pzShell = POSIX_SHELL; /* * Check for a specified output file */ - if (HAVE_OPT( SCRIPT )) - openOutput( OPT_ARG( SCRIPT )); + if (HAVE_GENSHELL_OPT(SCRIPT)) + openOutput(GENSHELL_OPT_ARG(SCRIPT)); - emitUsage( pOpts ); - emitSetup( pOpts ); + emitUsage(pOpts); + emitSetup(pOpts); /* * There are four modes of option processing. */ switch (pOpts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) { case OPTPROC_LONGOPT: - fputs( zLoopCase, stdout ); + fputs(zLoopCase, stdout); - fputs( zLongSelection, stdout ); - fputs( zLongOptInit, stdout ); - emitLong( pOpts ); - printf( zLongOptArg, pOpts->pzPROGNAME ); - fputs( zEndSelection, stdout ); + fputs(zLongSelection, stdout); + fputs(zLongOptInit, stdout); + emitLong(pOpts); + printf(zLongOptArg, pOpts->pzPROGNAME); + fputs(zEndSelection, stdout); - fputs( zNoSelection, stdout ); + fputs(zNoSelection, stdout); break; case 0: - fputs( zLoopOnly, stdout ); - fputs( zLongOptInit, stdout ); - emitLong( pOpts ); - printf( zLongOptArg, pOpts->pzPROGNAME ); + fputs(zLoopOnly, stdout); + fputs(zLongOptInit, stdout); + emitLong(pOpts); + printf(zLongOptArg, pOpts->pzPROGNAME); break; case OPTPROC_SHORTOPT: - fputs( zLoopCase, stdout ); + fputs(zLoopCase, stdout); - fputs( zFlagSelection, stdout ); - fputs( zFlagOptInit, stdout ); - emitFlag( pOpts ); - printf( zFlagOptArg, pOpts->pzPROGNAME ); - fputs( zEndSelection, stdout ); + fputs(zFlagSelection, stdout); + fputs(zFlagOptInit, stdout); + emitFlag(pOpts); + printf(zFlagOptArg, pOpts->pzPROGNAME); + fputs(zEndSelection, stdout); - fputs( zNoSelection, stdout ); + fputs(zNoSelection, stdout); break; case OPTPROC_LONGOPT|OPTPROC_SHORTOPT: - fputs( zLoopCase, stdout ); + fputs(zLoopCase, stdout); - fputs( zLongSelection, stdout ); - fputs( zLongOptInit, stdout ); - emitLong( pOpts ); - printf( zLongOptArg, pOpts->pzPROGNAME ); - fputs( zEndSelection, 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(zFlagSelection, stdout); + fputs(zFlagOptInit, stdout); + emitFlag(pOpts); + printf(zFlagOptArg, pOpts->pzPROGNAME); + fputs(zEndSelection, stdout); - fputs( zNoSelection, stdout ); + fputs(zNoSelection, stdout); break; } - printf( zLoopEnd, pOpts->pzPROGNAME, zTrailerMarker ); + 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 ); + fputs(pzTrailer, stdout); + else if (ENABLED_GENSHELL_OPT(SHELL)) + printf("\nenv | grep '^%s_'\n", pOpts->pzPROGNAME); + + fflush(stdout); + fchmod(STDOUT_FILENO, 0755); + fclose(stdout); + if (ferror(stdout)) { + fputs(zOutputFail, stderr); + exit(EXIT_FAILURE); + } +} + +#ifdef HAVE_WORKING_FORK +static void +emit_var_text(char const * prog, char const * var, int fdin) +{ + FILE * fp = fdopen(fdin, "r" FOPEN_BINARY_FLAG); + int nlct = 0; /* defer newlines and skip trailing ones */ + + printf("%s_%s_TEXT='", prog, var); + if (fp == NULL) + goto skip_text; + + for (;;) { + int ch = fgetc(fp); + switch (ch) { + + case '\n': + nlct++; + break; + + case '\'': + while (nlct > 0) { + fputc('\n', stdout); + nlct--; + } + fputs("'\\''", stdout); + break; + + case EOF: + goto endCharLoop; + + default: + while (nlct > 0) { + fputc('\n', stdout); + nlct--; + } + fputc(ch, stdout); + break; + } + } endCharLoop:; - fflush( stdout ); - fchmod( STDOUT_FILENO, 0755 ); - fclose( stdout ); + fclose(fp); + +skip_text: + + fputs("'\n\n", stdout); } +#endif +/* + * The purpose of this function is to assign "long usage", short usage + * and version information to a shell variable. Rather than wind our + * way through all the logic necessary to emit the text directly, we + * fork(), have our child process emit the text the normal way and + * capture the output in the parent process. + */ static void -textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD ) +textToVariable(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD) { -# define _TT_(n) tSCC z ## n [] = #n; +# define _TT_(n) static char const z ## n [] = #n; TEXTTO_TABLE # undef _TT_ # define _TT_(n) z ## n , - static char const* apzTTNames[] = { TEXTTO_TABLE }; + static char const * apzTTNames[] = { TEXTTO_TABLE }; # undef _TT_ -#if defined(__windows__) && !defined(__CYGWIN__) - printf( "%1$s_%2$s_TEXT='no %2$s text'\n", - pOpts->pzPROGNAME, apzTTNames[ whichVar ]); +#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 ); + fflush(stdout); + fflush(stderr); - if (pipe( pipeFd ) != 0) { - fprintf( stderr, zBadPipe, errno, strerror( errno )); - exit( EXIT_FAILURE ); + 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 ); + 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] ); + /* + * Send both stderr and stdout to the pipe. No matter which + * descriptor is used, we capture the output on the read end. + */ + dup2(pipeFd[1], STDERR_FILENO); + dup2(pipeFd[1], STDOUT_FILENO); + close(pipeFd[0]); switch (whichVar) { case TT_LONGUSAGE: - (*(pOpts->pUsageProc))( pOpts, EXIT_SUCCESS ); + (*(pOpts->pUsageProc))(pOpts, EXIT_SUCCESS); /* NOTREACHED */ - exit( EXIT_FAILURE ); case TT_USAGE: - (*(pOpts->pUsageProc))( pOpts, EXIT_FAILURE ); + (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE); /* NOTREACHED */ - exit( EXIT_FAILURE ); case TT_VERSION: if (pOD->fOptState & OPTST_ALLOC_ARG) { @@ -550,57 +589,26 @@ textToVariable( tOptions* pOpts, teTextTo whichVar, tOptDesc* pOD ) pOD->fOptState &= ~OPTST_ALLOC_ARG; } pOD->optArg.argString = "c"; - optionPrintVersion( pOpts, pOD ); + optionPrintVersion(pOpts, pOD); /* NOTREACHED */ default: - exit( EXIT_FAILURE ); + exit(EXIT_FAILURE); } default: - close( pipeFd[1] ); - fp = fdopen( pipeFd[0], "r" FOPEN_BINARY_FLAG ); + close(pipeFd[1]); } - 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] ); + emit_var_text(pOpts->pzPROGNAME, apzTTNames[whichVar], pipeFd[0]); #endif } static void -emitUsage( tOptions* pOpts ) +emitUsage(tOptions* pOpts) { - char zTimeBuf[ AO_NAME_SIZE ]; + char zTimeBuf[AO_NAME_SIZE]; /* * First, switch stdout to the output file name. @@ -609,45 +617,52 @@ emitUsage( tOptions* pOpts ) * executable name). Down case the upper cased name. */ if (pzLeader != NULL) - fputs( pzLeader, stdout ); + fputs(pzLeader, stdout); { tSCC zStdout[] = "stdout"; tCC* pzOutName; { - time_t curTime = time( NULL ); - struct tm* pTime = localtime( &curTime ); + 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 ); + if (HAVE_GENSHELL_OPT(SCRIPT)) + pzOutName = GENSHELL_OPT_ARG(SCRIPT); else pzOutName = zStdout; if ((pzLeader == NULL) && (pzShell != NULL)) - printf( "#! %s\n", pzShell ); + printf("#! %s\n", pzShell); - printf( zPreamble, zStartMarker, pzOutName, zTimeBuf ); + printf(zPreamble, zStartMarker, pzOutName, zTimeBuf); } + printf(zEndPreamble, pOpts->pzPROGNAME); + /* - * Get a copy of the original program name in lower case + * Get a copy of the original program name in lower case and + * fill in an approximation of the program name from it. */ { - char* pzPN = zTimeBuf; - tCC* pz = pOpts->pzPROGNAME; + char * pzPN = zTimeBuf; + char const * pz = pOpts->pzPROGNAME; + char ** pp; + for (;;) { - if ((*pzPN++ = tolower( *pz++ )) == '\0') + if ((*pzPN++ = tolower(*pz++)) == '\0') break; } - } - printf( zEndPreamble, pOpts->pzPROGNAME ); + pp = (char **)(void *)&(pOpts->pzProgPath); + *pp = zTimeBuf; + pp = (char **)(void *)&(pOpts->pzProgName); + *pp = zTimeBuf; + } - pOpts->pzProgPath = pOpts->pzProgName = zTimeBuf; - textToVariable( pOpts, TT_LONGUSAGE, NULL ); - textToVariable( pOpts, TT_USAGE, NULL ); + textToVariable(pOpts, TT_LONGUSAGE, NULL); + textToVariable(pOpts, TT_USAGE, NULL); { tOptDesc* pOptDesc = pOpts->pOptDesc; @@ -655,7 +670,7 @@ emitUsage( tOptions* pOpts ) for (;;) { if (pOptDesc->pOptProc == optionPrintVersion) { - textToVariable( pOpts, TT_VERSION, pOptDesc ); + textToVariable(pOpts, TT_VERSION, pOptDesc); break; } @@ -668,7 +683,7 @@ emitUsage( tOptions* pOpts ) static void -emitSetup( tOptions* pOpts ) +emitSetup(tOptions* pOpts) { tOptDesc* pOptDesc = pOpts->pOptDesc; int optionCt = pOpts->presetOptCt; @@ -695,7 +710,7 @@ emitSetup( tOptions* pOpts ) */ switch (OPTST_GET_ARGTYPE(pOptDesc->fOptState)) { case OPARG_TYPE_ENUMERATION: - (*(pOptDesc->pOptProc))( (tOptions*)2UL, pOptDesc ); + (*(pOptDesc->pOptProc))(OPTPROC_EMIT_SHELL, pOptDesc ); pzDefault = pOptDesc->optArg.argString; break; @@ -703,14 +718,14 @@ emitSetup( tOptions* pOpts ) * Numeric and membership bit options are just printed as a number. */ case OPARG_TYPE_NUMERIC: - snprintf( zVal, sizeof( zVal ), "%d", - (int)pOptDesc->optArg.argInt ); + 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 ); + snprintf(zVal, sizeof(zVal), "%lu", + (unsigned long)pOptDesc->optArg.argIntptr); pzDefault = zVal; break; @@ -728,99 +743,99 @@ emitSetup( tOptions* pOpts ) pzDefault = pOptDesc->optArg.argString; } - printf( pzFmt, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pzDefault ); + printf(pzFmt, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pzDefault); } } static void -printOptionAction( tOptions* pOpts, tOptDesc* pOptDesc ) +printOptionAction(tOptions* pOpts, tOptDesc* pOptDesc) { if (pOptDesc->pOptProc == optionPrintVersion) - printf( zTextExit, pOpts->pzPROGNAME, "VERSION" ); + printf(zTextExit, pOpts->pzPROGNAME, "VERSION"); else if (pOptDesc->pOptProc == optionPagedUsage) - printf( zPagedUsageExit, pOpts->pzPROGNAME ); + printf(zPagedUsageExit, pOpts->pzPROGNAME); else if (pOptDesc->pOptProc == optionLoadOpt) { - printf( zCmdFmt, "echo 'Warning: Cannot load options files' >&2" ); - printf( zCmdFmt, "OPT_ARG_NEEDED=YES" ); + 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" ); + printf(zCmdFmt, "echo 'Warning: Cannot save options files' " + ">&2"); + printf(zCmdFmt, "OPT_ARG_NEEDED=OK"); } else - printf( zTextExit, pOpts->pzPROGNAME, "LONGUSAGE" ); + printf(zTextExit, pOpts->pzPROGNAME, "LONGUSAGE"); } else { if (pOptDesc->optMaxCt == 1) - printf( zSingleArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); + printf(zSingleArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME); else { if ((unsigned)pOptDesc->optMaxCt < NOLIMIT) - printf( zCountTest, pOpts->pzPROGNAME, - pOptDesc->pz_NAME, pOptDesc->optMaxCt ); + printf(zCountTest, pOpts->pzPROGNAME, + pOptDesc->pz_NAME, pOptDesc->optMaxCt); - printf( zMultiArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); + 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 ); + printf(zCantArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME); } else if (pOptDesc->fOptState & OPTST_ARG_OPTIONAL) { - printf( zMayArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME ); + printf(zMayArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME); } else { - fputs( zMustArg, stdout ); + fputs(zMustArg, stdout); } } - fputs( zOptionEndSelect, stdout ); + fputs(zOptionEndSelect, stdout); } static void -printOptionInaction( tOptions* pOpts, tOptDesc* pOptDesc ) +printOptionInaction(tOptions* pOpts, tOptDesc* pOptDesc) { if (pOptDesc->pOptProc == optionLoadOpt) { - printf( zCmdFmt, "echo 'Warning: Cannot suppress the loading of " - "options files' >&2" ); + 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 ); + printf(zNoSingleArg, pOpts->pzPROGNAME, + pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx); else - printf( zNoMultiArg, pOpts->pzPROGNAME, - pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx ); + printf(zNoMultiArg, pOpts->pzPROGNAME, + pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx); - printf( zCmdFmt, "OPT_ARG_NEEDED=NO" ); - fputs( zOptionEndSelect, stdout ); + printf(zCmdFmt, "OPT_ARG_NEEDED=NO"); + fputs(zOptionEndSelect, stdout); } static void -emitFlag( tOptions* pOpts ) +emitFlag(tOptions* pOpts) { tOptDesc* pOptDesc = pOpts->pOptDesc; int optionCt = pOpts->optCt; - fputs( zOptionCase, stdout ); + fputs(zOptionCase, stdout); for (;optionCt > 0; pOptDesc++, --optionCt) { if (SKIP_OPT(pOptDesc)) continue; - if (isprint( pOptDesc->optValue )) { - printf( zOptionFlag, pOptDesc->optValue ); - printOptionAction( pOpts, pOptDesc ); + if (IS_GRAPHIC_CHAR(pOptDesc->optValue)) { + printf(zOptionFlag, pOptDesc->optValue); + printOptionAction(pOpts, pOptDesc); } } - printf( zOptionUnknown, "flag", pOpts->pzPROGNAME ); + printf(zOptionUnknown, "flag", pOpts->pzPROGNAME); } @@ -828,7 +843,7 @@ emitFlag( tOptions* pOpts ) * Emit the match text for a long option */ static void -emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ) +emitMatchExpr(tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts) { tOptDesc* pOD = pOpts->pOptDesc; int oCt = pOpts->optCt; @@ -854,8 +869,8 @@ emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ) * 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] )) + while ( toupper(pOD->pz_Name[matchCt]) + == toupper(pzMatchName[matchCt])) matchCt++; if (matchCt > min) @@ -866,8 +881,8 @@ emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ) */ if (pOD->pz_DisableName != NULL) { matchCt = 0; - while ( toupper( pOD->pz_DisableName[matchCt] ) - == toupper( pzMatchName[matchCt] )) + while ( toupper(pOD->pz_DisableName[matchCt]) + == toupper(pzMatchName[matchCt])) matchCt++; if (matchCt > min) min = matchCt; @@ -883,7 +898,7 @@ emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ) */ if ( (pzMatchName[min ] == NUL) || (pzMatchName[min+1] == NUL) ) - printf( zOptionFullName, pzMatchName ); + printf(zOptionFullName, pzMatchName); else { int matchCt = 0; @@ -892,11 +907,11 @@ emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ) for (;;) { *pz = NUL; - printf( zOptionPartName, zName ); + printf(zOptionPartName, zName); *pz++ = pzMatchName[matchCt++]; if (pzMatchName[matchCt] == NUL) { *pz = NUL; - printf( zOptionFullName, zName ); + printf(zOptionFullName, zName); break; } } @@ -908,12 +923,12 @@ emitMatchExpr( tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts ) * Emit GNU-standard long option handling code */ static void -emitLong( tOptions* pOpts ) +emitLong(tOptions* pOpts) { tOptDesc* pOD = pOpts->pOptDesc; int ct = pOpts->optCt; - fputs( zOptionCase, stdout ); + fputs(zOptionCase, stdout); /* * do each option, ... @@ -925,24 +940,24 @@ emitLong( tOptions* pOpts ) if (SKIP_OPT(pOD)) continue; - emitMatchExpr( pOD->pz_Name, pOD, pOpts ); - printOptionAction( pOpts, pOD ); + 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 ); + emitMatchExpr(pOD->pz_DisableName, pOD, pOpts); + printOptionInaction(pOpts, pOD); } } while (pOD++, --ct > 0); - printf( zOptionUnknown, "option", pOpts->pzPROGNAME ); + printf(zOptionUnknown, "option", pOpts->pzPROGNAME); } static void -openOutput( char const* pzFile ) +openOutput(char const* pzFile) { FILE* fp; char* pzData = NULL; @@ -957,19 +972,19 @@ openOutput( char const* pzFile ) * THEN assume we are creating a new file. * Skip the loading of the old data. */ - if (stat( pzFile, &stbf ) != 0) + 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 ); + 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 ); + fp = fopen(pzFile, "r" FOPEN_BINARY_FLAG); sizeLeft = (unsigned)stbf.st_size; pzScan = pzData; @@ -978,7 +993,7 @@ openOutput( char const* pzFile ) * Read in all the data as fast as our OS will let us. */ for (;;) { - int inct = fread( (void*)pzScan, (size_t)1, sizeLeft, fp); + int inct = fread((void*)pzScan, (size_t)1, sizeLeft, fp); if (inct == 0) break; @@ -993,29 +1008,32 @@ openOutput( char const* pzFile ) * NUL-terminate the leader and look for the trailer */ *pzScan = '\0'; - fclose( fp ); - pzScan = strstr( pzData, zStartMarker ); + fclose(fp); + pzScan = strstr(pzData, zStartMarker); if (pzScan == NULL) { pzTrailer = pzData; break; } *(pzScan++) = NUL; - pzScan = strstr( pzScan, zTrailerMarker ); + 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 + * Check to see if the data contains our marker. + * If it does, then we will skip over it */ - pzTrailer = pzScan + sizeof( zTrailerMarker ) - 1; + pzTrailer = pzScan + sizeof(zTrailerMarker) - 1; pzLeader = pzData; } while (AG_FALSE); - freopen( pzFile, "w" FOPEN_BINARY_FLAG, stdout ); + if (freopen(pzFile, "w" FOPEN_BINARY_FLAG, stdout) != stdout) { + fprintf(stderr, zFreopenFail, errno, strerror(errno)); + exit(EXIT_FAILURE); + } } @@ -1034,19 +1052,21 @@ openOutput( char const* pzFile ) * and create shell script variables containing the two types of text. =*/ void -genshelloptUsage( tOptions* pOpts, int exitCode ) +genshelloptUsage(tOptions * pOpts, int exitCode) { -#if defined(__windows__) && !defined(__CYGWIN__) - optionUsage( pOpts, exitCode ); +#if ! defined(HAVE_WORKING_FORK) + 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 ); + optionUsage(pOpts, exitCode); + fflush(stderr); + fflush(stdout); + if (ferror(stdout) || ferror(stderr)) + exit(EXIT_FAILURE); option_usage_fp = stdout; @@ -1055,20 +1075,19 @@ genshelloptUsage( tOptions* pOpts, int exitCode ) */ switch (fork()) { case -1: - optionUsage( pOpts, EXIT_FAILURE ); - /*NOTREACHED*/ - _exit( EXIT_FAILURE ); + optionUsage(pOpts, EXIT_FAILURE); + /* NOTREACHED */ case 0: pagerState = PAGER_STATE_CHILD; - optionUsage( pOpts, EXIT_SUCCESS ); - /*NOTREACHED*/ - _exit( EXIT_FAILURE ); + optionUsage(pOpts, EXIT_SUCCESS); + /* NOTREACHED */ + _exit(EXIT_FAILURE); default: { int sts; - wait( &sts ); + wait(&sts); } } @@ -1077,11 +1096,12 @@ genshelloptUsage( tOptions* pOpts, int exitCode ) * gets it from the command line */ { - char* pz; - AGDUPSTR( pz, pShellParseOptions->pzPROGNAME, "program name" ); - pShellParseOptions->pzProgName = pz; + char * pz; + char ** pp = (char **)(void *)&(optionParseShellOptions->pzProgName); + AGDUPSTR(pz, optionParseShellOptions->pzPROGNAME, "program name"); + *pp = pz; while (*pz != NUL) { - *pz = tolower( *pz ); + *pz = tolower(*pz); pz++; } } @@ -1089,8 +1109,8 @@ genshelloptUsage( tOptions* pOpts, int exitCode ) /* * Separate the makeshell usage from the client usage */ - fprintf( option_usage_fp, zGenshell, pShellParseOptions->pzProgName ); - fflush( option_usage_fp ); + fprintf(option_usage_fp, zGenshell, optionParseShellOptions->pzProgName); + fflush(option_usage_fp); /* * Now, print the client usage. @@ -1100,16 +1120,22 @@ genshelloptUsage( tOptions* pOpts, int exitCode ) pagerState = PAGER_STATE_CHILD; /*FALLTHROUGH*/ case -1: - optionUsage( pShellParseOptions, EXIT_FAILURE ); + optionUsage(optionParseShellOptions, EXIT_FAILURE); default: { int sts; - wait( &sts ); + wait(&sts); } } - exit( EXIT_SUCCESS ); + fflush(stdout); + if (ferror(stdout)) { + fputs(zOutputFail, stderr); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); #endif } |