change over to new error message format
[unix-history] / usr / src / usr.bin / tip / value.c
CommitLineData
5d6e692a
BJ
1/* value.c 4.1 81/05/09 */
2#include "tip.h"
3
4#define MIDDLE 35
5
6static value_t *vlookup();
7static int col = 0;
8
9/*
10 * Variable manipulation
11 */
12vinit()
13{
14 register value_t *p;
15 register char *cp;
16 FILE *f;
17 char file[256];
18
19 for (p = vtable; p->v_name != NULL; p++) {
20 if (p->v_type&ENVIRON)
21 if (cp = getenv(p->v_name))
22 p->v_value = cp;
23 if (p->v_type&IREMOTE)
24 number(p->v_value) = *address(p->v_value);
25 }
26 /*
27 * Read the .tiprc file in the HOME directory
28 * for sets
29 */
30 strcpy(file, value(HOME));
31 strcat(file, "/.tiprc");
32 if ((f = fopen(file, "r")) != NULL) {
33 register char *tp;
34
35 while (fgets(file, sizeof(file)-1, f) != NULL) {
36 if (vflag)
37 printf("set %s", file);
38 if (tp = rindex(file, '\n'))
39 *tp = '\0';
40 vlex(file);
41 }
42 fclose(f);
43 }
44 /*
45 * To allow definition of exception prior to fork
46 */
47 vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
48}
49
50/*VARARGS1*/
51vassign(p, v)
52register value_t *p;
53char *v;
54{
55
56 if (!vaccess(p->v_access, WRITE)) {
57 printf("access denied\r\n");
58 return;
59 }
60 switch(p->v_type&TMASK) {
61
62 case STRING:
63 if (equal(p->v_value, v))
64 return;
65 if (!(p->v_type&(ENVIRON|INIT)))
66 free(p->v_value);
67 if ((p->v_value = malloc(size(v)+1)) == NOSTR) {
68 printf("out of core\r\n");
69 return;
70 }
71 p->v_type &= ~(ENVIRON|INIT);
72 strcpy(p->v_value, v);
73 break;
74
75 case NUMBER:
76 if (number(p->v_value) == number(v))
77 return;
78 number(p->v_value) = number(v);
79 break;
80
81 case BOOL:
82 if (boolean(p->v_value) == (*v != '!'))
83 return;
84 boolean(p->v_value) = (*v != '!');
85 break;
86
87 case CHAR:
88 if (character(p->v_value) == *v)
89 return;
90 character(p->v_value) = *v;
91 }
92 p->v_access |= CHANGED;
93}
94
95vlex(s)
96register char *s;
97{
98 register value_t *p;
99
100 if (equal(s, "all")) {
101 for (p = vtable; p->v_name; p++)
102 if (vaccess(p->v_access, READ))
103 vprint(p);
104 } else {
105 register char *cp;
106
107 do {
108 if (cp = vinterp(s, ' '))
109 cp++;
110 vtoken(s);
111 s = cp;
112 } while (s);
113 }
114 if (col > 0) {
115 printf("\r\n");
116 col = 0;
117 }
118}
119
120static int
121vtoken(s)
122register char *s;
123{
124 register value_t *p;
125 register char *cp;
126
127 if (cp = index(s, '=')) {
128 *cp = '\0';
129 if (p = vlookup(s)) {
130 cp++;
131 if (p->v_type&NUMBER)
132 vassign(p, atoi(cp));
133 else
134 vassign(p, cp);
135 return;
136 }
137 } else if (cp = index(s, '?')) {
138 *cp = '\0';
139 if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
140 vprint(p);
141 return;
142 }
143 } else {
144 if (*s != '!')
145 p = vlookup(s);
146 else
147 p = vlookup(s+1);
148 if (p != NOVAL) {
149 vassign(p, s);
150 return;
151 }
152 }
153 printf("%s: unknown variable\r\n", s);
154}
155
156static int
157vprint(p)
158register value_t *p;
159{
160 register char *cp;
161 extern char *interp(), *ctrl();
162
163 if (col > 0 && col < MIDDLE)
164 while (col++ < MIDDLE)
165 putchar(' ');
166 col += size(p->v_name);
167 switch(p->v_type&TMASK)
168 {
169 case BOOL:
170 if (boolean(p->v_value) == FALSE) {
171 col++;
172 putchar('!');
173 }
174 printf("%s", p->v_name);
175 break;
176 case STRING:
177 printf("%s=", p->v_name);
178 col++;
179 if (p->v_value) {
180 cp = interp(p->v_value);
181 col += size(cp);
182 printf("%s", cp);
183 }
184 break;
185 case NUMBER:
186 col += 6;
187 printf("%s=%-5d", p->v_name, number(p->v_value));
188 break;
189 case CHAR:
190 printf("%s=", p->v_name);
191 col++;
192 if (p->v_value) {
193 cp = ctrl(character(p->v_value));
194 col += size(cp);
195 printf("%s", cp);
196 }
197 break;
198 }
199 if (col >= MIDDLE) {
200 col = 0;
201 printf("\r\n");
202 return;
203 }
204}
205
206
207static int
208vaccess(mode, rw)
209register unsigned mode, rw;
210{
211 if (mode & (rw<<PUBLIC))
212 return(1);
213 if (mode & (rw<<PRIVATE))
214 return(1);
215 return((mode & (rw<<ROOT)) && getuid() == 0);
216}
217
218static value_t *
219vlookup(s)
220register char *s;
221{
222 register value_t *p;
223
224 for (p = vtable; p->v_name; p++)
225 if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
226 return(p);
227 return(NULL);
228}
229
230char *
231vinterp(s, stop)
232register char *s;
233char stop;
234{
235 register char *p = s, c;
236 int num;
237
238 while ((c = *s++) && c != stop) switch(c)
239 {
240 case '^':
241 if (*s)
242 *p++ = *s++ - 0100;
243 else
244 *p++ = c;
245 break;
246
247 case '\\':
248 num = 0;
249 c = *s++;
250 if (c >= '0' && c <= '7')
251 num = (num<<3)+(c-'0');
252 else {
253 register char *q = "n\nr\rt\tb\bf\f";
254
255 for (; *q; q++)
256 if (c == *q++) {
257 *p++ = *q;
258 goto cont;
259 }
260 *p++ = c;
261 cont:
262 break;
263 }
264 if ((c = *s++) >= '0' && c <= '7') {
265 num = (num<<3)+(c-'0');
266 if ((c = *s++) >= '0' && c <= '7')
267 num = (num<<3)+(c-'0');
268 else
269 s--;
270 } else
271 s--;
272 *p++ = num;
273 break;
274
275 default:
276 *p++ = c;
277 }
278 *p = '\0';
279 return(c == stop ? s-1 : NULL);
280}