5 Commits

Author SHA1 Message Date
marcnava-42cursus
dd6101edec A POR TODAAS 2026-02-14 06:14:59 +01:00
e2b734cf0c save commit 2026-02-14 05:48:18 +01:00
32b3bd72b5 fix: prompt was not being requested to hashmap 2026-02-14 02:05:49 +01:00
c95703b42b update: replaced set_env by set_var in export builtin 2026-02-14 02:02:52 +01:00
f4cfae1107 feat: added internal variables 2026-02-14 02:01:10 +01:00
18 changed files with 621 additions and 270 deletions

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/10/29 22:09:51 by sede-san #+# #+# */ /* Created: 2025/10/29 22:09:51 by sede-san #+# #+# */
/* Updated: 2026/02/08 19:42:50 by sede-san ### ########.fr */ /* Updated: 2026/02/14 01:15:34 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -16,6 +16,7 @@
# include "ft_args.h" # include "ft_args.h"
# include "minishell.h" # include "minishell.h"
# include "core.h" # include "core.h"
# include "variables.h"
typedef uint8_t (*t_builtin_func)(t_command cmd, t_minishell *minishell); typedef uint8_t (*t_builtin_func)(t_command cmd, t_minishell *minishell);

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/10/22 19:10:13 by sede-san #+# #+# */ /* Created: 2025/10/22 19:10:13 by sede-san #+# #+# */
/* Updated: 2026/02/13 20:06:08 by sede-san ### ########.fr */ /* Updated: 2026/02/14 01:25:43 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -63,15 +63,9 @@ typedef struct s_redirection
typedef struct s_variables typedef struct s_variables
{ {
t_hashmap *environment; t_hashmap *environment;
// char **internal; t_hashmap *internal;
} t_variables; } t_variables;
typedef struct s_prompt
{
const char *ps1; // primary prompt string
const char *ps2; // secondary prompt string for multiline input
} t_prompt;
/** /**
* @brief Main minishell structure containing global state information * @brief Main minishell structure containing global state information
* *
@@ -84,7 +78,6 @@ typedef struct s_minishell
{ {
t_variables variables; t_variables variables;
t_hashmap *builtins; t_hashmap *builtins;
t_prompt prompt;
uint8_t exit_status; uint8_t exit_status;
bool exit; bool exit;
} t_minishell; } t_minishell;
@@ -149,8 +142,8 @@ extern char **get_envp(t_minishell *msh);
extern void free_envp(char **envp); extern void free_envp(char **envp);
extern char *get_env(const char *env_name, t_minishell *msh); void handle_sigint_status(t_minishell *minishell);
bool handle_eof(char *line, t_minishell *minishell);
extern void unset_env(const char *env_name, t_minishell *msh);
#endif /* CORE_H */ #endif /* CORE_H */

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/10 22:28:01 by sede-san #+# #+# */ /* Created: 2026/02/10 22:28:01 by sede-san #+# #+# */
/* Updated: 2026/02/10 23:24:16 by sede-san ### ########.fr */ /* Updated: 2026/02/14 01:11:38 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -19,5 +19,6 @@
extern void syntax_error_unexpected_token(t_token *token); extern void syntax_error_unexpected_token(t_token *token);
extern void malloc_error(void); extern void malloc_error(void);
extern void command_not_found_error(const char *command);
#endif /* ERRORS_H */ #endif /* ERRORS_H */

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/10/20 16:35:10 by sede-san #+# #+# */ /* Created: 2025/10/20 16:35:10 by sede-san #+# #+# */
/* Updated: 2026/02/13 20:12:25 by sede-san ### ########.fr */ /* Updated: 2026/02/14 01:13:42 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -42,7 +42,4 @@
# include <term.h> // tgetent(3), tgetflag(3), tgetnum(3), # include <term.h> // tgetent(3), tgetflag(3), tgetnum(3),
// tgetstr(3), tgoto(3), tputs(3) // tgetstr(3), tgoto(3), tputs(3)
void handle_sigint_status(t_minishell *minishell);
bool handle_eof(char *line, t_minishell *minishell);
#endif /* MINISHELL_H */ #endif /* MINISHELL_H */

43
include/variables.h Normal file
View File

@@ -0,0 +1,43 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* variables.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/13 21:45:35 by sede-san #+# #+# */
/* Updated: 2026/02/14 01:24:49 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef VARIABLES_H
# define VARIABLES_H
# include "minishell.h"
# include "core.h"
// variables.c
extern char *get_var(const char *name, t_minishell *minishell);
extern void set_var(const char *name, char *value, t_minishell *minishell);
extern void unset_var(const char *name, t_minishell *minishell);
// environment.c
extern char *get_env(const char *name, t_minishell *minishell);
extern void set_env(const char *name, char *value, t_minishell *minishell);
extern void unset_env(const char *name, t_minishell *minishell);
extern void set_envp(char **envp, t_minishell *minishell);
extern char **get_envp(t_minishell *minishell);
extern void free_envp(char **envp);
// internal.c
extern char *get_int(const char *name, t_minishell *minishell);
extern void set_int(const char *name, char *value, t_minishell *minishell);
extern void unset_int(const char *name, t_minishell *minishell);
extern void set_intp(t_minishell *minishell);
#endif /* VARIABLES_H */

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/09 22:05:00 by codex #+# #+# */ /* Created: 2026/02/09 22:05:00 by codex #+# #+# */
/* Updated: 2026/02/09 22:05:00 by codex ### ########.fr */ /* Updated: 2026/02/14 02:02:14 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -71,9 +71,9 @@ static uint8_t export_one(
if (name == NULL) if (name == NULL)
return (EXIT_FAILURE); return (EXIT_FAILURE);
if (eq_pos != NULL) if (eq_pos != NULL)
set_env(name, eq_pos + 1, msh); set_var(name, eq_pos + 1, msh);
else else
set_env(name, "", msh); set_var(name, "", msh);
free(name); free(name);
return (EXIT_SUCCESS); return (EXIT_SUCCESS);
} }

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/11 00:00:00 by sede-san #+# #+# */ /* Created: 2026/02/11 00:00:00 by sede-san #+# #+# */
/* Updated: 2026/02/11 00:00:00 by sede-san ### ########.fr */ /* Updated: 2026/02/14 01:34:37 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -40,9 +40,13 @@ static void handle_execve_error(
) )
{ {
uint8_t exit_status; uint8_t exit_status;
size_t i;
exit_status = resolve_execve_status(); exit_status = resolve_execve_status();
free_envp(envp); i = 0;
while (envp[i] != NULL)
free(envp[i++]);
free(envp);
perror(command->path); perror(command->path);
exit(exit_status); exit(exit_status);
} }

View File

@@ -6,11 +6,12 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/11 00:00:00 by sede-san #+# #+# */ /* Created: 2026/02/11 00:00:00 by sede-san #+# #+# */
/* Updated: 2026/02/11 00:00:00 by sede-san ### ########.fr */ /* Updated: 2026/02/14 01:17:01 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "executor.h" #include "executor.h"
#include "variables.h"
static bool is_path_explicit( static bool is_path_explicit(
const char *command_name const char *command_name

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/10/20 20:51:33 by sede-san #+# #+# */ /* Created: 2025/10/20 20:51:33 by sede-san #+# #+# */
/* Updated: 2026/02/13 20:12:07 by sede-san ### ########.fr */ /* Updated: 2026/02/14 02:23:17 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
@@ -15,29 +15,22 @@
#include "parser.h" #include "parser.h"
#include "executor.h" #include "executor.h"
static void set_prompts(
t_minishell *minishell
)
{
minishell->prompt.ps1 = DEFAULT_PS1;
minishell->prompt.ps2 = DEFAULT_PS2;
}
void minishell_init( void minishell_init(
t_minishell *minishell, t_minishell *minishell,
char **envp char **envp
){ ){
ft_bzero(minishell, sizeof(t_minishell)); ft_bzero(minishell, sizeof(t_minishell));
set_intp(minishell);
set_envp(envp, minishell); set_envp(envp, minishell);
set_builtins(minishell); set_builtins(minishell);
set_prompts(minishell);
if (minishell->variables.environment == NULL || minishell->builtins == NULL) if (minishell->variables.environment == NULL || minishell->builtins == NULL)
minishell_clear(minishell); minishell_clear(minishell);
} }
void minishell_run( void minishell_run(
t_minishell *minishell t_minishell *minishell
){ )
{
char *line; char *line;
t_list *commands; t_list *commands;
@@ -47,7 +40,7 @@ void minishell_run(
while (!minishell->exit) while (!minishell->exit)
{ {
if (isatty(STDIN_FILENO)) if (isatty(STDIN_FILENO))
line = readline(minishell->prompt.ps1); line = readline(get_var("PS1", minishell));
else else
line = get_next_line(STDIN_FILENO); line = get_next_line(STDIN_FILENO);
handle_sigint_status(minishell); handle_sigint_status(minishell);
@@ -67,6 +60,8 @@ void minishell_clear(
t_minishell *minishell t_minishell *minishell
){ ){
rl_clear_history(); rl_clear_history();
if (minishell->variables.internal != NULL)
ft_hashmap_clear(&minishell->variables.internal, free);
if (minishell->variables.environment != NULL) if (minishell->variables.environment != NULL)
ft_hashmap_clear(&minishell->variables.environment, free); ft_hashmap_clear(&minishell->variables.environment, free);
if (minishell->builtins != NULL) if (minishell->builtins != NULL)

View File

@@ -6,92 +6,54 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/13 21:24:45 by sede-san #+# #+# */ /* Created: 2026/02/13 21:24:45 by sede-san #+# #+# */
/* Updated: 2026/02/13 21:24:45 by sede-san ### ########.fr */ /* Updated: 2026/02/14 06:56:00 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "parser.h" #include "parser_expand_internal.h"
#include "errors.h"
static char *replace_value(char *original, char *value, int start, int end); static bool expand_argv(
static void expand_variable(char **argument, int *i, t_minishell *minishell); t_command *command,
static void expand_argument(char **argument, t_minishell *minishell);
static char *replace_value(
char *original,
char *value,
int start,
int end
)
{
const char *before = ft_substr(original, 0, start);
const char *after = ft_substr(original, end, ft_strlen(original) - end);
const char *expanded = ft_strnjoin(3, before, value, after);
free((char *)before);
free((char *)after);
return ((char *)expanded);
}
static void expand_variable(
char **argument,
int *i,
t_minishell *minishell t_minishell *minishell
) )
{ {
char *expanded;
char *variable_name;
char *variable_value;
const int start = *i + 1;
int end;
end = start;
while (ft_isalnum((*argument)[end]) || (*argument)[end] == '_')
end++;
variable_name = ft_substr(*argument, start, end - start);
if (variable_name == NULL)
return (minishell->exit = true, malloc_error());
variable_value = get_env(variable_name, minishell);
free(variable_name);
if (variable_value == NULL)
variable_value = "";
expanded = replace_value(*argument, variable_value, start - 1, end);
if (expanded == NULL)
return (minishell->exit = true, malloc_error());
*i += ft_strlen(variable_value);
free(*argument);
*argument = expanded;
}
static void expand_argument(
char **argument,
t_minishell *minishell
)
{
bool in_single_quote;
bool in_double_quote;
int i; int i;
char *expanded;
in_single_quote = false;
in_double_quote = false;
i = 0; i = 0;
while ((*argument)[i] != '\0') while (i < command->argc)
{ {
if ((*argument)[i] == '$' && !in_single_quote) expanded = parser_expand_word(command->argv[i], minishell, true);
{ if (expanded == NULL)
expand_variable(argument, &i, minishell); return (false);
if (*argument == NULL) free(command->argv[i]);
return (minishell->exit = true, malloc_error()); command->argv[i] = expanded;
}
else
{
if ((*argument)[i] == '\'' && !in_double_quote)
in_single_quote = !in_single_quote;
else if ((*argument)[i] == '"' && !in_single_quote)
in_double_quote = !in_double_quote;
i++; i++;
} }
return (true);
}
static bool expand_redirections(
t_list *redirections,
t_minishell *minishell,
bool expand_vars
)
{
t_redirection *redirection;
char *expanded;
while (redirections != NULL)
{
redirection = (t_redirection *)redirections->content;
expanded = parser_expand_word(redirection->target, minishell,
expand_vars);
if (expanded == NULL)
return (false);
free(redirection->target);
redirection->target = expanded;
redirections = redirections->next;
} }
return (true);
} }
void expand( void expand(
@@ -99,24 +61,23 @@ void expand(
t_minishell *minishell t_minishell *minishell
) )
{ {
t_list *current_command; t_list *current;
t_command *command; t_command *command;
int i;
current_command = *commands; if (commands == NULL || *commands == NULL)
while (current_command != NULL) return ;
current = *commands;
while (current != NULL)
{ {
command = (t_command *)current_command->content; command = (t_command *)current->content;
i = 0; if (!expand_argv(command, minishell)
while (i < command->argc) || !expand_redirections(command->redirections, minishell, true)
|| !expand_redirections(command->heredocs, minishell, false))
{ {
expand_argument(&command->argv[i], minishell);
if (command->argv[i] == NULL)
ft_lstclear(commands, (void (*)(void *))command_clear); ft_lstclear(commands, (void (*)(void *))command_clear);
i++; *commands = NULL;
return ;
} }
if (command == NULL) current = current->next;
return (ft_lstclear(commands, (void (*)(void *))command_clear));
current_command = current_command->next;
} }
} }

View File

@@ -0,0 +1,35 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser_expand_internal.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/14 06:56:00 by sede-san #+# #+# */
/* Updated: 2026/02/14 06:56:00 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef PARSER_EXPAND_INTERNAL_H
# define PARSER_EXPAND_INTERNAL_H
# include "parser.h"
# include "errors.h"
# include "variables.h"
void parser_expand_malloc_error(t_minishell *minishell);
char *parser_expand_variable(const char *word, size_t *i,
t_minishell *minishell);
char *parser_expand_word(const char *word, t_minishell *minishell,
bool expand_vars);
typedef struct s_word_ctx
{
char **result;
bool *in_single_quote;
bool *in_double_quote;
t_minishell *minishell;
bool expand_vars;
} t_word_ctx;
#endif

View File

@@ -0,0 +1,82 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser_expand_variable.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/14 06:56:00 by sede-san #+# #+# */
/* Updated: 2026/02/14 06:56:00 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "parser_expand_internal.h"
void parser_expand_malloc_error(
t_minishell *minishell
)
{
minishell->exit = true;
malloc_error();
}
static bool is_var_char(
char c
)
{
return (ft_isalnum(c) || c == '_');
}
static char *dup_or_error(
const char *value,
t_minishell *minishell
)
{
char *dup;
dup = ft_strdup(value);
if (dup == NULL)
return (parser_expand_malloc_error(minishell), NULL);
return (dup);
}
static char *expand_named_variable(
const char *word,
size_t *i,
t_minishell *minishell
)
{
char *name;
char *value;
size_t start;
start = *i;
while (word[*i] != '\0' && is_var_char(word[*i]))
(*i)++;
name = ft_substr(word, start, *i - start);
if (name == NULL)
return (parser_expand_malloc_error(minishell), NULL);
value = get_var(name, minishell);
free(name);
if (value == NULL)
value = "";
return (dup_or_error(value, minishell));
}
char *parser_expand_variable(const char *word, size_t *i,
t_minishell *minishell)
{
char *expanded;
(*i)++;
if (word[*i] == '?')
{
expanded = ft_itoa(minishell->exit_status);
if (expanded == NULL)
return (parser_expand_malloc_error(minishell), NULL);
return ((*i)++, expanded);
}
if (word[*i] == '\0' || !is_var_char(word[*i]))
return (dup_or_error("$", minishell));
return (expand_named_variable(word, i, minishell));
}

View File

@@ -0,0 +1,100 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser_expand_word.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/14 06:56:00 by sede-san #+# #+# */
/* Updated: 2026/02/14 06:56:00 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "parser_expand_internal.h"
static bool word_toggle_quotes(
char c,
bool *in_single_quote,
bool *in_double_quote
)
{
if (c == '\'' && !*in_double_quote)
return (*in_single_quote = !*in_single_quote, true);
if (c == '\"' && !*in_single_quote)
return (*in_double_quote = !*in_double_quote, true);
return (false);
}
static bool word_append(
char **result,
const char *value,
t_minishell *minishell
)
{
char *joined;
joined = ft_strnjoin(2, *result, (char *)value);
if (joined == NULL)
{
free(*result);
*result = NULL;
return (parser_expand_malloc_error(minishell), false);
}
free(*result);
*result = joined;
return (true);
}
static bool word_step(
const char *word,
size_t *i,
t_word_ctx ctx
)
{
char *expanded;
char value[2];
if (word_toggle_quotes(word[*i], ctx.in_single_quote, ctx.in_double_quote))
return ((*i)++, true);
if (word[*i] == '$' && !*ctx.in_single_quote && ctx.expand_vars)
{
expanded = parser_expand_variable(word, i, ctx.minishell);
if (expanded == NULL || !word_append(ctx.result, expanded,
ctx.minishell))
return (free(expanded), false);
return (free(expanded), true);
}
value[0] = word[*i];
value[1] = '\0';
(*i)++;
return (word_append(ctx.result, value, ctx.minishell));
}
char *parser_expand_word(
const char *word,
t_minishell *minishell,
bool expand_vars
)
{
char *result;
size_t i;
bool in_single_quote;
bool in_double_quote;
result = ft_strdup("");
if (result == NULL)
return (parser_expand_malloc_error(minishell), NULL);
i = 0;
in_single_quote = false;
in_double_quote = false;
while (word[i] != '\0')
{
if (!word_step(word, &i, (t_word_ctx){&result, &in_single_quote,
&in_double_quote, minishell, expand_vars}))
return (NULL);
}
if (in_single_quote || in_double_quote)
return (free(result), syntax_error_unexpected_token(NULL),
minishell->exit_status = 2, NULL);
return (result);
}

View File

@@ -6,7 +6,7 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/13 21:29:44 by sede-san #+# #+# */ /* Created: 2026/02/13 21:29:44 by sede-san #+# #+# */
/* Updated: 2026/02/13 21:29:44 by sede-san ### ########.fr */ /* Updated: 2026/02/14 03:34:38 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */

