Skip to content

Commit c40851a

Browse files
committed
ksh -n: remove linter warning for | & ; < > inside ${...}
On Usenet in comp.unix.shell, Janis Papanagnou <[email protected]> reported: > With syntax-check ('ksh -n') I get a warning in Ksh for this > expression > > "${pipe#* | }" > > concerning the pipe symbol. (Bash and Zsh don't complain.) > > (2709)$ ksh -n -c '"${pipe#* | }"' > ksh: warning: line 1: | within ${} should be quoted > (2710)$ ksh -n -c '"${pipe#* [|] }"' > ksh: warning: line 1: | within ${} should be quoted > (2711)$ ksh -n -c '"${pipe#* \| }"' This is very strange. Neither POSIX nor any existing shell requires '|' to be quoted in that context. ksh also works fine without quoting it. In lexstates.h, we find a clue to the reason: #define S_META 35 /* | & ; < > inside ${...} reserved for future use */ Those AT&T plans for future use (whatever they might have been) never materialised, and I have no such plans -- particularly as requiring quoting there to avoid hypothetical new features would be a backward incompatibility with POSIX and with historic ksh usage. A look at ast-open-archive shows that these had been 'reserved for future use' since the earliest version of that repo, so since 1995-08-28 or before. Yet another thing AT&T simply forgot about. src/cmd/ksh93/sh/lex.c, src/cmd/ksh93/data/lexstates.c, src/cmd/ksh93/include/lexstates.h: - sh_lex(): Remove the warning in question, e_lexusequote (separately for ';' and the other four). - Remove e_lexusequote message with the text for that warning. - Remove S_META state, which was only used in the ST_NESTED state table for this warning. - Remove nested_tilde flag from the lexd struct, which was used to avoid the warning within ~(...) (pattern options) within ${...}. Further discussion: https://comp.unix.shell.narkive.com/H5Rfs3q8/ksh-warning-pipe-symbol-within-should-be-quoted
1 parent 68fe82b commit c40851a

File tree

5 files changed

+6
-33
lines changed

5 files changed

+6
-33
lines changed

src/cmd/ksh93/data/lexstates.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ static const char sh_lexstate5[256] =
353353
0, 0, 0, 0, 0, 0, 0, 0,
354354

355355
/* space ! " # $ % & ' */
356-
S_BLNK, 0, S_QUOTE,0, S_DOL, 0, S_META, S_LIT,
356+
S_BLNK, 0, S_QUOTE,0, S_DOL, 0, 0, S_LIT,
357357

358358
/* ( ) * + , - . / */
359359
S_PUSH, S_POP, 0, 0, 0, 0, 0, 0,
@@ -362,7 +362,7 @@ static const char sh_lexstate5[256] =
362362
0, 0, 0, 0, 0, 0, 0, 0,
363363

364364
/* 8 9 : ; < = > ? */
365-
0, 0, 0, S_POP, S_META, 0, S_META, 0,
365+
0, 0, 0, S_POP, 0, 0, 0, 0,
366366

367367
/* @ A B C D E F G */
368368
0, 0, 0, 0, 0, 0, 0, 0,
@@ -386,7 +386,7 @@ static const char sh_lexstate5[256] =
386386
0, 0, 0, 0, 0, 0, 0, 0,
387387

388388
/* x y z { | } ~ del */
389-
0, 0, 0, S_BRACE,S_META, S_POP, S_TILDE,0
389+
0, 0, 0, S_BRACE,0, S_POP, S_TILDE,0
390390
};
391391

