From 147743058dd7bf98d0c36cfd82452ec62de92a19 Mon Sep 17 00:00:00 2001 From: mcolonna Date: Mon, 1 Jul 2024 11:23:31 +0200 Subject: [PATCH 1/5] norm --- include/main.h | 12 ++++++------ include/parse_command.h | 21 ++++++++++----------- src/parse_command_utils.h | 16 ++++++++-------- src/variables.c | 8 +++++--- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/include/main.h b/include/main.h index 80a8769..23d6552 100644 --- a/include/main.h +++ b/include/main.h @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ -/* Updated: 2024/06/28 14:01:25 by mcolonna ### ########.fr */ +/* Updated: 2024/07/01 11:12:51 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,11 +17,11 @@ typedef struct s_env { - t_memclass mc_global; // open during all the runtime - t_memclass mc_command; // open during the execution of a command - int errorstatus; // Error status of the last executed command - t_list *variables; // Shell variables - bool exit; // Set to true to exit minishell + t_memclass mc_global; + t_memclass mc_command; + int errorstatus; + t_list *variables; + bool exit; } t_env; #endif diff --git a/include/parse_command.h b/include/parse_command.h index ded1531..e81c21f 100644 --- a/include/parse_command.h +++ b/include/parse_command.h @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ -/* Updated: 2024/06/27 13:47:56 by mcolonna ### ########.fr */ +/* Updated: 2024/07/01 11:16:02 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,26 +18,25 @@ // Represents a call to a program (the program name and its arguments) typedef struct s_call { - const char *program; // path of the program to call. - int argc; // number of arguments given - char *const *argv; // arguments given (ended by NULL) - // (argc and argv must include the program name) + const char *program; + int argc; + char *const *argv; } t_call; // Represents a command given by the user. typedef struct s_command { - int error; // 0 if parse_command() succeded, error status if not - bool empty; // true if there isn't anything to do - 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) + int error; + bool empty; + const t_call *calls; + int input_fd; + int output_fd; } t_command; // An element of a list of pipes typedef struct s_pipes { - int pipe[2]; // Simple pipe, we write on pipe[1] and we read on pipe[0] + int pipe[2]; } t_pipes; // Return the t_command representing the command given by the user. diff --git a/src/parse_command_utils.h b/src/parse_command_utils.h index e622f0b..368d0f9 100644 --- a/src/parse_command_utils.h +++ b/src/parse_command_utils.h @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ -/* Updated: 2024/06/27 14:47:14 by mcolonna ### ########.fr */ +/* Updated: 2024/07/01 11:15:33 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,13 +20,13 @@ // Global variables for all the parsing functions typedef struct s_parsing_args { - t_memclass mc; // mc freed given to parse_command - t_command r; // t_command that parse_command will return - t_stream stream; // stream reading the command string - t_list calls; // list of calls - bool got_first_call; // already got at least the first program call? - const char *heredoc; // EOF line for heredoc. NULL if no heredoc - t_list *variables; // list of current variables + t_memclass mc; + t_command r; + t_stream stream; + t_list calls; + bool got_first_call; + const char *heredoc; + t_list *variables; t_env *env; } t_parsing_args; diff --git a/src/variables.c b/src/variables.c index 53142f9..f2d4adb 100644 --- a/src/variables.c +++ b/src/variables.c @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ -/* Updated: 2024/06/28 14:33:14 by mcolonna ### ########.fr */ +/* Updated: 2024/07/01 13:38:03 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,8 +15,10 @@ void variables_set(t_list *variables, const char *name, const char *value) { - variables_find(variables, name)->value = ( - str_dup(fatal_error, variables->mc, value)); + t_variable *var; + + var = variables_find(variables, name); + var->value = str_dup(fatal_error, variables->mc, value); } const char *variables_get(t_list *variables, const char *name) From c637b5f382cf6b8c6f30ad3db9f7a3f5523972db Mon Sep 17 00:00:00 2001 From: mcolonna Date: Mon, 1 Jul 2024 13:46:55 +0200 Subject: [PATCH 2/5] fix: builtins and pipes * also: dev: add dev/nocluster.sh --- Makefile | 6 +++--- dev/nocluster.sh | 3 +++ src/builtin.c | 18 +++++++++--------- src/exec_command.c | 18 +++++++++--------- 4 files changed, 24 insertions(+), 21 deletions(-) create mode 100755 dev/nocluster.sh diff --git a/Makefile b/Makefile index 027cebd..3e2fe8e 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ LIBRARIES_LINK = # to use with the flag -l LINK = # flags to add to the compiler -MORE_FLAGS += $(addprefix -L,$(LIBRARIES_LINK)) $(addprefix -l,$(LIBRARIES_LINK) $(LINK)) $(addprefix -I,$(INCLUDES)) +MORE_FLAGSS = $(MORE_FLAGS) $(addprefix -L,$(LIBRARIES_LINK)) $(addprefix -l,$(LIBRARIES_LINK) $(LINK)) $(addprefix -I,$(INCLUDES)) ##### END OF THE INTERESTING PART ##### @@ -55,7 +55,7 @@ debug : $(NAME) : $(O_FILES) $(LIBRARIES) @echo "\e[30;47;1m $(NAME): linking... \e[0m" - $(CC) -lreadline -o $(NAME) $(O_FILES) $(LIBRARIES_FILES) $(MORE_FLAGS) + $(CC) -lreadline -o $(NAME) $(O_FILES) $(LIBRARIES_FILES) $(MORE_FLAGSS) @echo "\e[30;47;1m $(NAME): linked! \e[0m" $(LIBRARIES) : @@ -68,6 +68,6 @@ endif @echo "\e[30;47;1m $(NAME): library $@ made! \e[0m" %.o : %.c - $(CC) -c $< -o $@ $(MORE_FLAGS) + $(CC) -c $< -o $@ $(MORE_FLAGSS) .PHONY : all debug clean fclean re $(LIBRARIES) diff --git a/dev/nocluster.sh b/dev/nocluster.sh new file mode 100755 index 0000000..85142f7 --- /dev/null +++ b/dev/nocluster.sh @@ -0,0 +1,3 @@ +# call this file with "source dev/nocluster.sh" + +alias makee="make MORE_FLAGS=\"-lreadline\"" diff --git a/src/builtin.c b/src/builtin.c index 8d45b7a..21f51fb 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/03 12:02:45 by jschaft #+# #+# */ -/* Updated: 2024/06/28 15:30:51 by mcolonna ### ########.fr */ +/* Updated: 2024/07/01 12:35:09 by jschaft ### ########.fr */ /* */ /* ************************************************************************** */ @@ -82,18 +82,18 @@ static int env_builtin(t_env *env, t_call call) int exec_builtin(t_env *env, t_call call) { if (ft_strncmp(call.program, "cd", 3) == 0) - return (cd_builtin(env, call)); + exit (cd_builtin(env, call)); if (ft_strncmp(call.program, "exit", 5) == 0) - return (exit_builtin(env, call)); + exit (exit_builtin(env, call)); if (ft_strncmp(call.program, "export", 7) == 0) - return (export_builtin(env, call)); + exit (export_builtin(env, call)); if (ft_strncmp(call.program, "unset", 6) == 0) - return (unset_builtin(env, call)); + exit (unset_builtin(env, call)); if (ft_strncmp(call.program, "pwd", 4) == 0) - return (pwd_builtin(env, call)); + exit (pwd_builtin(env, call)); if (ft_strncmp(call.program, "echo", 5) == 0) - return (echo_builtin(env, call)); + exit (echo_builtin(env, call)); if (ft_strncmp(call.program, "env", 4) == 0) - return (env_builtin(env, call)); - return (1); + exit (env_builtin(env, call)); + exit (1); } diff --git a/src/exec_command.c b/src/exec_command.c index 37e2d66..d050a18 100644 --- a/src/exec_command.c +++ b/src/exec_command.c @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:48:00 by jschaft #+# #+# */ -/* Updated: 2024/06/28 16:08:02 by mcolonna ### ########.fr */ +/* Updated: 2024/07/01 12:36:03 by jschaft ### ########.fr */ /* */ /* ************************************************************************** */ @@ -40,8 +40,8 @@ static void close_all_pipes(t_exec_command_global *global) // If the program wasn't to found in $PATH, or the fork didn't work, // write the error and return the error status. static int execute_call( - t_exec_command_global *global, t_call call, const int inout[2], - char *const envp[]) + t_exec_command_global *global, t_call call, + const int inout[2], char *const envp[]) { pid_t pid; const char *program_path; @@ -60,7 +60,10 @@ static int execute_call( if (dup2(inout[0], 0) < 0 || dup2(inout[1], 1) < 0) return (minishell_error("errno"), errno); close_all_pipes(global); - execve(program_path, call.argv, envp); + if (is_builtin(call.program)) + exec_builtin(global->env, call); + else + execve(program_path, call.argv, envp); return (minishell_error("errno"), errno); } return (0); @@ -97,11 +100,8 @@ static int exec_each_call(t_exec_command_global *global, mc = mem_subclass(fatal_error, global->mc); inout[0] = global->pipes[i].pipe[0]; inout[1] = global->pipes[i + 1].pipe[1]; - if (is_builtin(command.calls[i].program)) - r = exec_builtin(env, command.calls[i]); - else - r = execute_call(global, command.calls[i], inout, - variables_envp(env->variables, mc)); + r = execute_call(global, command.calls[i], inout, + variables_envp(env->variables, mc)); mem_freeall(mc); if (r) return (r); From 7d38a40717b8e612bea004d1628a4ece9fc17382 Mon Sep 17 00:00:00 2001 From: mcolonna Date: Mon, 1 Jul 2024 14:33:38 +0200 Subject: [PATCH 3/5] fix: several builtins * With the fork, the builtins didn't have access to the parent process values. --- include/builtins.h | 16 ++++++++++------ src/builtin.c | 32 +++++++++++++++++--------------- src/builtin2.c | 19 +++++++++++-------- src/exec_command.c | 16 ++++++++-------- 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/include/builtins.h b/include/builtins.h index 402dd4d..c7d9d0d 100644 --- a/include/builtins.h +++ b/include/builtins.h @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/23 14:15:12 by mcolonna #+# #+# */ -/* Updated: 2024/06/28 15:26:29 by mcolonna ### ########.fr */ +/* Updated: 2024/07/01 14:10:47 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,22 +15,26 @@ # include "include.h" +// for the 'std' parameter in all these functions: +// - std[0] is stdin +// - std[1] is stdout + // Check if the command is a builtin. bool is_builtin(const char *str); // Execute the builtin command -int exec_builtin(t_env *env, t_call call); +int exec_builtin(t_env *env, t_call call, int std[2]); // Execute echo builtin -int echo_builtin(t_env *env, t_call call); +int echo_builtin(t_env *env, t_call call, int std[2]); // Execute cd builtin -int cd_builtin(t_env *env, t_call call); +int cd_builtin(t_env *env, t_call call, int std[2]); // Execute export builtin -int export_builtin(t_env *env, t_call call); +int export_builtin(t_env *env, t_call call, int std[2]); // Execute exit builtin -int exit_builtin(t_env *env, t_call call); +int exit_builtin(t_env *env, t_call call, int std[2]); #endif diff --git a/src/builtin.c b/src/builtin.c index 21f51fb..cf023a3 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -6,16 +6,17 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/03 12:02:45 by jschaft #+# #+# */ -/* Updated: 2024/07/01 12:35:09 by jschaft ### ########.fr */ +/* Updated: 2024/07/01 14:20:51 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" -static int unset_builtin(t_env *env, t_call call) +static int unset_builtin(t_env *env, t_call call, int std[2]) { int i; + (void)std; i = 0; while (call.argv[++i]) variables_unset(env->variables, call.argv[i]); @@ -39,23 +40,24 @@ bool is_builtin(const char *str) // Execute the builtin pwd for the current directory. // Return 0 for the sake of returning something for exec_builtin -static int pwd_builtin(t_env *env, t_call call) +static int pwd_builtin(t_env *env, t_call call, int std[2]) { char *str; (void)env; + (void)std; if (call.argv[1]) { print_line(fatal_error, 2, "too many arguments"); return (1); } str = getcwd(NULL, 0); - printf("%s\n", str); + print_line(fatal_error, std[1], str); free(str); return (0); } -static int env_builtin(t_env *env, t_call call) +static int env_builtin(t_env *env, t_call call, int std[2]) { int i; const t_memclass mc = mem_subclass(fatal_error, env->mc_global); @@ -69,7 +71,7 @@ static int env_builtin(t_env *env, t_call call) i = 0; while (envp[i] != NULL) { - printf("%s\n", envp[i]); + print_line(fatal_error, std[1], envp[i]); i++; } mem_freeall(mc); @@ -79,21 +81,21 @@ static int env_builtin(t_env *env, t_call call) // Execute the specified builtin. // The builtin must exist. // Return the error value returned by the builtin. -int exec_builtin(t_env *env, t_call call) +int exec_builtin(t_env *env, t_call call, int std[2]) { if (ft_strncmp(call.program, "cd", 3) == 0) - exit (cd_builtin(env, call)); + return (cd_builtin(env, call, std)); if (ft_strncmp(call.program, "exit", 5) == 0) - exit (exit_builtin(env, call)); + return (exit_builtin(env, call, std)); if (ft_strncmp(call.program, "export", 7) == 0) - exit (export_builtin(env, call)); + return (export_builtin(env, call, std)); if (ft_strncmp(call.program, "unset", 6) == 0) - exit (unset_builtin(env, call)); + return (unset_builtin(env, call, std)); if (ft_strncmp(call.program, "pwd", 4) == 0) - exit (pwd_builtin(env, call)); + return (pwd_builtin(env, call, std)); if (ft_strncmp(call.program, "echo", 5) == 0) - exit (echo_builtin(env, call)); + return (echo_builtin(env, call, std)); if (ft_strncmp(call.program, "env", 4) == 0) - exit (env_builtin(env, call)); - exit (1); + return (env_builtin(env, call, std)); + return (1); } diff --git a/src/builtin2.c b/src/builtin2.c index 02f9373..abe9df3 100644 --- a/src/builtin2.c +++ b/src/builtin2.c @@ -6,13 +6,13 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/25 13:28:29 by jschaft #+# #+# */ -/* Updated: 2024/06/28 15:30:55 by mcolonna ### ########.fr */ +/* Updated: 2024/07/01 14:18:19 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" -int export_builtin(t_env *env, t_call call) +int export_builtin(t_env *env, t_call call, int std[2]) { int i; char *name; @@ -20,6 +20,7 @@ int export_builtin(t_env *env, t_call call) char **splitted; const t_memclass mc = mem_subclass(fatal_error, env->mc_global); + (void)std; i = 0; while (call.argv[++i]) { @@ -40,10 +41,11 @@ int export_builtin(t_env *env, t_call call) return (0); } -int exit_builtin(t_env *env, t_call call) +int exit_builtin(t_env *env, t_call call, int std[2]) { int r; + (void)std; if (call.argv[1] && call.argv[2]) { print_line(fatal_error, 2, "exit: too many arguments"); @@ -63,7 +65,7 @@ int exit_builtin(t_env *env, t_call call) return (r); } -int echo_builtin(t_env *env, t_call call) +int echo_builtin(t_env *env, t_call call, int std[2]) { int i; bool newline; @@ -78,13 +80,13 @@ int echo_builtin(t_env *env, t_call call) } while (call.argv[i] != NULL) { - printf("%s", call.argv[i]); + print_str(fatal_error, std[1], call.argv[i]); if (call.argv[i + 1] != NULL) - printf(" "); + print_str(fatal_error, std[1], " "); i++; } if (newline) - printf("\n"); + print_str(fatal_error, std[1], "\n"); return (0); } @@ -95,11 +97,12 @@ static int go_home(t_env *env) // Execute the builtin cd for the specified path. // Return 0 if success, errno if error. -int cd_builtin(t_env *env, t_call call) +int cd_builtin(t_env *env, t_call call, int std[2]) { int r; int argc; + (void)std; argc = 0; while (call.argv[argc]) argc++; diff --git a/src/exec_command.c b/src/exec_command.c index d050a18..258b7ca 100644 --- a/src/exec_command.c +++ b/src/exec_command.c @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:48:00 by jschaft #+# #+# */ -/* Updated: 2024/07/01 12:36:03 by jschaft ### ########.fr */ +/* Updated: 2024/07/01 14:32:09 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,7 +35,7 @@ static void close_all_pipes(t_exec_command_global *global) // Execute a program with specific stdin and stdout: // - inout[0] is stdin -// - inout[0] is stdout +// - inout[1] is stdout // If call.program doesn't have any '/' in it, find the program in $PATH. // If the program wasn't to found in $PATH, or the fork didn't work, // write the error and return the error status. @@ -48,9 +48,11 @@ static int execute_call( program_path = search_path(global->mc, global->env->variables, call.program); - if (!program_path) + if (!program_path && !is_builtin(call.program)) return (minishell_error(str_join(fatal_error, global->mc, "command not found: ", call.program)), 127); + if (is_builtin(call.program)) + return (exec_builtin(global->env, call, (int *)inout)); pid = fork(); if (pid < 0) return (minishell_error("errno"), errno); @@ -60,10 +62,7 @@ static int execute_call( if (dup2(inout[0], 0) < 0 || dup2(inout[1], 1) < 0) return (minishell_error("errno"), errno); close_all_pipes(global); - if (is_builtin(call.program)) - exec_builtin(global->env, call); - else - execve(program_path, call.argv, envp); + execve(program_path, call.argv, envp); return (minishell_error("errno"), errno); } return (0); @@ -115,6 +114,7 @@ int execute_command(t_env *env, t_command command) int r; int wstatus; + wstatus = 0; r = 0; global.mc = env->mc_command; global.nb_calls = 0; @@ -132,7 +132,7 @@ int execute_command(t_env *env, t_command command) ; if (errno != ECHILD) return (minishell_error("errno"), errno); - if (!r) + if (WEXITSTATUS(wstatus)) r = WEXITSTATUS(wstatus); return (r); } From 6862a1913bd59e32efe204b32c58c1e547380e71 Mon Sep 17 00:00:00 2001 From: mcolonna Date: Wed, 3 Jul 2024 12:10:35 +0200 Subject: [PATCH 4/5] fix: export builtin and other things * fix: parse_command: syntaxes like: "hello"'hello'hello fix: export builtin: "NAME=VALUE" syntax fix: variables can contain digits add: variables_nameisvalid() change: dev/valgrind.sh --- Makefile | 5 +-- dev/valgrind.sh | 2 +- include/variables.h | 8 ++++- src/builtin2.c | 31 +---------------- src/export_builtin.c | 60 +++++++++++++++++++++++++++++++++ src/parse_command_read_string.c | 12 +++---- src/parse_command_utils.h | 4 +-- src/variables2.c | 24 +++++++++++++ 8 files changed, 102 insertions(+), 44 deletions(-) create mode 100644 src/export_builtin.c create mode 100644 src/variables2.c diff --git a/Makefile b/Makefile index 3e2fe8e..fbad3b2 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,9 @@ SRCS = src/ INCLUDES = include/ libtf/ libft/ # .c files in src/ without the extension CODE = main ask_command error path parse_command exec_command builtin builtin2\ - signals cool_readline variables parse_command_utils \ - parse_command_read_string parse_command_read_element variables_utils + signals cool_readline variables variables2 parse_command_utils \ + parse_command_read_string parse_command_read_element variables_utils \ + export_builtin # directories to 'make' LIBRARIES = libtf libft # .a files to include diff --git a/dev/valgrind.sh b/dev/valgrind.sh index 0298a06..a23074a 100755 --- a/dev/valgrind.sh +++ b/dev/valgrind.sh @@ -1,2 +1,2 @@ #!/bin/bash -valgrind --leak-check=full --show-leak-kinds=all --suppressions=dev/supp ./minishell +valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all --suppressions=dev/supp ./minishell diff --git a/include/variables.h b/include/variables.h index b64db7f..1bde87c 100644 --- a/include/variables.h +++ b/include/variables.h @@ -6,13 +6,16 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 13:43:21 by mcolonna #+# #+# */ -/* Updated: 2024/06/28 14:22:50 by mcolonna ### ########.fr */ +/* Updated: 2024/07/03 11:34:12 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef VARIABLES_H # define VARIABLES_H +# define SYMBOL_CHARS \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789" + typedef struct s_variable { const char *name; @@ -36,4 +39,7 @@ void variables_unset(t_list *variables, const char *name); // Get a envp of all exported variables. char *const *variables_envp(t_list *variables, t_memclass mc); +// Return true if 'name' is a valid variable name. +bool variables_nameisvalid(const char *name); + #endif diff --git a/src/builtin2.c b/src/builtin2.c index 659793d..7d6c3c8 100644 --- a/src/builtin2.c +++ b/src/builtin2.c @@ -6,41 +6,12 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/25 13:28:29 by jschaft #+# #+# */ -/* Updated: 2024/07/02 11:21:53 by mcolonna ### ########.fr */ +/* Updated: 2024/07/03 12:16:48 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #include "include.h" -int export_builtin(t_env *env, t_call call, int std[2]) -{ - int i; - char *name; - char *value; - char **splitted; - const t_memclass mc = mem_subclass(fatal_error, env->mc_global); - - (void)std; - i = 0; - while (call.argv[++i]) - { - if (char_isin('=', call.argv[i])) - { - splitted = str_split(fatal_error, mc, call.argv[i], "="); - name = splitted[0]; - value = splitted[1]; - if (!value) - value = ""; - variables_set(env->variables, name, value); - } - else - name = call.argv[i]; - variables_export(env->variables, name); - } - mem_freeall(mc); - return (0); -} - int exit_builtin(t_env *env, t_call call, int std[2]) { int r; diff --git a/src/export_builtin.c b/src/export_builtin.c new file mode 100644 index 0000000..7329bf1 --- /dev/null +++ b/src/export_builtin.c @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* export_builtin.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jschaft +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/06/25 13:28:29 by jschaft #+# #+# */ +/* Updated: 2024/07/03 12:17:03 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "include.h" + +static bool export_builtin_2(t_env *env, t_memclass mc, char **name, + const char *arg) +{ + int i; + + i = -1; + while (arg[++i] != '=') + ; + *name = mem_alloc(fatal_error, mc, (i + 1) * sizeof(char)); + i = -1; + while (arg[++i] != '=') + (*name)[i] = arg[i]; + (*name)[i] = '\0'; + if (!variables_nameisvalid(*name)) + return (false); + variables_set(env->variables, *name, arg + i + 1); + return (true); +} + +int export_builtin(t_env *env, t_call call, int std[2]) +{ + int i; + char *name; + const t_memclass mc = mem_subclass(fatal_error, env->mc_global); + int r; + + (void)std; + r = 0; + i = 0; + while (call.argv[++i]) + { + if (char_isin('=', call.argv[i]) && export_builtin_2( + env, mc, &name, call.argv[i])); + else if (variables_nameisvalid(call.argv[i])) + name = call.argv[i]; + else + { + print_line(fatal_error, 2, "builtin: bad variable name"); + r = 1; + continue ; + } + variables_export(env->variables, name); + } + mem_freeall(mc); + return (r); +} diff --git a/src/parse_command_read_string.c b/src/parse_command_read_string.c index 8f95dc4..6ebee89 100644 --- a/src/parse_command_read_string.c +++ b/src/parse_command_read_string.c @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ -/* Updated: 2024/06/27 14:32:37 by mcolonna ### ########.fr */ +/* Updated: 2024/07/03 12:08:12 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -52,10 +52,11 @@ static void read_string_noquote(t_parsing_args *args, const char **dest, const char *stop_charset) { const char *real_stop_charset - = str_join(fatal_error, args->mc, stop_charset, "$"); + = str_join(fatal_error, args->mc, stop_charset, "$\"'"); while (stream_read(&args->stream) - && !char_isin(stream_read(&args->stream), stop_charset)) + && !char_isin(stream_read(&args->stream), stop_charset) + && !char_isin(stream_read(&args->stream), "\"'")) { read_until(args, dest, real_stop_charset); if (stream_read(&args->stream) == '$') @@ -117,10 +118,7 @@ static bool read_string_doublequote(t_parsing_args *args, const char **dest) } // Read the string, stop if the char is in stop_charset. -// Possible syntaxes: -// - /[^(stop_charset)]+/ -// - /'.*'/ -// - /".*"/ +// Syntax: /([^{stop_charset}]|'.*'|".*")+/ // Change args->r.error and return NULL if error. const char *read_string(t_parsing_args *args, const char *stop_charset) { diff --git a/src/parse_command_utils.h b/src/parse_command_utils.h index 368d0f9..c6e98a5 100644 --- a/src/parse_command_utils.h +++ b/src/parse_command_utils.h @@ -6,7 +6,7 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/04/24 13:47:40 by mcolonna #+# #+# */ -/* Updated: 2024/07/01 11:15:33 by mcolonna ### ########.fr */ +/* Updated: 2024/07/03 11:33:12 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,8 +15,6 @@ # include "include.h" -# define SYMBOL_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_" - // Global variables for all the parsing functions typedef struct s_parsing_args { diff --git a/src/variables2.c b/src/variables2.c new file mode 100644 index 0000000..1ce2683 --- /dev/null +++ b/src/variables2.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* variables2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: mcolonna +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/02 15:39:55 by mcolonna #+# #+# */ +/* Updated: 2024/07/02 15:41:42 by mcolonna ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "include.h" + +bool variables_nameisvalid(const char *name) +{ + int i; + + i = -1; + while (name[++i]) + if (!char_isin(name[i], SYMBOL_CHARS)) + return (false); + return (true); +} From 75150f95dd2dea4af043ffbebe45210a2227f851 Mon Sep 17 00:00:00 2001 From: mcolonna Date: Wed, 3 Jul 2024 14:10:44 +0200 Subject: [PATCH 5/5] norm --- include/variables.h | 6 +++--- src/builtin2.c | 5 ++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/variables.h b/include/variables.h index 1bde87c..0344eac 100644 --- a/include/variables.h +++ b/include/variables.h @@ -6,15 +6,15 @@ /* By: mcolonna +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/27 13:43:21 by mcolonna #+# #+# */ -/* Updated: 2024/07/03 11:34:12 by mcolonna ### ########.fr */ +/* Updated: 2024/07/03 14:09:27 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef VARIABLES_H # define VARIABLES_H -# define SYMBOL_CHARS \ - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789" +# define SYMBOL_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\ +_0123456789" typedef struct s_variable { diff --git a/src/builtin2.c b/src/builtin2.c index 7d6c3c8..2ad64fe 100644 --- a/src/builtin2.c +++ b/src/builtin2.c @@ -6,7 +6,7 @@ /* By: jschaft +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/06/25 13:28:29 by jschaft #+# #+# */ -/* Updated: 2024/07/03 12:16:48 by mcolonna ### ########.fr */ +/* Updated: 2024/07/03 14:06:04 by mcolonna ### ########.fr */ /* */ /* ************************************************************************** */ @@ -75,10 +75,9 @@ int cd_builtin(t_env *env, t_call call, int std[2]) { int r; const char *pwd; - bool go_oldpwd; + const bool go_oldpwd = call.argv[1] && str_eq(call.argv[1], "-"); (void)std; - go_oldpwd = call.argc > 1 && str_eq(call.argv[1], "-"); if (call.argc == 1 || go_oldpwd) pwd = go_home(env, go_oldpwd); else if (call.argc == 2)