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
|
MKDIR = mkdir -p
|
||||||
RM = /bin/rm -rf
|
RM = /bin/rm -rf
|
||||||
|
|
||||||
.PHONY: all clean fclean re tags test
|
.PHONY: all clean fclean re libft
|
||||||
|
|
||||||
all: $(NAME)
|
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)
|
@$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS)
|
||||||
@echo "Compiling "$<"..."
|
@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)
|
@$(MKDIR) $(D_OBJ)
|
||||||
@$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS)
|
@$(CC) $(O_INC) $(W_FLAGS) -c $< -o $@ $(D_FLAGS)
|
||||||
@echo "Compiling "$<"..."
|
@echo "Compiling "$<"..."
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#ifndef EXEC_H
|
#ifndef EXEC_H
|
||||||
# define EXEC_H
|
# define EXEC_H
|
||||||
# include "lexer_parser.h"
|
|
||||||
|
|
||||||
|
# include "minishell.h"
|
||||||
|
|
||||||
|
typedef long long t_type;
|
||||||
typedef struct s_exec t_exec;
|
typedef struct s_exec t_exec;
|
||||||
|
|
||||||
struct s_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
|
#ifndef LINE_EDITING_H
|
||||||
# define LINE_EDITING_H
|
# define LINE_EDITING_H
|
||||||
|
|
||||||
# include "libft.h"
|
# include "minishell.h"
|
||||||
# include <curses.h>
|
# include <curses.h>
|
||||||
# include <term.h>
|
# include <term.h>
|
||||||
|
|
||||||
|
|
@ -45,26 +45,11 @@
|
||||||
|
|
||||||
typedef struct s_data t_data;
|
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[];
|
extern t_stof g_keys[];
|
||||||
|
|
||||||
int ft_set_termios(t_data *data, int input_mode);
|
int ft_set_termios(t_data *data, int input_mode);
|
||||||
int ft_interactive_sh(t_data *data);
|
int ft_interactive_sh(t_data *data);
|
||||||
int ft_prompt(void);
|
int ft_prompt(void);
|
||||||
int ft_input_is_escaped(t_dlist *input_chain);
|
|
||||||
int ft_history_add(t_data *data);
|
int ft_history_add(t_data *data);
|
||||||
|
|
||||||
typedef int key_press(t_data *data, char *buf);
|
typedef int key_press(t_data *data, char *buf);
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,47 @@
|
||||||
# define MINISHELL_H
|
# define MINISHELL_H
|
||||||
|
|
||||||
# include "libft.h"
|
# include "libft.h"
|
||||||
|
|
||||||
# include "line_editing.h"
|
# include "line_editing.h"
|
||||||
# include "lexer_parser.h"
|
# include "lexer.h"
|
||||||
|
# include "parser.h"
|
||||||
# include "exec.h"
|
# include "exec.h"
|
||||||
|
|
||||||
# include <dirent.h>
|
# include <dirent.h>
|
||||||
# include <sys/stat.h>
|
# include <sys/stat.h>
|
||||||
# include <sys/types.h>
|
# include <sys/types.h>
|
||||||
# include <signal.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 t_stof g_builtins[];
|
||||||
extern pid_t g_pid;
|
extern pid_t g_pid;
|
||||||
|
|
||||||
void sig_handler(int signo);
|
void sig_handler(int signo);
|
||||||
int data_init(t_data *data);
|
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_process(char **argv, char ***env_p);
|
||||||
int ft_cmd_exec(char *execpath, char **argv, char ***env_p);
|
int ft_cmd_exec(char *execpath, char **argv, char ***env_p);
|
||||||
char **ft_cmd_getav(char *cmd);
|
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);
|
char *ft_findexec(char **path, char *file);
|
||||||
|
|
||||||
int ft_tokenize(t_list **alst, char *str);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
/* */
|
/* */
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* token.h :+: :+: :+: */
|
/* parser.h :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
|
@ -10,30 +10,22 @@
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#ifndef TOKEN_H
|
#ifndef PARSER_H
|
||||||
# define TOKEN_H
|
# define PARSER_H
|
||||||
|
|
||||||
# include "libft.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 long long t_type;
|
||||||
typedef struct s_token t_token;
|
|
||||||
typedef struct s_parser t_parser;
|
typedef struct s_parser t_parser;
|
||||||
typedef struct s_astnode t_astnode;
|
typedef struct s_astnode t_astnode;
|
||||||
typedef struct s_redir t_redir;
|
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
|
struct s_redir
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
@ -41,20 +33,7 @@ struct s_redir
|
||||||
{
|
{
|
||||||
char *word;
|
char *word;
|
||||||
int fd;
|
int fd;
|
||||||
} u_word;
|
} 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);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct s_astnode
|
struct s_astnode
|
||||||
|
|
@ -69,14 +48,6 @@ struct s_astnode
|
||||||
|
|
||||||
extern t_parser g_parser[];
|
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 ft_parse(t_btree **ast, t_list *token);
|
||||||
int parse_separator(t_btree **ast, t_list *start, t_list *lst);
|
int parse_separator(t_btree **ast, t_list *start, t_list *lst);
|
||||||
int parse_less(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);
|
int parse_word(t_btree **ast, t_list *start, t_list *lst);
|
||||||
|
|
||||||
void tree_type(t_btree *tree);
|
void tree_type(t_btree *tree);
|
||||||
|
|
||||||
#endif
|
#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;
|
t_token *token;
|
||||||
char *cmd;
|
|
||||||
int pos;
|
|
||||||
|
|
||||||
pos = 0;
|
if (!*str)
|
||||||
cmd = ft_strdup(str);
|
return (0);
|
||||||
while ((token = token_getnext(&pos, cmd)))
|
token = token_init();
|
||||||
{
|
if (!*alst)
|
||||||
*alst = ft_lstnew(token, sizeof(*token));
|
*alst = ft_lstnew(token, sizeof(*token));
|
||||||
alst = &(*alst)->next;
|
if (ft_is_delim(*str))
|
||||||
free(token);
|
state = DELIM;
|
||||||
|
if (*str == ';' || *str == '|')
|
||||||
|
state = SEP;
|
||||||
|
else if (*str == '\'')
|
||||||
|
{
|
||||||
|
state = QUOTE;
|
||||||
|
str++;
|
||||||
}
|
}
|
||||||
ft_strdel(&cmd);
|
else if (*str == '\"')
|
||||||
return (0);
|
{
|
||||||
|
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)
|
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)
|
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)
|
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)
|
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()
|
t_token *token_init()
|
||||||
{
|
{
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#include "lexer_parser.h"
|
#include "lexer.h"
|
||||||
|
|
||||||
void token_print(t_list *lst)
|
void token_print(t_list *lst)
|
||||||
{
|
{
|
||||||
|
|
@ -54,8 +54,7 @@ int ft_interactive_sh(t_data *data)
|
||||||
ft_strdel(&data->input);
|
ft_strdel(&data->input);
|
||||||
data->input = ft_memalloc(10);
|
data->input = ft_memalloc(10);
|
||||||
data->input_pos = 0;
|
data->input_pos = 0;
|
||||||
data->quoting = 0;
|
data->state_now = Q_NONE;
|
||||||
data->backslach = 0;
|
|
||||||
ft_set_termios(data, 1);
|
ft_set_termios(data, 1);
|
||||||
ft_prompt();
|
ft_prompt();
|
||||||
while (1)
|
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 = ft_strinsert(data->input, *buf, data->input_pos);
|
||||||
data->input_pos++;
|
data->input_pos++;
|
||||||
ft_strdel(&tmp);
|
ft_strdel(&tmp);
|
||||||
quote_update(data, *buf);
|
qstate_update(data, *buf);
|
||||||
if ((res = tgetstr("IC", NULL)))
|
if ((res = tgetstr("IC", NULL)))
|
||||||
{
|
{
|
||||||
tputs(tgoto(res, 0, 0), 1, &ft_putchar);
|
tputs(tgoto(res, 0, 0), 1, &ft_putchar);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,8 @@ int ft_key_del(t_data *data, char *buf)
|
||||||
return (0);
|
return (0);
|
||||||
if (data->input[data->input_pos - 1] == '\n')
|
if (data->input[data->input_pos - 1] == '\n')
|
||||||
return (0);
|
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--;
|
data->input_pos--;
|
||||||
if ((res = tgetstr("le", NULL)) == NULL)
|
if ((res = tgetstr("le", NULL)) == NULL)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,13 @@
|
||||||
int ft_key_enter(t_data *data, char *buf)
|
int ft_key_enter(t_data *data, char *buf)
|
||||||
{
|
{
|
||||||
(void)buf;
|
(void)buf;
|
||||||
if (data->quoting || data->backslash)
|
if (data->state_now == Q_NONE)
|
||||||
{
|
{
|
||||||
ft_key_basic(data, buf);
|
ft_putchar('\n');
|
||||||
ft_printf("> ");
|
ft_history_add(data);
|
||||||
return (0);
|
return (2);
|
||||||
}
|
}
|
||||||
ft_putchar('\n');
|
ft_key_default(data, buf);
|
||||||
ft_history_add(data);
|
ft_printf("> ");
|
||||||
return (2);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ int ft_set_termios(t_data *data, int input_mode)
|
||||||
if (tcgetattr(0, &term) == -1)
|
if (tcgetattr(0, &term) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
term.c_lflag &= ~(ICANON); // Met le terminal en mode canonique.
|
term.c_lflag &= ~(ICANON); // Met le terminal en mode canonique.
|
||||||
if (input_mode == 1)
|
if (input_mode)
|
||||||
term.c_lflag &= ~(ISIG) & ~(ECHO);
|
term.c_lflag &= ~(ISIG) & ~(ECHO);
|
||||||
else
|
else
|
||||||
term.c_lflag |= ISIG | ECHO;
|
term.c_lflag |= ISIG | ECHO;
|
||||||
|
|
|
||||||
|
|
@ -28,22 +28,18 @@ int main(void)
|
||||||
if (ft_interactive_sh(&data))
|
if (ft_interactive_sh(&data))
|
||||||
return (1);
|
return (1);
|
||||||
ft_printf("got command:'%s'\n", data.input);
|
ft_printf("got command:'%s'\n", data.input);
|
||||||
/* if (ft_tokenize(&token, data.history->prev->content)) */
|
if (ft_tokenize(&token, data.input, DEFAULT))
|
||||||
/* return (1); */
|
return (1);
|
||||||
/* token_print(token); */
|
token_print(token);
|
||||||
/* (void)ast; */
|
if (ft_parse(&ast, token))
|
||||||
/* if (ft_parse(&ast, token)) */
|
return (1);
|
||||||
/* return (1); */
|
btree_print(ast, &tree_type);
|
||||||
/* btree_print(ast, &tree_type); */
|
ft_printf("root: %i\n", ((t_astnode*)ast->item)->type);
|
||||||
/* ft_printf("root: %i\n", ((t_astnode*)ast->item)->type); */
|
ft_lstdel(&token, &token_free);
|
||||||
/* ft_lstdel(&token, &token_free); */
|
|
||||||
token = NULL;
|
token = NULL;
|
||||||
/* if (ft_exec(ast)) */
|
/* if (ft_exec(ast)) */
|
||||||
/* return (1); */
|
/* return (1); */
|
||||||
|
|
||||||
/* char **av = ft_cmd_getav(data.history->prev->content); */
|
|
||||||
/* if (av && av[0]) */
|
|
||||||
/* ft_cmd_process(av, &data.env); */
|
|
||||||
}
|
}
|
||||||
return (0);
|
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[] =
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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)
|
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