Implement variables framework, update Libft
authorLukas Jiriste <ljiriste@student.42prague.com>
Thu, 2 May 2024 11:27:09 +0000 (13:27 +0200)
committerLukas Jiriste <ljiriste@student.42prague.com>
Thu, 2 May 2024 12:00:21 +0000 (14:00 +0200)
So far the variable handling consists of copying the environment
inherited by minishell to separate variable to make changes to it
possible (I suspect that one should not directly change the environ).

The vars struct consists of 2 vectos of strings, one for the exported
variables and one for the others.
This is done so that the exported->vec can be directly passed to execve
instead of contructing it by filtering the exported values from
a common vector.
This is also why the vector is initialized with NULL. The other vec
is constructed the same way so as to be able to reuse the code for
exported.

During work on this commit the function ft_strcat_alloc seemed to be
a great candidate for  addition to Libft. That was done and the
function was used in this commit, hence the Libft update.

Libft
Makefile
inc/minishell.h [new file with mode: 0644]
src/main.c
src/vars.c [new file with mode: 0644]

diff --git a/Libft b/Libft
index 580d3d9325f4105b5448a5f0e5503e6d105c6117..85fc90a5625657e074a2833cb5a51ffe9a0db255 160000 (submodule)
--- a/Libft
+++ b/Libft
@@ -1 +1 @@
-Subproject commit 580d3d9325f4105b5448a5f0e5503e6d105c6117
+Subproject commit 85fc90a5625657e074a2833cb5a51ffe9a0db255
index 9166aa6cfdf2a2d4fda0b605b880da41253936de..573dd599d2608530c056fcfb1cbb96057b79c1b3 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,6 +15,7 @@ INCLUDE := $(addprefix -I, $(INCDIR))
 SRCDIR := src
 
 SOURCES :=     main.c                  \
+                       vars.c                  \
 
 SOURCES := $(addprefix $(SRCDIR)/, $(SOURCES))
 
diff --git a/inc/minishell.h b/inc/minishell.h
new file mode 100644 (file)
index 0000000..06a02cc
--- /dev/null
@@ -0,0 +1,29 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   minishell.h                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/05/02 13:22:57 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/05/02 13:25:41 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#ifndef MINISHELL_H
+# define MINISHELL_H
+
+# include "libft.h"
+
+typedef struct s_vars
+{
+       t_vec   exported;
+       t_vec   other;
+}                      t_vars;
+
+int            init_vars(t_vars *vars, char **envp);
+int            add_var_line(t_vec *vec, const char *line);
+int            add_var(t_vec *vec, const char *key, const char *value);
+void   clean_vars(t_vars *vars);
+
+#endif // MINISHELL_H
index 59d0bf713f8c369fc803bdb872a6ef50182f635a..52c5889807f573f9cb0e1c4dc0e702bf5f48ed91 100644 (file)
@@ -6,10 +6,11 @@
 /*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/04/26 13:11:47 by ljiriste          #+#    #+#             */
-/*   Updated: 2024/04/26 14:13:15 by ljiriste         ###   ########.fr       */
+/*   Updated: 2024/05/02 13:54:36 by ljiriste         ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
+#include "minishell.h"
 #include "libft.h"
 #include <stdlib.h>
 #include <unistd.h>                            // getcwd
@@ -50,25 +51,49 @@ char        *rl_get_line(void)
        return (line);
 }
 
-void   handle_input(__attribute__((unused)) const char *input)
+void   handle_input(__attribute__((unused)) const char *input, __attribute__((unused)) t_vars *vars)
 {
        return ;
 }
 
-int main(void)
+void   print_help(void)
+{
+       ft_printf("Minishell should be used without any arguments.\n");
+       return ;
+}
+
+/*
+// This would be more portable than the main with 3 input args
+extern char    **environ;
+const char     **envp = environ;
+int    main(int argc, char **argv)
+*/
+int    main(int argc, __attribute__((unused)) char **argv, char **envp)
 {
        char    *line;
+       t_vars  vars;
 
+       if (argc > 1)
+       {
+               print_help();
+               return (1);
+       }
+       if (init_vars(&vars, envp))
+       {
+               clean_vars(&vars);
+               return (2);
+       }
        while (1)
        {
                line = rl_get_line();
                if (!line || !ft_strcmp(line, "exit"))
-               {
-                       rl_clear_history();
-                       ft_printf("exit\n");
-                       return (0);
-               }
-               handle_input(line);
+                       break ;
+               handle_input(line, &vars);
                free(line);
        }
+       rl_clear_history();
+       clean_vars(&vars);
+       free(line);
+       ft_printf("exit\n");
+       return (0);
 }
diff --git a/src/vars.c b/src/vars.c
new file mode 100644 (file)
index 0000000..8b11d6d
--- /dev/null
@@ -0,0 +1,85 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   vars.c                                             :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: ljiriste <marvin@42.fr>                    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2024/05/02 13:21:32 by ljiriste          #+#    #+#             */
+/*   Updated: 2024/05/02 13:24:39 by ljiriste         ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "minishell.h"
+#include "libft.h"
+#include <stdlib.h>
+
+int    add_var_line(t_vec *vec, const char *line)
+{
+       char    *tmp;
+
+       tmp = ft_strdup(line);
+       if (!tmp)
+               return (1);
+       if (ft_vec_insert(vec, &tmp, vec->size - 1) != success)
+       {
+               free(tmp);
+               return (1);
+       }
+       return (0);
+}
+
+// The keyval_pair is freed only in case of error
+// When allocation fails in ft_strcal_alloc, it is freed automatically
+// When allocation the insert fails, it needs to be freed here
+// When everything goes smoothly, the memory is freed when the vec
+// erases this entry
+int    add_var(t_vec *vec, const char *key, const char *value)
+{
+       char    *keyval_pair;
+
+       keyval_pair = ft_strdup(key);
+       if (!keyval_pair)
+               return (1);
+       if (!ft_strcat_alloc(&keyval_pair, "="))
+               return (1);
+       if (!ft_strcat_alloc(&keyval_pair, value))
+               return (1);
+       if (ft_vec_insert(vec, &keyval_pair, vec->size - 1) != success)
+       {
+               free(keyval_pair);
+               return (1);
+       }
+       return (0);
+}
+
+int    init_vars(t_vars *vars, char **envp)
+{
+       char    *tmp;
+
+       ft_vec_init(&vars->exported, sizeof(char *));
+       ft_vec_init(&vars->other, sizeof(char *));
+       tmp = NULL;
+       ft_vec_append(&vars->exported, &tmp);
+       ft_vec_append(&vars->other, &tmp);
+       while (*envp)
+       {
+               if (add_var_line(&vars->exported, *envp))
+                       return (1);
+               ++envp;
+       }
+       return (0);
+}
+
+static void    free_str(void *str)
+{
+       free(*(char **)str);
+       return ;
+}
+
+void   clean_vars(t_vars *vars)
+{
+       ft_vec_free(&vars->exported, free_str);
+       ft_vec_free(&vars->other, free_str);
+       return ;
+}