major stuff today: wrote a proper lexer based on finite state machines, quoting OK. next is finishing the parser, and history of line editing module
This commit is contained in:
parent
74f9916047
commit
bce0f37b8e
46 changed files with 477 additions and 156 deletions
|
|
@ -25,7 +25,7 @@ D_FLAGS =
|
|||
MKDIR = mkdir -p
|
||||
RM = /bin/rm -rf
|
||||
|
||||
.PHONY: all clean fclean re tags test
|
||||
.PHONY: all clean fclean re libft
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
|
|
@ -52,7 +52,12 @@ $(D_OBJ)/%.o: $(D_SRC)/line-editing/%.c includes/line_editing.h
|
|||
@$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS)
|
||||
@echo "Compiling "$<"..."
|
||||
|
||||
$(D_OBJ)/%.o: $(D_SRC)/lexer-parser/%.c includes/lexer_parser.h
|
||||
$(D_OBJ)/%.o: $(D_SRC)/lexer/%.c includes/lexer.h
|
||||
@$(MKDIR) $(D_OBJ)
|
||||
@$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS)
|
||||
@echo "Compiling "$<"..."
|
||||
|
||||
$(D_OBJ)/%.o: $(D_SRC)/parser/%.c includes/parser.h
|
||||
@$(MKDIR) $(D_OBJ)
|
||||
@$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS)
|
||||
@echo "Compiling "$<"..."
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef EXEC_H
|
||||
# define EXEC_H
|
||||
# include "lexer_parser.h"
|
||||
|
||||
# include "minishell.h"
|
||||
|
||||
typedef long long t_type;
|
||||
typedef struct s_exec t_exec;
|
||||
|
||||
struct s_exec
|
||||
|
|
|
|||
86
42sh/includes/lexer.h
Normal file
86
42sh/includes/lexer.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2016/11/10 15:31:42 by jhalford #+# #+# */
|
||||
/* Updated: 2016/11/14 18:22:04 by jhalford ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef LEXER_H
|
||||
# define LEXER_H
|
||||
|
||||
# include "minishell.h"
|
||||
|
||||
# define TK_LESS 0x0001
|
||||
# define TK_GREAT 0x0002
|
||||
# define TK_DLESS 0x0004
|
||||
# define TK_DGREAT 0x0008
|
||||
# define TK_LESSAND 0x0010
|
||||
# define TK_GREATAND 0x0020
|
||||
# define TK_SEMI 0x0040
|
||||
# define TK_PIPE 0x0080
|
||||
# define TK_WORD 0x0100
|
||||
# define TK_COMMAND 0x0200
|
||||
|
||||
# define TK_REDIR 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20
|
||||
|
||||
typedef long long t_type;
|
||||
typedef enum e_lexstate t_lexstate;
|
||||
typedef struct s_token t_token;
|
||||
typedef int t_lexer(t_list **alst,
|
||||
char *str);
|
||||
|
||||
enum e_lexstate
|
||||
{
|
||||
DEFAULT,
|
||||
DELIM,
|
||||
SEP,
|
||||
WORD,
|
||||
NUMBER,
|
||||
GREAT,
|
||||
LESS,
|
||||
GREATAND,
|
||||
LESSAND,
|
||||
QUOTE,
|
||||
DQUOTE,
|
||||
BACKSLASH,
|
||||
};
|
||||
|
||||
struct s_token
|
||||
{
|
||||
t_type type;
|
||||
char *data;
|
||||
int size;
|
||||
};
|
||||
|
||||
extern t_lexer *g_lexer[];
|
||||
|
||||
/* t_token *token_getnext(int *pos,char *line); */
|
||||
t_token *token_init();
|
||||
int ft_tokenize(t_list **alst, char *str, t_lexstate state);
|
||||
int token_append(t_token *token, char c);
|
||||
void token_free(void *data, size_t size);
|
||||
int token_cmp_type(t_type data, t_type ref);
|
||||
void token_print(t_list *lst);
|
||||
|
||||
int ft_is_delim(char c);
|
||||
|
||||
t_lexer lexer_default;
|
||||
t_lexer lexer_delim;
|
||||
t_lexer lexer_sep;
|
||||
t_lexer lexer_word;
|
||||
t_lexer lexer_number;
|
||||
t_lexer lexer_greatand;
|
||||
t_lexer lexer_lessand;
|
||||
t_lexer lexer_quote;
|
||||
t_lexer lexer_dquote;
|
||||
t_lexer lexer_backslash;
|
||||
|
||||
t_lexer lexer_less;
|
||||
t_lexer lexer_great;
|
||||
|
||||
#endif
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
#ifndef LINE_EDITING_H
|
||||
# define LINE_EDITING_H
|
||||
|
||||
# include "libft.h"
|
||||
# include "minishell.h"
|
||||
# include <curses.h>
|
||||
# include <term.h>
|
||||
|
||||
|
|
@ -45,26 +45,11 @@
|
|||
|
||||
typedef struct s_data t_data;
|
||||
|
||||
struct s_data
|
||||
{
|
||||
char **env;
|
||||
t_dlist *history;
|
||||
t_dlist *input_mem;
|
||||
|
||||
char *input;
|
||||
int input_pos;
|
||||
t_quote state_now;
|
||||
t_quote state_last;
|
||||
char quoted;
|
||||
char backslash;
|
||||
};
|
||||
|
||||
extern t_stof g_keys[];
|
||||
|
||||
int ft_set_termios(t_data *data, int input_mode);
|
||||
int ft_interactive_sh(t_data *data);
|
||||
int ft_prompt(void);
|
||||
int ft_input_is_escaped(t_dlist *input_chain);
|
||||
int ft_history_add(t_data *data);
|
||||
|
||||
typedef int key_press(t_data *data, char *buf);
|
||||
|
|
|
|||
|
|
@ -14,20 +14,47 @@
|
|||
# define MINISHELL_H
|
||||
|
||||
# include "libft.h"
|
||||
|
||||
# include "line_editing.h"
|
||||
# include "lexer_parser.h"
|
||||
# include "lexer.h"
|
||||
# include "parser.h"
|
||||
# include "exec.h"
|
||||
|
||||
# include <dirent.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/types.h>
|
||||
# include <signal.h>
|
||||
|
||||
typedef enum e_qstate t_qstate;
|
||||
typedef struct s_data t_data;
|
||||
|
||||
enum e_qstate
|
||||
{
|
||||
Q_NONE,
|
||||
Q_QUOTE,
|
||||
Q_DQUOTE,
|
||||
Q_BACKSLASH,
|
||||
};
|
||||
|
||||
struct s_data
|
||||
{
|
||||
char **env;
|
||||
t_dlist *history;
|
||||
|
||||
char *input;
|
||||
int input_pos;
|
||||
t_qstate state_now;
|
||||
t_qstate state_last;
|
||||
};
|
||||
|
||||
extern t_stof g_builtins[];
|
||||
extern pid_t g_pid;
|
||||
|
||||
void sig_handler(int signo);
|
||||
int data_init(t_data *data);
|
||||
|
||||
void qstate_update(t_data *data, char c);
|
||||
|
||||
int ft_cmd_process(char **argv, char ***env_p);
|
||||
int ft_cmd_exec(char *execpath, char **argv, char ***env_p);
|
||||
char **ft_cmd_getav(char *cmd);
|
||||
|
|
@ -44,6 +71,4 @@ void ft_expand_dollar(char **av, char **env);
|
|||
|
||||
char *ft_findexec(char **path, char *file);
|
||||
|
||||
int ft_tokenize(t_list **alst, char *str);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* token.h :+: :+: :+: */
|
||||
/* parser.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
|
|
@ -10,30 +10,22 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef TOKEN_H
|
||||
# define TOKEN_H
|
||||
#ifndef PARSER_H
|
||||
# define PARSER_H
|
||||
|
||||
# include "libft.h"
|
||||
|
||||
# define TK_LESS 0x0001
|
||||
# define TK_GREAT 0x0002
|
||||
# define TK_DLESS 0x0004
|
||||
# define TK_DGREAT 0x0008
|
||||
# define TK_LESSAND 0x0010
|
||||
# define TK_GREATAND 0x0020
|
||||
# define TK_SEMI 0x0040
|
||||
# define TK_PIPE 0x0080
|
||||
# define TK_WORD 0x0100
|
||||
# define TK_COMMAND 0x0200
|
||||
|
||||
# define TK_REDIR 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20
|
||||
# include "minishell.h"
|
||||
|
||||
typedef long long t_type;
|
||||
typedef struct s_token t_token;
|
||||
typedef struct s_parser t_parser;
|
||||
typedef struct s_astnode t_astnode;
|
||||
typedef struct s_redir t_redir;
|
||||
|
||||
struct s_parser
|
||||
{
|
||||
t_type type;
|
||||
int (*f)(t_btree **ast, t_list *start, t_list *token);
|
||||
};
|
||||
|
||||
struct s_redir
|
||||
{
|
||||
int n;
|
||||
|
|
@ -41,20 +33,7 @@ struct s_redir
|
|||
{
|
||||
char *word;
|
||||
int fd;
|
||||
} u_word;
|
||||
};
|
||||
|
||||
struct s_token
|
||||
{
|
||||
t_type type;
|
||||
char *data;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct s_parser
|
||||
{
|
||||
t_type type;
|
||||
int (*f)(t_btree **ast, t_list *start, t_list *token);
|
||||
} word;
|
||||
};
|
||||
|
||||
struct s_astnode
|
||||
|
|
@ -69,14 +48,6 @@ struct s_astnode
|
|||
|
||||
extern t_parser g_parser[];
|
||||
|
||||
t_token *token_init();
|
||||
t_token *token_getnext(int *pos,char *line);
|
||||
int ft_tokenize(t_list **alst, char *str);
|
||||
int token_append(t_token *token, char c);
|
||||
void token_free(void *data, size_t size);
|
||||
int token_cmp_type(t_type data, t_type ref);
|
||||
void token_print(t_list *lst);
|
||||
|
||||
int ft_parse(t_btree **ast, t_list *token);
|
||||
int parse_separator(t_btree **ast, t_list *start, t_list *lst);
|
||||
int parse_less(t_btree **ast, t_list *start, t_list *lst);
|
||||
|
|
@ -88,4 +59,5 @@ int parse_greatand(t_btree **ast, t_list *start, t_list *lst);
|
|||
int parse_word(t_btree **ast, t_list *start, t_list *lst);
|
||||
|
||||
void tree_type(t_btree *tree);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef LINE_EDITING_H
|
||||
# define LINE_EDITING_H
|
||||
|
||||
typedef enum e_quote t_quote;
|
||||
|
||||
enum e_quote
|
||||
{
|
||||
NONE,
|
||||
QUOTE,
|
||||
DQUOTE,
|
||||
BACKSLASH,
|
||||
};
|
||||
|
||||
void quote_update(t_data *data, char c);
|
||||
|
||||
#endif
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 202926ba40a54535c54650272db67a60a9598e1d
|
||||
Subproject commit 3741ee4abd2986790543bb1877371570da39a435
|
||||
|
|
@ -10,22 +10,53 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "lexer.h"
|
||||
|
||||
int ft_tokenize(t_list **alst, char *str)
|
||||
t_lexer *g_lexer[] =
|
||||
{
|
||||
&lexer_default,
|
||||
&lexer_delim,
|
||||
&lexer_sep,
|
||||
&lexer_word,
|
||||
&lexer_number,
|
||||
&lexer_great,
|
||||
&lexer_less,
|
||||
&lexer_greatand,
|
||||
&lexer_lessand,
|
||||
&lexer_quote,
|
||||
&lexer_dquote,
|
||||
&lexer_backslash,
|
||||
};
|
||||
|
||||
int ft_is_delim(char c)
|
||||
{
|
||||
return (c == ' ' || c == '\t' || c == '\n');
|
||||
}
|
||||
|
||||
int ft_tokenize(t_list **alst, char *str, t_lexstate state)
|
||||
{
|
||||
t_token *token;
|
||||
char *cmd;
|
||||
int pos;
|
||||
|
||||
pos = 0;
|
||||
cmd = ft_strdup(str);
|
||||
while ((token = token_getnext(&pos, cmd)))
|
||||
{
|
||||
if (!*str)
|
||||
return (0);
|
||||
token = token_init();
|
||||
if (!*alst)
|
||||
*alst = ft_lstnew(token, sizeof(*token));
|
||||
alst = &(*alst)->next;
|
||||
free(token);
|
||||
if (ft_is_delim(*str))
|
||||
state = DELIM;
|
||||
if (*str == ';' || *str == '|')
|
||||
state = SEP;
|
||||
else if (*str == '\'')
|
||||
{
|
||||
state = QUOTE;
|
||||
str++;
|
||||
}
|
||||
ft_strdel(&cmd);
|
||||
return (0);
|
||||
else if (*str == '\"')
|
||||
{
|
||||
state = DQUOTE;
|
||||
str++;
|
||||
}
|
||||
else if (*str == '\\')
|
||||
state = BACKSLASH;
|
||||
return ((*g_lexer[state])(alst, str));
|
||||
}
|
||||
11
42sh/src/lexer/lexer_backslash.c
Normal file
11
42sh/src/lexer/lexer_backslash.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_backslash(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
token->type = TK_WORD;
|
||||
token_append(token, str[1]);
|
||||
return (ft_tokenize(alst, str + 2, WORD));
|
||||
}
|
||||
18
42sh/src/lexer/lexer_default.c
Normal file
18
42sh/src/lexer/lexer_default.c
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_default(t_list **alst, char *str)
|
||||
{
|
||||
t_lexstate state;
|
||||
|
||||
state = DEFAULT;
|
||||
if (*str == '>')
|
||||
state = GREAT;
|
||||
else if (*str == '<')
|
||||
state = LESS;
|
||||
else if (ft_isdigit(*str))
|
||||
state = NUMBER;
|
||||
else
|
||||
state = WORD;
|
||||
token_append((*alst)->content ,*str);
|
||||
return (ft_tokenize(alst, str + 1, state));
|
||||
}
|
||||
14
42sh/src/lexer/lexer_delim.c
Normal file
14
42sh/src/lexer/lexer_delim.c
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_delim(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
while (ft_is_delim(*str))
|
||||
str++;
|
||||
if (*token->data)
|
||||
return (ft_tokenize(&(*alst)->next, str, DEFAULT));
|
||||
else
|
||||
return (ft_tokenize(alst, str, DEFAULT));
|
||||
}
|
||||
19
42sh/src/lexer/lexer_dquote.c
Normal file
19
42sh/src/lexer/lexer_dquote.c
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_dquote(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
token->type = WORD;
|
||||
if (*str == '\"')
|
||||
return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT));
|
||||
if (*str == '\\')
|
||||
{
|
||||
token_append(token, *str);
|
||||
token_append(token, *(str + 1));
|
||||
return (lexer_dquote(alst, str + 2));
|
||||
}
|
||||
token_append(token, *str);
|
||||
return (lexer_dquote(alst, str + 1));
|
||||
}
|
||||
24
42sh/src/lexer/lexer_great.c
Normal file
24
42sh/src/lexer/lexer_great.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_great(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
if (*str == '&')
|
||||
{
|
||||
token_append(token, *str);
|
||||
return (lexer_greatand(alst, str + 1));
|
||||
}
|
||||
else if (*str == '>')
|
||||
{
|
||||
token->type = TK_DGREAT;
|
||||
token_append(token, *str);
|
||||
return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT));
|
||||
}
|
||||
else
|
||||
{
|
||||
token->type = TK_GREAT;
|
||||
return (ft_tokenize(&(*alst)->next, str, DEFAULT));
|
||||
}
|
||||
}
|
||||
20
42sh/src/lexer/lexer_greatand.c
Normal file
20
42sh/src/lexer/lexer_greatand.c
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_greatand(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
token->type = GREATAND;
|
||||
if (ft_isdigit(*str))
|
||||
{
|
||||
token_append(token, *str);
|
||||
return (lexer_greatand(alst, str + 1));
|
||||
}
|
||||
else if (*str == '-')
|
||||
{
|
||||
token_append(token, *str);
|
||||
return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT));
|
||||
}
|
||||
return (ft_tokenize(alst, str, DEFAULT));
|
||||
}
|
||||
25
42sh/src/lexer/lexer_less.c
Normal file
25
42sh/src/lexer/lexer_less.c
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_less(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
if (*str == '&')
|
||||
{
|
||||
token_append(token, *str);
|
||||
return (lexer_lessand(alst, str + 1));
|
||||
}
|
||||
else if (*str == '<')
|
||||
{
|
||||
token->type = TK_DLESS;
|
||||
token_append(token, *str);
|
||||
return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT));
|
||||
}
|
||||
else
|
||||
{
|
||||
token->type = TK_LESS;
|
||||
token_append(token, *str);
|
||||
return (ft_tokenize(alst, str + 1, DEFAULT));
|
||||
}
|
||||
}
|
||||
20
42sh/src/lexer/lexer_lessand.c
Normal file
20
42sh/src/lexer/lexer_lessand.c
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_lessand(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
token->type = LESSAND;
|
||||
if (ft_isdigit(*str))
|
||||
{
|
||||
token_append(token, *str);
|
||||
return (lexer_lessand(alst, str + 1));
|
||||
}
|
||||
else if (*str == '-')
|
||||
{
|
||||
token_append(token, *str);
|
||||
return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT));
|
||||
}
|
||||
return (ft_tokenize(alst, str, DEFAULT));
|
||||
}
|
||||
24
42sh/src/lexer/lexer_number.c
Normal file
24
42sh/src/lexer/lexer_number.c
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_number(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
if (*str == '>')
|
||||
{
|
||||
token_append(token, *str);
|
||||
return (lexer_great(alst, str + 1));
|
||||
}
|
||||
else if (*str == '<')
|
||||
{
|
||||
token_append(token, *str);
|
||||
return (lexer_less(alst, str + 1));
|
||||
}
|
||||
else if (ft_isdigit(*str))
|
||||
{
|
||||
token_append(token, *str);
|
||||
return (lexer_number(alst, str + 1));
|
||||
}
|
||||
return (ft_tokenize(alst, str, DEFAULT));
|
||||
}
|
||||
13
42sh/src/lexer/lexer_quote.c
Normal file
13
42sh/src/lexer/lexer_quote.c
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_quote(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
token->type = TK_WORD;
|
||||
if (*str == '\'')
|
||||
return (ft_tokenize(&(*alst)->next, str + 1, WORD));
|
||||
token_append(token, *str);
|
||||
return (lexer_quote(alst, str + 1));
|
||||
}
|
||||
21
42sh/src/lexer/lexer_sep.c
Normal file
21
42sh/src/lexer/lexer_sep.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_sep(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
if (*alst)
|
||||
{
|
||||
token = (*alst)->content;
|
||||
if (*token->data)
|
||||
return (lexer_sep(&(*alst)->next, str));
|
||||
}
|
||||
else
|
||||
{
|
||||
token = token_init();
|
||||
*alst = ft_lstnew(token, sizeof(*token));
|
||||
}
|
||||
token->type = *str == ';' ? TK_SEMI : TK_PIPE;
|
||||
token_append(token, *str);
|
||||
return (ft_tokenize(&(*alst)->next, str + 1, DEFAULT));
|
||||
}
|
||||
15
42sh/src/lexer/lexer_word.c
Normal file
15
42sh/src/lexer/lexer_word.c
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#include "lexer.h"
|
||||
|
||||
int lexer_word(t_list **alst, char *str)
|
||||
{
|
||||
t_token *token;
|
||||
|
||||
token = (*alst)->content;
|
||||
token->type = TK_WORD;
|
||||
if (*str == '>')
|
||||
return (ft_tokenize(&(*alst)->next, str, GREAT));
|
||||
else if (*str == '<')
|
||||
return (ft_tokenize(&(*alst)->next, str, LESS));
|
||||
token_append(token, *str);
|
||||
return (ft_tokenize(alst, str + 1, WORD));
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "lexer.h"
|
||||
|
||||
int token_append(t_token *token, char c)
|
||||
{
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "lexer_parser.h"
|
||||
#include "lexer.h"
|
||||
|
||||
int token_cmp_type(t_type data, t_type ref)
|
||||
{
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "lexer_parser.h"
|
||||
#include "lexer.h"
|
||||
|
||||
void token_free(void *data, size_t size)
|
||||
{
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#include "lexer_parser.h"
|
||||
#include "lexer.h"
|
||||
|
||||
static int is_separator(char c)
|
||||
{
|
||||
return (c==' ' || c=='\t' || c=='\n' || c=='\r');
|
||||
return (c==' ' || c=='\t' || c=='\n');
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "lexer.h"
|
||||
|
||||
t_token *token_init()
|
||||
{
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "lexer_parser.h"
|
||||
#include "lexer.h"
|
||||
|
||||
void token_print(t_list *lst)
|
||||
{
|
||||
|
|
@ -54,8 +54,7 @@ int ft_interactive_sh(t_data *data)
|
|||
ft_strdel(&data->input);
|
||||
data->input = ft_memalloc(10);
|
||||
data->input_pos = 0;
|
||||
data->quoting = 0;
|
||||
data->backslach = 0;
|
||||
data->state_now = Q_NONE;
|
||||
ft_set_termios(data, 1);
|
||||
ft_prompt();
|
||||
while (1)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ int ft_key_default(t_data *data, char *buf)
|
|||
data->input = ft_strinsert(data->input, *buf, data->input_pos);
|
||||
data->input_pos++;
|
||||
ft_strdel(&tmp);
|
||||
quote_update(data, *buf);
|
||||
qstate_update(data, *buf);
|
||||
if ((res = tgetstr("IC", NULL)))
|
||||
{
|
||||
tputs(tgoto(res, 0, 0), 1, &ft_putchar);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ int ft_key_del(t_data *data, char *buf)
|
|||
return (0);
|
||||
if (data->input[data->input_pos - 1] == '\n')
|
||||
return (0);
|
||||
ft_strsqueeze(data->input, data->input_pos - 1);
|
||||
ft_strcpy(data->input + data->input_pos - 1,
|
||||
data->input + data->input_pos);
|
||||
data->input_pos--;
|
||||
if ((res = tgetstr("le", NULL)) == NULL)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@
|
|||
int ft_key_enter(t_data *data, char *buf)
|
||||
{
|
||||
(void)buf;
|
||||
if (data->quoting || data->backslash)
|
||||
if (data->state_now == Q_NONE)
|
||||
{
|
||||
ft_key_basic(data, buf);
|
||||
ft_printf("> ");
|
||||
return (0);
|
||||
ft_putchar('\n');
|
||||
ft_history_add(data);
|
||||
return (2);
|
||||
}
|
||||
ft_putchar('\n');
|
||||
ft_history_add(data);
|
||||
return (2);
|
||||
ft_key_default(data, buf);
|
||||
ft_printf("> ");
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ int ft_set_termios(t_data *data, int input_mode)
|
|||
if (tcgetattr(0, &term) == -1)
|
||||
return (-1);
|
||||
term.c_lflag &= ~(ICANON); // Met le terminal en mode canonique.
|
||||
if (input_mode == 1)
|
||||
if (input_mode)
|
||||
term.c_lflag &= ~(ISIG) & ~(ECHO);
|
||||
else
|
||||
term.c_lflag |= ISIG | ECHO;
|
||||
|
|
|
|||
|
|
@ -28,22 +28,18 @@ int main(void)
|
|||
if (ft_interactive_sh(&data))
|
||||
return (1);
|
||||
ft_printf("got command:'%s'\n", data.input);
|
||||
/* if (ft_tokenize(&token, data.history->prev->content)) */
|
||||
/* return (1); */
|
||||
/* token_print(token); */
|
||||
/* (void)ast; */
|
||||
/* if (ft_parse(&ast, token)) */
|
||||
/* return (1); */
|
||||
/* btree_print(ast, &tree_type); */
|
||||
/* ft_printf("root: %i\n", ((t_astnode*)ast->item)->type); */
|
||||
/* ft_lstdel(&token, &token_free); */
|
||||
if (ft_tokenize(&token, data.input, DEFAULT))
|
||||
return (1);
|
||||
token_print(token);
|
||||
if (ft_parse(&ast, token))
|
||||
return (1);
|
||||
btree_print(ast, &tree_type);
|
||||
ft_printf("root: %i\n", ((t_astnode*)ast->item)->type);
|
||||
ft_lstdel(&token, &token_free);
|
||||
token = NULL;
|
||||
/* if (ft_exec(ast)) */
|
||||
/* return (1); */
|
||||
|
||||
/* char **av = ft_cmd_getav(data.history->prev->content); */
|
||||
/* if (av && av[0]) */
|
||||
/* ft_cmd_process(av, &data.env); */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
|
|||
35
42sh/src/main/qstate_update.c
Normal file
35
42sh/src/main/qstate_update.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#include "minishell.h"
|
||||
|
||||
void qstate_update(t_data *data, char c)
|
||||
{
|
||||
t_qstate *now;
|
||||
t_qstate *last;
|
||||
|
||||
now = &data->state_now;
|
||||
last = &data->state_last;
|
||||
if (*now == Q_NONE)
|
||||
{
|
||||
if (c == '\\')
|
||||
{
|
||||
*last = Q_NONE;
|
||||
*now = Q_BACKSLASH;
|
||||
}
|
||||
*now = c == '\'' ? Q_QUOTE : *now;
|
||||
*now = c == '\"' ? Q_DQUOTE : *now;
|
||||
}
|
||||
else if (*now == Q_QUOTE)
|
||||
*now = c == '\'' ? Q_NONE : *now;
|
||||
else if (*now == Q_DQUOTE)
|
||||
{
|
||||
if (c == '\\')
|
||||
{
|
||||
*last = Q_DQUOTE;
|
||||
*now = Q_BACKSLASH;
|
||||
}
|
||||
*now = c == '\"' ? Q_NONE : *now;
|
||||
}
|
||||
else if (*now == Q_BACKSLASH)
|
||||
{
|
||||
*now = *last;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
t_parser g_parser[] =
|
||||
{
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
int parse_dgreat(t_btree **ast, t_list *start, t_list *lst)
|
||||
{
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
int parse_dless(t_btree **ast, t_list *start, t_list *lst)
|
||||
{
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
int parse_great(t_btree **ast, t_list *start, t_list *lst)
|
||||
{
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
int parse_greatand(t_btree **ast, t_list *start, t_list *lst)
|
||||
{
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
int parse_less(t_btree **ast, t_list *start, t_list *lst)
|
||||
{
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
int parse_lessand(t_btree **ast, t_list *start, t_list *lst)
|
||||
{
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
int parse_separator(t_btree **ast, t_list *start, t_list *lst)
|
||||
{
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
int parse_word(t_btree **ast, t_list *start, t_list *lst)
|
||||
{
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "lexer_parser.h"
|
||||
#include "parser.h"
|
||||
|
||||
void tree_type(t_btree *tree)
|
||||
{
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#include "libft.h"
|
||||
|
||||
void quote_state_update(t_data *data, char c)
|
||||
{
|
||||
t_quote now;
|
||||
t_quote last;
|
||||
|
||||
now = data->state_now;
|
||||
last = data->state_last;
|
||||
if (c == '\\' && now != DQUOTE)
|
||||
{
|
||||
if (now == BACKSLASH)
|
||||
now = last;
|
||||
else
|
||||
now = BACKSLASH;
|
||||
}
|
||||
if (quote != BACKSLASH)
|
||||
{
|
||||
if (c == '\'')
|
||||
quoted = now == QUOTE ? 0 : '\'';
|
||||
if (c == '\"' )
|
||||
data->quoted = now == DQUOTE ? 0 : '\"';
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue