heredoc and builtins fix

This commit is contained in:
marcnava-42cursus
2026-02-14 14:26:58 +01:00
parent ba40670ace
commit 73ed56aa16
29 changed files with 1107 additions and 155 deletions

View File

@@ -12,8 +12,18 @@
#include "builtins.h"
static uint8_t is_valid_identifier(const char *arg, size_t name_len);
static uint8_t export_one(char *arg, t_minishell *msh);
static uint8_t print_exported(t_minishell *msh);
static void **entries_to_array(t_list *lst, size_t *count,
bool add_oldpwd);
static void sort_entries(t_map_entry **entries, size_t count);
bool export_is_valid_identifier(const char *arg, size_t name_len);
void export_parse_assignment(char *arg, char **eq_pos,
size_t *name_len, bool *append);
uint8_t export_set_assigned_value(const char *name, char *eq_pos,
bool append, t_minishell *msh);
bool export_print_declaration(const char *name, const char *value);
static t_map_entry g_oldpwd_entry = {"OLDPWD", NULL};
uint8_t builtin_export(
t_command cmd,
@@ -21,36 +31,24 @@ uint8_t builtin_export(
)
{
uint8_t status;
uint8_t result;
size_t i;
if (cmd.argc == 1)
return (builtin_env(cmd, msh));
return (print_exported(msh));
status = EXIT_SUCCESS;
i = 0;
while (cmd.argv[++i] != NULL)
if (export_one(cmd.argv[i], msh) != EXIT_SUCCESS)
{
result = export_one(cmd.argv[i], msh);
if (result == 2)
return (2);
if (result != EXIT_SUCCESS)
status = EXIT_FAILURE;
}
return (status);
}
static uint8_t is_valid_identifier(
const char *arg,
size_t name_len
)
{
size_t i;
if (name_len == 0 || arg == NULL)
return (0);
if (!ft_isalpha(arg[0]) && arg[0] != '_')
return (0);
i = 0;
while (++i < name_len)
if (!ft_isalnum(arg[i]) && arg[i] != '_')
return (0);
return (1);
}
static uint8_t export_one(
char *arg,
t_minishell *msh
@@ -59,21 +57,111 @@ static uint8_t export_one(
char *eq_pos;
char *name;
size_t name_len;
bool append;
eq_pos = ft_strchr(arg, '=');
name_len = ft_strlen(arg);
if (eq_pos != NULL)
name_len = (size_t)(eq_pos - arg);
if (!is_valid_identifier(arg, name_len))
return (ft_eprintf("minishell: export: `%s': not a valid identifier\n",
arg), EXIT_FAILURE);
if (arg[0] == '-' && arg[1] != '\0')
return (ft_eprintf("minishell: export: %s: invalid option\n", arg),
ft_eputendl("export: usage: export [name[=value] ...]"), 2);
export_parse_assignment(arg, &eq_pos, &name_len, &append);
if (!export_is_valid_identifier(arg, name_len))
return (ft_eprintf(
"minishell: export: `%s': not a valid identifier\n", arg),
EXIT_FAILURE);
name = ft_substr(arg, 0, name_len);
if (name == NULL)
return (EXIT_FAILURE);
if (eq_pos != NULL)
set_var(name, eq_pos + 1, msh);
else
set_var(name, "", msh);
if (export_set_assigned_value(name, eq_pos, append, msh) != EXIT_SUCCESS)
return (free(name), EXIT_FAILURE);
free(name);
return (EXIT_SUCCESS);
}
static uint8_t print_exported(
t_minishell *msh
)
{
t_list *entries;
t_map_entry **sorted_entries;
size_t count;
size_t i;
bool add_oldpwd;
entries = ft_hashmap_entries(msh->variables.environment);
if (entries == NULL)
return (EXIT_SUCCESS);
add_oldpwd = !ft_hashmap_contains_key(msh->variables.environment, "OLDPWD");
sorted_entries = (t_map_entry **)entries_to_array(entries, &count,
add_oldpwd);
ft_lstclear_nodes(&entries);
if (sorted_entries == NULL)
return (EXIT_FAILURE);
sort_entries(sorted_entries, count);
i = 0;
while (i < count)
{
if (!export_print_declaration((char *)sorted_entries[i]->key,
(char *)sorted_entries[i]->value))
return (free(sorted_entries), EXIT_FAILURE);
i++;
}
free(sorted_entries);
return (EXIT_SUCCESS);
}
static void **entries_to_array(
t_list *entries,
size_t *count,
bool add_oldpwd
)
{
void **array;
t_list *node;
t_map_entry *entry;
size_t i;
*count = (size_t)ft_lstsize(entries) + (size_t)add_oldpwd;
array = (void **)malloc(sizeof(void *) * (*count));
if (array == NULL)
return (NULL);
i = 0;
node = entries;
while (node != NULL)
{
entry = (t_map_entry *)node->content;
if (entry != NULL && ft_strcmp((char *)entry->key, "_") != 0)
array[i++] = entry;
node = node->next;
}
if (add_oldpwd)
array[i++] = &g_oldpwd_entry;
*count = i;
return (array);
}
static void sort_entries(
t_map_entry **entries,
size_t count
)
{
size_t i;
size_t j;
t_map_entry *tmp;
i = 0;
while (i < count)
{
j = i + 1;
while (j < count)
{
if (ft_strcmp((char *)entries[i]->key,
(char *)entries[j]->key) > 0)
{
tmp = entries[i];
entries[i] = entries[j];
entries[j] = tmp;
}
j++;
}
i++;
}
}