GitHub

@@ -177,6 +177,72 @@ static char *function_expand(const char *name, int argc, char *argv[])

177177

return 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

*/

186252

static 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;

189255

int new_argc = 0;

190256

char *new_argv[FUNCTION_MAX_ARGS];

191257

int nest = 0;

192258

int i;

259+

unsigned long n;

193260194261

tmp = 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+196274

prev = p = tmp;

197275198276

/*

@@ -238,6 +316,11 @@ static char *eval_clause(const char *str, size_t len, int argc, char *argv[])

238316

new_argv[i] = expand_string_with_args(new_argv[i + 1],

239317

argc, 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 */

242325

res = function_expand(name, new_argc, new_argv);

243326

if (res)

@@ -255,6 +338,7 @@ static char *eval_clause(const char *str, size_t len, int argc, char *argv[])

255338

for (i = 0; i < new_argc; i++)

256339

free(new_argv[i]);

257340

free(name);

341+

free_tmp:

258342

free(tmp);

259343260344

return res;

Read the original on github.com ↗