Annotation of embedaddon/ntp/sntp/libopts/putshell.c, revision 1.1.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>