View File

@@ -6,65 +6,33 @@
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */ /* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
/* Created: 2025/12/01 09:12:39 by sede-san #+# #+# */ /* Created: 2025/12/01 09:12:39 by sede-san #+# #+# */
/* Updated: 2026/02/08 19:44:15 by sede-san ### ########.fr */ /* Updated: 2026/02/14 01:32:42 by sede-san ### ########.fr */
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "minishell.h" #include "minishell.h"
#include "core.h" #include "core.h"
#include "variables.h"
#include "errors.h"
/** /**
* @brief Parses and stores environment variables from envp array into a hashmap * @brief Retrieves the value of an environment variable from the shell's
* environment hashmap.
* *
* This function iterates through the environment variables array (envp) and * This function searches for the specified environment variable name in the
* splits each variable string on the '=' delimiter to separate the variable * minishell's environment variable hashmap and returns its associated value.
* name from its value. Each name-value pair is then stored in the minishell's
* environment hashmap for later retrieval.
* *
* @param envp Array of environment variable strings in "NAME=value" format * @param name The name of the environment variable to retrieve.
* @param msh Pointer to the minishell structure containing the environment * @param minishell Pointer to the minishell object.
* hashmap
* *
* @note The function assumes envp strings are in the standard format * @return The value of the environment variable if found, NULL if not found
* "NAME=value"
*/ */
void set_envp( char *get_env(
char **envp, const char *name,
t_minishell *msh t_minishell *minishell
) { )
char *equal_sign; {
char *key; return (ft_hashmap_get(minishell->variables.environment, name));
char *value;
if (msh == NULL || envp == NULL)
return ;
msh->variables.environment
= ft_hashmap_new(32, ft_hashmap_hashstr, ft_hashmap_strcmp);
if (msh->variables.environment == NULL)
return ;
while (*envp != NULL)
{
equal_sign = ft_strchr(*envp, '=');
if (equal_sign == NULL)
{
key = ft_strdup(*envp);
value = ft_strdup("");
}
else
{
key = ft_substr(*envp, 0, equal_sign - *envp);
value = ft_strdup(equal_sign + 1);
}
if (key == NULL || value == NULL)
{
free(key);
free(value);
ft_hashmap_clear(&msh->variables.environment, free);
return ;
}
ft_hashmap_put(msh->variables.environment, key, value);
envp++;
}
} }
/** /**
@@ -75,29 +43,74 @@ void set_envp(
* the old value is freed to prevent memory leaks. If the variable is new, * the old value is freed to prevent memory leaks. If the variable is new,
* a duplicate of the key name is created for storage. * a duplicate of the key name is created for storage.
* *
* @param env_name The name of the environment variable to set * @param name The name of the environment variable to set
* @param env_value The value to assign to the environment variable * @param value The value to assign to the environment variable
* @param msh Pointer to the minishell structure containing the * @param minishell Pointer to the minishell object.
* environment hashmap
*/ */
void set_env( void set_env(
const char *env_name, const char *name,
char *env_value, char *value,
t_minishell *msh t_minishell *minishell
) { )
{
t_hashmap *environment; t_hashmap *environment;
const char *key; char *key;
char *val;
char *old_value; char *old_value;
environment = msh->variables.environment; environment = minishell->variables.environment;
key = env_name; key = (char *)name;
if (!ft_hashmap_contains_key(environment, key)) if (key != NULL && !ft_hashmap_contains_key(environment, key))
key = ft_strdup(env_name); {
old_value = ft_hashmap_put(environment, key, ft_strdup(env_value)); key = ft_strdup(name);
if (key == NULL)
{
minishell->exit = true;
malloc_error();
return ;
}
}
val = value;
if (val == NULL)
val = ft_strdup("");
else
val = ft_strdup(value);
if (val == NULL)
{
if (key != name)
free(key);
minishell->exit = true;
malloc_error();
return ;
}
old_value = ft_hashmap_put(environment, key, val);
if (old_value != NULL) if (old_value != NULL)
free(old_value); free(old_value);
} }
/**
* @brief Removes an environment variable by name.
*
* @param name The name of the environment variable to remove.
* @param minishell Pointer to the minishell structure.
*
* @note If the environment variable exists, it will be removed from the hashmap
* and its associated value will be freed.
*/
void unset_env(
const char *name,
t_minishell *minishell
)
{
t_hashmap *environment;
char *val;
environment = minishell->variables.environment;
val = ft_hashmap_remove(environment, (void *)name);
if (val != NULL)
free(val);
}
/** /**
* @brief Converts the environment variables hashmap to an envp array format. * @brief Converts the environment variables hashmap to an envp array format.
* *
@@ -105,7 +118,7 @@ void set_env(
* environment hashmap and converts them into a NULL-terminated array of * environment hashmap and converts them into a NULL-terminated array of
* strings in the format "KEY=VALUE". * strings in the format "KEY=VALUE".
* *
* @param msh Pointer to the minishell structure containing the environment * @param minishell Pointer to the minishell structure containing the environment
* variables hashmap. * variables hashmap.
* *
* @return A dynamically allocated array of strings representing environment * @return A dynamically allocated array of strings representing environment
@@ -120,17 +133,18 @@ void set_env(
* the NULL terminator. * the NULL terminator.
*/ */
char **get_envp( char **get_envp(
t_minishell *msh t_minishell *minishell
) { )
{
char **envp; char **envp;
t_list *env_list; t_list *env_list;
t_list *env; t_list *env;
t_map_entry *entry; t_map_entry *entry;
size_t i; size_t i;
env_list = ft_hashmap_entries(msh->variables.environment); env_list = ft_hashmap_entries(minishell->variables.environment);
envp = (char **)malloc( envp = (char **)malloc(
(msh->variables.environment->size + 1) * sizeof(char *) (minishell->variables.environment->size + 1) * sizeof(char *)
); );
if (envp != NULL) if (envp != NULL)
{ {
@@ -149,44 +163,39 @@ char **get_envp(
} }
/** /**
* @brief Frees a dynamically allocated environment variables array * @brief Parses and stores environment variables from envp array into a hashmap
* *
* This function deallocates memory for an array of strings that was previously * This function iterates through the environment variables array (envp) and
* allocated by `get_envp()`. It iterates through each string in the array, * splits each variable string on the '=' delimiter to separate the variable
* frees the memory for individual strings, and then frees the array itself. * name from its value. Each name-value pair is then stored in the minishell's
* environment hashmap for later retrieval.
* *
* @param envp Pointer to the array of environment variable strings to be freed. * @param envp Array of environment variable strings in "NAME=value" format
* Each string in the array should be dynamically allocated. * @param minishell Pointer to the minishell structure containing the environment
* The array must be NULL-terminated. * hashmap
*
* @note The function assumes envp strings are in the standard format
* "NAME=value"
*/ */
void free_envp( void set_envp(
char **envp char **envp,
) { t_minishell *minishell
size_t i; )
{
t_hashmap **environment;
char **key_value;
i = -1; if (minishell == NULL || envp == NULL)
while (envp[++i] != NULL) return ;
free(envp[i]); environment = &minishell->variables.environment;
free(envp); *environment = ft_hashmap_new(32, ft_hashmap_hashstr, ft_hashmap_strcmp);
} if (*environment == NULL)
return ;
/** while (*envp != NULL)
* @brief Retrieves the value of an environment variable from the shell's {
* environment hashmap. key_value = ft_split(*envp, '=');
* set_env(key_value[0], key_value[1], minishell);
* This function searches for the specified environment variable name in the ft_free_split(key_value);
* minishell's environment variable hashmap and returns its associated value. envp++;
* }
* @param env_name The name of the environment variable to retrieve (e.g.,
* "PATH", "HOME")
* @param msh Pointer to the minishell structure containing the environment
* variables hashmap
*
* @return The value of the environment variable if found, NULL if not found
*/
char *get_env(
const char *env_name,
t_minishell *msh
) {
return (ft_hashmap_get(msh->variables.environment, env_name));
} }

View File

@@ -1,41 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* environment_unset.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/09 22:16:00 by codex #+# #+# */
/* Updated: 2026/02/09 22:16:00 by codex ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
#include "core.h"
void unset_env(
const char *env_name,
t_minishell *msh
){
t_hashmap *new_env;
t_list *entries;
t_list *current;
t_map_entry *entry;
new_env = ft_hashmap_new(32, ft_hashmap_hashstr, ft_hashmap_strcmp);
if (new_env == NULL)
return ;
entries = ft_hashmap_entries(msh->variables.environment);
current = entries;
while (current != NULL)
{
entry = current->content;
if (ft_strcmp(entry->key, env_name) != 0)
ft_hashmap_put(new_env,
ft_strdup(entry->key), ft_strdup(entry->value));
current = current->next;
}
ft_lstclear_nodes(&entries);
ft_hashmap_clear(&msh->variables.environment, free);
msh->variables.environment = new_env;
}

View File

@@ -0,0 +1,120 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* internal.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/13 21:29:43 by sede-san #+# #+# */
/* Updated: 2026/02/14 01:39:36 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
#include "core.h"
#include "errors.h"
/**
* @brief Retrieves the value of an internal variable by name.
*
* @param name The name of the internal variable to retrieve.
* @param minishell Pointer to the minishell structure.
*
* @return The value of the internal variable if found, or NULL if not found.
*/
char *get_int(
const char *name,
t_minishell *minishell
)
{
return (ft_hashmap_get(minishell->variables.internal, name));
}
/**
* @brief Stores a variable as internal.
*
* @param name The name of the internal variable to set.
* @param value The value to associate with the internal variable.
* @param minishell Pointer to the minishell structure.
*
* @note If the internal variable already exists, its value will be updated and
* the old value will be freed. If it does not exist, a new internal
* variable will be created.
*/
void set_int(
const char *name,
char *value,
t_minishell *minishell
)
{
t_hashmap *internal;
char *key;
char *val;
char *old_val;
internal = minishell->variables.internal;
key = (char *)name;
if (key != NULL && !ft_hashmap_contains_key(internal, key))
{
key = ft_strdup(name);
if (key == NULL)
return (minishell->exit = true, malloc_error());
}
val = value;
if (val != NULL)
val = ft_strdup(value);
if (val == NULL)
{
if (key != name)
free(key);
return (minishell->exit = true, malloc_error());
}
old_val = ft_hashmap_put(internal, key, val);
if (old_val != NULL)
free(old_val);
}
/**
* @brief Removes an internal variable by name.
*
* @param name The name of the internal variable to remove.
* @param minishell Pointer to the minishell structure.
*
* @note If the internal variable exists, it will be removed from the hashmap
* and its associated value will be freed.
*/
void unset_int(
const char *name,
t_minishell *minishell
)
{
char *value;
value = ft_hashmap_remove(minishell->variables.internal, (void *)name);
if (value != NULL)
free(value);
}
/**
* @brief Initializes the internal variables hashmap with default values.
*
* @param minishell Pointer to the minishell structure to initialize.
*
* @warning This function must be called only once during the initialization of
* the minishell.
*/
void set_intp(
t_minishell *minishell
)
{
if (minishell == NULL)
return ;
minishell->variables.internal
= ft_hashmap_new(16, ft_hashmap_hashstr, ft_hashmap_strcmp);
if (minishell->variables.internal == NULL)
return ;
set_int("?", "0", minishell);
set_int("_", "minishell", minishell);
set_int("PS1", DEFAULT_PS1, minishell);
set_int("PS2", DEFAULT_PS2, minishell);
}

50
src/variables/variables.c Normal file
View File

@@ -0,0 +1,50 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* variables.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: sede-san <sede-san@student.42madrid.com +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/02/13 21:41:44 by sede-san #+# #+# */
/* Updated: 2026/02/14 00:52:12 by sede-san ### ########.fr */
/* */
/* ************************************************************************** */
#include "variables.h"
/**
* @brief Retrieves the value of a variable by name.
*
* @param name The name of the variable to retrieve.
* @param minishell Pointer to the minishell structure.
*
* @return The value of the variable if found, or NULL if not found.
*/
char *get_var(
const char *name,
t_minishell *minishell
)
{
char *value;
value = get_int(name, minishell);
if (value == NULL)
value = get_env(name, minishell);
return (value);
}
void set_var(const char *name, char *value, t_minishell *minishell)
{
if (ft_hashmap_contains_key(minishell->variables.internal, name))
set_int(name, value, minishell);
set_env(name, value, minishell);
}
void unset_var(
const char *name,
t_minishell *minishell
)
{
unset_int(name, minishell);
unset_env(name, minishell);
}