mirror of
https://codeberg.org/la-chouette/minishell.git
synced 2025-12-06 07:28:09 +01:00
ENV: A small set of functions for internal env
This commit is contained in:
parent
18a2835a7c
commit
660d785237
8 changed files with 447 additions and 41 deletions
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/02/14 18:43:38 by jguelen #+# #+# */
|
||||
/* Updated: 2025/02/18 16:23:24 by khais ### ########.fr */
|
||||
/* Updated: 2025/02/18 16:33:10 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -66,3 +66,18 @@ char *envp_get_val(char *line)
|
|||
val_pointer++;
|
||||
return (ft_strdup(val_pointer));
|
||||
}
|
||||
|
||||
/*
|
||||
** 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);
|
||||
}
|
||||
|
|
|
|||
178
src/env_manip.c
Normal file
178
src/env_manip.c
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* env_manip.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/02/12 18:29:12 by jguelen #+# #+# */
|
||||
/* Updated: 2025/02/18 18:41:30 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "env_manip.h"
|
||||
#include "libft.h"
|
||||
|
||||
/*
|
||||
** Remove the first env node of the given linked list where the key matches the
|
||||
** given key.
|
||||
**
|
||||
** In any given env linked list, there should only be one entry for a given key.
|
||||
**
|
||||
** If the linked list is empty or the pointer is NULL, nothing is done.
|
||||
**
|
||||
** If the linked list does not contain an element matching the given key,
|
||||
** nothing is done.
|
||||
*/
|
||||
void env_rm_entry(t_env **env, char *key)
|
||||
{
|
||||
t_env *current;
|
||||
t_env *next;
|
||||
|
||||
if (env == NULL || (*env) == NULL)
|
||||
return ;
|
||||
if (strncmp((*env)->key, key, INT_MAX) == 0)
|
||||
{
|
||||
next = (*env)->next;
|
||||
env_destroy_node(*env);
|
||||
(*env) = next;
|
||||
return ;
|
||||
}
|
||||
current = *env;
|
||||
while (current->next)
|
||||
{
|
||||
if (strncmp(current->next->key, key, INT_MAX) == 0)
|
||||
{
|
||||
next = current->next;
|
||||
current->next = next->next;
|
||||
env_destroy_node(next);
|
||||
return ;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Add the given element to the end of the given linked list.
|
||||
*/
|
||||
static void env_add_back(t_env **env, t_env *new)
|
||||
{
|
||||
t_env *last;
|
||||
|
||||
last = *env;
|
||||
if (last == NULL)
|
||||
{
|
||||
*env = new;
|
||||
return ;
|
||||
}
|
||||
while (last->next)
|
||||
last = last->next;
|
||||
last->next = new;
|
||||
}
|
||||
|
||||
/*
|
||||
** In the given env linked list, if an element with the given key exist, set its
|
||||
** value to the one provided. If no such element exist, create a new one with
|
||||
** the provided value.
|
||||
**
|
||||
** The provided key and value must be allocated. In case of error, they will be
|
||||
** freed. In case a node matching the given key is found the provided key value
|
||||
** is freed.
|
||||
**
|
||||
** If key or value are null, both are freed and NULL is returned.
|
||||
**
|
||||
** If key is an empty string, key and value is freed and a non-error value is
|
||||
** returned.
|
||||
**
|
||||
** If there is a failure allocating a new node, NULL is returned.
|
||||
**
|
||||
** Returns a pointer to the first element in the linked list, or NULL on error.
|
||||
*/
|
||||
t_env *env_set_entry(t_env **env, char *key, char *value)
|
||||
{
|
||||
t_env *node;
|
||||
|
||||
if (key == NULL || value == NULL)
|
||||
return (free(key), free(value), NULL);
|
||||
if (*key == '\0')
|
||||
return (free(key), free(value), *env);
|
||||
node = env_find_node_bykey(*env, key);
|
||||
if (node == NULL)
|
||||
{
|
||||
node = ft_calloc(1, sizeof(t_env));
|
||||
if (!node)
|
||||
return (free(key), free(value), NULL);
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
env_add_back(env, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
free(node->value);
|
||||
free(key);
|
||||
node->value = value;
|
||||
}
|
||||
return (*env);
|
||||
}
|
||||
|
||||
/*
|
||||
** 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);
|
||||
}
|
||||
|
||||
/*
|
||||
** 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);
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/02/14 13:46:39 by jguelen #+# #+# */
|
||||
/* Updated: 2025/02/16 12:55:27 by jguelen ### ########.fr */
|
||||
/* Updated: 2025/02/18 16:47:34 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
|
@ -36,8 +36,8 @@ t_env *env_from_envp(char **envp);
|
|||
/*env_manip_utils*/
|
||||
size_t env_get_size(t_env *env);
|
||||
void env_destroy_node(t_env *node);
|
||||
void env_destroy(t_env **env);
|
||||
void envp_destroy_envp(char **envp);
|
||||
void env_destroy(t_env *env);
|
||||
void envp_destroy(char **envp);
|
||||
t_env *env_find_node_bykey(t_env *env, char *key);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
97
src/env_manip_utils.c
Normal file
97
src/env_manip_utils.c
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* env_manip_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/02/14 18:31:38 by jguelen #+# #+# */
|
||||
/* Updated: 2025/02/18 16:40:32 by khais ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "env_manip.h"
|
||||
#include "libft.h"
|
||||
|
||||
/*
|
||||
** 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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** 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);
|
||||
}
|
||||
|
||||
/*
|
||||
** 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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue