|
|
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.