Home | History | Annotate | Line # | Download | only in tip
value.c revision 1.4
      1 /*	$NetBSD: value.c,v 1.4 1996/12/29 10:34:14 cgd Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1983, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by the University of
     18  *	California, Berkeley and its contributors.
     19  * 4. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #ifndef lint
     37 #if 0
     38 static char sccsid[] = "@(#)value.c	8.1 (Berkeley) 6/6/93";
     39 #endif
     40 static char rcsid[] = "$NetBSD: value.c,v 1.4 1996/12/29 10:34:14 cgd Exp $";
     41 #endif /* not lint */
     42 
     43 #include "tip.h"
     44 
     45 #define MIDDLE	35
     46 
     47 static value_t *vlookup();
     48 static int col = 0;
     49 
     50 /*
     51  * Variable manipulation
     52  */
     53 vinit()
     54 {
     55 	register value_t *p;
     56 	register char *cp;
     57 	FILE *f;
     58 	char file[256];
     59 
     60 	for (p = vtable; p->v_name != NULL; p++) {
     61 		if (p->v_type&ENVIRON)
     62 			if (cp = getenv(p->v_name))
     63 				p->v_value = cp;
     64 		if (p->v_type&IREMOTE)
     65 			setnumber(p->v_value, *address(p->v_value));
     66 	}
     67 	/*
     68 	 * Read the .tiprc file in the HOME directory
     69 	 *  for sets
     70 	 */
     71 	strcpy(file, value(HOME));
     72 	strcat(file, "/.tiprc");
     73 	if ((f = fopen(file, "r")) != NULL) {
     74 		register char *tp;
     75 
     76 		while (fgets(file, sizeof(file)-1, f) != NULL) {
     77 			if (vflag)
     78 				printf("set %s", file);
     79 			if (tp = rindex(file, '\n'))
     80 				*tp = '\0';
     81 			vlex(file);
     82 		}
     83 		fclose(f);
     84 	}
     85 	/*
     86 	 * To allow definition of exception prior to fork
     87 	 */
     88 	vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
     89 }
     90 
     91 static int vaccess();
     92 
     93 /*VARARGS1*/
     94 vassign(p, v)
     95 	register value_t *p;
     96 	char *v;
     97 {
     98 
     99 	if (!vaccess(p->v_access, WRITE)) {
    100 		printf("access denied\r\n");
    101 		return;
    102 	}
    103 	switch (p->v_type&TMASK) {
    104 
    105 	case STRING:
    106 		if (p->v_value && equal(p->v_value, v))
    107 			return;
    108 		if (!(p->v_type&(ENVIRON|INIT)))
    109 			free(p->v_value);
    110 		if ((p->v_value = malloc(size(v)+1)) == NOSTR) {
    111 			printf("out of core\r\n");
    112 			return;
    113 		}
    114 		p->v_type &= ~(ENVIRON|INIT);
    115 		strcpy(p->v_value, v);
    116 		break;
    117 
    118 	case NUMBER:
    119 		if (number(p->v_value) == number(v))
    120 			return;
    121 		setnumber(p->v_value, number(v));
    122 		break;
    123 
    124 	case BOOL:
    125 		if (boolean(p->v_value) == (*v != '!'))
    126 			return;
    127 		setboolean(p->v_value, (*v != '!'));
    128 		break;
    129 
    130 	case CHAR:
    131 		if (character(p->v_value) == *v)
    132 			return;
    133 		setcharacter(p->v_value, *v);
    134 	}
    135 	p->v_access |= CHANGED;
    136 }
    137 
    138 static void vprint();
    139 
    140 vlex(s)
    141 	register char *s;
    142 {
    143 	register value_t *p;
    144 	static void vtoken();
    145 
    146 	if (equal(s, "all")) {
    147 		for (p = vtable; p->v_name; p++)
    148 			if (vaccess(p->v_access, READ))
    149 				vprint(p);
    150 	} else {
    151 		register char *cp;
    152 
    153 		do {
    154 			if (cp = vinterp(s, ' '))
    155 				cp++;
    156 			vtoken(s);
    157 			s = cp;
    158 		} while (s);
    159 	}
    160 	if (col > 0) {
    161 		printf("\r\n");
    162 		col = 0;
    163 	}
    164 }
    165 
    166 static void
    167 vtoken(s)
    168 	register char *s;
    169 {
    170 	register value_t *p;
    171 	register char *cp;
    172 	char *expand();
    173 
    174 	if (cp = index(s, '=')) {
    175 		*cp = '\0';
    176 		if (p = vlookup(s)) {
    177 			cp++;
    178 			if (p->v_type&NUMBER)
    179 				vassign(p, atoi(cp));
    180 			else {
    181 				if (strcmp(s, "record") == 0)
    182 					cp = expand(cp);
    183 				vassign(p, cp);
    184 			}
    185 			return;
    186 		}
    187 	} else if (cp = index(s, '?')) {
    188 		*cp = '\0';
    189 		if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
    190 			vprint(p);
    191 			return;
    192 		}
    193 	} else {
    194 		if (*s != '!')
    195 			p = vlookup(s);
    196 		else
    197 			p = vlookup(s+1);
    198 		if (p != NOVAL) {
    199 			vassign(p, s);
    200 			return;
    201 		}
    202 	}
    203 	printf("%s: unknown variable\r\n", s);
    204 }
    205 
    206 static void
    207 vprint(p)
    208 	register value_t *p;
    209 {
    210 	register char *cp;
    211 	extern char *interp(), *ctrl();
    212 
    213 	if (col > 0 && col < MIDDLE)
    214 		while (col++ < MIDDLE)
    215 			putchar(' ');
    216 	col += size(p->v_name);
    217 	switch (p->v_type&TMASK) {
    218 
    219 	case BOOL:
    220 		if (boolean(p->v_value) == FALSE) {
    221 			col++;
    222 			putchar('!');
    223 		}
    224 		printf("%s", p->v_name);
    225 		break;
    226 
    227 	case STRING:
    228 		printf("%s=", p->v_name);
    229 		col++;
    230 		if (p->v_value) {
    231 			cp = interp(p->v_value, NULL);
    232 			col += size(cp);
    233 			printf("%s", cp);
    234 		}
    235 		break;
    236 
    237 	case NUMBER:
    238 		col += 6;
    239 		printf("%s=%-5d", p->v_name, number(p->v_value));
    240 		break;
    241 
    242 	case CHAR:
    243 		printf("%s=", p->v_name);
    244 		col++;
    245 		if (p->v_value) {
    246 			cp = ctrl(character(p->v_value));
    247 			col += size(cp);
    248 			printf("%s", cp);
    249 		}
    250 		break;
    251 	}
    252 	if (col >= MIDDLE) {
    253 		col = 0;
    254 		printf("\r\n");
    255 		return;
    256 	}
    257 }
    258 
    259 
    260 static int
    261 vaccess(mode, rw)
    262 	register unsigned mode, rw;
    263 {
    264 	if (mode & (rw<<PUBLIC))
    265 		return (1);
    266 	if (mode & (rw<<PRIVATE))
    267 		return (1);
    268 	return ((mode & (rw<<ROOT)) && getuid() == 0);
    269 }
    270 
    271 static value_t *
    272 vlookup(s)
    273 	register char *s;
    274 {
    275 	register value_t *p;
    276 
    277 	for (p = vtable; p->v_name; p++)
    278 		if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
    279 			return (p);
    280 	return (NULL);
    281 }
    282 
    283 char *
    284 vinterp(s, stop)
    285 	register char *s;
    286 	char stop;
    287 {
    288 	register char *p = s, c;
    289 	int num;
    290 
    291 	while ((c = *s++) && c != stop)
    292 		switch (c) {
    293 
    294 		case '^':
    295 			if (*s)
    296 				*p++ = *s++ - 0100;
    297 			else
    298 				*p++ = c;
    299 			break;
    300 
    301 		case '\\':
    302 			num = 0;
    303 			c = *s++;
    304 			if (c >= '0' && c <= '7')
    305 				num = (num<<3)+(c-'0');
    306 			else {
    307 				register char *q = "n\nr\rt\tb\bf\f";
    308 
    309 				for (; *q; q++)
    310 					if (c == *q++) {
    311 						*p++ = *q;
    312 						goto cont;
    313 					}
    314 				*p++ = c;
    315 			cont:
    316 				break;
    317 			}
    318 			if ((c = *s++) >= '0' && c <= '7') {
    319 				num = (num<<3)+(c-'0');
    320 				if ((c = *s++) >= '0' && c <= '7')
    321 					num = (num<<3)+(c-'0');
    322 				else
    323 					s--;
    324 			} else
    325 				s--;
    326 			*p++ = num;
    327 			break;
    328 
    329 		default:
    330 			*p++ = c;
    331 		}
    332 	*p = '\0';
    333 	return (c == stop ? s-1 : NULL);
    334 }
    335 
    336 /*
    337  * assign variable s with value v (for NUMBER or STRING or CHAR types)
    338  */
    339 
    340 vstring(s,v)
    341 	register char *s;
    342 	register char *v;
    343 {
    344 	register value_t *p;
    345 	char *expand();
    346 
    347 	p = vlookup(s);
    348 	if (p == 0)
    349 		return (1);
    350 	if (p->v_type&NUMBER)
    351 		vassign(p, atoi(v));
    352 	else {
    353 		if (strcmp(s, "record") == 0)
    354 			v = expand(v);
    355 		vassign(p, v);
    356 	}
    357 	return (0);
    358 }
    359