aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--doc/pies.texi15
-rw-r--r--lib/envop.c31
-rw-r--r--src/pies.c22
4 files changed, 67 insertions, 9 deletions
diff --git a/NEWS b/NEWS
index 4ee1ae5..f5be6dd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU Pies NEWS -- history of user-visible changes. 2019-06-06
+GNU Pies NEWS -- history of user-visible changes. 2019-06-07
See the end of file for copying conditions.
Please send Pies bug reports to <bug-pies@gnu.org> or
@@ -55,6 +55,12 @@ variables matching the pattern are retained.
Sets the environment variable for the component. VALUE is subject
to variable expansion.
+** eval "VALUE"
+Perform variable expansion on VALUE and discard the result (similar
+to the shell ":" command). Useful for side effects, e.g.:
+
+ eval ${HOME:=/home/t}
+
** unset NAME
Unsets the variable. NAME can be a globbing pattern, in which case all
variables matching the pattern are unset.
diff --git a/doc/pies.texi b/doc/pies.texi
index 63064e5..4bd2f8f 100644
--- a/doc/pies.texi
+++ b/doc/pies.texi
@@ -1064,6 +1064,7 @@ env @{
clear;
keep @var{pattern};
set "@var{name}=@var{value}";
+ eval "@var{value}";
unset @var{pattern};
@}
@end group
@@ -1123,6 +1124,20 @@ env @{
@end example
@end deffn
+@deffn {env} eval "@var{value}"
+Perform variable expansion on @var{value} and discard the result. This
+is useful for side-effects. For example, to provide default value for
+the @env{LD_LIBRARY_PATH} variable, one may write:
+
+@example
+@group
+env @{
+ eval "$@{LD_LIBRARY_PATH:=/usr/local/lib@}";
+@}
+@end group
+@end example
+@end deffn
+
@deffn {env} unset @var{pattern}
Unset environment variables matching @var{pattern}. The following
will unset the @env{LOGIN} variable:
diff --git a/lib/envop.c b/lib/envop.c
index ce24b92..93bd425 100644
--- a/lib/envop.c
+++ b/lib/envop.c
@@ -167,13 +167,15 @@ environ_set (environ_t *env, char const *name, char const *value)
char *def;
struct wordsplit ws;
+ if (!value)
+ {
if (!name)
{
errno = EINVAL;
return -1;
}
- if (!value)
return environ_unset (env, name, value);
+ }
ws.ws_env = (char const **) env->env_base;
if (wordsplit (value, &ws,
@@ -191,7 +193,18 @@ environ_set (environ_t *env, char const *name, char const *value)
return -1;
}
- if (strcmp (name, ":") == 0)
+ if (ws.ws_envbuf)
+ {
+ free (env->env_base);
+ env->env_base = ws.ws_envbuf;
+ env->env_count = ws.ws_envidx;
+ env->env_max = ws.ws_envsiz;
+ ws.ws_envbuf = NULL;
+ ws.ws_envidx = 0;
+ ws.ws_envsiz = 0;
+ }
+
+ if (name == NULL || strcmp (name, ":") == 0)
{
wordsplit_free (&ws);
return 0;
@@ -334,6 +347,7 @@ envop_entry_add (struct envop_entry **head,
{
struct envop_entry *op;
size_t s;
+ char *p;
switch (code)
{
@@ -341,7 +355,7 @@ envop_entry_add (struct envop_entry **head,
break;
case envop_set:
- if (!name || !(*name == ':' || valid_envar_name (name)))
+ if (name && !(*name == ':' || valid_envar_name (name)))
{
errno = EINVAL;
return -1;
@@ -359,11 +373,9 @@ envop_entry_add (struct envop_entry **head,
s = sizeof (op[0]);
if (name)
- {
s += strlen (name) + 1;
if (value)
s += strlen (value) + 1;
- }
op = malloc (s);
if (!op)
return -1;
@@ -371,16 +383,19 @@ envop_entry_add (struct envop_entry **head,
op->code = code;
op->name = NULL;
op->value = NULL;
+
+ p = (char*)(op + 1);
if (name)
{
- op->name = (char*)(op + 1);
+ op->name = p;
strcpy (op->name, name);
+ p += strlen (name) + 1;
+ }
if (value)
{
- op->value = op->name + strlen (name) + 1;
+ op->value = p;
strcpy (op->value, value);
}
- }
envop_entry_insert (head, op);
return 0;
}
diff --git a/src/pies.c b/src/pies.c
index 1f5fb8f..73d33a0 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -786,6 +786,22 @@ _cb_env_set (enum grecs_callback_command cmd,
}
static int
+_cb_env_eval (enum grecs_callback_command cmd,
+ grecs_node_t *node,
+ void *varptr, void *cb_data)
+{
+ grecs_locus_t *locus = &node->locus;
+ grecs_value_t *value = node->v.value;
+ struct component *comp = varptr;
+
+ if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING))
+ return 1;
+ if (envop_entry_add (&comp->envop, envop_set, NULL, value->v.string))
+ grecs_error (locus, errno, "envop_entry_add");
+ return 0;
+}
+
+static int
_cb_env_unset (enum grecs_callback_command cmd,
grecs_node_t *node,
void *varptr, void *cb_data)
@@ -825,6 +841,12 @@ struct grecs_keyword cb_env_keywords[] = {
grecs_type_string, GRECS_DFLT,
NULL, 0,
_cb_env_set },
+ { "eval",
+ N_("string"),
+ N_("Evaluate string. Useful for side-effects, e.g. eval ${X:=2}."),
+ grecs_type_string, GRECS_DFLT,
+ NULL, 0,
+ _cb_env_eval },
{ "unset",
N_("name"),
N_("Unset environment variable. Name can contain wildcards."),

Return to:

Send suggestions and report system problems to the System administrator.