diff options
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | doc/pies.texi | 15 | ||||
-rw-r--r-- | lib/envop.c | 51 | ||||
-rw-r--r-- | src/pies.c | 22 |
4 files changed, 77 insertions, 19 deletions
@@ -1,2 +1,2 @@ | |||
1 | GNU Pies NEWS -- history of user-visible changes. 2019-06-06 | 1 | GNU Pies NEWS -- history of user-visible changes. 2019-06-07 |
2 | See the end of file for copying conditions. | 2 | See the end of file for copying conditions. |
@@ -57,2 +57,8 @@ to variable expansion. | |||
57 | 57 | ||
58 | ** eval "VALUE" | ||
59 | Perform variable expansion on VALUE and discard the result (similar | ||
60 | to the shell ":" command). Useful for side effects, e.g.: | ||
61 | |||
62 | eval ${HOME:=/home/t} | ||
63 | |||
58 | ** unset NAME | 64 | ** 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 @{ | |||
1066 | set "@var{name}=@var{value}"; | 1066 | set "@var{name}=@var{value}"; |
1067 | eval "@var{value}"; | ||
1067 | unset @var{pattern}; | 1068 | unset @var{pattern}; |
@@ -1125,2 +1126,16 @@ env @{ | |||
1125 | 1126 | ||
1127 | @deffn {env} eval "@var{value}" | ||
1128 | Perform variable expansion on @var{value} and discard the result. This | ||
1129 | is useful for side-effects. For example, to provide default value for | ||
1130 | the @env{LD_LIBRARY_PATH} variable, one may write: | ||
1131 | |||
1132 | @example | ||
1133 | @group | ||
1134 | env @{ | ||
1135 | eval "$@{LD_LIBRARY_PATH:=/usr/local/lib@}"; | ||
1136 | @} | ||
1137 | @end group | ||
1138 | @end example | ||
1139 | @end deffn | ||
1140 | |||
1126 | @deffn {env} unset @var{pattern} | 1141 | @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) | |||
169 | 169 | ||
170 | if (!name) | 170 | if (!value) |
171 | { | 171 | { |
172 | errno = EINVAL; | 172 | if (!name) |
173 | return -1; | 173 | { |
174 | errno = EINVAL; | ||
175 | return -1; | ||
176 | } | ||
177 | return environ_unset (env, name, value); | ||
174 | } | 178 | } |
175 | if (!value) | ||
176 | return environ_unset (env, name, value); | ||
177 | 179 | ||
@@ -193,3 +195,14 @@ environ_set (environ_t *env, char const *name, char const *value) | |||
193 | 195 | ||
194 | if (strcmp (name, ":") == 0) | 196 | if (ws.ws_envbuf) |
197 | { | ||
198 | free (env->env_base); | ||
199 | env->env_base = ws.ws_envbuf; | ||
200 | env->env_count = ws.ws_envidx; | ||
201 | env->env_max = ws.ws_envsiz; | ||
202 | ws.ws_envbuf = NULL; | ||
203 | ws.ws_envidx = 0; | ||
204 | ws.ws_envsiz = 0; | ||
205 | } | ||
206 | |||
207 | if (name == NULL || strcmp (name, ":") == 0) | ||
195 | { | 208 | { |
@@ -336,2 +349,3 @@ envop_entry_add (struct envop_entry **head, | |||
336 | size_t s; | 349 | size_t s; |
350 | char *p; | ||
337 | 351 | ||
@@ -343,3 +357,3 @@ envop_entry_add (struct envop_entry **head, | |||
343 | case envop_set: | 357 | case envop_set: |
344 | if (!name || !(*name == ':' || valid_envar_name (name))) | 358 | if (name && !(*name == ':' || valid_envar_name (name))) |
345 | { | 359 | { |
@@ -361,7 +375,5 @@ envop_entry_add (struct envop_entry **head, | |||
361 | if (name) | 375 | if (name) |
362 | { | 376 | s += strlen (name) + 1; |
363 | s += strlen (name) + 1; | 377 | if (value) |
364 | if (value) | 378 | s += strlen (value) + 1; |
365 | s += strlen (value) + 1; | ||
366 | } | ||
367 | op = malloc (s); | 379 | op = malloc (s); |
@@ -373,11 +385,14 @@ envop_entry_add (struct envop_entry **head, | |||
373 | op->value = NULL; | 385 | op->value = NULL; |
386 | |||
387 | p = (char*)(op + 1); | ||
374 | if (name) | 388 | if (name) |
375 | { | 389 | { |
376 | op->name = (char*)(op + 1); | 390 | op->name = p; |
377 | strcpy (op->name, name); | 391 | strcpy (op->name, name); |
378 | if (value) | 392 | p += strlen (name) + 1; |
379 | { | 393 | } |
380 | op->value = op->name + strlen (name) + 1; | 394 | if (value) |
381 | strcpy (op->value, value); | 395 | { |
382 | } | 396 | op->value = p; |
397 | strcpy (op->value, value); | ||
383 | } | 398 | } |
@@ -788,2 +788,18 @@ _cb_env_set (enum grecs_callback_command cmd, | |||
788 | static int | 788 | static int |
789 | _cb_env_eval (enum grecs_callback_command cmd, | ||
790 | grecs_node_t *node, | ||
791 | void *varptr, void *cb_data) | ||
792 | { | ||
793 | grecs_locus_t *locus = &node->locus; | ||
794 | grecs_value_t *value = node->v.value; | ||
795 | struct component *comp = varptr; | ||
796 | |||
797 | if (grecs_assert_node_value_type (cmd, node, GRECS_TYPE_STRING)) | ||
798 | return 1; | ||
799 | if (envop_entry_add (&comp->envop, envop_set, NULL, value->v.string)) | ||
800 | grecs_error (locus, errno, "envop_entry_add"); | ||
801 | return 0; | ||
802 | } | ||
803 | |||
804 | static int | ||
789 | _cb_env_unset (enum grecs_callback_command cmd, | 805 | _cb_env_unset (enum grecs_callback_command cmd, |
@@ -827,2 +843,8 @@ struct grecs_keyword cb_env_keywords[] = { | |||
827 | _cb_env_set }, | 843 | _cb_env_set }, |
844 | { "eval", | ||
845 | N_("string"), | ||
846 | N_("Evaluate string. Useful for side-effects, e.g. eval ${X:=2}."), | ||
847 | grecs_type_string, GRECS_DFLT, | ||
848 | NULL, 0, | ||
849 | _cb_env_eval }, | ||
828 | { "unset", | 850 | { "unset", |