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