Commit | Line | Data |
---|---|---|
3f48242d | 1 | /* value.c 4.3 81/11/29 */ |
5d6e692a BJ |
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) | |
d8feebc2 SL |
52 | register value_t *p; |
53 | char *v; | |
5d6e692a BJ |
54 | { |
55 | ||
56 | if (!vaccess(p->v_access, WRITE)) { | |
57 | printf("access denied\r\n"); | |
58 | return; | |
59 | } | |
3f48242d | 60 | switch (p->v_type&TMASK) { |
5d6e692a | 61 | |
3f48242d SL |
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; | |
5d6e692a | 74 | |
3f48242d SL |
75 | case NUMBER: |
76 | if (number(p->v_value) == number(v)) | |
77 | return; | |
78 | number(p->v_value) = number(v); | |
79 | break; | |
5d6e692a | 80 | |
3f48242d SL |
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; | |
5d6e692a BJ |
91 | } |
92 | p->v_access |= CHANGED; | |
93 | } | |
94 | ||
95 | vlex(s) | |
d8feebc2 | 96 | register char *s; |
5d6e692a BJ |
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) | |
d8feebc2 | 122 | register char *s; |
5d6e692a BJ |
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) | |
d8feebc2 | 158 | register value_t *p; |
5d6e692a BJ |
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); | |
3f48242d SL |
167 | switch (p->v_type&TMASK) { |
168 | ||
169 | case BOOL: | |
170 | if (boolean(p->v_value) == FALSE) { | |
5d6e692a | 171 | col++; |
3f48242d SL |
172 | putchar('!'); |
173 | } | |
174 | printf("%s", p->v_name); | |
175 | break; | |
176 | ||
177 | case STRING: | |
178 | printf("%s=", p->v_name); | |
179 | col++; | |
180 | if (p->v_value) { | |
181 | cp = interp(p->v_value); | |
182 | col += size(cp); | |
183 | printf("%s", cp); | |
184 | } | |
185 | break; | |
186 | ||
187 | case NUMBER: | |
188 | col += 6; | |
189 | printf("%s=%-5d", p->v_name, number(p->v_value)); | |
190 | break; | |
191 | ||
192 | case CHAR: | |
193 | printf("%s=", p->v_name); | |
194 | col++; | |
195 | if (p->v_value) { | |
196 | cp = ctrl(character(p->v_value)); | |
197 | col += size(cp); | |
198 | printf("%s", cp); | |
199 | } | |
200 | break; | |
5d6e692a BJ |
201 | } |
202 | if (col >= MIDDLE) { | |
203 | col = 0; | |
204 | printf("\r\n"); | |
205 | return; | |
206 | } | |
207 | } | |
208 | ||
209 | ||
210 | static int | |
211 | vaccess(mode, rw) | |
d8feebc2 | 212 | register unsigned mode, rw; |
5d6e692a BJ |
213 | { |
214 | if (mode & (rw<<PUBLIC)) | |
3f48242d | 215 | return (1); |
5d6e692a | 216 | if (mode & (rw<<PRIVATE)) |
3f48242d SL |
217 | return (1); |
218 | return ((mode & (rw<<ROOT)) && getuid() == 0); | |
5d6e692a BJ |
219 | } |
220 | ||
221 | static value_t * | |
222 | vlookup(s) | |
d8feebc2 | 223 | register char *s; |
5d6e692a BJ |
224 | { |
225 | register value_t *p; | |
226 | ||
227 | for (p = vtable; p->v_name; p++) | |
228 | if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s))) | |
3f48242d SL |
229 | return (p); |
230 | return (NULL); | |
5d6e692a BJ |
231 | } |
232 | ||
233 | char * | |
234 | vinterp(s, stop) | |
d8feebc2 | 235 | register char *s; |
3f48242d | 236 | char stop; |
5d6e692a BJ |
237 | { |
238 | register char *p = s, c; | |
239 | int num; | |
240 | ||
3f48242d SL |
241 | while ((c = *s++) && c != stop) |
242 | switch (c) { | |
243 | ||
5d6e692a BJ |
244 | case '^': |
245 | if (*s) | |
246 | *p++ = *s++ - 0100; | |
247 | else | |
248 | *p++ = c; | |
249 | break; | |
250 | ||
251 | case '\\': | |
252 | num = 0; | |
253 | c = *s++; | |
254 | if (c >= '0' && c <= '7') | |
255 | num = (num<<3)+(c-'0'); | |
256 | else { | |
257 | register char *q = "n\nr\rt\tb\bf\f"; | |
258 | ||
259 | for (; *q; q++) | |
260 | if (c == *q++) { | |
261 | *p++ = *q; | |
262 | goto cont; | |
263 | } | |
264 | *p++ = c; | |
265 | cont: | |
266 | break; | |
267 | } | |
268 | if ((c = *s++) >= '0' && c <= '7') { | |
269 | num = (num<<3)+(c-'0'); | |
270 | if ((c = *s++) >= '0' && c <= '7') | |
271 | num = (num<<3)+(c-'0'); | |
272 | else | |
273 | s--; | |
274 | } else | |
275 | s--; | |
276 | *p++ = num; | |
277 | break; | |
278 | ||
279 | default: | |
280 | *p++ = c; | |
3f48242d | 281 | } |
5d6e692a | 282 | *p = '\0'; |
3f48242d | 283 | return (c == stop ? s-1 : NULL); |
5d6e692a | 284 | } |