diff --git a/include/include.h b/include/include.h index 47104c6..338de2b 100644 --- a/include/include.h +++ b/include/include.h @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ -/* Updated: 2024/04/26 14:21:43 by mcolonna ### ########.fr */ +/* Updated: 2024/04/29 15:48:25 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -46,7 +46,7 @@ typedef struct s_call // Represents a command given by the user. typedef struct s_command { - bool error; // true if an error occured in interpret_command(). + int error; // 0 if parse_command() succeded, error status if not const t_call *calls; // all calls to programs (ended by .program == NULL) int input_fd; // fd to use with '<' redirection (0 by default) int output_fd; // fd to use with '>' redirection (1 by default) @@ -65,10 +65,10 @@ int execute_command(t_memclass mc, t_command command, ///// ERROR ///// // Call to show an error. -// If msg == "errno", use strerror(errno) +// If msg == "errno", use perror() void minishell_error(const char *msg); -// Call to write the error and exit the program. +// Call perror() and exit the program. void fatal_error(const char *msg); ///// PATH ///// @@ -82,4 +82,7 @@ char **get_path(char *const envp[]); const char *search_path( const t_memclass mc, const char **path, const char *prog); +///// MAIN ///// +extern t_memclass g_mc; + #endif diff --git a/src/ask_command.c b/src/ask_command.c index 66c1cd2..5652910 100644 --- a/src/ask_command.c +++ b/src/ask_command.c @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 15:03:23 by mcolonna #+# #+# */ -/* Updated: 2024/04/24 13:19:42 by mcolonna ### ########.fr */ +/* Updated: 2024/04/29 15:11:06 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,8 +16,8 @@ const char *ask_command(const t_memclass mc) { const char *r; - print_str(minishell_error, 1, "( ^.^)> "); - r = read_line(minishell_error, mc, 0); + print_str(fatal_error, 1, "( ^.^)> "); + r = read_line(fatal_error, mc, 0); if (r) return (r); else diff --git a/src/error.c b/src/error.c index 4316050..ac0246b 100644 --- a/src/error.c +++ b/src/error.c @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 15:51:56 by mcolonna #+# #+# */ -/* Updated: 2024/04/25 13:41:57 by mcolonna ### ########.fr */ +/* Updated: 2024/04/29 15:39:56 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,16 +15,19 @@ void minishell_error(const char *msg) { if (str_eq(msg, "errno")) - msg = strerror(errno); - print_str(err_remember, 2, "minishell: "); - print_str(err_remember, 2, msg); - err_get(); + perror("minishell"); + else + { + print_str(err_remember, 2, "minishell: "); + print_line(err_remember, 2, msg); + err_get(); + } } -// TODO adapt for msg == errno void fatal_error(const char *msg) { - print_str(err_remember, 2, "Fatal error: "); - print_line(err_remember, 2, msg); - exit(1); + (void)msg; + minishell_error("errno"); + mem_freeall(g_mc); + exit(errno); } diff --git a/src/main.c b/src/main.c index 1c8448b..944584b 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:33:45 by mcolonna #+# #+# */ -/* Updated: 2024/04/26 14:11:46 by mcolonna ### ########.fr */ +/* Updated: 2024/04/29 15:40:08 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,7 +15,7 @@ // Clean the screen static void execclear(char *const envp[]) { - const t_memclass mc = mem_newclass(fatal_error); + const t_memclass mc = mem_subclass(fatal_error, g_mc); t_command command; command = parse_command(mc, "clear"); @@ -51,9 +51,10 @@ static void print_hi(void) printf("|_____________________________________________|\n\n"); } +t_memclass g_mc; + int main(const int argc, const char *argv[], char *const envp[]) { - char **const path = get_path(envp); t_memclass mc; const char *command_str; t_command command; @@ -61,14 +62,14 @@ int main(const int argc, const char *argv[], char *const envp[]) (void)argc; (void)argv; - (void)path; - (void)command; + g_mc = NULL; + g_mc = mem_newclass(fatal_error); execclear(envp); print_hi(); errorstatus = 0; while (true) { - mc = mem_newclass(minishell_error); + mc = mem_subclass(fatal_error, g_mc); command_str = ask_command(mc); command = parse_command(mc, command_str); if (command.error) diff --git a/src/parse_command.c b/src/parse_command.c index 0370d36..8233fa2 100644 --- a/src/parse_command.c +++ b/src/parse_command.c @@ -6,17 +6,18 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ -/* Updated: 2024/04/25 17:58:54 by mcolonna ### ########.fr */ +/* Updated: 2024/04/29 15:48:43 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" -// To call when a parse error occurs (TODO) -static void parse_error(const char *msg) +// To call when a parse error occurs. +// Always returns 1 (parse error's status). +static int parse_error(void) { - (void)msg; - fatal_error("parse error"); + minishell_error("parse error"); + return (1); } // Global variables for all the parsing functions @@ -62,7 +63,7 @@ static const char *get_string(t_parsing_args *args, const char *stop_charset) } // Get a program call (program names & its arguments) until stop_charset. -static void get_call(t_parsing_args *args, const char *stop_charset) +static int get_call(t_parsing_args *args, const char *stop_charset) { t_call *r; t_list arguments; @@ -76,57 +77,69 @@ static void get_call(t_parsing_args *args, const char *stop_charset) skip_blank(&args->stream); } r = mem_alloc(fatal_error, args->mc, sizeof(t_call)); - r->program = (char *)list_get(parse_error, &arguments, 0); + r->program = (char *)list_get(err_remember, &arguments, 0); + if (err_get()) + return (parse_error()); r->argc = list_getsize(&arguments); r->argv = (char *const *)list_convert( fatal_error, args->mc, &arguments); list_add(fatal_error, &args->calls, (t_call *)r); args->got_first_call = true; + return (0); } // Read an element (a call to a program, a '< FILE' or a '> FILE') +// On success, return 0. On error, return the error status. // (TODO redirections) -static void get_element(t_parsing_args *args) +static int get_element(t_parsing_args *args) { char c; + int error; - while (stream_read(&args->stream)) + error = 0; + while (!error && stream_read(&args->stream)) { c = stream_read(&args->stream); if (c == '|') { if (!args->got_first_call) - parse_error(NULL); + return (parse_error()); stream_pop(&args->stream); skip_blank(&args->stream); - get_call(args, "<>|"); + error = get_call(args, "<>|"); } else if (!args->got_first_call) - get_call(args, "<>|"); + error = get_call(args, "<>|"); else - parse_error(NULL); + return (parse_error()); skip_blank(&args->stream); } + return (error); } t_command parse_command(const t_memclass mc, const char *command) { t_parsing_args args; + int error; + error = 0; args.mc = mc; - args.r.error = false; + args.r.error = 0; args.r.input_fd = 0; args.r.output_fd = 1; args.calls = list_createempty(mc); args.got_first_call = false; streamstr_init(&args.stream, command); skip_blank(&args.stream); - while (stream_read(&args.stream)) + while (!error && stream_read(&args.stream)) { - get_element(&args); + error = get_element(&args); skip_blank(&args.stream); } - args.r.calls = (t_call *)list_convert_type( - fatal_error, args.mc, &args.calls, sizeof(t_call)); + if (!error) + args.r.calls = (t_call *)list_convert_type( + fatal_error, args.mc, &args.calls, sizeof(t_call)); + if (error) + args.r.error = error; return (args.r); }