aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Bennett <steveb@workware.net.au>2020-05-07 09:21:23 +1000
committerSteve Bennett <steveb@workware.net.au>2020-05-07 09:23:37 +1000
commita6c24e9c1a78da2ae9a5d5e6a110f26da40ac143 (patch)
tree87f009623110e373dceb5fc082e62147ffcf2aa1
parent659f043196f313c69e32876e3641d0865a1e49cd (diff)
downloadjimtcl-a6c24e9c1a78da2ae9a5d5e6a110f26da40ac143.zip
jimtcl-a6c24e9c1a78da2ae9a5d5e6a110f26da40ac143.tar.gz
jimtcl-a6c24e9c1a78da2ae9a5d5e6a110f26da40ac143.tar.bz2
lsearch, switch: fix -regexp case with option-like pattern
If the pattern begins with -, the internal invocation of regexp will treat the pattern as an option. Fix this by adding -- to the internal invocation of regexp. Fixes #154 Reported-by: Barry Arthur <barry.arthur@gmail.com> Signed-off-by: Steve Bennett <steveb@workware.net.au>
-rw-r--r--jim.c35
-rw-r--r--jim.h1
-rw-r--r--tests/jim.test9
-rw-r--r--tests/lsearch.test8
4 files changed, 41 insertions, 12 deletions
diff --git a/jim.c b/jim.c
index bbdb6fe..08c448b 100644
--- a/jim.c
+++ b/jim.c
@@ -12028,19 +12028,24 @@ static int Jim_IfCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
}
-/* Returns 1 if match, 0 if no match or -<error> on error (e.g. -JIM_ERR, -JIM_BREAK)*/
+/* Returns 1 if match, 0 if no match or -<error> on error (e.g. -JIM_ERR, -JIM_BREAK)
+ * flags may contain JIM_NOCASE and/or JIM_OPT_END
+ */
int Jim_CommandMatchObj(Jim_Interp *interp, Jim_Obj *commandObj, Jim_Obj *patternObj,
- Jim_Obj *stringObj, int nocase)
+ Jim_Obj *stringObj, int flags)
{
- Jim_Obj *parms[4];
+ Jim_Obj *parms[5];
int argc = 0;
long eq;
int rc;
parms[argc++] = commandObj;
- if (nocase) {
+ if (flags & JIM_NOCASE) {
parms[argc++] = Jim_NewStringObj(interp, "-nocase", -1);
}
+ if (flags & JIM_OPT_END) {
+ parms[argc++] = Jim_NewStringObj(interp, "--", -1);
+ }
parms[argc++] = patternObj;
parms[argc++] = stringObj;
@@ -12058,6 +12063,7 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
{
enum { SWITCH_EXACT, SWITCH_GLOB, SWITCH_RE, SWITCH_CMD };
int matchOpt = SWITCH_EXACT, opt = 1, patCount, i;
+ int match_flags = 0;
Jim_Obj *command = NULL, *scriptObj = NULL, *strObj;
Jim_Obj **caseList;
@@ -12080,8 +12086,10 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
matchOpt = SWITCH_EXACT;
else if (strncmp(option, "-glob", 2) == 0)
matchOpt = SWITCH_GLOB;
- else if (strncmp(option, "-regexp", 2) == 0)
+ else if (strncmp(option, "-regexp", 2) == 0) {
matchOpt = SWITCH_RE;
+ match_flags |= JIM_OPT_END;
+ }
else if (strncmp(option, "-command", 2) == 0) {
matchOpt = SWITCH_CMD;
if ((argc - opt) < 2)
@@ -12124,7 +12132,7 @@ static int Jim_SwitchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a
command = Jim_NewStringObj(interp, "regexp", -1);
/* Fall thru intentionally */
case SWITCH_CMD:{
- int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, 0);
+ int rc = Jim_CommandMatchObj(interp, command, patObj, strObj, match_flags);
/* After the execution of a command we need to
* make sure to reconvert the object into a list
@@ -12227,7 +12235,6 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
int i;
int opt_bool = 0;
int opt_not = 0;
- int opt_nocase = 0;
int opt_all = 0;
int opt_inline = 0;
int opt_match = OPT_EXACT;
@@ -12235,6 +12242,7 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
int rc = JIM_OK;
Jim_Obj *listObjPtr = NULL;
Jim_Obj *commandObj = NULL;
+ int match_flags = 0;
if (argc < 3) {
wrongargs:
@@ -12258,7 +12266,7 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
opt_not = 1;
break;
case OPT_NOCASE:
- opt_nocase = 1;
+ match_flags |= JIM_NOCASE;
break;
case OPT_INLINE:
opt_inline = 1;
@@ -12267,6 +12275,10 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
case OPT_ALL:
opt_all = 1;
break;
+ case OPT_REGEXP:
+ opt_match = option;
+ match_flags |= JIM_OPT_END;
+ break;
case OPT_COMMAND:
if (i >= argc - 2) {
goto wrongargs;
@@ -12275,7 +12287,6 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
/* fallthru */
case OPT_EXACT:
case OPT_GLOB:
- case OPT_REGEXP:
opt_match = option;
break;
}
@@ -12300,16 +12311,16 @@ static int Jim_LsearchCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *
switch (opt_match) {
case OPT_EXACT:
- eq = Jim_StringCompareObj(interp, argv[1], objPtr, opt_nocase) == 0;
+ eq = Jim_StringCompareObj(interp, argv[1], objPtr, match_flags) == 0;
break;
case OPT_GLOB:
- eq = Jim_StringMatchObj(interp, argv[1], objPtr, opt_nocase);
+ eq = Jim_StringMatchObj(interp, argv[1], objPtr, match_flags);
break;
case OPT_REGEXP:
case OPT_COMMAND:
- eq = Jim_CommandMatchObj(interp, commandObj, argv[1], objPtr, opt_nocase);
+ eq = Jim_CommandMatchObj(interp, commandObj, argv[1], objPtr, match_flags);
if (eq < 0) {
if (listObjPtr) {
Jim_FreeNewObj(interp, listObjPtr);
diff --git a/jim.h b/jim.h
index f156980..807ad9b 100644
--- a/jim.h
+++ b/jim.h
@@ -161,6 +161,7 @@ extern "C" {
/* Flags used by API calls getting a 'nocase' argument. */
#define JIM_CASESENS 0 /* case sensitive */
#define JIM_NOCASE 1 /* no case */
+#define JIM_OPT_END 2 /* if implemented by a command (e.g. regexp), add -- to the argument list */
/* Filesystem related */
#define JIM_PATH_LEN 1024
diff --git a/tests/jim.test b/tests/jim.test
index 121e909..eaef8aa 100644
--- a/tests/jim.test
+++ b/tests/jim.test
@@ -2500,6 +2500,15 @@ test switch-3.7 {-exact vs. -glob vs. -regexp} {
list [catch {switch -foo a b c} msg] $msg
} {1 {bad option "-foo": must be -exact, -glob, -regexp, -command procname or --}}
+test switch-3.8 {switch -regexp with option-like pattern} regexp {
+ switch -regexp -- -def {
+ -abc {concat first}
+ -def {concat second}
+ -ghi {concat third}
+ default {concat none}
+ }
+} second
+
test switch-4.1 {error in executed command} {
list [catch {switch a a {error "Just a test"} default {expr 1}} msg] \
$msg
diff --git a/tests/lsearch.test b/tests/lsearch.test
index 1eb6607..ff1342a 100644
--- a/tests/lsearch.test
+++ b/tests/lsearch.test
@@ -72,6 +72,14 @@ test lsearch-2.9 {search modes, -nocase} {
lsearch -nocase -glob {b.x ^bc xy bcx} B*
} 0
+test lsearch-2.10 {regexp with option-looking pattern} regexp {
+ lsearch -regexp {-abc -def -ghi} -def
+} 1
+
+test lsearch-2.11 {regexp with option-looking pattern, -nocase} regexp {
+ lsearch -nocase -regexp {-abc -def -ghi} -DEF
+} 1
+
test lsearch-3.1 {lsearch errors} {
list [catch lsearch msg]
} {1}