@@ -177,6 +177,72 @@ static char *function_expand(const char *name, int argc, char *argv[])
177177return NULL;
178178}
179179180+/*
181+ * Variables (and user-defined functions)
182+ */
183+static LIST_HEAD(variable_list);
184+185+struct variable {
186+char *name;
187+char *value;
188+struct list_head node;
189+};
190+191+static struct variable *variable_lookup(const char *name)
192+{
193+struct variable *v;
194+195+list_for_each_entry(v, &variable_list, node) {
196+if (!strcmp(name, v->name))
197+return v;
198+ }
199+200+return NULL;
201+}
202+203+static char *variable_expand(const char *name, int argc, char *argv[])
204+{
205+struct variable *v;
206+207+v = variable_lookup(name);
208+if (!v)
209+return NULL;
210+211+return expand_string_with_args(v->value, argc, argv);
212+}
213+214+void variable_add(const char *name, const char *value)
215+{
216+struct variable *v;
217+218+v = variable_lookup(name);
219+if (v) {
220+free(v->value);
221+ } else {
222+v = xmalloc(sizeof(*v));
223+v->name = xstrdup(name);
224+list_add_tail(&v->node, &variable_list);
225+ }
226+227+v->value = xstrdup(value);
228+}
229+230+static void variable_del(struct variable *v)
231+{
232+list_del(&v->node);
233+free(v->name);
234+free(v->value);
235+free(v);
236+}
237+238+void variable_all_del(void)
239+{
240+struct variable *v, *tmp;
241+242+list_for_each_entry_safe(v, tmp, &variable_list, node)
243+variable_del(v);
244+}
245+180246/*
181247 * Evaluate a clause with arguments. argc/argv are arguments from the upper
182248 * function call.
@@ -185,14 +251,26 @@ static char *function_expand(const char *name, int argc, char *argv[])
185251 */
186252static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
187253{
188-char *tmp, *name, *res, *prev, *p;
254+char *tmp, *name, *res, *endptr, *prev, *p;
189255int new_argc = 0;
190256char *new_argv[FUNCTION_MAX_ARGS];
191257int nest = 0;
192258int i;
259+unsigned long n;
193260194261tmp = xstrndup(str, len);
195262263+/*
264+ * If variable name is '1', '2', etc. It is generally an argument
265+ * from a user-function call (i.e. local-scope variable). If not
266+ * available, then look-up global-scope variables.
267+ */
268+n = strtoul(tmp, &endptr, 10);
269+if (!*endptr && n > 0 && n <= argc) {
270+res = xstrdup(argv[n - 1]);
271+ goto free_tmp;
272+ }
273+196274prev = p = tmp;
197275198276/*
@@ -238,6 +316,11 @@ static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
238316new_argv[i] = expand_string_with_args(new_argv[i + 1],
239317argc, argv);
240318319+/* Search for variables */
320+res = variable_expand(name, new_argc, new_argv);
321+if (res)
322+ goto free;
323+241324/* Look for built-in functions */
242325res = function_expand(name, new_argc, new_argv);
243326if (res)
@@ -255,6 +338,7 @@ static char *eval_clause(const char *str, size_t len, int argc, char *argv[])
255338for (i = 0; i < new_argc; i++)
256339free(new_argv[i]);
257340free(name);
341+free_tmp:
258342free(tmp);
259343260344return res;