heredoc starting to work; goto do multiple heredoc and execution part

This commit is contained in:
Jack Halford 2017-02-14 20:32:34 +01:00
parent 75c11ff4a6
commit c764027070
12 changed files with 104 additions and 26 deletions

View file

@ -138,6 +138,7 @@ job-control/sigttin_handler.c\
job-control/sigttou_handler.c\ job-control/sigttou_handler.c\
lexer/command_getoutput.c\ lexer/command_getoutput.c\
lexer/expand_bquotes.c\ lexer/expand_bquotes.c\
lexer/get_lexer_stack.c\
lexer/get_state_global.c\ lexer/get_state_global.c\
lexer/get_state_redir.c\ lexer/get_state_redir.c\
lexer/lexer_backslash.c\ lexer/lexer_backslash.c\
@ -149,6 +150,7 @@ lexer/lexer_dquote.c\
lexer/lexer_end.c\ lexer/lexer_end.c\
lexer/lexer_great.c\ lexer/lexer_great.c\
lexer/lexer_greatand.c\ lexer/lexer_greatand.c\
lexer/lexer_init.c\
lexer/lexer_less.c\ lexer/lexer_less.c\
lexer/lexer_lessand.c\ lexer/lexer_lessand.c\
lexer/lexer_lex.c\ lexer/lexer_lex.c\
@ -165,6 +167,7 @@ lexer/token_cmp_type.c\
lexer/token_free.c\ lexer/token_free.c\
lexer/token_init.c\ lexer/token_init.c\
lexer/token_print.c\ lexer/token_print.c\
lexer_dless.c\
line-editing/builtin_history.c\ line-editing/builtin_history.c\
line-editing/completion.c\ line-editing/completion.c\
line-editing/control_c_and_d.c\ line-editing/control_c_and_d.c\

View file

@ -45,10 +45,11 @@ enum e_lexstate
SEP, SEP,
WORD, WORD,
NUMBER, NUMBER,
GREAT,
LESS, LESS,
GREATAND, GREAT,
LESSAND, LESSAND,
GREATAND,
DLESS,
QUOTE, QUOTE,
DQUOTE, DQUOTE,
BQUOTE, BQUOTE,
@ -74,6 +75,7 @@ struct s_lexer
int pos; int pos;
t_lexstate state; t_lexstate state;
t_list *stack; t_list *stack;
t_list *heredoc_stack;
}; };
@ -101,6 +103,8 @@ char *stack_to_prompt(t_list *stack);
t_lexstate get_state_global(t_lexer *lexer); t_lexstate get_state_global(t_lexer *lexer);
t_lexstate get_state_redir(t_lexer *lexer); t_lexstate get_state_redir(t_lexer *lexer);
int get_lexer_stack(t_lexer lexer);
void lexer_init(t_lexer *lexer);
int lexer_lex(t_list **alst, t_lexer *lexer); int lexer_lex(t_list **alst, t_lexer *lexer);
int lexer_default(t_list **alst, t_lexer *lexer); int lexer_default(t_list **alst, t_lexer *lexer);
int lexer_newline(t_list **alst, t_lexer *lexer); int lexer_newline(t_list **alst, t_lexer *lexer);
@ -110,8 +114,9 @@ int lexer_word(t_list **alst, t_lexer *lexer);
int lexer_number(t_list **alst, t_lexer *lexer); int lexer_number(t_list **alst, t_lexer *lexer);
int lexer_less(t_list **alst, t_lexer *lexer); int lexer_less(t_list **alst, t_lexer *lexer);
int lexer_great(t_list **alst, t_lexer *lexer); int lexer_great(t_list **alst, t_lexer *lexer);
int lexer_lessand(t_list **alst, t_lexer *lexer);
int lexer_greatand(t_list **alst, t_lexer *lexer); int lexer_greatand(t_list **alst, t_lexer *lexer);
int lexer_lessand(t_list **alst, t_lexer *lexer);
int lexer_dless(t_list **alst, t_lexer *lexer);
int lexer_quote(t_list **alst, t_lexer *lexer); int lexer_quote(t_list **alst, t_lexer *lexer);
int lexer_dquote(t_list **alst, t_lexer *lexer); int lexer_dquote(t_list **alst, t_lexer *lexer);
int lexer_bquote(t_list **alst, t_lexer *lexer); int lexer_bquote(t_list **alst, t_lexer *lexer);

View file

@ -30,14 +30,13 @@ int process_redirect(t_process *p)
int i; int i;
redirs = p->redirs; redirs = p->redirs;
DG("process redirect");
while (redirs) while (redirs)
{ {
redir = redirs->content; redir = redirs->content;
DG("process redirect 2, type=[%i]", redir->type);
if (redir->n > 9) if (redir->n > 9)
{ return (bad_fd(redir->n));
bad_fd(redir->n);
exit(1);
}
i = 0; i = 0;
while (g_redirmap[i].type) while (g_redirmap[i].type)
{ {

View file

@ -17,6 +17,7 @@ int redirect_greatand(t_redir *redir)
int fdold; int fdold;
int fdnew; int fdnew;
DG("redir greatand");
if (redir->close) if (redir->close)
{ {
close(redir->n); close(redir->n);

View file

@ -0,0 +1,6 @@
#include "lexer.h"
int get_lexer_stack(t_lexer lexer)
{
return (lexer.stack ? *(int*)lexer.stack->content : 0);
}

View file

@ -5,14 +5,23 @@ int lexer_end(t_list **alst, t_lexer *lexer)
t_token *token; t_token *token;
DG("check"); DG("check");
if (*alst && (lexer->state == QUOTE if ((*alst && (lexer->state == QUOTE
|| lexer->state == DQUOTE || lexer->state == DQUOTE
|| lexer->state == BQUOTE)) || lexer->state == BQUOTE))
|| get_lexer_stack(*lexer) == DLESS)
{ {
token = (*alst)->content;
ft_strappend(&lexer->str, (char[]){'\n', 0}); ft_strappend(&lexer->str, (char[]){'\n', 0});
token_append(token, lexer, 1, 0);
lexer->pos++; lexer->pos++;
if (get_lexer_stack(*lexer) == DLESS)
{
token = (*(t_list**)lexer->heredoc_stack->content)->content;
token_append_char(token, '\n', 0, 0);
}
else
{
token = (*alst)->content;
token_append_char(token, '\n', 1, 0);
}
return (0); return (0);
} }
return (0); return (0);

View file

@ -0,0 +1,10 @@
#include "lexer.h"
void lexer_init(t_lexer *lexer)
{
lexer->str = NULL;
lexer->pos = 0;
lexer->state = DEFAULT;
lexer->stack = NULL;
lexer->heredoc_stack = NULL;
}

View file

@ -28,11 +28,13 @@ int lexer_less(t_list **alst, t_lexer *lexer)
} }
if (lexer->str[lexer->pos + 1] == '<') if (lexer->str[lexer->pos + 1] == '<')
{ {
token_free(token, 0);
(*alst)->content = token_init();
token->type = TK_DLESS; token->type = TK_DLESS;
lexer->pos++; lexer->pos += 2;
token_append(token, lexer, 0, 0); push(&lexer->stack, DLESS);
lexer->pos++;
lexer->state = DEFAULT; lexer->state = DEFAULT;
ft_lsteadd(&lexer->heredoc_stack, ft_lstnew(alst, sizeof(alst)));
return (lexer_lex(&(*alst)->next, lexer)); return (lexer_lex(&(*alst)->next, lexer));
} }
else else

View file

@ -20,10 +20,11 @@ int (*g_lexer[])(t_list **alst, t_lexer *lexer) =
&lexer_sep, &lexer_sep,
&lexer_word, &lexer_word,
&lexer_number, &lexer_number,
&lexer_great,
&lexer_less, &lexer_less,
&lexer_greatand, &lexer_great,
&lexer_lessand, &lexer_lessand,
&lexer_greatand,
&lexer_dless,
&lexer_quote, &lexer_quote,
&lexer_dquote, &lexer_dquote,
&lexer_bquote, &lexer_bquote,
@ -43,6 +44,7 @@ int lexer_lex(t_list **alst, t_lexer *lexer)
{ {
t_token *token; t_token *token;
DG("check 01, state=[%i]", lexer->state);
if (lexer->str[lexer->pos] == 0) if (lexer->str[lexer->pos] == 0)
return (lexer_end(alst, lexer)); return (lexer_end(alst, lexer));
if (!*alst) if (!*alst)

View file

@ -31,6 +31,8 @@ char *stack_to_prompt(t_list *stack)
return ("dquote bquote> "); return ("dquote bquote> ");
else if (top == PAREN) else if (top == PAREN)
return ("subsh> "); return ("subsh> ");
else if (top == DLESS)
return ("heredoc> ");
else else
return ("error> "); return ("error> ");
} }

36
42sh/src/lexer_dless.c Normal file
View file

@ -0,0 +1,36 @@
#include "lexer.h"
int lexer_dless(t_list **alst, t_lexer *lexer)
{
t_list *heredoc_lst;
t_token *eof_tok;
t_token *heredoc_tok;
(void)alst;
(void)lexer;
heredoc_lst = *(t_list**)lexer->heredoc_stack->content;
heredoc_tok = heredoc_lst->content;
if (!(heredoc_lst->next))
{
ft_dprintf(2, "{red}%s: parse error near `\\n'{eoc}\n", SHELL_NAME);
return (1);
}
eof_tok = heredoc_lst->next->content;
if (!(eof_tok->type == TK_WORD))
{
ft_dprintf(2, "{red}%s: expected word token after <<{eoc}\n", SHELL_NAME);
return (1);
}
DG("heredoc contains [%s]", heredoc_tok->data);
DG("heredoc ends at [%s]", eof_tok->data);
DG("input is [%s]", lexer->str + lexer->pos);
if (ft_strcmp(eof_tok->data, lexer->str + lexer->pos) == 0)
{
pop(&lexer->stack);
pop(&lexer->heredoc_stack);
return (0);
}
while (lexer->str[lexer->pos])
token_append_char(heredoc_tok, lexer->str[lexer->pos++], 0, 0);
return (lexer_end(alst, lexer));
}

View file

@ -18,10 +18,8 @@ int non_interactive_shell(char *command)
t_lexer lexer; t_lexer lexer;
t_btree *ast; t_btree *ast;
lexer.pos = 0; lexer_init(&lexer);
lexer.state = DEFAULT;
lexer.str = command; lexer.str = command;
lexer.stack = NULL;
token = NULL; token = NULL;
ast = NULL; ast = NULL;
while (lexer.str[lexer.pos]) while (lexer.str[lexer.pos])
@ -43,6 +41,7 @@ int non_interactive_shell(char *command)
} }
return (0); return (0);
} }
int interactive_shell() int interactive_shell()
{ {
t_list *token; t_list *token;
@ -50,21 +49,25 @@ int interactive_shell()
t_lexer lexer; t_lexer lexer;
t_btree *ast; t_btree *ast;
lexer.pos = 0; lexer_init(&lexer);
lexer.state = DEFAULT;
lexer.str = NULL;
token = NULL; token = NULL;
lexer.stack = NULL;
ast = NULL; ast = NULL;
do { do {
ft_strappend(&lexer.str, readline(stack_to_prompt(lexer.stack))); ft_strappend(&lexer.str, readline(stack_to_prompt(lexer.stack)));
if (lexer.stack && *(int*)lexer.stack->content == BACKSLASH) DG("check 0");
if (get_lexer_stack(lexer) == BACKSLASH)
pop(&lexer.stack); pop(&lexer.stack);
else if (get_lexer_stack(lexer) == DLESS)
lexer.state = DLESS;
DG("check 1");
ltoken = ft_lstlast(token); ltoken = ft_lstlast(token);
lexer_lex((token ? &ltoken : &token), &lexer); if (lexer_lex((token ? &ltoken : &token), &lexer))
return (1);
DG("check 2");
DG("[{mag}%s{eoc}] stack=[%i] state=[%i]", lexer.str, lexer.stack ? *(int*)lexer.stack->content : 0, lexer.state); DG("[{mag}%s{eoc}] stack=[%i] state=[%i]", lexer.str, lexer.stack ? *(int*)lexer.stack->content : 0, lexer.state);
DG("check 3");
token_print(token); token_print(token);
} while (lexer.stack); } while (get_lexer_stack(lexer));
if (bquotes_expand(&token)) if (bquotes_expand(&token))
return (1); return (1);
if (!token) if (!token)
@ -85,7 +88,7 @@ int main(int ac, char **av)
data = data_singleton(); data = data_singleton();
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
shell_init(ac, av); shell_init(ac, av);
DG("{inv}{bol}{gre}start of shell{eoc} pid=%i pgrp=%i job_control is %s", getpid(), getpgrp(), SH_HAS_JOBC(data->opts) ? "ON" : "OFF"); DG("{inv}{bol}{gre}start of shell{eoc} JOBC is %s", SH_HAS_JOBC(data->opts)?"ON":"OFF");
if (SH_IS_INTERACTIVE(data->opts)) if (SH_IS_INTERACTIVE(data->opts))
{ {
while (1) while (1)