Annotation of embedaddon/ntp/sntp/libopts/makeshell.c, revision 1.1

1.1     ! misho       1: 
        !             2: /**
        !             3:  * \file makeshell.c
        !             4:  *
        !             5:  * Time-stamp:      "2011-04-20 11:06:57 bkorb"
        !             6:  *
        !             7:  *  This module will interpret the options set in the tOptions
        !             8:  *  structure and create a Bourne shell script capable of parsing them.
        !             9:  *
        !            10:  *  This file is part of AutoOpts, a companion to AutoGen.
        !            11:  *  AutoOpts is free software.
        !            12:  *  AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
        !            13:  *
        !            14:  *  AutoOpts is available under any one of two licenses.  The license
        !            15:  *  in use must be one of these two and the choice is under the control
        !            16:  *  of the user of the license.
        !            17:  *
        !            18:  *   The GNU Lesser General Public License, version 3 or later
        !            19:  *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
        !            20:  *
        !            21:  *   The Modified Berkeley Software Distribution License
        !            22:  *      See the file "COPYING.mbsd"
        !            23:  *
        !            24:  *  These files have the following md5sums:
        !            25:  *
        !            26:  *  43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
        !            27:  *  06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
        !            28:  *  66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
        !            29:  */
        !            30: 
        !            31: tOptions * optionParseShellOptions = NULL;
        !            32: 
        !            33: /* * * * * * * * * * * * * * * * * * * * *
        !            34:  *
        !            35:  *  Setup Format Strings
        !            36:  */
        !            37: static char const zStartMarker[] =
        !            38: "# # # # # # # # # # -- do not modify this marker --\n#\n"
        !            39: "#  DO NOT EDIT THIS SECTION";
        !            40: 
        !            41: static char const zPreamble[] =
        !            42: "%s OF %s\n#\n"
        !            43: "#  From here to the next `-- do not modify this marker --',\n"
        !            44: "#  the text has been generated %s\n";
        !            45: 
        !            46: static char const zEndPreamble[] =
        !            47: "#  From the %s option definitions\n#\n";
        !            48: 
        !            49: static char const zMultiDef[] = "\n"
        !            50: "if test -z \"${%1$s_%2$s}\"\n"
        !            51: "then\n"
        !            52: "  %1$s_%2$s_CT=0\n"
        !            53: "else\n"
        !            54: "  %1$s_%2$s_CT=1\n"
        !            55: "  %1$s_%2$s_1=\"${%1$s_%2$s}\"\n"
        !            56: "fi\n"
        !            57: "export %1$s_%2$s_CT";
        !            58: 
        !            59: static char const zSingleDef[] = "\n"
        !            60: "%1$s_%2$s=\"${%1$s_%2$s-'%3$s'}\"\n"
        !            61: "%1$s_%2$s_set=false\n"
        !            62: "export %1$s_%2$s\n";
        !            63: 
        !            64: static char const zSingleNoDef[] = "\n"
        !            65: "%1$s_%2$s=\"${%1$s_%2$s}\"\n"
        !            66: "%1$s_%2$s_set=false\n"
        !            67: "export %1$s_%2$s\n";
        !            68: 
        !            69: /* * * * * * * * * * * * * * * * * * * * *
        !            70:  *
        !            71:  *  LOOP START
        !            72:  *
        !            73:  *  The loop may run in either of two modes:
        !            74:  *  all options are named options (loop only)
        !            75:  *  regular, marked option processing.
        !            76:  */
        !            77: static char const zLoopCase[] = "\n"
        !            78: "OPT_PROCESS=true\n"
        !            79: "OPT_ARG=\"$1\"\n\n"
        !            80: "while ${OPT_PROCESS} && [ $# -gt 0 ]\ndo\n"
        !            81: "    OPT_ELEMENT=''\n"
        !            82: "    OPT_ARG_VAL=''\n\n"
        !            83:      /*
        !            84:       *  'OPT_ARG' may or may not match the current $1
        !            85:       */
        !            86: "    case \"${OPT_ARG}\" in\n"
        !            87: "    -- )\n"
        !            88: "        OPT_PROCESS=false\n"
        !            89: "        shift\n"
        !            90: "        ;;\n\n";
        !            91: 
        !            92: static char const zLoopOnly[] = "\n"
        !            93: "OPT_ARG=\"$1\"\n\n"
        !            94: "while [ $# -gt 0 ]\ndo\n"
        !            95: "    OPT_ELEMENT=''\n"
        !            96: "    OPT_ARG_VAL=''\n\n"
        !            97: "    OPT_ARG=\"${1}\"\n";
        !            98: 
        !            99: /* * * * * * * * * * * * * * * *
        !           100:  *
        !           101:  *  CASE SELECTORS
        !           102:  *
        !           103:  *  If the loop runs as a regular option loop,
        !           104:  *  then we must have selectors for each acceptable option
        !           105:  *  type (long option, flag character and non-option)
        !           106:  */
        !           107: static char const zLongSelection[] =
        !           108: "    --* )\n";
        !           109: 
        !           110: static char const zFlagSelection[] =
        !           111: "    -* )\n";
        !           112: 
        !           113: static char const zEndSelection[] =
        !           114: "        ;;\n\n";
        !           115: 
        !           116: static char const zNoSelection[] =
        !           117: "    * )\n"
        !           118: "         OPT_PROCESS=false\n"
        !           119: "         ;;\n"
        !           120: "    esac\n\n";
        !           121: 
        !           122: /* * * * * * * * * * * * * * * *
        !           123:  *
        !           124:  *  LOOP END
        !           125:  */
        !           126: static char const zLoopEnd[] =
        !           127: "    if [ -n \"${OPT_ARG_VAL}\" ]\n"
        !           128: "    then\n"
        !           129: "        eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n"
        !           130: "        export %1$s_${OPT_NAME}${OPT_ELEMENT}\n"
        !           131: "    fi\n"
        !           132: "done\n\n"
        !           133: "unset OPT_PROCESS || :\n"
        !           134: "unset OPT_ELEMENT || :\n"
        !           135: "unset OPT_ARG || :\n"
        !           136: "unset OPT_ARG_NEEDED || :\n"
        !           137: "unset OPT_NAME || :\n"
        !           138: "unset OPT_CODE || :\n"
        !           139: "unset OPT_ARG_VAL || :\n%2$s";
        !           140: 
        !           141: static char const zTrailerMarker[] = "\n"
        !           142: "# # # # # # # # # #\n#\n"
        !           143: "#  END OF AUTOMATED OPTION PROCESSING\n"
        !           144: "#\n# # # # # # # # # # -- do not modify this marker --\n";
        !           145: 
        !           146: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        !           147:  *
        !           148:  *  OPTION SELECTION
        !           149:  */
        !           150: static char const zOptionCase[] =
        !           151: "        case \"${OPT_CODE}\" in\n";
        !           152: 
        !           153: static char const zOptionPartName[] =
        !           154: "        '%s' | \\\n";
        !           155: 
        !           156: static char const zOptionFullName[] =
        !           157: "        '%s' )\n";
        !           158: 
        !           159: static char const zOptionFlag[] =
        !           160: "        '%c' )\n";
        !           161: 
        !           162: static char const zOptionEndSelect[] =
        !           163: "            ;;\n\n";
        !           164: 
        !           165: static char const zOptionUnknown[] =
        !           166: "        * )\n"
        !           167: "            echo Unknown %s: \"${OPT_CODE}\" >&2\n"
        !           168: "            echo \"$%s_USAGE_TEXT\"\n"
        !           169: "            exit 1\n"
        !           170: "            ;;\n"
        !           171: "        esac\n\n";
        !           172: 
        !           173: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        !           174:  *
        !           175:  *  OPTION PROCESSING
        !           176:  *
        !           177:  *  Formats for emitting the text for handling particular options
        !           178:  */
        !           179: static char const zTextExit[] =
        !           180: "            echo \"$%s_%s_TEXT\"\n"
        !           181: "            exit 0\n";
        !           182: 
        !           183: static char const zPagedUsageExit[] =
        !           184: "            echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n"
        !           185: "            exit 0\n";
        !           186: 
        !           187: static char const zCmdFmt[] =
        !           188: "            %s\n";
        !           189: 
        !           190: static char const zCountTest[] =
        !           191: "            if [ $%1$s_%2$s_CT -ge %3$d ] ; then\n"
        !           192: "                echo Error:  more than %3$d %2$s options >&2\n"
        !           193: "                echo \"$%1$s_USAGE_TEXT\"\n"
        !           194: "                exit 1 ; fi\n";
        !           195: 
        !           196: static char const zMultiArg[] =
        !           197: "            %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1`\n"
        !           198: "            OPT_ELEMENT=\"_${%1$s_%2$s_CT}\"\n"
        !           199: "            OPT_NAME='%2$s'\n";
        !           200: 
        !           201: static char const zSingleArg[] =
        !           202: "            if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
        !           203: "                echo Error:  duplicate %2$s option >&2\n"
        !           204: "                echo \"$%1$s_USAGE_TEXT\"\n"
        !           205: "                exit 1 ; fi\n"
        !           206: "            %1$s_%2$s_set=true\n"
        !           207: "            OPT_NAME='%2$s'\n";
        !           208: 
        !           209: static char const zNoMultiArg[] =
        !           210: "            %1$s_%2$s_CT=0\n"
        !           211: "            OPT_ELEMENT=''\n"
        !           212: "            %1$s_%2$s='%3$s'\n"
        !           213: "            export %1$s_%2$s\n"
        !           214: "            OPT_NAME='%2$s'\n";
        !           215: 
        !           216: static char const zNoSingleArg[] =
        !           217: "            if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
        !           218: "                echo Error:  duplicate %2$s option >&2\n"
        !           219: "                echo \"$%1$s_USAGE_TEXT\"\n"
        !           220: "                exit 1 ; fi\n"
        !           221: "            %1$s_%2$s_set=true\n"
        !           222: "            %1$s_%2$s='%3$s'\n"
        !           223: "            export %1$s_%2$s\n"
        !           224: "            OPT_NAME='%2$s'\n";
        !           225: 
        !           226: static char const zMayArg[]  =
        !           227: "            eval %1$s_%2$s${OPT_ELEMENT}=true\n"
        !           228: "            export %1$s_%2$s${OPT_ELEMENT}\n"
        !           229: "            OPT_ARG_NEEDED=OK\n";
        !           230: 
        !           231: static char const zMustArg[] =
        !           232: "            OPT_ARG_NEEDED=YES\n";
        !           233: 
        !           234: static char const zCantArg[] =
        !           235: "            eval %1$s_%2$s${OPT_ELEMENT}=true\n"
        !           236: "            export %1$s_%2$s${OPT_ELEMENT}\n"
        !           237: "            OPT_ARG_NEEDED=NO\n";
        !           238: 
        !           239: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        !           240:  *
        !           241:  *  LONG OPTION PROCESSING
        !           242:  *
        !           243:  *  Formats for emitting the text for handling long option types
        !           244:  */
        !           245: static char const zLongOptInit[] =
        !           246: "        OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n"
        !           247: "        shift\n"
        !           248: "        OPT_ARG=\"$1\"\n\n"
        !           249: "        case \"${OPT_CODE}\" in *=* )\n"
        !           250: "            OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n"
        !           251: "            OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\n";
        !           252: 
        !           253: static char const zLongOptArg[] =
        !           254: "        case \"${OPT_ARG_NEEDED}\" in\n"
        !           255: "        NO )\n"
        !           256: "            OPT_ARG_VAL=''\n"
        !           257: "            ;;\n\n"
        !           258: "        YES )\n"
        !           259: "            if [ -z \"${OPT_ARG_VAL}\" ]\n"
        !           260: "            then\n"
        !           261: "                if [ $# -eq 0 ]\n"
        !           262: "                then\n"
        !           263: "                    echo No argument provided for ${OPT_NAME} option >&2\n"
        !           264: "                    echo \"$%s_USAGE_TEXT\"\n"
        !           265: "                    exit 1\n"
        !           266: "                fi\n\n"
        !           267: "                OPT_ARG_VAL=\"${OPT_ARG}\"\n"
        !           268: "                shift\n"
        !           269: "                OPT_ARG=\"$1\"\n"
        !           270: "            fi\n"
        !           271: "            ;;\n\n"
        !           272: "        OK )\n"
        !           273: "            if [ -z \"${OPT_ARG_VAL}\" ] && [ $# -gt 0 ]\n"
        !           274: "            then\n"
        !           275: "                case \"${OPT_ARG}\" in -* ) ;; * )\n"
        !           276: "                    OPT_ARG_VAL=\"${OPT_ARG}\"\n"
        !           277: "                    shift\n"
        !           278: "                    OPT_ARG=\"$1\" ;; esac\n"
        !           279: "            fi\n"
        !           280: "            ;;\n"
        !           281: "        esac\n";
        !           282: 
        !           283: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
        !           284:  *
        !           285:  *  FLAG OPTION PROCESSING
        !           286:  *
        !           287:  *  Formats for emitting the text for handling flag option types
        !           288:  */
        !           289: static char const zFlagOptInit[] =
        !           290: "        OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n"
        !           291: "        OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\n";
        !           292: 
        !           293: static char const zFlagOptArg[] =
        !           294: "        case \"${OPT_ARG_NEEDED}\" in\n"
        !           295: "        NO )\n"
        !           296: "            if [ -n \"${OPT_ARG}\" ]\n"
        !           297: "            then\n"
        !           298: "                OPT_ARG=-\"${OPT_ARG}\"\n"
        !           299: "            else\n"
        !           300: "                shift\n"
        !           301: "                OPT_ARG=\"$1\"\n"
        !           302: "            fi\n"
        !           303: "            ;;\n\n"
        !           304: "        YES )\n"
        !           305: "            if [ -n \"${OPT_ARG}\" ]\n"
        !           306: "            then\n"
        !           307: "                OPT_ARG_VAL=\"${OPT_ARG}\"\n\n"
        !           308: "            else\n"
        !           309: "                if [ $# -eq 0 ]\n"
        !           310: "                then\n"
        !           311: "                    echo No argument provided for ${OPT_NAME} option >&2\n"
        !           312: "                    echo \"$%s_USAGE_TEXT\"\n"
        !           313: "                    exit 1\n"
        !           314: "                fi\n"
        !           315: "                shift\n"
        !           316: "                OPT_ARG_VAL=\"$1\"\n"
        !           317: "            fi\n\n"
        !           318: "            shift\n"
        !           319: "            OPT_ARG=\"$1\"\n"
        !           320: "            ;;\n\n"
        !           321: "        OK )\n"
        !           322: "            if [ -n \"${OPT_ARG}\" ]\n"
        !           323: "            then\n"
        !           324: "                OPT_ARG_VAL=\"${OPT_ARG}\"\n"
        !           325: "                shift\n"
        !           326: "                OPT_ARG=\"$1\"\n\n"
        !           327: "            else\n"
        !           328: "                shift\n"
        !           329: "                if [ $# -gt 0 ]\n"
        !           330: "                then\n"
        !           331: "                    case \"$1\" in -* ) ;; * )\n"
        !           332: "                        OPT_ARG_VAL=\"$1\"\n"
        !           333: "                        shift ;; esac\n"
        !           334: "                    OPT_ARG=\"$1\"\n"
        !           335: "                fi\n"
        !           336: "            fi\n"
        !           337: "            ;;\n"
        !           338: "        esac\n";
        !           339: 
        !           340: tSCC* pzShell = NULL;
        !           341: static char*  pzLeader  = NULL;
        !           342: static char*  pzTrailer = NULL;
        !           343: 
        !           344: /* = = = START-STATIC-FORWARD = = = */
        !           345: static void
        !           346: emit_var_text(char const * prog, char const * var, int fdin);
        !           347: 
        !           348: static void
        !           349: textToVariable(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD);
        !           350: 
        !           351: static void
        !           352: emitUsage(tOptions* pOpts);
        !           353: 
        !           354: static void
        !           355: emitSetup(tOptions* pOpts);
        !           356: 
        !           357: static void
        !           358: printOptionAction(tOptions* pOpts, tOptDesc* pOptDesc);
        !           359: 
        !           360: static void
        !           361: printOptionInaction(tOptions* pOpts, tOptDesc* pOptDesc);
        !           362: 
        !           363: static void
        !           364: emitFlag(tOptions* pOpts);
        !           365: 
        !           366: static void
        !           367: emitMatchExpr(tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts);
        !           368: 
        !           369: static void
        !           370: emitLong(tOptions* pOpts);
        !           371: 
        !           372: static void
        !           373: openOutput(char const* pzFile);
        !           374: /* = = = END-STATIC-FORWARD = = = */
        !           375: 
        !           376: /*=export_func  optionParseShell
        !           377:  * private:
        !           378:  *
        !           379:  * what:  Decipher a boolean value
        !           380:  * arg:   + tOptions* + pOpts    + program options descriptor +
        !           381:  *
        !           382:  * doc:
        !           383:  *  Emit a shell script that will parse the command line options.
        !           384: =*/
        !           385: void
        !           386: optionParseShell(tOptions* pOpts)
        !           387: {
        !           388:     /*
        !           389:      *  Check for our SHELL option now.
        !           390:      *  IF the output file contains the "#!" magic marker,
        !           391:      *  it will override anything we do here.
        !           392:      */
        !           393:     if (HAVE_GENSHELL_OPT(SHELL))
        !           394:         pzShell = GENSHELL_OPT_ARG(SHELL);
        !           395: 
        !           396:     else if (! ENABLED_GENSHELL_OPT(SHELL))
        !           397:         pzShell = NULL;
        !           398: 
        !           399:     else if ((pzShell = getenv("SHELL")),
        !           400:              pzShell == NULL)
        !           401: 
        !           402:         pzShell = POSIX_SHELL;
        !           403: 
        !           404:     /*
        !           405:      *  Check for a specified output file
        !           406:      */
        !           407:     if (HAVE_GENSHELL_OPT(SCRIPT))
        !           408:         openOutput(GENSHELL_OPT_ARG(SCRIPT));
        !           409: 
        !           410:     emitUsage(pOpts);
        !           411:     emitSetup(pOpts);
        !           412: 
        !           413:     /*
        !           414:      *  There are four modes of option processing.
        !           415:      */
        !           416:     switch (pOpts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) {
        !           417:     case OPTPROC_LONGOPT:
        !           418:         fputs(zLoopCase,        stdout);
        !           419: 
        !           420:         fputs(zLongSelection,   stdout);
        !           421:         fputs(zLongOptInit,     stdout);
        !           422:         emitLong(pOpts);
        !           423:         printf(zLongOptArg,     pOpts->pzPROGNAME);
        !           424:         fputs(zEndSelection,    stdout);
        !           425: 
        !           426:         fputs(zNoSelection,     stdout);
        !           427:         break;
        !           428: 
        !           429:     case 0:
        !           430:         fputs(zLoopOnly,        stdout);
        !           431:         fputs(zLongOptInit,     stdout);
        !           432:         emitLong(pOpts);
        !           433:         printf(zLongOptArg,     pOpts->pzPROGNAME);
        !           434:         break;
        !           435: 
        !           436:     case OPTPROC_SHORTOPT:
        !           437:         fputs(zLoopCase,        stdout);
        !           438: 
        !           439:         fputs(zFlagSelection,   stdout);
        !           440:         fputs(zFlagOptInit,     stdout);
        !           441:         emitFlag(pOpts);
        !           442:         printf(zFlagOptArg,     pOpts->pzPROGNAME);
        !           443:         fputs(zEndSelection,    stdout);
        !           444: 
        !           445:         fputs(zNoSelection,     stdout);
        !           446:         break;
        !           447: 
        !           448:     case OPTPROC_LONGOPT|OPTPROC_SHORTOPT:
        !           449:         fputs(zLoopCase,        stdout);
        !           450: 
        !           451:         fputs(zLongSelection,   stdout);
        !           452:         fputs(zLongOptInit,     stdout);
        !           453:         emitLong(pOpts);
        !           454:         printf(zLongOptArg,     pOpts->pzPROGNAME);
        !           455:         fputs(zEndSelection,    stdout);
        !           456: 
        !           457:         fputs(zFlagSelection,   stdout);
        !           458:         fputs(zFlagOptInit,     stdout);
        !           459:         emitFlag(pOpts);
        !           460:         printf(zFlagOptArg,     pOpts->pzPROGNAME);
        !           461:         fputs(zEndSelection,    stdout);
        !           462: 
        !           463:         fputs(zNoSelection,     stdout);
        !           464:         break;
        !           465:     }
        !           466: 
        !           467:     printf(zLoopEnd, pOpts->pzPROGNAME, zTrailerMarker);
        !           468:     if ((pzTrailer != NULL) && (*pzTrailer != '\0'))
        !           469:         fputs(pzTrailer, stdout);
        !           470:     else if (ENABLED_GENSHELL_OPT(SHELL))
        !           471:         printf("\nenv | grep '^%s_'\n", pOpts->pzPROGNAME);
        !           472: 
        !           473:     fflush(stdout);
        !           474:     fchmod(STDOUT_FILENO, 0755);
        !           475:     fclose(stdout);
        !           476:     if (ferror(stdout)) {
        !           477:         fputs(zOutputFail, stderr);
        !           478:         exit(EXIT_FAILURE);
        !           479:     }
        !           480: }
        !           481: 
        !           482: #ifdef HAVE_WORKING_FORK
        !           483: static void
        !           484: emit_var_text(char const * prog, char const * var, int fdin)
        !           485: {
        !           486:     FILE * fp   = fdopen(fdin, "r" FOPEN_BINARY_FLAG);
        !           487:     int    nlct = 0; /* defer newlines and skip trailing ones */
        !           488: 
        !           489:     printf("%s_%s_TEXT='", prog, var);
        !           490:     if (fp == NULL)
        !           491:         goto skip_text;
        !           492: 
        !           493:     for (;;) {
        !           494:         int  ch = fgetc(fp);
        !           495:         switch (ch) {
        !           496: 
        !           497:         case '\n':
        !           498:             nlct++;
        !           499:             break;
        !           500: 
        !           501:         case '\'':
        !           502:             while (nlct > 0) {
        !           503:                 fputc('\n', stdout);
        !           504:                 nlct--;
        !           505:             }
        !           506:             fputs("'\\''", stdout);
        !           507:             break;
        !           508: 
        !           509:         case EOF:
        !           510:             goto endCharLoop;
        !           511: 
        !           512:         default:
        !           513:             while (nlct > 0) {
        !           514:                 fputc('\n', stdout);
        !           515:                 nlct--;
        !           516:             }
        !           517:             fputc(ch, stdout);
        !           518:             break;
        !           519:         }
        !           520:     } endCharLoop:;
        !           521: 
        !           522:     fclose(fp);
        !           523: 
        !           524: skip_text:
        !           525: 
        !           526:     fputs("'\n\n", stdout);
        !           527: }
        !           528: 
        !           529: #endif
        !           530: 
        !           531: /*
        !           532:  *  The purpose of this function is to assign "long usage", short usage
        !           533:  *  and version information to a shell variable.  Rather than wind our
        !           534:  *  way through all the logic necessary to emit the text directly, we
        !           535:  *  fork(), have our child process emit the text the normal way and
        !           536:  *  capture the output in the parent process.
        !           537:  */
        !           538: static void
        !           539: textToVariable(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD)
        !           540: {
        !           541: #   define _TT_(n) static char const z ## n [] = #n;
        !           542:     TEXTTO_TABLE
        !           543: #   undef _TT_
        !           544: #   define _TT_(n) z ## n ,
        !           545:       static char const * apzTTNames[] = { TEXTTO_TABLE };
        !           546: #   undef _TT_
        !           547: 
        !           548: #if ! defined(HAVE_WORKING_FORK)
        !           549:     printf("%1$s_%2$s_TEXT='no %2$s text'\n",
        !           550:            pOpts->pzPROGNAME, apzTTNames[ whichVar ]);
        !           551: #else
        !           552:     int  pipeFd[2];
        !           553: 
        !           554:     fflush(stdout);
        !           555:     fflush(stderr);
        !           556: 
        !           557:     if (pipe(pipeFd) != 0) {
        !           558:         fprintf(stderr, zBadPipe, errno, strerror(errno));
        !           559:         exit(EXIT_FAILURE);
        !           560:     }
        !           561: 
        !           562:     switch (fork()) {
        !           563:     case -1:
        !           564:         fprintf(stderr, zForkFail, errno, strerror(errno), pOpts->pzProgName);
        !           565:         exit(EXIT_FAILURE);
        !           566:         break;
        !           567: 
        !           568:     case 0:
        !           569:         /*
        !           570:          * Send both stderr and stdout to the pipe.  No matter which
        !           571:          * descriptor is used, we capture the output on the read end.
        !           572:          */
        !           573:         dup2(pipeFd[1], STDERR_FILENO);
        !           574:         dup2(pipeFd[1], STDOUT_FILENO);
        !           575:         close(pipeFd[0]);
        !           576: 
        !           577:         switch (whichVar) {
        !           578:         case TT_LONGUSAGE:
        !           579:             (*(pOpts->pUsageProc))(pOpts, EXIT_SUCCESS);
        !           580:             /* NOTREACHED */
        !           581: 
        !           582:         case TT_USAGE:
        !           583:             (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
        !           584:             /* NOTREACHED */
        !           585: 
        !           586:         case TT_VERSION:
        !           587:             if (pOD->fOptState & OPTST_ALLOC_ARG) {
        !           588:                 AGFREE(pOD->optArg.argString);
        !           589:                 pOD->fOptState &= ~OPTST_ALLOC_ARG;
        !           590:             }
        !           591:             pOD->optArg.argString = "c";
        !           592:             optionPrintVersion(pOpts, pOD);
        !           593:             /* NOTREACHED */
        !           594: 
        !           595:         default:
        !           596:             exit(EXIT_FAILURE);
        !           597:         }
        !           598: 
        !           599:     default:
        !           600:         close(pipeFd[1]);
        !           601:     }
        !           602: 
        !           603:     emit_var_text(pOpts->pzPROGNAME, apzTTNames[whichVar], pipeFd[0]);
        !           604: #endif
        !           605: }
        !           606: 
        !           607: 
        !           608: static void
        !           609: emitUsage(tOptions* pOpts)
        !           610: {
        !           611:     char zTimeBuf[AO_NAME_SIZE];
        !           612: 
        !           613:     /*
        !           614:      *  First, switch stdout to the output file name.
        !           615:      *  Then, change the program name to the one defined
        !           616:      *  by the definitions (rather than the current
        !           617:      *  executable name).  Down case the upper cased name.
        !           618:      */
        !           619:     if (pzLeader != NULL)
        !           620:         fputs(pzLeader, stdout);
        !           621: 
        !           622:     {
        !           623:         tSCC    zStdout[] = "stdout";
        !           624:         tCC*    pzOutName;
        !           625: 
        !           626:         {
        !           627:             time_t    curTime = time(NULL);
        !           628:             struct tm*  pTime = localtime(&curTime);
        !           629:             strftime(zTimeBuf, AO_NAME_SIZE, "%A %B %e, %Y at %r %Z", pTime );
        !           630:         }
        !           631: 
        !           632:         if (HAVE_GENSHELL_OPT(SCRIPT))
        !           633:              pzOutName = GENSHELL_OPT_ARG(SCRIPT);
        !           634:         else pzOutName = zStdout;
        !           635: 
        !           636:         if ((pzLeader == NULL) && (pzShell != NULL))
        !           637:             printf("#! %s\n", pzShell);
        !           638: 
        !           639:         printf(zPreamble, zStartMarker, pzOutName, zTimeBuf);
        !           640:     }
        !           641: 
        !           642:     printf(zEndPreamble, pOpts->pzPROGNAME);
        !           643: 
        !           644:     /*
        !           645:      *  Get a copy of the original program name in lower case and
        !           646:      *  fill in an approximation of the program name from it.
        !           647:      */
        !           648:     {
        !           649:         char *       pzPN = zTimeBuf;
        !           650:         char const * pz   = pOpts->pzPROGNAME;
        !           651:         char **      pp;
        !           652: 
        !           653:         for (;;) {
        !           654:             if ((*pzPN++ = tolower(*pz++)) == '\0')
        !           655:                 break;
        !           656:         }
        !           657: 
        !           658:         pp = (char **)(void *)&(pOpts->pzProgPath);
        !           659:         *pp = zTimeBuf;
        !           660:         pp  = (char **)(void *)&(pOpts->pzProgName);
        !           661:         *pp = zTimeBuf;
        !           662:     }
        !           663: 
        !           664:     textToVariable(pOpts, TT_LONGUSAGE, NULL);
        !           665:     textToVariable(pOpts, TT_USAGE,     NULL);
        !           666: 
        !           667:     {
        !           668:         tOptDesc* pOptDesc = pOpts->pOptDesc;
        !           669:         int       optionCt = pOpts->optCt;
        !           670: 
        !           671:         for (;;) {
        !           672:             if (pOptDesc->pOptProc == optionPrintVersion) {
        !           673:                 textToVariable(pOpts, TT_VERSION, pOptDesc);
        !           674:                 break;
        !           675:             }
        !           676: 
        !           677:             if (--optionCt <= 0)
        !           678:                 break;
        !           679:             pOptDesc++;
        !           680:         }
        !           681:     }
        !           682: }
        !           683: 
        !           684: 
        !           685: static void
        !           686: emitSetup(tOptions* pOpts)
        !           687: {
        !           688:     tOptDesc* pOptDesc = pOpts->pOptDesc;
        !           689:     int       optionCt = pOpts->presetOptCt;
        !           690:     char const* pzFmt;
        !           691:     char const* pzDefault;
        !           692: 
        !           693:     for (;optionCt > 0; pOptDesc++, --optionCt) {
        !           694:         char zVal[16];
        !           695: 
        !           696:         /*
        !           697:          *  Options that are either usage documentation or are compiled out
        !           698:          *  are not to be processed.
        !           699:          */
        !           700:         if (SKIP_OPT(pOptDesc) || (pOptDesc->pz_NAME == NULL))
        !           701:             continue;
        !           702: 
        !           703:         if (pOptDesc->optMaxCt > 1)
        !           704:              pzFmt = zMultiDef;
        !           705:         else pzFmt = zSingleDef;
        !           706: 
        !           707:         /*
        !           708:          *  IF this is an enumeration/bitmask option, then convert the value
        !           709:          *  to a string before printing the default value.
        !           710:          */
        !           711:         switch (OPTST_GET_ARGTYPE(pOptDesc->fOptState)) {
        !           712:         case OPARG_TYPE_ENUMERATION:
        !           713:             (*(pOptDesc->pOptProc))(OPTPROC_EMIT_SHELL, pOptDesc );
        !           714:             pzDefault = pOptDesc->optArg.argString;
        !           715:             break;
        !           716: 
        !           717:         /*
        !           718:          *  Numeric and membership bit options are just printed as a number.
        !           719:          */
        !           720:         case OPARG_TYPE_NUMERIC:
        !           721:             snprintf(zVal, sizeof(zVal), "%d",
        !           722:                      (int)pOptDesc->optArg.argInt);
        !           723:             pzDefault = zVal;
        !           724:             break;
        !           725: 
        !           726:         case OPARG_TYPE_MEMBERSHIP:
        !           727:             snprintf(zVal, sizeof(zVal), "%lu",
        !           728:                      (unsigned long)pOptDesc->optArg.argIntptr);
        !           729:             pzDefault = zVal;
        !           730:             break;
        !           731: 
        !           732:         case OPARG_TYPE_BOOLEAN:
        !           733:             pzDefault = (pOptDesc->optArg.argBool) ? "true" : "false";
        !           734:             break;
        !           735: 
        !           736:         default:
        !           737:             if (pOptDesc->optArg.argString == NULL) {
        !           738:                 if (pzFmt == zSingleDef)
        !           739:                     pzFmt = zSingleNoDef;
        !           740:                 pzDefault = NULL;
        !           741:             }
        !           742:             else
        !           743:                 pzDefault = pOptDesc->optArg.argString;
        !           744:         }
        !           745: 
        !           746:         printf(pzFmt, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pzDefault);
        !           747:     }
        !           748: }
        !           749: 
        !           750: 
        !           751: static void
        !           752: printOptionAction(tOptions* pOpts, tOptDesc* pOptDesc)
        !           753: {
        !           754:     if (pOptDesc->pOptProc == optionPrintVersion)
        !           755:         printf(zTextExit, pOpts->pzPROGNAME, "VERSION");
        !           756: 
        !           757:     else if (pOptDesc->pOptProc == optionPagedUsage)
        !           758:         printf(zPagedUsageExit, pOpts->pzPROGNAME);
        !           759: 
        !           760:     else if (pOptDesc->pOptProc == optionLoadOpt) {
        !           761:         printf(zCmdFmt, "echo 'Warning:  Cannot load options files' >&2");
        !           762:         printf(zCmdFmt, "OPT_ARG_NEEDED=YES");
        !           763: 
        !           764:     } else if (pOptDesc->pz_NAME == NULL) {
        !           765: 
        !           766:         if (pOptDesc->pOptProc == NULL) {
        !           767:             printf(zCmdFmt, "echo 'Warning:  Cannot save options files' "
        !           768:                     ">&2");
        !           769:             printf(zCmdFmt, "OPT_ARG_NEEDED=OK");
        !           770:         } else
        !           771:             printf(zTextExit, pOpts->pzPROGNAME, "LONGUSAGE");
        !           772: 
        !           773:     } else {
        !           774:         if (pOptDesc->optMaxCt == 1)
        !           775:             printf(zSingleArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
        !           776:         else {
        !           777:             if ((unsigned)pOptDesc->optMaxCt < NOLIMIT)
        !           778:                 printf(zCountTest, pOpts->pzPROGNAME,
        !           779:                        pOptDesc->pz_NAME, pOptDesc->optMaxCt);
        !           780: 
        !           781:             printf(zMultiArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
        !           782:         }
        !           783: 
        !           784:         /*
        !           785:          *  Fix up the args.
        !           786:          */
        !           787:         if (OPTST_GET_ARGTYPE(pOptDesc->fOptState) == OPARG_TYPE_NONE) {
        !           788:             printf(zCantArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
        !           789: 
        !           790:         } else if (pOptDesc->fOptState & OPTST_ARG_OPTIONAL) {
        !           791:             printf(zMayArg,  pOpts->pzPROGNAME, pOptDesc->pz_NAME);
        !           792: 
        !           793:         } else {
        !           794:             fputs(zMustArg, stdout);
        !           795:         }
        !           796:     }
        !           797:     fputs(zOptionEndSelect, stdout);
        !           798: }
        !           799: 
        !           800: 
        !           801: static void
        !           802: printOptionInaction(tOptions* pOpts, tOptDesc* pOptDesc)
        !           803: {
        !           804:     if (pOptDesc->pOptProc == optionLoadOpt) {
        !           805:         printf(zCmdFmt, "echo 'Warning:  Cannot suppress the loading of "
        !           806:                 "options files' >&2");
        !           807: 
        !           808:     } else if (pOptDesc->optMaxCt == 1)
        !           809:         printf(zNoSingleArg, pOpts->pzPROGNAME,
        !           810:                pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx);
        !           811:     else
        !           812:         printf(zNoMultiArg, pOpts->pzPROGNAME,
        !           813:                pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx);
        !           814: 
        !           815:     printf(zCmdFmt, "OPT_ARG_NEEDED=NO");
        !           816:     fputs(zOptionEndSelect, stdout);
        !           817: }
        !           818: 
        !           819: 
        !           820: static void
        !           821: emitFlag(tOptions* pOpts)
        !           822: {
        !           823:     tOptDesc* pOptDesc = pOpts->pOptDesc;
        !           824:     int       optionCt = pOpts->optCt;
        !           825: 
        !           826:     fputs(zOptionCase, stdout);
        !           827: 
        !           828:     for (;optionCt > 0; pOptDesc++, --optionCt) {
        !           829: 
        !           830:         if (SKIP_OPT(pOptDesc))
        !           831:             continue;
        !           832: 
        !           833:         if (IS_GRAPHIC_CHAR(pOptDesc->optValue)) {
        !           834:             printf(zOptionFlag, pOptDesc->optValue);
        !           835:             printOptionAction(pOpts, pOptDesc);
        !           836:         }
        !           837:     }
        !           838:     printf(zOptionUnknown, "flag", pOpts->pzPROGNAME);
        !           839: }
        !           840: 
        !           841: 
        !           842: /*
        !           843:  *  Emit the match text for a long option
        !           844:  */
        !           845: static void
        !           846: emitMatchExpr(tCC* pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts)
        !           847: {
        !           848:     tOptDesc* pOD = pOpts->pOptDesc;
        !           849:     int       oCt = pOpts->optCt;
        !           850:     int       min = 1;
        !           851:     char      zName[ 256 ];
        !           852:     char*     pz  = zName;
        !           853: 
        !           854:     for (;;) {
        !           855:         int matchCt = 0;
        !           856: 
        !           857:         /*
        !           858:          *  Omit the current option, Documentation opts and compiled out opts.
        !           859:          */
        !           860:         if ((pOD == pCurOpt) || SKIP_OPT(pOD)){
        !           861:             if (--oCt <= 0)
        !           862:                 break;
        !           863:             pOD++;
        !           864:             continue;
        !           865:         }
        !           866: 
        !           867:         /*
        !           868:          *  Check each character of the name case insensitively.
        !           869:          *  They must not be the same.  They cannot be, because it would
        !           870:          *  not compile correctly if they were.
        !           871:          */
        !           872:         while (  toupper(pOD->pz_Name[matchCt])
        !           873:               == toupper(pzMatchName[matchCt]))
        !           874:             matchCt++;
        !           875: 
        !           876:         if (matchCt > min)
        !           877:             min = matchCt;
        !           878: 
        !           879:         /*
        !           880:          *  Check the disablement name, too.
        !           881:          */
        !           882:         if (pOD->pz_DisableName != NULL) {
        !           883:             matchCt = 0;
        !           884:             while (  toupper(pOD->pz_DisableName[matchCt])
        !           885:                   == toupper(pzMatchName[matchCt]))
        !           886:                 matchCt++;
        !           887:             if (matchCt > min)
        !           888:                 min = matchCt;
        !           889:         }
        !           890:         if (--oCt <= 0)
        !           891:             break;
        !           892:         pOD++;
        !           893:     }
        !           894: 
        !           895:     /*
        !           896:      *  IF the 'min' is all or one short of the name length,
        !           897:      *  THEN the entire string must be matched.
        !           898:      */
        !           899:     if (  (pzMatchName[min  ] == NUL)
        !           900:        || (pzMatchName[min+1] == NUL) )
        !           901:         printf(zOptionFullName, pzMatchName);
        !           902: 
        !           903:     else {
        !           904:         int matchCt = 0;
        !           905:         for (; matchCt <= min; matchCt++)
        !           906:             *pz++ = pzMatchName[matchCt];
        !           907: 
        !           908:         for (;;) {
        !           909:             *pz = NUL;
        !           910:             printf(zOptionPartName, zName);
        !           911:             *pz++ = pzMatchName[matchCt++];
        !           912:             if (pzMatchName[matchCt] == NUL) {
        !           913:                 *pz = NUL;
        !           914:                 printf(zOptionFullName, zName);
        !           915:                 break;
        !           916:             }
        !           917:         }
        !           918:     }
        !           919: }
        !           920: 
        !           921: 
        !           922: /*
        !           923:  *  Emit GNU-standard long option handling code
        !           924:  */
        !           925: static void
        !           926: emitLong(tOptions* pOpts)
        !           927: {
        !           928:     tOptDesc* pOD = pOpts->pOptDesc;
        !           929:     int       ct  = pOpts->optCt;
        !           930: 
        !           931:     fputs(zOptionCase, stdout);
        !           932: 
        !           933:     /*
        !           934:      *  do each option, ...
        !           935:      */
        !           936:     do  {
        !           937:         /*
        !           938:          *  Documentation & compiled-out options
        !           939:          */
        !           940:         if (SKIP_OPT(pOD))
        !           941:             continue;
        !           942: 
        !           943:         emitMatchExpr(pOD->pz_Name, pOD, pOpts);
        !           944:         printOptionAction(pOpts, pOD);
        !           945: 
        !           946:         /*
        !           947:          *  Now, do the same thing for the disablement version of the option.
        !           948:          */
        !           949:         if (pOD->pz_DisableName != NULL) {
        !           950:             emitMatchExpr(pOD->pz_DisableName, pOD, pOpts);
        !           951:             printOptionInaction(pOpts, pOD);
        !           952:         }
        !           953:     } while (pOD++, --ct > 0);
        !           954: 
        !           955:     printf(zOptionUnknown, "option", pOpts->pzPROGNAME);
        !           956: }
        !           957: 
        !           958: 
        !           959: static void
        !           960: openOutput(char const* pzFile)
        !           961: {
        !           962:     FILE* fp;
        !           963:     char* pzData = NULL;
        !           964:     struct stat stbf;
        !           965: 
        !           966:     do  {
        !           967:         char*    pzScan;
        !           968:         size_t sizeLeft;
        !           969: 
        !           970:         /*
        !           971:          *  IF we cannot stat the file,
        !           972:          *  THEN assume we are creating a new file.
        !           973:          *       Skip the loading of the old data.
        !           974:          */
        !           975:         if (stat(pzFile, &stbf) != 0)
        !           976:             break;
        !           977: 
        !           978:         /*
        !           979:          *  The file must be a regular file
        !           980:          */
        !           981:         if (! S_ISREG(stbf.st_mode)) {
        !           982:             fprintf(stderr, zNotFile, pzFile);
        !           983:             exit(EXIT_FAILURE);
        !           984:         }
        !           985: 
        !           986:         pzData = AGALOC(stbf.st_size + 1, "file data");
        !           987:         fp = fopen(pzFile, "r" FOPEN_BINARY_FLAG);
        !           988: 
        !           989:         sizeLeft = (unsigned)stbf.st_size;
        !           990:         pzScan   = pzData;
        !           991: 
        !           992:         /*
        !           993:          *  Read in all the data as fast as our OS will let us.
        !           994:          */
        !           995:         for (;;) {
        !           996:             int inct = fread((void*)pzScan, (size_t)1, sizeLeft, fp);
        !           997:             if (inct == 0)
        !           998:                 break;
        !           999: 
        !          1000:             pzScan   += inct;
        !          1001:             sizeLeft -= inct;
        !          1002: 
        !          1003:             if (sizeLeft == 0)
        !          1004:                 break;
        !          1005:         }
        !          1006: 
        !          1007:         /*
        !          1008:          *  NUL-terminate the leader and look for the trailer
        !          1009:          */
        !          1010:         *pzScan = '\0';
        !          1011:         fclose(fp);
        !          1012:         pzScan  = strstr(pzData, zStartMarker);
        !          1013:         if (pzScan == NULL) {
        !          1014:             pzTrailer = pzData;
        !          1015:             break;
        !          1016:         }
        !          1017: 
        !          1018:         *(pzScan++) = NUL;
        !          1019:         pzScan  = strstr(pzScan, zTrailerMarker);
        !          1020:         if (pzScan == NULL) {
        !          1021:             pzTrailer = pzData;
        !          1022:             break;
        !          1023:         }
        !          1024: 
        !          1025:         /*
        !          1026:          *  Check to see if the data contains our marker.
        !          1027:          *  If it does, then we will skip over it
        !          1028:          */
        !          1029:         pzTrailer = pzScan + sizeof(zTrailerMarker) - 1;
        !          1030:         pzLeader  = pzData;
        !          1031:     } while (AG_FALSE);
        !          1032: 
        !          1033:     if (freopen(pzFile, "w" FOPEN_BINARY_FLAG, stdout) != stdout) {
        !          1034:         fprintf(stderr, zFreopenFail, errno, strerror(errno));
        !          1035:         exit(EXIT_FAILURE);
        !          1036:     }
        !          1037: }
        !          1038: 
        !          1039: 
        !          1040: /*=export_func genshelloptUsage
        !          1041:  * private:
        !          1042:  * what: The usage function for the genshellopt generated program
        !          1043:  *
        !          1044:  * arg:  + tOptions* + pOpts    + program options descriptor +
        !          1045:  * arg:  + int       + exitCode + usage text type to produce +
        !          1046:  *
        !          1047:  * doc:
        !          1048:  *  This function is used to create the usage strings for the option
        !          1049:  *  processing shell script code.  Two child processes are spawned
        !          1050:  *  each emitting the usage text in either the short (error exit)
        !          1051:  *  style or the long style.  The generated program will capture this
        !          1052:  *  and create shell script variables containing the two types of text.
        !          1053: =*/
        !          1054: void
        !          1055: genshelloptUsage(tOptions * pOpts, int exitCode)
        !          1056: {
        !          1057: #if ! defined(HAVE_WORKING_FORK)
        !          1058:     optionUsage(pOpts, exitCode);
        !          1059: #else
        !          1060:     /*
        !          1061:      *  IF not EXIT_SUCCESS,
        !          1062:      *  THEN emit the short form of usage.
        !          1063:      */
        !          1064:     if (exitCode != EXIT_SUCCESS)
        !          1065:         optionUsage(pOpts, exitCode);
        !          1066:     fflush(stderr);
        !          1067:     fflush(stdout);
        !          1068:     if (ferror(stdout) || ferror(stderr))
        !          1069:         exit(EXIT_FAILURE);
        !          1070: 
        !          1071:     option_usage_fp = stdout;
        !          1072: 
        !          1073:     /*
        !          1074:      *  First, print our usage
        !          1075:      */
        !          1076:     switch (fork()) {
        !          1077:     case -1:
        !          1078:         optionUsage(pOpts, EXIT_FAILURE);
        !          1079:         /* NOTREACHED */
        !          1080: 
        !          1081:     case 0:
        !          1082:         pagerState = PAGER_STATE_CHILD;
        !          1083:         optionUsage(pOpts, EXIT_SUCCESS);
        !          1084:         /* NOTREACHED */
        !          1085:         _exit(EXIT_FAILURE);
        !          1086: 
        !          1087:     default:
        !          1088:     {
        !          1089:         int  sts;
        !          1090:         wait(&sts);
        !          1091:     }
        !          1092:     }
        !          1093: 
        !          1094:     /*
        !          1095:      *  Generate the pzProgName, since optionProcess() normally
        !          1096:      *  gets it from the command line
        !          1097:      */
        !          1098:     {
        !          1099:         char *  pz;
        !          1100:         char ** pp = (char **)(void *)&(optionParseShellOptions->pzProgName);
        !          1101:         AGDUPSTR(pz, optionParseShellOptions->pzPROGNAME, "program name");
        !          1102:         *pp = pz;
        !          1103:         while (*pz != NUL) {
        !          1104:             *pz = tolower(*pz);
        !          1105:             pz++;
        !          1106:         }
        !          1107:     }
        !          1108: 
        !          1109:     /*
        !          1110:      *  Separate the makeshell usage from the client usage
        !          1111:      */
        !          1112:     fprintf(option_usage_fp, zGenshell, optionParseShellOptions->pzProgName);
        !          1113:     fflush(option_usage_fp);
        !          1114: 
        !          1115:     /*
        !          1116:      *  Now, print the client usage.
        !          1117:      */
        !          1118:     switch (fork()) {
        !          1119:     case 0:
        !          1120:         pagerState = PAGER_STATE_CHILD;
        !          1121:         /*FALLTHROUGH*/
        !          1122:     case -1:
        !          1123:         optionUsage(optionParseShellOptions, EXIT_FAILURE);
        !          1124: 
        !          1125:     default:
        !          1126:     {
        !          1127:         int  sts;
        !          1128:         wait(&sts);
        !          1129:     }
        !          1130:     }
        !          1131: 
        !          1132:     fflush(stdout);
        !          1133:     if (ferror(stdout)) {
        !          1134:         fputs(zOutputFail, stderr);
        !          1135:         exit(EXIT_FAILURE);
        !          1136:     }
        !          1137: 
        !          1138:     exit(EXIT_SUCCESS);
        !          1139: #endif
        !          1140: }
        !          1141: 
        !          1142: /*
        !          1143:  * Local Variables:
        !          1144:  * mode: C
        !          1145:  * c-file-style: "stroustrup"
        !          1146:  * indent-tabs-mode: nil
        !          1147:  * End:
        !          1148:  * end of autoopts/makeshell.c */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>