bquotes expansion refactoring for future norm checks; still need to preventh field splitting for dquoted bquotes; also need to fuse bquote expansion into the globbing module
This commit is contained in:
parent
4840051dbd
commit
be6be17f2a
8 changed files with 86 additions and 72 deletions
|
|
@ -84,12 +84,16 @@ int ft_post_tokenize(t_list **alst, char **str);
|
||||||
t_token *token_init();
|
t_token *token_init();
|
||||||
int token_append(t_token *token, t_lexer *lexer,
|
int token_append(t_token *token, t_lexer *lexer,
|
||||||
short int esc, short int esc2);
|
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);
|
void token_free(void *data, size_t size);
|
||||||
int token_cmp_type(t_token *token, t_type *ref);
|
int token_cmp_type(t_token *token, t_type *ref);
|
||||||
void token_print(t_list *lst);
|
void token_print(t_list *lst);
|
||||||
|
|
||||||
int reduce_parens(t_list **alst, char *str);
|
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);
|
char *command_getoutput(char *command);
|
||||||
|
|
||||||
int ft_is_delim(char c);
|
int ft_is_delim(char c);
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit d0ac53c68648106b8bafcc5ee8334306f6b0bc7e
|
Subproject commit ec8cf4e252fe22cdc0925b9f71df2d2f5e8931f6
|
||||||
|
|
@ -13,10 +13,10 @@
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
|
|
||||||
#define CDOPT_L (1 << 0)
|
#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_P(x) (x & CD_OPT_P)
|
||||||
#define HAS_CDOPT_L(x) (x & CD_OPT_L)
|
#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[])
|
static char *builtin_cd_special(char *const av[], char *const env[])
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,75 +12,80 @@
|
||||||
|
|
||||||
#include "lexer.h"
|
#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 *new_word;
|
||||||
t_list *after_word;
|
t_list *after_word;
|
||||||
t_list *cur_word;
|
|
||||||
t_list *lst;
|
|
||||||
t_token *token;
|
t_token *token;
|
||||||
t_token *token_buf;
|
|
||||||
char *word;
|
after_word = cur_word->next;
|
||||||
char *ifs;
|
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 *output;
|
||||||
char *last_char;
|
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_start;
|
||||||
char *bq_end;
|
char *bq_end;
|
||||||
char *after_bq;
|
|
||||||
char **str;
|
|
||||||
t_lexer lexer;
|
|
||||||
t_flag tk;
|
t_flag tk;
|
||||||
|
|
||||||
tk = TK_WORD;
|
tk = TK_WORD;
|
||||||
cur_word = *alst;
|
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;
|
cur_word = lst;
|
||||||
after_word = cur_word->next;
|
if (!(bq_start = ft_strchr(((t_token*)cur_word->content)->data, '`')))
|
||||||
token = cur_word->content;
|
|
||||||
str = &token->data;
|
|
||||||
if (!(bq_start = ft_strchr(*str, '`')))
|
|
||||||
{
|
{
|
||||||
cur_word = cur_word->next;
|
cur_word = cur_word->next;
|
||||||
continue ;
|
return (0);
|
||||||
}
|
}
|
||||||
if (!(bq_end = ft_strchr(bq_start + 1, '`')))
|
if (!(bq_end = ft_strchr(bq_start + 1, '`')))
|
||||||
{
|
{
|
||||||
ft_dprintf(2, "{red}%s: parse error near '`'{eoc}\n", SHELL_NAME);
|
ft_dprintf(2, "{red}%s: parse error near '`'{eoc}\n", SHELL_NAME);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
*bq_end = 0;
|
if (bquotes_substitute(cur_word, bq_start, bq_end))
|
||||||
after_bq = ft_strdup(bq_end + 1);
|
return (-1);
|
||||||
word = command_getoutput(bq_start + 1);
|
cur_word = lst;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,12 @@ int lexer_end(t_list **alst, t_lexer *lexer)
|
||||||
{
|
{
|
||||||
t_token *token;
|
t_token *token;
|
||||||
|
|
||||||
token = (*alst)->content;
|
DG("check");
|
||||||
if (lexer->state == QUOTE
|
if (*alst && (lexer->state == QUOTE
|
||||||
|| lexer->state == DQUOTE
|
|| lexer->state == DQUOTE
|
||||||
|| lexer->state == BQUOTE)
|
|| lexer->state == BQUOTE))
|
||||||
{
|
{
|
||||||
|
token = (*alst)->content;
|
||||||
ft_strappend(&lexer->str, (char[]){'\n', 0});
|
ft_strappend(&lexer->str, (char[]){'\n', 0});
|
||||||
token_append(token, lexer, 1, 0);
|
token_append(token, lexer, 1, 0);
|
||||||
lexer->pos++;
|
lexer->pos++;
|
||||||
|
|
|
||||||
|
|
@ -12,12 +12,12 @@
|
||||||
|
|
||||||
#include "lexer.h"
|
#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;
|
int len;
|
||||||
char c;
|
|
||||||
|
|
||||||
c = lexer->str[lexer->pos];
|
|
||||||
len = ft_strlen(token->data);
|
len = ft_strlen(token->data);
|
||||||
if (len >= token->size)
|
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);
|
token->esc2[len >> 3] |= esc2 << (7 - len % 8);
|
||||||
return (0);
|
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));
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,18 +85,7 @@ char *readline(char *prompt)
|
||||||
readline_init(prompt);
|
readline_init(prompt);
|
||||||
input = ft_read_stdin();
|
input = ft_read_stdin();
|
||||||
ft_putchar('\n');
|
ft_putchar('\n');
|
||||||
/* ft_check_line(); */
|
|
||||||
/* ft_check_heredoc(&STR); */
|
|
||||||
if (tcsetattr(0, TCSANOW, ft_save_termios(0)) == -1)
|
if (tcsetattr(0, TCSANOW, ft_save_termios(0)) == -1)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
return (input);
|
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); */
|
|
||||||
/* } */
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ int non_interactive_shell(char *command)
|
||||||
do {
|
do {
|
||||||
lexer_lex(&token, &lexer);
|
lexer_lex(&token, &lexer);
|
||||||
} while (lexer.str[lexer.pos] == '\n');
|
} while (lexer.str[lexer.pos] == '\n');
|
||||||
if (expand_bquotes(&token))
|
if (bquotes_expand(&token))
|
||||||
return (1);
|
return (1);
|
||||||
token_print(token);
|
token_print(token);
|
||||||
if (ft_parse(&ast, &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);
|
DG("[{mag}%s{eoc}] stack=[%i] state=[%i]", lexer.str, lexer.stack ? *(int*)lexer.stack->content : 0, lexer.state);
|
||||||
token_print(token);
|
token_print(token);
|
||||||
} while (lexer.stack);
|
} while (lexer.stack);
|
||||||
if (expand_bquotes(&token))
|
if (!token)
|
||||||
|
return (0);
|
||||||
|
if (bquotes_expand(&token))
|
||||||
return (1);
|
return (1);
|
||||||
DG("check main 0");
|
|
||||||
token_print(token);
|
token_print(token);
|
||||||
if (ft_parse(&ast, &token))
|
if (ft_parse(&ast, &token))
|
||||||
return (1);
|
return (1);
|
||||||
DG("check main 1");
|
|
||||||
btree_print(STDBUG, ast, &ft_putast);
|
btree_print(STDBUG, ast, &ft_putast);
|
||||||
if (ft_exec(&ast))
|
if (ft_exec(&ast))
|
||||||
return (1);
|
return (1);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue