BSD 3 development
[unix-history] / usr / src / cmd / csh / sh.set.c
CommitLineData
ed144646
BJ
1/* Copyright (c) 1979 Regents of the University of California */
2#include "sh.h"
3
4/*
5 * C Shell
6 */
7
8doset(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 != '=')
42setsyn:
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
67char *
68getinx(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
82asx(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
93struct varent *
94getvx(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
105char plusplus[2] = { '1', 0 };
106
107
108dolet(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++;
153letsyn:
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
188char *
189xset(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
203char *
204operate(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
230onlyread(cp)
231 char *cp;
232{
233 extern char end[];
234
235 return (cp < end);
236}
237
238xfree(cp)
239 char *cp;
240{
241 extern char end[];
242
243 if (cp >= end && cp < (char *) &cp)
244 cfree(cp);
245}
246
247char *
248savestr(s)
249 register char *s;
250{
251
252 if (s == 0)
253 s = "";
254 return (strcpy(calloc(1, strlen(s) + 1), s));
255}
256
257static char *putp;
258
259char *
260putn(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
286putn1(n)
287 register int n;
288{
289 if (n > 9)
290 putn1(n / 10);
291 *putp++ = n % 10 + '0';
292}
293
294getn(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);
315badnum:
316 bferr("Badly formed number");
317 return (0);
318}
319
320char *
321value(var)
322 char *var;
323{
324
325 return (value1(var, &shvhed));
326}
327
328char *
329value1(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
339static struct varent *shprev;
340
341struct varent *
342adrof(var)
343 char *var;
344{
345
346 return (adrof1(var, &shvhed));
347}
348
349struct varent *
350madrof(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
365struct varent *
366adrof1(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 */
388set(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
397set1(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
418setq(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
437unset(v)
438 register char *v[];
439{
440
441 unset1(v, &shvhed);
442}
443
444unset1(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
464unsetv(var)
465 char *var;
466{
467
468 unsetv1(var, &shvhed);
469}
470
471unsetv1(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
487setNS(cp)
488 char *cp;
489{
490
491 set(cp, "");
492}
493
494shift(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
514deletev(cp)
515 register char *cp;
516{
517
518 if (adrof(cp))
519 unsetv(cp);
520}