rc: read heredoc when receiving '\n' (thanks Eckard Brauer)
Eckard's test case: cat <<! | cat asdf ! The issue is that we have to continue parsing until we see the '\n' before consuming the here document. So we revert to the old approach of having two functions: heredoc() which remembers if we'v seen a heredoc redirection and a second readhere() function that reads the doc from the lexers input and sets Tree.str on thee REDIR node.
This commit is contained in:
parent
70edb7fbae
commit
369cba5f93
3 changed files with 35 additions and 10 deletions
|
@ -58,7 +58,8 @@ void psubst(io*, unsigned char*);
|
|||
void pushlist(void);
|
||||
void pushredir(int, int, int);
|
||||
word* pushword(char*);
|
||||
char* readhere(tree*, io*);
|
||||
void readhere(io*);
|
||||
void heredoc(tree*);
|
||||
void setstatus(char*);
|
||||
void skipnl(void);
|
||||
void start(code*, int, var*, redir*);
|
||||
|
|
|
@ -6,16 +6,12 @@
|
|||
void psubst(io*, unsigned char*);
|
||||
void pstrs(io*, word*);
|
||||
|
||||
char*
|
||||
readhere(tree *tag, io *in)
|
||||
static char*
|
||||
readhere1(tree *tag, io *in)
|
||||
{
|
||||
io *out;
|
||||
char c, *m;
|
||||
|
||||
if(tag->type!=WORD){
|
||||
yyerror("Bad here tag");
|
||||
return 0;
|
||||
}
|
||||
pprompt();
|
||||
out = openiostr();
|
||||
m = tag->str;
|
||||
|
@ -47,6 +43,34 @@ readhere(tree *tag, io *in)
|
|||
return closeiostr(out);
|
||||
}
|
||||
|
||||
static tree *head, *tail;
|
||||
|
||||
void
|
||||
heredoc(tree *redir)
|
||||
{
|
||||
if(redir->child[0]->type!=WORD){
|
||||
yyerror("Bad here tag");
|
||||
return;
|
||||
}
|
||||
redir->child[2]=0;
|
||||
if(head)
|
||||
tail->child[2]=redir;
|
||||
else
|
||||
head=redir;
|
||||
tail=redir;
|
||||
}
|
||||
|
||||
void
|
||||
readhere(io *in)
|
||||
{
|
||||
while(head){
|
||||
tail=head->child[2];
|
||||
head->child[2]=0;
|
||||
head->str=readhere1(head->child[0], in);
|
||||
head=tail;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
psubst(io *f, unsigned char *s)
|
||||
{
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
%type<tree> WORD REDIR DUP PIPE
|
||||
%%
|
||||
rc: { return 1;}
|
||||
| line '\n' {return !compile($1);}
|
||||
| line '\n' {readhere(lex->input); return !compile($1);}
|
||||
line: cmd
|
||||
| cmdsa line {$$=tree2(';', $1, $2);}
|
||||
body: cmd
|
||||
|
@ -30,13 +30,13 @@ body: cmd
|
|||
cmdsa: cmd ';'
|
||||
| cmd '&' {$$=tree1('&', $1);}
|
||||
cmdsan: cmdsa
|
||||
| cmd '\n'
|
||||
| cmd '\n' {readhere(lex->input);}
|
||||
brace: '{' body '}' {$$=tree1(BRACE, $2);}
|
||||
paren: '(' body ')' {$$=tree1(PCMD, $2);}
|
||||
assign: first '=' word {$$=tree2('=', $1, $3);}
|
||||
epilog: {$$=0;}
|
||||
| redir epilog {$$=mung2($1, $1->child[0], $2);}
|
||||
redir: REDIR word {($$=mung1($1, $2))->str=$1->rtype==HERE?readhere($2,lex->input):0;}
|
||||
redir: REDIR word {$$=mung1($1, $2); if($$->rtype==HERE) heredoc($$);}
|
||||
| DUP
|
||||
cmd: {$$=0;}
|
||||
| brace epilog {$$=epimung($1, $2);}
|
||||
|
|
Loading…
Reference in a new issue