--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
--- /dev/null
+{
+ "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
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
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))
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:
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
/* ::: :::::::: */
/* 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
{
{
char **args;
struct s_redirection redirs[2];
+ t_list *create_files;
} t_cmd;
union u_node_content
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
/* ::: :::::::: */
/* 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
void dbg(char *str);
void panic(char *msg);
+
#endif
/* 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 */
/* */
/* ************************************************************************** */
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);
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
/* 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
/* 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 */
/* */
/* ************************************************************************** */
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
/* ::: :::::::: */
/* 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 */
/* */
/* ************************************************************************** */
/* 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 */
/* */
/* ************************************************************************** */
}
dest[i + j] = '\0';
return (dest);
-}
\ No newline at end of file
+}
/* 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 */
/* */
/* ************************************************************************** */
while (s1[i] && s1[i] == s2[i])
i++;
return (s1[i] - s2[i]);
-}
\ No newline at end of file
+}
/* 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 */
/* */
/* ************************************************************************** */
}
dest[i] = '\0';
return (dest);
-}
\ No newline at end of file
+}
/* ::: :::::::: */
/* 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> */
/* 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)
{
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;
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));
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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);
+}
/* 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));
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));
}
if (chdir(current->value) == -1)
return (1);
+ update_pwd(env);
}
else
{
}
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);
+}
/* 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);
}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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));
+}
/* ::: :::::::: */
/* 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)
{
/* 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)
{
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);
+}
/* 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);
cur = env;
while (i < size)
{
+ if (ft_strchr(cur->name, '?'))
+ cur = cur->next;
result[i] = get_var_assign(cur);
cur = cur->next;
i++;
result = ft_strjoin(left_side, cur->value);
free(left_side);
return (result);
-}
\ No newline at end of file
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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, ':'));
+// }
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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");
+}
/* 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);
+}
/* 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)
if (*dst != NULL)
len = ft_strlen(*dst);
else
- {
len = 0;
- }
result = malloc(len + (end - start) + 1);
if (!result)
return ;
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);
}
/* ::: :::::::: */
/* 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)
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);
}
/* ::: :::::::: */
/* 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)
{
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)
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
+ }
}
/* 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;
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);
}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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));
+}
/* ::: :::::::: */
/* 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 */
/* */
/* ************************************************************************** */
/* 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));
}
/* 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);
}
/* ::: :::::::: */
/* 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 */
/* */
/* ************************************************************************** */
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;
{
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);
/* ::: :::::::: */
/* 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 */
/* */
/* ************************************************************************** */
token = new_token(STRING_TOKEN, previous, next);
if (token == NULL)
+ {
+ free(str);
return (NULL);
+ }
token->content.string = str;
return (token);
}
/* 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 */
/* */
/* ************************************************************************** */
{
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);
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)
t_token *cur;
char **result;
int i;
+ t_token *next;
cur = *tokens;
i = 0;
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);
/* 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 */
/* */
/* ************************************************************************** */
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;
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)
if (left_side_tokens == NULL)
{
free_tokens(tokens);
+ tokens = NULL;
return (NULL);
}
else if (tokens != NULL)
if (result == split)
result = NULL;
free_token(split);
+ split = NULL;
return (result);
}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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;
+}
--- /dev/null
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* 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);
+}
/* 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);
}
}
/* ::: :::::::: */
/* 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 */
/* */
/* ************************************************************************** */
/* 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)
*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;
}
pos = i + 1;
}
}
+ *token_list = reverse_token_list(*token_list);
}
--- /dev/null
+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;
+}