xref: /original-bsd/usr.bin/window/var.c (revision 2bb802fc)
1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 static char sccsid[] = "@(#)var.c	3.10 (Berkeley) 06/29/88";
20 #endif /* not lint */
21 
22 #include "value.h"
23 #include "var.h"
24 #include "string.h"
25 
26 char *malloc();
27 
28 struct var *
29 var_set1(head, name, v)
30 struct var **head;
31 char *name;
32 struct value *v;
33 {
34 	register struct var **p;
35 	register struct var *r;
36 	struct value val;
37 
38 	/* do this first, easier to recover */
39 	val = *v;
40 	if (val.v_type == V_STR && val.v_str != 0 &&
41 	    (val.v_str = str_cpy(val.v_str)) == 0)
42 		return 0;
43 	if (*(p = var_lookup1(head, name)) == 0) {
44 		r = (struct var *) malloc(sizeof (struct var));
45 		if (r == 0) {
46 			val_free(val);
47 			return 0;
48 		}
49 		if ((r->r_name = str_cpy(name)) == 0) {
50 			val_free(val);
51 			free((char *) r);
52 			return 0;
53 		}
54 		r->r_left = r->r_right = 0;
55 		*p = r;
56 	} else {
57 		r = *p;
58 		val_free(r->r_val);
59 	}
60 	r->r_val = val;
61 	return r;
62 }
63 
64 struct var *
65 var_setstr1(head, name, str)
66 struct var **head;
67 char *name;
68 char *str;
69 {
70 	struct value v;
71 
72 	v.v_type = V_STR;
73 	v.v_str = str;
74 	return var_set1(head, name, &v);
75 }
76 
77 struct var *
78 var_setnum1(head, name, num)
79 struct var **head;
80 char *name;
81 int num;
82 {
83 	struct value v;
84 
85 	v.v_type = V_NUM;
86 	v.v_num = num;
87 	return var_set1(head, name, &v);
88 }
89 
90 var_unset1(head, name)
91 struct var **head;
92 char *name;
93 {
94 	register struct var **p;
95 	register struct var *r;
96 
97 	if (*(p = var_lookup1(head, name)) == 0)
98 		return -1;
99 	r = *p;
100 	*p = r->r_left;
101 	while (*p != 0)
102 		p = &(*p)->r_right;
103 	*p = r->r_right;
104 	val_free(r->r_val);
105 	str_free(r->r_name);
106 	free((char *) r);
107 	return 0;
108 }
109 
110 struct var **
111 var_lookup1(p, name)
112 register struct var **p;
113 register char *name;
114 {
115 	register cmp;
116 
117 	while (*p != 0) {
118 		if ((cmp = strcmp(name, (*p)->r_name)) < 0)
119 			p = &(*p)->r_left;
120 		else if (cmp > 0)
121 			p = &(*p)->r_right;
122 		else
123 			break;
124 	}
125 	return p;
126 }
127 
128 var_walk1(r, func, a)
129 register struct var *r;
130 int (*func)();
131 {
132 	if (r == 0)
133 		return 0;
134 	if (var_walk1(r->r_left, func, a) < 0 || (*func)(a, r) < 0
135 	    || var_walk1(r->r_right, func, a) < 0)
136 		return -1;
137 	return 0;
138 }
139