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