2025-02-16 13:07:33 +01:00
|
|
|
/* ************************************************************************** */
|
|
|
|
|
/* */
|
|
|
|
|
/* ::: :::::::: */
|
|
|
|
|
/* env_manip.c :+: :+: :+: */
|
|
|
|
|
/* +:+ +:+ +:+ */
|
2025-03-21 18:54:10 +01:00
|
|
|
/* By: jguelen <jguelen@student.42.fr> +#+ +:+ +#+ */
|
2025-02-16 13:07:33 +01:00
|
|
|
/* +#+#+#+#+#+ +#+ */
|
2025-04-30 11:26:59 +02:00
|
|
|
/* Created: 2025/03/19 17:55:24 by kcolin #+# #+# */
|
2025-03-21 18:54:10 +01:00
|
|
|
/* Updated: 2025/03/21 18:49:56 by jguelen ### ########.fr */
|
2025-02-16 13:07:33 +01:00
|
|
|
/* */
|
|
|
|
|
/* ************************************************************************** */
|
|
|
|
|
|
2025-02-19 16:39:18 +01:00
|
|
|
#include "env.h"
|
|
|
|
|
#include "env_convert.h"
|
2025-02-16 13:07:33 +01:00
|
|
|
#include "env_manip.h"
|
|
|
|
|
#include "libft.h"
|
2025-02-19 13:29:44 +01:00
|
|
|
#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);
|
|
|
|
|
}
|
2025-02-16 13:07:33 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
** 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 ;
|
2025-03-21 18:54:10 +01:00
|
|
|
if (ft_strncmp((*env)->key, key, INT_MAX) == 0)
|
2025-02-16 13:07:33 +01:00
|
|
|
{
|
|
|
|
|
next = (*env)->next;
|
|
|
|
|
env_destroy_node(*env);
|
|
|
|
|
(*env) = next;
|
|
|
|
|
return ;
|
|
|
|
|
}
|
|
|
|
|
current = *env;
|
|
|
|
|
while (current->next)
|
|
|
|
|
{
|
2025-03-21 18:54:10 +01:00
|
|
|
if (ft_strncmp(current->next->key, key, INT_MAX) == 0)
|
2025-02-16 13:07:33 +01:00
|
|
|
{
|
|
|
|
|
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.
|
|
|
|
|
**
|
2025-03-19 17:58:46 +01:00
|
|
|
** If key or value is null, both key and value are freed and NULL is returned.
|
|
|
|
|
** ft_errno is set to FT_EINVAL. We therefore allow for a value to be NULL.
|
2025-02-16 13:07:33 +01:00
|
|
|
**
|
2025-03-14 18:47:14 +01:00
|
|
|
** If key is an empty string, key and value are freed, ft_errno is set to
|
2025-02-17 16:52:17 +01:00
|
|
|
** FT_EBADID, and NULL is returned.
|
2025-02-16 13:07:33 +01:00
|
|
|
**
|
2025-02-17 16:52:17 +01:00
|
|
|
** If there is a failure allocating a new node, NULL is returned and ft_errno is
|
|
|
|
|
** set to FT_EERRNO (malloc would have set it to ENOMEM).
|
2025-02-16 13:07:33 +01:00
|
|
|
**
|
|
|
|
|
** Returns a pointer to the first element in the linked list, or NULL on error.
|
2025-02-17 16:52:17 +01:00
|
|
|
**
|
2025-02-19 13:29:44 +01:00
|
|
|
** Warning: does not check for validity of a key beyond what is described above.
|
|
|
|
|
**
|
2025-02-17 16:52:17 +01:00
|
|
|
** Implementation notes: free2 always returns NULL
|
2025-03-19 17:58:46 +01:00
|
|
|
**
|
|
|
|
|
** Note: once you pass a key to this function, if you pass it a second time, it
|
|
|
|
|
** will cause bad behaviour.
|
|
|
|
|
**
|
|
|
|
|
** Once you passed key and/or value to this function, env is the owner of these
|
|
|
|
|
** values and is responsible for freeing them. Do not pass multiple times the
|
|
|
|
|
** same pointers to this function!
|
2025-02-16 13:07:33 +01:00
|
|
|
*/
|
|
|
|
|
t_env *env_set_entry(t_env **env, char *key, char *value)
|
|
|
|
|
{
|
|
|
|
|
t_env *node;
|
|
|
|
|
|
2025-03-19 17:58:46 +01:00
|
|
|
if (key == NULL || value == NULL)
|
2025-02-17 16:52:17 +01:00
|
|
|
return (ft_errno(FT_EINVAL), free2(key, value));
|
2025-02-16 13:07:33 +01:00
|
|
|
if (*key == '\0')
|
2025-02-17 16:52:17 +01:00
|
|
|
return (ft_errno(FT_EBADID), free2(key, value));
|
2025-02-16 13:07:33 +01:00
|
|
|
node = env_find_node_bykey(*env, key);
|
|
|
|
|
if (node == NULL)
|
|
|
|
|
{
|
|
|
|
|
node = ft_calloc(1, sizeof(t_env));
|
|
|
|
|
if (!node)
|
2025-02-17 16:52:17 +01:00
|
|
|
return (ft_errno(FT_EERRNO), free2(key, value));
|
2025-02-16 13:07:33 +01:00
|
|
|
node->key = key;
|
|
|
|
|
node->value = value;
|
|
|
|
|
env_add_back(env, node);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
free(node->value);
|
|
|
|
|
free(key);
|
|
|
|
|
node->value = value;
|
|
|
|
|
}
|
|
|
|
|
return (*env);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2025-02-19 13:29:44 +01:00
|
|
|
** Find and return a pointer to the node in the given env linked list where the
|
|
|
|
|
** key matches the given key.
|
2025-02-16 13:07:33 +01:00
|
|
|
**
|
2025-02-19 13:29:44 +01:00
|
|
|
** If the node is not found, return NULL.
|
2025-02-16 13:07:33 +01:00
|
|
|
**
|
2025-02-19 13:29:44 +01:00
|
|
|
** Note that this is a pointer to the middle of the linked list, the node is not
|
|
|
|
|
** copied.
|
2025-02-16 13:07:33 +01:00
|
|
|
*/
|
2025-02-19 13:29:44 +01:00
|
|
|
t_env *env_find_node_bykey(t_env *env, char *key)
|
2025-02-16 13:07:33 +01:00
|
|
|
{
|
2025-02-19 13:29:44 +01:00
|
|
|
while (env)
|
2025-02-16 13:07:33 +01:00
|
|
|
{
|
2025-02-19 13:29:44 +01:00
|
|
|
if (ft_strncmp(env->key, key, INT_MAX) == 0)
|
|
|
|
|
return (env);
|
2025-02-16 13:07:33 +01:00
|
|
|
env = env->next;
|
|
|
|
|
}
|
2025-02-19 13:29:44 +01:00
|
|
|
return (NULL);
|
2025-02-16 13:07:33 +01:00
|
|
|
}
|