]> git.dkaiser.de - 42/minishell.git/commitdiff
here
authorChristopher Uhlig <chuhlig@3-H-2.42heilbronn.de>
Mon, 13 Jan 2025 10:06:54 +0000 (11:06 +0100)
committerChristopher Uhlig <chuhlig@3-H-2.42heilbronn.de>
Mon, 13 Jan 2025 10:06:54 +0000 (11:06 +0100)
22 files changed:
Makefile
include/env.h
include/minishell.h
lib/libft/Makefile
lib/libft/ft_strcat.c [new file with mode: 0644]
lib/libft/ft_strcmp.c [new file with mode: 0644]
lib/libft/ft_strcpy.c [new file with mode: 0644]
lib/libft/libft.h
src/builtins_part_one.c [new file with mode: 0644]
src/builtins_part_two.c [new file with mode: 0644]
src/collect_redirs.c
src/env.c
src/env_to_strlst.c [new file with mode: 0644]
src/execute_cmd.c [new file with mode: 0644]
src/format_string.c [new file with mode: 0644]
src/get_cmd_path.c [new file with mode: 0644]
src/interpreter.c [new file with mode: 0644]
src/main.c
src/parse_cmd.c
src/parser.c
src/repl.c
src/tokenizer.c

index 827c317214e23f6d99c8d644f9110f91e1f11597..7cfc8940f2c0a675efd65b2a15ed6845063015f6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,10 @@
 ################################## VARIABLES ###################################
 ################################################################################
 
+################################################################################
+################################## VARIABLES ###################################
+################################################################################
+
 NAME    := minishell
 
 CC      =  cc
@@ -13,7 +17,9 @@ HEADERS =  -I include -I $(LIB_DIR)/libft
 VPATH   := src
 SRC     := main.c debug_tools.c init.c signal_handling.c repl.c new_token.c \
            free_token.c new_node.c free_node.c tokenizer.c parser.c \
-           parse_cmd.c collect_redirs.c print_ast.c
+           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
 
 OBJ_DIR := _obj
 OBJ     := $(addprefix $(OBJ_DIR)/, $(SRC:%.c=%.o))
