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>