Annotation of src/usr.bin/tip/value.c, Revision 1.24
1.24 ! chl 1: /* $OpenBSD: value.c,v 1.23 2010/06/30 00:26:49 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.11 deraadt 53: FILE *fp;
1.1 deraadt 54:
1.23 nicm 55: /* Read environment variables. */
56: if (cp = getenv("HOME"))
57: value(HOME) = cp;
58: if (cp = getenv("SHELL"))
59: value(SHELL) = cp;
60:
61: /* Read the .tiprc file in the HOME directory. */
1.16 moritz 62: written = snprintf(file, sizeof(file), "%s/.tiprc", value(HOME));
63: if (written < 0 || written >= sizeof(file)) {
1.4 millert 64: (void)fprintf(stderr, "Home directory path too long: %s\n",
1.11 deraadt 65: value(HOME));
1.3 millert 66: } else {
1.11 deraadt 67: if ((fp = fopen(file, "r")) != NULL) {
1.7 millert 68: char *tp;
1.3 millert 69:
1.15 ray 70: while (fgets(file, sizeof(file), fp) != NULL) {
1.3 millert 71: if (vflag)
72: printf("set %s", file);
1.5 deraadt 73: if ((tp = strrchr(file, '\n')))
1.3 millert 74: *tp = '\0';
75: vlex(file);
76: }
1.11 deraadt 77: fclose(fp);
1.1 deraadt 78: }
79: }
80: }
81:
82: /*VARARGS1*/
1.13 moritz 83: static void
1.11 deraadt 84: vassign(value_t *p, char *v)
1.1 deraadt 85: {
1.21 nicm 86: if (p->v_flags & V_READONLY) {
1.1 deraadt 87: printf("access denied\r\n");
88: return;
89: }
1.11 deraadt 90:
1.21 nicm 91: switch (p->v_flags & V_TYPEMASK) {
92: case V_STRING:
1.19 nicm 93: if (p->v_value && strcmp(p->v_value, v) == 0)
1.1 deraadt 94: return;
1.23 nicm 95: if (!(p->v_flags & V_INIT))
1.1 deraadt 96: free(p->v_value);
1.17 moritz 97: if ((p->v_value = strdup(v)) == NULL) {
1.1 deraadt 98: printf("out of core\r\n");
99: return;
100: }
1.23 nicm 101: p->v_flags &= ~V_INIT;
1.1 deraadt 102: break;
1.21 nicm 103: case V_NUMBER:
1.1 deraadt 104: if (number(p->v_value) == number(v))
105: return;
1.4 millert 106: setnumber(p->v_value, number(v));
1.1 deraadt 107: break;
1.21 nicm 108: case V_BOOL:
1.1 deraadt 109: if (boolean(p->v_value) == (*v != '!'))
110: return;
1.4 millert 111: setboolean(p->v_value, (*v != '!'));
1.1 deraadt 112: break;
1.21 nicm 113: case V_CHAR:
1.1 deraadt 114: if (character(p->v_value) == *v)
115: return;
1.4 millert 116: setcharacter(p->v_value, *v);
1.1 deraadt 117: }
1.21 nicm 118: p->v_flags |= V_CHANGED;
1.1 deraadt 119: }
120:
1.5 deraadt 121: void
1.11 deraadt 122: vlex(char *s)
1.1 deraadt 123: {
1.7 millert 124: value_t *p;
1.11 deraadt 125: char *cp;
1.1 deraadt 126:
1.19 nicm 127: if (strcmp(s, "all") == 0) {
1.1 deraadt 128: for (p = vtable; p->v_name; p++)
1.20 nicm 129: vprint(p);
1.1 deraadt 130: } else {
131: do {
1.5 deraadt 132: if ((cp = vinterp(s, ' ')))
1.1 deraadt 133: cp++;
134: vtoken(s);
135: s = cp;
136: } while (s);
137: }
138: if (col > 0) {
139: printf("\r\n");
140: col = 0;
141: }
142: }
143:
144: static void
1.11 deraadt 145: vtoken(char *s)
1.1 deraadt 146: {
1.7 millert 147: value_t *p;
148: char *cp;
1.1 deraadt 149:
1.5 deraadt 150: if ((cp = strchr(s, '='))) {
1.1 deraadt 151: *cp = '\0';
1.5 deraadt 152: if ((p = vlookup(s))) {
1.1 deraadt 153: cp++;
1.21 nicm 154: if ((p->v_flags & V_TYPEMASK) == V_NUMBER)
1.11 deraadt 155: vassign(p, (char *)atoi(cp));
1.1 deraadt 156: else {
157: if (strcmp(s, "record") == 0)
158: cp = expand(cp);
159: vassign(p, cp);
160: }
161: return;
162: }
1.5 deraadt 163: } else if ((cp = strchr(s, '?'))) {
1.1 deraadt 164: *cp = '\0';
1.20 nicm 165: if (p = vlookup(s)) {
1.1 deraadt 166: vprint(p);
167: return;
168: }
169: } else {
170: if (*s != '!')
171: p = vlookup(s);
172: else
173: p = vlookup(s+1);
1.17 moritz 174: if (p != NULL) {
1.1 deraadt 175: vassign(p, s);
176: return;
177: }
178: }
179: printf("%s: unknown variable\r\n", s);
180: }
181:
182: static void
1.11 deraadt 183: vprint(value_t *p)
1.1 deraadt 184: {
1.7 millert 185: char *cp;
1.1 deraadt 186:
187: if (col > 0 && col < MIDDLE)
188: while (col++ < MIDDLE)
189: putchar(' ');
190: col += size(p->v_name);
1.21 nicm 191: switch (p->v_flags & V_TYPEMASK) {
1.1 deraadt 192:
1.21 nicm 193: case V_BOOL:
194: if (!boolean(p->v_value)) {
1.1 deraadt 195: col++;
196: putchar('!');
197: }
198: printf("%s", p->v_name);
199: break;
200:
1.21 nicm 201: case V_STRING:
1.1 deraadt 202: printf("%s=", p->v_name);
203: col++;
204: if (p->v_value) {
1.12 moritz 205: cp = interp(p->v_value);
1.1 deraadt 206: col += size(cp);
207: printf("%s", cp);
208: }
209: break;
210:
1.21 nicm 211: case V_NUMBER:
1.1 deraadt 212: col += 6;
1.5 deraadt 213: printf("%s=%-5ld", p->v_name, number(p->v_value));
1.1 deraadt 214: break;
215:
1.21 nicm 216: case V_CHAR:
1.1 deraadt 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;
225: }
226: if (col >= MIDDLE) {
227: col = 0;
228: printf("\r\n");
229: return;
230: }
231: }
232:
233: static value_t *
1.11 deraadt 234: vlookup(char *s)
1.1 deraadt 235: {
1.7 millert 236: value_t *p;
1.1 deraadt 237:
1.21 nicm 238: for (p = vtable; p->v_name; p++) {
1.19 nicm 239: if (strcmp(p->v_name, s) == 0 ||
1.21 nicm 240: (p->v_abbrev && strcmp(p->v_abbrev, s) == 0))
1.1 deraadt 241: return (p);
1.21 nicm 242: }
1.1 deraadt 243: return (NULL);
244: }
245:
1.13 moritz 246: static char *
1.11 deraadt 247: vinterp(char *s, int stop)
1.1 deraadt 248: {
1.7 millert 249: char *p = s, c;
1.1 deraadt 250: int num;
251:
1.11 deraadt 252: while ((c = *s++) && c != stop) {
1.1 deraadt 253: switch (c) {
254:
255: case '^':
256: if (*s)
257: *p++ = *s++ - 0100;
258: else
259: *p++ = c;
260: break;
261:
262: case '\\':
263: num = 0;
264: c = *s++;
265: if (c >= '0' && c <= '7')
266: num = (num<<3)+(c-'0');
267: else {
1.7 millert 268: char *q = "n\nr\rt\tb\bf\f";
1.1 deraadt 269:
270: for (; *q; q++)
271: if (c == *q++) {
272: *p++ = *q;
273: goto cont;
274: }
275: *p++ = c;
276: cont:
277: break;
278: }
279: if ((c = *s++) >= '0' && c <= '7') {
280: num = (num<<3)+(c-'0');
281: if ((c = *s++) >= '0' && c <= '7')
282: num = (num<<3)+(c-'0');
283: else
284: s--;
285: } else
286: s--;
287: *p++ = num;
288: break;
289:
290: default:
291: *p++ = c;
292: }
1.11 deraadt 293: }
1.1 deraadt 294: *p = '\0';
295: return (c == stop ? s-1 : NULL);
296: }
297:
298: /*
299: * assign variable s with value v (for NUMBER or STRING or CHAR types)
300: */
1.5 deraadt 301: int
1.11 deraadt 302: vstring(char *s, char *v)
1.1 deraadt 303: {
1.7 millert 304: value_t *p;
1.1 deraadt 305:
1.11 deraadt 306: p = vlookup(s);
1.1 deraadt 307: if (p == 0)
308: return (1);
1.21 nicm 309: if ((p->v_flags & V_TYPEMASK) == V_NUMBER)
1.11 deraadt 310: vassign(p, (char *)atoi(v));
1.1 deraadt 311: else {
312: if (strcmp(s, "record") == 0)
313: v = expand(v);
314: vassign(p, v);
315: }
316: return (0);
317: }