summaryrefslogtreecommitdiffabout
path: root/src
authorSergey Poznyakoff <gray@gnu.org>2019-06-13 11:20:20 (GMT)
committer Sergey Poznyakoff <gray@gnu.org>2019-06-13 11:20:20 (GMT)
commit12304127b52650588877f00b0c4b32dae083e852 (patch) (unidiff)
treee6a2fa21b66d16a82a7913933b88bd091f633dc6 /src
parentdbe318987cf3a36fe63893205d3df0dc3be7fa4a (diff)
downloadgrecs-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') (more/less context) (ignore whitespace changes)
-rw-r--r--src/wordsplit.c70
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
@@ -1034,15 +1034,13 @@ find_closing_paren (const char *str, size_t i, size_t len, size_t *poff,
1034 return 1; 1034 return 1;
1035} 1035}
1036 1036
1037static int 1037static char const *
1038wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len, 1038wsplt_env_find (struct wordsplit *wsp, const char *name, size_t len)
1039 char const **ret)
1040{ 1039{
1041 size_t i; 1040 size_t i;
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)
1047 { 1045 {
1048 /* A key-value pair environment */ 1046 /* A key-value pair environment */
@@ -1050,17 +1048,14 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len,
1050 { 1048 {
1051 size_t elen = strlen (wsp->ws_env[i]); 1049 size_t elen = strlen (wsp->ws_env[i]);
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. */
1058 i++; 1053 i++;
1059 if (wsp->ws_env[i] == NULL) 1054 if (wsp->ws_env[i] == NULL)
1060 break; 1055 break;
1061 } 1056 }
1062 } 1057 }
1063 else if (wsp->ws_env) 1058 else
1064 { 1059 {
1065 /* Usual (A=B) environment. */ 1060 /* Usual (A=B) environment. */
1066 for (i = 0; wsp->ws_env[i]; i++) 1061 for (i = 0; wsp->ws_env[i]; i++)
@@ -1072,16 +1067,39 @@ wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len,
1072 if (name[j] != var[j]) 1067 if (name[j] != var[j])
1073 break; 1068 break;
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
1076static int
1077wsplt_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 }
1080 } 1091 }
1081 return WRDSE_UNDEF; 1092 return WRDSE_UNDEF;
1082} 1093}
1083 1094
1084static int 1095static int
1096wsplt_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
1102static int
1085wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen, 1103wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
1086 char const *value) 1104 char const *value)
1087{ 1105{
@@ -1356,7 +1374,6 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
1356 size_t i = 0; 1374 size_t i = 0;
1357 const char *defstr = NULL; 1375 const char *defstr = NULL;
1358 char *value; 1376 char *value;
1359 const char *vptr;
1360 struct wordsplit_node *newnode; 1377 struct wordsplit_node *newnode;
1361 const char *start = str - 1; 1378 const char *start = str - 1;
1362 int rc; 1379 int rc;
@@ -1497,22 +1514,23 @@ expvar (struct wordsplit *wsp, const char *str, size_t len,
1497 } 1514 }
1498 else 1515 else
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 }
1517 1535
1518 if (rc == WRDSE_OK 1536 if (rc == WRDSE_OK

Return to:

Send suggestions and report system problems to the System administrator.