Commit f6a16e76 authored by pêle-mêle's avatar pêle-mêle
Browse files

new parsing wip

parent 75617583
......@@ -8,18 +8,18 @@ SRC += main.c
SRC += signal_handling.c
SRC += parse_input.c
SRC += parse_utils.c
SRC += prepare_args.c
#SRC += prepare_args.c
#SRC += test.c #alternative to prepare_args.c
SRC += launch_command.c
SRC += options.c
SRC += ft_echo.c
SRC += ft_pwd.c
SRC += ft_cd.c
#SRC += launch_command.c
#SRC += options.c
#SRC += ft_echo.c
#SRC += ft_pwd.c
#SRC += ft_cd.c
SRC += var_utils.c
SRC += ft_export.c
SRC += ft_unset.c
SRC += ft_env.c
#SRC += ft_unset.c
#SRC += ft_env.c
SRC += ft_exit.c
......
......@@ -93,7 +93,6 @@ typedef struct s_xe
int stat_loc;
char **env;
char **exported;
t_list *commands;
} t_xe;
......
......@@ -9,14 +9,11 @@ enum e_state
{
SPACE,
LETTER,
QUOTE,
// QUOTE,
BACKSLASH,
DOLLAR,
TILDE,
ANGLE_BRACKET,
SEMICOLON,
PIPE,
//METACHAR, // a la place des n precedents
// DOLLAR,
// TILDE,
// ANGLE_BRACKET,
END,
NB_STATES
};
......@@ -35,20 +32,22 @@ enum e_parsing_error
typedef struct s_state_machine
{
enum e_state state;
enum e_parsing_error error;
char buf[BUF_SIZE];
size_t len;
t_token *cur_token;
} t_state_machine;
char buf[BUF_SIZE];
size_t len;
char **args;
char *cur_arg;
enum e_state state;
t_byte pipe_flag;
uint8_t pad[3];
} t_state_machine;
typedef char *(*t_parse)(char *, t_list **, t_state_machine *);
typedef char *(*t_parse)(t_state_machine *, char *);
/*
** main function
*/
int parse_input(char *line, t_list **commands);
char **parse_one_command(char **line, t_byte *pipe_flag);
/*
** utils
......@@ -57,8 +56,8 @@ int parse_input(char *line, t_list **commands);
int new_command(t_list **commands);
int add_variable(t_list **var_list, size_t start, size_t len, t_byte split_flag);
char *parse_variable(char *line, t_state_machine *machine, t_byte split_flag);
int link_token(t_list **tokens, t_state_machine *machine);
int add_arg(t_state_machine *machine);
int reset_buf(t_state_machine *machine);
int add_to_buf(char c, t_state_machine *machine);
int add_to_buf(t_state_machine *machine, char c);
#endif
......@@ -6,7 +6,7 @@
# By: mvidal-a <marvin@42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2019/12/23 13:17:34 by mvidal-a #+# #+# #
# Updated: 2020/12/26 23:01:48 by mvidal-a ### ########.fr #
# Updated: 2021/01/09 18:32:21 by mvidal-a ### ########.fr #
# #
# **************************************************************************** #
......@@ -71,6 +71,7 @@ SRCS_CUSTOM += rm_str_from_array.c
SRCS_CUSTOM += sort_str_array.c
SRCS_CUSTOM += ft_lstshift.c
SRCS_CUSTOM += ft_swap.c
SRCS_CUSTOM += strjoin_free.c
VPATH = part_1:part_2:bonus:custom
......
......@@ -6,7 +6,7 @@
/* By: mvidal-a <mvidal-a@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/12/22 12:48:07 by mvidal-a #+# #+# */
/* Updated: 2020/12/26 02:16:29 by mvidal-a ### ########.fr */
/* Updated: 2021/01/09 18:45:23 by mvidal-a ### ########.fr */
/* */
/* ************************************************************************** */
......@@ -19,6 +19,8 @@ char **push_str_to_array(char **array, char *str)
char **new_array;
size_t i;
if (str == NULL)
return (NULL);
array_size = ft_arraylen(array);
new_array = (char **)malloc(sizeof(char *) * (array_size + 2));
if (new_array == NULL)
......@@ -29,7 +31,7 @@ char **push_str_to_array(char **array, char *str)
new_array[i] = array[i];
i++;
}
new_array[i] = ft_strdup(str);
new_array[i] = str;
new_array[i + 1] = NULL;
free(array);
return (new_array);
......
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* strjoin_free.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: mvidal-a <mvidal-a@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2021/01/09 18:31:27 by mvidal-a #+# #+# */
/* Updated: 2021/01/10 00:34:08 by mvidal-a ### ########.fr */
/* */
/* ************************************************************************** */
#include <stdlib.h>
#include "libft.h"
char *strjoin_free(char *s1, char const *s2)
{
char *join;
join = ft_strjoin(s1, s2);
free(s1);
return (join);
}
......@@ -6,7 +6,7 @@
/* By: mvidal-a <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2019/11/04 12:29:06 by mvidal-a #+# #+# */
/* Updated: 2020/12/27 14:57:35 by mvidal-a ### ########.fr */
/* Updated: 2021/01/10 00:34:26 by mvidal-a ### ########.fr */
/* */
/* ************************************************************************** */
......@@ -114,5 +114,6 @@ void sort_str_array(char **array);
void *ft_lstshift(t_list **lst);
void ft_swap(void **a, void **b);
char *strjoin_free(char *s1, char const *s2);
#endif
......@@ -21,7 +21,7 @@ parsing errors
command loop (semicolon) -> dans handle_commands?
SHLVL
ajouter des errno = 0;?
quit apres une erreur de parsing? (fonction error())
par exemple export d=\
......
......@@ -79,7 +79,7 @@ static int ft_env_append_from_exp(char *var, t_xe *xe, ssize_t equalsign_pos)
ft_memcpy(new_var, var, equalsign_pos - 1);
ft_strlcpy(new_var + equalsign_pos - 1,
var + equalsign_pos, ft_strlen(var));
new_array = push_str_to_array(xe->env, new_var);
new_array = push_str_to_array(xe->env, ft_strdup(new_var));
if (new_array == NULL)
return (MALLOC_ERR);
free(new_var);
......@@ -122,7 +122,7 @@ static int ft_env_set_from_exp(char *var, t_xe *xe, ssize_t equalsign_pos)
return (MALLOC_ERR);
xe->exported = new_array;
}
new_array = push_str_to_array(xe->env, var);
new_array = push_str_to_array(xe->env, ft_strdup(var));
if (new_array == NULL)
return (MALLOC_ERR);
xe->env = new_array;
......@@ -171,7 +171,7 @@ static int ft_exported_export(char *var, t_xe *xe)
if (get_var_pos(xe->env, var, ft_strlen(var)) == NOT_FOUND
&& get_var_pos(xe->exported, var, ft_strlen(var)) == NOT_FOUND)
{
new_array = push_str_to_array(xe->exported, var);
new_array = push_str_to_array(xe->exported, ft_strdup(var));
if (new_array == NULL)
return (MALLOC_ERR);
xe->exported = new_array;
......
......@@ -122,7 +122,7 @@ int execute_cmd(char **args, t_xe *xe)
{
int i;
int ret;
enum e_cmd_code cmd_code;
enum e_cmd_code cmd_code;
const t_exec command[8] = {ft_echo, ft_cd, ft_pwd,
ft_export, ft_unset, ft_env,
launch_exit, launch_ext};
......
......@@ -7,9 +7,8 @@
#include <sys/types.h> // waitpid
#include <sys/wait.h> // waitpid
static int get_input(t_list **commands)
static int get_input(char **line)
{
char *line;
int ret;
if (isatty(STDIN_FILENO)) // temp pour le testeur
......@@ -17,132 +16,151 @@ static int get_input(t_list **commands)
if (ft_putstr_fd(FT_PS1, STDOUT_FILENO) == ERROR)
return (WRITE_ERR);
}
ret = get_next_line(STDIN_FILENO, &line);
ret = get_next_line(STDIN_FILENO, line);
if (ret == ERROR)
return (GNL_ERR);
else if (ret == 0) // EOF in files and heredocs (noeol files not yet supported)
{
free(line);
free(*line);
return (CLEAN_EXIT);
}
ret = parse_input(line, commands);
free(line);
return (ret);
}
int handle_execution(t_xe *xe, int fd_in, int proc)
{
int i;
int fd[2];
int ret;
char **args;
t_command *cur_command;
//int handle_execution(t_xe *xe, int fd_in, int proc)
//{
// int i;
// int fd[2];
// int ret;
// char **args;
// t_command *cur_command;
//
// ret = SUCCESS;
// xe->gpid = -1;
// cur_command = NULL;
//// if (xe->commands != NULL)
//// cur_command = ft_lstshift(&(xe->commands));
// if (cur_command != NULL) // le contraire possible?
// {
// if (((t_list *)cur_command->tokens) == NULL)
// {
// free_command(cur_command);
// // cur_command = ft_lstshift(&(xe->commands));
// // il faudrait plutôt partir sur une recursion ici
// dup2(xe->backup_stdout, STDOUT_FILENO);
// dup2(xe->backup_stdin, STDIN_FILENO);
// return (SUCCESS);
// }
// else if (cur_command->pipe_flag == TRUE)
// {
// pipe(fd);// error?
// xe->gpid = fork();// error?
// if (xe->gpid == 0)
// {
// //xe->child = 1;
// signal(SIGINT, SIG_DFL);
// signal(SIGQUIT, SIG_DFL);
// close(fd[0]);// error
// // dup2(fd_in, STDIN_FILENO);
// if (fd_in != STDIN_FILENO)
// {
// if (dup2(fd_in, STDIN_FILENO) != -1)
// close(fd_in);
// }
// // dup2(fd[1], STDOUT_FILENO);
// if (dup2(fd[1], STDOUT_FILENO) != -1)// error
// close(fd[1]);
// //dprintf(xe->backup_stdout, "list: child = %s\n", ((t_token *)((t_list *)cur_command->tokens)->content)->str);
// args = prepare_args(cur_command, xe->env, xe->stat_loc);// error
// //dprintf(xe->backup_stdout, "args0: child = %s\n", args[0]);
// //dprintf(xe->backup_stdout, "args1: child = %s\n", args[1]);
// ret = execute_cmd(args, xe);// error
// return (CLEAN_EXIT);
// }
// else
// {
// //xe->child = 0;
// close(fd[1]);// error
// close(fd_in);
// free_command(cur_command);
///*
// cur_command = ft_lstshift(&(xe->commands));
// if (cur_command == NULL)
// return (MALLOC_ERR);
// //dprintf(xe->backup_stdout, "list: parent = %s\n", ((t_token *)((t_list *)cur_command->tokens)->content)->str);
// args = prepare_args(cur_command, xe->env, xe->stat_loc);// error
// //dprintf(xe->backup_stdout, "args0: parent = %s\n", args[0]);
// //dprintf(xe->backup_stdout, "args1: parent = %s\n", args[1]);
// ret = execute_cmd(args, xe);// error
// close(fd[0]);
// dup2(xe->backup_stdout, STDOUT_FILENO);
// dup2(xe->backup_stdin, STDIN_FILENO);
// return (ret);
//*/
// return (handle_execution(xe, fd[0], proc + 1));
// }
// }
// else
// {
// if (fd_in != STDIN_FILENO)
// {
// if (dup2(fd_in, STDIN_FILENO) != -1)
// close(fd_in);
// }
// args = prepare_args(cur_command, xe->env, xe->stat_loc);// error
// ret = execute_cmd(args, xe);// error
// dup2(xe->backup_stdout, STDOUT_FILENO);
// dup2(xe->backup_stdin, STDIN_FILENO);
// i = 0;
// while (i < proc)
// {
// wait(NULL);
// i++;
// }
// if (ret == SUCCESS)
// return (handle_execution(xe, STDIN_FILENO, 0));
// else
// return (ret);
// }
// }
// else
// {
// dup2(xe->backup_stdout, STDOUT_FILENO);
// dup2(xe->backup_stdin, STDIN_FILENO);
// return (SUCCESS);
// }
//}
ret = SUCCESS;
xe->gpid = -1;
cur_command = NULL;
if (xe->commands != NULL)
cur_command = ft_lstshift(&(xe->commands));
if (cur_command != NULL) // le contraire possible?
{
if (((t_list *)cur_command->tokens) == NULL)
{
free_command(cur_command);
// cur_command = ft_lstshift(&(xe->commands));
// il faudrait plutôt partir sur une recursion ici
dup2(xe->backup_stdout, STDOUT_FILENO);
dup2(xe->backup_stdin, STDIN_FILENO);
return (SUCCESS);
}
else if (cur_command->pipe_flag == TRUE)
{
pipe(fd);// error?
xe->gpid = fork();// error?
if (xe->gpid == 0)
{
//xe->child = 1;
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
close(fd[0]);// error
// dup2(fd_in, STDIN_FILENO);
if (fd_in != STDIN_FILENO)
{
if (dup2(fd_in, STDIN_FILENO) != -1)
close(fd_in);
}
// dup2(fd[1], STDOUT_FILENO);
if (dup2(fd[1], STDOUT_FILENO) != -1)// error
close(fd[1]);
//dprintf(xe->backup_stdout, "list: child = %s\n", ((t_token *)((t_list *)cur_command->tokens)->content)->str);
args = prepare_args(cur_command, xe->env, xe->stat_loc);// error
//dprintf(xe->backup_stdout, "args0: child = %s\n", args[0]);
//dprintf(xe->backup_stdout, "args1: child = %s\n", args[1]);
ret = execute_cmd(args, xe);// error
return (CLEAN_EXIT);
}
else
{
//xe->child = 0;
close(fd[1]);// error
close(fd_in);
free_command(cur_command);
/*
cur_command = ft_lstshift(&(xe->commands));
if (cur_command == NULL)
return (MALLOC_ERR);
//dprintf(xe->backup_stdout, "list: parent = %s\n", ((t_token *)((t_list *)cur_command->tokens)->content)->str);
args = prepare_args(cur_command, xe->env, xe->stat_loc);// error
//dprintf(xe->backup_stdout, "args0: parent = %s\n", args[0]);
//dprintf(xe->backup_stdout, "args1: parent = %s\n", args[1]);
ret = execute_cmd(args, xe);// error
close(fd[0]);
dup2(xe->backup_stdout, STDOUT_FILENO);
dup2(xe->backup_stdin, STDIN_FILENO);
return (ret);
*/
return (handle_execution(xe, fd[0], proc + 1));
}
}
else
{
if (fd_in != STDIN_FILENO)
{
if (dup2(fd_in, STDIN_FILENO) != -1)
close(fd_in);
}
args = prepare_args(cur_command, xe->env, xe->stat_loc);// error
ret = execute_cmd(args, xe);// error
dup2(xe->backup_stdout, STDOUT_FILENO);
dup2(xe->backup_stdin, STDIN_FILENO);
i = 0;
while (i < proc)
{
wait(NULL);
i++;
}
if (ret == SUCCESS)
return (handle_execution(xe, STDIN_FILENO, 0));
else
return (ret);
}
}
else
{
dup2(xe->backup_stdout, STDOUT_FILENO);
dup2(xe->backup_stdin, STDIN_FILENO);
return (SUCCESS);
}
int empty_command(char *line)
{
while (ft_isspace(*line))
line++;
if (*line == '\0')
return (TRUE);
return (FALSE);
}
static int main_loop(t_xe *xe)
{
int ret;
char *line;
char **args;
t_byte pipe_flag;
ret = get_input(&xe->commands);
ret = get_input(&line);
if (ret == SUCCESS)
ret = handle_execution(xe, STDIN_FILENO, 0);
else if (ret == PARSING_ERR)
ret = SUCCESS;
{
//check_syntax(line);
while (empty_command(line) == FALSE)
{
args = parse_one_command(&line, &pipe_flag);
if (args == NULL)
return (MALLOC_ERR);
(void)xe;
//ret = handle_execution(xe, args, STDIN_FILENO, 0);
}
free(line);
}
return (ret);
}
......@@ -171,8 +189,6 @@ int main(int argc, char **argv, char **env_source)
ret = SUCCESS;
xe = (t_xe *)malloc(sizeof(t_xe));
ft_bzero(xe, sizeof(t_xe));
xe->backup_stdin = dup(STDIN_FILENO);
xe->backup_stdout = dup(STDOUT_FILENO);
if (xe == NULL)
ret = MALLOC_ERR;
else if (argc != 1)
......@@ -182,6 +198,8 @@ int main(int argc, char **argv, char **env_source)
}
else
{
xe->backup_stdin = dup(STDIN_FILENO);
xe->backup_stdout = dup(STDOUT_FILENO);
signal_handler(); // err?
exec_env_init(xe, env_source);
if (xe->env == NULL)
......
#include "parsing.h"
int parsing_error(t_list **commands, t_state_machine *machine)
{
static char *err_msg[NB_PARSING_ERRORS] = {
"=== no error (here for padding) ===",
"No matching single quote",
"No matching double quote",
"Multiline inputs are currently not supported",
"Redirection path invalid",
"No redirection path specified",
"Empty command before ; or |"};
ft_putstr_fd("minishell: syntax error: ", STDERR_FILENO);
ft_putstr_fd(err_msg[machine->error], STDERR_FILENO);
ft_putchar_fd('\n', STDERR_FILENO);
if (machine->cur_token != NULL)
{
free_token(machine->cur_token);
free_commands(commands);
}
else
*commands = NULL;/////// no need to free?
return (PARSING_ERR);
}
char *space(char *line, t_list **commands, t_state_machine *machine)
{
(void)commands;
if (*line == '\0')
machine->state = END;
else if (ft_isspace(*line))
line++;
else if (*line == '>' || *line == '<')
machine->state = ANGLE_BRACKET;
else if (*line == ';')
machine->state = SEMICOLON;
else if (*line == '|')
machine->state = PIPE;
else
machine->state = LETTER;
return (line);
}
//int parsing_error(t_list **commands, t_state_machine *machine)
//{
// static char *err_msg[NB_PARSING_ERRORS] = {
// "=== no error (here for padding) ===",
// "No matching single quote",
// "No matching double quote",
// "Multiline inputs are currently not supported",
// "Redirection path invalid",
// "No redirection path specified",
// "Empty command before ; or |"};
//
// ft_putstr_fd("minishell: syntax error: ", STDERR_FILENO);
// ft_putstr_fd(err_msg[machine->error], STDERR_FILENO);
// ft_putchar_fd('\n', STDERR_FILENO);
// if (machine->cur_token != NULL)
// {
// free_token(machine->cur_token);
// free_commands(commands);
// }
// else
// *commands = NULL;/////// no need to free?
// return (PARSING_ERR);
//}
//
//char *dollar(t_state_machine *machine, char *line)
//{
// line++;
// if (*line == '"' || *line == '\'')
// machine->state = QUOTE;
// else if (*line == '?' || ft_isalnum(*line) || *line == '_')
// {
// line = parse_variable(line, machine, TO_SPLIT);
// if (line == NULL)
// return (NULL);
// machine->state = LETTER;
// }
// else
// {
// add_to_buf(machine, '$');
// machine->state = LETTER;
// }
// return (line);
//}
//
//char *quote(t_state_machine *machine, char *line)
//{
// char quote_style;
//
// (void)commands;
// quote_style = *line;
// line++;
// while (*line != quote_style && *line != '\0')
// {
// if (quote_style == '"' && *line == '$')
// {
// line++;
// if (*line == '?' || ft_isalnum(*line) || *line == '_')
// {
// line = parse_variable(line, machine, NOT_TO_SPLIT);
// if (line == NULL)
// return (NULL);
// }
// else
// add_to_buf(machine, '$');
// }
// else
// {
// if (quote_style == '"' && *line == '\\'
// && ft_isset(line[1], "\\\"$"))
// line++;
// add_to_buf(machine, *line);
// line++;
// }
// }
// if (*line == '\0')
// machine->error = ft_index("'\"", quote_style);