392392
/*
@@ -752,7 +752,6 @@ const char e_lexobsolete4[] = "line %d: [[ ... %s ... ]] obsolete, use ((... %s
752752
const char e_lexobsolete5[] = "line %d: set %s obsolete";
753753
const char e_lexobsolete6[] = "line %d: `{' instead of `in' is obsolete";
754754
const char e_lexusebrace[] = "line %d: use braces to avoid ambiguities with $id[...]";
755-
const char e_lexusequote[] = "line %d: %c within ${} should be quoted";
756755
const char e_lexescape[] = "line %d: escape %c to avoid ambiguities";
757756
const char e_lexquote[] = "line %d: quote %c to avoid ambiguities";
758757
const char e_lexnested[] = "line %d: spaces required for nested subshell";

src/cmd/ksh93/include/lexstates.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
#define S_EDOL 32 /* ends $identifier */
5050
#define S_BRACE 33 /* left brace */
5151
#define S_DOT 34 /* . char */
52-
#define S_META 35 /* | & ; < > inside ${...} reserved for future use */
5352
#define S_SPACE S_BREAK /* IFS space characters */
5453
#define S_DELIM S_RES /* IFS delimiter characters */
5554
#define S_MBYTE S_NAME /* IFS first byte of multi-byte char */
@@ -149,7 +148,6 @@ extern const char e_lexobsolete4[];
149148
extern const char e_lexobsolete5[];
150149
extern const char e_lexobsolete6[];
151150
extern const char e_lexusebrace[];
152-
extern const char e_lexusequote[];
153151
extern const char e_lexescape[];
154152
extern const char e_lexquote[];
155153
extern const char e_lexnested[];

src/cmd/ksh93/include/shlex.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ struct _shlex_pvt_lexdata_
5050
char dolparen_arithexp; /* set while comsub() is lexing an arithmetic expansion */
5151
char nest;
5252
char docword;
53-
char nested_tilde;
5453
char *docend;
5554
char inlexskip; /* set when sh_lex() is called from sh_lexskip() */
5655
char warn;

src/cmd/ksh93/include/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include <ast_release.h>
1919
#include "git.h"
2020

21-
#define SH_RELEASE_DATE "2025-05-31" /* must be in this format for $((.sh.version)) */
21+
#define SH_RELEASE_DATE "2025-06-08" /* must be in this format for $((.sh.version)) */
2222
/*
2323
* This comment keeps SH_RELEASE_DATE a few lines away from SH_RELEASE_SVER to avoid
2424
* merge conflicts when cherry-picking dev branch commits onto a release branch.

src/cmd/ksh93/sh/lex.c

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -660,10 +660,7 @@ int sh_lex(Lex_t* lp)
660660
if(c=='~' && mode==ST_NESTED)
661661
{
662662
if(endchar(lp)==RBRACE)
663-
{
664-
lp->lexd.nested_tilde++;
665663
goto tilde;
666-
}
667664
continue;
668665
}
669666
/* FALLTHROUGH */
@@ -686,19 +683,9 @@ int sh_lex(Lex_t* lp)
686683
n = fcgetc();
687684
if(n>0)
688685
{
689-
if(c=='~' && n==LPAREN)
690-
{
691-
if(lp->lexd.nested_tilde)
692-
lp->lexd.nested_tilde++;
693-
else if(lp->lex.incase)
694-
lp->lex.incase = TEST_RE;
695-
}
686+
if(c=='~' && n==LPAREN && lp->lex.incase)
687+
lp->lex.incase = TEST_RE;
696688
fcseek(-LEN);
697-
if(lp->lexd.nested_tilde)
698-
{
699-
lp->lexd.nested_tilde--;
700-
continue;
701-
}
702689
}
703690
if(n==LPAREN)
704691
goto epat;
@@ -1038,10 +1025,6 @@ int sh_lex(Lex_t* lp)
10381025
fcseek(-LEN);
10391026
}
10401027
continue;
1041-
case S_META:
1042-
if(lp->lexd.warn && endchar(lp)==RBRACE && !lp->lexd.nested_tilde)
1043-
errormsg(SH_DICT,ERROR_warn(0),e_lexusequote,sh.inlineno,c);
1044-
continue;
10451028
case S_PUSH:
10461029
n = fcgetc();
10471030
if(n==RPAREN)
@@ -1080,14 +1063,8 @@ int sh_lex(Lex_t* lp)
10801063
fcseek(-LEN);
10811064
n = RPAREN;
10821065
}
1083-
if(c==RBRACE)
1084-
lp->lexd.nested_tilde = 0;
10851066
if(c==';' && n!=';')
1086-
{
1087-
if(lp->lexd.warn && n==RBRACE)
1088-
errormsg(SH_DICT,ERROR_warn(0),e_lexusequote,sh.inlineno,c);
10891067
continue;
1090-
}
10911068
if(mode==ST_QNEST)
10921069
{
10931070
if(lp->lexd.warn)

0 commit comments

Comments
 (0)