diff --git a/42sh/includes/lexer.h b/42sh/includes/lexer.h index 3e9f37fd..687203de 100644 --- a/42sh/includes/lexer.h +++ b/42sh/includes/lexer.h @@ -84,12 +84,16 @@ int ft_post_tokenize(t_list **alst, char **str); t_token *token_init(); int token_append(t_token *token, t_lexer *lexer, short int esc, short int esc2); +int token_append_char(t_token *token, char c, + short int esc, short int esc2); +int token_append_str(t_token *token, char *str, + short int esc, short int esc2); void token_free(void *data, size_t size); int token_cmp_type(t_token *token, t_type *ref); void token_print(t_list *lst); int reduce_parens(t_list **alst, char *str); -int expand_bquotes(t_list **alst); +int bquotes_expand(t_list **alst); char *command_getoutput(char *command); int ft_is_delim(char c); diff --git a/42sh/libft b/42sh/libft index d0ac53c6..ec8cf4e2 160000 --- a/42sh/libft +++ b/42sh/libft @@ -1 +1 @@ -Subproject commit d0ac53c68648106b8bafcc5ee8334306f6b0bc7e +Subproject commit ec8cf4e252fe22cdc0925b9f71df2d2f5e8931f6 diff --git a/42sh/src/builtin/builtin_cd.c b/42sh/src/builtin/builtin_cd.c index b973bf53..adb0c8f4 100644 --- a/42sh/src/builtin/builtin_cd.c +++ b/42sh/src/builtin/builtin_cd.c @@ -13,10 +13,10 @@ #include "builtin.h" #define CDOPT_L (1 << 0) -#define CDOPT_P (1 << 2) +#define CDOPT_P (1 << 1) #define HAS_CDOPT_P(x) (x & CD_OPT_P) #define HAS_CDOPT_L(x) (x & CD_OPT_L) -#define CDERR_1 "cd: no such file or directory: %s\n" +#define CDERR_1 "{red}cd: no such file or directory: %s{eoc}\n" static char *builtin_cd_special(char *const av[], char *const env[]) { diff --git a/42sh/src/lexer/expand_bquotes.c b/42sh/src/lexer/expand_bquotes.c index 92d65856..e76391cf 100644 --- a/42sh/src/lexer/expand_bquotes.c +++ b/42sh/src/lexer/expand_bquotes.c @@ -12,75 +12,80 @@ #include "lexer.h" -int expand_bquotes(t_list **alst) +int bquotes_insert_words(t_list *cur_word, char *word, char *after_bq) { + char *ifs; t_list *new_word; t_list *after_word; - t_list *cur_word; - t_list *lst; t_token *token; - t_token *token_buf; - char *word; - char *ifs; + + after_word = cur_word->next; + ifs = ft_getenv(data_singleton()->env, "IFS"); + if (ifs) + word = ft_strtok(word, ifs); + token = cur_word->content; + token_append_str(token, word, 0, 0); + if (ifs) + while ((word = ft_strtok(NULL, ifs))) + { + token = token_init(); + token->type = TK_WORD; + token_append_str(token, word, 0, 0); + new_word = ft_lstnew(token, sizeof(*token)); + cur_word->next = new_word; + new_word->next = after_word; + cur_word = new_word; + } + token = cur_word->content; + ft_strappend(&token->data, after_bq); + return (0); +} + +int bquotes_substitute(t_list *cur_word, char *bq_start, char *bq_end) +{ char *output; char *last_char; + char *after_bq; + + *bq_start = 0; + *bq_end = 0; + output = command_getoutput(bq_start + 1); + after_bq = ft_strdup(bq_end + 1); + last_char = output + ft_strlen(output) - 1; + while (*last_char == '\n') + *last_char++ = 0; + bquotes_insert_words(cur_word, output, after_bq); + ft_strdel(&output); + ft_strdel(&after_bq); + return (0); +} + +int bquotes_expand(t_list **alst) +{ + t_list *cur_word; + t_list *lst; char *bq_start; char *bq_end; - char *after_bq; - char **str; - t_lexer lexer; t_flag tk; tk = TK_WORD; cur_word = *alst; - while (cur_word && (lst = ft_lst_find(cur_word, &tk, token_cmp_type))) + while ((lst = ft_lst_find(cur_word, &tk, token_cmp_type))) { cur_word = lst; - after_word = cur_word->next; - token = cur_word->content; - str = &token->data; - if (!(bq_start = ft_strchr(*str, '`'))) + if (!(bq_start = ft_strchr(((t_token*)cur_word->content)->data, '`'))) { cur_word = cur_word->next; - continue ; + return (0); } if (!(bq_end = ft_strchr(bq_start + 1, '`'))) { ft_dprintf(2, "{red}%s: parse error near '`'{eoc}\n", SHELL_NAME); return (-1); } - *bq_end = 0; - after_bq = ft_strdup(bq_end + 1); - word = command_getoutput(bq_start + 1); - output = word; - last_char = word + ft_strlen(word) - 1; - while (*last_char == '\n') - *last_char++ = 0; - ifs = ft_getenv(data_singleton()->env, "IFS"); - if (ifs) - word = ft_strtok(word, ifs); - *bq_start = 0; - ft_strappend(str, word); - while (ifs && (lexer.str = ft_strtok(NULL, ifs))) - { - lexer.pos = 0; - token_buf = token_init(); - token_buf->type = TK_WORD; - while (lexer.str[lexer.pos]) - { - token_append(token_buf, &lexer, 0, 0); - lexer.pos++; - } - new_word = ft_lstnew(token_buf, sizeof(*token_buf)); - cur_word->next = new_word; - new_word->next = after_word; - cur_word = new_word; - } - token = cur_word->content; - ft_strappend(&token->data, after_bq); - ft_strdel(&after_bq); - ft_strdel(&output); - cur_word = after_word; + if (bquotes_substitute(cur_word, bq_start, bq_end)) + return (-1); + cur_word = lst; } return (0); } diff --git a/42sh/src/lexer/lexer_end.c b/42sh/src/lexer/lexer_end.c index f635cb3d..f7650e81 100644 --- a/42sh/src/lexer/lexer_end.c +++ b/42sh/src/lexer/lexer_end.c @@ -4,11 +4,12 @@ int lexer_end(t_list **alst, t_lexer *lexer) { t_token *token; - token = (*alst)->content; - if (lexer->state == QUOTE + DG("check"); + if (*alst && (lexer->state == QUOTE || lexer->state == DQUOTE - || lexer->state == BQUOTE) + || lexer->state == BQUOTE)) { + token = (*alst)->content; ft_strappend(&lexer->str, (char[]){'\n', 0}); token_append(token, lexer, 1, 0); lexer->pos++; diff --git a/42sh/src/lexer/token_append.c b/42sh/src/lexer/token_append.c index 1b82a8d3..4917e23d 100644 --- a/42sh/src/lexer/token_append.c +++ b/42sh/src/lexer/token_append.c @@ -12,12 +12,12 @@ #include "lexer.h" -int token_append(t_token *token, t_lexer *lexer, short int esc, short int esc2) + +int token_append_char(t_token *token, char c, + short int esc, short int esc2) { int len; - char c; - c = lexer->str[lexer->pos]; len = ft_strlen(token->data); if (len >= token->size) { @@ -37,3 +37,18 @@ int token_append(t_token *token, t_lexer *lexer, short int esc, short int esc2) token->esc2[len >> 3] |= esc2 << (7 - len % 8); return (0); } + +int token_append_str(t_token *token, char *str, + short int esc, short int esc2) +{ + while (*str) + if (token_append_char(token, *str++, esc, esc2)) + return (1); + return (0); +} + +int token_append(t_token *token, t_lexer *lexer, + short int esc, short int esc2) +{ + return (token_append_char(token, lexer->str[lexer->pos], esc, esc2)); +} diff --git a/42sh/src/line-editing/readline.c b/42sh/src/line-editing/readline.c index ba2e6498..bce462e1 100644 --- a/42sh/src/line-editing/readline.c +++ b/42sh/src/line-editing/readline.c @@ -85,18 +85,7 @@ char *readline(char *prompt) readline_init(prompt); input = ft_read_stdin(); ft_putchar('\n'); - /* ft_check_line(); */ - /* ft_check_heredoc(&STR); */ if (tcsetattr(0, TCSANOW, ft_save_termios(0)) == -1) return (NULL); return (input); - - /* ft_history_parsing(); */ - /* if (STR && (!data_singleton()->line.list_beg || */ - /* ft_strcmp(data_singleton()->line.list_beg->prev->str, STR))) */ - /* { */ - /* ft_push_back_history(&data_singleton()->line.list_beg, */ - /* ft_create_history_list(STR)); */ - /* ft_add_in_history_file(STR); */ - /* } */ } diff --git a/42sh/src/main/main.c b/42sh/src/main/main.c index 7fa3ae46..29497659 100644 --- a/42sh/src/main/main.c +++ b/42sh/src/main/main.c @@ -31,7 +31,7 @@ int non_interactive_shell(char *command) do { lexer_lex(&token, &lexer); } while (lexer.str[lexer.pos] == '\n'); - if (expand_bquotes(&token)) + if (bquotes_expand(&token)) return (1); token_print(token); if (ft_parse(&ast, &token)) @@ -63,13 +63,13 @@ int interactive_shell() DG("[{mag}%s{eoc}] stack=[%i] state=[%i]", lexer.str, lexer.stack ? *(int*)lexer.stack->content : 0, lexer.state); token_print(token); } while (lexer.stack); - if (expand_bquotes(&token)) + if (!token) + return (0); + if (bquotes_expand(&token)) return (1); - DG("check main 0"); token_print(token); if (ft_parse(&ast, &token)) return (1); - DG("check main 1"); btree_print(STDBUG, ast, &ft_putast); if (ft_exec(&ast)) return (1);