]> git.dkaiser.de - 42/minishell.git/commitdiff
kinda fix for pipe error and again.vs for you db just chnage workfolder gn
authorChristopher Uhlig <chuhlig@3-G-5.42heilbronn.de>
Wed, 22 Jan 2025 01:40:27 +0000 (02:40 +0100)
committerChristopher Uhlig <chuhlig@3-G-5.42heilbronn.de>
Wed, 22 Jan 2025 01:40:27 +0000 (02:40 +0100)
102 files changed:
.vscode/c_cpp_properties.json [new file with mode: 0644]
.vscode/launch copy.json [new file with mode: 0644]
.vscode/launch.json [new file with mode: 0644]
.vscode/settings.json [new file with mode: 0644]
.vscode/tasks copy.json [new file with mode: 0644]
.vscode/tasks.json [new file with mode: 0644]
Makefile
include/ast.h
include/debug_tools.h
include/env.h
include/minishell.h
include/token.h
lib/libft/_obj/ft_atoi.o [new file with mode: 0644]
lib/libft/_obj/ft_atol.o [new file with mode: 0644]
lib/libft/_obj/ft_bzero.o [new file with mode: 0644]
lib/libft/_obj/ft_calloc.o [new file with mode: 0644]
lib/libft/_obj/ft_isalnum.o [new file with mode: 0644]
lib/libft/_obj/ft_isalpha.o [new file with mode: 0644]
lib/libft/_obj/ft_isascii.o [new file with mode: 0644]
lib/libft/_obj/ft_isdigit.o [new file with mode: 0644]
lib/libft/_obj/ft_isprint.o [new file with mode: 0644]
lib/libft/_obj/ft_isspace.o [new file with mode: 0644]
lib/libft/_obj/ft_itoa.o [new file with mode: 0644]
lib/libft/_obj/ft_lstadd_back_bonus.o [new file with mode: 0644]
lib/libft/_obj/ft_lstadd_front_bonus.o [new file with mode: 0644]
lib/libft/_obj/ft_lstclear_bonus.o [new file with mode: 0644]
lib/libft/_obj/ft_lstdelone_bonus.o [new file with mode: 0644]
lib/libft/_obj/ft_lstiter_bonus.o [new file with mode: 0644]
lib/libft/_obj/ft_lstlast_bonus.o [new file with mode: 0644]
lib/libft/_obj/ft_lstmap_bonus.o [new file with mode: 0644]
lib/libft/_obj/ft_lstnew_bonus.o [new file with mode: 0644]
lib/libft/_obj/ft_lstsize_bonus.o [new file with mode: 0644]
lib/libft/_obj/ft_memchr.o [new file with mode: 0644]
lib/libft/_obj/ft_memcmp.o [new file with mode: 0644]
lib/libft/_obj/ft_memcpy.o [new file with mode: 0644]
lib/libft/_obj/ft_memmove.o [new file with mode: 0644]
lib/libft/_obj/ft_memset.o [new file with mode: 0644]
lib/libft/_obj/ft_printaddr.o [new file with mode: 0644]
lib/libft/_obj/ft_printf.o [new file with mode: 0644]
lib/libft/_obj/ft_printhex.o [new file with mode: 0644]
lib/libft/_obj/ft_printnbr.o [new file with mode: 0644]
lib/libft/_obj/ft_putchar_fd.o [new file with mode: 0644]
lib/libft/_obj/ft_putendl_fd.o [new file with mode: 0644]
lib/libft/_obj/ft_putnbr_fd.o [new file with mode: 0644]
lib/libft/_obj/ft_putstr_fd.o [new file with mode: 0644]
lib/libft/_obj/ft_split.o [new file with mode: 0644]
lib/libft/_obj/ft_strcat.o [new file with mode: 0644]
lib/libft/_obj/ft_strchr.o [new file with mode: 0644]
lib/libft/_obj/ft_strcmp.o [new file with mode: 0644]
lib/libft/_obj/ft_strcpy.o [new file with mode: 0644]
lib/libft/_obj/ft_strdup.o [new file with mode: 0644]
lib/libft/_obj/ft_striteri.o [new file with mode: 0644]
lib/libft/_obj/ft_strjoin.o [new file with mode: 0644]
lib/libft/_obj/ft_strlcat.o [new file with mode: 0644]
lib/libft/_obj/ft_strlcpy.o [new file with mode: 0644]
lib/libft/_obj/ft_strlen.o [new file with mode: 0644]
lib/libft/_obj/ft_strmapi.o [new file with mode: 0644]
lib/libft/_obj/ft_strncmp.o [new file with mode: 0644]
lib/libft/_obj/ft_strncpy.o [new file with mode: 0644]
lib/libft/_obj/ft_strnstr.o [new file with mode: 0644]
lib/libft/_obj/ft_strrchr.o [new file with mode: 0644]
lib/libft/_obj/ft_strtrim.o [new file with mode: 0644]
lib/libft/_obj/ft_substr.o [new file with mode: 0644]
lib/libft/_obj/ft_tolower.o [new file with mode: 0644]
lib/libft/_obj/ft_toupper.o [new file with mode: 0644]
lib/libft/_obj/get_next_line.o [new file with mode: 0644]
lib/libft/_obj/get_next_line_utils.o [new file with mode: 0644]
lib/libft/ft_split.c
lib/libft/ft_strcat.c
lib/libft/ft_strcmp.c
lib/libft/ft_strcpy.c
lib/libft/ft_strjoin.c
lib/libft/libft.a [new file with mode: 0644]
src/builtins_part_one.c
src/builtins_part_three.c [new file with mode: 0644]
src/builtins_part_two.c
src/collect_redirs.c
src/create_files.c [new file with mode: 0644]
src/debug_tools.c
src/env.c
src/env_to_strlst.c
src/env_tools.c [new file with mode: 0644]
src/error.c [new file with mode: 0644]
src/execute_cmd.c
src/format_string.c
src/free_node.c
src/free_token.c
src/get_cmd_path.c
src/handle_redir.c [new file with mode: 0644]
src/init.c
src/interpreter.c
src/main.c
src/new_node.c
src/new_token.c
src/parse_cmd.c
src/parser.c
src/praise_the_norme.c [new file with mode: 0644]
src/read_heredoc.c [new file with mode: 0644]
src/repl.c
src/signal_handling.c
src/tokenizer.c
valgrind_out.txt [new file with mode: 0644]

diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
new file mode 100644 (file)
index 0000000..94b2ae4
--- /dev/null
@@ -0,0 +1,18 @@
+{
+       "configurations": [
+         {
+               "name": "macos-clang-x64",
+               "includePath": [
+                 "${workspaceFolder}/**"
+               ],
+               "compilerPath": "/usr/bin/clang",
+               "cStandard": "${default}",
+               "cppStandard": "${default}",
+               "intelliSenseMode": "macos-clang-x64",
+               "compilerArgs": [
+                 ""
+               ]
+         }
+       ],
+       "version": 4
+  }
\ No newline at end of file
diff --git a/.vscode/launch copy.json b/.vscode/launch copy.json
new file mode 100644 (file)
index 0000000..6dcd55f
--- /dev/null
@@ -0,0 +1,13 @@
+{
+       "version": "0.2.0",
+       "configurations": [
+         {
+               "name": "C/C++ Runner: Debug Session",
+               "type": "lldb",
+               "request": "launch",
+               "args": [],
+               "cwd": "/Users/chuhlig/Documents/",
+               "program": "/Users/chuhlig/Documents/minishell"
+         }
+       ]
+  }
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644 (file)
index 0000000..6dcd55f
--- /dev/null
@@ -0,0 +1,13 @@
+{
+       "version": "0.2.0",
+       "configurations": [
+         {
+               "name": "C/C++ Runner: Debug Session",
+               "type": "lldb",
+               "request": "launch",
+               "args": [],
+               "cwd": "/Users/chuhlig/Documents/",
+               "program": "/Users/chuhlig/Documents/minishell"
+         }
+       ]
+  }
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644 (file)
index 0000000..91f5074
--- /dev/null
@@ -0,0 +1,65 @@
+{
+       "C_Cpp_Runner.cCompilerPath": "clang",
+       "C_Cpp_Runner.cppCompilerPath": "clang++",
+       "C_Cpp_Runner.debuggerPath": "lldb",
+       "C_Cpp_Runner.cStandard": "",
+       "C_Cpp_Runner.cppStandard": "",
+       "C_Cpp_Runner.msvcBatchPath": "",
+       "C_Cpp_Runner.useMsvc": false,
+       "C_Cpp_Runner.warnings": [
+         "-Wall",
+         "-Wextra",
+         "-Wpedantic",
+         "-Wshadow",
+         "-Wformat=2",
+         "-Wcast-align",
+         "-Wconversion",
+         "-Wsign-conversion",
+         "-Wnull-dereference"
+       ],
+       "C_Cpp_Runner.msvcWarnings": [
+         "/W4",
+         "/permissive-",
+         "/w14242",
+         "/w14287",
+         "/w14296",
+         "/w14311",
+         "/w14826",
+         "/w44062",
+         "/w44242",
+         "/w14905",
+         "/w14906",
+         "/w14263",
+         "/w44265",
+         "/w14928"
+       ],
+       "C_Cpp_Runner.enableWarnings": true,
+       "C_Cpp_Runner.warningsAsError": false,
+       "C_Cpp_Runner.compilerArgs": [],
+       "C_Cpp_Runner.linkerArgs": [],
+       "C_Cpp_Runner.includePaths": [],
+       "C_Cpp_Runner.includeSearch": [
+         "*",
+         "**/*"
+       ],
+       "C_Cpp_Runner.excludeSearch": [
+         "**/build",
+         "**/build/**",
+         "**/.*",
+         "**/.*/**",
+         "**/.vscode",
+         "**/.vscode/**"
+       ],
+       "C_Cpp_Runner.useAddressSanitizer": false,
+       "C_Cpp_Runner.useUndefinedSanitizer": false,
+       "C_Cpp_Runner.useLeakSanitizer": false,
+       "C_Cpp_Runner.showCompilationTime": false,
+       "C_Cpp_Runner.useLinkTimeOptimization": false,
+       "C_Cpp_Runner.msvcSecureNoWarnings": false,
+       "files.associations": {
+               "minishell.h": "c",
+               "debug_tools.h": "c",
+               "token.h": "c",
+               "ios": "c"
+       }
+  }
\ No newline at end of file
diff --git a/.vscode/tasks copy.json b/.vscode/tasks copy.json
new file mode 100644 (file)
index 0000000..4ede37a
--- /dev/null
@@ -0,0 +1,29 @@
+{
+    "tasks": [
+        {
+            "type": "cppbuild",
+            "label": "C/C++: clang build active file",
+            "command": "/usr/bin/clang",
+            "args": [
+                "-fcolor-diagnostics",
+                "-fansi-escape-codes",
+                "-g",
+                "${file}",
+                "-o",
+                "${fileDirname}/${fileBasenameNoExtension}"
+            ],
+            "options": {
+                "cwd": "${fileDirname}"
+            },
+            "problemMatcher": [
+                "$gcc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            },
+            "detail": "Task generated by Debugger."
+        }
+    ],
+    "version": "2.0.0"
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644 (file)
index 0000000..4ede37a
--- /dev/null
@@ -0,0 +1,29 @@
+{
+    "tasks": [
+        {
+            "type": "cppbuild",
+            "label": "C/C++: clang build active file",
+            "command": "/usr/bin/clang",
+            "args": [
+                "-fcolor-diagnostics",
+                "-fansi-escape-codes",
+                "-g",
+                "${file}",
+                "-o",
+                "${fileDirname}/${fileBasenameNoExtension}"
+            ],
+            "options": {
+                "cwd": "${fileDirname}"
+            },
+            "problemMatcher": [
+                "$gcc"
+            ],
+            "group": {
+                "kind": "build",
+                "isDefault": true
+            },
+            "detail": "Task generated by Debugger."
+        }
+    ],
+    "version": "2.0.0"
+}
\ No newline at end of file
index 7cfc8940f2c0a675efd65b2a15ed6845063015f6..568a7a36d475431c4bb67ee82c2c9e2e7531509f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@
 NAME    := minishell
 
 CC      =  cc
-CFLAGS  =  -Wall -Wextra -Werror
+CFLAGS  =  -Wall -Wextra -g
 LIB_DIR = lib
 LIBS    =  -L $(LIB_DIR)/libft -lft -lreadline
 HEADERS =  -I include -I $(LIB_DIR)/libft
@@ -19,7 +19,9 @@ SRC     := main.c debug_tools.c init.c signal_handling.c repl.c new_token.c \
            free_token.c new_node.c free_node.c tokenizer.c parser.c \
            parse_cmd.c collect_redirs.c print_ast.c interpreter.c env.c \
            get_cmd_path.c env_to_strlst.c execute_cmd.c format_string.c \
-                  builtins_part_one.c builtins_part_two.c
+                  builtins_part_one.c builtins_part_two.c env_tools.c error.c \
+                  read_heredoc.c create_files.c builtins_part_three.c handle_redir.c \
+                  praise_the_norme.c
 
 OBJ_DIR := _obj
 OBJ     := $(addprefix $(OBJ_DIR)/, $(SRC:%.c=%.o))
@@ -30,18 +32,18 @@ OBJ     := $(addprefix $(OBJ_DIR)/, $(SRC:%.c=%.o))
 
 all: libs $(NAME)
 
-$(NAME): $(OBJ)
-       @$(CC) $(CFLAGS) $(HEADERS) $(LIBS) $^ -o $@
-       @echo "[$(NAME)] Created binary."
-
 libs:
        @make -C $(LIB_DIR)/libft
 
+$(NAME): $(OBJ)
+       @$(CC) $(CFLAGS) $^ -o $@ $(HEADERS) $(LIBS) 
+       @echo "[$(NAME)] Created binary."
+
 $(OBJ_DIR)/%.o: %.c
        @if [ ! -d "$(dir $@)" ]; then \
                mkdir -p $(dir $@); \
        fi
-       @$(CC) $(CFLAGS) $(HEADERS) -c $< -o $@
+       @$(CC) $(CFLAGS) -c $< -o $@ $(HEADERS)
        @echo "[$(NAME)] Compiled $<."
 
 clean:
@@ -63,7 +65,9 @@ debug: CFLAGS += -g
 debug: CFLAGS += -fsanitize=address -fsanitize=undefined \
                                 -fno-sanitize-recover=all -fsanitize=float-divide-by-zero \
                                 -fsanitize=float-cast-overflow -fno-sanitize=null \
-                                -fno-sanitize=alignment
+                                -fno-sanitize=alignment -fno-sanitize=object-size \
+                                -fno-sanitize=vptr -fno-sanitize=return -fno-sanitize=signed-integer-overflow \
+                                -fno-sanitize=bounds -fno-sanitize=pointer-subtract -fno-sanitize=pointer-compare
 debug: CFLAGS += -DDEBUG=1
 debug: clean all
 
index cd2f9c9eff893a1c1506a503043e20d0071af83c..0dede5083972242c01c0c8f02750d227f4ee5861 100644 (file)
@@ -3,15 +3,17 @@
 /*                                                        :::      ::::::::   */
 /*   ast.h                                              :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/27 11:48:27 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/08/11 12:20:56 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/18 19:28:51 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
-#include "debug_tools.h"
-#include "stdlib.h"
+#ifndef AST_H
+# define AST_H
+# include "debug_tools.h"
+# include "stdlib.h"
 
 enum                                           e_node_type
 {
@@ -44,6 +46,7 @@ typedef struct s_cmd
 {
        char                                    **args;
        struct s_redirection    redirs[2];
+       t_list                                  *create_files;
 }                                                      t_cmd;
 
 union                                          u_node_content
@@ -61,7 +64,10 @@ typedef struct s_node
 
 t_node                                         *new_node(int type);
 t_node                                         *new_pipe_node(t_node *left, t_node *right);
-t_node                                         *new_cmd_node(char **args, t_redirection redirs[2]);
+t_node                                         *new_cmd_node(char **args, t_redirection redirs[2],
+                                                               t_list *create_files);
 t_node                                         *new_string_node(char *string);
 
 void                                           free_node(t_node *node);
+
+#endif
\ No newline at end of file
index 4a7ff109419ae6423b2750d2cf1e84e3393c6396..3f3dd2683e024e4f630b58678e7f23a99022816d 100644 (file)
@@ -3,17 +3,17 @@
 /*                                                        :::      ::::::::   */
 /*   debug_tools.h                                      :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/24 18:34:37 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/06/28 15:05:12 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/20 19:38:02 by dkaiser          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #ifndef DEBUG_TOOLS_H
 # define DEBUG_TOOLS_H
-
 # include "libft.h"
+# include <stdarg.h>
 
 # ifndef DEBUG
 #  define DEBUG 0
@@ -22,4 +22,5 @@
 
 void   dbg(char *str);
 void   panic(char *msg);
+
 #endif
index d38ed290da8323430cb8788047ee30f65d5dee98..bfb28c7c0f7c05ab3bdc269af88ece5116a08fed 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/08/08 16:53:39 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/12/24 16:21:50 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/20 16:48:57 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -22,6 +22,7 @@ typedef struct s_env
        struct s_env    *next;
 }                                      t_env;
 
+void   free_env_node(t_env *node);
 void   getenvlst(t_env **env, char **en);
 void   free_envlst(t_env **env);
 char   *env_get(t_env *env, char *name);
@@ -29,10 +30,14 @@ char        **env_to_strlst(t_env *env);
 void   update_oldpwd(t_env **env);
 void   update_pwd(t_env **env);
 int            unset(char **av, t_env **env);
-int            export(char **av, t_env **env);
+int            export(char **av, t_env **env, int f);
 int            echo(char **av);
 int            pwd(t_env *env);
 int            cd(t_env **env, char **args);
 int            ft_env(t_env *env);
+int            builtin_exit(char **args, t_env **env);
+t_env  *env_new(char *name);
+t_env  *check_existing(t_env *env, char *av);
+int            check_flag(int f);
 
-#endif
\ No newline at end of file
+#endif
index 028a4fcc30612e7026dfdf966e1b14d214664bda..06abb04d4ab58081c33161d2e6cdd38b77e15c50 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/22 17:14:49 by dkaiser           #+#    #+#             */
-/*   Updated: 2025/01/11 16:05:11 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/21 20:20:09 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 # include <stdlib.h>
 # include <termios.h>
 # include <unistd.h>
+# include <fcntl.h>
 
 int                            init(void);
 int                            init_signal_handling(void);
 
-void                   repl(const char *prompt, t_env **env);
+void                   repl(const char *prompt, t_env **env, int *promptflag);
 
-t_list                 *parse(t_token *tokens, t_env **env);
+t_node                 *parse(t_token *tokens, t_env **env);
 t_node                 *parse_cmd(t_token *tokens, t_env **env);
-t_redirection  *collect_redirs(t_token **tokens);
+t_redirection  *collect_redirs(t_token **tokens, t_env *env, t_list **cf);
 
 void                   print_ast(t_node *ast);
+
 int                            eval(t_node *node, t_env **env);
-char                   *get_cmd_path(char *cmd, t_env *env);
+char                   *get_cmd_path(char *cmd, t_env *env, int *return_code);
 int                            execute_cmd(t_cmd *cmd, t_env **env);
-char                   *format_string(char *str, t_env *env);
+char                   *format_string(char *str, t_env *env, int is_literal);
+void                   set_return_code(int return_code, t_env **env);
+int                            handle_redirections(t_redirection *redirs);
+void                   *error(int err_code, char *err_text, int exit_code,
+                                       int *ret_code);
+void                   command_not_found_error(char *cmd);
+char                   *read_heredoc(char *delimiter);
+int                            handle_input_redirection(t_redirection *redir);
+int                            handle_output_redirection(t_redirection *redir);
+int                            handle_redirections(t_redirection *redirs);
+int                            handle_pipe_parent(int p[2], t_node *node, t_env **env);
+int                            handle_pipe_child(int p[2], t_node *node, t_env **env,
+                                       int in_fd);
+int                            open_file(char *path, int flags, int mode);
+int                            eval_rec(t_node *node, t_env **env, int in_fd);
+int                            create_files(t_list *files);
+void                   q4fc(t_list **queue, t_redirection *redir);
+void                   i_love_the_norme(t_token **cur, t_token **tokens);
 
+typedef struct s_minidata
+{
+       t_env           *env;
+       t_list          **create_files;
+}                              t_minidata;
 
 #endif
index 54a65f2a01302f0048adcaa902e3807d9f529a25..2e8da3501424eb093070eb2ded8bc8d297c727be 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/27 13:27:18 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/08/29 15:26:23 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/20 19:10:30 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -43,11 +43,11 @@ t_token                                             *new_str_token(char *str, t_token *previous,
                                                                t_token *next);
 t_token                                                *new_redir_token(int type, t_token *previous,
                                                                t_token *next);
-
+void                                           free_tokens(t_token *tokens);
 void                                           free_token(t_token *token);
 void                                           free_token_and_connect(t_token *token);
-void                                           free_tokens(t_token *tokens);
 void                                           tokenizer(char *s, t_token **token_list,
                                                                char quote_check);
+void                                           print_token(t_token *token);
 
 #endif
diff --git a/lib/libft/_obj/ft_atoi.o b/lib/libft/_obj/ft_atoi.o
new file mode 100644 (file)
index 0000000..b5601c8
Binary files /dev/null and b/lib/libft/_obj/ft_atoi.o differ
diff --git a/lib/libft/_obj/ft_atol.o b/lib/libft/_obj/ft_atol.o
new file mode 100644 (file)
index 0000000..ae1eb17
Binary files /dev/null and b/lib/libft/_obj/ft_atol.o differ
diff --git a/lib/libft/_obj/ft_bzero.o b/lib/libft/_obj/ft_bzero.o
new file mode 100644 (file)
index 0000000..14b59f2
Binary files /dev/null and b/lib/libft/_obj/ft_bzero.o differ
diff --git a/lib/libft/_obj/ft_calloc.o b/lib/libft/_obj/ft_calloc.o
new file mode 100644 (file)
index 0000000..7e3b83b
Binary files /dev/null and b/lib/libft/_obj/ft_calloc.o differ
diff --git a/lib/libft/_obj/ft_isalnum.o b/lib/libft/_obj/ft_isalnum.o
new file mode 100644 (file)
index 0000000..ffdb654
Binary files /dev/null and b/lib/libft/_obj/ft_isalnum.o differ
diff --git a/lib/libft/_obj/ft_isalpha.o b/lib/libft/_obj/ft_isalpha.o
new file mode 100644 (file)
index 0000000..3989dd3
Binary files /dev/null and b/lib/libft/_obj/ft_isalpha.o differ
diff --git a/lib/libft/_obj/ft_isascii.o b/lib/libft/_obj/ft_isascii.o
new file mode 100644 (file)
index 0000000..2023ffc
Binary files /dev/null and b/lib/libft/_obj/ft_isascii.o differ
diff --git a/lib/libft/_obj/ft_isdigit.o b/lib/libft/_obj/ft_isdigit.o
new file mode 100644 (file)
index 0000000..befcb64
Binary files /dev/null and b/lib/libft/_obj/ft_isdigit.o differ
diff --git a/lib/libft/_obj/ft_isprint.o b/lib/libft/_obj/ft_isprint.o
new file mode 100644 (file)
index 0000000..f75f178
Binary files /dev/null and b/lib/libft/_obj/ft_isprint.o differ
diff --git a/lib/libft/_obj/ft_isspace.o b/lib/libft/_obj/ft_isspace.o
new file mode 100644 (file)
index 0000000..6325fbb
Binary files /dev/null and b/lib/libft/_obj/ft_isspace.o differ
diff --git a/lib/libft/_obj/ft_itoa.o b/lib/libft/_obj/ft_itoa.o
new file mode 100644 (file)
index 0000000..a861d2b
Binary files /dev/null and b/lib/libft/_obj/ft_itoa.o differ
diff --git a/lib/libft/_obj/ft_lstadd_back_bonus.o b/lib/libft/_obj/ft_lstadd_back_bonus.o
new file mode 100644 (file)
index 0000000..b579431
Binary files /dev/null and b/lib/libft/_obj/ft_lstadd_back_bonus.o differ
diff --git a/lib/libft/_obj/ft_lstadd_front_bonus.o b/lib/libft/_obj/ft_lstadd_front_bonus.o
new file mode 100644 (file)
index 0000000..e72302f
Binary files /dev/null and b/lib/libft/_obj/ft_lstadd_front_bonus.o differ
diff --git a/lib/libft/_obj/ft_lstclear_bonus.o b/lib/libft/_obj/ft_lstclear_bonus.o
new file mode 100644 (file)
index 0000000..5bad20b
Binary files /dev/null and b/lib/libft/_obj/ft_lstclear_bonus.o differ
diff --git a/lib/libft/_obj/ft_lstdelone_bonus.o b/lib/libft/_obj/ft_lstdelone_bonus.o
new file mode 100644 (file)
index 0000000..3bc3219
Binary files /dev/null and b/lib/libft/_obj/ft_lstdelone_bonus.o differ
diff --git a/lib/libft/_obj/ft_lstiter_bonus.o b/lib/libft/_obj/ft_lstiter_bonus.o
new file mode 100644 (file)
index 0000000..025f21a
Binary files /dev/null and b/lib/libft/_obj/ft_lstiter_bonus.o differ
diff --git a/lib/libft/_obj/ft_lstlast_bonus.o b/lib/libft/_obj/ft_lstlast_bonus.o
new file mode 100644 (file)
index 0000000..b968ed3
Binary files /dev/null and b/lib/libft/_obj/ft_lstlast_bonus.o differ
diff --git a/lib/libft/_obj/ft_lstmap_bonus.o b/lib/libft/_obj/ft_lstmap_bonus.o
new file mode 100644 (file)
index 0000000..aa0df25
Binary files /dev/null and b/lib/libft/_obj/ft_lstmap_bonus.o differ
diff --git a/lib/libft/_obj/ft_lstnew_bonus.o b/lib/libft/_obj/ft_lstnew_bonus.o
new file mode 100644 (file)
index 0000000..1e5a07e
Binary files /dev/null and b/lib/libft/_obj/ft_lstnew_bonus.o differ
diff --git a/lib/libft/_obj/ft_lstsize_bonus.o b/lib/libft/_obj/ft_lstsize_bonus.o
new file mode 100644 (file)
index 0000000..f3ac188
Binary files /dev/null and b/lib/libft/_obj/ft_lstsize_bonus.o differ
diff --git a/lib/libft/_obj/ft_memchr.o b/lib/libft/_obj/ft_memchr.o
new file mode 100644 (file)
index 0000000..70158a2
Binary files /dev/null and b/lib/libft/_obj/ft_memchr.o differ
diff --git a/lib/libft/_obj/ft_memcmp.o b/lib/libft/_obj/ft_memcmp.o
new file mode 100644 (file)
index 0000000..1d24639
Binary files /dev/null and b/lib/libft/_obj/ft_memcmp.o differ
diff --git a/lib/libft/_obj/ft_memcpy.o b/lib/libft/_obj/ft_memcpy.o
new file mode 100644 (file)
index 0000000..62d92ff
Binary files /dev/null and b/lib/libft/_obj/ft_memcpy.o differ
diff --git a/lib/libft/_obj/ft_memmove.o b/lib/libft/_obj/ft_memmove.o
new file mode 100644 (file)
index 0000000..c49861b
Binary files /dev/null and b/lib/libft/_obj/ft_memmove.o differ
diff --git a/lib/libft/_obj/ft_memset.o b/lib/libft/_obj/ft_memset.o
new file mode 100644 (file)
index 0000000..f3d6f95
Binary files /dev/null and b/lib/libft/_obj/ft_memset.o differ
diff --git a/lib/libft/_obj/ft_printaddr.o b/lib/libft/_obj/ft_printaddr.o
new file mode 100644 (file)
index 0000000..1a108d4
Binary files /dev/null and b/lib/libft/_obj/ft_printaddr.o differ
diff --git a/lib/libft/_obj/ft_printf.o b/lib/libft/_obj/ft_printf.o
new file mode 100644 (file)
index 0000000..a2584ef
Binary files /dev/null and b/lib/libft/_obj/ft_printf.o differ
diff --git a/lib/libft/_obj/ft_printhex.o b/lib/libft/_obj/ft_printhex.o
new file mode 100644 (file)
index 0000000..3fec031
Binary files /dev/null and b/lib/libft/_obj/ft_printhex.o differ
diff --git a/lib/libft/_obj/ft_printnbr.o b/lib/libft/_obj/ft_printnbr.o
new file mode 100644 (file)
index 0000000..173d69e
Binary files /dev/null and b/lib/libft/_obj/ft_printnbr.o differ
diff --git a/lib/libft/_obj/ft_putchar_fd.o b/lib/libft/_obj/ft_putchar_fd.o
new file mode 100644 (file)
index 0000000..a3b55db
Binary files /dev/null and b/lib/libft/_obj/ft_putchar_fd.o differ
diff --git a/lib/libft/_obj/ft_putendl_fd.o b/lib/libft/_obj/ft_putendl_fd.o
new file mode 100644 (file)
index 0000000..99fe4b3
Binary files /dev/null and b/lib/libft/_obj/ft_putendl_fd.o differ
diff --git a/lib/libft/_obj/ft_putnbr_fd.o b/lib/libft/_obj/ft_putnbr_fd.o
new file mode 100644 (file)
index 0000000..7f2b2c3
Binary files /dev/null and b/lib/libft/_obj/ft_putnbr_fd.o differ
diff --git a/lib/libft/_obj/ft_putstr_fd.o b/lib/libft/_obj/ft_putstr_fd.o
new file mode 100644 (file)
index 0000000..dc75865
Binary files /dev/null and b/lib/libft/_obj/ft_putstr_fd.o differ
diff --git a/lib/libft/_obj/ft_split.o b/lib/libft/_obj/ft_split.o
new file mode 100644 (file)
index 0000000..c0742f5
Binary files /dev/null and b/lib/libft/_obj/ft_split.o differ
diff --git a/lib/libft/_obj/ft_strcat.o b/lib/libft/_obj/ft_strcat.o
new file mode 100644 (file)
index 0000000..7ff5887
Binary files /dev/null and b/lib/libft/_obj/ft_strcat.o differ
diff --git a/lib/libft/_obj/ft_strchr.o b/lib/libft/_obj/ft_strchr.o
new file mode 100644 (file)
index 0000000..632528a
Binary files /dev/null and b/lib/libft/_obj/ft_strchr.o differ
diff --git a/lib/libft/_obj/ft_strcmp.o b/lib/libft/_obj/ft_strcmp.o
new file mode 100644 (file)
index 0000000..0a6aa67
Binary files /dev/null and b/lib/libft/_obj/ft_strcmp.o differ
diff --git a/lib/libft/_obj/ft_strcpy.o b/lib/libft/_obj/ft_strcpy.o
new file mode 100644 (file)
index 0000000..5e4d60f
Binary files /dev/null and b/lib/libft/_obj/ft_strcpy.o differ
diff --git a/lib/libft/_obj/ft_strdup.o b/lib/libft/_obj/ft_strdup.o
new file mode 100644 (file)
index 0000000..177e976
Binary files /dev/null and b/lib/libft/_obj/ft_strdup.o differ
diff --git a/lib/libft/_obj/ft_striteri.o b/lib/libft/_obj/ft_striteri.o
new file mode 100644 (file)
index 0000000..5f45ab5
Binary files /dev/null and b/lib/libft/_obj/ft_striteri.o differ
diff --git a/lib/libft/_obj/ft_strjoin.o b/lib/libft/_obj/ft_strjoin.o
new file mode 100644 (file)
index 0000000..1bd4c7a
Binary files /dev/null and b/lib/libft/_obj/ft_strjoin.o differ
diff --git a/lib/libft/_obj/ft_strlcat.o b/lib/libft/_obj/ft_strlcat.o
new file mode 100644 (file)
index 0000000..2d4a576
Binary files /dev/null and b/lib/libft/_obj/ft_strlcat.o differ
diff --git a/lib/libft/_obj/ft_strlcpy.o b/lib/libft/_obj/ft_strlcpy.o
new file mode 100644 (file)
index 0000000..9ff1435
Binary files /dev/null and b/lib/libft/_obj/ft_strlcpy.o differ
diff --git a/lib/libft/_obj/ft_strlen.o b/lib/libft/_obj/ft_strlen.o
new file mode 100644 (file)
index 0000000..00d6890
Binary files /dev/null and b/lib/libft/_obj/ft_strlen.o differ
diff --git a/lib/libft/_obj/ft_strmapi.o b/lib/libft/_obj/ft_strmapi.o
new file mode 100644 (file)
index 0000000..309084c
Binary files /dev/null and b/lib/libft/_obj/ft_strmapi.o differ
diff --git a/lib/libft/_obj/ft_strncmp.o b/lib/libft/_obj/ft_strncmp.o
new file mode 100644 (file)
index 0000000..a6cfedf
Binary files /dev/null and b/lib/libft/_obj/ft_strncmp.o differ
diff --git a/lib/libft/_obj/ft_strncpy.o b/lib/libft/_obj/ft_strncpy.o
new file mode 100644 (file)
index 0000000..978f1ef
Binary files /dev/null and b/lib/libft/_obj/ft_strncpy.o differ
diff --git a/lib/libft/_obj/ft_strnstr.o b/lib/libft/_obj/ft_strnstr.o
new file mode 100644 (file)
index 0000000..5a06fae
Binary files /dev/null and b/lib/libft/_obj/ft_strnstr.o differ
diff --git a/lib/libft/_obj/ft_strrchr.o b/lib/libft/_obj/ft_strrchr.o
new file mode 100644 (file)
index 0000000..0c99b66
Binary files /dev/null and b/lib/libft/_obj/ft_strrchr.o differ
diff --git a/lib/libft/_obj/ft_strtrim.o b/lib/libft/_obj/ft_strtrim.o
new file mode 100644 (file)
index 0000000..d7332af
Binary files /dev/null and b/lib/libft/_obj/ft_strtrim.o differ
diff --git a/lib/libft/_obj/ft_substr.o b/lib/libft/_obj/ft_substr.o
new file mode 100644 (file)
index 0000000..d3dbbc4
Binary files /dev/null and b/lib/libft/_obj/ft_substr.o differ
diff --git a/lib/libft/_obj/ft_tolower.o b/lib/libft/_obj/ft_tolower.o
new file mode 100644 (file)
index 0000000..17dbc32
Binary files /dev/null and b/lib/libft/_obj/ft_tolower.o differ
diff --git a/lib/libft/_obj/ft_toupper.o b/lib/libft/_obj/ft_toupper.o
new file mode 100644 (file)
index 0000000..fb08203
Binary files /dev/null and b/lib/libft/_obj/ft_toupper.o differ
diff --git a/lib/libft/_obj/get_next_line.o b/lib/libft/_obj/get_next_line.o
new file mode 100644 (file)
index 0000000..23c2b36
Binary files /dev/null and b/lib/libft/_obj/get_next_line.o differ
diff --git a/lib/libft/_obj/get_next_line_utils.o b/lib/libft/_obj/get_next_line_utils.o
new file mode 100644 (file)
index 0000000..204f4dc
Binary files /dev/null and b/lib/libft/_obj/get_next_line_utils.o differ
index fbd16c1dc0583d2e6d03ed7c54b757dd488d3f27..1502ce33d4d21c4abd8daae248f0447a1a12ef12 100644 (file)
@@ -3,10 +3,10 @@
 /*                                                        :::      ::::::::   */
 /*   ft_split.c                                         :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/08 15:36:44 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/05/08 11:49:32 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/21 20:28:31 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
index 648c1840b9fcc317384c1531494f42d4facedc3c..b21235b224569b427f4a5bf2e89129e9671cf7e9 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/01/09 13:06:44 by chuhlig           #+#    #+#             */
-/*   Updated: 2025/01/09 13:07:15 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/14 14:09:49 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -26,4 +26,4 @@ char  *ft_strcat(char *dest, char *src)
        }
        dest[i + j] = '\0';
        return (dest);
-}
\ No newline at end of file
+}
index af7b2a121a7d44c0cf9687babac06e74df9bb0a9..a319c63e2060cb0dc40220e4d5f1f597385ee9ee 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/12/18 19:03:14 by chuhlig           #+#    #+#             */
-/*   Updated: 2024/12/18 19:05:01 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/14 14:09:59 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -20,4 +20,4 @@ int   ft_strcmp(char *s1, char *s2)
        while (s1[i] && s1[i] == s2[i])
                i++;
        return (s1[i] - s2[i]);
-}
\ No newline at end of file
+}
index b5c612f6d9bb29480d3a4aca71a62bf5c61ebb52..94a07f7c388f0a2f857218d284ee130acd84550e 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2025/01/09 14:38:30 by chuhlig           #+#    #+#             */
-/*   Updated: 2025/01/09 14:38:53 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/14 14:10:06 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -22,4 +22,4 @@ char  *ft_strcpy(char *dest, char *src)
        }
        dest[i] = '\0';
        return (dest);
-}
\ No newline at end of file
+}
index 526592b03bb56a784bda7d2ad58419edc07cd0f7..5c0bf41ad5df0f60367426a83c91e4e2b4629739 100644 (file)
@@ -3,44 +3,44 @@
 /*                                                        :::      ::::::::   */
 /*   ft_strjoin.c                                       :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/07 10:15:33 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/03/10 14:02:07 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/22 00:27:04 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "libft.h"
 
-static int     copy_str(char *dst, const char *src)
-{
-       int     i;
-
-       i = 0;
-       while (src[i])
-       {
-               dst[i] = src[i];
-               i++;
-       }
-       return (i);
-}
+// static int  copy_str(char *dst, const char *src)
+// {
+//     int     i;
+
+//     i = 0;
+//     while (src[i])
+//     {
+//             dst[i] = src[i];
+//             i++;
+//     }
+//     return (i);
+// }
 
-char   *ft_strjoin(char const *s1, char const *s2)
+char *ft_strjoin(const char *s1, const char *s2)
 {
-       int             len;
-       char    *result;
-
-       len = ft_strlen(s1) + ft_strlen(s2);
-       result = malloc(len + 1);
-       if (result)
-       {
-               result[len] = '\0';
-               len = copy_str(result, s1);
-               len = copy_str(result + len, s2);
-               return (result);
-       }
-       else
-               return (0);
+    char *joined_str;
+    size_t len1;
+    size_t len2;
+
+    if (!s1 || !s2)
+        return (NULL);
+    len1 = strlen(s1);
+    len2 = strlen(s2);
+    joined_str = malloc(len1 + len2 + 1);
+    if (!joined_str)
+        return (NULL);
+    strcpy(joined_str, s1);
+    strcat(joined_str, s2);
+    return (joined_str);
 }
 
 /* #include <stdio.h> */
diff --git a/lib/libft/libft.a b/lib/libft/libft.a
new file mode 100644 (file)
index 0000000..fe3527d
Binary files /dev/null and b/lib/libft/libft.a differ
index d64bb549d453f6a5db6a85d943cf5cfa9230c9a2..11989cc9e7fb763d3afce59c2fdab856559e5468 100644 (file)
@@ -6,79 +6,12 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/08/09 17:01:16 by chuhlig           #+#    #+#             */
-/*   Updated: 2025/01/10 14:36:55 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/20 19:07:18 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "env.h"
-
-int    echo(char **av)
-{
-       int     i;
-       int     f;
-
-       i = 1;
-       f = 1;
-       if (av[1] == NULL || av[1][0] == '\0')
-       {
-               write(1, "\n", 1);
-               return (1);
-       }
-       if (ft_strncmp(av[1], "-n", 3) == 0)
-       {
-               i++;
-               f = 0;
-       }
-       while (av[i])
-       {
-               write(1, av[i], ft_strlen(av[i]));
-               i++;
-               if (av[i])
-                       write(1, " ", 1);
-       }
-       if (f)
-               write(1, "\n", 1);
-       return (0);
-}
-
-int    pwd(t_env *env)
-{
-       while (env)
-       {
-               if (ft_strncmp(env->name, "PWD", 4) == 0)
-               {
-                       ft_printf("%s\n", env->value);
-                       break ;
-               }
-               env = env->next;
-       }
-       return (0);
-}
-
-int    ft_env(t_env *env)
-{
-       while (env != NULL)
-       {
-               printf("%s", env->name);
-               printf("=%s\n", env->value);
-               env = env->next;
-       }
-       return (0);
-}
-
-// int exit(char *av)
-// {
-//     freenode free toke free sequence stop repl free env;
-//     clear history;
-// }
-////
-
-void   free_env_node(t_env *node)
-{
-       free(node->name);
-       free(node->value);
-       free(node);
-}
+#include <stdio.h>
 
 int    unset(char **av, t_env **env)
 {
@@ -109,21 +42,12 @@ int        unset(char **av, t_env **env)
        return (0);
 }
 
-t_env  *env_new(char *name)
-{
-       t_env   *result;
-
-       result = malloc(sizeof(t_env));
-       if (!result)
-               return (NULL);
-       result->name = name;
-       return (result);
-}
-
 t_env  *check_existing(t_env *env, char *av)
 {
        while (env)
        {
+               if (ft_strcmp("$", av) == 0)
+                       return (NULL);
                if (ft_strcmp(env->name, av) == 0)
                        return (env);
                env = env->next;
@@ -131,31 +55,66 @@ t_env      *check_existing(t_env *env, char *av)
        return (NULL);
 }
 
-int    export(char **av, t_env **env)
+void   export_export(char *av, t_env **env)
 {
        char    *tmp;
        t_env   *current;
-       int             i;
 
        current = NULL;
+       tmp = ft_strchr(av, '=');
+       *tmp = '\0';
+       current = check_existing(*env, av);
+       if (current)
+               free(current->value);
+       else
+       {
+               current = env_new(ft_strdup(av));
+               current->next = *env;
+               *env = current;
+       }
+       current->value = ft_strdup(tmp + 1);
+}
+
+int    is_valid_identifier(char *str)
+{
+       int     i;
+
+       i = 0;
+       if (!ft_isalpha(str[0]) && str[0] != '_')
+               return (0);
+       while (str[i] && str[i] != '=')
+       {
+               if (!ft_isalnum(str[i]) && str[i] != '_')
+                       return (0);
+               i++;
+       }
+       return (1);
+}
+
+int    export(char **av, t_env **env, int f)
+{
+       char    *equal_sign;
+       int             i;
+
        i = 0;
        while (av[++i])
        {
-               if ((ft_strchr(av[i], '=')))
+               equal_sign = ft_strchr(av[i], '=');
+               if (equal_sign)
+                       *equal_sign = '\0';
+               if (!is_valid_identifier(av[i]))
                {
-                       tmp = ft_strchr(av[i], '=');
-                       *tmp = '\0';
-                       current = check_existing(*env, av[i]);
-                       if (current)
-                               free(current->value);
-                       else
-                       {
-                               current = env_new(ft_strdup(av[i]));
-                               current->next = *env;
-                               *env = current;
-                       }
-                       current->value = ft_strdup(tmp + 1);
+                       write(1, "Minishell $ export: not a valid identifier\n", 43);
+                       if (equal_sign)
+                               *equal_sign = '=';
+                       f++;
+                       continue ;
+               }
+               if (equal_sign)
+               {
+                       *equal_sign = '=';
+                       export_export(av[i], env);
                }
        }
-       return (0);
-}
\ No newline at end of file
+       return (check_flag(f));
+}
diff --git a/src/builtins_part_three.c b/src/builtins_part_three.c
new file mode 100644 (file)
index 0000000..3b9b100
--- /dev/null
@@ -0,0 +1,85 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   builtins_part_three.c                              :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/18 18:29:24 by chuhlig           #+#    #+#             */
+/*   Updated: 2025/01/21 16:15:19 by chuhlig          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "env.h"
+
+void   exit_shell(t_env **env, int exit_status)
+{
+       free_envlst(env);
+       exit(exit_status);
+}
+
+int    builtin_exit(char **av, t_env **env)
+{
+       int     exit_status;
+
+       if (av[1] && !av[2])
+               exit_status = ft_atoi(av[1]);
+       else if (av[2])
+               exit_status = 1;
+       else
+               exit_status = 0;
+       exit_shell(env, exit_status);
+       return (exit_status);
+}
+
+void   set_return_code(int return_code, t_env **env)
+{
+       t_env   *cur;
+
+       cur = check_existing(*env, "?");
+       if (cur)
+               free(cur->value);
+       else
+       {
+               cur = env_new(ft_strdup("?"));
+               cur->next = *env;
+               *env = cur;
+       }
+       cur->value = ft_itoa(return_code);
+}
+
+int    echo(char **av)
+{
+       int     i;
+       int     f;
+
+       i = 1;
+       f = 1;
+       if (av[1] == NULL || av[1][0] == '\0')
+       {
+               write(1, "\n", 1);
+               return (0);
+       }
+       if (ft_strncmp(av[1], "-n", 3) == 0)
+       {
+               i++;
+               f = 0;
+       }
+       while (av[i])
+       {
+               write(1, av[i], ft_strlen(av[i]));
+               i++;
+               if (av[i])
+                       write(1, " ", 1);
+       }
+       if (f)
+               write(1, "\n", 1);
+       return (0);
+}
+
+int    check_flag(int f)
+{
+       if (f)
+               return (1);
+       return (0);
+}
index f54e04f7b05874a2015374dd22e50dd4a62ba3b8..2382f255950d394643ba414af3c31faf009f18fb 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/10/25 20:52:16 by chuhlig           #+#    #+#             */
-/*   Updated: 2024/12/20 18:53:03 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/21 18:44:03 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 void   update_oldpwd(t_env **env)
 {
        t_env   *current;
-       t_env   *prev;
        char    cwd[1028];
        char    *tmp;
 
-       prev = NULL;
        current = *env;
        while (current)
        {
                if (ft_strncmp(current->name, "OLDPWD", 6) == 0)
                        break ;
-               prev = current;
                current = current->next;
        }
        getcwd(cwd, sizeof(cwd));
@@ -37,17 +34,14 @@ void        update_oldpwd(t_env **env)
 void   update_pwd(t_env **env)
 {
        t_env   *current;
-       t_env   *prev;
        char    cwd[1028];
        char    *tmp;
 
-       prev = NULL;
        current = *env;
        while (current)
        {
                if (ft_strncmp(current->name, "PWD", 3) == 0)
                        break ;
-               prev = current;
                current = current->next;
        }
        getcwd(cwd, sizeof(cwd));
@@ -72,6 +66,7 @@ int   cd(t_env **env, char **av)
                }
                if (chdir(current->value) == -1)
                        return (1);
+               update_pwd(env);
        }
        else
        {
@@ -82,3 +77,33 @@ int  cd(t_env **env, char **av)
        }
        return (0);
 }
+
+int    pwd(t_env *env)
+{
+       while (env)
+       {
+               if (ft_strncmp(env->name, "PWD", 4) == 0)
+               {
+                       ft_printf("%s\n", env->value);
+                       break ;
+               }
+               env = env->next;
+       }
+       return (0);
+}
+
+int    ft_env(t_env *env)
+{
+       while (env != NULL)
+       {
+               if (ft_strchr(env->name, '?'))
+               {
+                       env = env->next;
+                       continue ;
+               }
+               printf("%s", env->name);
+               printf("=%s\n", env->value);
+               env = env->next;
+       }
+       return (0);
+}
index be0e00f28af1f52a1ef55428973ac77919323d1c..67ab8f855592e11298c8c1bf6fcc470a2b73c1cc 100644 (file)
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/08/02 13:49:31 by dkaiser           #+#    #+#             */
-/*   Updated: 2025/01/13 09:52:00 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/21 20:19:48 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "minishell.h"
+#include <stdlib.h>
 
-static void            collect_and_check_redir(t_redirection *result, t_token **cur);
-static void            set_redir(t_redirection *redir, int type, char *specifier);
+static void                            collect_and_check_redir(t_redirection *result,
+                                                       t_token **cur, t_minidata *data, t_token **tokens);
+static t_redirection   *set_redir(t_redirection *redir, int type, char *spec,
+                                                       t_env *env);
+static int                             set_heredoc_data(t_token *cur, t_redirection *result,
+                                                       t_env *env);
 
-static char    *read_heredoc(char *delimiter)
-{
-       char    *line;
-       char    *result;
-       char    *temp;
-       size_t  total_length;
-       size_t  line_length;
-
-       total_length = 0;
-       result = NULL;
-       while (1)
-       {
-               line = readline("> ");
-               if (!line || ft_strcmp(line, delimiter) == 0)
-               {
-                       free(line);
-                       break ;
-               }
-               line_length = ft_strlen(line) + 1;
-               temp = malloc(total_length + line_length + 1);
-               if (!temp)
-               {
-                       perror("malloc");
-                       free(result);
-                       return (NULL);
-               }
-               if (result)
-               {
-                       ft_strcpy(temp, result);
-                       free(result);
-               }
-               else
-               {
-                       temp[0] = '\0';
-               }
-               ft_strcat(temp, line);
-               ft_strcat(temp, "\n");
-               result = temp;
-               total_length += line_length;
-               free(line);
-       }
-       return (result);
-}
-
-t_redirection  *collect_redirs(t_token **tokens)
+t_redirection  *collect_redirs(t_token **tokens, t_env *env,
+               t_list **create_files)
 {
        t_redirection   *result;
        t_token                 *cur;
+       t_minidata              data;
 
        cur = *tokens;
        result = malloc(sizeof(t_redirection) * 2);
        if (result == NULL)
                return (free_tokens(*tokens), NULL);
-       set_redir(&result[0], 0, NULL);
-       set_redir(&result[1], 0, NULL);
-       while (cur != NULL && cur->next != NULL)
+       free(set_redir(&result[0], 0, NULL, env));
+       free(set_redir(&result[1], 0, NULL, env));
+       data.create_files = create_files;
+       data.env = env;
+       while (cur != NULL)
        {
                if (cur->type == REDIR_TOKEN && cur->next->type == STRING_TOKEN)
-                       collect_and_check_redir(result, &cur);
+                       collect_and_check_redir(result, &cur, &data, tokens);
                else if (cur->type == REDIR_TOKEN)
                        return (free(result), NULL);
                else
                        cur = cur->next;
        }
-       if (cur && cur->type == REDIR_TOKEN)
-               return (free(result), NULL);
        return (result);
 }
 
-static void    set_redir(t_redirection *redir, int type, char *specifier)
+static void    collect_and_check_redir(t_redirection *result, t_token **cur,
+               t_minidata *data, t_token **tokens)
 {
+       char    *str;
+
+       if ((*cur)->content.redir_type != INPUT_LIMITER)
+               str = ft_strdup((*cur)->next->content.string);
+       if ((*cur)->content.redir_type == INPUT_LIMITER)
+       {
+               if (!set_heredoc_data(*cur, result, data->env))
+                       return ;
+       }
+       else if ((*cur)->content.redir_type == INPUT_FILE)
+               q4fc(data->create_files, set_redir(&result[0], INPUT_FILE,
+                               format_string(str, data->env, 0), data->env));
+       else if ((*cur)->content.redir_type == OUTPUT_OVERRIDE)
+               q4fc(data->create_files, set_redir(&result[1], OUTPUT_OVERRIDE,
+                               format_string(str, data->env, 0), data->env));
+       else if ((*cur)->content.redir_type == OUTPUT_APPEND) 
+               q4fc(data->create_files, set_redir(&result[1], OUTPUT_APPEND,
+                               format_string(str, data->env, 0), data->env));
+       i_love_the_norme(cur, tokens);
+}
+
+static t_redirection   *set_redir(t_redirection *redir, int type, char *spec,
+               t_env *env)
+{
+       t_redirection   *result;
+
        redir->type = type;
-       redir->specifier = specifier;
+       // if (redir->specifier != NULL)
+       //      free(redir->specifier);
+       if (spec != NULL)
+               redir->specifier = format_string(spec, env, ft_atoi("0"));
+       else
+               redir->specifier = spec;
+       if (redir->type != INPUT_LIMITER)
+       {
+               result = malloc(sizeof(t_redirection));
+               if (!result)
+                       return (NULL);
+               result->type = type;
+               result->specifier = spec;
+               return (result);
+       }
+       return (NULL);
 }
 
-static void    collect_and_check_redir(t_redirection *result, t_token **cur)
+static int     set_heredoc_data(t_token *cur, t_redirection *result, t_env *env)
 {
        char    *heredoc_data;
-       t_token *next_token;
 
        heredoc_data = NULL;
-       if ((*cur)->content.redir_type == INPUT_LIMITER)
+       if (cur->content.redir_type == INPUT_LIMITER)
        {
-               heredoc_data = read_heredoc((*cur)->next->content.string);
+               heredoc_data = read_heredoc(cur->next->content.string);
                if (!heredoc_data)
                {
                        perror("Heredoc allocation failed");
-                       return ;
+                       return (0);
                }
-               set_redir(&result[0], INPUT_LIMITER, heredoc_data);
-       }
-       else if ((*cur)->content.redir_type == INPUT_FILE)
-               set_redir(&result[0], INPUT_FILE, ft_strdup((*cur)->next->content.string));
-       else if ((*cur)->content.redir_type == OUTPUT_OVERRIDE)
-               set_redir(&result[1], OUTPUT_OVERRIDE, ft_strdup((*cur)->next->content.string));
-       else if ((*cur)->content.redir_type == OUTPUT_APPEND)
-               set_redir(&result[1], OUTPUT_APPEND, ft_strdup((*cur)->next->content.string));
-       else
-               printf("Unknown redirection type encountered\n");
-       next_token = (*cur)->next;
-       free_token_and_connect(*cur);
-       if (next_token)
-       {
-               *cur = next_token->next;
-               free_token_and_connect(next_token);
+               set_redir(&result[0], INPUT_LIMITER, heredoc_data, env);
        }
-       else
-               *cur = NULL;
+       set_redir(&result[0], INPUT_LIMITER, heredoc_data, env);
+       return (1);
 }
diff --git a/src/create_files.c b/src/create_files.c
new file mode 100644 (file)
index 0000000..8c04d8f
--- /dev/null
@@ -0,0 +1,65 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   create_files.c                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/16 16:23:51 by dkaiser           #+#    #+#             */
+/*   Updated: 2025/01/21 13:17:47 by dkaiser          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "minishell.h"
+#include <sys/fcntl.h>
+#include <unistd.h>
+
+static int     cant_write(char *filename);
+static void    create_file(char *filename, int mode);
+
+int    create_files(t_list *files)
+{
+       t_redirection   *file;
+
+       while (files)
+       {
+               if (files->content != NULL)
+               {
+                       file = (t_redirection *)files->content;
+                       if (file->type == INPUT_FILE && (access(file->specifier, F_OK) == -1
+                                       || access(file->specifier, R_OK) == -1))
+                               return (EXIT_FAILURE);
+                       if (cant_write(file->specifier))
+                               break ;
+                       if (file->type == OUTPUT_OVERRIDE)
+                               create_file(file->specifier, O_TRUNC);
+                       else if (file->type == OUTPUT_APPEND)
+                               create_file(file->specifier, O_APPEND);
+                       if (files->next == NULL)
+                               break ;
+                       if (((t_redirection *)files->next->content)->type == 0)
+                               break ;
+               }
+               files = files->next;
+       }
+       return (EXIT_SUCCESS);
+}
+
+static int     cant_write(char *filename)
+{
+       return (access(filename, F_OK) != -1 && access(filename, W_OK) == -1);
+}
+
+static void    create_file(char *filename, int mode)
+{
+       int     fd;
+
+       fd = open(filename, O_WRONLY | O_CREAT | mode, 0644);
+       if (fd != -1)
+               close(fd);
+}
+
+void   q4fc(t_list **queue, t_redirection *redir)
+{
+       ft_lstadd_back(queue, ft_lstnew(redir));
+}
index de5970355c8efd53a59357683b87d0dbb04c446c..6bee1b0f6027ce92424fcbba773e7ae981d4afa5 100644 (file)
@@ -3,14 +3,16 @@
 /*                                                        :::      ::::::::   */
 /*   debug_tools.c                                      :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/24 15:34:14 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/06/28 15:04:43 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/20 12:50:36 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "debug_tools.h"
+#include <stdio.h>
+#include <stdarg.h>
 
 void   dbg(char *msg)
 {
index 0213209541618098e0bce096697eb8f3435fd749..572040c290814efc617795eba732f535c6f6dde5 100644 (file)
--- a/src/env.c
+++ b/src/env.c
@@ -6,11 +6,12 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/10/17 14:31:07 by chuhlig           #+#    #+#             */
-/*   Updated: 2024/12/17 19:36:14 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/20 19:12:43 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "env.h"
+#include "minishell.h"
 #include <stdlib.h>
 
 void   getenvlst(t_env **env, char **en)
@@ -54,9 +55,27 @@ char *env_get(t_env *env, char *name)
 {
        while (env != NULL)
        {
-               if (!ft_strncmp(env->name, name, ft_strlen(name)))
+               if (!ft_strncmp(env->name, name, ft_strlen(env->name)))
                        return (env->value);
                env = env->next;
        }
        return (NULL);
-}
\ No newline at end of file
+}
+
+t_env  *env_new(char *name)
+{
+       t_env   *result;
+
+       result = malloc(sizeof(t_env));
+       if (!result)
+               return (NULL);
+       result->name = name;
+       return (result);
+}
+
+void   free_env_node(t_env *node)
+{
+       free(node->name);
+       free(node->value);
+       free(node);
+}
index c4c98c32e6323454d7114e17aaca1f27f0e25ddc..5806d96217ca6c7feb5a8c8292f25dd3b26629c5 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/12/17 19:22:28 by chuhlig           #+#    #+#             */
-/*   Updated: 2024/12/17 19:22:36 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/18 18:50:49 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 
 static char    *get_var_assign(t_env *cur);
 
-char   **env_to_strlst(t_env *env)
+static int     getsize(t_env *env)
 {
        int             size;
        t_env   *cur;
-       char    **result;
-       int             i;
 
        size = 0;
        cur = env;
-       while (cur != NULL)
+       while (cur)
        {
-               size++;
+               if (!ft_strchr(cur->name, '?'))
+                       size++;
                cur = cur->next;
        }
+       return (size);
+}
+
+char   **env_to_strlst(t_env *env)
+{
+       int             size;
+       t_env   *cur;
+       char    **result;
+       int             i;
+
+       size = 0;
+       cur = env;
+       size = getsize(env);
        result = malloc(sizeof(char *) * (size + 1));
        if (result == NULL)
                return (NULL);
@@ -36,6 +48,8 @@ char  **env_to_strlst(t_env *env)
        cur = env;
        while (i < size)
        {
+               if (ft_strchr(cur->name, '?'))
+                       cur = cur->next;
                result[i] = get_var_assign(cur);
                cur = cur->next;
                i++;
@@ -55,4 +69,4 @@ static char   *get_var_assign(t_env *cur)
        result = ft_strjoin(left_side, cur->value);
        free(left_side);
        return (result);
-}
\ No newline at end of file
+}
diff --git a/src/env_tools.c b/src/env_tools.c
new file mode 100644 (file)
index 0000000..f1c3748
--- /dev/null
@@ -0,0 +1,21 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   env_tools.c                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/15 16:14:31 by dkaiser           #+#    #+#             */
+/*   Updated: 2025/01/22 00:01:03 by chuhlig          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "minishell.h"
+
+// char        **get_split_path(t_env *env)
+// {
+//     char    *path;
+
+//     path = env_get(env, "PATH");
+//     return (ft_split(path, ':'));
+// }
diff --git a/src/error.c b/src/error.c
new file mode 100644 (file)
index 0000000..2ca60b2
--- /dev/null
@@ -0,0 +1,30 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   error.c                                            :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/15 16:35:53 by dkaiser           #+#    #+#             */
+/*   Updated: 2025/01/20 18:12:40 by dkaiser          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "minishell.h"
+#include <errno.h>
+
+void   *error(int err_code, char *err_text, int exit_code, int *ret_code)
+{
+       errno = err_code;
+       perror(err_text);
+       if (ret_code != NULL)
+               *ret_code = exit_code;
+       return (NULL);
+}
+
+void   command_not_found_error(char *cmd)
+{
+       ft_printf("%s:", cmd);
+       ft_putstr_fd(" command not found", 2);
+       ft_printf("\n");
+}
index 803d88fec1121d257e59084d24efea35fe2fe3b1..012391fb46cfeaff1891769482b81ae1c2e390cd 100644 (file)
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/12/17 19:21:35 by chuhlig           #+#    #+#             */
-/*   Updated: 2025/01/13 09:50:56 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/21 23:52:38 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "minishell.h"
-#include <fcntl.h>
+#include <stdio.h>
 #include <stdlib.h>
-#include <sys/_types/_pid_t.h>
-#include <sys/_types/_s_ifmt.h>
-#include <sys/fcntl.h>
-#include <unistd.h>
+
+static void    establish_pipeline(int original_stdin, int original_stdout);
+static int     exec_cmd(t_cmd *cmd, t_env **env, int original_std[2], int result);
+
+int    is_builtin(char *cmd)
+{
+       return ((ft_strcmp(cmd, "export") == 0) || (ft_strcmp(cmd, "unset") == 0)
+               || (ft_strcmp(cmd, "cd") == 0) || (ft_strcmp(cmd, "exit") == 0)
+               || (ft_strcmp(cmd, "echo") == 0) || (ft_strcmp(cmd, "pwd") == 0)
+               || (ft_strcmp(cmd, "env") == 0));
+}
+
+int    execute_builtin(char **args, t_env **env)
+{
+       if (ft_strcmp(args[0], "export") == 0)
+               return (export(args, env, ft_atoi("0")));
+       else if (ft_strcmp(args[0], "unset") == 0)
+               return (unset(args, env));
+       else if (ft_strcmp(args[0], "cd") == 0)
+               return (cd(env, args));
+       else if (ft_strcmp(args[0], "echo") == 0)
+               return (echo(args));
+       else if (ft_strcmp(args[0], "pwd") == 0)
+               return (pwd(*env));
+       else if (ft_strcmp(args[0], "env") == 0)
+               return (ft_env(*env));
+       else if (ft_strcmp(args[0], "exit") == 0)
+               return (builtin_exit(args, env));
+       return (1);
+}
 
 int    execute_cmd(t_cmd *cmd, t_env **env)
 {
-       char    *cmd_path;
-       pid_t   pid;
-       int             status;
-       int             result;
-       int             original_stdout;
-       int             original_stdin;
+       int     original_std[2];
+       int     result;
 
-       original_stdout = dup(STDOUT_FILENO);
-       original_stdin = dup(STDIN_FILENO);
+       original_std[1] = dup(STDOUT_FILENO);
+       original_std[0] = dup(STDIN_FILENO);
+       create_files(cmd->create_files);
        if (handle_redirections(cmd->redirs) == -1)
        {
-               dup2(original_stdout, STDOUT_FILENO);
-               dup2(original_stdin, STDIN_FILENO);
-               close(original_stdout);
-               close(original_stdin);
+               establish_pipeline(original_std[0], original_std[1]);
                return (EXIT_FAILURE);
        }
        if (is_builtin(cmd->args[0]))
        {
                result = execute_builtin(cmd->args, env);
-               dup2(original_stdout, STDOUT_FILENO);
-               dup2(original_stdin, STDIN_FILENO);
-               close(original_stdout);
-               close(original_stdin);
+               establish_pipeline(original_std[0], original_std[1]);
                return (result);
        }
+       return (exec_cmd(cmd, env, original_std, EXIT_SUCCESS));
+}
+
+static void    establish_pipeline(int original_stdin, int original_stdout)
+{
+       dup2(original_stdout, STDOUT_FILENO);
+       dup2(original_stdin, STDIN_FILENO);
+       close(original_stdout);
+       close(original_stdin);
+}
+
+static int     exec_cmd(t_cmd *cmd, t_env **env, int original_std[2], int result)
+{
+       int             i;
+       int             status;
+       char    *cmd_path;
+       pid_t   pid;
+
        pid = fork();
        if (pid == -1)
        {
                perror("fork");
-               dup2(original_stdout, STDOUT_FILENO);
-               dup2(original_stdin, STDIN_FILENO);
-               close(original_stdout);
-               close(original_stdin);
+               establish_pipeline(original_std[0], original_std[1]);
                return (EXIT_FAILURE);
        }
        if (pid == 0)
        {
-               cmd_path = get_cmd_path(cmd->args[0], *env);
-               if (!cmd_path)
-               {
-                       printf("%s: command not found\n", cmd->args[0]);
-                       exit(EXIT_FAILURE);
-               }
-               execve(cmd_path, cmd->args, env_to_strlst(*env));
-               perror("execve");
-               exit(EXIT_FAILURE);
+               i = 0;
+               while (cmd->args[i][0] == '\0')
+                       i++;
+               cmd_path = get_cmd_path(cmd->args[i], *env, &result);
+               if (cmd_path != NULL)
+                       execve(cmd_path, &(cmd->args[i]), env_to_strlst(*env));
+               free(cmd_path);
+               exit(result);
        }
        waitpid(pid, &status, 0);
-       dup2(original_stdout, STDOUT_FILENO);
-       dup2(original_stdin, STDIN_FILENO);
-       close(original_stdout);
-       close(original_stdin);
-       return (WEXITSTATUS(status));
-}
\ No newline at end of file
+       establish_pipeline(original_std[0], original_std[1]);
+       return ((status >> 8) & 255);
+}
index bd7f703d8192744f18e456b16b3c33ed849820be..775a3dafb0b7e699cdd602e80a2e63b924074e9d 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/12/17 19:30:11 by chuhlig           #+#    #+#             */
-/*   Updated: 2024/12/17 19:31:54 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/21 23:25:20 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "libft.h"
 #include "minishell.h"
 
-static void    append_slice(char **dst, char *src, int start, int end);
-static void    append_var(char **dst, char *src, int *pos, t_env *env);
-
-enum           e_format_mode
-{
-       LITERAL = 1,
-       VARIABLE = 2,
-};
-
-char   *format_string(char *str, t_env *env)
+void   append_var_exit_code(char **dst, t_env *env)
 {
+       char    *exit_code;
        char    *result;
-       int             pos;
-       int             start;
-       int             mode;
 
-       pos = 0;
-       start = 0;
-       mode = 0;
-       result = NULL;
-       if (str == NULL)
-               return (NULL);
-       while (str[pos] != '\0')
+       exit_code = env_get(env, "?");
+       if (exit_code)
        {
-               if (str[pos] == '\'')
-               {
-                       append_slice(&result, str, start, pos);
-                       start = pos + 1;
-                       mode ^= LITERAL;
-               }
-               if (str[pos] == '"' && !(mode & LITERAL))
-               {
-                       append_slice(&result, str, start, pos);
-                       start = pos + 1;
-               }
-               if (str[pos] == '$' && !(mode & LITERAL))
-               {
-                       append_slice(&result, str, start, pos);
-                       append_var(&result, str, &pos, env);
-                       start = pos;
-                       continue ;
-               }
-               pos++;
+               result = ft_strjoin(*dst, exit_code);
+               free(*dst);
+               *dst = result;
        }
-       append_slice(&result, str, start, pos);
-       return (result);
 }
 
 static void    append_slice(char **dst, char *src, int start, int end)
@@ -71,9 +37,7 @@ static void   append_slice(char **dst, char *src, int start, int end)
        if (*dst != NULL)
                len = ft_strlen(*dst);
        else
-       {
                len = 0;
-       }
        result = malloc(len + (end - start) + 1);
        if (!result)
                return ;
@@ -99,27 +63,63 @@ static void append_var(char **dst, char *src, int *pos, t_env *env)
 
        i = 0;
        *pos += 1;
-       while (src[*pos + i] != '\0' && src[*pos + i] != '\'' && src[*pos
-               + i] != '"' && src[*pos + i] != '$')
-       {
+       while (ft_isalnum(src[*pos + i]) || src[*pos + i] == '_')
                i++;
-       }
-       var = malloc(i + 1);
-       if (var == NULL)
+       if (i == 0)
                return ;
-       var[i] = '\0';
-       i--;
-       while (i >= 0)
-       {
-               var[i] = src[*pos + i];
-               i--;
-       }
+       var = ft_substr(src, *pos, i);
        value = env_get(env, var);
-       if (value != NULL)
+       if (value)
        {
                result = ft_strjoin(*dst, value);
                free(*dst);
                *dst = result;
        }
-       *pos += ft_strlen(var);
+       *pos += i;
+       free(var);
+}
+
+static void    handle_dollar_sign(char **result, char *str, int *pos, t_env *env)
+{
+       if (str[*pos + 1] == '?')
+       {
+               append_var_exit_code(result, env);
+               *pos += 2;
+       }
+       else if (ft_isalnum(str[*pos + 1]) || str[*pos + 1] == '_')
+               append_var(result, str, pos, env);
+       else
+       {
+               append_slice(result, str, *pos, *pos + 1);
+               (*pos)++;
+       }
+}
+
+char   *format_string(char *str, t_env *env, int is_literal)
+{
+       char    *result;
+       int             pos;
+       int             start;
+
+       pos = 0;
+       start = 0;
+       result = NULL;
+       if (!str)
+               return (NULL);
+       while (str[pos])
+       {
+               if (str[pos] == '\'' || (str[pos] == '\"' && !is_literal)
+                       || (str[pos] == '$' && !is_literal))
+               {
+                       append_slice(&result, str, start, pos);
+                       if (str[pos] == '$')
+                               handle_dollar_sign(&result, str, &pos, env);
+                       else
+                               is_literal ^= (str[pos++] == '\'');
+                       start = pos;
+                       continue ;
+               }
+               pos++;
+       }
+       return (append_slice(&result, str, start, pos), result);
 }
index 6eae05906d28fbc9cfe29df3ee252802c85e7749..d866727179c5e99d8c60a74f8d935fba62b884d0 100644 (file)
@@ -3,10 +3,10 @@
 /*                                                        :::      ::::::::   */
 /*   free_node.c                                        :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/27 11:41:46 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/08/11 12:26:20 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/22 01:53:34 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 
 static void    free_pipe_node(t_node *node);
 static void    free_cmd_node(t_node *node);
+static void    free_file(void *arg);
+
+// void        free_node(t_node *node)
+// {
+//     if (node->type == PIPE_NODE)
+//             free_pipe_node(node);
+//     else if (node->type == CMD_NODE)
+//             free_cmd_node(node);
+//     else if (node->type == STRING_NODE)
+//             free(node->content.string);
+//     else
+//             panic(UNREACHABLE);
+//     free(node);
+// }
+void   free_redirections(t_redirection redirs[2])
+{
+    for (int i = 0; i < 2; i++)
+    {
+        if (redirs[i].specifier)
+            free(redirs[i].specifier);
+    }
+}
 
 void   free_node(t_node *node)
 {
-       if (node->type == PIPE_NODE)
-               free_pipe_node(node);
-       else if (node->type == CMD_NODE)
-               free_cmd_node(node);
-       else if (node->type == STRING_NODE)
-               free(node->content.string);
-       else
-               panic(UNREACHABLE);
-       free(node);
+    if (!node)
+        return;
+
+    if (node->type == PIPE_NODE)
+    {
+        free_node(node->content.pipe.left);
+        free_node(node->content.pipe.right);
+    }
+    else if (node->type == CMD_NODE)
+    {
+        if (node->content.cmd.args)
+        {
+            for (int i = 0; node->content.cmd.args[i]; i++)
+                free(node->content.cmd.args[i]);
+            free(node->content.cmd.args);
+        }
+        free_redirections(node->content.cmd.redirs);
+        // Assuming create_files is a list of dynamically allocated strings
+        t_list *current = node->content.cmd.create_files;
+        t_list *next;
+        while (current)
+        {
+            next = current->next;
+            free(current->content);
+            free(current);
+            current = next;
+        }
+    }
+    else if (node->type == STRING_NODE)
+    {
+        free(node->content.string);
+    }
+    free(node);
 }
 
 static void    free_pipe_node(t_node *node)
@@ -51,4 +97,15 @@ static void  free_cmd_node(t_node *node)
        if (node->content.cmd.redirs[1].type != 0
                && node->content.cmd.redirs[0].specifier != NULL)
                free(node->content.cmd.redirs[1].specifier);
+       if (node->content.cmd.create_files != NULL)
+               ft_lstclear(&node->content.cmd.create_files, free_file);
+}
+
+static void    free_file(void *arg)
+{
+       t_redirection   *file;
+
+       file = (t_redirection *)arg;
+       free(file->specifier);
+       free(file);
 }
index 9b035ac1c545e13cd3ea0e4fab8736a94a04980a..64278a8050a4bb977413d4ad95cf9f00a76bd6eb 100644 (file)
@@ -3,14 +3,15 @@
 /*                                                        :::      ::::::::   */
 /*   free_token.c                                       :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/27 14:38:57 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/08/02 14:23:56 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/22 00:07:58 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "token.h"
+#include "debug_tools.h"
 
 void   free_token(t_token *token)
 {
@@ -18,7 +19,10 @@ void free_token(t_token *token)
                token->previous->next = NULL;
        if (token->next != NULL)
                token->next->previous = NULL;
-       free(token);
+    // if (token->type == STRING_TOKEN && token->content.string != NULL)
+    //     free(token->content.string); // Ensure content is freed
+       free(token);//maybe free token
+       token = NULL;
 }
 
 void   free_token_and_connect(t_token *token)
@@ -28,14 +32,26 @@ void        free_token_and_connect(t_token *token)
        if (token->next != NULL)
                token->next->previous = token->previous;
        free(token);
+       token = NULL;
 }
 
-void   free_tokens(t_token *tokens)
+// void        free_tokens(t_token *tokens)
+// {
+//     while (tokens->next != NULL)
+//     {
+//             tokens = tokens->next;
+//             free_token(tokens->previous);
+//     }
+//     free_token(tokens);
+// }
+void free_tokens(t_token *tokens)
 {
-       while (tokens->next != NULL)
-       {
-               tokens = tokens->next;
-               free_token(tokens->previous);
-       }
-       free_token(tokens);
+    t_token *tmp;
+
+    while (tokens)
+    {
+        tmp = tokens;
+        tokens = tokens->next;
+        free_token(tmp); // Ensure each token is freed
+    }
 }
index 8a27584c0e7ae90775c2512a09bcab4c2de4079a..713c397bc6b732f2376763ebcb083e0cbe3c3ffa 100644 (file)
@@ -6,28 +6,35 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/12/17 19:19:59 by chuhlig           #+#    #+#             */
-/*   Updated: 2024/12/17 19:20:08 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/22 00:01:48 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "libft.h"
 #include "minishell.h"
+#include <errno.h>
+#include <sys/errno.h>
+#include <sys/stat.h>
+#include <sys/unistd.h>
+#include <unistd.h>
 
-static char    *get_absolute_cmd_path(char *cmd, t_env *env);
-static char    *find_in_path(char *cmd, t_env *env);
+static char    *get_simple_cmd_path(char *cmd, int *return_code);
+static char    *get_absolute_cmd_path(char *cmd, t_env *env, int *return_code);
+static char    *find_in_path(char *cmd, t_env *env, int *return_code);
 char           **get_split_path(t_env *env);
+static int     is_directory(char *path);
 
-char   *get_cmd_path(char *cmd, t_env *env)
+char   *get_cmd_path(char *cmd, t_env *env, int *return_code)
 {
        if (cmd[0] == '/')
-               return (ft_strdup(cmd));
+               return (get_simple_cmd_path(cmd, return_code));
        else if (ft_strchr(cmd, '/'))
-               return (get_absolute_cmd_path(cmd, env));
+               return (get_absolute_cmd_path(cmd, env, return_code));
        else
-               return (find_in_path(cmd, env));
+               return (find_in_path(cmd, env, return_code));
 }
 
-static char    *get_absolute_cmd_path(char *cmd, t_env *env)
+static char    *get_absolute_cmd_path(char *cmd, t_env *env, int *return_code)
 {
        char    *cur_dir;
        char    *result;
@@ -38,45 +45,118 @@ static char        *get_absolute_cmd_path(char *cmd, t_env *env)
        result = ft_strjoin(cur_dir, cmd);
        free(cur_dir);
        if (!result)
-               return (NULL);
+               return (error(ENOENT, cmd, 127, return_code));
+       if (access(result, F_OK) == -1)
+       {
+               free(result);
+               return (error(ENOENT, cmd, 127, return_code));
+       }
        if (access(result, X_OK) == -1)
        {
                free(result);
-               return (NULL);
+               return (error(EACCES, cmd, 126, return_code));
        }
+       if (is_directory(cmd))
+               return (error(EISDIR, cmd, 126, return_code));
        return (result);
 }
 
-static char    *find_in_path(char *cmd, t_env *env)
+void free_split_path(char **path)
+{
+    char **tmp = path;
+    while (*tmp)
+    {
+        free(*tmp);
+        tmp++;
+    }
+    free(path);
+}
+
+char **get_split_path(t_env *env)
 {
-       char    *cur_path;
-       char    *cmd_path;
-       char    **path;
+    char *path_env;
+    char **split_path;
 
-       path = get_split_path(env);
-       cmd_path = NULL;
-       while (*path)
+    path_env = env_get(env, "PATH");
+    if (!path_env)
+        return (NULL);
+    split_path = ft_split(path_env, ':');
+    free(path_env);
+    return (split_path);
+}
+
+static char    *find_in_path(char *cmd, t_env *env, int *return_code)
+{
+    char       *cur_path;
+    char       *cmd_path;
+    char       **path;
+    char       **path_start; // To keep track of the start of the path array
+
+    path = get_split_path(env);
+    path_start = path; // Save the start of the path array
+    cmd_path = NULL;
+    while (*path)
+    {
+        if (cmd_path)
+            free(cmd_path);
+        cur_path = ft_strjoin(*path, "/");
+        if (!cur_path)
+        {
+            free_split_path(path_start); // Free the entire path array
+            return (NULL);
+        }
+        cmd_path = ft_strjoin(cur_path, cmd);
+        free(cur_path);
+        if (!cmd_path)
+        {
+            free_split_path(path_start); // Free the entire path array
+            return (NULL);
+        }
+        if (access(cmd_path, X_OK) != -1)
+        {
+            free_split_path(path_start); // Free the entire path array
+            return (cmd_path);
+        }
+        path++;
+    }
+    free_split_path(path_start); // Free the entire path array
+    *return_code = 127;
+    command_not_found_error(cmd);
+    return (NULL);
+}
+
+static char    *get_simple_cmd_path(char *cmd, int *return_code)
+{
+       char    *result;
+
+       result = ft_strdup(cmd);
+       if (!result)
+               return (NULL);
+       if (access(result, F_OK) == -1)
+       {
+               free(result);
+               return (error(ENOENT, cmd, 127, return_code));
+       }
+       if (access(result, X_OK) == -1)
        {
-               if (cmd_path)
-                       free(cmd_path);
-               cur_path = ft_strjoin(*path, "/");
-               if (!cur_path)
-                       return (NULL);
-               cmd_path = ft_strjoin(cur_path, cmd);
-               free(cur_path);
-               if (!cmd_path)
-                       return (NULL);
-               if (access(cmd_path, X_OK) != -1)
-                       return (cmd_path);
-               path++;
+               free(result);
+               return (error(EACCES, cmd, 126, return_code));
        }
-       return (NULL);
+       if (is_directory(cmd))
+       {
+               free(result);
+               return (error(EISDIR, cmd, 126, return_code));
+       }
+       return (result);
 }
 
-char   **get_split_path(t_env *env)
+static int     is_directory(char *path)
 {
-       char    *path;
+       struct stat     path_stat;
 
-       path = env_get(env, "PATH");
-       return (ft_split(path, ':'));
+       stat(path, &path_stat);
+       if ((path_stat.st_mode & S_IFMT) == S_IFDIR)
+               return (1);
+       else
+               return (0);
 }
diff --git a/src/handle_redir.c b/src/handle_redir.c
new file mode 100644 (file)
index 0000000..e8a1010
--- /dev/null
@@ -0,0 +1,103 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   handle_redir.c                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/18 18:34:51 by chuhlig           #+#    #+#             */
+/*   Updated: 2025/01/20 14:59:38 by chuhlig          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "minishell.h"
+
+int    handle_input_redirection(t_redirection *redir)
+{
+       int     fd;
+
+       if (redir->type == INPUT_FILE)
+       {
+               fd = open_file(redir->specifier, O_RDONLY, 0);
+               if (fd < 0)
+                       return (-1);
+               dup2(fd, STDIN_FILENO);
+               close(fd);
+       }
+       else if (redir->type == INPUT_LIMITER)
+       {
+               fd = open_file("/tmp/heredoc_tmp", O_WRONLY | O_TRUNC, 0644);
+               if (fd < 0)
+                       return (-1);
+               write(fd, redir->specifier, ft_strlen(redir->specifier));
+               close(fd);
+               fd = open_file("/tmp/heredoc_tmp", O_RDONLY, 0);
+               if (fd < 0)
+                       return (-1);
+               dup2(fd, STDIN_FILENO);
+               close(fd);
+       }
+       return (0);
+}
+
+int    handle_output_redirection(t_redirection *redir)
+{
+       int     fd;
+
+       if (redir->type == OUTPUT_OVERRIDE)
+       {
+               fd = open_file(redir->specifier, O_WRONLY | O_TRUNC, 0644);
+               if (fd < 0)
+                       return (-1);
+               dup2(fd, STDOUT_FILENO);
+               close(fd);
+       }
+       else if (redir->type == OUTPUT_APPEND)
+       {
+               fd = open_file(redir->specifier, O_WRONLY | O_APPEND, 0644);
+               if (fd < 0)
+                       return (-1);
+               dup2(fd, STDOUT_FILENO);
+               close(fd);
+       }
+       return (0);
+}
+
+int    handle_redirections(t_redirection *redirs)
+{
+       if (redirs[0].type == INPUT_FILE || redirs[0].type == INPUT_LIMITER)
+       {
+               if (handle_input_redirection(&redirs[0]) < 0)
+                       return (-1);
+       }
+       if (redirs[1].type == OUTPUT_OVERRIDE || redirs[1].type == OUTPUT_APPEND)
+       {
+               if (handle_output_redirection(&redirs[1]) < 0)
+                       return (-1);
+       }
+       return (0);
+}
+
+int    handle_pipe_parent(int p[2], t_node *node, t_env **env)
+{
+       int     original_stdin;
+       int     result;
+
+       close(p[1]);
+       original_stdin = dup(STDIN_FILENO);
+       dup2(p[0], STDIN_FILENO);
+       result = eval_rec(node->content.pipe.right, env, p[0]);
+       dup2(original_stdin, STDIN_FILENO);
+       close(original_stdin);
+       close(p[0]);
+       return (result);
+}
+
+int    handle_pipe_child(int p[2], t_node *node, t_env **env, int in_fd)
+{
+       close(p[0]);
+       dup2(in_fd, STDIN_FILENO);
+       dup2(p[1], STDOUT_FILENO);
+       close(p[1]);
+       exit(eval_rec(node->content.pipe.left, env, in_fd));
+}
index fd2c8ac2e4d9d26ad3b973179dc97ef8a94606ce..f41e64a54d8361481d380a5abd92016ace6a8e07 100644 (file)
@@ -3,10 +3,10 @@
 /*                                                        :::      ::::::::   */
 /*   init.c                                             :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/24 15:02:24 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/06/24 15:25:57 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/13 17:45:46 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
index 7b0306f91f1f3e9f24ec241b6abdcc4d47015482..11f06203da46cda7a207b47836cc3c19e3b64337 100644 (file)
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/12/17 19:15:49 by chuhlig           #+#    #+#             */
-/*   Updated: 2025/01/13 09:53:33 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/21 16:35:38 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "debug_tools.h"
 #include "minishell.h"
-#include <stdlib.h>
-#include <sys/_types/_pid_t.h>
-#include <sys/cdefs.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <sys/fcntl.h>
-#include <sys/types.h>
 
-int    is_builtin(char *cmd)
-{
-       return ((ft_strcmp(cmd, "export") == 0)
-               || (ft_strcmp(cmd, "unset") == 0)
-               || (ft_strcmp(cmd, "cd") == 0)
-               || (ft_strcmp(cmd, "exit") == 0)
-               || (ft_strcmp(cmd, "echo") == 0)
-               || (ft_strcmp(cmd, "pwd") == 0)
-               || (ft_strcmp(cmd, "env") == 0));
-}
-
-int    execute_builtin(char **args, t_env **env)
-{
-       if (ft_strcmp(args[0], "export") == 0)
-               return (export(args, env));
-       else if (ft_strcmp(args[0], "unset") == 0)
-               return (unset(args, env));
-       else if (ft_strcmp(args[0], "cd") == 0)
-               return (cd(env, args));
-       else if (ft_strcmp(args[0], "exit") == 0)
-               return (EXIT_SUCCESS);
-       else if (ft_strcmp(args[0], "echo") == 0)
-               return (echo(args));
-       else if (ft_strcmp(args[0], "pwd") == 0)
-               return (pwd(*env));
-       else if (ft_strcmp(args[0], "env") == 0)
-               return (ft_env(*env));
-       return (1);
-}
+int    eval_rec(t_node *node, t_env **env, int in_fd);
 
-static int     handle_redirections(t_redirection *redirs)
+int    open_file(char *path, int flags, int mode)
 {
        int     fd;
 
-       if (redirs[0].type == INPUT_FILE)
-       {
-               fd = open(redirs[0].specifier, O_RDONLY);
-               if (fd < 0)
-               {
-                       perror("open");
-                       return (-1);
-               }
-               dup2(fd, STDIN_FILENO);
-               close(fd);
-       }
-       else if (redirs[0].type == INPUT_LIMITER)
-       {
-               fd = open("/tmp/heredoc_tmp", O_WRONLY | O_CREAT | O_TRUNC, 0644);
-               if (fd < 0)
-               {
-                       perror("open");
-                       return (-1);
-               }
-               write(fd, redirs[0].specifier, ft_strlen(redirs[0].specifier));
-               close(fd);
-               fd = open("/tmp/heredoc_tmp", O_RDONLY);
-               if (fd < 0)
-               {
-                       perror("open");
-                       return (-1);
-               }
-               dup2(fd, STDIN_FILENO);
-               close(fd);
-       }
-       if (redirs[1].type == OUTPUT_OVERRIDE)
-       {
-               fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_TRUNC, 0644);
-               if (fd < 0)
-               {
-                       perror("open");
-                       return (-1);
-               }
-               dup2(fd, STDOUT_FILENO);
-               close(fd);
-       }
-       else if (redirs[1].type == OUTPUT_APPEND)
-       {
-               fd = open(redirs[1].specifier, O_WRONLY | O_CREAT | O_APPEND, 0644);
-               if (fd < 0)
-               {
-                       perror("open");
-                       return (-1);
-               }
-               dup2(fd, STDOUT_FILENO);
-               close(fd);
-       }
-       return (0);
-       }
+       fd = open(path, flags, mode);
+       if (fd < 0)
+               perror(path);
+       return (fd);
+}
 
-static int     eval_rec(t_node *node, t_env **env, int in_fd)
+int    eval_rec(t_node *node, t_env **env, int in_fd)
 {
-       pid_t   pid;
        int             p[2];
+       pid_t   pid;
        int             result;
-       int             status;
-       int             original_stdin;
 
        if (node->type == PIPE_NODE)
        {
-               pipe(p);
+               if (pipe(p) == -1)
+                       return (perror("pipe"), EXIT_FAILURE);
                pid = fork();
+               if (pid == -1)
+                       return (perror("fork"), close(p[0]), close(p[1]), EXIT_FAILURE);
                if (pid == 0)
-               {
-                       close(p[0]);
-                       dup2(in_fd, STDIN_FILENO);
-                       dup2(p[1], STDOUT_FILENO);
-                       result = eval_rec(node->content.pipe.left, env, in_fd);
-                       exit(result);
-               }
-               else
-               {
-                       close(p[1]);
-                       original_stdin = dup(STDIN_FILENO);
-                       dup2(p[0], STDIN_FILENO);
-                       result = eval_rec(node->content.pipe.right, env, p[0]);
-                       waitpid(pid, &status, 0);
-                       dup2(original_stdin, STDIN_FILENO);
-                       close(original_stdin);
-               }
+                       handle_pipe_child(p, node, env, in_fd);
+               result = handle_pipe_parent(p, node, env);
        }
        else if (node->type == CMD_NODE)
-       {
                result = execute_cmd(&node->content.cmd, env);
-       }
        else
        {
-               printf("Handling unknown node type\n");
-               panic("UNREACHABLE");
                result = EXIT_FAILURE;
+               free_node(node);
        }
        return (result);
 }
 
-int eval(t_node *node, t_env **env)
+int    eval(t_node *node, t_env **env)
 {
        return (eval_rec(node, env, STDIN_FILENO));
 }
index a53760c8471d6fed9793a5e58b4c5c5c6f89878b..e863f3a6076125bd688cb0e5f8aca553c105d79f 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/22 17:14:03 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/12/17 19:26:42 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/22 01:49:12 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 
 int    main(int argc, char *argv[], char *envp[])
 {
-       t_env   *env;
+       t_env           *env;
+       static int      promptflag;
 
        env = NULL;
+       promptflag = 0;
        if (!argc && !argv)
                return (1);
        if (init())
                return (1);
        getenvlst(&env, envp);
-       repl("Minishell $ ", &env);
+       set_return_code(0, &env);
+       repl("Minishell $ ", &env, &promptflag);
+       free_envlst(&env);
+       return (0);
 }
index c58d2915546f3e60e4275e368848b4d9c44829d8..b2ab7ea7965732a8550f1192b6958fba05c9364c 100644 (file)
@@ -3,10 +3,10 @@
 /*                                                        :::      ::::::::   */
 /*   new_node.c                                         :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/27 11:21:03 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/09/17 18:46:35 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/20 17:59:01 by dkaiser          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -37,7 +37,8 @@ t_node        *new_pipe_node(t_node *left, t_node *right)
        return (node);
 }
 
-t_node *new_cmd_node(char **args, t_redirection redirs[2])
+t_node *new_cmd_node(char **args, t_redirection redirs[2],
+               t_list *create_files)
 {
        t_node  *node;
 
@@ -49,7 +50,9 @@ t_node        *new_cmd_node(char **args, t_redirection redirs[2])
        {
                node->content.cmd.redirs[0] = redirs[0];
                node->content.cmd.redirs[1] = redirs[1];
+               node->content.cmd.create_files = create_files;
                free(redirs);
+               redirs = NULL;
                return (node);
        }
        return (NULL);
index 92ff421ddb224a86e0360b4e93eedf61c4720d0f..6f49681318925fa4186ccd2f6ede57798f6990ab 100644 (file)
@@ -3,10 +3,10 @@
 /*                                                        :::      ::::::::   */
 /*   new_token.c                                        :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/27 14:29:44 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/06/28 14:59:34 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/22 00:41:47 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -35,7 +35,10 @@ t_token      *new_str_token(char *str, t_token *previous, t_token *next)
 
        token = new_token(STRING_TOKEN, previous, next);
        if (token == NULL)
+       {
+               free(str);
                return (NULL);
+       }
        token->content.string = str;
        return (token);
 }
index 3c4eb965f683aa1ab0a5238ee58f0376b0afa6f8..c0a9ad941e225198a71adb17f72f8027ef2bf73c 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/07/08 15:06:25 by dkaiser           #+#    #+#             */
-/*   Updated: 2025/01/11 16:04:50 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/21 21:27:29 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -18,8 +18,10 @@ t_node       *parse_cmd(t_token *tokens, t_env **env)
 {
        char                    **args;
        t_redirection   *redirs;
+       t_list                  *create_files;
 
-       redirs = collect_redirs(&tokens);
+       create_files = NULL;
+       redirs = collect_redirs(&tokens, *env, &create_files);
        if (redirs == NULL)
                return (NULL);
        args = collect_args(&tokens, env);
@@ -28,7 +30,7 @@ t_node        *parse_cmd(t_token *tokens, t_env **env)
                free(redirs);
                return (NULL);
        }
-       return (new_cmd_node(args, redirs));
+       return (new_cmd_node(args, redirs, create_files));
 }
 
 static char    **collect_args(t_token **tokens, t_env **env)
@@ -36,6 +38,7 @@ static char   **collect_args(t_token **tokens, t_env **env)
        t_token *cur;
        char    **result;
        int             i;
+       t_token *next;
 
        cur = *tokens;
        i = 0;
@@ -48,11 +51,14 @@ static char **collect_args(t_token **tokens, t_env **env)
        i = 0;
        while (cur != NULL && cur->type == STRING_TOKEN)
        {
+               next = cur->next;
                if (cur->previous)
                        free_token(cur->previous);
-               result[i] = format_string(cur->content.string, *env);
+               result[i] = format_string(cur->content.string, *env, ft_atoi("0"));
                i++;
-               cur = cur->next;
+               if (cur->next == NULL)
+                       free_token(cur);
+               cur = next;
        }
        result[i] = NULL;
        return (result);
index 1375954e9941f5385031005527e807ac1edd23fb..e7b53c20f20bc2ef68659f755fc39d6db75de68b 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/29 15:53:29 by dkaiser           #+#    #+#             */
-/*   Updated: 2025/01/11 16:06:54 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/21 21:27:15 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -19,7 +19,7 @@ static t_token        *find_token_by_type(t_token *tokens, int type);
 t_token                        *split_at_first(t_token **tokens, int type);
 static t_node  *parse_statement(t_token *tokens, t_env **env);
 
-t_list *parse(t_token *tokens, t_env **env)
+t_node *parse(t_token *tokens, t_env **env)
 {
        t_node  *result;
 
@@ -29,7 +29,7 @@ t_list        *parse(t_token *tokens, t_env **env)
                result = parse_statement(tokens, env);
        if (result == NULL)
                printf("Parsing error.\n");
-       return (ft_lstnew(result));
+       return (result);
 }
 
 static t_node  *parse_statement(t_token *tokens, t_env **env)
@@ -40,6 +40,7 @@ static t_node *parse_statement(t_token *tokens, t_env **env)
        if (left_side_tokens == NULL)
        {
                free_tokens(tokens);
+               tokens = NULL;
                return (NULL);
        }
        else if (tokens != NULL)
@@ -70,6 +71,7 @@ t_token       *split_at_first(t_token **tokens, int type)
        if (result == split)
                result = NULL;
        free_token(split);
+       split = NULL;
        return (result);
 }
 
diff --git a/src/praise_the_norme.c b/src/praise_the_norme.c
new file mode 100644 (file)
index 0000000..a22843b
--- /dev/null
@@ -0,0 +1,30 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   praise_the_norme.c                                 :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/20 18:35:41 by dkaiser           #+#    #+#             */
+/*   Updated: 2025/01/20 18:39:31 by dkaiser          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "minishell.h"
+
+void   i_love_the_norme(t_token **cur, t_token **tokens)
+{
+       t_token *next_token;
+
+       next_token = (*cur)->next;
+       free_token_and_connect(*cur);
+       if (next_token)
+       {
+               if (next_token->previous == NULL)
+                       *tokens = next_token->next;
+               *cur = next_token->next;
+               free_token_and_connect(next_token);
+       }
+       else
+               *cur = NULL;
+}
diff --git a/src/read_heredoc.c b/src/read_heredoc.c
new file mode 100644 (file)
index 0000000..53633e8
--- /dev/null
@@ -0,0 +1,76 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   read_heredoc.c                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*                                                +#+#+#+#+#+   +#+           */
+/*   Created: 2025/01/15 18:22:09 by dkaiser           #+#    #+#             */
+/*   Updated: 2025/01/15 19:08:07 by dkaiser          ###   ########.fr       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "minishell.h"
+#include <errno.h>
+#include <stdio.h>
+#include <sys/errno.h>
+
+static char    *concat_str(char *temp, char *line);
+static char    *get_result(char *temp, char *result, char *line);
+static void    *print_error_and_free(char *result);
+
+char   *read_heredoc(char *delimiter)
+{
+       char    *line;
+       char    *result;
+       char    *temp;
+       size_t  total_length;
+       size_t  line_length;
+
+       total_length = 0;
+       result = NULL;
+       while (1)
+       {
+               line = readline("> ");
+               if (!line || ft_strcmp(line, delimiter) == 0)
+               {
+                       free(line);
+                       break ;
+               }
+               line_length = ft_strlen(line) + 1;
+               temp = malloc(total_length + line_length + 1);
+               if (!temp)
+                       return (print_error_and_free(result));
+               result = get_result(temp, result, line);
+               total_length += line_length;
+       }
+       return (result);
+}
+
+static char    *concat_str(char *temp, char *line)
+{
+       ft_strcat(temp, line);
+       ft_strcat(temp, "\n");
+       free(line);
+       return (temp);
+}
+
+static char    *get_result(char *temp, char *result, char *line)
+{
+       if (result)
+       {
+               ft_strcpy(temp, result);
+               free(result);
+       }
+       else
+               temp[0] = '\0';
+       return (concat_str(temp, line));
+}
+
+static void    *print_error_and_free(char *result)
+{
+       errno = ENOMEM;
+       perror("heredoc");
+       free(result);
+       return (NULL);
+}
index 7ff80a8adfdb12f7573c17131b287e767fff1a2a..2dcd16d23bc531b5e8656739fc87fc4d88ca97f6 100644 (file)
@@ -6,56 +6,44 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/24 16:07:04 by dkaiser           #+#    #+#             */
-/*   Updated: 2025/01/11 16:01:44 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/21 21:29:16 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "../include/minishell.h"
 #include "token.h"
 
-t_token        *reverse_token_list(t_token *head)
+void   free_repl(char *input, t_node *ast)
 {
-       t_token *prev;
-       t_token *current;
-       t_token *next;
-
-       prev = NULL;
-       current = head;
-       next = NULL;
-       while (current != NULL)
-       {
-               next = current->previous;
-               current->next = prev;
-               current->previous = next;
-               prev = current;
-               current = next;
-       }
-       return (prev);
+       free(input);
+       free_node(ast);
 }
 
-void   repl(const char *prompt, t_env **env)
+void   repl(const char *prompt, t_env **env, int *promptflag)
 {
        char    *input;
        t_token *token_list;
-       t_list  *lines;
+       t_node  *ast;
 
+       (*promptflag)++;
        while (1)
        {
                input = readline(prompt);
                if (input == NULL)
-                       return ;
+               {
+                       if (*promptflag > 1)
+                               (*promptflag)--;
+                       printf("exit\n");
+                       break ;
+               }
                if (input[0] == '\0')
                        continue ;
                add_history(input);
                token_list = NULL;
                tokenizer(input, &token_list, '\0');
-               token_list = reverse_token_list(token_list);
-               lines = parse(token_list, env);
-               if (lines)
-               {
-                       print_ast(lines->content);
-                       eval(lines->content, env);
-               }
-               free(input);
+               ast = parse(token_list, env);
+               if (ast)
+                       set_return_code(eval(ast, env), env);
+               free_repl(input, ast);
        }
 }
index a19fa945520bf365ba1e8c21473e626f4dc364f7..6c6ca1e009b43296a79107fcf454d4fafe28820e 100644 (file)
@@ -3,10 +3,10 @@
 /*                                                        :::      ::::::::   */
 /*   signal_handling.c                                  :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/24 15:08:43 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/06/25 13:33:26 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/20 12:15:32 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
index 26edd2eb23cc90b264ad7b08a43f948ce994542f..451fa50d5bb1ced315c780034782217191565dc7 100644 (file)
@@ -6,13 +6,33 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/28 20:55:50 by chuhlig           #+#    #+#             */
-/*   Updated: 2025/01/11 15:22:07 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/22 00:49:10 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "minishell.h"
 #include "token.h"
 
+t_token        *reverse_token_list(t_token *head)
+{
+       t_token *prev;
+       t_token *current;
+       t_token *next;
+
+       prev = NULL;
+       current = head;
+       next = NULL;
+       while (current != NULL)
+       {
+               next = current->previous;
+               current->next = prev;
+               current->previous = next;
+               prev = current;
+               current = next;
+       }
+       return (prev);
+}
+
 void   print_token(t_token *token)
 {
        if (DEBUG)
@@ -77,11 +97,11 @@ void        handle_special_chars(char *s, int *i, int *start, t_token **token_list)
                *token_list = new_token(PIPE_TOKEN, *token_list, NULL);
        else if (s[*i] == '\n')
                *token_list = new_token(NEWLINE_TOKEN, *token_list, NULL);
-       print_token(*token_list);
        if (s[*i] == '<' && s[*i + 1] == '<')
                (*i)++;
        if (s[*i] == '>' && s[*i + 1] == '>')
                (*i)++;
+       print_token(*token_list);
        *start = *i + 1;
 }
 
@@ -111,4 +131,5 @@ void        tokenizer(char *s, t_token **token_list, char quote_check)
                        pos = i + 1;
                }
        }
+       *token_list = reverse_token_list(*token_list);
 }
diff --git a/valgrind_out.txt b/valgrind_out.txt
new file mode 100644 (file)
index 0000000..c005c63
--- /dev/null
@@ -0,0 +1,1040 @@
+root@aaf7f63c7efc:/dorker_workspace# valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./minishell 
+==7626== Memcheck, a memory error detector
+==7626== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
+==7626== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
+==7626== Command: ./minishell
+==7626== 
+Minishell $ a
+==7626== Invalid read of size 8
+==7626==    at 0x1097D1: free_tokens (free_token.c:55)
+==7626==    by 0x10A08A: parse (parser.c:40)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Address 0x4b01c38 is 24 bytes inside a block of size 32 free'd
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x109746: free_token (free_token.c:24)
+==7626==    by 0x10A395: collect_args (parse_cmd.c:91)
+==7626==    by 0x10A24F: parse_cmd (parse_cmd.c:27)
+==7626==    by 0x10A12A: parse_statement (parser.c:62)
+==7626==    by 0x10A07A: parse (parser.c:39)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Block was alloc'd at
+==7626==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7626==    by 0x1095F6: new_token (new_token.c:19)
+==7626==    by 0x109686: new_str_token (new_token.c:36)
+==7626==    by 0x109C55: snap_string_token (tokenizer.c:79)
+==7626==    by 0x10A014: tokenizer (tokenizer.c:130)
+==7626==    by 0x109573: repl (repl.c:50)
+==7626==    by 0x109372: main (main.c:28)
+==7626== 
+==7626== Invalid read of size 8
+==7626==    at 0x1097DD: free_tokens (free_token.c:56)
+==7626==    by 0x10A08A: parse (parser.c:40)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Address 0x4b01c28 is 8 bytes inside a block of size 32 free'd
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x109746: free_token (free_token.c:24)
+==7626==    by 0x10A395: collect_args (parse_cmd.c:91)
+==7626==    by 0x10A24F: parse_cmd (parse_cmd.c:27)
+==7626==    by 0x10A12A: parse_statement (parser.c:62)
+==7626==    by 0x10A07A: parse (parser.c:39)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Block was alloc'd at
+==7626==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7626==    by 0x1095F6: new_token (new_token.c:19)
+==7626==    by 0x109686: new_str_token (new_token.c:36)
+==7626==    by 0x109C55: snap_string_token (tokenizer.c:79)
+==7626==    by 0x10A014: tokenizer (tokenizer.c:130)
+==7626==    by 0x109573: repl (repl.c:50)
+==7626==    by 0x109372: main (main.c:28)
+==7626== 
+==7626== Invalid free() / delete / delete[] / realloc()
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x1097F4: free_tokens (free_token.c:57)
+==7626==    by 0x10A08A: parse (parser.c:40)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Address 0x4b01c20 is 0 bytes inside a block of size 32 free'd
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x109746: free_token (free_token.c:24)
+==7626==    by 0x10A395: collect_args (parse_cmd.c:91)
+==7626==    by 0x10A24F: parse_cmd (parse_cmd.c:27)
+==7626==    by 0x10A12A: parse_statement (parser.c:62)
+==7626==    by 0x10A07A: parse (parser.c:39)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Block was alloc'd at
+==7626==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7626==    by 0x1095F6: new_token (new_token.c:19)
+==7626==    by 0x109686: new_str_token (new_token.c:36)
+==7626==    by 0x109C55: snap_string_token (tokenizer.c:79)
+==7626==    by 0x10A014: tokenizer (tokenizer.c:130)
+==7626==    by 0x109573: repl (repl.c:50)
+==7626==    by 0x109372: main (main.c:28)
+==7626== 
+a: command not found
+==7627== 
+==7627== HEAP SUMMARY:
+==7627==     in use at exit: 199,597 bytes in 269 blocks
+==7627==   total heap usage: 450 allocs, 182 frees, 224,561 bytes allocated
+==7627== 
+==7627== 2 bytes in 1 blocks are still reachable in loss record 1 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10D412: ft_strdup (in /dorker_workspace/minishell)
+==7627==    by 0x10C82F: set_return_code (builtins_part_three.c:44)
+==7627==    by 0x109355: main (main.c:27)
+==7627== 
+==7627== 2 bytes in 1 blocks are still reachable in loss record 2 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10CFE2: ft_itoa (in /dorker_workspace/minishell)
+==7627==    by 0x10C85F: set_return_code (builtins_part_three.c:48)
+==7627==    by 0x109355: main (main.c:27)
+==7627== 
+==7627== 2 bytes in 1 blocks are still reachable in loss record 3 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x489124E: _rl_init_locale (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4891321: _rl_init_eightbit (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700F2: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 2 bytes in 1 blocks are still reachable in loss record 4 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EFB9: readline_internal_teardown (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48703DA: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 2 bytes in 1 blocks are still reachable in loss record 5 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x489258C: alloc_history_entry (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48927F9: add_history (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x109553: repl (repl.c:48)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 2 bytes in 1 blocks are still reachable in loss record 6 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10B868: append_slice (format_string.c:41)
+==7627==    by 0x10BC33: format_string (format_string.c:124)
+==7627==    by 0x10A375: collect_args (parse_cmd.c:88)
+==7627==    by 0x10A24F: parse_cmd (parse_cmd.c:27)
+==7627==    by 0x10A12A: parse_statement (parser.c:62)
+==7627==    by 0x10A07A: parse (parser.c:39)
+==7627==    by 0x109586: repl (repl.c:51)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 5 bytes in 1 blocks are still reachable in loss record 7 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x494C969: strdup (strdup.c:42)
+==7627==    by 0x4AA4435: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 6 bytes in 1 blocks are still reachable in loss record 8 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48976A6: sh_get_home_dir (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x489832C: tilde_expand_word (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4898560: tilde_expand (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487E26B: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487E4FB: rl_read_init_file (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700F9: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 7 bytes in 1 blocks are definitely lost in loss record 9 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10D4F9: ft_strjoin (in /dorker_workspace/minishell)
+==7627==    by 0x10AFDA: find_in_path (get_cmd_path.c:79)
+==7627==    by 0x10ADFF: get_cmd_path (get_cmd_path.c:34)
+==7627==    by 0x10B720: exec_cmd (execute_cmd.c:96)
+==7627==    by 0x10B622: execute_cmd (execute_cmd.c:66)
+==7627==    by 0x10AB22: eval_rec (interpreter.c:46)
+==7627==    by 0x10AB67: eval (interpreter.c:57)
+==7627==    by 0x1095A4: repl (repl.c:53)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 8 bytes in 1 blocks are still reachable in loss record 10 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899377: xrealloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4881C4E: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48827F5: rl_expand_prompt (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486ECFE: rl_set_prompt (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870385: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 12 bytes in 1 blocks are still reachable in loss record 11 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48927D7: add_history (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x109553: repl (repl.c:48)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 13 bytes in 1 blocks are still reachable in loss record 12 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486ECDA: rl_set_prompt (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870385: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 13 bytes in 1 blocks are still reachable in loss record 13 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4882183: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48827F5: rl_expand_prompt (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486ECFE: rl_set_prompt (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870385: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 13 bytes in 1 blocks are still reachable in loss record 14 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487E422: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700F9: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 16 bytes in 1 blocks are still reachable in loss record 15 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x48701E7: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 16 bytes in 1 blocks are still reachable in loss record 16 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10A2DC: collect_args (parse_cmd.c:78)
+==7627==    by 0x10A24F: parse_cmd (parse_cmd.c:27)
+==7627==    by 0x10A12A: parse_statement (parser.c:62)
+==7627==    by 0x10A07A: parse (parser.c:39)
+==7627==    by 0x109586: repl (repl.c:51)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 20 bytes in 1 blocks are still reachable in loss record 17 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487F143: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487DFD2: rl_parse_and_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487E39C: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700F9: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 24 bytes in 1 blocks are still reachable in loss record 18 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10AD28: env_new (env.c:69)
+==7627==    by 0x10C837: set_return_code (builtins_part_three.c:44)
+==7627==    by 0x109355: main (main.c:27)
+==7627== 
+==7627== 24 bytes in 1 blocks are still reachable in loss record 19 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4892573: alloc_history_entry (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48927F9: add_history (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x109553: repl (repl.c:48)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 33 bytes in 1 blocks are still reachable in loss record 20 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4AABF1A: _nc_read_termtype (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACB1A: _nc_read_file_entry (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACE7C: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACFCB: _nc_read_entry2 (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4018: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA43D5: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627== 
+==7627== 33 bytes in 1 blocks are still reachable in loss record 21 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4A9F2E8: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4404: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 40 bytes in 1 blocks are still reachable in loss record 22 of 67
+==7627==    at 0x48455EF: calloc (vg_replace_malloc.c:1328)
+==7627==    by 0x4AA15CB: _nc_first_db (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACFA6: _nc_read_entry2 (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4018: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA43D5: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 44 bytes in 1 blocks are still reachable in loss record 23 of 67
+==7627==    at 0x48455EF: calloc (vg_replace_malloc.c:1328)
+==7627==    by 0x4AAC020: _nc_read_termtype (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACB1A: _nc_read_file_entry (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACE7C: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACFCB: _nc_read_entry2 (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4018: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA43D5: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627== 
+==7627== 44 bytes in 1 blocks are still reachable in loss record 24 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4A9F0BE: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4404: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 56 bytes in 1 blocks are still reachable in loss record 25 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x109814: new_node (new_node.c:19)
+==7627==    by 0x1098B2: new_cmd_node (new_node.c:45)
+==7627==    by 0x10A284: parse_cmd (parse_cmd.c:33)
+==7627==    by 0x10A12A: parse_statement (parser.c:62)
+==7627==    by 0x10A07A: parse (parser.c:39)
+==7627==    by 0x109586: repl (repl.c:51)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 61 bytes in 6 blocks are indirectly lost in loss record 26 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10D193: get_next_token (in /dorker_workspace/minishell)
+==7627==    by 0x10D27E: ft_split (in /dorker_workspace/minishell)
+==7627==    by 0x10C32A: get_split_path (env_tools.c:20)
+==7627==    by 0x10AF78: find_in_path (get_cmd_path.c:70)
+==7627==    by 0x10ADFF: get_cmd_path (get_cmd_path.c:34)
+==7627==    by 0x10B720: exec_cmd (execute_cmd.c:96)
+==7627==    by 0x10B622: execute_cmd (execute_cmd.c:66)
+==7627==    by 0x10AB22: eval_rec (interpreter.c:46)
+==7627==    by 0x10AB67: eval (interpreter.c:57)
+==7627==    by 0x1095A4: repl (repl.c:53)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 72 bytes in 1 blocks are still reachable in loss record 27 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4AA1530: _nc_first_db (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACFA6: _nc_read_entry2 (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4018: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA43D5: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 78 bytes in 1 blocks are still reachable in loss record 28 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4A9F1FD: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4404: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 106 bytes in 12 blocks are still reachable in loss record 29 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10D412: ft_strdup (in /dorker_workspace/minishell)
+==7627==    by 0x10ABEC: getenvlst (env.c:30)
+==7627==    by 0x109344: main (main.c:26)
+==7627== 
+==7627== 117 (56 direct, 61 indirect) bytes in 1 blocks are definitely lost in loss record 30 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10D236: ft_split (in /dorker_workspace/minishell)
+==7627==    by 0x10C32A: get_split_path (env_tools.c:20)
+==7627==    by 0x10AF78: find_in_path (get_cmd_path.c:70)
+==7627==    by 0x10ADFF: get_cmd_path (get_cmd_path.c:34)
+==7627==    by 0x10B720: exec_cmd (execute_cmd.c:96)
+==7627==    by 0x10B622: execute_cmd (execute_cmd.c:66)
+==7627==    by 0x10AB22: eval_rec (interpreter.c:46)
+==7627==    by 0x10AB67: eval (interpreter.c:57)
+==7627==    by 0x1095A4: repl (repl.c:53)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 156 bytes in 1 blocks are still reachable in loss record 31 of 67
+==7627==    at 0x48455EF: calloc (vg_replace_malloc.c:1328)
+==7627==    by 0x4AAC0CE: _nc_read_termtype (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACB1A: _nc_read_file_entry (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACE7C: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACFCB: _nc_read_entry2 (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4018: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA43D5: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627== 
+==7627== 253 bytes in 12 blocks are still reachable in loss record 32 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10D412: ft_strdup (in /dorker_workspace/minishell)
+==7627==    by 0x10AC03: getenvlst (env.c:31)
+==7627==    by 0x109344: main (main.c:26)
+==7627== 
+==7627== 256 bytes in 1 blocks are still reachable in loss record 33 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870346: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 288 bytes in 12 blocks are still reachable in loss record 34 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x10ABC9: getenvlst (env.c:29)
+==7627==    by 0x109344: main (main.c:26)
+==7627== 
+==7627== 760 bytes in 1 blocks are still reachable in loss record 35 of 67
+==7627==    at 0x48455EF: calloc (vg_replace_malloc.c:1328)
+==7627==    by 0x4AA437F: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 1,024 bytes in 1 blocks are still reachable in loss record 36 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899377: xrealloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48813DB: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48814E2: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4887916: rl_redisplay (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EDFA: readline_internal_setup (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48703AE: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 1,024 bytes in 1 blocks are still reachable in loss record 37 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899377: xrealloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48813F3: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48814E2: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4887916: rl_redisplay (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EDFA: readline_internal_setup (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48703AE: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 1,024 bytes in 1 blocks are still reachable in loss record 38 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899377: xrealloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x488140B: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48814E2: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4887916: rl_redisplay (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EDFA: readline_internal_setup (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48703AE: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 1,024 bytes in 1 blocks are still reachable in loss record 39 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899377: xrealloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4881423: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48814E2: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4887916: rl_redisplay (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EDFA: readline_internal_setup (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48703AE: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 1,024 bytes in 1 blocks are still reachable in loss record 40 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4881535: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4887916: rl_redisplay (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EDFA: readline_internal_setup (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48703AE: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 1,024 bytes in 1 blocks are still reachable in loss record 41 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4881550: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4887916: rl_redisplay (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EDFA: readline_internal_setup (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48703AE: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 1,024 bytes in 1 blocks are still reachable in loss record 42 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4881568: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4887916: rl_redisplay (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EDFA: readline_internal_setup (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48703AE: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 1,024 bytes in 1 blocks are still reachable in loss record 43 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4881580: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4887916: rl_redisplay (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EDFA: readline_internal_setup (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48703AE: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 1,536 bytes in 1 blocks are still reachable in loss record 44 of 67
+==7627==    at 0x484582F: realloc (vg_replace_malloc.c:1437)
+==7627==    by 0x489935D: xrealloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874B84: rl_add_funmap_entry (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874BCE: rl_initialize_funmap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700ED: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 2,032 bytes in 1 blocks are still reachable in loss record 45 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x488E6C9: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 2,272 bytes in 142 blocks are still reachable in loss record 46 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874B2C: rl_add_funmap_entry (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874BCE: rl_initialize_funmap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700ED: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 3,312 bytes in 1 blocks are still reachable in loss record 47 of 67
+==7627==    at 0x48455EF: calloc (vg_replace_malloc.c:1328)
+==7627==    by 0x4AAC1A9: _nc_read_termtype (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACB1A: _nc_read_file_entry (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACE7C: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AACFCB: _nc_read_entry2 (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4018: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA43D5: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627== 
+==7627== 3,312 bytes in 1 blocks are still reachable in loss record 48 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4A9F0DE: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4404: _nc_setupterm (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA4922: tgetent_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E45C: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 4,016 bytes in 1 blocks are still reachable in loss record 49 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4892869: add_history (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x109553: repl (repl.c:48)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 4,080 bytes in 1 blocks are still reachable in loss record 50 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x488E6A9: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 4,112 bytes in 1 blocks are still reachable in loss record 51 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EBD9: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870145: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 4,112 bytes in 1 blocks are still reachable in loss record 52 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EC7A: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870145: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 4,112 bytes in 1 blocks are still reachable in loss record 53 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EBD9: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870154: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 4,112 bytes in 1 blocks are still reachable in loss record 54 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EC7A: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870154: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 4,112 bytes in 1 blocks are still reachable in loss record 55 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EBD9: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870179: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 4,112 bytes in 1 blocks are still reachable in loss record 56 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EC7A: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870179: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 7,952 bytes in 1 blocks are still reachable in loss record 57 of 67
+==7627==    at 0x48455EF: calloc (vg_replace_malloc.c:1328)
+==7627==    by 0x4AA07A7: ??? (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA0F1A: _nc_find_type_entry (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x4AA52B4: tgetstr_sp (in /usr/lib/x86_64-linux-gnu/libtinfo.so.6.4)
+==7627==    by 0x488E49A: _rl_init_terminal_io (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700D0: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 8,224 bytes in 2 blocks are still reachable in loss record 58 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EC6B: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870145: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 8,224 bytes in 2 blocks are still reachable in loss record 59 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EB62: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870154: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 8,224 bytes in 2 blocks are still reachable in loss record 60 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EB62: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870179: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 8,224 bytes in 2 blocks are still reachable in loss record 61 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870193: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 12,336 bytes in 3 blocks are still reachable in loss record 62 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EC42: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870154: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 12,336 bytes in 3 blocks are still reachable in loss record 63 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EC6B: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870154: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 12,336 bytes in 3 blocks are still reachable in loss record 64 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EC42: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870179: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 12,336 bytes in 3 blocks are still reachable in loss record 65 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x486EC6B: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4870179: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 12,336 bytes in 3 blocks are still reachable in loss record 66 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487D4AD: rl_bind_keyseq_if_unbound_in_map (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48701A2: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== 41,120 bytes in 10 blocks are still reachable in loss record 67 of 67
+==7627==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7627==    by 0x4899338: xmalloc (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x4874CBD: rl_make_bare_keymap (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487C3DD: rl_generic_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487E1BA: rl_parse_and_bind (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487E39C: ??? (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x48700F9: rl_initialize (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x487038A: readline (in /usr/lib/x86_64-linux-gnu/libreadline.so.8.2)
+==7627==    by 0x1094FF: repl (repl.c:38)
+==7627==    by 0x109372: main (main.c:28)
+==7627== 
+==7627== LEAK SUMMARY:
+==7627==    definitely lost: 63 bytes in 2 blocks
+==7627==    indirectly lost: 61 bytes in 6 blocks
+==7627==      possibly lost: 0 bytes in 0 blocks
+==7627==    still reachable: 199,473 bytes in 261 blocks
+==7627==         suppressed: 0 bytes in 0 blocks
+==7627== 
+==7627== For lists of detected and suppressed errors, rerun with: -s
+==7627== ERROR SUMMARY: 5 errors from 5 contexts (suppressed: 0 from 0)
+==7626== Invalid read of size 8
+==7626==    at 0x1097D1: free_tokens (free_token.c:55)
+==7626==    by 0x1094C1: free_repl (repl.c:25)
+==7626==    by 0x1095CB: repl (repl.c:54)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Address 0x4b01c38 is 24 bytes inside a block of size 32 free'd
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x109746: free_token (free_token.c:24)
+==7626==    by 0x10A395: collect_args (parse_cmd.c:91)
+==7626==    by 0x10A24F: parse_cmd (parse_cmd.c:27)
+==7626==    by 0x10A12A: parse_statement (parser.c:62)
+==7626==    by 0x10A07A: parse (parser.c:39)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Block was alloc'd at
+==7626==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7626==    by 0x1095F6: new_token (new_token.c:19)
+==7626==    by 0x109686: new_str_token (new_token.c:36)
+==7626==    by 0x109C55: snap_string_token (tokenizer.c:79)
+==7626==    by 0x10A014: tokenizer (tokenizer.c:130)
+==7626==    by 0x109573: repl (repl.c:50)
+==7626==    by 0x109372: main (main.c:28)
+==7626== 
+==7626== Invalid read of size 8
+==7626==    at 0x1097DD: free_tokens (free_token.c:56)
+==7626==    by 0x1094C1: free_repl (repl.c:25)
+==7626==    by 0x1095CB: repl (repl.c:54)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Address 0x4b01c28 is 8 bytes inside a block of size 32 free'd
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x109746: free_token (free_token.c:24)
+==7626==    by 0x10A395: collect_args (parse_cmd.c:91)
+==7626==    by 0x10A24F: parse_cmd (parse_cmd.c:27)
+==7626==    by 0x10A12A: parse_statement (parser.c:62)
+==7626==    by 0x10A07A: parse (parser.c:39)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Block was alloc'd at
+==7626==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7626==    by 0x1095F6: new_token (new_token.c:19)
+==7626==    by 0x109686: new_str_token (new_token.c:36)
+==7626==    by 0x109C55: snap_string_token (tokenizer.c:79)
+==7626==    by 0x10A014: tokenizer (tokenizer.c:130)
+==7626==    by 0x109573: repl (repl.c:50)
+==7626==    by 0x109372: main (main.c:28)
+==7626== 
+==7626== Invalid free() / delete / delete[] / realloc()
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x1097E8: free_tokens (free_token.c:56)
+==7626==    by 0x1094C1: free_repl (repl.c:25)
+==7626==    by 0x1095CB: repl (repl.c:54)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Address 0x4b01bd0 is 0 bytes inside a block of size 2 free'd
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x1097E8: free_tokens (free_token.c:56)
+==7626==    by 0x10A08A: parse (parser.c:40)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Block was alloc'd at
+==7626==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7626==    by 0x109BCD: snap_string_token (tokenizer.c:68)
+==7626==    by 0x10A014: tokenizer (tokenizer.c:130)
+==7626==    by 0x109573: repl (repl.c:50)
+==7626==    by 0x109372: main (main.c:28)
+==7626== 
+==7626== Invalid free() / delete / delete[] / realloc()
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x1097F4: free_tokens (free_token.c:57)
+==7626==    by 0x1094C1: free_repl (repl.c:25)
+==7626==    by 0x1095CB: repl (repl.c:54)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Address 0x4b01c20 is 0 bytes inside a block of size 32 free'd
+==7626==    at 0x484317B: free (vg_replace_malloc.c:872)
+==7626==    by 0x109746: free_token (free_token.c:24)
+==7626==    by 0x10A395: collect_args (parse_cmd.c:91)
+==7626==    by 0x10A24F: parse_cmd (parse_cmd.c:27)
+==7626==    by 0x10A12A: parse_statement (parser.c:62)
+==7626==    by 0x10A07A: parse (parser.c:39)
+==7626==    by 0x109586: repl (repl.c:51)
+==7626==    by 0x109372: main (main.c:28)
+==7626==  Block was alloc'd at
+==7626==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
+==7626==    by 0x1095F6: new_token (new_token.c:19)
+==7626==    by 0x109686: new_str_token (new_token.c:36)
+==7626==    by 0x109C55: snap_string_token (tokenizer.c:79)
+==7626==    by 0x10A014: tokenizer (tokenizer.c:130)
+==7626==    by 0x109573: repl (repl.c:50)
+==7626==    by 0x109372: main (main.c:28)
+==7626== 
+
+atic t_assign                  **collect_assigns(t_token **tokens);
+static char                            **collect_args(t_token **tokens);
+static t_assign                        *to_assign(char *str);
+static void                            set_redir(t_redirection *redir, int type,
+                                                       char *specifier);
+
+t_node *parse_cmd(t_token *tokens)
+{
+       char                    **args;
+       t_assign                **assigns;
+       t_redirection   *redirs;
+
+       redirs = collect_redirs(&tokens);
+       assigns = collect_assigns(&tokens);
+       args = collect_args(&tokens);
+       return (new_cmd_node(args, assigns, redirs));
+}
+
+static t_redirection   *collect_redirs(t_token **tokens)
+{
+       t_redirection   *result;
+       t_token                 *cur;
+       int                             idx;
+
+       cur = *tokens;
+       result = malloc(sizeof(t_redirection) * 2);
+       if (result == NULL)
+       {
+               // free all tokens
+               return (NULL);
+       }
+       set_redir(&result[0], 0, NULL);
+       set_redir(&result[1], 0, NULL);
+       while (cur != NULL && cur->next != NULL)
+       {
+               if (cur->type == REDIR_TOKEN && cur->next->type == STRING_TOKEN)
+               {
+                       if (cur->content.redir_type & (INPUT_FILE | INPUT_LIMITER))
+                               idx = 0;
+                       else if (cur->content.redir_type & (OUTPUT_APPEND | OUTPUT_OVERRIDE))
+                               idx = 1;
+                       set_redir(&result[idx], cur->content.redir_type,
+                               cur->next->content.string);
+                       cur = cur->next;
+                       free_token_and_connect(cur->previous);
+                       if (cur->next != NULL)
+                       {
+                               cur = cur->next;
+                               free_token_and_connect(cur->previous);
+                       }
+                       else
+                       {
+                               free_token(cur);
+                       }
+               }
+               else if (cur->type == REDIR_TOKEN)
+               {
+                       // err Parsing error
+                       free(result);
+                       return (NULL);
+               }
+               else
+               {
+                       cur = cur->next;
+               }
+       }
+       return (result);
+}
+
+static t_assign        **collect_assigns(t_token **tokens)
+{
+       t_token         *cur;
+       t_assign        **result;
+       int                     i;
+
+       cur = *tokens;
+       i = 0;
+       while (cur != NULL && cur->type == STRING_TOKEN
+               && cur->content.string[0] != '"' && cur->content.string[0] != '\''
+               && ft_strchr(cur->content.string, '=') != NULL)
+       {
+               i++;
+               cur = cur->next;
+       }
+       result = malloc(sizeof(t_assign *) * (i + 1));
+       if (!result)
+       {
+               // free all tokens
+               return (NULL);
+       }
+       cur = *tokens;
+       i = 0;
+       while (cur != NULL && cur->type == STRING_TOKEN
+               && cur->content.string[0] != '"' && cur->content.string[0] != '\''
+               && ft_strchr(cur->content.string, '=') != NULL)
+       {
+               result[i] = to_assign(cur->content.string);
+               i++;
+               cur = cur->next;
+               free_token(cur->previous);
+       }
+       *tokens = cur;
+       result[i] = NULL;
+       return (result);
+}
+
+static t_assign        *to_assign(char *str)
+{
+       t_assign        *result;
+       char            *split_pos;
+
+       split_pos = ft_strchr(str, '=');
+       *split_pos = '\0';
+       result = malloc(sizeof(t_assign));
+       if (result == NULL)
+       {
+               return (NULL);
+       }
+       result->var = str;
+       result->value = split_pos + 1;
+       return (result);
+}
+
+static char    **collect_args(t_token **tokens)
+{
+       t_token *cur;
+       char    **result;
+       int             i;
+
+       cur = *tokens;
+       i = 0;
+       while (cur != NULL)
+       {
+               i++;
+               cur = cur->next;
+       }
+       result = malloc(sizeof(char *) * (i + 1));
+       if (!result)
+       {
+               // free all tokens;
+               return (NULL);
+       }
+       cur = *tokens;
+       i = 0;
+       while (cur != NULL)
+       {
+               result[i] = cur->content.string;
+               // free token
+               i++;
+               cur = cur->next;
+       }
+       result[i] = NULL;
+       return (result);
+}
+
+static void    set_redir(t_redirection *redir, int type, char *specifier)
+{
+       redir->type = type;
+       redir->specifier = specifier;
+}