Hello,

As an exercise I tried writing a csh script and I found strange
behaviour in its parsing of switch statements.
The following snippet causes a syntax error (switch: Missing ].):

 set c="["
 switch ("$c")
 case "[":
  echo match
  breaksw
 endsw

The call tree is main() -> process() -> execute() -> execute() ->
 func() -> doswitch() -> search() -> Gmatch() -> pmatch().

Gmatch() is performing a glob match and pmatch() is looking for
matching []s in a glob. In csh a switch case can be a glob
pattern, but the "case" argument is treated as a glob even if
it is quoted. This is at least inconsistent with other glob
usages in csh, where quoted strings are *not* treated as globs.

works as a glob:
 ls [ab]*.c
does not work as a glob:
 ls "[ab]*.c"

The patch below removes a call to strip(), which was causing
the string (Char *) returned by Dfix1() to lose its QUOTE flag.
When Gmatch()/pmatch() sees the QUOTE flag it knows to not treat
the case argument as a glob.

Thanks to Prashant Satish for helping to debug this.

OK?

- Michael


Index: func.c
===================================================================
RCS file: /cvs/src/bin/csh/func.c,v
retrieving revision 1.38
diff -u -p -u -r1.38 func.c
--- func.c      8 Sep 2018 01:28:39 -0000       1.38
+++ func.c      23 Sep 2018 14:51:25 -0000
@@ -657,7 +657,7 @@ search(int type, int level, Char *goal)
            (void) getword(aword);
            if (lastchr(aword) == ':')
                aword[Strlen(aword) - 1] = 0;
-           cp = strip(Dfix1(aword));
+           cp = Dfix1(aword);
            if (Gmatch(goal, cp))
                level = -1;
            free(cp);

Reply via email to