Sync usage with man page.
[netbsd-mini2440.git] / dist / ipf / lib / var.c
blobc1f35e9d17b5af428fe7aaf3ab2e9589682de1dc
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2002-2004 by Darren Reed.
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 *
8 * Id: var.c,v 1.4.2.3 2006/06/16 17:21:18 darrenr Exp
9 */
11 #include <ctype.h>
13 #include "ipf.h"
15 typedef struct variable {
16 struct variable *v_next;
17 char *v_name;
18 char *v_value;
19 } variable_t;
21 static variable_t *vtop = NULL;
23 static variable_t *find_var __P((char *));
24 static char *expand_string __P((char *, int));
27 static variable_t *find_var(name)
28 char *name;
30 variable_t *v;
32 for (v = vtop; v != NULL; v = v->v_next)
33 if (!strcmp(name, v->v_name))
34 return v;
35 return NULL;
39 char *get_variable(string, after, line)
40 char *string, **after;
41 int line;
43 char c, *s, *t, *value;
44 variable_t *v;
46 s = string;
48 if (*s == '{') {
49 s++;
50 for (t = s; *t != '\0'; t++)
51 if (*t == '}')
52 break;
53 if (*t == '\0') {
54 fprintf(stderr, "%d: { without }\n", line);
55 return NULL;
57 } else if (ISALPHA(*s)) {
58 for (t = s + 1; *t != '\0'; t++)
59 if (!ISALPHA(*t) && !ISDIGIT(*t) && (*t != '_'))
60 break;
61 } else {
62 fprintf(stderr, "%d: variables cannot start with '%c'\n",
63 line, *s);
64 return NULL;
67 if (after != NULL)
68 *after = t;
69 c = *t;
70 *t = '\0';
71 v = find_var(s);
72 *t = c;
73 if (v == NULL) {
74 fprintf(stderr, "%d: unknown variable '%s'\n", line, s);
75 return NULL;
78 s = strdup(v->v_value);
79 value = expand_string(s, line);
80 if (value != s)
81 free(s);
82 return value;
86 static char *expand_string(oldstring, line)
87 char *oldstring;
88 int line;
90 char c, *s, *p1, *p2, *p3, *newstring, *value;
91 int len;
93 p3 = NULL;
94 newstring = oldstring;
96 for (s = oldstring; *s != '\0'; s++)
97 if (*s == '$') {
98 *s = '\0';
99 s++;
101 switch (*s)
103 case '$' :
104 bcopy(s, s - 1, strlen(s));
105 break;
106 default :
107 c = *s;
108 if (c == '\0')
109 return newstring;
111 value = get_variable(s, &p3, line);
112 if (value == NULL)
113 return NULL;
115 p2 = expand_string(value, line);
116 if (p2 == NULL)
117 return NULL;
119 len = strlen(newstring) + strlen(p2);
120 if (p3 != NULL) {
121 if (c == '{' && *p3 == '}')
122 p3++;
123 len += strlen(p3);
125 p1 = malloc(len + 1);
126 if (p1 == NULL)
127 return NULL;
129 *(s - 1) = '\0';
130 strcpy(p1, newstring);
131 strcat(p1, p2);
132 if (p3 != NULL)
133 strcat(p1, p3);
135 s = p1 + len - strlen(p3) - 1;
136 if (newstring != oldstring)
137 free(newstring);
138 newstring = p1;
139 break;
142 return newstring;
146 void set_variable(name, value)
147 char *name;
148 char *value;
150 variable_t *v;
151 int len;
153 if (name == NULL || value == NULL || *name == '\0')
154 return;
156 v = find_var(name);
157 if (v != NULL) {
158 free(v->v_value);
159 v->v_value = strdup(value);
160 return;
163 len = strlen(value);
165 if ((*value == '"' && value[len - 1] == '"') ||
166 (*value == '\'' && value[len - 1] == '\'')) {
167 value[len - 1] = '\0';
168 value++;
169 len -=2;
172 v = (variable_t *)malloc(sizeof(*v));
173 if (v == NULL)
174 return;
175 v->v_name = strdup(name);
176 v->v_value = strdup(value);
177 v->v_next = vtop;
178 vtop = v;