Annotation of src/usr.bin/tip/value.c, Revision 1.29
1.29 ! nicm 1: /* $OpenBSD: value.c,v 1.28 2010/07/02 05:56:29 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:
1.26 nicm 35: /*
36: * Variable manipulation.
37: */
38:
1.1 deraadt 39: #define MIDDLE 35
40:
1.29 ! nicm 41: static int vlookup(char *);
! 42: static void vtoken(char *);
! 43: static void vprint(value_t *);
! 44: static char *vinterp(char *, int);
1.13 moritz 45:
1.14 moritz 46: static size_t col = 0;
1.1 deraadt 47:
1.26 nicm 48: /* Get a string value. */
49: char *
50: vgetstr(int value)
51: {
1.28 nicm 52: value_t *vp = &vtable[value];
53: int type;
54:
55: type = vp->v_flags & V_TYPEMASK;
56: if (type != V_STRING)
57: errx(1, "variable %s not a string", vp->v_name);
58: return (vp->v_string);
1.26 nicm 59: }
60:
61: /* Get a number value. */
62: int
63: vgetnum(int value)
64: {
1.28 nicm 65: value_t *vp = &vtable[value];
66: int type;
67:
68: type = vp->v_flags & V_TYPEMASK;
69: if (type != V_NUMBER && type != V_BOOL && type != V_CHAR)
70: errx(1, "variable %s not a number", vp->v_name);
71: return (vp->v_number);
1.26 nicm 72: }
73:
74: /* Set a string value. */
75: void
76: vsetstr(int value, char *string)
77: {
1.28 nicm 78: value_t *vp = &vtable[value];
79: int type;
80:
81: type = vp->v_flags & V_TYPEMASK;
82: if (type != V_STRING)
83: errx(1, "variable %s not a string", vp->v_name);
84:
85: if (value == RECORD && string != NULL)
86: string = expand(string);
87:
88: if (!(vp->v_flags & V_INIT))
89: free(vp->v_string);
90: if (string != NULL) {
91: vp->v_string = strdup(string);
92: if (vp->v_string == NULL)
93: err(1, "strdup");
94: } else
95: vp->v_string = NULL;
96: vp->v_flags &= ~V_INIT;
1.26 nicm 97: }
98:
99: /* Set a number value. */
100: void
101: vsetnum(int value, int number)
102: {
1.28 nicm 103: value_t *vp = &vtable[value];
104: int type;
105:
106: type = vp->v_flags & V_TYPEMASK;
107: if (type != V_NUMBER && type != V_BOOL && type != V_CHAR)
108: errx(1, "variable %s not a number", vp->v_name);
109:
110: vp->v_number = number;
1.26 nicm 111: }
112:
1.29 ! nicm 113: /* Find index of variable by name or abbreviation. */
! 114: static int
! 115: vlookup(char *s)
! 116: {
! 117: value_t *vp;
! 118: u_int i;
! 119:
! 120: for (i = 0; vtable[i].v_name != NULL; i++) {
! 121: vp = &vtable[i];
! 122: if (strcmp(vp->v_name, s) == 0 ||
! 123: (vp->v_abbrev != NULL && strcmp(vp->v_abbrev, s) == 0))
! 124: return (i);
! 125: }
! 126: return (-1);
! 127: }
! 128:
1.5 deraadt 129: void
1.11 deraadt 130: vinit(void)
1.1 deraadt 131: {
1.11 deraadt 132: char file[FILENAME_MAX], *cp;
1.16 moritz 133: int written;
1.11 deraadt 134: FILE *fp;
1.1 deraadt 135:
1.23 nicm 136: /* Read environment variables. */
1.27 nicm 137: if ((cp = getenv("HOME")))
1.25 nicm 138: vsetstr(HOME, cp);
1.27 nicm 139: if ((cp = getenv("SHELL")))
1.25 nicm 140: vsetstr(SHELL, cp);
1.23 nicm 141:
142: /* Read the .tiprc file in the HOME directory. */
1.25 nicm 143: written = snprintf(file, sizeof(file), "%s/.tiprc", vgetstr(HOME));
1.16 moritz 144: if (written < 0 || written >= sizeof(file)) {
1.4 millert 145: (void)fprintf(stderr, "Home directory path too long: %s\n",
1.25 nicm 146: vgetstr(HOME));
1.3 millert 147: } else {
1.11 deraadt 148: if ((fp = fopen(file, "r")) != NULL) {
1.7 millert 149: char *tp;
1.3 millert 150:
1.15 ray 151: while (fgets(file, sizeof(file), fp) != NULL) {
1.3 millert 152: if (vflag)
153: printf("set %s", file);
1.5 deraadt 154: if ((tp = strrchr(file, '\n')))
1.3 millert 155: *tp = '\0';
156: vlex(file);
157: }
1.11 deraadt 158: fclose(fp);
1.1 deraadt 159: }
160: }
161: }
162:
1.5 deraadt 163: void
1.11 deraadt 164: vlex(char *s)
1.1 deraadt 165: {
1.7 millert 166: value_t *p;
1.11 deraadt 167: char *cp;
1.1 deraadt 168:
1.19 nicm 169: if (strcmp(s, "all") == 0) {
1.1 deraadt 170: for (p = vtable; p->v_name; p++)
1.20 nicm 171: vprint(p);
1.1 deraadt 172: } else {
173: do {
1.5 deraadt 174: if ((cp = vinterp(s, ' ')))
1.1 deraadt 175: cp++;
176: vtoken(s);
177: s = cp;
178: } while (s);
179: }
180: if (col > 0) {
181: printf("\r\n");
182: col = 0;
183: }
184: }
185:
1.29 ! nicm 186: /* Set a variable from a token. */
1.1 deraadt 187: static void
1.11 deraadt 188: vtoken(char *s)
1.1 deraadt 189: {
1.29 ! nicm 190: value_t *vp;
! 191: int i, value;
! 192: char *cp;
! 193: const char *cause;
1.1 deraadt 194:
1.5 deraadt 195: if ((cp = strchr(s, '='))) {
1.1 deraadt 196: *cp = '\0';
1.29 ! nicm 197: if ((i = vlookup(s)) != -1) {
! 198: vp = &vtable[i];
! 199: if (vp->v_flags & V_READONLY) {
! 200: printf("access denied\r\n");
! 201: return;
! 202: }
1.1 deraadt 203: cp++;
1.29 ! nicm 204: switch (vp->v_flags & V_TYPEMASK) {
! 205: case V_STRING:
! 206: vsetstr(i, cp);
! 207: break;
! 208: case V_BOOL:
! 209: vsetnum(i, 1);
! 210: break;
! 211: case V_NUMBER:
! 212: value = strtonum(cp, 0, INT_MAX, &cause);
! 213: if (cause != NULL) {
! 214: printf("%s: number %s\r\n", s, cause);
! 215: return;
! 216: }
! 217: vsetnum(i, value);
! 218: break;
! 219: case V_CHAR:
! 220: if (cp[0] != '\0' && cp[1] != '\0') {
! 221: printf("%s: character too big\r\n", s);
! 222: return;
! 223: }
! 224: vsetnum(i, *cp);
1.1 deraadt 225: }
1.29 ! nicm 226: vp->v_flags |= V_CHANGED;
1.1 deraadt 227: return;
228: }
1.5 deraadt 229: } else if ((cp = strchr(s, '?'))) {
1.1 deraadt 230: *cp = '\0';
1.29 ! nicm 231: if ((i = vlookup(s)) != -1) {
! 232: vprint(&vtable[i]);
1.1 deraadt 233: return;
234: }
235: } else {
236: if (*s != '!')
1.29 ! nicm 237: i = vlookup(s);
1.1 deraadt 238: else
1.29 ! nicm 239: i = vlookup(s + 1);
! 240: if (i != -1) {
! 241: vp = &vtable[i];
! 242: if (vp->v_flags & V_READONLY) {
! 243: printf("%s: access denied\r\n", s);
! 244: return;
! 245: }
! 246: if ((vp->v_flags & V_TYPEMASK) != V_BOOL) {
! 247: printf("%s: not a boolean\r\n", s);
! 248: return;
! 249: }
! 250: vsetnum(i, *s != '!');
! 251: vp->v_flags |= V_CHANGED;
1.1 deraadt 252: return;
253: }
254: }
255: printf("%s: unknown variable\r\n", s);
256: }
257:
258: static void
1.11 deraadt 259: vprint(value_t *p)
1.1 deraadt 260: {
1.7 millert 261: char *cp;
1.1 deraadt 262:
263: if (col > 0 && col < MIDDLE)
264: while (col++ < MIDDLE)
265: putchar(' ');
266: col += size(p->v_name);
1.21 nicm 267: switch (p->v_flags & V_TYPEMASK) {
1.1 deraadt 268:
1.21 nicm 269: case V_BOOL:
1.26 nicm 270: if (!p->v_number) {
1.1 deraadt 271: col++;
272: putchar('!');
273: }
274: printf("%s", p->v_name);
275: break;
276:
1.21 nicm 277: case V_STRING:
1.1 deraadt 278: printf("%s=", p->v_name);
279: col++;
1.26 nicm 280: if (p->v_string) {
281: cp = interp(p->v_string);
1.1 deraadt 282: col += size(cp);
283: printf("%s", cp);
284: }
285: break;
286:
1.21 nicm 287: case V_NUMBER:
1.1 deraadt 288: col += 6;
1.26 nicm 289: printf("%s=%-5d", p->v_name, p->v_number);
1.1 deraadt 290: break;
291:
1.21 nicm 292: case V_CHAR:
1.1 deraadt 293: printf("%s=", p->v_name);
294: col++;
1.26 nicm 295: if (p->v_number) {
296: cp = ctrl(p->v_number);
1.1 deraadt 297: col += size(cp);
298: printf("%s", cp);
299: }
300: break;
301: }
302: if (col >= MIDDLE) {
303: col = 0;
304: printf("\r\n");
305: return;
306: }
307: }
308:
1.13 moritz 309: static char *
1.11 deraadt 310: vinterp(char *s, int stop)
1.1 deraadt 311: {
1.7 millert 312: char *p = s, c;
1.1 deraadt 313: int num;
314:
1.11 deraadt 315: while ((c = *s++) && c != stop) {
1.1 deraadt 316: switch (c) {
317:
318: case '^':
319: if (*s)
320: *p++ = *s++ - 0100;
321: else
322: *p++ = c;
323: break;
324:
325: case '\\':
326: num = 0;
327: c = *s++;
328: if (c >= '0' && c <= '7')
329: num = (num<<3)+(c-'0');
330: else {
1.7 millert 331: char *q = "n\nr\rt\tb\bf\f";
1.1 deraadt 332:
333: for (; *q; q++)
334: if (c == *q++) {
335: *p++ = *q;
336: goto cont;
337: }
338: *p++ = c;
339: cont:
340: break;
341: }
342: if ((c = *s++) >= '0' && c <= '7') {
343: num = (num<<3)+(c-'0');
344: if ((c = *s++) >= '0' && c <= '7')
345: num = (num<<3)+(c-'0');
346: else
347: s--;
348: } else
349: s--;
350: *p++ = num;
351: break;
352:
353: default:
354: *p++ = c;
355: }
1.11 deraadt 356: }
1.1 deraadt 357: *p = '\0';
358: return (c == stop ? s-1 : NULL);
359: }