summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--NEWS8
-rw-r--r--doc/pies.texi15
-rw-r--r--lib/envop.c51
-rw-r--r--src/pies.c22
4 files changed, 77 insertions, 19 deletions
diff --git a/NEWS b/NEWS
index 4ee1ae5..f5be6dd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,2 +1,2 @@
-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.
@@ -57,2 +57,8 @@ 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
diff --git a/doc/pies.texi b/doc/pies.texi
index 63064e5..4bd2f8f 100644
--- a/doc/pies.texi
+++ b/doc/pies.texi
@@ -1066,2 +1066,3 @@ env @{
set "@var{name}=@var{value}";
+ eval "@var{value}";
unset @var{pattern};
@@ -1125,2 +1126,16 @@ env @{
+@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}
diff --git a/lib/envop.c b/lib/envop.c
index ce24b92..93bd425 100644
--- a/lib/envop.c
+++ b/lib/envop.c
@@ -169,9 +169,11 @@ environ_set (environ_t *env, char const *name, char const *value)
- if (!name)
+ if (!value)
{
- errno = EINVAL;
- return -1;
+ if (!name)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+ return environ_unset (env, name, value);
}
- if (!value)
- return environ_unset (env, name, value);
@@ -193,3 +195,14 @@ environ_set (environ_t *env, char const *name, char const *value)
- 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)
{
@@ -336,2 +349,3 @@ envop_entry_add (struct envop_entry **head,
size_t s;
+ char *p;
@@ -343,3 +357,3 @@ envop_entry_add (struct envop_entry **head,
case envop_set:
- if (!name || !(*name == ':' || valid_envar_name (name)))
+ if (name && !(*name == ':' || valid_envar_name (name)))
{
@@ -361,7 +375,5 @@ envop_entry_add (struct envop_entry **head,
if (name)
- {
- s += strlen (name) + 1;
- if (value)
- s += strlen (value) + 1;
- }
+ s += strlen (name) + 1;
+ if (value)
+ s += strlen (value) + 1;
op = malloc (s);
@@ -373,11 +385,14 @@ envop_entry_add (struct envop_entry **head,
op->value = NULL;
+
+ p = (char*)(op + 1);
if (name)
{
- op->name = (char*)(op + 1);
+ op->name = p;
strcpy (op->name, name);
- if (value)
- {
- op->value = op->name + strlen (name) + 1;
- strcpy (op->value, value);
- }
+ p += strlen (name) + 1;
+ }
+ if (value)
+ {
+ op->value = p;
+ strcpy (op->value, value);
}
diff --git a/src/pies.c b/src/pies.c
index 1f5fb8f..73d33a0 100644
--- a/src/pies.c
+++ b/src/pies.c
@@ -788,2 +788,18 @@ _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,
@@ -827,2 +843,8 @@ struct grecs_keyword cb_env_keywords[] = {
_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",

Return to:

Send suggestions and report system problems to the System administrator.