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