env_manip: sort funcs per structure that is being manipulated

This is instead of the operation that is being performed.

I find it more logical this way, but if you prefer we can keep it as-is.

I also put the identifier_isvalid func into parser/matchers
This commit is contained in:
Khaïs COLIN 2025-02-19 13:29:44 +01:00
parent e985fcc562
commit e445f668b3
Signed by: logistic-bot
SSH key fingerprint: SHA256:RlpiqKeXpcPFZZ4y9Ou4xi2M8OhRJovIwDlbCaMsuAo
13 changed files with 317 additions and 215 deletions

View file

@ -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)

59
src/env/env.c vendored Normal file
View file

@ -0,0 +1,59 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/19 13:59:20 by khais #+# #+# */
/* Updated: 2025/02/19 14:42:35 by khais ### ########.fr */
/* */
/* ************************************************************************** */
#include "env.h"
#include <stdlib.h>
/*
** 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);
}

29
src/env/env.h vendored Normal file
View file

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <stddef.h>
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

76
src/env/env_convert.c vendored Normal file
View file

@ -0,0 +1,76 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env_convert.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

21
src/env/env_convert.h vendored Normal file
View file

@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env_convert.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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

View file

@ -6,13 +6,28 @@
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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++;
}
if (ft_strncmp(env->key, key, INT_MAX) == 0)
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);
return (NULL);
}

View file

@ -6,41 +6,20 @@
/* By: jguelen <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <stdlib.h>
# include <stdbool.h>
# 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

View file

@ -1,16 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env_get.c :+: :+: :+: */
/* envp.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <stddef.h>
/*
** 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);
}

20
src/env/envp.h vendored Normal file
View file

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* envp.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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

View file

@ -1,104 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env_manip_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <stdbool.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;
}
}
/*
** 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);
}

View file

@ -0,0 +1,36 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* identifier.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

View file

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* identifier.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <stdbool.h>
bool is_identifier(char *id);
#endif

View file

@ -6,11 +6,11 @@
/* By: khais <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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"