Home | History | Annotate | Line # | Download | only in tip
value.c revision 1.8
      1 /*	$NetBSD: value.c,v 1.8 1997/11/23 04:03:05 mrg 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 #include <sys/cdefs.h>
     37 #ifndef lint
     38 #if 0
     39 static char sccsid[] = "@(#)value.c	8.1 (Berkeley) 6/6/93";
     40 #endif
     41 __RCSID("$NetBSD: value.c,v 1.8 1997/11/23 04:03:05 mrg Exp $");
     42 #endif /* not lint */
     43 
     44 #include "tip.h"
     45 
     46 #define MIDDLE	35
     47 
     48 static int col = 0;
     49 
     50 static	int	vaccess __P((unsigned, unsigned));
     51 static	void	vassign __P((value_t *, char *));
     52 static	value_t *vlookup __P((char *));
     53 static	void	vprint __P((value_t *));
     54 static	void	vtoken __P((char *));
     55 
     56 /*
     57  * Variable manipulation
     58  */
     59 void
     60 vinit()
     61 {
     62 	value_t *p;
     63 	char *cp;
     64 	FILE *f;
     65 	char file[MAXPATHLEN];
     66 
     67 	for (p = vtable; p->v_name != NULL; p++) {
     68 		if (p->v_type&ENVIRON)
     69 			if ((cp = getenv(p->v_name)) != NULL)
     70 				p->v_value = cp;
     71 		if (p->v_type&IREMOTE)
     72 			setnumber(p->v_value, *address(p->v_value));
     73 	}
     74 	/*
     75 	 * Read the .tiprc file in the HOME directory
     76 	 *  for sets
     77 	 */
     78 	snprintf(file, sizeof(file), "%s/.tiprc", value(HOME));
     79 	if ((f = fopen(file, "r")) != NULL) {
     80 		char *tp;
     81 
     82 		while (fgets(file, sizeof(file)-1, f) != NULL) {
     83 			if (vflag)
     84 				printf("set %s", file);
     85 			if ((tp = strrchr(file, '\n')) != NULL)
     86 				*tp = '\0';
     87 			vlex(file);
     88 		}
     89 		fclose(f);
     90 	}
     91 	/*
     92 	 * To allow definition of exception prior to fork
     93 	 */
     94 	vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
     95 }
     96 
     97 void
     98 vassign(p, v)
     99 	value_t *p;
    100 	char *v;
    101 {
    102 
    103 	if (!vaccess(p->v_access, WRITE)) {
    104 		printf("access denied\r\n");
    105 		return;
    106 	}
    107 	switch (p->v_type&TMASK) {
    108 
    109 	case STRING:
    110 		if (p->v_value && equal(p->v_value, v))
    111 			return;
    112 		if (!(p->v_type&(ENVIRON|INIT)))
    113 			free(p->v_value);
    114 		if ((p->v_value = strdup(v)) == NULL) {
    115 			printf("out of core\r\n");
    116 			return;
    117 		}
    118 		p->v_type &= ~(ENVIRON|INIT);
    119 		break;
    120 
    121 	case NUMBER:
    122 		if (number(p->v_value) == number(v))
    123 			return;
    124 		setnumber(p->v_value, number(v));
    125 		break;
    126 
    127 	case BOOL:
    128 		if (boolean(p->v_value) == (*v != '!'))
    129 			return;
    130 		setboolean(p->v_value, (*v != '!'));
    131 		break;
    132 
    133 	case CHAR:
    134 		if (character(p->v_value) == *v)
    135 			return;
    136 		setcharacter(p->v_value, *v);
    137 	}
    138 	p->v_access |= CHANGED;
    139 }
    140 
    141 void
    142 vlex(s)
    143 	char *s;
    144 {
    145 	value_t *p;
    146 
    147 	if (equal(s, "all")) {
    148 		for (p = vtable; p->v_name; p++)
    149 			if (vaccess(p->v_access, READ))
    150 				vprint(p);
    151 	} else {
    152 		char *cp;
    153 
    154 		do {
    155 			if ((cp = vinterp(s, ' ')) != NULL)
    156 				cp++;
    157 			vtoken(s);
    158 			s = cp;
    159 		} while (s);
    160 	}
    161 	if (col > 0) {
    162 		printf("\r\n");
    163 		col = 0;
    164 	}
    165 }
    166 
    167 static void
    168 vtoken(s)
    169 	char *s;
    170 {
    171 	value_t *p;
    172 	char *cp;
    173 
    174 	if ((cp = strchr(s, '=')) != NULL) {
    175 		*cp = '\0';
    176 		if ((p = vlookup(s)) != NULL) {
    177 			cp++;
    178 			if (p->v_type&NUMBER)
    179 				vassign(p, (char *)(long)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 = strchr(s, '?')) != NULL) {
    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 != NULL) {
    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 	value_t *p;
    209 {
    210 	char *cp;
    211 
    212 	if (col > 0 && col < MIDDLE)
    213 		while (col++ < MIDDLE)
    214 			putchar(' ');
    215 	col += strlen(p->v_name);
    216 	switch (p->v_type&TMASK) {
    217 
    218 	case BOOL:
    219 		if (boolean(p->v_value) == FALSE) {
    220 			col++;
    221 			putchar('!');
    222 		}
    223 		printf("%s", p->v_name);
    224 		break;
    225 
    226 	case STRING:
    227 		printf("%s=", p->v_name);
    228 		col++;
    229 		if (p->v_value) {
    230 			cp = interp(p->v_value);
    231 			col += strlen(cp);
    232 			printf("%s", cp);
    233 		}
    234 		break;
    235 
    236 	case NUMBER:
    237 		col += 6;
    238 		printf("%s=%-5d", p->v_name, (int)number(p->v_value));
    239 		break;
    240 
    241 	case CHAR:
    242 		printf("%s=", p->v_name);
    243 		col++;
    244 		if (p->v_value) {
    245 			cp = ctrl(character(p->v_value));
    246 			col += strlen(cp);
    247 			printf("%s", cp);
    248 		}
    249 		break;
    250 	}
    251 	if (col >= MIDDLE) {
    252 		col = 0;
    253 		printf("\r\n");
    254 		return;
    255 	}
    256 }
    257 
    258 
    259 static int
    260 vaccess(mode, rw)
    261 	unsigned mode, rw;
    262 {
    263 	if (mode & (rw<<PUBLIC))
    264 		return (1);
    265 	if (mode & (rw<<PRIVATE))
    266 		return (1);
    267 	return ((mode & (rw<<ROOT)) && getuid() == 0);
    268 }
    269 
    270 static value_t *
    271 vlookup(s)
    272 	char *s;
    273 {
    274 	value_t *p;
    275 
    276 	for (p = vtable; p->v_name; p++)
    277 		if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
    278 			return (p);
    279 	return (NULL);
    280 }
    281 
    282 char *
    283 vinterp(s, stop)
    284 	char *s;
    285 	char stop;
    286 {
    287 	char *p = s, c;
    288 	int num;
    289 
    290 	while ((c = *s++) && c != stop)
    291 		switch (c) {
    292 
    293 		case '^':
    294 			if (*s)
    295 				*p++ = *s++ - 0100;
    296 			else
    297 				*p++ = c;
    298 			break;
    299 
    300 		case '\\':
    301 			num = 0;
    302 			c = *s++;
    303 			if (c >= '0' && c <= '7')
    304 				num = (num<<3)+(c-'0');
    305 			else {
    306 				char *q = "n\nr\rt\tb\bf\f";
    307 
    308 				for (; *q; q++)
    309 					if (c == *q++) {
    310 						*p++ = *q;
    311 						goto cont;
    312 					}
    313 				*p++ = c;
    314 			cont:
    315 				break;
    316 			}
    317 			if ((c = *s++) >= '0' && c <= '7') {
    318 				num = (num<<3)+(c-'0');
    319 				if ((c = *s++) >= '0' && c <= '7')
    320 					num = (num<<3)+(c-'0');
    321 				else
    322 					s--;
    323 			} else
    324 				s--;
    325 			*p++ = num;
    326 			break;
    327 
    328 		default:
    329 			*p++ = c;
    330 		}
    331 	*p = '\0';
    332 	return (c == stop ? s-1 : NULL);
    333 }
    334 
    335 /*
    336  * assign variable s with value v (for NUMBER or STRING or CHAR types)
    337  */
    338 
    339 int
    340 vstring(s,v)
    341 	char *s;
    342 	char *v;
    343 {
    344 	value_t *p;
    345 
    346 	p = vlookup(s);
    347 	if (p == 0)
    348 		return (1);
    349 	if (p->v_type&NUMBER)
    350 		vassign(p, (char *)(long)atoi(v));
    351 	else {
    352 		if (strcmp(s, "record") == 0)
    353 			v = expand(v);
    354 		vassign(p, v);
    355 	}
    356 	return (0);
    357 }
    358