diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2019-06-13 14:20:20 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2019-06-13 14:20:20 +0300 |
commit | 12304127b52650588877f00b0c4b32dae083e852 (patch) | |
tree | e6a2fa21b66d16a82a7913933b88bd091f633dc6 /src | |
parent | dbe318987cf3a36fe63893205d3df0dc3be7fa4a (diff) | |
download | grecs-12304127b52650588877f00b0c4b32dae083e852.tar.gz grecs-12304127b52650588877f00b0c4b32dae083e852.tar.bz2 |
wordsplit: configurable order of lookups if both WRDSF_ENV and WRDSF_GETVAR are set
* lib/wordsplit.h (WRDSO_GETVARPREF): New option.
* lib/wordsplit.c (wordsplit_find_env): Rewrite as wsplt_env_lookup
wsplt_env_getvar): New function.
(expvar): Select preference of wsplt_env_lookup vs. wsplt_env_getvar
depending on the value if WRDSO_GETVARPREF option.
Diffstat (limited to 'src')
-rw-r--r-- | src/wordsplit.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/src/wordsplit.c b/src/wordsplit.c index d01fd43..9179a87 100644 --- a/src/wordsplit.c +++ b/src/wordsplit.c | |||
@@ -1036,5 +1036,4 @@ find_closing_paren (const char *str, size_t i, size_t len, size_t *poff, | |||
1036 | 1036 | ||
1037 | static int | 1037 | static char const * |
1038 | wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, | 1038 | wsplt_env_find (struct wordsplit *wsp, const char *name, size_t len) |
1039 | char const **ret) | ||
1040 | { | 1039 | { |
@@ -1042,5 +1041,4 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, | |||
1042 | 1041 | ||
1043 | if (!(wsp->ws_flags & WRDSF_ENV)) | 1042 | if (!wsp->ws_env) |
1044 | return WRDSE_UNDEF; | 1043 | return NULL; |
1045 | |||
1046 | if (wsp->ws_flags & WRDSF_ENV_KV) | 1044 | if (wsp->ws_flags & WRDSF_ENV_KV) |
@@ -1052,6 +1050,3 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, | |||
1052 | if (elen == len && memcmp (wsp->ws_env[i], name, elen) == 0) | 1050 | if (elen == len && memcmp (wsp->ws_env[i], name, elen) == 0) |
1053 | { | 1051 | return wsp->ws_env[i + 1]; |
1054 | *ret = wsp->ws_env[i + 1]; | ||
1055 | return WRDSE_OK; | ||
1056 | } | ||
1057 | /* Skip the value. Break the loop if it is NULL. */ | 1052 | /* Skip the value. Break the loop if it is NULL. */ |
@@ -1062,3 +1057,3 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, | |||
1062 | } | 1057 | } |
1063 | else if (wsp->ws_env) | 1058 | else |
1064 | { | 1059 | { |
@@ -1074,6 +1069,22 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, | |||
1074 | if (j == len && var[j] == '=') | 1069 | if (j == len && var[j] == '=') |
1075 | { | 1070 | return var + j + 1; |
1076 | *ret = var + j + 1; | 1071 | } |
1077 | return WRDSE_OK; | 1072 | } |
1078 | } | 1073 | return NULL; |
1074 | } | ||
1075 | |||
1076 | static int | ||
1077 | wsplt_env_lookup (struct wordsplit *wsp, const char *name, size_t len, | ||
1078 | char **ret) | ||
1079 | { | ||
1080 | if (wsp->ws_flags & WRDSF_ENV) | ||
1081 | { | ||
1082 | char const *val = wsplt_env_find (wsp, name, len); | ||
1083 | if (val) | ||
1084 | { | ||
1085 | char *retval = strdup (val); | ||
1086 | if (!retval) | ||
1087 | return WRDSE_NOSPACE; | ||
1088 | *ret = retval; | ||
1089 | return WRDSE_OK; | ||
1079 | } | 1090 | } |
@@ -1084,2 +1095,9 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, | |||
1084 | static int | 1095 | static int |
1096 | wsplt_env_getvar (struct wordsplit *wsp, const char *name, size_t len, | ||
1097 | char **ret) | ||
1098 | { | ||
1099 | return wsp->ws_getvar (ret, name, len, wsp->ws_closure); | ||
1100 | } | ||
1101 | |||
1102 | static int | ||
1085 | wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen, | 1103 | wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen, |
@@ -1358,3 +1376,2 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, | |||
1358 | char *value; | 1376 | char *value; |
1359 | const char *vptr; | ||
1360 | struct wordsplit_node *newnode; | 1377 | struct wordsplit_node *newnode; |
@@ -1499,18 +1516,19 @@ expvar (struct wordsplit *wsp, const char *str, size_t len, | |||
1499 | { | 1516 | { |
1500 | rc = wordsplit_find_env (wsp, str, i, &vptr); | 1517 | if (wsp->ws_flags & WRDSF_GETVAR) |
1501 | if (rc == WRDSE_OK) | ||
1502 | { | 1518 | { |
1503 | if (vptr) | 1519 | if (wsp->ws_options & WRDSO_GETVARPREF) |
1504 | { | 1520 | { |
1505 | value = strdup (vptr); | 1521 | rc = wsplt_env_getvar (wsp, str, i, &value); |
1506 | if (!value) | 1522 | if (rc == WRDSE_UNDEF) |
1507 | rc = WRDSE_NOSPACE; | 1523 | rc = wsplt_env_lookup (wsp, str, i, &value); |
1508 | } | 1524 | } |
1509 | else | 1525 | else |
1510 | rc = WRDSE_UNDEF; | 1526 | { |
1527 | rc = wsplt_env_lookup (wsp, str, i, &value); | ||
1528 | if (rc == WRDSE_UNDEF) | ||
1529 | rc = wsplt_env_getvar (wsp, str, i, &value); | ||
1530 | } | ||
1511 | } | 1531 | } |
1512 | else if (wsp->ws_flags & WRDSF_GETVAR) | ||
1513 | rc = wsp->ws_getvar (&value, str, i, wsp->ws_closure); | ||
1514 | else | 1532 | else |
1515 | rc = WRDSE_UNDEF; | 1533 | rc = wsplt_env_lookup (wsp, str, i, &value); |
1516 | } | 1534 | } |