|
|
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 struct dolnod *freedolh();
13: extern struct dolnod *freeargs();
14: static struct dolnod *dolh;
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: 'k',
28: 'u',
29: 'f',
30: 'a',
31: 'p',
32: 0
33: };
34:
35: long flagval[] =
36: {
37: execpr,
38: noexec,
39: readpr,
40: oneflg,
41: stdflg,
42: intflg,
43: errflg,
44: keyflg,
45: setflg,
46: nofngflg,
47: exportflg,
48: protflg,
49: 0
50: };
51:
52: /* ======== option handling ======== */
53:
54:
55: options(argc,argv)
56: char **argv;
57: int argc;
58: {
59: register char *cp;
60: register char **argp = argv;
61: register char *flagc;
62: char *flagp;
63:
64: if (argc > 1 && *argp[1] == '-')
65: {
66: /*
67: * if first argument is "--" then options are not
68: * to be changed. Fix for problems getting
69: * $1 starting with a "-"
70: */
71:
72: cp = argp[1];
73: if (cp[1] == '-')
74: {
75: argp[1] = argp[0];
76: argc--;
77: return(argc);
78: }
79: if (cp[1] == '\0')
80: flags &= ~(execpr|readpr);
81:
82: /*
83: * Step along 'flagchar[]' looking for matches.
84: * 'sic' are not legal with 'set' command.
85: */
86:
87: while (*++cp)
88: {
89: flagc = flagchar;
90: while (*flagc && *flagc != *cp)
91: flagc++;
92: if (*cp == *flagc)
93: {
94: if (eq(argv[0], "set") && any(*cp, "sic"))
95: failed(argv[1], badopt);
96: else
97: {
98: flags |= flagval[flagc-flagchar];
99: if (flags & errflg)
100: eflag = errflg;
101: if (*cp == 'p')
102: prot_env();
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, p */
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, "sic") && *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:
172: while (Rcheat(*argp++) != ENDARGS)
173: argn++;
174: /*
175: * free old ones unless on for loop chain
176: */
177: freedolh();
178: dolh = copyargs(argi, argn);
179: dolc = argn - 1;
180: }
181:
182:
183: static struct dolnod *
184: freedolh()
185: {
186: register char **argp;
187: register struct dolnod *argblk;
188:
189: if (argblk = dolh)
190: {
191: if ((--argblk->doluse) == 0)
192: {
193: for (argp = argblk->dolarg; Rcheat(*argp) != ENDARGS; argp++)
194: free(*argp);
195: free(argblk);
196: }
197: }
198: }
199:
200: struct dolnod *
201: freeargs(blk)
202: struct dolnod *blk;
203: {
204: register char **argp;
205: register struct dolnod *argr = 0;
206: register struct dolnod *argblk;
207: int cnt;
208:
209: if (argblk = blk)
210: {
211: argr = argblk->dolnxt;
212: cnt = --argblk->doluse;
213:
214: if (argblk == dolh)
215: {
216: if (cnt == 1)
217: return(argr);
218: else
219: return(argblk);
220: }
221: else
222: {
223: if (cnt == 0)
224: {
225: for (argp = argblk->dolarg; Rcheat(*argp) != ENDARGS; argp++)
226: free(*argp);
227: free(argblk);
228: }
229: }
230: }
231: return(argr);
232: }
233:
234: static struct dolnod *
235: copyargs(from, n)
236: char *from[];
237: {
238: register struct dolnod *np = (struct dolnod *)alloc(sizeof(char**) * n + 3 * BYTESPERWORD);
239: register char **fp = from;
240: register char **pp;
241:
242: np->doluse = 1; /* use count */
243: pp = np->dolarg;
244: dolv = pp;
245:
246: while (n--)
247: *pp++ = make(*fp++);
248: *pp++ = ENDARGS;
249: return(np);
250: }
251:
252:
253: struct dolnod *
254: clean_args(blk)
255: struct dolnod *blk;
256: {
257: register char **argp;
258: register struct dolnod *argr = 0;
259: register struct dolnod *argblk;
260:
261: if (argblk = blk)
262: {
263: argr = argblk->dolnxt;
264:
265: if (argblk == dolh)
266: argblk->doluse = 1;
267: else
268: {
269: for (argp = argblk->dolarg; Rcheat(*argp) != ENDARGS; argp++)
270: free(*argp);
271: free(argblk);
272: }
273: }
274: return(argr);
275: }
276:
277: clearup()
278: {
279: /*
280: * force `for' $* lists to go away
281: */
282: while (argfor = clean_args(argfor))
283: ;
284: /*
285: * clean up io files
286: */
287: while (pop())
288: ;
289:
290: /*
291: * clean up tmp files
292: */
293: while (poptemp())
294: ;
295: }
296:
297: struct dolnod *
298: useargs()
299: {
300: if (dolh)
301: {
302: if (dolh->doluse++ == 1)
303: {
304: dolh->dolnxt = argfor;
305: argfor = dolh;
306: }
307: }
308: return(dolh);
309: }
310:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.