date and time created 83/02/11 15:45:15 by rrh
[unix-history] / usr / src / usr.bin / tip / value.c
CommitLineData
3f48242d 1/* value.c 4.3 81/11/29 */
5d6e692a
BJ
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)
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
95vlex(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
120static int
121vtoken(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
156static int
157vprint(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
210static int
211vaccess(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
221static value_t *
222vlookup(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
233char *
234vinterp(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}