diff --git a/Makefile b/Makefile index 9898526..8202be5 100644 --- a/Makefile +++ b/Makefile @@ -19,10 +19,12 @@ ifeq ($(CFLAGS),) endif export CFLAGS srcs = \ - src/env_get.c \ - src/env_manip.c \ - src/env_manip_utils.c \ + src/env/env.c \ + src/env/env_convert.c \ + src/env/env_manip.c \ + src/env/envp.c \ src/ft_errno.c \ + src/parser/matchers/identifier.c \ src/parser/matchers/metacharacter.c \ objs = $(srcs:.c=.o) diff --git a/src/env/env.c b/src/env/env.c new file mode 100644 index 0000000..2eeadb3 --- /dev/null +++ b/src/env/env.c @@ -0,0 +1,59 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 13:59:20 by khais #+# #+# */ +/* Updated: 2025/02/19 14:42:35 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "env.h" +#include + +/* +** Free the given env node. +*/ +void env_destroy_node(t_env *env) +{ + if (!env) + return ; + free(env->key); + free(env->value); + free(env); +} + +/* +** Free the given env linked list. +*/ +void env_destroy(t_env *env) +{ + t_env *next; + + if (!env) + return ; + while (env) + { + next = env->next; + env_destroy_node(env); + env = next; + } +} + +/* +** Get the number of mappings in the givne env linked list +*/ +size_t env_get_size(t_env *env) +{ + size_t nb_elem; + + nb_elem = 0; + while (env) + { + nb_elem++; + env = env->next; + } + return (nb_elem); +} diff --git a/src/env/env.h b/src/env/env.h new file mode 100644 index 0000000..78b2814 --- /dev/null +++ b/src/env/env.h @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 13:58:41 by khais #+# #+# */ +/* Updated: 2025/02/19 14:41:51 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ENV_H +# define ENV_H + +# include + +typedef struct s_env +{ + char *key; + char *value; + struct s_env *next; +} t_env; + +void env_destroy_node(t_env *node); +void env_destroy(t_env *env); +size_t env_get_size(t_env *env); + +#endif diff --git a/src/env/env_convert.c b/src/env/env_convert.c new file mode 100644 index 0000000..c67bf8a --- /dev/null +++ b/src/env/env_convert.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env_convert.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 14:39:57 by khais #+# #+# */ +/* Updated: 2025/02/19 14:45:54 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "env_convert.h" +#include "libft.h" + +/* +** Create an envp structure from the given env linked list. +** +** The linked list is not destroyed. +** +** in case of allocation error, all memory is freed and NULL is returned. +*/ +char **envp_from_env(t_env *env) +{ + char **new_envp; + size_t size; + size_t i; + + size = env_get_size(env); + new_envp = ft_calloc(size + 1, sizeof(char *)); + if (new_envp == NULL) + return (NULL); + i = 0; + while (i < size) + { + new_envp[i] = ft_strjoin_sepc(env->key, env->value, '='); + if (new_envp[i] == NULL) + { + envp_destroy(new_envp); + return (NULL); + } + i++; + env = env->next; + } + new_envp[size] = NULL; + return (new_envp); +} + +/* +** read an envp structure, and create a t_env linked list containing the same +** information. +** +** the envp structure is not freed. +** +** in case of error, all memory is freed and null is returned. +** +** no checks additional checks than those of envp_get_key and envp_get_val are +** performed +*/ +t_env *env_from_envp(char **envp) +{ + t_env *env; + + env = NULL; + while (*envp) + { + if (env_set_entry(&env, envp_get_key(*envp), + envp_get_val(*envp)) == NULL) + { + env_destroy(env); + return (NULL); + } + envp++; + } + return (env); +} diff --git a/src/env/env_convert.h b/src/env/env_convert.h new file mode 100644 index 0000000..a8a6286 --- /dev/null +++ b/src/env/env_convert.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* env_convert.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 14:38:43 by khais #+# #+# */ +/* Updated: 2025/02/19 14:39:39 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ENV_CONVERT_H +# define ENV_CONVERT_H + +# include "env_manip.h" + +char **envp_from_env(t_env *env); +t_env *env_from_envp(char **envp); + +#endif diff --git a/src/env_manip.c b/src/env/env_manip.c similarity index 74% rename from src/env_manip.c rename to src/env/env_manip.c index 65f1f80..b5ccc6a 100644 --- a/src/env_manip.c +++ b/src/env/env_manip.c @@ -6,13 +6,28 @@ /* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/12 18:29:12 by jguelen #+# #+# */ -/* Updated: 2025/02/19 13:17:55 by khais ### ########.fr */ +/* Updated: 2025/02/19 14:41:06 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #include "env_manip.h" #include "libft.h" -#include "ft_errno.h" +#include "../ft_errno.h" + +/* +** Get the value corresponding to a given key in the given environment structure +** +** If not found, return null +*/ +char *env_get_val(t_env *env, char *key) +{ + t_env *node; + + node = env_find_node_bykey(env, key); + if (node) + return (node->value); + return (NULL); +} /* ** Remove the first env node of the given linked list where the key matches the @@ -91,6 +106,8 @@ static void env_add_back(t_env **env, t_env *new) ** ** Returns a pointer to the first element in the linked list, or NULL on error. ** +** Warning: does not check for validity of a key beyond what is described above. +** ** Implementation notes: free2 always returns NULL */ t_env *env_set_entry(t_env **env, char *key, char *value) @@ -121,63 +138,21 @@ t_env *env_set_entry(t_env **env, char *key, char *value) } /* -** read an envp structure, and create a t_env linked list containing the same -** information. +** Find and return a pointer to the node in the given env linked list where the +** key matches the given key. ** -** the envp structure is not freed. +** If the node is not found, return NULL. ** -** in case of error, all memory is freed and null is returned. -** -** no checks additional checks than those of envp_get_key and envp_get_val are -** performed +** Note that this is a pointer to the middle of the linked list, the node is not +** copied. */ -t_env *env_from_envp(char **envp) +t_env *env_find_node_bykey(t_env *env, char *key) { - t_env *env; - - env = NULL; - while (*envp) + while (env) { - if (env_set_entry(&env, envp_get_key(*envp), - envp_get_val(*envp)) == NULL) - { - env_destroy(env); - return (NULL); - } - envp++; - } - return (env); -} - -/* -** Create an envp structure from the given env linked list. -** -** The linked list is not destroyed. -** -** in case of allocation error, all memory is freed and NULL is returned. -*/ -char **envp_from_env(t_env *env) -{ - char **new_envp; - size_t size; - size_t i; - - size = env_get_size(env); - new_envp = ft_calloc(size + 1, sizeof(char *)); - if (new_envp == NULL) - return (NULL); - i = 0; - while (i < size) - { - new_envp[i] = ft_strjoin_sepc(env->key, env->value, '='); - if (new_envp[i] == NULL) - { - envp_destroy(new_envp); - return (NULL); - } - i++; + if (ft_strncmp(env->key, key, INT_MAX) == 0) + return (env); env = env->next; } - new_envp[size] = NULL; - return (new_envp); + return (NULL); } diff --git a/src/env_manip.h b/src/env/env_manip.h similarity index 60% rename from src/env_manip.h rename to src/env/env_manip.h index ff16b80..96d2a4c 100644 --- a/src/env_manip.h +++ b/src/env/env_manip.h @@ -6,41 +6,20 @@ /* By: jguelen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/14 13:46:39 by jguelen #+# #+# */ -/* Updated: 2025/02/19 13:08:58 by khais ### ########.fr */ +/* Updated: 2025/02/19 14:43:49 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef ENV_MANIP_H # define ENV_MANIP_H -# include -# include -# include "libft.h" +# include "envp.h" +# include "env.h" +# include "env_convert.h" -typedef struct s_env -{ - char *key; - char *value; - struct s_env *next; -} t_env; - -char *envp_get_key(char *line); -char *envp_get_val(char *line); char *env_get_val(t_env *env, char *key); -size_t env_get_size(t_env *env); -/**/ void env_rm_entry(t_env **env, char *key); -/*WARNING: env_set_entry does NOT check for the actual validity of an -identifier (i.e. key) in the sense that it does not check what characters -compose it.*/ t_env *env_set_entry(t_env **env, char *key, char *value); -char **envp_from_env(t_env *env); -t_env *env_from_envp(char **envp); -/*env_manip_utils*/ -void env_destroy_node(t_env *node); -void env_destroy(t_env *env); -void envp_destroy(char **envp); t_env *env_find_node_bykey(t_env *env, char *key); -bool identifier_isvalid(char *id); #endif diff --git a/src/env_get.c b/src/env/envp.c similarity index 74% rename from src/env_get.c rename to src/env/envp.c index 0b037bd..6bf8ecc 100644 --- a/src/env_get.c +++ b/src/env/envp.c @@ -1,16 +1,18 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* env_get.c :+: :+: :+: */ +/* envp.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/02/19 12:30/54 by khais #+# #+# */ -/* Updated: 2025/02/19 12:30:54 by khais ### ########.fr */ +/* Created: 2025/02/19 13:35:44 by khais #+# #+# */ +/* Updated: 2025/02/19 13:43:19 by khais ### ########.fr */ /* */ /* ************************************************************************** */ -#include "env_manip.h" +#include "envp.h" +#include "libft.h" +#include /* ** Get the key part of a line of envp @@ -68,32 +70,19 @@ char *envp_get_val(char *line) } /* -** Get the value corresponding to a given key in the given environment structure -** -** If not found, return null +** Free all memory related to a given envp structure */ -char *env_get_val(t_env *env, char *key) +void envp_destroy(char **envp) { - t_env *node; + int i; - node = env_find_node_bykey(env, key); - if (node) - return (node->value); - return (NULL); -} - -/* -** Get the number of mappings in the givne env linked list -*/ -size_t env_get_size(t_env *env) -{ - size_t nb_elem; - - nb_elem = 0; - while (env) + if (!envp) + return ; + i = 0; + while (envp[i]) { - nb_elem++; - env = env->next; + free(envp[i]); + i++; } - return (nb_elem); + free(envp); } diff --git a/src/env/envp.h b/src/env/envp.h new file mode 100644 index 0000000..f85906d --- /dev/null +++ b/src/env/envp.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* envp.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 13:32:34 by khais #+# #+# */ +/* Updated: 2025/02/19 13:35:37 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ENVP_H +# define ENVP_H + +char *envp_get_key(char *line); +char *envp_get_val(char *line); +void envp_destroy(char **envp); + +#endif diff --git a/src/env_manip_utils.c b/src/env_manip_utils.c deleted file mode 100644 index 2049e6a..0000000 --- a/src/env_manip_utils.c +++ /dev/null @@ -1,104 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* env_manip_utils.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: khais +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2025/02/19 13:16/49 by khais #+# #+# */ -/* Updated: 2025/02/19 13:16:49 by khais ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "env_manip.h" -#include "libft.h" -#include - -/* -** Free all memory related to a given envp structure -*/ -void envp_destroy(char **envp) -{ - int i; - - if (!envp) - return ; - i = 0; - while (envp[i]) - { - free(envp[i]); - i++; - } - free(envp); -} - -/* -** Free the given env node. -*/ -void env_destroy_node(t_env *env) -{ - if (!env) - return ; - free(env->key); - free(env->value); - free(env); -} - -/* -** Free the given env linked list. -*/ -void env_destroy(t_env *env) -{ - t_env *next; - - if (!env) - return ; - while (env) - { - next = env->next; - env_destroy_node(env); - env = next; - } -} - -/* -** Find and return a pointer to the node in the given env linked list where the -** key matches the given key. -** -** If the node is not found, return NULL. -** -** Note that this is a pointer to the middle of the linked list, the node is not -** copied. -*/ -t_env *env_find_node_bykey(t_env *env, char *key) -{ - while (env) - { - if (ft_strncmp(env->key, key, INT_MAX) == 0) - return (env); - env = env->next; - } - return (NULL); -} - -/* -** Return true if id is a valid bash identifier, false otherwise. -** -** A valid identifier starts with one of a-zA-Z_ -** It can contain any char a-zA-Z0-9_ -** It must contain at least one char -*/ -bool identifier_isvalid(char *id) -{ - if (id == NULL || id[0] == '\0') - return (false); - if (!ft_isalpha(id[0]) && id[0] != '_') - return (false); - while (*id != '\0') - { - if (!ft_isalpha(*id) && !ft_isdigit(*id) && *id != '_') - return (false); - id++; - } - return (true); -} diff --git a/src/parser/matchers/identifier.c b/src/parser/matchers/identifier.c new file mode 100644 index 0000000..638f1e5 --- /dev/null +++ b/src/parser/matchers/identifier.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* identifier.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 14:43:57 by khais #+# #+# */ +/* Updated: 2025/02/19 14:47:00 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "identifier.h" +#include "libft.h" + +/* +** Return true if id is a valid bash identifier, false otherwise. +** +** A valid identifier starts with one of a-zA-Z_ +** It can contain any char a-zA-Z0-9_ +** It must contain at least one char +*/ +bool is_identifier(char *id) +{ + if (id == NULL || id[0] == '\0') + return (false); + if (!ft_isalpha(id[0]) && id[0] != '_') + return (false); + while (*id != '\0') + { + if (!ft_isalpha(*id) && !ft_isdigit(*id) && *id != '_') + return (false); + id++; + } + return (true); +} diff --git a/src/parser/matchers/identifier.h b/src/parser/matchers/identifier.h new file mode 100644 index 0000000..71f4d3f --- /dev/null +++ b/src/parser/matchers/identifier.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* identifier.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/02/19 14:43:09 by khais #+# #+# */ +/* Updated: 2025/02/19 14:47:01 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef IDENTIFIER_H +# define IDENTIFIER_H + +# include + +bool is_identifier(char *id); + +#endif diff --git a/tests/test_env_manip.c b/tests/test_env_manip.c index b658255..292571c 100644 --- a/tests/test_env_manip.c +++ b/tests/test_env_manip.c @@ -6,11 +6,11 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/18 15:11:14 by khais #+# #+# */ -/* Updated: 2025/02/19 13:15:43 by khais ### ########.fr */ +/* Updated: 2025/02/19 13:30:38 by khais ### ########.fr */ /* */ /* ************************************************************************** */ -#include "../src/env_manip.h" +#include "../src/env/env_manip.h" #include "../src/ft_errno.h" #include "libft.h" #include "testutil.h"