index 5a6533387339d930e4fc00cd87b7268d177f1435..d38ed290da8323430cb8788047ee30f65d5dee98 100644 (file)
@@ -6,10 +6,15 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/08/08 16:53:39 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/10/17 15:37:32 by chuhlig          ###   ########.fr       */
+/*   Updated: 2024/12/24 16:21:50 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
+#ifndef ENV_H
+# define ENV_H
+# include "libft.h"
+# include <stdio.h>
+
 typedef struct s_env
 {
        char                    *name;
@@ -19,4 +24,15 @@ typedef struct s_env
 
 void   getenvlst(t_env **env, char **en);
 void   free_envlst(t_env **env);
+char   *env_get(t_env *env, char *name);
+char   **env_to_strlst(t_env *env);
+void   update_oldpwd(t_env **env);
+void   update_pwd(t_env **env);
+int            unset(char **av, t_env **env);
+int            export(char **av, t_env **env);
+int            echo(char **av);
+int            pwd(t_env *env);
+int            cd(t_env **env, char **args);
+int            ft_env(t_env *env);
 
+#endif
\ No newline at end of file
index 6997b15c97ad59265328c300ec9ed2680da68dac..028a4fcc30612e7026dfdf966e1b14d214664bda 100644 (file)
@@ -3,10 +3,10 @@
 /*                                                        :::      ::::::::   */
 /*   minishell.h                                        :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/22 17:14:49 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/08/11 12:22:07 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/11 16:05:11 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 int                            init(void);
 int                            init_signal_handling(void);
 
-void                   repl(const char *prompt);
+void                   repl(const char *prompt, t_env **env);
 
-t_list                 *parse(t_token *tokens);
-t_node                 *parse_cmd(t_token *tokens);
+t_list                 *parse(t_token *tokens, t_env **env);
+t_node                 *parse_cmd(t_token *tokens, t_env **env);
 t_redirection  *collect_redirs(t_token **tokens);
 
 void                   print_ast(t_node *ast);
+int                            eval(t_node *node, t_env **env);
+char                   *get_cmd_path(char *cmd, t_env *env);
+int                            execute_cmd(t_cmd *cmd, t_env **env);
+char                   *format_string(char *str, t_env *env);
+
+
 #endif
index 6f2950c5c99f6c7a7a5db44f23b1e2d7bdbb93e6..2150e99a2fc40f9782f73bcdced82664d6394b9f 100644 (file)
@@ -26,6 +26,8 @@ SRC =         ft_atoi.c \
                        ft_strdup.c \
                        ft_striteri.c \
                        ft_strjoin.c \
+                       ft_strcat.c \
+                       ft_strcpy.c \
                        ft_strlcat.c \
                        ft_strlcpy.c \
                        ft_strlen.c \
@@ -45,6 +47,7 @@ SRC =         ft_atoi.c \
                        get_next_line.c \
                        get_next_line_utils.c \
                        ft_atol.c \
+                       ft_strcmp.c \
                        ft_lstnew_bonus.c \
                        ft_lstadd_front_bonus.c \
                        ft_lstsize_bonus.c \
diff --git a/lib/libft/ft_strcat.c b/lib/libft/ft_strcat.c
new file mode 100644 (file)
index 0000000..648c184
--- /dev/null
@@ -0,0 +1,29 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_strcat.c                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+char   *ft_strcat(char *dest, char *src)
+{
+       int             i;
+       int             j;
+
+       j = 0;
+       i = 0;
+       while (dest[i])
+               i++;
+       while (src[j])
+       {
+               dest[i + j] = src[j];
+               j++;
+       }
+       dest[i + j] = '\0';
+       return (dest);
+}
\ No newline at end of file
diff --git a/lib/libft/ft_strcmp.c b/lib/libft/ft_strcmp.c
new file mode 100644 (file)
index 0000000..af7b2a1
--- /dev/null
@@ -0,0 +1,23 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_strcmp.c                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "libft.h"
+
+int    ft_strcmp(char *s1, char *s2)
+{
+       int     i;
+
+       i = 0;
+       while (s1[i] && s1[i] == s2[i])
+               i++;
+       return (s1[i] - s2[i]);
+}
\ No newline at end of file
diff --git a/lib/libft/ft_strcpy.c b/lib/libft/ft_strcpy.c
new file mode 100644 (file)
index 0000000..b5c612f
--- /dev/null
@@ -0,0 +1,25 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   ft_strcpy.c                                        :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+char   *ft_strcpy(char *dest, char *src)
+{
+       int     i;
+
+       i = 0;
+       while (src[i] != '\0')
+       {
+               dest[i] = src[i];
+               i++;
+       }
+       dest[i] = '\0';
+       return (dest);
+}
\ No newline at end of file
index abb739da6253d2904bd29c7b1122598bce8386da..6b4c824842afc862df69fe21c24784e8d5b361f9 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/03/10 16:37:54 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/08/11 14:01:57 by chuhlig          ###   ########.fr       */
+/*   Updated: 2025/01/09 14:39:28 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -26,6 +26,7 @@ int                                   ft_isalnum(int c);
 int                                    ft_isprint(int c);
 int                                    ft_isspace(char c);
 int                                    ft_isascii(int c);
+int                                    ft_strcmp(char *s1, char *s2);
 int                                    ft_strlen(const char *str);
 void                           *ft_memset(void *b, int c, size_t len);
 void                           ft_bzero(void *s, size_t n);
@@ -59,6 +60,8 @@ void                          ft_putstr_fd(char *s, int fd);
 void                           ft_putendl_fd(char *s, int fd);
 void                           ft_putnbr_fd(int n, int fd);
 char                           *ft_strncpy(char *s1, char *s2, int n);
+char                           *ft_strcat(char *dest, char *src);
+char                           *ft_strcpy(char *dest, char *src);
 
 typedef struct s_list
 {
diff --git a/src/builtins_part_one.c b/src/builtins_part_one.c
new file mode 100644 (file)
index 0000000..d64bb54
--- /dev/null
@@ -0,0 +1,161 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   builtins_part_one.c                                :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#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);
+}
+
+int    unset(char **av, t_env **env)
+{
+       t_env   *current;
+       t_env   *prev;
+       int             i;
+
+       i = 0;
+       while (av[++i])
+       {
+               current = *env;
+               prev = NULL;
+               while (current)
+               {
+                       if (ft_strcmp(current->name, av[i]) == 0)
+                       {
+                               if (prev)
+                                       prev->next = current->next;
+                               else
+                                       *env = current->next;
+                               free_env_node(current);
+                               break ;
+                       }
+                       prev = current;
+                       current = current->next;
+               }
+       }
+       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(env->name, av) == 0)
+                       return (env);
+               env = env->next;
+       }
+       return (NULL);
+}
+
+int    export(char **av, t_env **env)
+{
+       char    *tmp;
+       t_env   *current;
+       int             i;
+
+       current = NULL;
+       i = 0;
+       while (av[++i])
+       {
+               if ((ft_strchr(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);
+               }
+       }
+       return (0);
+}
\ No newline at end of file
diff --git a/src/builtins_part_two.c b/src/builtins_part_two.c
new file mode 100644 (file)
index 0000000..f54e04f
--- /dev/null
@@ -0,0 +1,84 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   builtins_part_two.c                                :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "env.h"
+
+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));
+       tmp = ft_strdup(cwd);
+       free(current->value);
+       current->value = tmp;
+}
+
+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));
+       tmp = ft_strdup(cwd);
+       free(current->value);
+       current->value = tmp;
+}
+
+int    cd(t_env **env, char **av)
+{
+       t_env   *current;
+
+       current = *env;
+       if (av[1] == NULL)
+       {
+               update_oldpwd(env);
+               while (current)
+               {
+                       if (ft_strncmp(current->name, "HOME", 4) == 0)
+                               break ;
+                       current = current->next;
+               }
+               if (chdir(current->value) == -1)
+                       return (1);
+       }
+       else
+       {
+               update_oldpwd(env);
+               if (chdir(av[1]) == -1)
+                       return (1);
+               update_pwd(env);
+       }
+       return (0);
+}
index 9ac1605ef413f7bf57d39ce75613e524d66bd7d5..be0e00f28af1f52a1ef55428973ac77919323d1c 100644 (file)
@@ -3,21 +3,61 @@
 /*                                                        :::      ::::::::   */
 /*   collect_redirs.c                                   :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/08/02 13:49:31 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/09/17 19:48:48 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/13 09:52:00 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "minishell.h"
 
-static t_token *collect_redir(t_token **tokens, t_redirection *result,
-                                       t_token *cur);
-static void            collect_and_check_redir(t_token **tokens, t_redirection *result,
-                                       t_token **cur);
+static void            collect_and_check_redir(t_redirection *result, t_token **cur);
 static void            set_redir(t_redirection *redir, int type, char *specifier);
-static int             is_output_redir(int i);
+
+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)
 {
@@ -33,7 +73,7 @@ t_redirection *collect_redirs(t_token **tokens)
        while (cur != NULL && cur->next != NULL)
        {
                if (cur->type == REDIR_TOKEN && cur->next->type == STRING_TOKEN)
-                       collect_and_check_redir(tokens, result, &cur);
+                       collect_and_check_redir(result, &cur);
                else if (cur->type == REDIR_TOKEN)
                        return (free(result), NULL);
                else
@@ -44,56 +84,43 @@ t_redirection       *collect_redirs(t_token **tokens)
        return (result);
 }
 
-static void    collect_and_check_redir(t_token **tokens, t_redirection *result,
-               t_token **cur)
-{
-       int     is_redir_only;
-
-       is_redir_only = 0;
-       if ((*cur)->previous == NULL && (*cur)->next->next == NULL)
-               is_redir_only = 1;
-       *cur = collect_redir(tokens, result, *cur);
-       if (is_redir_only)
-               *tokens = NULL;
-}
-
-static t_token *collect_redir(t_token **tokens, t_redirection *result,
-               t_token *cur)
-{
-       set_redir(&result[is_output_redir(cur->content.redir_type)],
-               cur->content.redir_type, cur->next->content.string);
-       cur = cur->next;
-       free_token_and_connect(cur->previous);
-       if (cur->next != NULL)
-       {
-               if (cur->previous == NULL)
-                       *tokens = cur->next;
-               cur = cur->next;
-               free_token_and_connect(cur->previous);
-       }
-       else
-       {
-               free_token(cur);
-               return (NULL);
-       }
-       return (cur);
-}
-
 static void    set_redir(t_redirection *redir, int type, char *specifier)
 {
        redir->type = type;
        redir->specifier = specifier;
 }
 
-static int     is_output_redir(int i)
+static void    collect_and_check_redir(t_redirection *result, t_token **cur)
 {
-       if (i & (INPUT_FILE | INPUT_LIMITER))
-               return (0);
-       else if (i & (OUTPUT_APPEND | OUTPUT_OVERRIDE))
-               return (1);
+       char    *heredoc_data;
+       t_token *next_token;
+
+       heredoc_data = NULL;
+       if ((*cur)->content.redir_type == INPUT_LIMITER)
+       {
+               heredoc_data = read_heredoc((*cur)->next->content.string);
+               if (!heredoc_data)
+               {
+                       perror("Heredoc allocation failed");
+                       return ;
+               }
+               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)
        {
-               panic(UNREACHABLE);
-               return (-1);
+               *cur = next_token->next;
+               free_token_and_connect(next_token);
        }
+       else
+               *cur = NULL;
 }
index 8105bf42e915933606f3356e2f7202d1fc3bdaef..0213209541618098e0bce096697eb8f3435fd749 100644 (file)
--- a/src/env.c
+++ b/src/env.c
@@ -6,11 +6,12 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/10/17 14:31:07 by chuhlig           #+#    #+#             */
-/*   Updated: 2024/10/17 15:18:44 by chuhlig          ###   ########.fr       */
+/*   Updated: 2024/12/17 19:36:14 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "env.h"
+#include <stdlib.h>
 
 void   getenvlst(t_env **env, char **en)
 {
@@ -22,7 +23,7 @@ void  getenvlst(t_env **env, char **en)
        while (en[i] != NULL)
        {
                tmp = ft_strchr(en[i], '=');
-               tmp = '\0';
+               *tmp = '\0';
                current = *env;
                current = malloc(sizeof(t_env));
                current->name = ft_strdup(en[i]);
@@ -47,4 +48,15 @@ void free_envlst(t_env **env)
                free(cur);
                cur = new;
        }
+}
+
+char   *env_get(t_env *env, char *name)
+{
+       while (env != NULL)
+       {
+               if (!ft_strncmp(env->name, name, ft_strlen(name)))
+                       return (env->value);
+               env = env->next;
+       }
+       return (NULL);
 }
\ No newline at end of file
diff --git a/src/env_to_strlst.c b/src/env_to_strlst.c
new file mode 100644 (file)
index 0000000..c4c98c3
--- /dev/null
@@ -0,0 +1,58 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   env_to_strlst.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "libft.h"
+#include "minishell.h"
+
+static char    *get_var_assign(t_env *cur);
+
+char   **env_to_strlst(t_env *env)
+{
+       int             size;
+       t_env   *cur;
+       char    **result;
+       int             i;
+
+       size = 0;
+       cur = env;
+       while (cur != NULL)
+       {
+               size++;
+               cur = cur->next;
+       }
+       result = malloc(sizeof(char *) * (size + 1));
+       if (result == NULL)
+               return (NULL);
+       i = 0;
+       cur = env;
+       while (i < size)
+       {
+               result[i] = get_var_assign(cur);
+               cur = cur->next;
+               i++;
+       }
+       result[i] = NULL;
+       return (result);
+}
+
+static char    *get_var_assign(t_env *cur)
+{
+       char    *left_side;
+       char    *result;
+
+       left_side = ft_strjoin(cur->name, "=");
+       if (left_side == NULL)
+               return (NULL);
+       result = ft_strjoin(left_side, cur->value);
+       free(left_side);
+       return (result);
+}
\ No newline at end of file
diff --git a/src/execute_cmd.c b/src/execute_cmd.c
new file mode 100644 (file)
index 0000000..803d88f
--- /dev/null
@@ -0,0 +1,77 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   execute_cmd.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "minishell.h"
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/_types/_pid_t.h>
+#include <sys/_types/_s_ifmt.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+
+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;
+
+       original_stdout = dup(STDOUT_FILENO);
+       original_stdin = dup(STDIN_FILENO);
+       if (handle_redirections(cmd->redirs) == -1)
+       {
+               dup2(original_stdout, STDOUT_FILENO);
+               dup2(original_stdin, STDIN_FILENO);
+               close(original_stdout);
+               close(original_stdin);
+               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);
+               return (result);
+       }
+       pid = fork();
+       if (pid == -1)
+       {
+               perror("fork");
+               dup2(original_stdout, STDOUT_FILENO);
+               dup2(original_stdin, STDIN_FILENO);
+               close(original_stdout);
+               close(original_stdin);
+               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);
+       }
+       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
diff --git a/src/format_string.c b/src/format_string.c
new file mode 100644 (file)
index 0000000..bd7f703
--- /dev/null
@@ -0,0 +1,125 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   format_string.c                                    :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "get_next_line.h"
+#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)
+{
+       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')
+       {
+               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++;
+       }
+       append_slice(&result, str, start, pos);
+       return (result);
+}
+
+static void    append_slice(char **dst, char *src, int start, int end)
+{
+       char    *result;
+       int             len;
+       int             i;
+
+       if (*dst != NULL)
+               len = ft_strlen(*dst);
+       else
+       {
+               len = 0;
+       }
+       result = malloc(len + (end - start) + 1);
+       if (!result)
+               return ;
+       ft_strncpy(result, *dst, len);
+       i = 0;
+       while (start + i < end)
+       {
+               result[len + i] = src[start + i];
+               i++;
+       }
+       result[len + i] = '\0';
+       if (*dst != NULL)
+               free(*dst);
+       *dst = result;
+}
+
+static void    append_var(char **dst, char *src, int *pos, t_env *env)
+{
+       int             i;
+       char    *var;
+       char    *value;
+       char    *result;
+
+       i = 0;
+       *pos += 1;
+       while (src[*pos + i] != '\0' && src[*pos + i] != '\'' && src[*pos
+               + i] != '"' && src[*pos + i] != '$')
+       {
+               i++;
+       }
+       var = malloc(i + 1);
+       if (var == NULL)
+               return ;
+       var[i] = '\0';
+       i--;
+       while (i >= 0)
+       {
+               var[i] = src[*pos + i];
+               i--;
+       }
+       value = env_get(env, var);
+       if (value != NULL)
+       {
+               result = ft_strjoin(*dst, value);
+               free(*dst);
+               *dst = result;
+       }
+       *pos += ft_strlen(var);
+}
diff --git a/src/get_cmd_path.c b/src/get_cmd_path.c
new file mode 100644 (file)
index 0000000..8a27584
--- /dev/null
@@ -0,0 +1,82 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   get_cmd_path.c                                     :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#include "libft.h"
+#include "minishell.h"
+
+static char    *get_absolute_cmd_path(char *cmd, t_env *env);
+static char    *find_in_path(char *cmd, t_env *env);
+char           **get_split_path(t_env *env);
+
+char   *get_cmd_path(char *cmd, t_env *env)
+{
+       if (cmd[0] == '/')
+               return (ft_strdup(cmd));
+       else if (ft_strchr(cmd, '/'))
+               return (get_absolute_cmd_path(cmd, env));
+       else
+               return (find_in_path(cmd, env));
+}
+
+static char    *get_absolute_cmd_path(char *cmd, t_env *env)
+{
+       char    *cur_dir;
+       char    *result;
+
+       cur_dir = ft_strjoin(env_get(env, "PWD"), "/");
+       if (!cur_dir)
+               return (NULL);
+       result = ft_strjoin(cur_dir, cmd);
+       free(cur_dir);
+       if (!result)
+               return (NULL);
+       if (access(result, X_OK) == -1)
+       {
+               free(result);
+               return (NULL);
+       }
+       return (result);
+}
+
+static char    *find_in_path(char *cmd, t_env *env)
+{
+       char    *cur_path;
+       char    *cmd_path;
+       char    **path;
+
+       path = get_split_path(env);
+       cmd_path = NULL;
+       while (*path)
+       {
+               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++;
+       }
+       return (NULL);
+}
+
+char   **get_split_path(t_env *env)
+{
+       char    *path;
+
+       path = env_get(env, "PATH");
+       return (ft_split(path, ':'));
+}
diff --git a/src/interpreter.c b/src/interpreter.c
new file mode 100644 (file)
index 0000000..7b0306f
--- /dev/null
@@ -0,0 +1,159 @@
+/* ************************************************************************** */
+/*                                                                            */
+/*                                                        :::      ::::::::   */
+/*   interpreter.c                                      :+:      :+:    :+:   */
+/*                                                    +:+ +:+         +:+     */
+/*   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       */
+/*                                                                            */
+/* ************************************************************************** */
+
+#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);
+}
+
+static int     handle_redirections(t_redirection *redirs)
+{
+       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);
+       }
+
+static int     eval_rec(t_node *node, t_env **env, int in_fd)
+{
+       pid_t   pid;
+       int             p[2];
+       int             result;
+       int             status;
+       int             original_stdin;
+
+       if (node->type == PIPE_NODE)
+       {
+               pipe(p);
+               pid = fork();
+               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);
+               }
+       }
+       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;
+       }
+       return (result);
+}
+
+int eval(t_node *node, t_env **env)
+{
+       return (eval_rec(node, env, STDIN_FILENO));
+}
index 8523b9e56459e744278120d4110cbdf14242fde9..a53760c8471d6fed9793a5e58b4c5c5c6f89878b 100644 (file)
@@ -6,15 +6,21 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/22 17:14:03 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/07/18 16:44:14 by chuhlig          ###   ########.fr       */
+/*   Updated: 2024/12/17 19:26:42 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "../include/minishell.h"
 
-int    main(void)
+int    main(int argc, char *argv[], char *envp[])
 {
+       t_env   *env;
+
+       env = NULL;
+       if (!argc && !argv)
+               return (1);
        if (init())
                return (1);
-       repl("Minishell $ ");
+       getenvlst(&env, envp);
+       repl("Minishell $ ", &env);
 }
index 2755cae856426e05a99a835d6605a2930a24301d..3c4eb965f683aa1ab0a5238ee58f0376b0afa6f8 100644 (file)
@@ -3,28 +3,35 @@
 /*                                                        :::      ::::::::   */
 /*   parse_cmd.c                                        :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/07/08 15:06:25 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/08/11 12:20:06 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/11 16:04:50 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "minishell.h"
 
-static char    **collect_args(t_token **tokens);
+static char    **collect_args(t_token **tokens, t_env **env);
 
-t_node *parse_cmd(t_token *tokens)
+t_node *parse_cmd(t_token *tokens, t_env **env)
 {
        char                    **args;
        t_redirection   *redirs;
 
        redirs = collect_redirs(&tokens);
-       args = collect_args(&tokens);
+       if (redirs == NULL)
+               return (NULL);
+       args = collect_args(&tokens, env);
+       if (args == NULL)
+       {
+               free(redirs);
+               return (NULL);
+       }
        return (new_cmd_node(args, redirs));
 }
 
-static char    **collect_args(t_token **tokens)
+static char    **collect_args(t_token **tokens, t_env **env)
 {
        t_token *cur;
        char    **result;
@@ -43,7 +50,7 @@ static char   **collect_args(t_token **tokens)
        {
                if (cur->previous)
                        free_token(cur->previous);
-               result[i] = cur->content.string;
+               result[i] = format_string(cur->content.string, *env);
                i++;
                cur = cur->next;
        }
index 06c1df7ee22f41932f64a0e058e81da6429eba24..1375954e9941f5385031005527e807ac1edd23fb 100644 (file)
@@ -3,35 +3,36 @@
 /*                                                        :::      ::::::::   */
 /*   parser.c                                           :+:      :+:    :+:   */
 /*                                                    +:+ +:+         +:+     */
