diff options
-rw-r--r-- | include/wordsplit.h | 3 | ||||
-rw-r--r-- | src/wordsplit.c | 70 |
2 files changed, 46 insertions, 27 deletions
diff --git a/include/wordsplit.h b/include/wordsplit.h index 0d6eef3..3451979 100644 --- a/include/wordsplit.h +++ b/include/wordsplit.h | |||
@@ -216,7 +216,8 @@ struct wordsplit | |||
216 | #define WRDSO_FAILGLOB 0x00000002 | 216 | #define WRDSO_FAILGLOB 0x00000002 |
217 | /* Allow a leading period to be matched by metacharacters. */ | 217 | /* Allow a leading period to be matched by metacharacters. */ |
218 | #define WRDSO_DOTGLOB 0x00000004 | 218 | #define WRDSO_DOTGLOB 0x00000004 |
219 | /* Unused value: 0x00000008 */ | 219 | /* Prefer ws_getvar over lookup in ws_env, if both are supplied */ |
220 | #define WRDSO_GETVARPREF 0x00000008 | ||
220 | /* Keep backslash in unrecognized escape sequences in words */ | 221 | /* Keep backslash in unrecognized escape sequences in words */ |
221 | #define WRDSO_BSKEEP_WORD 0x00000010 | 222 | #define WRDSO_BSKEEP_WORD 0x00000010 |
222 | /* Handle octal escapes in words */ | 223 | /* Handle octal escapes in words */ |
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 | ||
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 | { |
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 | |||
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 | } |
1080 | } | 1091 | } |
1081 | return WRDSE_UNDEF; | 1092 | return WRDSE_UNDEF; |
1082 | } | 1093 | } |
1083 | 1094 | ||
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, |
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 |