Commit | Line | Data |
---|---|---|
5d6e692a BJ |
1 | /* value.c 4.1 81/05/09 */ |
2 | #include "tip.h" | |
3 | ||
4 | #define MIDDLE 35 | |
5 | ||
6 | static value_t *vlookup(); | |
7 | static int col = 0; | |
8 | ||
9 | /* | |
10 | * Variable manipulation | |
11 | */ | |
12 | vinit() | |
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*/ | |
51 | vassign(p, v) | |
52 | register value_t *p; | |
53 | char *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 | ||
95 | vlex(s) | |
96 | register 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 | ||
120 | static int | |
121 | vtoken(s) | |
122 | register 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 | ||
156 | static int | |
157 | vprint(p) | |
158 | register 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 | ||
207 | static int | |
208 | vaccess(mode, rw) | |
209 | register 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 | ||
218 | static value_t * | |
219 | vlookup(s) | |
220 | register 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 | ||
230 | char * | |
231 | vinterp(s, stop) | |
232 | register char *s; | |
233 | char 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 | } |