|
|
1.1 ! root 1: /* @(#)args.c 1.4 */ ! 2: /* ! 3: * UNIX shell ! 4: * ! 5: * Bell Telephone Laboratories ! 6: * ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: ! 11: static struct dolnod *copyargs(); ! 12: static void freedolh(); ! 13: extern struct dolnod *freeargs(); ! 14: static struct dolnod *dolh; ! 15: static int dollev = 0; ! 16: static char **savdolv; ! 17: static int savdolc; ! 18: ! 19: char flagchar[] = ! 20: { ! 21: 'x', ! 22: 'n', ! 23: 'v', ! 24: 't', ! 25: STDFLG, ! 26: 'i', ! 27: 'e', ! 28: 'k', ! 29: 'u', ! 30: 'f', ! 31: 'a', ! 32: 'p', ! 33: 0 ! 34: }; ! 35: ! 36: char flagadr[sizeof(flagchar)/sizeof(flagchar[0])]; ! 37: ! 38: long flagval[] = ! 39: { ! 40: execpr, ! 41: noexec, ! 42: readpr, ! 43: oneflg, ! 44: stdflg, ! 45: intflg, ! 46: errflg, ! 47: keyflg, ! 48: setflg, ! 49: nofngflg, ! 50: exportflg, ! 51: protflg, ! 52: 0 ! 53: }; ! 54: ! 55: /* ======== option handling ======== */ ! 56: ! 57: ! 58: options(argc,argv) ! 59: char **argv; ! 60: int argc; ! 61: { ! 62: register char *cp; ! 63: register char **argp = argv; ! 64: register char *flagc; ! 65: char *flagp; ! 66: ! 67: if (argc > 1 && *argp[1] == '-') ! 68: { ! 69: /* ! 70: * if first argument is "--" then options are not ! 71: * to be changed. Fix for problems getting ! 72: * $1 starting with a "-" ! 73: */ ! 74: ! 75: cp = argp[1]; ! 76: if (cp[1] == '-') ! 77: { ! 78: argp[1] = argp[0]; ! 79: argc--; ! 80: return(argc); ! 81: } ! 82: if (cp[1] == '\0') ! 83: flags &= ~(execpr|readpr); ! 84: ! 85: /* ! 86: * Step along 'flagchar[]' looking for matches. ! 87: * 'sic' are not legal with 'set' command. ! 88: */ ! 89: ! 90: while (*++cp) ! 91: { ! 92: flagc = flagchar; ! 93: while (*flagc && *flagc != *cp) ! 94: flagc++; ! 95: if (*cp == *flagc) ! 96: { ! 97: if (eq(argv[0], "set") && any(*cp, "sic")) ! 98: failed(argv[1], badopt); ! 99: else ! 100: { ! 101: flags |= flagval[flagc-flagchar]; ! 102: if (flags & errflg) ! 103: eflag = errflg; ! 104: if (*cp == 'p') ! 105: prot_env(); ! 106: } ! 107: } ! 108: else if (*cp == 'c' && argc > 2 && comdiv == 0) ! 109: { ! 110: comdiv = argp[2]; ! 111: argp[1] = argp[0]; ! 112: argp++; ! 113: argc--; ! 114: } ! 115: else ! 116: failed(argv[1],badopt); ! 117: } ! 118: argp[1] = argp[0]; ! 119: argc--; ! 120: } ! 121: else if (argc > 1 && *argp[1] == '+') /* unset flags x, k, t, n, v, e, u, p */ ! 122: { ! 123: cp = argp[1]; ! 124: while (*++cp) ! 125: { ! 126: flagc = flagchar; ! 127: while (*flagc && *flagc != *cp) ! 128: flagc++; ! 129: /* ! 130: * step through flags ! 131: */ ! 132: if (!any(*cp, "sic") && *cp == *flagc) ! 133: { ! 134: /* ! 135: * only turn off if already on ! 136: */ ! 137: if ((flags & flagval[flagc-flagchar])) ! 138: { ! 139: flags &= ~(flagval[flagc-flagchar]); ! 140: if (*cp == 'e') ! 141: eflag = 0; ! 142: } ! 143: } ! 144: } ! 145: argp[1] = argp[0]; ! 146: argc--; ! 147: } ! 148: /* ! 149: * set up $- ! 150: */ ! 151: flagp = flagadr; ! 152: if (flags) ! 153: { ! 154: flagc = flagchar; ! 155: while (*flagc) ! 156: { ! 157: if (flags & flagval[flagc-flagchar]) ! 158: *flagp++ = *flagc; ! 159: flagc++; ! 160: } ! 161: } ! 162: *flagp = 0; ! 163: return(argc); ! 164: } ! 165: ! 166: /* ! 167: * sets up positional parameters ! 168: */ ! 169: setargs(argi) ! 170: char *argi[]; ! 171: { ! 172: register char **argp = argi; /* count args */ ! 173: register int argn = 0; ! 174: register struct dolnod *nxtblk = 0; ! 175: ! 176: while (Rcheat(*argp++) != ENDARGS) ! 177: argn++; ! 178: /* ! 179: * free old ones unless on 'for' loop chain ! 180: */ ! 181: if (dolh) ! 182: nxtblk = dolh->dolnxt; ! 183: freedolh(); ! 184: dolh = copyargs(argi, argn); ! 185: dolc = argn - 1; ! 186: dolh->dolnxt = nxtblk; ! 187: } ! 188: ! 189: ! 190: ! 191: /* ! 192: * pushes a set of positional parameters ! 193: */ ! 194: pushargs(argi) ! 195: char *argi[]; ! 196: { ! 197: register char **argp = argi; /* count args */ ! 198: register int argn = 0; ! 199: register struct dolnod *nxtblk; ! 200: ! 201: while (Rcheat(*argp++) != ENDARGS) ! 202: argn++; ! 203: if (nxtblk = dolh) ! 204: ++nxtblk->doluse; ! 205: else /* if (dollev == 0) */ ! 206: { ! 207: savdolv = dolv; ! 208: savdolc = dolc; ! 209: } ! 210: dolh = copyargs(argi, argn); /* sets dolv also */ ! 211: dolc = argn - 1; ! 212: ++dollev; ! 213: dolh->dolnxt = nxtblk; ! 214: } ! 215: ! 216: ! 217: /* ! 218: * pop a set of positional parameters ! 219: */ ! 220: popargs() ! 221: { ! 222: register char **argp; /* count args */ ! 223: register int argn; ! 224: register struct dolnod *nxtblk = 0; ! 225: ! 226: if (dolh && (nxtblk = dolh->dolnxt)) ! 227: --nxtblk->doluse; ! 228: --dollev; ! 229: freedolh(); ! 230: if (dolh = nxtblk) ! 231: { ! 232: dolv = dolh->dolarg; ! 233: for (argp = dolv, argn = 0; Rcheat(*argp++) != ENDARGS; argn++); ! 234: dolc = argn - 1; ! 235: } ! 236: else /* if (dollev == 0) */ ! 237: { ! 238: dolv = savdolv; ! 239: dolc = savdolc; ! 240: } ! 241: } ! 242: ! 243: ! 244: static void ! 245: freedolh() ! 246: { ! 247: register char **argp; ! 248: register struct dolnod *argblk; ! 249: ! 250: if (argblk = dolh) ! 251: { ! 252: if ((--argblk->doluse) == 0) ! 253: { ! 254: for (argp = argblk->dolarg; Rcheat(*argp) != ENDARGS; argp++) ! 255: shfree(*argp); ! 256: shfree(argblk); ! 257: } ! 258: } ! 259: } ! 260: ! 261: struct dolnod * ! 262: freeargs(blk) ! 263: struct dolnod *blk; ! 264: { ! 265: register char **argp; ! 266: register struct dolnod *argr = 0; ! 267: register struct dolnod *argblk; ! 268: int cnt; ! 269: ! 270: if (argblk = blk) ! 271: { ! 272: argr = argblk->dolfor; ! 273: cnt = --argblk->doluse; ! 274: ! 275: if (argblk == dolh) ! 276: { ! 277: if (cnt == 1) ! 278: return(argr); ! 279: else ! 280: return(argblk); ! 281: } ! 282: else ! 283: { ! 284: if (cnt == 0) ! 285: { ! 286: for (argp = argblk->dolarg; Rcheat(*argp) != ENDARGS; argp++) ! 287: shfree(*argp); ! 288: shfree(argblk); ! 289: } ! 290: } ! 291: } ! 292: return(argr); ! 293: } ! 294: ! 295: static struct dolnod * ! 296: copyargs(from, n) ! 297: char *from[]; ! 298: { ! 299: register struct dolnod *np = (struct dolnod *)shalloc(sizeof(struct dolnod) + sizeof(char**) * n); ! 300: register char **fp = from; ! 301: register char **pp; ! 302: ! 303: np->doluse = 1; /* use count */ ! 304: np->dolnxt = 0; ! 305: np->dolfor = 0; ! 306: pp = np->dolarg; ! 307: dolv = pp; ! 308: ! 309: while (n--) ! 310: *pp++ = make(*fp++); ! 311: *pp++ = ENDARGS; ! 312: return(np); ! 313: } ! 314: ! 315: ! 316: struct dolnod * ! 317: clean_args(blk) ! 318: struct dolnod *blk; ! 319: { ! 320: register char **argp; ! 321: register struct dolnod *argr = 0; ! 322: register struct dolnod *argblk; ! 323: ! 324: if (argblk = blk) ! 325: { ! 326: argr = argblk->dolfor; ! 327: ! 328: if ((--argblk->doluse) == 0) ! 329: { ! 330: for (argp = argblk->dolarg; Rcheat(*argp) != ENDARGS; argp++) ! 331: shfree(*argp); ! 332: shfree(argblk); ! 333: } ! 334: } ! 335: return(argr); ! 336: } ! 337: ! 338: clearup() ! 339: { ! 340: /* ! 341: * force `for' $* lists to go away ! 342: */ ! 343: while (argfor = clean_args(argfor)) ! 344: ; ! 345: /* ! 346: * now throw away pushed on arglists for functions ! 347: */ ! 348: while (dolh && dollev > 0) ! 349: popargs(); ! 350: /* ! 351: * clean up io files ! 352: */ ! 353: while (pop()) ! 354: ; ! 355: ! 356: /* ! 357: * clean up tmp files ! 358: */ ! 359: while (poptemp()) ! 360: ; ! 361: } ! 362: ! 363: struct dolnod * ! 364: useargs() ! 365: { ! 366: if (dolh) ! 367: { ! 368: if (dolh->doluse++ == 1) ! 369: { ! 370: dolh->dolfor = argfor; ! 371: argfor = dolh; ! 372: } ! 373: } ! 374: return(dolh); ! 375: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.