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