do -s processing, even if output not a tty
[unix-history] / usr / src / usr.bin / tip / value.c
CommitLineData
051b1e55 1/*
c9686c12
KB
2 * Copyright (c) 1983 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
051b1e55
DF
16 */
17
05862919 18#ifndef lint
c9686c12
KB
19static char sccsid[] = "@(#)value.c 5.2 (Berkeley) %G%";
20#endif /* not lint */
05862919 21
5d6e692a
BJ
22#include "tip.h"
23
24#define MIDDLE 35
25
26static value_t *vlookup();
27static int col = 0;
28
29/*
30 * Variable manipulation
31 */
32vinit()
33{
34 register value_t *p;
35 register char *cp;
36 FILE *f;
37 char file[256];
38
39 for (p = vtable; p->v_name != NULL; p++) {
40 if (p->v_type&ENVIRON)
41 if (cp = getenv(p->v_name))
42 p->v_value = cp;
43 if (p->v_type&IREMOTE)
44 number(p->v_value) = *address(p->v_value);
45 }
46 /*
47 * Read the .tiprc file in the HOME directory
48 * for sets
49 */
50 strcpy(file, value(HOME));
51 strcat(file, "/.tiprc");
52 if ((f = fopen(file, "r")) != NULL) {
53 register char *tp;
54
55 while (fgets(file, sizeof(file)-1, f) != NULL) {
56 if (vflag)
57 printf("set %s", file);
58 if (tp = rindex(file, '\n'))
59 *tp = '\0';
60 vlex(file);
61 }
62 fclose(f);
63 }
64 /*
65 * To allow definition of exception prior to fork
66 */
67 vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
68}
69
70/*VARARGS1*/
71vassign(p, v)
d8feebc2
SL
72 register value_t *p;
73 char *v;
5d6e692a
BJ
74{
75
76 if (!vaccess(p->v_access, WRITE)) {
77 printf("access denied\r\n");
78 return;
79 }
3f48242d 80 switch (p->v_type&TMASK) {
5d6e692a 81
3f48242d
SL
82 case STRING:
83 if (equal(p->v_value, v))
84 return;
85 if (!(p->v_type&(ENVIRON|INIT)))
86 free(p->v_value);
87 if ((p->v_value = malloc(size(v)+1)) == NOSTR) {
88 printf("out of core\r\n");
89 return;
90 }
91 p->v_type &= ~(ENVIRON|INIT);
92 strcpy(p->v_value, v);
93 break;
5d6e692a 94
3f48242d
SL
95 case NUMBER:
96 if (number(p->v_value) == number(v))
97 return;
98 number(p->v_value) = number(v);
99 break;
5d6e692a 100
3f48242d
SL
101 case BOOL:
102 if (boolean(p->v_value) == (*v != '!'))
103 return;
104 boolean(p->v_value) = (*v != '!');
105 break;
106
107 case CHAR:
108 if (character(p->v_value) == *v)
109 return;
110 character(p->v_value) = *v;
5d6e692a
BJ
111 }
112 p->v_access |= CHANGED;
113}
114
115vlex(s)
d8feebc2 116 register char *s;
5d6e692a
BJ
117{
118 register value_t *p;
119
120 if (equal(s, "all")) {
121 for (p = vtable; p->v_name; p++)
122 if (vaccess(p->v_access, READ))
123 vprint(p);
124 } else {
125 register char *cp;
126
127 do {
128 if (cp = vinterp(s, ' '))
129 cp++;
130 vtoken(s);
131 s = cp;
132 } while (s);
133 }
134 if (col > 0) {
135 printf("\r\n");
136 col = 0;
137 }
138}
139
140static int
141vtoken(s)
d8feebc2 142 register char *s;
5d6e692a
BJ
143{
144 register value_t *p;
145 register char *cp;
6b46907f 146 char *expand();
5d6e692a
BJ
147
148 if (cp = index(s, '=')) {
149 *cp = '\0';
150 if (p = vlookup(s)) {
151 cp++;
152 if (p->v_type&NUMBER)
153 vassign(p, atoi(cp));
6b46907f
RC
154 else {
155 if (strcmp(s, "record") == 0)
156 cp = expand(cp);
5d6e692a 157 vassign(p, cp);
6b46907f 158 }
5d6e692a
BJ
159 return;
160 }
161 } else if (cp = index(s, '?')) {
162 *cp = '\0';
163 if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
164 vprint(p);
165 return;
166 }
167 } else {
168 if (*s != '!')
169 p = vlookup(s);
170 else
171 p = vlookup(s+1);
172 if (p != NOVAL) {
173 vassign(p, s);
174 return;
175 }
176 }
177 printf("%s: unknown variable\r\n", s);
178}
179
180static int
181vprint(p)
d8feebc2 182 register value_t *p;
5d6e692a
BJ
183{
184 register char *cp;
185 extern char *interp(), *ctrl();
186
187 if (col > 0 && col < MIDDLE)
188 while (col++ < MIDDLE)
189 putchar(' ');
190 col += size(p->v_name);
3f48242d
SL
191 switch (p->v_type&TMASK) {
192
193 case BOOL:
194 if (boolean(p->v_value) == FALSE) {
5d6e692a 195 col++;
3f48242d
SL
196 putchar('!');
197 }
198 printf("%s", p->v_name);
199 break;
200
201 case STRING:
202 printf("%s=", p->v_name);
203 col++;
204 if (p->v_value) {
6b46907f 205 cp = interp(p->v_value, NULL);
3f48242d
SL
206 col += size(cp);
207 printf("%s", cp);
208 }
209 break;
210
211 case NUMBER:
212 col += 6;
213 printf("%s=%-5d", p->v_name, number(p->v_value));
214 break;
215
216 case CHAR:
217 printf("%s=", p->v_name);
218 col++;
219 if (p->v_value) {
220 cp = ctrl(character(p->v_value));
221 col += size(cp);
222 printf("%s", cp);
223 }
224 break;
5d6e692a
BJ
225 }
226 if (col >= MIDDLE) {
227 col = 0;
228 printf("\r\n");
229 return;
230 }
231}
232
233
234static int
235vaccess(mode, rw)
d8feebc2 236 register unsigned mode, rw;
5d6e692a
BJ
237{
238 if (mode & (rw<<PUBLIC))
3f48242d 239 return (1);
5d6e692a 240 if (mode & (rw<<PRIVATE))
3f48242d
SL
241 return (1);
242 return ((mode & (rw<<ROOT)) && getuid() == 0);
5d6e692a
BJ
243}
244
245static value_t *
246vlookup(s)
d8feebc2 247 register char *s;
5d6e692a
BJ
248{
249 register value_t *p;
250
251 for (p = vtable; p->v_name; p++)
252 if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
3f48242d
SL
253 return (p);
254 return (NULL);
5d6e692a
BJ
255}
256
257char *
258vinterp(s, stop)
d8feebc2 259 register char *s;
3f48242d 260 char stop;
5d6e692a
BJ
261{
262 register char *p = s, c;
263 int num;
264
3f48242d
SL
265 while ((c = *s++) && c != stop)
266 switch (c) {
267
5d6e692a
BJ
268 case '^':
269 if (*s)
270 *p++ = *s++ - 0100;
271 else
272 *p++ = c;
273 break;
274
275 case '\\':
276 num = 0;
277 c = *s++;
278 if (c >= '0' && c <= '7')
279 num = (num<<3)+(c-'0');
280 else {
281 register char *q = "n\nr\rt\tb\bf\f";
282
283 for (; *q; q++)
284 if (c == *q++) {
285 *p++ = *q;
286 goto cont;
287 }
288 *p++ = c;
289 cont:
290 break;
291 }
292 if ((c = *s++) >= '0' && c <= '7') {
293 num = (num<<3)+(c-'0');
294 if ((c = *s++) >= '0' && c <= '7')
295 num = (num<<3)+(c-'0');
296 else
297 s--;
298 } else
299 s--;
300 *p++ = num;
301 break;
302
303 default:
304 *p++ = c;
3f48242d 305 }
5d6e692a 306 *p = '\0';
3f48242d 307 return (c == stop ? s-1 : NULL);
5d6e692a 308}
6b46907f
RC
309
310/*
311 * assign variable s with value v (for NUMBER or STRING or CHAR types)
312 */
313
314vstring(s,v)
315 register char *s;
316 register char *v;
317{
318 register value_t *p;
319 char *expand();
320
05862919
SL
321 p = vlookup(s);
322 if (p == 0)
323 return (1);
324 if (p->v_type&NUMBER)
325 vassign(p, atoi(v));
326 else {
327 if (strcmp(s, "record") == 0)
328 v = expand(v);
329 vassign(p, v);
330 }
331 return (0);
6b46907f 332}