Annotation of src/usr.bin/tip/value.c, Revision 1.22
1.22 ! nicm 1: /* $OpenBSD: value.c,v 1.21 2010/06/29 21:34:50 nicm Exp $ */
1.4 millert 2: /* $NetBSD: value.c,v 1.6 1997/02/11 09:24:09 mrg Exp $ */
1.1 deraadt 3:
4: /*
5: * Copyright (c) 1983, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
1.10 millert 16: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 17: * may be used to endorse or promote products derived from this software
18: * without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30: * SUCH DAMAGE.
31: */
32:
33: #include "tip.h"
34:
35: #define MIDDLE 35
36:
1.11 deraadt 37: static value_t *vlookup(char *);
1.13 moritz 38: static void vassign(value_t *, char *);
39: static void vtoken(char *);
40: static void vprint(value_t *);
41: static char *vinterp(char *, int);
42:
1.14 moritz 43: static size_t col = 0;
1.1 deraadt 44:
45: /*
46: * Variable manipulation
47: */
1.5 deraadt 48: void
1.11 deraadt 49: vinit(void)
1.1 deraadt 50: {
1.11 deraadt 51: char file[FILENAME_MAX], *cp;
1.16 moritz 52: int written;
1.7 millert 53: value_t *p;
1.11 deraadt 54: FILE *fp;
1.1 deraadt 55:
56: for (p = vtable; p->v_name != NULL; p++) {
1.22 ! nicm 57: if (p->v_flags & V_ENVIRON) {
1.5 deraadt 58: if ((cp = getenv(p->v_name)))
1.1 deraadt 59: p->v_value = cp;
1.22 ! nicm 60: }
1.1 deraadt 61: }
62: /*
63: * Read the .tiprc file in the HOME directory
64: * for sets
65: */
1.16 moritz 66: written = snprintf(file, sizeof(file), "%s/.tiprc", value(HOME));
67: if (written < 0 || written >= sizeof(file)) {
1.4 millert 68: (void)fprintf(stderr, "Home directory path too long: %s\n",
1.11 deraadt 69: value(HOME));
1.3 millert 70: } else {
1.11 deraadt 71: if ((fp = fopen(file, "r")) != NULL) {
1.7 millert 72: char *tp;
1.3 millert 73:
1.15 ray 74: while (fgets(file, sizeof(file), fp) != NULL) {
1.3 millert 75: if (vflag)
76: printf("set %s", file);
1.5 deraadt 77: if ((tp = strrchr(file, '\n')))
1.3 millert 78: *tp = '\0';
79: vlex(file);
80: }
1.11 deraadt 81: fclose(fp);
1.1 deraadt 82: }
83: }
84: }
85:
86: /*VARARGS1*/
1.13 moritz 87: static void
1.11 deraadt 88: vassign(value_t *p, char *v)
1.1 deraadt 89: {
1.21 nicm 90: if (p->v_flags & V_READONLY) {
1.1 deraadt 91: printf("access denied\r\n");
92: return;
93: }
1.11 deraadt 94:
1.21 nicm 95: switch (p->v_flags & V_TYPEMASK) {
96: case V_STRING:
1.19 nicm 97: if (p->v_value && strcmp(p->v_value, v) == 0)
1.1 deraadt 98: return;
1.21 nicm 99: if (!(p->v_flags & (V_ENVIRON|V_INIT)))
1.1 deraadt 100: free(p->v_value);
1.17 moritz 101: if ((p->v_value = strdup(v)) == NULL) {
1.1 deraadt 102: printf("out of core\r\n");
103: return;
104: }
1.21 nicm 105: p->v_flags &= ~(V_ENVIRON|V_INIT);
1.1 deraadt 106: break;
1.21 nicm 107: case V_NUMBER:
1.1 deraadt 108: if (number(p->v_value) == number(v))
109: return;
1.4 millert 110: setnumber(p->v_value, number(v));
1.1 deraadt 111: break;
1.21 nicm 112: case V_BOOL:
1.1 deraadt 113: if (boolean(p->v_value) == (*v != '!'))
114: return;
1.4 millert 115: setboolean(p->v_value, (*v != '!'));
1.1 deraadt 116: break;
1.21 nicm 117: case V_CHAR:
1.1 deraadt 118: if (character(p->v_value) == *v)
119: return;
1.4 millert 120: setcharacter(p->v_value, *v);
1.1 deraadt 121: }
1.21 nicm 122: p->v_flags |= V_CHANGED;
1.1 deraadt 123: }
124:
1.5 deraadt 125: void
1.11 deraadt 126: vlex(char *s)
1.1 deraadt 127: {
1.7 millert 128: value_t *p;
1.11 deraadt 129: char *cp;
1.1 deraadt 130:
1.19 nicm 131: if (strcmp(s, "all") == 0) {
1.1 deraadt 132: for (p = vtable; p->v_name; p++)
1.20 nicm 133: vprint(p);
1.1 deraadt 134: } else {
135: do {
1.5 deraadt 136: if ((cp = vinterp(s, ' ')))
1.1 deraadt 137: cp++;
138: vtoken(s);
139: s = cp;
140: } while (s);
141: }
142: if (col > 0) {
143: printf("\r\n");
144: col = 0;
145: }
146: }
147:
148: static void
1.11 deraadt 149: vtoken(char *s)
1.1 deraadt 150: {
1.7 millert 151: value_t *p;
152: char *cp;
1.1 deraadt 153:
1.5 deraadt 154: if ((cp = strchr(s, '='))) {
1.1 deraadt 155: *cp = '\0';
1.5 deraadt 156: if ((p = vlookup(s))) {
1.1 deraadt 157: cp++;
1.21 nicm 158: if ((p->v_flags & V_TYPEMASK) == V_NUMBER)
1.11 deraadt 159: vassign(p, (char *)atoi(cp));
1.1 deraadt 160: else {
161: if (strcmp(s, "record") == 0)
162: cp = expand(cp);
163: vassign(p, cp);
164: }
165: return;
166: }
1.5 deraadt 167: } else if ((cp = strchr(s, '?'))) {
1.1 deraadt 168: *cp = '\0';
1.20 nicm 169: if (p = vlookup(s)) {
1.1 deraadt 170: vprint(p);
171: return;
172: }
173: } else {
174: if (*s != '!')
175: p = vlookup(s);
176: else
177: p = vlookup(s+1);
1.17 moritz 178: if (p != NULL) {
1.1 deraadt 179: vassign(p, s);
180: return;
181: }
182: }
183: printf("%s: unknown variable\r\n", s);
184: }
185:
186: static void
1.11 deraadt 187: vprint(value_t *p)
1.1 deraadt 188: {
1.7 millert 189: char *cp;
1.1 deraadt 190:
191: if (col > 0 && col < MIDDLE)
192: while (col++ < MIDDLE)
193: putchar(' ');
194: col += size(p->v_name);
1.21 nicm 195: switch (p->v_flags & V_TYPEMASK) {
1.1 deraadt 196:
1.21 nicm 197: case V_BOOL:
198: if (!boolean(p->v_value)) {
1.1 deraadt 199: col++;
200: putchar('!');
201: }
202: printf("%s", p->v_name);
203: break;
204:
1.21 nicm 205: case V_STRING:
1.1 deraadt 206: printf("%s=", p->v_name);
207: col++;
208: if (p->v_value) {
1.12 moritz 209: cp = interp(p->v_value);
1.1 deraadt 210: col += size(cp);
211: printf("%s", cp);
212: }
213: break;
214:
1.21 nicm 215: case V_NUMBER:
1.1 deraadt 216: col += 6;
1.5 deraadt 217: printf("%s=%-5ld", p->v_name, number(p->v_value));
1.1 deraadt 218: break;
219:
1.21 nicm 220: case V_CHAR:
1.1 deraadt 221: printf("%s=", p->v_name);
222: col++;
223: if (p->v_value) {
224: cp = ctrl(character(p->v_value));
225: col += size(cp);
226: printf("%s", cp);
227: }
228: break;
229: }
230: if (col >= MIDDLE) {
231: col = 0;
232: printf("\r\n");
233: return;
234: }
235: }
236:
237: static value_t *
1.11 deraadt 238: vlookup(char *s)
1.1 deraadt 239: {
1.7 millert 240: value_t *p;
1.1 deraadt 241:
1.21 nicm 242: for (p = vtable; p->v_name; p++) {
1.19 nicm 243: if (strcmp(p->v_name, s) == 0 ||
1.21 nicm 244: (p->v_abbrev && strcmp(p->v_abbrev, s) == 0))
1.1 deraadt 245: return (p);
1.21 nicm 246: }
1.1 deraadt 247: return (NULL);
248: }
249:
1.13 moritz 250: static char *
1.11 deraadt 251: vinterp(char *s, int stop)
1.1 deraadt 252: {
1.7 millert 253: char *p = s, c;
1.1 deraadt 254: int num;
255:
1.11 deraadt 256: while ((c = *s++) && c != stop) {
1.1 deraadt 257: switch (c) {
258:
259: case '^':
260: if (*s)
261: *p++ = *s++ - 0100;
262: else
263: *p++ = c;
264: break;
265:
266: case '\\':
267: num = 0;
268: c = *s++;
269: if (c >= '0' && c <= '7')
270: num = (num<<3)+(c-'0');
271: else {
1.7 millert 272: char *q = "n\nr\rt\tb\bf\f";
1.1 deraadt 273:
274: for (; *q; q++)
275: if (c == *q++) {
276: *p++ = *q;
277: goto cont;
278: }
279: *p++ = c;
280: cont:
281: break;
282: }
283: if ((c = *s++) >= '0' && c <= '7') {
284: num = (num<<3)+(c-'0');
285: if ((c = *s++) >= '0' && c <= '7')
286: num = (num<<3)+(c-'0');
287: else
288: s--;
289: } else
290: s--;
291: *p++ = num;
292: break;
293:
294: default:
295: *p++ = c;
296: }
1.11 deraadt 297: }
1.1 deraadt 298: *p = '\0';
299: return (c == stop ? s-1 : NULL);
300: }
301:
302: /*
303: * assign variable s with value v (for NUMBER or STRING or CHAR types)
304: */
1.5 deraadt 305: int
1.11 deraadt 306: vstring(char *s, char *v)
1.1 deraadt 307: {
1.7 millert 308: value_t *p;
1.1 deraadt 309:
1.11 deraadt 310: p = vlookup(s);
1.1 deraadt 311: if (p == 0)
312: return (1);
1.21 nicm 313: if ((p->v_flags & V_TYPEMASK) == V_NUMBER)
1.11 deraadt 314: vassign(p, (char *)atoi(v));
1.1 deraadt 315: else {
316: if (strcmp(s, "record") == 0)
317: v = expand(v);
318: vassign(p, v);
319: }
320: return (0);
321: }