summaryrefslogtreecommitdiff
path: root/Src/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/lex.c')
-rw-r--r--Src/lex.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/Src/lex.c b/Src/lex.c
index 0f260d08f..3ea878c7b 100644
--- a/Src/lex.c
+++ b/Src/lex.c
@@ -35,7 +35,7 @@
/* tokens */
/**/
-mod_export char ztokens[] = "#$^*(())$=|{}[]`<>>?~`,'\"\\\\";
+mod_export char ztokens[] = "#$^*(())$=|{}[]`<>>?~`,-!'\"\\\\";
/* parts of the current token */
@@ -394,8 +394,10 @@ ctxtlex(void)
#define LX2_DQUOTE 15
#define LX2_BQUOTE 16
#define LX2_COMMA 17
-#define LX2_OTHER 18
-#define LX2_META 19
+#define LX2_DASH 18
+#define LX2_BANG 19
+#define LX2_OTHER 20
+#define LX2_META 21
static unsigned char lexact1[256], lexact2[256], lextok2[256];
@@ -405,10 +407,10 @@ initlextabs(void)
{
int t0;
static char *lx1 = "\\q\n;!&|(){}[]<>";
- static char *lx2 = ";)|$[]~({}><=\\\'\"`,";
+ static char *lx2 = ";)|$[]~({}><=\\\'\"`,-!";
for (t0 = 0; t0 != 256; t0++) {
- lexact1[t0] = LX1_OTHER;
+ lexact1[t0] = LX1_OTHER;
lexact2[t0] = LX2_OTHER;
lextok2[t0] = t0;
}
@@ -801,7 +803,7 @@ gettok(void)
return INOUTPAR;
hungetc(d);
lexstop = 0;
- if (!(incond == 1 || incmdpos))
+ if (!(isset(SHGLOB) || incond == 1 || incmdpos))
break;
return INPAR;
case LX1_OUTPAR:
@@ -919,7 +921,7 @@ gettok(void)
static enum lextok
gettokstr(int c, int sub)
{
- int bct = 0, pct = 0, brct = 0, fdpar = 0;
+ int bct = 0, pct = 0, brct = 0, seen_brct = 0, fdpar = 0;
int intpos = 1, in_brace_param = 0;
int inquote, unmatched = 0;
enum lextok peek;
@@ -1033,8 +1035,10 @@ gettokstr(int c, int sub)
}
break;
case LX2_INBRACK:
- if (!in_brace_param)
+ if (!in_brace_param) {
brct++;
+ seen_brct = 1;
+ }
c = Inbrack;
break;
case LX2_OUTBRACK:
@@ -1346,9 +1350,32 @@ gettokstr(int c, int sub)
c = Tick;
SETPAREND
break;
- }
- add(c);
- c = hgetc();
+ case LX2_DASH:
+ /*
+ * - shouldn't be treated as a special character unless
+ * we're in a pattern. Howeve,simply counting "[" doesn't
+ * work as []a-z] is a valid expression and we don't know
+ * down here what this "[" is for as $foo[stuff] is valid
+ * in zsh. So just detect an opening [, which is enough
+ * to turn this into a pattern; the Dash will be harmlessly
+ * untokenised if not wanted.
+ */
+ if (seen_brct)
+ c = Dash;
+ else
+ c = '-';
+ break;
+ case LX2_BANG:
+ /*
+ * Same logic as Dash, for ! to perform negation in range.
+ */
+ if (seen_brct)
+ c = Bang;
+ else
+ c = '!';
+ }
+ add(c);
+ c = hgetc();
if (intpos)
intpos--;
if (lexstop)