xref: /illumos-gate/usr/src/cmd/ipf/lib/common/var.c (revision 7c478bd9)
1 #include <ctype.h>
2 
3 #include "ipf.h"
4 
5 typedef	struct	variable	{
6 	struct	variable	*v_next;
7 	char	*v_name;
8 	char	*v_value;
9 } variable_t;
10 
11 static	variable_t	*vtop = NULL;
12 
13 static variable_t *find_var __P((char *));
14 static char *expand_string __P((char *, int));
15 
16 
17 static variable_t *find_var(name)
18 char *name;
19 {
20 	variable_t *v;
21 
22 	for (v = vtop; v != NULL; v = v->v_next)
23 		if (!strcmp(name, v->v_name))
24 			return v;
25 	return NULL;
26 }
27 
28 
29 char *get_variable(string, after, line)
30 char *string, **after;
31 int line;
32 {
33 	char c, *s, *t, *value;
34 	variable_t *v;
35 
36 	s = string;
37 
38 	if (*s == '{') {
39 		s++;
40 		for (t = s; *t != '\0'; t++)
41 			if (*t == '}')
42 				break;
43 		if (*t == '\0') {
44 			fprintf(stderr, "%d: { without }\n", line);
45 			return NULL;
46 		}
47 	} else if (isalpha(*s)) {
48 		for (t = s + 1; *t != '\0'; t++)
49 			if (!isalpha(*t) && !isdigit(*t))
50 				break;
51 	} else {
52 		fprintf(stderr, "%d: variables cannot start with '%c'\n",
53 			line, *s);
54 		return NULL;
55 	}
56 
57 	if (after != NULL)
58 		*after = t;
59 	c = *t;
60 	*t = '\0';
61 	v = find_var(s);
62 	*t = c;
63 	if (v == NULL) {
64 		fprintf(stderr, "%d: unknown variable '%s'\n", line, s);
65 		return NULL;
66 	}
67 
68 	s = strdup(v->v_value);
69 	value = expand_string(s, line);
70 	if (value != s)
71 		free(s);
72 	return value;
73 }
74 
75 
76 static char *expand_string(oldstring, line)
77 char *oldstring;
78 int line;
79 {
80 	char c, *s, *p1, *p2, *p3, *newstring, *value;
81 	int len;
82 
83 	p3 = NULL;
84 	newstring = oldstring;
85 
86 	for (s = oldstring; *s != '\0'; s++)
87 		if (*s == '$') {
88 			*s = '\0';
89 			s++;
90 
91 			switch (*s)
92 			{
93 			case '$' :
94 				bcopy(s, s - 1, strlen(s));
95 				break;
96 			default :
97 				c = *s;
98 				value = get_variable(s, &p3, line);
99 				if (value == NULL)
100 					return NULL;
101 
102 				p2 = expand_string(value, line);
103 				if (p2 == NULL)
104 					return NULL;
105 
106 				len = strlen(newstring) + strlen(p2);
107 				if (p3 != NULL) {
108 					if (c == '{' && *p3 == '}')
109 						p3++;
110 					len += strlen(p3);
111 				}
112 				p1 = malloc(len + 1);
113 				if (p1 == NULL)
114 					return NULL;
115 
116 				*(s - 1) = '\0';
117 				strcpy(p1, newstring);
118 				strcat(p1, p2);
119 				if (p3 != NULL)
120 					strcat(p1, p3);
121 
122 				s = p1 + len - strlen(p3);
123 				if (newstring != oldstring)
124 					free(newstring);
125 				newstring = p1;
126 				break;
127 			}
128 		}
129 	return newstring;
130 }
131 
132 
133 void set_variable(name, value)
134 char *name;
135 char *value;
136 {
137 	variable_t *v;
138 	int len;
139 
140 	if (name == NULL || value == NULL || *name == '\0')
141 		return;
142 
143 	v = find_var(name);
144 	if (v != NULL) {
145 		free(v->v_value);
146 		v->v_value = strdup(value);
147 		return;
148 	}
149 
150 	len = strlen(value);
151 
152 	if ((*value == '"' && value[len - 1] == '"') ||
153 	    (*value == '\'' && value[len - 1] == '\'')) {
154 		value[len - 1] = '\0';
155 		value++;
156 		len -=2;
157 	}
158 
159 	v = (variable_t *)malloc(sizeof(*v));
160 	if (v == NULL)
161 		return;
162 	v->v_name = strdup(name);
163 	v->v_value = strdup(value);
164 	v->v_next = vtop;
165 	vtop = v;
166 }
167