From 6862a1913bd59e32efe204b32c58c1e547380e71 Mon Sep 17 00:00:00 2001 From: mcolonna Date: Wed, 3 Jul 2024 12:10:35 +0200 Subject: [PATCH] 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); +}