|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #include "sh.h"
3:
4: /*
5: * C Shell
6: */
7:
8: doset(v)
9: register char **v;
10: {
11: register char *p;
12: char *vp, op;
13: bool hadsub;
14: int subscr;
15:
16: v++;
17: p = *v++;
18: if (p == 0) {
19: prvars();
20: return;
21: }
22: do {
23: hadsub = 0;
24: for (vp = p; letter(*p); p++)
25: continue;
26: if (vp == p)
27: goto setsyn;
28: if (*p == '[') {
29: hadsub++;
30: p = getinx(p, &subscr);
31: }
32: if (op = *p) {
33: *p++ = 0;
34: if (*p == 0 && *v && **v == '(')
35: p = *v++;
36: } else if (*v && eq(*v, "=")) {
37: op = '=', v++;
38: if (*v)
39: p = *v++;
40: }
41: if (op && op != '=')
42: setsyn:
43: bferr("Syntax error");
44: if (eq(p, "(")) {
45: register char **e = v;
46:
47: if (hadsub)
48: goto setsyn;
49: for (;;) {
50: if (!*e)
51: bferr("Missing )");
52: if (**e == ')')
53: break;
54: e++;
55: }
56: p = *e, *e = 0, set1(vp, saveblk(v), &shvhed), *e = p;
57: v = e + 1;
58: } else if (hadsub)
59: asx(vp, subscr, savestr(p));
60: else
61: set(vp, savestr(p));
62: if (strcmp(vp, "path") == 0)
63: dohash();
64: } while (p = *v++);
65: }
66:
67: char *
68: getinx(cp, ip)
69: register char *cp;
70: register int *ip;
71: {
72:
73: *ip = 0;
74: *cp++ = 0;
75: while (*cp && digit(*cp))
76: *ip = *ip * 10 + *cp++ - '0';
77: if (*cp++ != ']')
78: bferr("Subscript error");
79: return (cp);
80: }
81:
82: asx(vp, subscr, p)
83: char *vp;
84: int subscr;
85: char *p;
86: {
87: register struct varent *v = getvx(vp, subscr);
88:
89: xfree(v->vec[subscr - 1]);
90: v->vec[subscr - 1] = globone(p);
91: }
92:
93: struct varent *
94: getvx(vp, subscr)
95: {
96: register struct varent *v = adrof(vp);
97:
98: if (v == 0)
99: udvar(vp);
100: if (subscr < 1 || subscr > blklen(v->vec))
101: bferr("Subscript out of range");
102: return (v);
103: }
104:
105: char plusplus[2] = { '1', 0 };
106:
107:
108: dolet(v)
109: char **v;
110: {
111: register char *p;
112: char *vp, c, op;
113: bool hadsub;
114: int subscr;
115:
116: v++;
117: p = *v++;
118: if (p == 0) {
119: prvars();
120: return;
121: }
122: do {
123: hadsub = 0;
124: for (vp = p; letter(*p); p++)
125: continue;
126: if (vp == p)
127: goto letsyn;
128: if (*p == '[') {
129: hadsub++;
130: p = getinx(p, &subscr);
131: }
132: if (*p == 0 && *v)
133: p = *v++;
134: if (op = *p)
135: *p++ = 0;
136: else
137: goto letsyn;
138: vp = savestr(vp);
139: if (op == '=') {
140: c = '=';
141: p = xset(p, &v);
142: } else {
143: c = *p++;
144: if (any(c, "+-")) {
145: if (c != op || *p)
146: goto letsyn;
147: p = plusplus;
148: } else {
149: if (any(op, "<>")) {
150: if (c != op)
151: goto letsyn;
152: c = *p++;
153: letsyn:
154: bferr("Syntax error");
155: }
156: if (c != '=')
157: goto letsyn;
158: p = xset(p, &v);
159: }
160: }
161: if (op == '=')
162: if (hadsub)
163: asx(vp, subscr, p);
164: else
165: set(vp, p);
166: else
167: if (hadsub)
168: #ifndef V6
169: /* avoid bug in vax CC */
170: {
171: struct varent *gv = getvx(vp, subscr);
172:
173: asx(vp, subscr, operate(op, gv->vec[subscr - 1], p));
174: }
175: #else
176: asx(vp, subscr, operate(op, getvx(vp, subscr)->vec[subscr - 1], p));
177: #endif
178: else
179: set(vp, operate(op, value(vp), p));
180: if (strcmp(vp, "path") == 0)
181: dohash();
182: xfree(vp);
183: if (c != '=')
184: xfree(p);
185: } while (p = *v++);
186: }
187:
188: char *
189: xset(cp, vp)
190: char *cp, ***vp;
191: {
192: register char *dp;
193:
194: if (*cp) {
195: dp = savestr(cp);
196: --(*vp);
197: xfree(**vp);
198: **vp = dp;
199: }
200: return (putn(exp(vp)));
201: }
202:
203: char *
204: operate(op, vp, p)
205: char op, *vp, *p;
206: {
207: char opr[2];
208: char *vec[5];
209: register char **v = vec;
210: char **vecp = v;
211: register int i;
212:
213: if (op != '=') {
214: if (*vp)
215: *v++ = vp;
216: opr[0] = op;
217: opr[1] = 0;
218: *v++ = opr;
219: if (op == '<' || op == '>')
220: *v++ = opr;
221: }
222: *v++ = p;
223: *v++ = 0;
224: i = exp(&vecp);
225: if (*vecp)
226: bferr("Expression syntax");
227: return (putn(i));
228: }
229:
230: onlyread(cp)
231: char *cp;
232: {
233: extern char end[];
234:
235: return (cp < end);
236: }
237:
238: xfree(cp)
239: char *cp;
240: {
241: extern char end[];
242:
243: if (cp >= end && cp < (char *) &cp)
244: cfree(cp);
245: }
246:
247: char *
248: savestr(s)
249: register char *s;
250: {
251:
252: if (s == 0)
253: s = "";
254: return (strcpy(calloc(1, strlen(s) + 1), s));
255: }
256:
257: static char *putp;
258:
259: char *
260: putn(n)
261: register int n;
262: {
263: static char number[15];
264:
265: putp = number;
266: if (n < 0) {
267: n = -n;
268: *putp++ = '-';
269: }
270: if (sizeof (int) == 2 && n == -32768) {
271: *putp++ = '3';
272: n = 2768;
273: #ifdef pdp11
274: }
275: #else
276: } else if (sizeof (int) == 4 && n == -2147483648) {
277: *putp++ = '2';
278: n = 147483648;
279: }
280: #endif
281: putn1(n);
282: *putp = 0;
283: return (savestr(number));
284: }
285:
286: putn1(n)
287: register int n;
288: {
289: if (n > 9)
290: putn1(n / 10);
291: *putp++ = n % 10 + '0';
292: }
293:
294: getn(cp)
295: register char *cp;
296: {
297: register int n;
298: int sign;
299:
300: sign = 0;
301: if (cp[0] == '+' && cp[1])
302: cp++;
303: if (*cp == '-') {
304: sign++;
305: cp++;
306: if (!digit(*cp))
307: goto badnum;
308: }
309: n = 0;
310: while (digit(*cp))
311: n = n * 10 + *cp++ - '0';
312: if (*cp)
313: goto badnum;
314: return (sign ? -n : n);
315: badnum:
316: bferr("Badly formed number");
317: return (0);
318: }
319:
320: char *
321: value(var)
322: char *var;
323: {
324:
325: return (value1(var, &shvhed));
326: }
327:
328: char *
329: value1(var, head)
330: char *var;
331: struct varent *head;
332: {
333: register struct varent *vp;
334:
335: vp = adrof1(var, head);
336: return (vp == 0 || vp->vec[0] == 0 ? "" : vp->vec[0]);
337: }
338:
339: static struct varent *shprev;
340:
341: struct varent *
342: adrof(var)
343: char *var;
344: {
345:
346: return (adrof1(var, &shvhed));
347: }
348:
349: struct varent *
350: madrof(pat, head)
351: char *pat;
352: struct varent *head;
353: {
354: register struct varent *vp;
355:
356: shprev = head;
357: for (vp = shprev->link; vp != 0; vp = vp->link) {
358: if (Gmatch(vp->name, pat))
359: return (vp);
360: shprev = vp;
361: }
362: return (0);
363: }
364:
365: struct varent *
366: adrof1(var, head)
367: char *var;
368: struct varent *head;
369: {
370: register struct varent *vp;
371: int cmp;
372:
373: shprev = head;
374: for (vp = shprev->link; vp != 0; vp = vp->link) {
375: cmp = strcmp(vp->name, var);
376: if (cmp == 0)
377: return (vp);
378: else if (cmp > 0)
379: return (0);
380: shprev = vp;
381: }
382: return (0);
383: }
384:
385: /*
386: * The caller is responsible for putting value in a safe place
387: */
388: set(var, value)
389: char *var, *value;
390: {
391: register char **vec = (char **) calloc(2, sizeof (char **));
392:
393: vec[0] = onlyread(value) ? savestr(value) : value;
394: set1(var, vec, &shvhed);
395: }
396:
397: set1(var, vec, head)
398: char *var, **vec;
399: struct varent *head;
400: {
401:
402: register char **oldv = vec;
403:
404: gflag = 0; rscan(oldv, tglob);
405: if (gflag) {
406: vec = glob(oldv);
407: if (vec == 0) {
408: bferr("No match");
409: blkfree(oldv);
410: return;
411: }
412: blkfree(oldv);
413: gargv = 0;
414: }
415: setq(var, vec, head);
416: }
417:
418: setq(var, vec, head)
419: char *var, **vec;
420: struct varent *head;
421: {
422: register struct varent *vp;
423:
424: vp = adrof1(var, head);
425: if (vp == 0) {
426: vp = (struct varent *) calloc(1, sizeof *vp);
427: vp->name = savestr(var);
428: vp->link = shprev->link;
429: shprev->link = vp;
430: }
431: if (vp->vec)
432: blkfree(vp->vec);
433: scan(vec, trim);
434: vp->vec = vec;
435: }
436:
437: unset(v)
438: register char *v[];
439: {
440:
441: unset1(v, &shvhed);
442: }
443:
444: unset1(v, head)
445: register char *v[];
446: struct varent *head;
447: {
448: register char *var;
449: register struct varent *vp;
450: register int cnt;
451:
452: v++;
453: while (var = *v++) {
454: cnt = 0;
455: while (vp = madrof(var, head))
456: unsetv1(vp->name, head), cnt++;
457: /*
458: if (cnt == 0)
459: setname(var), bferr("No match");
460: */
461: }
462: }
463:
464: unsetv(var)
465: char *var;
466: {
467:
468: unsetv1(var, &shvhed);
469: }
470:
471: unsetv1(var, head)
472: char *var;
473: struct varent *head;
474: {
475: register struct varent *vp;
476:
477: vp = adrof1(var, head);
478: if (vp == 0)
479: udvar(var);
480: vp = shprev->link;
481: shprev->link = vp->link;
482: blkfree(vp->vec);
483: xfree(vp->name);
484: xfree(vp);
485: }
486:
487: setNS(cp)
488: char *cp;
489: {
490:
491: set(cp, "");
492: }
493:
494: shift(v)
495: register char **v;
496: {
497: register struct varent *argv;
498: register char *name;
499:
500: v++;
501: name = *v;
502: if (name == 0)
503: name = "argv";
504: else
505: strip(name);
506: argv = adrof(name);
507: if (argv == 0)
508: udvar(name);
509: if (argv->vec[0] == 0)
510: bferr("No more words");
511: lshift(argv->vec, 1);
512: }
513:
514: deletev(cp)
515: register char *cp;
516: {
517:
518: if (adrof(cp))
519: unsetv(cp);
520: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.