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

1.1     ! misho       1: 
        !             2: /**
        !             3:  * \file putshell.c
        !             4:  *
        !             5:  * Time-stamp:      "2010-09-05 06:10:56 bkorb"
        !             6:  *
        !             7:  *  This module will interpret the options set in the tOptions
        !             8:  *  structure and print them to standard out in a fashion that
        !             9:  *  will allow them to be interpreted by the Bourne or Korn shells.
        !            10:  *
        !            11:  *  This file is part of AutoOpts, a companion to AutoGen.
        !            12:  *  AutoOpts is free software.
        !            13:  *  AutoOpts is Copyright (c) 1992-2011 by Bruce Korb - all rights reserved
        !            14:  *
        !            15:  *  AutoOpts is available under any one of two licenses.  The license
        !            16:  *  in use must be one of these two and the choice is under the control
        !            17:  *  of the user of the license.
        !            18:  *
        !            19:  *   The GNU Lesser General Public License, version 3 or later
        !            20:  *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
        !            21:  *
        !            22:  *   The Modified Berkeley Software Distribution License
        !            23:  *      See the file "COPYING.mbsd"
        !            24:  *
        !            25:  *  These files have the following md5sums:
        !            26:  *
        !            27:  *  43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
        !            28:  *  06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
        !            29:  *  66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
        !            30:  */
        !            31: static char const zOptValFmt[] = "%s_%s=";
        !            32: static char const zOptEnd[]    = "\nexport %s_%s\n";
        !            33: static char const zOptNumFmt[] = "%1$s_%2$s=%3$d # 0x%3$X\nexport %1$s_%2$s\n";
        !            34: 
        !            35: /* = = = START-STATIC-FORWARD = = = */
        !            36: static void
        !            37: print_quot_str(tCC* pzStr);
        !            38: 
        !            39: static void
        !            40: print_enumeration(tOptions * pOpts, tOptDesc * pOD);
        !            41: 
        !            42: static void
        !            43: print_membership(tOptions * pOpts, tOptDesc * pOD);
        !            44: 
        !            45: static void
        !            46: print_stacked_arg(tOptions * pOpts, tOptDesc * pOD);
        !            47: 
        !            48: static void
        !            49: print_reordering(tOptions * pOpts);
        !            50: /* = = = END-STATIC-FORWARD = = = */
        !            51: 
        !            52: /*
        !            53:  *  Make sure embedded single quotes come out okay.  The initial quote has
        !            54:  *  been emitted and the closing quote will be upon return.
        !            55:  */
        !            56: static void
        !            57: print_quot_str(tCC* pzStr)
        !            58: {
        !            59:     /*
        !            60:      *  Handle empty strings to make the rest of the logic simpler.
        !            61:      */
        !            62:     if ((pzStr == NULL) || (*pzStr == NUL)) {
        !            63:         fputs("''", stdout);
        !            64:         return;
        !            65:     }
        !            66: 
        !            67:     /*
        !            68:      *  Emit any single quotes/apostrophes at the start of the string and
        !            69:      *  bail if that is all we need to do.
        !            70:      */
        !            71:     while (*pzStr == '\'') {
        !            72:         fputs("\\'", stdout);
        !            73:         pzStr++;
        !            74:     }
        !            75:     if (*pzStr == NUL)
        !            76:         return;
        !            77: 
        !            78:     /*
        !            79:      *  Start the single quote string
        !            80:      */
        !            81:     fputc('\'', stdout);
        !            82:     for (;;) {
        !            83:         tCC* pz = strchr(pzStr, '\'');
        !            84:         if (pz == NULL)
        !            85:             break;
        !            86: 
        !            87:         /*
        !            88:          *  Emit the string up to the single quote (apostrophe) we just found.
        !            89:          */
        !            90:         (void)fwrite(pzStr, (size_t)(pz - pzStr), (size_t)1, stdout);
        !            91:         fputc('\'', stdout);
        !            92:         pzStr = pz;
        !            93: 
        !            94:         /*
        !            95:          *  Emit an escaped apostrophe for every one we find.
        !            96:          *  If that ends the string, do not re-open the single quotes.
        !            97:          */
        !            98:         while (*++pzStr == '\'')   fputs("\\'", stdout);
        !            99:         if (*pzStr == NUL)
        !           100:             return;
        !           101: 
        !           102:         fputc('\'', stdout);
        !           103:     }
        !           104: 
        !           105:     /*
        !           106:      *  If we broke out of the loop, we must still emit the remaining text
        !           107:      *  and then close the single quote string.
        !           108:      */
        !           109:     fputs(pzStr, stdout);
        !           110:     fputc('\'', stdout);
        !           111: }
        !           112: 
        !           113: static void
        !           114: print_enumeration(tOptions * pOpts, tOptDesc * pOD)
        !           115: {
        !           116:     uintptr_t e_val = pOD->optArg.argEnum;
        !           117:     printf(zOptValFmt, pOpts->pzPROGNAME, pOD->pz_NAME);
        !           118: 
        !           119:     /*
        !           120:      *  Convert value to string, print that and restore numeric value.
        !           121:      */
        !           122:     (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
        !           123:     printf("'%s'", pOD->optArg.argString);
        !           124:     if (pOD->fOptState & OPTST_ALLOC_ARG)
        !           125:         AGFREE(pOD->optArg.argString);
        !           126:     pOD->optArg.argEnum = e_val;
        !           127: 
        !           128:     printf(zOptEnd, pOpts->pzPROGNAME, pOD->pz_NAME);
        !           129: }
        !           130: 
        !           131: static void
        !           132: print_membership(tOptions * pOpts, tOptDesc * pOD)
        !           133: {
        !           134:     char const * pz;
        !           135:     uintptr_t val = 1;
        !           136:     printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
        !           137:            (int)(uintptr_t)(pOD->optCookie));
        !           138:     pOD->optCookie = (void*)(uintptr_t)~0UL;
        !           139:     (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
        !           140: 
        !           141:     /*
        !           142:      *  We are building the typeset list.  The list returned starts with
        !           143:      *  'none + ' for use by option saving stuff.  We must ignore that.
        !           144:      */
        !           145:     pz = pOD->optArg.argString + 7;
        !           146:     while (*pz != NUL) {
        !           147:         printf("typeset -x -i %s_", pOD->pz_NAME);
        !           148:         while (IS_PLUS_N_SPACE_CHAR(*pz))  pz++;
        !           149: 
        !           150:         for (;;) {
        !           151:             int ch = *(pz++);
        !           152:             if (IS_LOWER_CASE_CHAR(ch))   fputc(toupper(ch), stdout);
        !           153:             else if (IS_UPPER_CASE_CHAR(ch))   fputc(ch, stdout);
        !           154:             else if (IS_PLUS_N_SPACE_CHAR(ch)) goto name_done;
        !           155:             else if (ch == NUL)        { pz--; goto name_done; }
        !           156:             else fputc('_', stdout);
        !           157:         } name_done:;
        !           158:         printf("=%1$lu # 0x%1$lX\n", (unsigned long)val);
        !           159:         val <<= 1;
        !           160:     }
        !           161: 
        !           162:     AGFREE(pOD->optArg.argString);
        !           163:     pOD->optArg.argString = NULL;
        !           164:     pOD->fOptState &= ~OPTST_ALLOC_ARG;
        !           165: }
        !           166: 
        !           167: static void
        !           168: print_stacked_arg(tOptions * pOpts, tOptDesc * pOD)
        !           169: {
        !           170:     tSCC zOptCookieCt[] = "%1$s_%2$s_CT=%3$d\nexport %1$s_%2$s_CT\n";
        !           171: 
        !           172:     tArgList*    pAL = (tArgList*)pOD->optCookie;
        !           173:     tCC**        ppz = pAL->apzArgs;
        !           174:     int          ct  = pAL->useCt;
        !           175: 
        !           176:     printf(zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct);
        !           177: 
        !           178:     while (--ct >= 0) {
        !           179:         tSCC numarg_z[] = "%s_%s_%d=";
        !           180:         tSCC end_z[]    = "\nexport %s_%s_%d\n";
        !           181: 
        !           182:         printf(numarg_z, pOpts->pzPROGNAME, pOD->pz_NAME,
        !           183:                pAL->useCt - ct);
        !           184:         print_quot_str(*(ppz++));
        !           185:         printf(end_z, pOpts->pzPROGNAME, pOD->pz_NAME,
        !           186:                pAL->useCt - ct);
        !           187:     }
        !           188: }
        !           189: 
        !           190: static void
        !           191: print_reordering(tOptions * pOpts)
        !           192: {
        !           193:     int  optIx;
        !           194: 
        !           195:     fputs("set --", stdout);
        !           196: 
        !           197:     for (optIx = pOpts->curOptIdx; optIx < pOpts->origArgCt; optIx++) {
        !           198: 
        !           199:         char* pzArg = pOpts->origArgVect[ optIx ];
        !           200: 
        !           201:         if (strchr(pzArg, '\'') == NULL)
        !           202:             printf(" '%s'", pzArg);
        !           203: 
        !           204:         else {
        !           205:             fputs(" '", stdout);
        !           206:             for (;;) {
        !           207:                 char ch = *(pzArg++);
        !           208:                 switch (ch) {
        !           209:                 case '\'':  fputs("'\\''", stdout); break;
        !           210:                 case NUL:   goto arg_done;
        !           211:                 default:    fputc(ch, stdout); break;
        !           212:                 }
        !           213:             } arg_done:;
        !           214:             fputc('\'', stdout);
        !           215:         }
        !           216:     }
        !           217:     fputs("\nOPTION_CT=0\n", stdout);
        !           218: }
        !           219: 
        !           220: /*=export_func  optionPutShell
        !           221:  * what:  write a portable shell script to parse options
        !           222:  * private:
        !           223:  * arg:   tOptions*, pOpts, the program options descriptor
        !           224:  * doc:   This routine will emit portable shell script text for parsing
        !           225:  *        the options described in the option definitions.
        !           226: =*/
        !           227: void
        !           228: optionPutShell(tOptions* pOpts)
        !           229: {
        !           230:     int  optIx = 0;
        !           231:     tSCC zOptCtFmt[]  = "OPTION_CT=%d\nexport OPTION_CT\n";
        !           232:     tSCC zOptDisabl[] = "%1$s_%2$s=%3$s\nexport %1$s_%2$s\n";
        !           233:     tSCC zFullOptFmt[]= "%1$s_%2$s='%3$s'\nexport %1$s_%2$s\n";
        !           234:     tSCC zEquivMode[] = "%1$s_%2$s_MODE='%3$s'\nexport %1$s_%2$s_MODE\n";
        !           235: 
        !           236:     printf(zOptCtFmt, pOpts->curOptIdx-1);
        !           237: 
        !           238:     do  {
        !           239:         tOptDesc* pOD = pOpts->pOptDesc + optIx;
        !           240: 
        !           241:         if (SKIP_OPT(pOD))
        !           242:             continue;
        !           243: 
        !           244:         /*
        !           245:          *  Equivalence classes are hard to deal with.  Where the
        !           246:          *  option data wind up kind of squishes around.  For the purposes
        !           247:          *  of emitting shell state, they are not recommended, but we'll
        !           248:          *  do something.  I guess we'll emit the equivalenced-to option
        !           249:          *  at the point in time when the base option is found.
        !           250:          */
        !           251:         if (pOD->optEquivIndex != NO_EQUIVALENT)
        !           252:             continue; /* equivalence to a different option */
        !           253: 
        !           254:         /*
        !           255:          *  Equivalenced to a different option.  Process the current option
        !           256:          *  as the equivalenced-to option.  Keep the persistent state bits,
        !           257:          *  but copy over the set-state bits.
        !           258:          */
        !           259:         if (pOD->optActualIndex != optIx) {
        !           260:             tOptDesc* p   = pOpts->pOptDesc + pOD->optActualIndex;
        !           261:             p->optArg     = pOD->optArg;
        !           262:             p->fOptState &= OPTST_PERSISTENT_MASK;
        !           263:             p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK;
        !           264:             printf(zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME);
        !           265:             pOD = p;
        !           266:         }
        !           267: 
        !           268:         /*
        !           269:          *  If the argument type is a set membership bitmask, then we always
        !           270:          *  emit the thing.  We do this because it will always have some sort
        !           271:          *  of bitmask value and we need to emit the bit values.
        !           272:          */
        !           273:         if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) {
        !           274:             print_membership(pOpts, pOD);
        !           275:             continue;
        !           276:         }
        !           277: 
        !           278:         /*
        !           279:          *  IF the option was either specified or it wakes up enabled,
        !           280:          *  then we will emit information.  Otherwise, skip it.
        !           281:          *  The idea is that if someone defines an option to initialize
        !           282:          *  enabled, we should tell our shell script that it is enabled.
        !           283:          */
        !           284:         if (UNUSED_OPT(pOD) && DISABLED_OPT(pOD)) {
        !           285:             continue;
        !           286:         }
        !           287: 
        !           288:         /*
        !           289:          *  Handle stacked arguments
        !           290:          */
        !           291:         if (  (pOD->fOptState & OPTST_STACKED)
        !           292:            && (pOD->optCookie != NULL) )  {
        !           293:             print_stacked_arg(pOpts, pOD);
        !           294:             continue;
        !           295:         }
        !           296: 
        !           297:         /*
        !           298:          *  If the argument has been disabled,
        !           299:          *  Then set its value to the disablement string
        !           300:          */
        !           301:         if ((pOD->fOptState & OPTST_DISABLED) != 0) {
        !           302:             printf(zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME,
        !           303:                    (pOD->pz_DisablePfx != NULL)
        !           304:                    ? pOD->pz_DisablePfx : "false");
        !           305:             continue;
        !           306:         }
        !           307: 
        !           308:         /*
        !           309:          *  If the argument type is numeric, the last arg pointer
        !           310:          *  is really the VALUE of the string that was pointed to.
        !           311:          */
        !           312:         if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) {
        !           313:             printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
        !           314:                    (int)pOD->optArg.argInt);
        !           315:             continue;
        !           316:         }
        !           317: 
        !           318:         /*
        !           319:          *  If the argument type is an enumeration, then it is much
        !           320:          *  like a text value, except we call the callback function
        !           321:          *  to emit the value corresponding to the "optArg" number.
        !           322:          */
        !           323:         if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) {
        !           324:             print_enumeration(pOpts, pOD);
        !           325:             continue;
        !           326:         }
        !           327: 
        !           328:         /*
        !           329:          *  If the argument type is numeric, the last arg pointer
        !           330:          *  is really the VALUE of the string that was pointed to.
        !           331:          */
        !           332:         if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) {
        !           333:             printf(zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
        !           334:                    (pOD->optArg.argBool == 0) ? "false" : "true");
        !           335:             continue;
        !           336:         }
        !           337: 
        !           338:         /*
        !           339:          *  IF the option has an empty value,
        !           340:          *  THEN we set the argument to the occurrence count.
        !           341:          */
        !           342:         if (  (pOD->optArg.argString == NULL)
        !           343:            || (pOD->optArg.argString[0] == NUL) ) {
        !           344: 
        !           345:             printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
        !           346:                    pOD->optOccCt);
        !           347:             continue;
        !           348:         }
        !           349: 
        !           350:         /*
        !           351:          *  This option has a text value
        !           352:          */
        !           353:         printf(zOptValFmt, pOpts->pzPROGNAME, pOD->pz_NAME);
        !           354:         print_quot_str(pOD->optArg.argString);
        !           355:         printf(zOptEnd, pOpts->pzPROGNAME, pOD->pz_NAME);
        !           356: 
        !           357:     } while (++optIx < pOpts->presetOptCt );
        !           358: 
        !           359:     if (  ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
        !           360:        && (pOpts->curOptIdx < pOpts->origArgCt))
        !           361:         print_reordering(pOpts);
        !           362: 
        !           363:     fflush(stdout);
        !           364: }
        !           365: 
        !           366: /*
        !           367:  * Local Variables:
        !           368:  * mode: C
        !           369:  * c-file-style: "stroustrup"
        !           370:  * indent-tabs-mode: nil
        !           371:  * End:
        !           372:  * end of autoopts/putshell.c */

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