-/*   By: dkaiser <dkaiser@student.42heilbronn.de    +#+  +:+       +#+        */
+/*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/29 15:53:29 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/09/17 19:03:48 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/11 16:06:54 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "libft.h"
 #include "minishell.h"
 #include "token.h"
+#include "env.h"
 
 static t_token *find_token_by_type(t_token *tokens, int type);
 t_token                        *split_at_first(t_token **tokens, int type);
-static t_node  *parse_statement(t_token *tokens);
+static t_node  *parse_statement(t_token *tokens, t_env **env);
 
-t_list *parse(t_token *tokens)
+t_list *parse(t_token *tokens, t_env **env)
 {
        t_node  *result;
 
        if ((*tokens).type == PIPE_TOKEN)
                result = NULL;
        else
-               result = parse_statement(tokens);
+               result = parse_statement(tokens, env);
        if (result == NULL)
                printf("Parsing error.\n");
        return (ft_lstnew(result));
 }
 
-static t_node  *parse_statement(t_token *tokens)
+static t_node  *parse_statement(t_token *tokens, t_env **env)
 {
        t_token *left_side_tokens;
 
@@ -43,12 +44,12 @@ static t_node       *parse_statement(t_token *tokens)
        }
        else if (tokens != NULL)
        {
-               return (new_pipe_node(parse_cmd(left_side_tokens),
-                               parse_statement(tokens)));
+               return (new_pipe_node(parse_cmd(left_side_tokens, env),
+                               parse_statement(tokens, env)));
        }
        else
        {
-               return (parse_cmd(left_side_tokens));
+               return (parse_cmd(left_side_tokens, env));
        }
 }
 
index d590fec3fcee0c0aa3ff817d7f5fd30f2dad9e77..7ff80a8adfdb12f7573c17131b287e767fff1a2a 100644 (file)
@@ -6,14 +6,34 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/24 16:07:04 by dkaiser           #+#    #+#             */
-/*   Updated: 2024/09/13 16:26:35 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/11 16:01:44 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
 #include "../include/minishell.h"
 #include "token.h"
 
-void   repl(const char *prompt)
+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   repl(const char *prompt, t_env **env)
 {
        char    *input;
        t_token *token_list;
@@ -29,9 +49,13 @@ void repl(const char *prompt)
                add_history(input);
                token_list = NULL;
                tokenizer(input, &token_list, '\0');
-               lines = parse(token_list);
+               token_list = reverse_token_list(token_list);
+               lines = parse(token_list, env);
                if (lines)
+               {
                        print_ast(lines->content);
+                       eval(lines->content, env);
+               }
                free(input);
        }
 }
index ab8a6ac2907daaa5b36ea256ec0706c77a00771b..26edd2eb23cc90b264ad7b08a43f948ce994542f 100644 (file)
@@ -6,7 +6,7 @@
 /*   By: chuhlig <chuhlig@student.42.fr>            +#+  +:+       +#+        */
 /*                                                +#+#+#+#+#+   +#+           */
 /*   Created: 2024/06/28 20:55:50 by chuhlig           #+#    #+#             */
-/*   Updated: 2024/08/29 15:26:55 by dkaiser          ###   ########.fr       */
+/*   Updated: 2025/01/11 15:22:07 by chuhlig          ###   ########.fr       */
 /*                                                                            */
 /* ************************************************************************** */
 
@@ -111,6 +111,4 @@ void        tokenizer(char *s, t_token **token_list, char quote_check)
                        pos = i + 1;
                }
        }
-       while ((*token_list)->previous)
-               *token_list = (*token_list)->previous;
 }