diff options
Diffstat (limited to 'Src/lex.c')
-rw-r--r-- | Src/lex.c | 49 |
1 files changed, 38 insertions, 11 deletions
@@ -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) |