intra to gitea

This commit is contained in:
root 2025-11-15 22:28:42 +00:00
commit 03b080ed92
98 changed files with 5522 additions and 0 deletions

143
Makefile Executable file
View File

@ -0,0 +1,143 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: tordner <tordner@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2025/01/29 17:32:15 by thorgal #+# #+# #
# Updated: 2025/06/03 04:09:04 by tordner ### ########.fr #
# #
# **************************************************************************** #
NAME = minishell
CC = cc
CFLAGS = -pthread -Iincludes -Wall -Wextra -Wextra
SRCDIR = src
LIBFT = libft.a
OBJDIR = obj
INCDIR = includes
SRCS = $(SRCDIR)/main/main.c \
$(SRCDIR)/main/shell.c \
$(SRCDIR)/main/signals.c \
$(SRCDIR)/main/signals_utils.c \
$(SRCDIR)/utils/utils.c \
$(SRCDIR)/main/prompt.c \
$(SRCDIR)/exec/execute_pipeline.c \
$(SRCDIR)/utils/free.c \
$(SRCDIR)/utils/get_env_value.c \
$(SRCDIR)/main/input.c \
$(SRCDIR)/tokens/tokens.c \
$(SRCDIR)/tokens/handle_quoted_count.c \
$(SRCDIR)/tokens/extract_quoted_content.c \
$(SRCDIR)/tokens/tokens_utils.c \
$(SRCDIR)/tokens/syntax.c \
$(SRCDIR)/tokens/check_pipes.c \
$(SRCDIR)/tokens/check_redirections.c \
$(SRCDIR)/tokens/token_list.c \
$(SRCDIR)/builtins/echo.c \
$(SRCDIR)/builtins/cd.c \
$(SRCDIR)/builtins/cd_utils.c \
$(SRCDIR)/builtins/pwd.c \
$(SRCDIR)/builtins/env.c \
$(SRCDIR)/builtins/export.c \
$(SRCDIR)/builtins/unset.c \
$(SRCDIR)/exec/exec.c \
$(SRCDIR)/exec/file_handler.c \
$(SRCDIR)/exec/get_env.c \
$(SRCDIR)/exec/heredoc.c \
$(SRCDIR)/exec/pipe.c \
$(SRCDIR)/tokens/tokens_list2.c \
$(SRCDIR)/tokens/tokens_utils2.c \
$(SRCDIR)/tokens/tokenize_command.c \
$(SRCDIR)/tokens/extract_token_len.c \
$(SRCDIR)/builtins/export_utils.c \
$(SRCDIR)/builtins/export_utils2.c \
$(SRCDIR)/builtins/exit.c \
$(SRCDIR)/exec/exec_utils.c \
$(SRCDIR)/exec/setup_files.c \
$(SRCDIR)/exec/execute_ve.c \
$(SRCDIR)/exec/ft_exec.c \
$(SRCDIR)/exec/setup_output_redirections.c \
$(SRCDIR)/tokens/expander.c \
$(SRCDIR)/builtins/exit_utils.c \
$(SRCDIR)/builtins/export_utils_3.c
OBJS = $(SRCS:$(SRCDIR)/%.c=$(OBJDIR)/%.o)
OBJSUBDIRS = $(sort $(dir $(OBJS)))
GREEN = \033[0;32m
YELLOW = \033[0;33m
CYAN = \033[0;36m
RESET = \033[0m
BOLD = \033[1m
WHITE = \033[0;97m
BLUE = \033[0;34m
LOADING_CHARS = ⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏
define MINISHELL_ART
███▄ ▄███▓ ██▓ ███▄ █ ██▓ ██████ ██░ ██ ▓█████ ██▓ ██▓
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
endef
export MINISHELL_ART
all: print_art $(NAME)
print_art:
@printf "$(CYAN)%s$(RESET)\n" "$$MINISHELL_ART"
$(NAME): $(OBJS)
@$(MAKE) -s -C libft
@printf "$(BOLD)$(WHITE)Welcome to the $(BLUE)Minishell$(WHITE) compilation process.\nPlease hold on as we prepare your program.\n\n$(RESET)"
@printf "$(YELLOW)Compiling Minishell, Please wait...$(RESET)"
@for char in $(LOADING_CHARS); do \
printf "\r$(YELLOW)Compiling Minishell, Please wait... $$char$(RESET)"; \
sleep 0.1; \
done
@$(CC) $(CFLAGS) $(OBJS) -o $(NAME) -g3 -lreadline libft/$(LIBFT)
@printf "\r$(GREEN)Nice ! $(WHITE)Minishell compiled successfully ! $(RESET)\n\n"
@printf "$(BOLD)$(WHITE)Compilation complete !\n$(BLUE)Minishell$(WHITE) is ready to use !\n$(RESET)"
# Règle pour créer les fichiers objets
$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJSUBDIRS)
@$(CC) $(CFLAGS) -I $(INCDIR) -c $< -o $@
# Règle pour créer les sous-répertoires
$(OBJSUBDIRS):
@mkdir -p $@
clean:
@make clean -s -C libft
@rm -rf $(OBJDIR)
@printf "$(WHITE)Clean process completed for $(BLUE)Minishell.$(RESET)\n"
clean1:
@rm -rf $(OBJDIR)
fclean: clean1
@make fclean -s -C libft
@rm -f $(NAME)
@printf "$(WHITE)Full clean process completed for $(BLUE)Minishell.$(RESET)\n"
re: fclean all
.PHONY: all clean fclean re clean1 print_art
norminette:
norminette src/* includes/* | grep "Error"

35
includes/messages.h Normal file
View File

@ -0,0 +1,35 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* messages.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/21 15:38:19 by lfirmin #+# #+# */
/* Updated: 2025/06/02 00:35:25 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MESSAGES_H
# define MESSAGES_H
# include "minishell.h"
# define RED "\001\033[1;31m\002"
# define GREEN "\001\033[1;32m\002"
# define YELLOW "\001\033[1;33m\002"
# define BLUE "\001\033[1;34m\002"
# define MAGENTA "\001\033[1;35m\002"
# define CYAN "\001\033[1;36m\002"
# define RESET "\001\033[0m\002"
# define WELCOME_MESS "Welcome to our MiniShell.\n"
# define ERROR_TOKEN "Error: Tokenization failed\n"
# define ERROR_NOT_FOUND "Command not found: %s\n"
# define PROMPT_GIT "➜\001\033[0m\002 \001\033[1;36m\002%s\001\033[0\
m\002 \001\033[1;32m\002git:(\001\033[1;31m\002%s\001\033[1;\
32m\002)\001\033[0m\002 "
# define PROMPT_STD "➜\001\033[0m\002 \001\033[1;36m\002%s\001\033[0m\002 "
void debug_tokens(char **tokens);
#endif

335
includes/minishell.h Normal file
View File

@ -0,0 +1,335 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* minishell.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/05 15:00:11 by thorgal #+# #+# */
/* Updated: 2025/06/03 04:11:40 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MINISHELL_H
# define MINISHELL_H
////////////////////////////////////////////////////////////////
////////////////////////////INCLUDES////////////////////////////
////////////////////////////////////////////////////////////////
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <limits.h>
# include <readline/readline.h>
# include <readline/history.h>
# include <dirent.h>
# include <stddef.h>
# include <fcntl.h>
# include <stdbool.h>
# include <sys/types.h>
# include <sys/wait.h>
# include "../libft/include/libft.h"
# include <signal.h>
# include <termios.h>
# include "messages.h"
////////////////////////////////////////////////////////////////
////////////////////////////GLOBALS/////////////////////////////
////////////////////////////////////////////////////////////////
extern int g_signal;
////////////////////////////////////////////////////////////////
////////////////////////////ENUM////////////////////////////////
////////////////////////////////////////////////////////////////
typedef enum e_token_type
{
TOKEN_WORD,
TOKEN_REDIRECTION_IN,
TOKEN_REDIRECTION_OUT,
TOKEN_APPEND,
TOKEN_HEREDOC,
TOKEN_PIPE
} t_token_type;
////////////////////////////////////////////////////////////////
////////////////////////////DATA////////////////////////////////
////////////////////////////////////////////////////////////////
typedef struct s_escape_handler
{
char *input;
char *content;
int i;
int j;
} t_escape_handler;
typedef struct s_redirection
{
int type;
char *file;
struct s_redirection *next;
} t_redirection;
typedef struct s_cmd
{
char **args;
t_redirection *redir;
struct s_cmd *next;
} t_cmd;
typedef struct s_shell
{
char **env;
int exit_status;
int running;
int signaled;
int child_running;
int single_quoted_token;
} t_shell;
////////////////////////////////////////////////////////////////
////////////////////////////MAIN////////////////////////////////
////////////////////////////////////////////////////////////////
////////////////////
///////main.c///////
////////////////////
void initialize_shell(t_shell *shell, char **envp);
int execute_command(t_cmd *cmd, t_shell *shell);
int execute_builtin(t_cmd *cmd, t_shell *shell);
int is_builtin(char *cmd);
int main(void);
////////////////////
///////input.c//////
////////////////////
char **parse_input(char *input, t_shell *shell);
void process_input(char *input, t_shell *shell);
/////////////////////
///////shell.c///////
/////////////////////
void minishell_loop(t_shell *shell);
void handle_input(char *input, t_shell *shell);
char *generate_prompt(t_shell *shell);
char *create_git_prompt(char *dir_name, int exit_status);
char *create_standard_prompt(char *dir_name, int exit_status);
/////////////////////
///////signals.c/////
/////////////////////
void check_if_signal(t_shell *shell);
void handle_signal_parent(int num);
int sig_event(void);
void if_sigint(int sig);
void set_status_if_signal(t_shell *shell);
void set_signal_child(void);
void set_signal_parent_exec(void);
void set_signal_parent(void);
/////////////////////////////////////////////////////////////////
////////////////////////////UTILS////////////////////////////////
/////////////////////////////////////////////////////////////////
////////////////////
///////utils.c//////
////////////////////
char *get_current_dir_name(void);
char *ft_get_env_var(char **env, char *var);
char **copy_env(char **envp);
int is_git_repository(void);
char *get_git_branch(void);
////////////////////
///////free.c///////
////////////////////
void *free_tokens(char **tokens, int count);
/////////////////////////////////////////////////////////////////
////////////////////////////BULTINS//////////////////////////////
/////////////////////////////////////////////////////////////////
///////////////////
///////pwd.c///////
///////////////////
int ft_pwd(void);
//////////////////
///////cd.c///////
//////////////////
int handle_home_directory(t_shell *shell);
int handle_previous_directory(t_shell *shell);
int update_pwd_env(t_shell *shell);
char *resolve_env_variables(char *path, t_shell *shell);
char *expand_tilde(char *path, t_shell *shell);
int validate_cd_args(t_cmd *cmd, t_shell *shell);
char *resolve_cd_path(char *path, t_shell *shell);
int execute_cd_change(char *resolved_path);
int ft_cd(t_cmd *cmd, t_shell *shell);
//////////////////
///////env.c//////
//////////////////
int ft_env(t_shell *shell, t_cmd *cmd);
//////////////////
///////export.c///
//////////////////
int ft_export(t_shell *shell, t_cmd *cmd);
int process_export_args(t_shell *shell, char **args, int i);
int update_env_var(char **env, char *var);
char **add_env_var(char **env, char *new_var);
int is_valid_identifier(char *str);
//////////////////
///////unset.c////
//////////////////
int delete_line(char **array, int index);
int find_env_var(char **env, char *var);
int ft_unset(t_shell *shell, t_cmd *cmd);
//////////////////
///////echo.c/////
//////////////////
void print_echo_args(char **args, int i, int first);
int ft_echo(t_cmd *cmd, t_shell *shell);
/////////////////////////
///////export_utils.c////
/////////////////////////
int handle_env_var(t_shell *shell, char *arg);
char *handle_quotes_in_env_var(char *arg);
char *process_single_var(char *result, \
char *var_start, char *var_end, char **env);
char *expand_env_variables(char *str, char **env);
void handle_quote_char(char *var_value, \
int *i, int *in_quotes, char *quote_type);
char *process_quotes(char *var_value, char *clean_value);
/////////////////////////
///////export_utils2.c////
/////////////////////////
char *find_next_var(char *result, char **var_start, char **var_end);
char *build_expanded_string(char *result, char *var_start, \
char *var_end, char *var_value);
char *extract_var_name(char *result, char *var_start, char *var_end);
char *get_env_value_for_expansion(char **env, char *var_name);
/////////////////////////////////////////////////////////////////
////////////////////////////TOKENS///////////////////////////////
/////////////////////////////////////////////////////////////////
///////////////////////////
///////check_pipes.c///////
///////////////////////////
int check_before_pipe(char **tokens);
int pipe_sequence_invalid(char **tokens);
int validate_pipes(char **tokens);
//////////////////////////////////
///////check_redirections.c///////
//////////////////////////////////
int is_redirection(char *token);
int check_further_redirections(char **tokens, int i);
int validate_redirections(char **tokens);
//////////////////////
///////syntax.c///////
//////////////////////
t_token_type classify_token(char *token);
int validate_syntax(char **tokens);
//////////////////////////
///////token_list.c///////
//////////////////////////
void free_cmd_node(t_cmd *cmd);
t_cmd *create_command_node(void);
t_redirection *create_redirection_node(int type, char *file);
int add_argument(t_cmd *cmd, char *arg);
void add_redirection(t_cmd *cmd, t_redirection *redir);
///////////////////////////
///////token_list2.c///////
///////////////////////////
int handle_redirection(t_cmd *cmd, char **tokens, int *i);
t_cmd *init_cmd_segment(t_cmd **cmd_list, char **tokens, int *i);
int add_token_to_cmd(t_cmd *current, char **tokens, int *i);
t_cmd *parse_tokens_to_list(char **tokens);
void free_cmd_list(t_cmd *cmd_list);
///////////////////////////
///////token_utils.c///////
///////////////////////////
int count_tokens(char *str);
int handle_quoted_token(char *input, int *index, int *start);
int handle_special_token(char *input, int *index);
void handle_quoted_count(char *str, int *i, char quote);
void handle_special_count(char *str, int *i);
////////////////////
///////token.c//////
////////////////////
int extract_quoted_token(char *input, int *index, char quote_char);
int is_delimiter(char c);
int is_special(char c);
void skip_delimiters(char *str, int *i);
char *extract_quoted_content(char *input, int start, \
int len, char quote_char);
///////////////////////////
///////token_utils2.c//////
///////////////////////////
int extract_token_len(char *input, int *index, int *start);
char *extract_token(char *input, int *index, t_shell *shell);
int check_quotes(char *input);
char **tokenize_command(char *input, t_shell *shell);
void handle_word_count(char *str, int *i);
// Exec
int open_file(char *file, int flags, int mode);
int setup_files(t_redirection *redir);
int setup_input_redirections(t_redirection *redir);
int setup_output_redirections(t_redirection *redir);
int has_input_redirection(t_redirection *redir);
void close_files(int infile, int outfile);
char *find_command(char **paths, char *cmd);
char *get_path_env(char **envp);
int ft_exec(t_cmd *cmd, char **envp, t_shell *shell);
int execute_ve(t_cmd *cmd, char **envp);
int loop_open_files(t_cmd *cmd);
int handle_heredoc(char *delim);
int execute_pipeline(t_cmd *cmd_list, t_shell *shell);
char *execute_ve_2(t_cmd *cmd, char *path_env, char *full_path);
int ft_exit(t_cmd *cmd, t_shell *shell);
int setup_pipe(int pipefd[2]);
int is_valid_number(char *str);
int check_positive_overflow(long long result, char digit);
int check_negative_overflow(long long result, char digit);
// expand.c
char *expand_variables(char *str, t_shell *shell);
char *get_env_value(char *var, t_shell *shell);
void handle_child(t_cmd *cmd, int infile, int pipefd[2], \
t_shell *shell);
int wait_for_children(pid_t last_pid);
// pipe.c
void restore_fds(int saved_stdin, int saved_stdout);
int spawn_pipeline(t_cmd *cmd, t_shell *shell);
// setup_files.c
int setup_files(t_redirection *redir);
// setup_output_redirections.c
int setup_output_redirections(t_redirection *redir);
// execute_ve.c
int execute_ve(t_cmd *cmd, char **envp);
int file_exists(const char *path);
void run_child_process(t_cmd *cmd, char **envp);
#endif

68
libft/Makefile Normal file
View File

@ -0,0 +1,68 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/05/19 12:59:31 by lfirmin #+# #+# #
# Updated: 2025/04/19 11:53:48 by lfirmin ### ########.fr #
# #
# **************************************************************************** #
NAME = libft.a
HEADER = ./include
SRCS_DIR = ./srcs/
SRC = ft_isalnum.c ft_isprint.c ft_memcmp.c ft_putchar_fd.c ft_split.c \
ft_strlcat.c ft_strncmp.c ft_substr.c ft_atoi.c ft_isalpha.c \
ft_itoa.c ft_memcpy.c ft_putendl_fd.c ft_strchr.c ft_strlcpy.c \
ft_strnstr.c ft_tolower.c ft_bzero.c ft_isascii.c ft_strtrim.c \
ft_memmove.c ft_putnbr_fd.c ft_strdup.c ft_strlen.c ft_strrchr.c \
ft_toupper.c ft_calloc.c ft_isdigit.c ft_memchr.c ft_memset.c \
ft_putstr_fd.c ft_strjoin.c ft_strmapi.c ft_striteri.c \
ft_lstnew_bonus.c ft_lstadd_front_bonus.c ft_lstsize_bonus.c \
ft_lstlast_bonus.c ft_lstadd_back_bonus.c ft_lstdelone_bonus.c \
ft_lstclear_bonus.c ft_lstiter_bonus.c ft_lstmap_bonus.c ft_strcmp.c \
ft_atoll.c ft_straddchar.c ft_strcpy.c
SRCS = $(addprefix $(SRCS_DIR), $(SRC))
CC = cc
CFLAGS = -Wall -Wextra -Werror -g3
INCLUDE = -I $(HEADER)
OBJ_DIR = obj/
OBJ = $(addprefix $(OBJ_DIR), $(SRC:.c=.o))
GREEN = \033[0;32m
YELLOW = \033[0;33m
RESET = \033[0m
WHITE = \033[0;97m
LOADING_CHARS = ⠋ ⠙ ⠹ ⠸ ⠼ ⠴ ⠦ ⠧ ⠇ ⠏
all: $(NAME)
$(NAME): $(OBJ)
@printf "$(YELLOW)Compiling libft, Please wait...$(RESET)"
@for char in $(LOADING_CHARS); do \
printf "\r$(YELLOW)Compiling libft, Please wait... $$char$(RESET)"; \
sleep 0.1; \
done
@ar rc $(NAME) $(OBJ)
@ranlib $(NAME)
@printf "\r$(GREEN)Great news ! $(WHITE)Libft compiled successfully ! $(RESET)\n"
$(OBJ_DIR)%.o: $(SRCS_DIR)%.c
@mkdir -p $(OBJ_DIR)
@$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
clean:
@rm -rf $(OBJ_DIR)
@printf "$(WHITE)Clean process completed for $(GREEN)Libft.$(RESET)\n"
fclean: clean
@rm -f $(NAME)
@printf "$(WHITE)Full clean process completed for $(GREEN)Libft.$(RESET)\n"
re: fclean all
.PHONY: all clean fclean re

55
libft/Readme.md Normal file
View File

@ -0,0 +1,55 @@
# Libft - 42 Project
## Description
Libft is the first project at 42 school. The aim is to recreate various standard C library functions, as well as additional functions that will be useful throughout the cursus. This library will be used in most of the future 42 projects.
## Functions
### Libc Functions
`ft_isalpha``ft_isdigit``ft_isalnum``ft_isascii``ft_isprint``ft_strlen``ft_memset``ft_bzero``ft_memcpy``ft_memmove``ft_strlcpy``ft_strlcat``ft_toupper``ft_tolower``ft_strchr``ft_strrchr``ft_strncmp``ft_memchr``ft_memcmp``ft_strnstr``ft_atoi``ft_calloc``ft_strdup`
### Additional Functions
`ft_substr``ft_strjoin``ft_strtrim``ft_split``ft_itoa``ft_strmapi``ft_striteri``ft_putchar_fd``ft_putstr_fd``ft_putendl_fd``ft_putnbr_fd`
### Bonus Functions
`ft_lstnew``ft_lstadd_front``ft_lstsize``ft_lstlast``ft_lstadd_back``ft_lstdelone``ft_lstclear``ft_lstiter``ft_lstmap`
## Getting Started
### Prerequisites
- GCC compiler
- Make
### Usage
1. Include the header in your source file:
```c
#include "libft.h"
```
### Compilation
1. Compilation:
```bash
make
```
## Cleaning
- Remove object files:
```bash
make clean
```
- Remove object files and library:
```bash
make fclean
```
- Recompile everything:
```bash
make re
```
## Testing
This project doesn't come with unit tests, but you can use external testers:
- [libft-unit-test](https://github.com/alelievr/libft-unit-test)
- [libft-war-machine](https://github.com/ska42/libft-war-machine)
- [Tripouille/libfTester](https://github.com/Tripouille/libftTester)

92
libft/include/libft.h Normal file
View File

@ -0,0 +1,92 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* libft.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 11:19:08 by lfirmin #+# #+# */
/* Updated: 2025/04/19 11:56:03 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef LIBFT_H
# define LIBFT_H
# include <stdlib.h>
# include <string.h>
# include <stddef.h>
# include <stdio.h>
# include <unistd.h>
# include <limits.h>
typedef struct v
{
char **array;
int i;
int j;
int start;
int end;
} t_split_struct;
typedef struct s_list
{
void *content;
struct s_list *next;
} t_list;
int ft_isalnum(int c);
int ft_isalpha(int c);
int ft_isascii(int c);
int ft_isdigit(int c);
int ft_isprint(int c);
int ft_atoi(const char *str);
int ft_memcmp(const void *ptr1, const void *ptr2, size_t num);
int ft_strncmp(const char *s1, const char *s2, unsigned int n);
int ft_toupper(int c);
int ft_tolower(int c);
int ft_lstsize(t_list *lst);
int ft_strcmp(char *s1, char *s2);
long long ft_atoll(const char *str);
size_t ft_strlen(const char *s);
size_t ft_strlcat(char *dst, const char *src, size_t size);
size_t ft_strlcpy(char *dst, const char *src, size_t dsts);
void *ft_bzero(void *s, size_t n);
void *ft_calloc(size_t count, size_t n);
void *ft_memchr(const void *s, int c, size_t n);
void *ft_memcpy(void *dest, const void *src, size_t len);
void *ft_memset(void *b, int c, size_t len);
void *ft_memmove(void *s1, const void *s2, size_t len);
void *ft_memset(void *str, int c, size_t n);
void ft_putchar_fd(char c, int fd);
void ft_putstr_fd(char *s, int fd);
void ft_putendl_fd(char *s, int fd);
void ft_putnbr_fd(int n, int fd);
void ft_striteri(char *s, void (*f)(unsigned int, char*));
void ft_lstadd_front(t_list **lst, t_list *new);
void ft_lstadd_back(t_list **lst, t_list *new);
void ft_lstdelone(t_list *lst, void (*del)(void*));
void ft_lstclear(t_list **lst, void (*del)(void*));
void ft_lstiter(t_list *lst, void (*f)(void *));
char *ft_strchr(char const *str, int c);
char *ft_strdup(const char *src);
char *ft_strjoin(const char *s1, const char *s2);
char *ft_strnstr(const char *hay, const char *need, size_t len);
char *ft_strrchr(const char *str, int c);
char *ft_strtrim(char const *s1, char const *set);
char *ft_substr(char const *s, unsigned int start, size_t len);
char **ft_split(char const *s, char c);
char *ft_strmapi(char const *s, char (*f)(unsigned int, char));
char *ft_itoa(int n);
char *ft_straddchar(char *str, char c);
char *ft_strcpy(char *dest, char *src);
t_list *ft_lstnew(void *content);
t_list *ft_lstlast(t_list *lst);
t_list *ft_lstmap(t_list *lst, void *(*f)(void *), \
void (*del)(void *));
#endif

40
libft/srcs/ft_atoi.c Normal file
View File

@ -0,0 +1,40 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_atoi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 10:09:46 by lfirmin #+# #+# */
/* Updated: 2024/06/03 21:02:02 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_atoi(const char *str)
{
int i;
int s;
int m;
i = 0;
s = 0;
m = 0;
while ((str[i] <= 13 && str[i] >= 9) || str[i] == 32)
i++;
while (str[i] == '-' || str[i] == '+')
{
s++;
if (s >= 2)
return (0);
if (str[i] == '-')
m++;
i++;
}
s = 0;
while (str[i] >= 48 && str[i] <= 57)
s = s * 10 + (str[i++] - 48);
if (m % 2 == 1)
s = s * -1;
return (s);
}

38
libft/srcs/ft_atoll.c Normal file
View File

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_atoll.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/03 17:25:06 by lfirmin #+# #+# */
/* Updated: 2024/11/03 17:25:33 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
long long ft_atoll(const char *str)
{
long long result;
int sign;
result = 0;
sign = 1;
while (*str == ' ' || (*str >= 9 && *str <= 13))
str++;
if (*str == '-' || *str == '+')
{
if (*str == '-')
sign = -1;
str++;
}
while (*str >= '0' && *str <= '9')
{
if (result > INT_MAX || result < INT_MIN)
return (2147483648);
result = result * 10 + (*str - '0');
str++;
}
return (result * sign);
}

24
libft/srcs/ft_bzero.c Normal file
View File

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_bzero.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 00:20:00 by lfirmin #+# #+# */
/* Updated: 2024/05/30 19:49:23 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_bzero(void *b, size_t len)
{
size_t i;
unsigned char *r;
r = (unsigned char *)b;
i = 0;
while (i < len)
r[i++] = '\0';
return (b);
}

31
libft/srcs/ft_calloc.c Normal file
View File

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_calloc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 11:14:02 by lfirmin #+# #+# */
/* Updated: 2024/06/03 18:15:05 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_calloc(size_t c, size_t s)
{
void *ptr;
long long int tmp1;
long long int tmp2;
tmp1 = (long long int)c;
tmp2 = (long long int)s;
if ((c > 4294967295 || s > 4294967295) && (tmp1 < 0 && tmp2 < 0))
return (NULL);
if (tmp1 * tmp2 < 0)
return (NULL);
ptr = malloc(c * s);
if (!ptr)
return (NULL);
ft_bzero(ptr, c * s);
return (ptr);
}

19
libft/srcs/ft_isalnum.c Normal file
View File

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isalnum.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/20 02:29:49 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_isalnum(int c)
{
if ((c >= 97 && c <= 122) || (c >= 48 && c <= 57) || (c >= 65 && c <= 90))
return (1);
return (0);
}

19
libft/srcs/ft_isalpha.c Normal file
View File

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isalpha.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/20 01:55:52 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_isalpha(int c)
{
if ((c >= 97 && c <= 122) || (c >= 65 && c <= 90))
return (1);
return (0);
}

19
libft/srcs/ft_isascii.c Normal file
View File

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isascii.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/20 02:36:17 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_isascii(int c)
{
if (c >= 0 && c <= 127)
return (1);
return (0);
}

19
libft/srcs/ft_isdigit.c Normal file
View File

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isdigit.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/20 02:31:51 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_isdigit(int c)
{
if (c >= 48 && c <= 57)
return (1);
return (0);
}

19
libft/srcs/ft_isprint.c Normal file
View File

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isprint.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/20 02:38:24 by lfirmin #+# #+# */
/* Updated: 2024/05/23 06:21:54 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_isprint(int c)
{
if (((c >= 0 && c <= 31) || c >= 127 || c == EOF))
return (0);
return (1);
}

51
libft/srcs/ft_itoa.c Normal file
View File

@ -0,0 +1,51 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_itoa.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/24 12:59:00 by lfirmin #+# #+# */
/* Updated: 2024/05/29 10:31:36 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
static size_t ft_count(long int n)
{
size_t c;
c = 0;
if (n <= 0)
c = 1;
while (n != 0)
{
n = n / 10;
c++;
}
return (c);
}
char *ft_itoa(int n)
{
char *str;
size_t size;
long int num;
num = n;
size = ft_count(num);
str = (char *)malloc(size + 1);
if (!str)
return (NULL);
str[size] = '\0';
if (num < 0)
num = -num;
while (size--)
{
str[size] = num % 10 + '0';
num = num / 10;
if (n < 0 && size == 0)
str[size] = '-';
}
return (str);
}

View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstadd_back.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/01 02:01:18 by lfirmin #+# #+# */
/* Updated: 2024/06/03 15:59:33 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_lstadd_back(t_list **lst, t_list *new)
{
t_list *last;
if (!new)
return ;
if (!lst || !*lst)
{
*lst = new;
return ;
}
last = ft_lstlast(*lst);
last->next = new;
}

View File

@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstadd_front.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/31 20:34:57 by lfirmin #+# #+# */
/* Updated: 2024/05/31 20:41:34 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_lstadd_front(t_list **lst, t_list *new)
{
if (lst && new)
{
new->next = *lst;
*lst = new;
}
}

View File

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstclear.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/01 20:46:07 by lfirmin #+# #+# */
/* Updated: 2024/06/01 20:51:07 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_lstclear(t_list **lst, void (*del)(void*))
{
t_list *t;
if (lst)
{
while (*lst)
{
t = (*lst)->next;
ft_lstdelone(*lst, del);
(*lst) = t;
}
(*lst) = NULL;
}
}

View File

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstdelone.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/01 20:32:56 by lfirmin #+# #+# */
/* Updated: 2024/06/01 20:32:56 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_lstdelone(t_list *lst, void (*del)(void*))
{
if (!lst || !del)
return ;
del(lst->content);
free(lst);
}

View File

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstiter.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/01 21:05:12 by lfirmin #+# #+# */
/* Updated: 2024/06/01 21:05:12 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_lstiter(t_list *lst, void (*f)(void *))
{
if (!lst || !f)
return ;
while (lst)
{
f(lst->content);
lst = lst->next;
}
}

View File

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstlast.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/01 01:52:09 by lfirmin #+# #+# */
/* Updated: 2024/06/01 01:57:22 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
t_list *ft_lstlast(t_list *lst)
{
while (lst)
{
if (!lst->next)
return (lst);
lst = lst->next;
}
return (lst);
}

View File

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstmap.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/02 18:21:09 by lfirmin #+# #+# */
/* Updated: 2024/06/03 15:53:13 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *))
{
t_list *new;
t_list *save;
if (!lst || !del || !f)
return (NULL);
new = ft_lstnew(lst->content);
if (!new)
return (NULL);
new->content = f(new->content);
save = new;
lst = lst->next;
while (lst)
{
new->next = ft_lstnew(lst->content);
if (!new->next)
{
ft_lstclear(&save, del);
return (NULL);
}
new->next->content = f(new->next->content);
new = new->next;
lst = lst->next;
}
new->next = NULL;
return (save);
}

View File

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstnew.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/31 18:41:23 by lfirmin #+# #+# */
/* Updated: 2024/05/31 20:33:26 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
t_list *ft_lstnew(void *content)
{
t_list *new;
new = (t_list *)malloc(sizeof(*new));
if (!new)
return (NULL);
new->content = content;
new->next = NULL;
return (new);
}

View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstsize.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/31 22:00:49 by lfirmin #+# #+# */
/* Updated: 2024/05/31 22:12:17 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_lstsize(t_list *lst)
{
int i;
t_list *count;
count = lst;
i = 0;
while (count)
{
count = count->next;
i++;
}
return (i);
}

26
libft/srcs/ft_memchr.c Normal file
View File

@ -0,0 +1,26 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memchr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 07:40:39 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_memchr(const void *s, int c, size_t n)
{
unsigned char *str;
str = (unsigned char *)s;
while (n--)
{
if (*str == (unsigned char)c)
return (str);
str++;
}
return (NULL);
}

30
libft/srcs/ft_memcmp.c Normal file
View File

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memcmp.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 07:57:58 by lfirmin #+# #+# */
/* Updated: 2024/05/22 11:34:35 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_memcmp(const void *ptr1, const void *ptr2, size_t num)
{
unsigned char *pt1;
unsigned char *pt2;
size_t i;
pt1 = (unsigned char *)ptr1;
pt2 = (unsigned char *)ptr2;
i = 0;
while (i < num)
{
if (pt1[i] != pt2[i])
return (pt1[i] - pt2[i]);
i++;
}
return (0);
}

32
libft/srcs/ft_memcpy.c Normal file
View File

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memcpy.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 01:08:31 by lfirmin #+# #+# */
/* Updated: 2025/06/02 00:40:39 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_memcpy(void *dest, const void *src, size_t len)
{
size_t i;
unsigned char *r;
unsigned char *s;
i = 0;
r = (unsigned char *)dest;
s = (unsigned char *)src;
if (dest == (void *)0 && src == (void *)0)
return (dest);
while (i < len)
{
r[i] = s[i];
i++;
}
return (dest);
}

39
libft/srcs/ft_memmove.c Normal file
View File

@ -0,0 +1,39 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memmov.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 01:26:13 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_memmove(void *s1, const void *s2, size_t len)
{
unsigned char *dest;
unsigned char *src;
unsigned int i;
dest = (unsigned char *)s1;
src = (unsigned char *)s2;
i = 0;
if (dest == NULL && src == NULL)
return (NULL);
if (dest < src)
{
while (i < len)
{
dest[i] = src[i];
i++;
}
}
else
{
while (0 < len--)
dest[len] = src[len];
}
return (dest);
}

24
libft/srcs/ft_memset.c Normal file
View File

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memset.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/20 02:42:40 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_memset(void *b, int c, size_t len)
{
size_t i;
unsigned char *r;
i = 0;
r = (unsigned char *)b;
while (i < len)
r[i++] = (unsigned char)c;
return (b);
}

View File

@ -0,0 +1,17 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putchar_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/29 11:17:45 by lfirmin #+# #+# */
/* Updated: 2024/05/29 11:20:42 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_putchar_fd(char c, int fd)
{
write(fd, &c, 1);
}

View File

@ -0,0 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putendl_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/29 11:35:44 by lfirmin #+# #+# */
/* Updated: 2024/05/29 11:38:36 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_putendl_fd(char *s, int fd)
{
ft_putstr_fd(s, fd);
ft_putchar_fd('\n', fd);
}

31
libft/srcs/ft_putnbr_fd.c Normal file
View File

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putnbr_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/29 11:42:38 by lfirmin #+# #+# */
/* Updated: 2024/05/29 11:56:04 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_putnbr_fd(int n, int fd)
{
long int nb;
nb = n;
if (nb < 0)
{
nb = -nb;
ft_putchar_fd('-', fd);
}
if (nb >= 10)
{
ft_putnbr_fd(nb / 10, fd);
ft_putnbr_fd(nb % 10, fd);
}
else
ft_putchar_fd(nb + '0', fd);
}

24
libft/srcs/ft_putstr_fd.c Normal file
View File

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putstr_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/29 11:27:05 by lfirmin #+# #+# */
/* Updated: 2024/05/29 11:33:18 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_putstr_fd(char *s, int fd)
{
int i;
i = 0;
while (s[i])
{
ft_putchar_fd(s[i], fd);
i++;
}
}

95
libft/srcs/ft_split.c Normal file
View File

@ -0,0 +1,95 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_split.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/22 05:56:37 by lfirmin #+# #+# */
/* Updated: 2024/06/04 12:08:51 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
static int ft_c(char const *s, char c)
{
int i;
int count;
count = 0;
i = 0;
while (s[i])
{
if (s[i] != c && (i == 0 || s[i - 1] == c))
count++;
i++;
}
return (count);
}
void init_split_struct(t_split_struct *v, char const *s, char c)
{
if (!s)
return ;
v->array = (char **)malloc((ft_c(s, c) + 1) * sizeof(char *));
if (!s || !v->array)
return ;
v->i = 0;
v->j = 0;
}
static char *ft_strncpy(char *dest, const char *src, unsigned int n)
{
unsigned int i;
i = 0;
while (src[i] != '\0' && i < n)
{
dest[i] = src[i];
++i;
}
while (i < n)
{
dest[i] = '\0';
i++;
}
return (dest);
}
char **free_split(char **array, size_t j)
{
while (j > 0)
{
free(array[--j]);
}
free(array);
return (NULL);
}
char **ft_split(char const *s, char c)
{
t_split_struct v;
init_split_struct(&v, s, c);
if (!s || !v.array)
return (NULL);
while (s[v.i])
{
while (s[v.i] == c && s[v.i])
v.i++;
v.start = v.i;
while (s[v.i] != c && s[v.i])
v.i++;
if (v.i > v.start)
{
v.array[v.j] = (char *)malloc(v.i - v.start + 1);
if (!v.array[v.j])
return (free_split(v.array, v.j));
ft_strncpy(v.array[v.j], &s[v.start], v.i - v.start);
v.array[v.j][v.i - v.start] = '\0';
v.j++;
}
}
v.array[v.j] = NULL;
return (v.array);
}

View File

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_straddchar.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/08 06:02:17 by lfirmin #+# #+# */
/* Updated: 2024/11/08 06:02:17 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_straddchar(char *str, char c)
{
int i;
char *res;
if (!str)
return (NULL);
i = 0;
while (str[i])
i++;
res = (char *)malloc(sizeof(char) * (i + 2));
if (!res)
return (NULL);
i = 0;
while (str[i])
{
res[i] = str[i];
i++;
}
res[i] = c;
res[i + 1] = '\0';
return (res);
}

26
libft/srcs/ft_strchr.c Normal file
View File

@ -0,0 +1,26 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strchr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 06:46:40 by lfirmin #+# #+# */
/* Updated: 2024/05/24 08:51:25 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strchr(char const *str, int c)
{
while (*str)
{
if (*str == (char)c)
return ((char *)str);
str++;
}
if (*str == (char)c)
return ((char *)str);
else
return (NULL);
}

22
libft/srcs/ft_strcmp.c Normal file
View File

@ -0,0 +1,22 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strcmp.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/19 21:01:26 by lfirmin #+# #+# */
/* Updated: 2024/10/19 21:01:26 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_strcmp(char *s1, char *s2)
{
int i;
i = 0;
while (s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')
i++;
return (s1[i] - s2[i]);
}

27
libft/srcs/ft_strcpy.c Normal file
View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strcpy.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/19 11:53:24 by lfirmin #+# #+# */
/* Updated: 2025/04/19 11:58:04 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strcpy(char *dest, char *src)
{
size_t i;
i = 0;
while (src[i] != '\0')
{
dest[i] = src[i];
i++;
}
dest[i] = '\0';
return (dest);
}

34
libft/srcs/ft_strdup.c Normal file
View File

@ -0,0 +1,34 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strdup.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/15 05:28:24 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strdup(const char *src)
{
char *dest;
int i;
int size;
size = 0;
while (src[size] != '\0')
size++;
dest = malloc(sizeof(char) * (size + 1));
if (dest == NULL)
return (NULL);
i = 0;
while (i != size)
{
dest[i] = src[i];
i++;
}
dest[i] = '\0';
return (dest);
}

27
libft/srcs/ft_striteri.c Normal file
View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_striteri.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/29 10:54:40 by lfirmin #+# #+# */
/* Updated: 2024/05/29 11:12:05 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_striteri(char *s, void (*f)(unsigned int, char*))
{
int i;
i = 0;
if (s)
{
while (s[i])
{
f(i, &s[i]);
++i;
}
}
}

34
libft/srcs/ft_strjoin.c Normal file
View File

@ -0,0 +1,34 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strjoin.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/22 01:00:14 by lfirmin #+# #+# */
/* Updated: 2024/05/24 08:49:06 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strjoin(const char *s1, const char *s2)
{
char *res;
int i;
int j;
i = 0;
j = 0;
if (s1 == NULL && s2 == NULL)
return (NULL);
res = (char *) malloc((ft_strlen(s1) + ft_strlen(s2) + 1) * sizeof(char));
if (!res)
return (NULL);
while (s1[i])
res[j++] = s1[i++];
i = 0;
while (s2[i])
res[j++] = s2[i++];
res[j] = 0;
return (res);
}

32
libft/srcs/ft_strlcat.c Normal file
View File

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strlcat.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 03:55:25 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
size_t ft_strlcat(char *dst, const char *src, size_t size)
{
size_t i;
size_t r;
size_t s;
i = 0;
r = ft_strlen(dst);
s = ft_strlen(src);
if (size <= r)
return (s + size);
while (r + i < size - 1 && src[i] != '\0')
{
dst[r + i] = src[i];
i++;
}
dst[r + i] = '\0';
return (r + s);
}

34
libft/srcs/ft_strlcpy.c Normal file
View File

@ -0,0 +1,34 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strlcpy.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 02:18:17 by lfirmin #+# #+# */
/* Updated: 2024/05/30 18:36:18 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
size_t ft_strlcpy(char *dst, const char *src, size_t dsts)
{
size_t srcs;
size_t i;
ft_strlen(src);
if (!src || !dst)
return (0);
srcs = ft_strlen(src);
i = 0;
if (dsts != 0)
{
while (src[i] != '\0' && i < (dsts - 1))
{
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}
return (srcs);
}

22
libft/srcs/ft_strlen.c Normal file
View File

@ -0,0 +1,22 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strlen.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/19 23:16:45 by lfirmin #+# #+# */
/* Updated: 2024/05/23 07:36:59 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
size_t ft_strlen(const char *s)
{
int i;
i = 0;
while (s[i])
i++;
return ((size_t)i);
}

32
libft/srcs/ft_strmapi.c Normal file
View File

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strmapi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/28 15:10:42 by lfirmin #+# #+# */
/* Updated: 2024/05/28 17:00:27 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strmapi(char const *s, char (*f)(unsigned int, char))
{
char *str;
int i;
if (!s)
return (NULL);
str = (char *)malloc(ft_strlen(s) + 1);
if (!str)
return (NULL);
i = 0;
while (s[i])
{
str[i] = f(i, s[i]);
++i;
}
str[i] = '\0';
return (str);
}

32
libft/srcs/ft_strncmp.c Normal file
View File

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strncmp.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 06:55:09 by lfirmin #+# #+# */
/* Updated: 2024/05/24 08:47:59 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_strncmp(const char *s1, const char *s2, unsigned int n)
{
unsigned int i;
unsigned char c1;
unsigned char c2;
i = 0;
if (n == 0)
return (0);
while (i < n)
{
c1 = (unsigned char)s1[i];
c2 = (unsigned char)s2[i];
if (c1 != c2 || c1 == '\0' || c2 == '\0')
return (c1 - c2);
i++;
}
return (0);
}

36
libft/srcs/ft_strnstr.c Normal file
View File

@ -0,0 +1,36 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strnstr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 08:22:59 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strnstr(const char *hay, const char *need, size_t len)
{
size_t i;
size_t n;
i = 0;
if (need[0] == '\0')
return ((char *)hay);
while (hay[i] != '\0')
{
n = 0;
while (hay[i + n] == need[n] && (i + n) < len)
{
if (hay[i + n] == '\0' && need[n] == '\0')
return ((char *)&hay[i]);
n++;
}
if (need[n] == '\0')
return ((char *)hay + i);
i++;
}
return (0);
}

35
libft/srcs/ft_strrchr.c Normal file
View File

@ -0,0 +1,35 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strrchr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 06:42:38 by lfirmin #+# #+# */
/* Updated: 2024/05/30 18:30:00 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strrchr(const char *str, int c)
{
int i;
int last_occurrence;
ft_strlen(str);
i = 0;
last_occurrence = -1;
if (str == NULL)
return (NULL);
while (str[i])
{
if (str[i] == (char)c)
last_occurrence = i;
i++;
}
if ((char)c == '\0')
return ((char *)&str[i]);
if (last_occurrence != -1)
return ((char *)&str[last_occurrence]);
return (NULL);
}

68
libft/srcs/ft_strtrim.c Normal file
View File

@ -0,0 +1,68 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strtrim.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/23 21:32:01 by lfirmin #+# #+# */
/* Updated: 2024/05/31 02:04:11 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
static int is_in_set(char c, const char *set)
{
while (*set)
{
if (c == *set)
{
return (1);
}
set++;
}
return (0);
}
static char *ft_strncpy(char *dest, const char *src, unsigned int n)
{
unsigned int i;
i = 0;
while (src[i] != '\0' && i < n)
{
dest[i] = src[i];
++i;
}
while (i < n)
{
dest[i] = '\0';
i++;
}
return (dest);
}
char *ft_strtrim(const char *s1, const char *set)
{
size_t s;
size_t e;
size_t len;
char *str;
if (!s1 || !set)
return (NULL);
s = 0;
while (s1[s] && is_in_set(s1[s], set))
s++;
e = ft_strlen(s1);
while (e > s && is_in_set(s1[e - 1], set))
e--;
len = e - s;
str = (char *)malloc(sizeof(char) * (len + 1));
if (!str)
return (NULL);
ft_strncpy(str, s1 + s, len);
str[len] = '\0';
return (str);
}

34
libft/srcs/ft_substr.c Normal file
View File

@ -0,0 +1,34 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_substr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/22 00:15:54 by lfirmin #+# #+# */
/* Updated: 2024/05/24 08:28:01 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_substr(char const *s, unsigned int start, size_t len)
{
char *sub;
size_t i;
if ((ft_strlen(s) - start) < len)
len = ft_strlen(s) - start;
if (ft_strlen(s) < start)
return (ft_strdup(""));
i = 0;
sub = (char *) malloc(len + 1);
if (!sub)
return (NULL);
while (len > 0)
{
sub[i++] = s[start++];
len--;
}
sub[i] = '\0';
return (sub);
}

19
libft/srcs/ft_tolower.c Normal file
View File

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_tolower.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 04:50:40 by lfirmin #+# #+# */
/* Updated: 2024/05/22 11:09:36 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_tolower(int c)
{
if (c >= 65 && c <= 90)
return (c + 32);
return (c);
}

19
libft/srcs/ft_toupper.c Normal file
View File

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_toupper.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 04:50:40 by lfirmin #+# #+# */
/* Updated: 2024/05/22 09:59:44 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_toupper(int c)
{
if (c >= 97 && c <= 122)
return (c - 32);
return (c);
}

127
src/builtins/cd.c Normal file
View File

@ -0,0 +1,127 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/23 11:41:05 by lfirmin #+# #+# */
/* Updated: 2025/06/01 21:35:36 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int update_pwd_env(t_shell *shell)
{
char cwd[PATH_MAX];
char *old_pwd;
char *new_pwd;
old_pwd = ft_get_env_var(shell->env, "PWD");
if (old_pwd)
{
new_pwd = ft_strjoin("OLDPWD=", old_pwd);
if (new_pwd)
{
update_env_var(shell->env, new_pwd);
free(new_pwd);
}
}
if (getcwd(cwd, PATH_MAX) != NULL)
{
new_pwd = ft_strjoin("PWD=", cwd);
if (new_pwd)
{
update_env_var(shell->env, new_pwd);
free(new_pwd);
}
return (0);
}
return (1);
}
char *resolve_env_variables(char *path, t_shell *shell)
{
char *env_value;
char *var_name;
int i;
int start;
if (!path || !path[0] || !shell)
return (ft_strdup(path));
if (path[0] != '$')
return (ft_strdup(path));
start = 1;
i = start;
while (path[i] && path[i] != '/' && path[i] != ' ')
i++;
var_name = ft_substr(path, start, i - start);
if (!var_name)
return (NULL);
env_value = ft_get_env_var(shell->env, var_name);
free(var_name);
if (!env_value)
return (ft_strdup(""));
if (path[i])
return (ft_strjoin(env_value, &path[i]));
return (ft_strdup(env_value));
}
char *expand_tilde(char *path, t_shell *shell)
{
char *home;
char *result;
if (!path || path[0] != '~')
return (ft_strdup(path));
home = ft_get_env_var(shell->env, "HOME");
if (!home)
return (ft_strdup(path));
if (path[1] == '\0')
return (ft_strdup(home));
if (path[1] == '/')
{
result = ft_strjoin(home, path + 1);
return (result);
}
return (ft_strdup(path));
}
int validate_cd_args(t_cmd *cmd, t_shell *shell)
{
if (!cmd || !cmd->args)
return (1);
if (!cmd->args[1] || ft_strlen(cmd->args[1]) == 0)
return (handle_home_directory(shell));
if (ft_strcmp(cmd->args[1], "-") == 0)
return (handle_previous_directory(shell));
if (ft_strcmp(cmd->args[1], "~") == 0)
return (handle_home_directory(shell));
if (cmd->args[1] && cmd->args[2])
{
ft_putendl_fd("cd: too many arguments", STDERR_FILENO);
return (1);
}
return (0);
}
int ft_cd(t_cmd *cmd, t_shell *shell)
{
char *path;
char *resolved_path;
int validation_result;
int status;
validation_result = validate_cd_args(cmd, shell);
if (validation_result != 0)
return (validation_result);
path = cmd->args[1];
resolved_path = resolve_cd_path(path, shell);
if (!resolved_path)
return (1);
if (execute_cd_change(resolved_path) != 0)
return (1);
status = update_pwd_env(shell);
return (status);
}

130
src/builtins/cd_utils.c Normal file
View File

@ -0,0 +1,130 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cd_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/01 21:31:25 by tordner #+# #+# */
/* Updated: 2025/06/01 21:35:44 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int handle_home_directory(t_shell *shell)
{
char *home;
home = ft_get_env_var(shell->env, "HOME");
if (home == NULL)
{
ft_putendl_fd("cd: HOME not set", STDERR_FILENO);
return (1);
}
if (chdir(home) == -1)
{
ft_putstr_fd("cd: ", STDERR_FILENO);
ft_putstr_fd(home, STDERR_FILENO);
ft_putstr_fd(": ", STDERR_FILENO);
perror("");
return (1);
}
return (0);
}
int handle_previous_directory(t_shell *shell)
{
char *oldpwd;
oldpwd = ft_get_env_var(shell->env, "OLDPWD");
if (oldpwd == NULL)
{
ft_putendl_fd("cd: OLDPWD not set", STDERR_FILENO);
return (1);
}
ft_putendl_fd(oldpwd, STDOUT_FILENO);
if (chdir(oldpwd) == -1)
{
ft_putstr_fd("cd: ", STDERR_FILENO);
ft_putstr_fd(oldpwd, STDERR_FILENO);
ft_putstr_fd(": ", STDERR_FILENO);
perror("");
return (1);
}
return (0);
}
// char *resolve_cd_path(char *path, t_shell *shell)
// {
// char *resolved_path;
// if (path && path[0] == '~')
// resolved_path = expand_tilde(path, shell);
// else if (path && path[0] == '$')
// {
// resolved_path = resolve_env_variables(path, shell);
// if (!resolved_path || ft_strlen(resolved_path) == 0)
// {
// ft_putstr_fd("cd: ", STDERR_FILENO);
// ft_putstr_fd(path, STDERR_FILENO);
// ft_putendl_fd(": No such file or directory", STDERR_FILENO);
// if (resolved_path)
// free(resolved_path);
// return (NULL);
// }
// }
// else
// resolved_path = ft_strdup(path);
// return (resolved_path);
// }
char *resolve_cd_path(char *path, t_shell *shell)
{
char *resolved_path;
char *home;
if (!path)
{
home = get_env_value("HOME", shell);
if (!home)
{
ft_putendl_fd("minishell: cd: HOME not set", STDERR_FILENO);
return (NULL);
}
return (ft_strdup(home));
}
if (path[0] == '~')
resolved_path = expand_tilde(path, shell);
else if (path[0] == '$')
{
resolved_path = resolve_env_variables(path, shell);
if (!resolved_path || ft_strlen(resolved_path) == 0)
{
ft_putstr_fd("cd: ", STDERR_FILENO);
ft_putstr_fd(path, STDERR_FILENO);
ft_putendl_fd(": No such file or directory", STDERR_FILENO);
if (resolved_path)
free(resolved_path);
return (NULL);
}
}
else
resolved_path = ft_strdup(path);
return (resolved_path);
}
int execute_cd_change(char *resolved_path)
{
if (chdir(resolved_path) == -1)
{
ft_putstr_fd("cd: ", STDERR_FILENO);
ft_putstr_fd(resolved_path, STDERR_FILENO);
ft_putstr_fd(": ", STDERR_FILENO);
perror("");
free(resolved_path);
return (1);
}
free(resolved_path);
return (0);
}

73
src/builtins/echo.c Normal file
View File

@ -0,0 +1,73 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* echo.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/01/30 17:17:08 by thorgal #+# #+# */
/* Updated: 2025/06/02 00:22:51 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int is_valid_n_option(char *str)
{
int i;
if (!str || str[0] != '-' || str[1] != 'n')
return (0);
i = 2;
while (str[i])
{
if (str[i] != 'n')
return (0);
i++;
}
return (1);
}
void print_echo_args(char **args, int i, int first)
{
if (!args)
return ;
while (args[i])
{
if (!args[i])
i++;
else
{
if (!first)
printf(" ");
printf("%s", args[i]);
first = 0;
i++;
}
}
}
int ft_echo(t_cmd *cmd, t_shell *shell)
{
int print_newline;
int i;
char **args;
int first;
(void)shell;
if (!cmd || !cmd->args)
return (1);
i = 1;
print_newline = 1;
args = cmd->args;
while (args[i] && is_valid_n_option(args[i]))
{
print_newline = 0;
i++;
}
first = 1;
print_echo_args(args, i, first);
if (print_newline)
printf("\n");
return (0);
}

35
src/builtins/env.c Normal file
View File

@ -0,0 +1,35 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* env.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/04 15:49:05 by thorgal #+# #+# */
/* Updated: 2025/06/01 21:28:22 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int ft_env(t_shell *shell, t_cmd *cmd)
{
int i;
i = 0;
if (!shell->env)
return (1);
if (cmd && cmd->args && cmd->args[1])
{
ft_putstr_fd("env: '", 2);
ft_putstr_fd(cmd->args[1], 2);
ft_putstr_fd("': No such file or directory\n", 2);
return (127);
}
while (shell->env[i])
{
printf("%s\n", shell->env[i]);
i++;
}
return (0);
}

110
src/builtins/exit.c Normal file
View File

@ -0,0 +1,110 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exit.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/19 10:00:00 by lfirmin #+# #+# */
/* Updated: 2025/06/01 21:30:31 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
#include <limits.h>
#include <errno.h>
static long long parse_digits(char *str, int *i, int sign, int *overflow)
{
long long result;
result = 0;
while (str[*i] >= '0' && str[*i] <= '9')
{
if (sign == 1 && check_positive_overflow(result, str[*i]))
{
*overflow = 1;
return (LLONG_MAX);
}
if (sign == -1 && check_negative_overflow(result, str[*i]))
{
*overflow = 1;
return (LLONG_MIN);
}
result = result * 10 + (str[*i] - '0');
(*i)++;
}
return (result);
}
static long long safe_atoll(char *str, int *overflow)
{
long long result;
int sign;
int i;
result = 0;
sign = 1;
i = 0;
*overflow = 0;
if (str[i] == '-' || str[i] == '+')
{
if (str[i] == '-')
sign = -1;
i++;
}
result = parse_digits(str, &i, sign, overflow);
return (result * sign);
}
static void print_numeric_error(char *arg, t_shell *shell)
{
ft_putstr_fd("minishell: exit: ", 2);
ft_putstr_fd(arg, 2);
ft_putstr_fd(": numeric argument required\n", 2);
shell->exit_status = 2;
shell->running = 0;
}
static int handle_exit_argument(t_cmd *cmd, t_shell *shell, int *exit_code)
{
long long num;
int overflow;
if (!is_valid_number(cmd->args[1]))
{
print_numeric_error(cmd->args[1], shell);
return (2);
}
num = safe_atoll(cmd->args[1], &overflow);
if (overflow)
{
print_numeric_error(cmd->args[1], shell);
return (2);
}
*exit_code = (unsigned char)(num % 256);
if (cmd->args[2])
{
ft_putstr_fd("minishell: exit: too many arguments\n", 2);
return (1);
}
return (0);
}
int ft_exit(t_cmd *cmd, t_shell *shell)
{
int exit_code;
int result;
printf("exit\n");
exit_code = shell->exit_status;
if (cmd->args[1])
{
result = handle_exit_argument(cmd, shell, &exit_code);
if (result != 0)
return (result);
}
shell->exit_status = exit_code;
shell->running = 0;
return (exit_code);
}

47
src/builtins/exit_utils.c Normal file
View File

@ -0,0 +1,47 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exit_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/23 11:41:05 by lfirmin #+# #+# */
/* Updated: 2025/06/01 21:35:36 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int is_valid_number(char *str)
{
int i;
i = 0;
if (!str || !str[0])
return (0);
if (str[i] == '-' || str[i] == '+')
i++;
if (!str[i])
return (0);
while (str[i])
{
if (!ft_isdigit(str[i]))
return (0);
i++;
}
return (1);
}
int check_positive_overflow(long long result, char digit)
{
if (result > (LLONG_MAX - (digit - '0')) / 10)
return (1);
return (0);
}
int check_negative_overflow(long long result, char digit)
{
if (result > (-(LLONG_MIN + (digit - '0'))) / 10)
return (1);
return (0);
}

126
src/builtins/export.c Normal file
View File

@ -0,0 +1,126 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* export.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/23 11:54:38 by lfirmin #+# #+# */
/* Updated: 2025/06/01 21:30:55 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int update_env_var(char **env, char *var)
{
int i;
char *equal_sign;
int var_name_len;
equal_sign = ft_strchr(var, '=');
if (!equal_sign)
return (0);
var_name_len = equal_sign - var;
i = 0;
while (env[i])
{
if (ft_strncmp(env[i], var, var_name_len) == 0
&& (env[i][var_name_len] == '=' || env[i][var_name_len] == '\0'))
{
free(env[i]);
env[i] = ft_strdup(var);
if (!env[i])
return (-1);
return (1);
}
i++;
}
return (0);
}
int handle_export_validation(char *arg)
{
int validity;
validity = is_valid_identifier(arg);
if (validity <= 0)
{
ft_putstr_fd("export: '", 2);
ft_putstr_fd(arg, 2);
if (validity == -1)
{
ft_putstr_fd("': option invalide\n", 2);
return (2);
}
else
ft_putstr_fd("': not a valid identifier\n", 2);
return (1);
}
return (0);
}
int process_single_export_arg(t_shell *shell, char *arg)
{
int validation_result;
int status;
validation_result = handle_export_validation(arg);
if (validation_result > 0)
{
if (validation_result == 2)
return (2);
return (1);
}
if (ft_strchr(arg, '='))
{
status = handle_env_var(shell, arg);
if (status != 0)
return (status);
}
return (0);
}
int process_export_args(t_shell *shell, char **args, int i)
{
int ret;
int status;
int success;
ret = 1;
success = 0;
while (args[i])
{
status = process_single_export_arg(shell, args[i]);
if (status == 2)
return (2);
if (status == 1)
{
i++;
continue ;
}
if (status == 0)
success = 1;
i++;
}
if (success)
ret = 0;
return (ret);
}
int ft_export(t_shell *shell, t_cmd *cmd)
{
int i;
if (!cmd->args[1])
{
i = 0;
while (shell->env[i])
{
printf("declare -x %s\n", shell->env[i]);
i++;
}
return (0);
}
return (process_export_args(shell, cmd->args, 1));
}

View File

@ -0,0 +1,99 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* export_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/23 11:57:58 by lfirmin #+# #+# */
/* Updated: 2025/06/01 21:39:05 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *handle_quotes_in_env_var(char *arg)
{
char *equal_sign;
char *var_name;
char *var_value;
char *clean_value;
char *result;
equal_sign = ft_strchr(arg, '=');
if (!equal_sign)
return (ft_strdup(arg));
var_name = ft_substr(arg, 0, equal_sign - arg + 1);
if (!var_name)
return (NULL);
var_value = equal_sign + 1;
clean_value = malloc(ft_strlen(var_value) + 1);
if (!clean_value)
return (free(var_name), NULL);
process_quotes(var_value, clean_value);
result = ft_strjoin(var_name, clean_value);
free(var_name);
free(clean_value);
return (result);
}
static int handle_expansion_error(char *expanded_arg)
{
if (!expanded_arg)
{
ft_putstr_fd("export: memory allocation error\n", 2);
return (1);
}
return (0);
}
static int handle_processing_error(char *expanded_arg, char *processed_arg)
{
free(expanded_arg);
if (!processed_arg)
{
ft_putstr_fd("export: memory allocation error\n", 2);
return (1);
}
return (0);
}
static int handle_update_result(t_shell *shell, char *processed_arg,
int update_result)
{
if (update_result == 0)
{
shell->env = add_env_var(shell->env, processed_arg);
free(processed_arg);
if (!shell->env)
{
ft_putstr_fd("export: memory allocation error\n", 2);
return (1);
}
}
else if (update_result == -1)
{
free(processed_arg);
ft_putstr_fd("export: memory allocation error\n", 2);
return (1);
}
else
free(processed_arg);
return (0);
}
int handle_env_var(t_shell *shell, char *arg)
{
int update_result;
char *expanded_arg;
char *processed_arg;
expanded_arg = expand_env_variables(arg, shell->env);
if (handle_expansion_error(expanded_arg))
return (1);
processed_arg = handle_quotes_in_env_var(expanded_arg);
if (handle_processing_error(expanded_arg, processed_arg))
return (1);
update_result = update_env_var(shell->env, processed_arg);
return (handle_update_result(shell, processed_arg, update_result));
}

View File

@ -0,0 +1,117 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* export_utils2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/01 21:39:14 by tordner #+# #+# */
/* Updated: 2025/06/01 21:40:08 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int is_valid_identifier(char *str)
{
int i;
if (!str || !*str)
return (0);
if (str[0] == '-')
return (-1);
if (!((str[0] >= 'a' && str[0] <= 'z')
|| (str[0] >= 'A' && str[0] <= 'Z')
|| str[0] == '_'))
return (0);
i = 1;
while (str[i] && str[i] != '=')
{
if (!((str[i] >= 'a' && str[i] <= 'z')
|| (str[i] >= 'A' && str[i] <= 'Z')
|| (str[i] >= '0' && str[i] <= '9')
|| str[i] == '_'))
return (0);
i++;
}
return (1);
}
char *process_single_var(char *result, char *var_start, char *var_end,
char **env)
{
char *var_name;
char *var_value;
char *new_result;
var_name = extract_var_name(result, var_start, var_end);
if (!var_name)
return (free(result), NULL);
var_value = get_env_value_for_expansion(env, var_name);
if (!var_value)
var_value = "";
new_result = build_expanded_string(result, var_start, var_end, var_value);
free(var_name);
free(result);
return (new_result);
}
char *expand_env_variables(char *str, char **env)
{
char *result;
char *var_start;
char *var_end;
if (!str)
return (NULL);
result = ft_strdup(str);
if (!result)
return (NULL);
while (find_next_var(result, &var_start, &var_end) && var_start)
{
result = process_single_var(result, var_start, var_end, env);
if (!result)
return (NULL);
}
return (result);
}
void handle_quote_char(char *var_value, int *i, int *in_quotes,
char *quote_type)
{
if (!*in_quotes && (var_value[*i] == '\'' || var_value[*i] == '"'))
{
*in_quotes = 1;
*quote_type = var_value[*i];
(*i)++;
}
else if (*in_quotes && var_value[*i] == *quote_type)
{
*in_quotes = 0;
*quote_type = 0;
(*i)++;
}
}
char *process_quotes(char *var_value, char *clean_value)
{
int i;
int j;
int in_quotes;
char quote_type;
i = 0;
j = 0;
in_quotes = 0;
quote_type = 0;
while (var_value[i])
{
if ((var_value[i] == '\'' || var_value[i] == '"'))
handle_quote_char(var_value, &i, &in_quotes, &quote_type);
else
clean_value[j++] = var_value[i++];
}
clean_value[j] = '\0';
return (clean_value);
}
// char **add_env_var(char **env, char *new_var) in utils.c

View File

@ -0,0 +1,89 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* export_utils3.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/01 21:39:14 by tordner #+# #+# */
/* Updated: 2025/06/01 21:40:08 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
char *get_env_value_for_expansion(char **env, char *var_name)
{
int i;
int var_len;
char *equal_pos;
if (!env || !var_name)
return (NULL);
var_len = ft_strlen(var_name);
i = 0;
while (env[i])
{
equal_pos = ft_strchr(env[i], '=');
if (equal_pos && (equal_pos - env[i]) == var_len
&& ft_strncmp(env[i], var_name, var_len) == 0)
return (equal_pos + 1);
i++;
}
return (NULL);
}
char *extract_var_name(char *result, char *var_start, char *var_end)
{
return (ft_substr(result, var_start - result + 1, var_end - var_start - 1));
}
char *build_expanded_string(char *result, char *var_start, char *var_end,
char *var_value)
{
char *before_var;
char *after_var;
char *temp;
char *final_result;
before_var = ft_substr(result, 0, var_start - result);
after_var = ft_strdup(var_end);
if (!before_var || !after_var)
{
free(before_var);
free(after_var);
return (NULL);
}
temp = ft_strjoin(before_var, var_value);
free(before_var);
if (!temp)
{
free(after_var);
return (NULL);
}
final_result = ft_strjoin(temp, after_var);
free(temp);
free(after_var);
return (final_result);
}
char *find_next_var(char *result, char **var_start, char **var_end)
{
char *temp;
*var_start = ft_strchr(result, '$');
if (!*var_start)
return (result);
*var_end = *var_start + 1;
while (**var_end && (ft_isalnum(**var_end) || **var_end == '_'))
(*var_end)++;
if (*var_end == *var_start + 1)
{
temp = ft_strchr(*var_start + 1, '$');
if (!temp)
return (result);
*var_start = temp;
return (find_next_var(result, var_start, var_end));
}
return (result);
}

26
src/builtins/pwd.c Normal file
View File

@ -0,0 +1,26 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pwd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/23 11:41:22 by lfirmin #+# #+# */
/* Updated: 2025/04/23 11:41:34 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int ft_pwd(void)
{
static char pwd[PATH_MAX];
if (getcwd(pwd, PATH_MAX) == NULL)
{
perror("getcwd() error");
return (1);
}
printf("%s\n", pwd);
return (0);
}

59
src/builtins/unset.c Normal file
View File

@ -0,0 +1,59 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* unset.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/23 03:34:29 by lfirmin #+# #+# */
/* Updated: 2025/05/19 09:08:02 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int delete_line(char **array, int index)
{
if (!array[index])
return (0);
free(array[index]);
while (array[index + 1])
{
array[index] = array[index + 1];
index++;
}
array[index] = NULL;
return (1);
}
int find_env_var(char **env, char *var)
{
int i;
int len;
i = 0;
len = ft_strlen(var);
while (env[i])
{
if (ft_strncmp(env[i], var, len) == 0 && env[i][len] == '=')
return (i);
i++;
}
return (-1);
}
int ft_unset(t_shell *shell, t_cmd *cmd)
{
int i;
int index;
i = 1;
while (cmd->args[i])
{
index = find_env_var(shell->env, cmd->args[i]);
if (index != -1)
delete_line(shell->env, index);
i++;
}
return (0);
}

41
src/exec/exec.c Normal file
View File

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exec.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/12/02 13:25:52 by tordner #+# #+# */
/* Updated: 2025/06/03 04:11:33 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int file_exists(const char *path)
{
return (access(path, F_OK));
}
char *execute_ve_2(t_cmd *cmd, char *path_env, char *full_path)
{
if (!path_env)
{
write(2, "Error: PATH not found\n", 22);
exit(127);
}
full_path = find_command(ft_split(path_env, ':'), cmd->args[0]);
if (!full_path)
{
write(2, "Error: Command not found\n", 25);
exit(127);
}
return (full_path);
}
void run_child_process(t_cmd *cmd, char **envp)
{
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
execute_ve(cmd, envp);
}

93
src/exec/exec_utils.c Normal file
View File

@ -0,0 +1,93 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* exec_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/02 00:42:13 by tordner #+# #+# */
/* Updated: 2025/06/02 01:03:26 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int setup_pipe(int pipefd[2])
{
if (pipe(pipefd) == -1)
{
write(2, "Error creating pipe\n", 21);
return (1);
}
return (0);
}
int open_file(char *file, int flags, int mode)
{
int fd;
if (!file)
return (-1);
fd = open(file, flags, mode);
if (fd == -1)
{
perror(file);
return (-1);
}
return (fd);
}
int wait_for_children(pid_t last_pid)
{
int status;
int exit_status;
pid_t pid;
exit_status = 0;
pid = wait(&status);
while (pid > 0)
{
if (WIFEXITED(status))
{
if (pid == last_pid || last_pid == -1)
exit_status = WEXITSTATUS(status);
}
else if (WIFSIGNALED(status))
{
exit_status = 128 + WTERMSIG(status);
if (WTERMSIG(status) == SIGINT)
g_signal = 128 + SIGINT;
else if (WTERMSIG(status) == SIGQUIT)
g_signal = 128 + SIGQUIT;
}
pid = wait(&status);
}
return (exit_status);
}
void handle_child(t_cmd *cmd, int infile, int pipefd[2], t_shell *shell)
{
set_signal_child();
if (cmd->redir && setup_input_redirections(cmd->redir) != 0)
exit(1);
if (!has_input_redirection(cmd->redir))
{
if (dup2(infile, STDIN_FILENO) == -1)
exit(1);
}
if (cmd->next && dup2(pipefd[1], STDOUT_FILENO) == -1)
exit(1);
if (infile != STDIN_FILENO)
close(infile);
if (cmd->next)
{
close(pipefd[0]);
close(pipefd[1]);
}
if (cmd->redir && setup_output_redirections(cmd->redir) != 0)
exit(1);
if (is_builtin(cmd->args[0]))
exit(execute_builtin(cmd, shell));
execute_ve(cmd, shell->env);
exit(1);
}

View File

@ -0,0 +1,52 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* execute_pipeline.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 03:04:07 by tordner #+# #+# */
/* Updated: 2025/06/03 03:04:35 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static int handle_single_builtin(t_cmd *cmd, t_shell *shell)
{
int saved_stdin;
int saved_stdout;
int redir_status;
if (!cmd->redir)
return (execute_builtin(cmd, shell));
saved_stdin = dup(STDIN_FILENO);
saved_stdout = dup(STDOUT_FILENO);
shell->signaled = 0;
redir_status = loop_open_files(cmd);
if (redir_status != 0)
{
restore_fds(saved_stdin, saved_stdout);
return (1);
}
shell->exit_status = execute_builtin(cmd, shell);
restore_fds(saved_stdin, saved_stdout);
if (g_signal)
{
shell->signaled = 1;
shell->exit_status = g_signal;
}
return (shell->exit_status);
}
static int handle_pipeline(t_cmd *cmd_list, t_shell *shell)
{
return (spawn_pipeline(cmd_list, shell));
}
int execute_pipeline(t_cmd *cmd_list, t_shell *shell)
{
if (cmd_list && !cmd_list->next && is_builtin(cmd_list->args[0]))
return (handle_single_builtin(cmd_list, shell));
return (handle_pipeline(cmd_list, shell));
}

61
src/exec/execute_ve.c Normal file
View File

@ -0,0 +1,61 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* execute_ve.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 03:53:31 by tordner #+# #+# */
/* Updated: 2025/06/03 04:01:20 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
#include <sys/stat.h>
static int check_absolute_path(t_cmd *cmd)
{
struct stat file_stat;
if (file_exists(cmd->args[0]) != 0)
{
ft_putstr_fd(cmd->args[0], 2);
ft_putstr_fd(": No such file or directory\n", 2);
exit(127);
}
if (stat(cmd->args[0], &file_stat) == 0 && S_ISDIR(file_stat.st_mode))
{
ft_putstr_fd(cmd->args[0], 2);
ft_putstr_fd(": Is a directory\n", 2);
exit(126);
}
if (access(cmd->args[0], X_OK) == 0)
return (1);
ft_putstr_fd(cmd->args[0], 2);
ft_putstr_fd(": Permission denied\n", 2);
exit(126);
}
static void handle_path_execution(t_cmd *cmd, char **envp)
{
char *full_path;
char *path_env;
path_env = get_path_env(envp);
full_path = execute_ve_2(cmd, path_env, NULL);
if (full_path)
execve(full_path, cmd->args, envp);
ft_putstr_fd("Error: Command execution failed\n", 2);
exit(126);
}
int execute_ve(t_cmd *cmd, char **envp)
{
if (cmd->args[0][0] == '/' || cmd->args[0][0] == '.')
{
if (check_absolute_path(cmd))
execve(cmd->args[0], cmd->args, envp);
}
handle_path_execution(cmd, envp);
return (0);
}

74
src/exec/file_handler.c Normal file
View File

@ -0,0 +1,74 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* file_handler.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/12/02 16:27:31 by tordner #+# #+# */
/* Updated: 2025/06/03 03:51:22 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int loop_open_files(t_cmd *cmd)
{
t_redirection *redir;
int result;
if (!cmd || !cmd->redir)
return (0);
redir = cmd->redir;
while (redir)
{
result = setup_files(redir);
if (result != 0)
return (result);
redir = redir->next;
}
return (0);
}
int setup_input_redirections(t_redirection *redir)
{
int fd;
t_redirection *current;
current = redir;
while (current)
{
if (current->type == 1)
{
fd = open(current->file, O_RDONLY);
if (fd == -1)
{
perror(current->file);
return (1);
}
dup2(fd, STDIN_FILENO);
close(fd);
}
else if (current->type == 4)
{
if (handle_heredoc(current->file) != 0)
return (1);
}
current = current->next;
}
return (0);
}
int has_input_redirection(t_redirection *redir)
{
t_redirection *current;
current = redir;
while (current)
{
if (current->type == 1 || current->type == 4)
return (1);
current = current->next;
}
return (0);
}

56
src/exec/ft_exec.c Normal file
View File

@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_exec.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 04:08:12 by tordner #+# #+# */
/* Updated: 2025/06/03 04:09:39 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static void handle_child_process(t_cmd *cmd, char **envp)
{
if (cmd->redir)
{
if (loop_open_files(cmd) != 0)
exit(1);
}
run_child_process(cmd, envp);
}
static int get_exit_status(int status)
{
if (WIFEXITED(status))
return (WEXITSTATUS(status));
else if (WIFSIGNALED(status))
{
if (WTERMSIG(status) == SIGINT)
return (130);
return (128 + WTERMSIG(status));
}
return (1);
}
int ft_exec(t_cmd *cmd, char **envp, t_shell *shell)
{
pid_t pid;
int status;
shell->child_running = 1;
pid = fork();
if (pid == -1)
{
write(2, "Error forking process\n", 23);
shell->child_running = 0;
return (1);
}
if (pid == 0)
handle_child_process(cmd, envp);
waitpid(pid, &status, 0);
shell->child_running = 0;
return (get_exit_status(status));
}

68
src/exec/get_env.c Normal file
View File

@ -0,0 +1,68 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_env.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/12/03 16:30:02 by tordner #+# #+# */
/* Updated: 2025/04/19 12:39:55 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
char *join_path(char *directory, char *cmd)
{
char *path;
size_t dir_len;
size_t cmd_len;
size_t total_len;
dir_len = ft_strlen(directory);
cmd_len = ft_strlen(cmd);
total_len = dir_len + cmd_len + 2;
path = malloc(total_len);
if (!path)
return (NULL);
ft_strcpy(path, directory);
path[dir_len] = '/';
ft_strcpy(path + dir_len + 1, cmd);
return (path);
}
char *get_path_env(char **envp)
{
int i;
char *path_env;
i = 0;
path_env = NULL;
while (envp[i])
{
if (ft_strncmp(envp[i], "PATH=", 5) == 0)
{
path_env = envp[i] + 5;
break ;
}
i++;
}
return (path_env);
}
char *find_command(char **paths, char *cmd)
{
char *full_path;
int i;
i = 0;
while (paths[i])
{
full_path = join_path(paths[i], cmd);
if (access(full_path, X_OK) == 0)
return (full_path);
free(full_path);
i++;
}
return (NULL);
}

67
src/exec/heredoc.c Normal file
View File

@ -0,0 +1,67 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* heredoc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/23 01:17:12 by lfirmin #+# #+# */
/* Updated: 2025/06/03 03:37:59 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
static int create_heredoc_pipe(int pipefd[2])
{
if (pipe(pipefd) == -1)
{
perror("minishell: pipe");
return (1);
}
return (0);
}
static void process_heredoc_input(int pipefd[2], char *delim)
{
char *line;
while (1)
{
line = readline("> ");
if (!line)
{
ft_putstr_fd(\
"minishell: warning: here-document delimited "
"by end-of-file\n", 2);
break ;
}
if (ft_strcmp(line, delim) == 0)
{
free(line);
break ;
}
write(pipefd[1], line, ft_strlen(line));
write(pipefd[1], "\n", 1);
free(line);
}
}
int handle_heredoc(char *delim)
{
int pipefd[2];
if (!delim)
return (1);
if (create_heredoc_pipe(pipefd))
return (1);
process_heredoc_input(pipefd, delim);
close(pipefd[1]);
if (dup2(pipefd[0], STDIN_FILENO) == -1)
{
close(pipefd[0]);
return (1);
}
close(pipefd[0]);
return (0);
}

83
src/exec/pipe.c Normal file
View File

@ -0,0 +1,83 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* pipe.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/12/02 13:25:59 by tordner #+# #+# */
/* Updated: 2025/06/03 03:05:55 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
void handle_parent(int *infile, int pipefd[2], t_cmd *cmd)
{
if (*infile != STDIN_FILENO)
close(*infile);
if (cmd->next)
{
close(pipefd[1]);
*infile = pipefd[0];
}
else if (pipefd[0] != -1)
close(pipefd[0]);
}
int run_child_pipe(t_cmd *cmd, t_shell *shell, int *infile)
{
int pipefd[2];
pid_t pid;
if (cmd->next && pipe(pipefd) == -1)
return (1);
else if (!cmd->next)
{
pipefd[0] = -1;
pipefd[1] = STDOUT_FILENO;
}
pid = fork();
if (pid == -1)
return (1);
if (pid == 0)
handle_child(cmd, *infile, pipefd, shell);
handle_parent(infile, pipefd, cmd);
return (0);
}
int spawn_pipeline(t_cmd *cmd, t_shell *shell)
{
int infile;
int exit_status;
shell->child_running = 1;
shell->signaled = 0;
set_signal_parent_exec();
infile = STDIN_FILENO;
while (cmd)
{
if (run_child_pipe(cmd, shell, &infile) != 0)
{
shell->child_running = 0;
set_signal_parent();
return (1);
}
cmd = cmd->next;
}
exit_status = 0;
exit_status = wait_for_children(-1);
shell->child_running = 0;
if (g_signal)
shell->signaled = 1;
set_signal_parent();
return (exit_status);
}
void restore_fds(int saved_stdin, int saved_stdout)
{
dup2(saved_stdin, STDIN_FILENO);
dup2(saved_stdout, STDOUT_FILENO);
close(saved_stdin);
close(saved_stdout);
}

73
src/exec/setup_files.c Normal file
View File

@ -0,0 +1,73 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* setup_files.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 03:42:14 by tordner #+# #+# */
/* Updated: 2025/06/03 03:43:42 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static int handle_input_redir(t_redirection *redir)
{
int fd;
fd = open(redir->file, O_RDONLY);
if (fd == -1)
{
perror(redir->file);
return (1);
}
dup2(fd, STDIN_FILENO);
close(fd);
return (0);
}
static int handle_output_redir(t_redirection *redir)
{
int fd;
fd = open(redir->file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
{
perror(redir->file);
return (1);
}
dup2(fd, STDOUT_FILENO);
close(fd);
return (0);
}
static int handle_append_redir(t_redirection *redir)
{
int fd;
fd = open(redir->file, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (fd == -1)
{
perror(redir->file);
return (1);
}
dup2(fd, STDOUT_FILENO);
close(fd);
return (0);
}
int setup_files(t_redirection *redir)
{
if (!redir || !redir->file)
return (1);
if (redir->type == 1)
return (handle_input_redir(redir));
else if (redir->type == 2)
return (handle_output_redir(redir));
else if (redir->type == 3)
return (handle_append_redir(redir));
else if (redir->type == 4)
return (handle_heredoc(redir->file));
return (0);
}

View File

@ -0,0 +1,65 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* setup_output_redirections.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 03:48:01 by tordner #+# #+# */
/* Updated: 2025/06/03 03:48:24 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static int handle_trunc_redir(t_redirection *redir)
{
int fd;
fd = open(redir->file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1)
{
perror(redir->file);
return (1);
}
dup2(fd, STDOUT_FILENO);
close(fd);
return (0);
}
static int handle_append_redir(t_redirection *redir)
{
int fd;
fd = open(redir->file, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (fd == -1)
{
perror(redir->file);
return (1);
}
dup2(fd, STDOUT_FILENO);
close(fd);
return (0);
}
int setup_output_redirections(t_redirection *redir)
{
t_redirection *current;
current = redir;
while (current)
{
if (current->type == 2)
{
if (handle_trunc_redir(current))
return (1);
}
else if (current->type == 3)
{
if (handle_append_redir(current))
return (1);
}
current = current->next;
}
return (0);
}

60
src/main/input.c Normal file
View File

@ -0,0 +1,60 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* input.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/01/30 17:17:15 by lfirmin #+# #+# */
/* Updated: 2025/06/03 04:15:00 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
char **parse_input(char *input, t_shell *shell)
{
char **tokens;
int i;
tokens = tokenize_command(input, shell);
if (!tokens)
{
printf(ERROR_TOKEN);
shell->exit_status = 1;
return (NULL);
}
if (validate_syntax(tokens))
{
i = 0;
shell->exit_status = 2;
while (tokens[i])
free(tokens[i++]);
free(tokens);
return (NULL);
}
return (tokens);
}
void process_input(char *input, t_shell *shell)
{
char **tokens;
int i;
int ret;
t_cmd *cmd_list;
tokens = parse_input(input, shell);
if (!tokens)
return ;
cmd_list = parse_tokens_to_list(tokens);
if (cmd_list)
{
ret = execute_pipeline(cmd_list, shell);
shell->exit_status = ret;
free_cmd_list(cmd_list);
}
i = 0;
while (tokens[i])
free(tokens[i++]);
free(tokens);
}

95
src/main/main.c Normal file
View File

@ -0,0 +1,95 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/01/30 17:17:15 by lfirmin #+# #+# */
/* Updated: 2025/06/01 21:32:22 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void initialize_shell(t_shell *shell, char **envp)
{
shell->env = copy_env(envp);
shell->exit_status = 0;
shell->running = 1;
shell->signaled = 0;
}
int is_builtin(char *cmd)
{
return (ft_strcmp(cmd, "echo") == 0
|| ft_strcmp(cmd, "cd") == 0
|| ft_strcmp(cmd, "pwd") == 0
|| ft_strcmp(cmd, "exit") == 0
|| ft_strcmp(cmd, "env") == 0
|| ft_strcmp(cmd, "export") == 0
|| ft_strcmp(cmd, "unset") == 0);
}
int execute_builtin(t_cmd *cmd, t_shell *shell)
{
if (!cmd || !cmd->args || !cmd->args[0])
return (1);
if (ft_strcmp(cmd->args[0], "echo") == 0)
return (ft_echo(cmd, shell));
else if (ft_strcmp(cmd->args[0], "cd") == 0)
return (ft_cd(cmd, shell));
else if (ft_strcmp(cmd->args[0], "pwd") == 0)
return (ft_pwd());
else if (ft_strcmp(cmd->args[0], "exit") == 0)
return (ft_exit(cmd, shell));
else if (ft_strcmp(cmd->args[0], "env") == 0)
return (ft_env(shell, cmd));
else if (ft_strcmp(cmd->args[0], "export") == 0)
return (ft_export(shell, cmd));
else if (ft_strcmp(cmd->args[0], "unset") == 0)
return (ft_unset(shell, cmd));
return (1);
}
int execute_command(t_cmd *cmd, t_shell *shell)
{
int saved_stdin;
int saved_stdout;
if (!cmd || !cmd->args || !cmd->args[0])
return (1);
if (is_builtin(cmd->args[0]))
{
saved_stdin = dup(STDIN_FILENO);
saved_stdout = dup(STDOUT_FILENO);
if (cmd->redir)
loop_open_files(cmd);
shell->exit_status = execute_builtin(cmd, shell);
dup2(saved_stdin, STDIN_FILENO);
dup2(saved_stdout, STDOUT_FILENO);
close(saved_stdin);
close(saved_stdout);
}
else
shell->exit_status = ft_exec(cmd, shell->env, shell);
return (shell->exit_status);
}
int main(void)
{
t_shell shell;
extern char **environ;
int i;
initialize_shell(&shell, environ);
minishell_loop(&shell);
if (shell.env)
{
i = 0;
while (shell.env[i])
free(shell.env[i++]);
free(shell.env);
}
return (shell.exit_status);
}

54
src/main/prompt.c Normal file
View File

@ -0,0 +1,54 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* prompt.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 02:58:34 by tordner #+# #+# */
/* Updated: 2025/06/03 02:58:59 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *create_standard_prompt(char *dir_name, int exit_status)
{
char *prompt;
char *tmp;
if (exit_status == 0)
{
tmp = ft_strjoin(GREEN "\001\033[0m\002 \001\033[1;36m\002", dir_name);
if (!tmp)
return (NULL);
prompt = ft_strjoin(tmp, "\001\033[0m\002 ");
free(tmp);
}
else
{
tmp = ft_strjoin(RED "\001\033[0m\002 \001\033[1;36m\002", dir_name);
if (!tmp)
return (NULL);
prompt = ft_strjoin(tmp, "\001\033[0m\002 ");
free(tmp);
}
return (prompt);
}
char *generate_prompt(t_shell *shell)
{
char *dir_name;
char *prompt;
dir_name = get_current_dir_name();
if (!dir_name)
return (ft_strdup(" "));
else
prompt = create_standard_prompt(dir_name, shell->exit_status);
free(dir_name);
if (prompt)
return (prompt);
else
return (ft_strdup(" "));
}

77
src/main/shell.c Normal file
View File

@ -0,0 +1,77 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* shell.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/21 15:38:19 by lfirmin #+# #+# */
/* Updated: 2025/06/03 03:01:28 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../includes/minishell.h"
void handle_input(char *input, t_shell *shell)
{
int i;
i = 0;
while (input[i] && (input[i] == ' ' || input[i] == '\t'))
i++;
if (input[i] != '\0')
{
add_history(input);
process_input(input, shell);
}
}
static void handle_signal_state(t_shell *shell)
{
if (g_signal && !shell->child_running)
{
shell->exit_status = g_signal;
g_signal = 0;
}
}
static char *get_input(char *prompt)
{
char *input;
input = readline(prompt);
free(prompt);
return (input);
}
static void init_terminal_settings(void)
{
struct termios term;
tcgetattr(STDIN_FILENO, &term);
term.c_lflag &= ~(ECHOCTL);
tcsetattr(STDIN_FILENO, TCSANOW, &term);
rl_initialize();
}
void minishell_loop(t_shell *shell)
{
char *input;
char *prompt;
init_terminal_settings();
while (shell->running)
{
set_signal_parent();
prompt = generate_prompt(shell);
input = get_input(prompt);
if (!input)
{
printf("exit\n");
break ;
}
handle_signal_state(shell);
handle_input(input, shell);
free(input);
}
}

64
src/main/signals.c Normal file
View File

@ -0,0 +1,64 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* signals.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/01/27 00:00:00 by lfirmin #+# #+# */
/* Updated: 2025/06/02 01:05:49 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "../../includes/minishell.h"
int g_signal = 0;
void if_sigint(int sig)
{
g_signal = 128 + sig;
rl_done = 1;
}
void set_status_if_signal(t_shell *shell)
{
shell->exit_status = g_signal;
g_signal = 0;
}
void set_signal_child(void)
{
rl_event_hook = sig_event;
signal(SIGQUIT, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGTSTP, SIG_IGN);
}
void set_signal_parent_exec(void)
{
struct sigaction sa;
struct sigaction sb;
rl_event_hook = sig_event;
ft_memset(&sa, 0, sizeof(sa));
sa.sa_handler = handle_signal_parent;
sa.sa_flags = SA_RESTART;
sigaction(SIGINT, &sa, NULL);
ft_memset(&sb, 0, sizeof(sb));
sb.sa_handler = handle_signal_parent;
sb.sa_flags = SA_RESTART;
sigaction(SIGQUIT, &sb, NULL);
}
void set_signal_parent(void)
{
struct sigaction sa;
rl_event_hook = sig_event;
ft_memset(&sa, 0, sizeof(sa));
sa.sa_handler = if_sigint;
sa.sa_flags = SA_RESTART;
sigaction(SIGINT, &sa, NULL);
signal(SIGQUIT, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
}

44
src/main/signals_utils.c Normal file
View File

@ -0,0 +1,44 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* signals_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/02 00:58:26 by tordner #+# #+# */
/* Updated: 2025/06/03 02:58:02 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
// void check_if_signal(t_shell *shell)
// {
// if (shell->signaled == 1 && g_signal == 128 + SIGQUIT)
// {
// ft_putstr_fd("Quit (core dumped)\n", 2);
// shell->exit_status = g_signal;
// }
// if (g_signal == 128 + SIGINT && shell->signaled == 1)
// {
// write(STDERR_FILENO, "\n", 1);
// shell->exit_status = g_signal;
// }
// if (shell->exit_status == 128 + SIGSEGV && shell->signaled == 1)
// ft_putstr_fd("Segmentation fault (core dumped)\n", STDERR_FILENO);
// if (shell->signaled == 1)
// {
// shell->signaled = 0;
// g_signal = 0;
// }
// }
void handle_signal_parent(int num)
{
g_signal = num + 128;
}
int sig_event(void)
{
return (EXIT_SUCCESS);
}

98
src/tokens/check_pipes.c Normal file
View File

@ -0,0 +1,98 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_pipes.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/06 16:55:42 by tordner #+# #+# */
/* Updated: 2025/06/03 02:50:07 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int check_before_pipe(char **tokens)
{
int i;
i = 0;
while (tokens[i])
{
if (classify_token(tokens[i]) == TOKEN_PIPE && i > 0)
{
if (classify_token(tokens[i - 1]) == TOKEN_REDIRECTION_IN
|| classify_token(tokens[i - 1]) == TOKEN_REDIRECTION_OUT
|| classify_token(tokens[i - 1]) == TOKEN_APPEND
|| classify_token(tokens[i - 1]) == TOKEN_HEREDOC)
return (1);
}
i++;
}
return (0);
}
static int has_consecutive_pipes(char **tokens)
{
int i;
i = 0;
while (tokens[i])
{
if (classify_token(tokens[i]) == TOKEN_PIPE && tokens[i + 1]
&& classify_token(tokens[i + 1]) == TOKEN_PIPE)
return (1);
i++;
}
return (0);
}
static int has_valid_command_after_pipe(char **tokens, int pipe_pos)
{
int j;
int has_command;
j = pipe_pos + 1;
has_command = 0;
while (tokens[j] && classify_token(tokens[j]) != TOKEN_PIPE)
{
if (classify_token(tokens[j]) == TOKEN_WORD)
{
if (j == pipe_pos + 1 \
|| classify_token(tokens[j - 1]) == TOKEN_WORD)
has_command = 1;
}
j++;
}
return (has_command);
}
static int check_pipe_commands(char **tokens)
{
int i;
i = 0;
while (tokens[i])
{
if (classify_token(tokens[i]) == TOKEN_PIPE && tokens[i + 1])
{
if (!has_valid_command_after_pipe(tokens, i))
return (1);
}
i++;
}
return (0);
}
int pipe_sequence_invalid(char **tokens)
{
if (!tokens)
return (1);
if (has_consecutive_pipes(tokens))
return (1);
if (check_before_pipe(tokens))
return (1);
if (check_pipe_commands(tokens))
return (1);
return (0);
}

View File

@ -0,0 +1,92 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* check_redirections.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/06 17:17:19 by tordner #+# #+# */
/* Updated: 2025/06/03 02:50:31 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int is_redirection(char *token)
{
t_token_type type;
type = classify_token(token);
return (type == TOKEN_REDIRECTION_IN || type == TOKEN_REDIRECTION_OUT
|| type == TOKEN_APPEND || type == TOKEN_HEREDOC);
}
int check_further_redirections(char **tokens, int i)
{
if (is_redirection(tokens[i]) && !tokens[i + 1])
{
write(STDERR_FILENO, \
"Syntax error: Redirection cannot appear at the end\n", 52);
return (2);
}
if (is_redirection(tokens[i]) && is_redirection(tokens[i + 1]))
{
write(STDERR_FILENO, "Syntax error: Consecutive redirection operators "
"are not allowed\n", 65);
return (2);
}
return (0);
}
static int has_valid_command(char **tokens)
{
int j;
int has_command;
j = 0;
has_command = 0;
while (tokens[j])
{
if (classify_token(tokens[j]) == TOKEN_WORD)
{
if (j == 0 || !is_redirection(tokens[j - 1]))
has_command = 1;
}
j++;
}
if (!has_command)
{
write(STDERR_FILENO, "Syntax error: No command found\n", 32);
return (0);
}
return (1);
}
int validate_redirections(char **tokens)
{
int i;
if (!has_valid_command(tokens))
return (2);
i = 0;
while (tokens[i])
{
if (check_further_redirections(tokens, i))
return (2);
i++;
}
return (0);
}
int validate_pipes(char **tokens)
{
int end;
end = 0;
while (tokens[end + 1] != NULL)
end++;
if (classify_token(tokens[0]) == TOKEN_PIPE
|| classify_token(tokens[end]) == TOKEN_PIPE)
return (1);
return (pipe_sequence_invalid(tokens));
}

82
src/tokens/expander.c Normal file
View File

@ -0,0 +1,82 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* expander.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/01 22:59:57 by tordner #+# #+# */
/* Updated: 2025/06/02 01:19:06 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static char *append_status(char *res, t_shell *sh, int *i)
{
char *val;
char *tmp;
val = ft_itoa(sh->exit_status);
tmp = ft_strjoin(res, val);
free(res);
free(val);
*i += 2;
return (tmp);
}
static char *append_env(char *res, char *str, t_shell *sh, int *i)
{
int start;
char *var;
char *val;
char *tmp;
start = ++(*i);
while (str[*i] && (ft_isalnum(str[*i]) || str[*i] == '_'))
(*i)++;
var = ft_substr(str, start, *i - start);
val = get_env_value(var, sh);
if (!val)
val = "";
tmp = ft_strjoin(res, val);
free(res);
free(var);
return (tmp);
}
static char *append_char(char *res, char c)
{
char buf[2];
char *tmp;
buf[0] = c;
buf[1] = '\0';
tmp = ft_strjoin(res, buf);
free(res);
return (tmp);
}
char *expand_variables(char *str, t_shell *sh)
{
int i;
char *res;
i = 0;
res = ft_calloc(1, 1);
while (str && str[i])
{
if (str[i] == '$' && str[i + 1])
{
if (str[i + 1] == '?')
res = append_status(res, sh, &i);
else if (ft_isalnum(str[i + 1]) || str[i + 1] == '_')
res = append_env(res, str, sh, &i);
else
res = append_char(res, str[i++]);
}
else
res = append_char(res, str[i++]);
}
return (res);
}

View File

@ -0,0 +1,68 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* extract_quoted_content.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 00:39:01 by tordner #+# #+# */
/* Updated: 2025/06/03 01:08:06 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static int handle_double_quote_escape(t_escape_handler *m, int i)
{
if (m->input[i + 1] == '"' || m->input[i + 1] == '\\' \
|| m->input[i + 1] == '$' || m->input[i + 1] == '`' \
|| m->input[i + 1] == '\n')
{
m->content[m->j++] = m->input[i + 1];
return (2);
}
m->content[m->j++] = m->input[i];
return (1);
}
static int handle_single_quote_escape(t_escape_handler *m, int i)
{
if (m->input[i + 1] == '\'')
{
m->content[m->j++] = '\'';
return (2);
}
m->content[m->j++] = m->input[i];
return (1);
}
static int handle_escapes(t_escape_handler *mini_data, char quote)
{
if (quote == '"')
return (handle_double_quote_escape(mini_data, mini_data->i));
else if (quote == '\'')
return (handle_single_quote_escape(mini_data, mini_data->i));
mini_data->content[mini_data->j++] = mini_data->input[mini_data->i + 1];
return (2);
}
char *extract_quoted_content(char *input, int start, \
int len, char quote_char)
{
char *content;
t_escape_handler mini_data;
content = malloc(sizeof(char) * (len + 1));
if (!content)
return (NULL);
mini_data = (t_escape_handler){input, content, start, 0};
while (mini_data.i < start + len)
{
if (input[mini_data.i] == '\\' && mini_data.i + 1 < start + len)
mini_data.i += handle_escapes(&mini_data, quote_char);
else
mini_data.content[mini_data.j++] = mini_data.input[mini_data.i++];
}
mini_data.content[mini_data.j] = '\0';
return (content);
}

View File

@ -0,0 +1,64 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* extract_token_len.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 00:28:00 by tordner #+# #+# */
/* Updated: 2025/06/03 00:28:37 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static int skip_whitespace(char *input, int *index)
{
while (input[*index] && (input[*index] == ' ' || input[*index] == '\t'))
(*index)++;
return (*index);
}
static int handle_quotes_in_token(char *input, int *index)
{
char quote;
quote = input[*index];
(*index)++;
while (input[*index] && input[*index] != quote)
(*index)++;
if (input[*index] == quote)
(*index)++;
return (0);
}
static int handle_normal_token(char *input, int *index)
{
while (input[*index] && !is_delimiter(input[*index]) && \
!is_special(input[*index]))
{
if (input[*index] == '\'' || input[*index] == '\"')
handle_quotes_in_token(input, index);
else
(*index)++;
}
return (*index);
}
int extract_token_len(char *input, int *index, int *start)
{
int token_len;
skip_whitespace(input, index);
*start = *index;
if (input[*index] == '\'' || input[*index] == '\"')
token_len = handle_quoted_token(input, index, start);
else if (is_special(input[*index]))
token_len = handle_special_token(input, index);
else
{
handle_normal_token(input, index);
token_len = *index - *start;
}
return (token_len);
}

View File

@ -0,0 +1,55 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* handle_quoted_count.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 00:36:34 by tordner #+# #+# */
/* Updated: 2025/06/03 00:36:43 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static int is_escaped_in_double_quote(char *str, int i)
{
if (str[i + 1] == '"' || str[i + 1] == '\\' || str[i + 1] == '$'
|| str[i + 1] == '`' || str[i + 1] == '\n')
return (1);
return (0);
}
static int is_escaped_in_single_quote(char *str, int i)
{
if (str[i + 1] == '\'')
return (1);
return (0);
}
void handle_quoted_count(char *str, int *i, char quote)
{
(*i)++;
while (str[*i])
{
if (str[*i] == '\\' && str[*i + 1])
{
if (quote == '"' && is_escaped_in_double_quote(str, *i))
{
(*i) += 2;
continue ;
}
if (quote == '\'' && is_escaped_in_single_quote(str, *i))
{
(*i) += 2;
continue ;
}
}
if (str[*i] == quote)
{
(*i)++;
break ;
}
(*i)++;
}
}

40
src/tokens/syntax.c Normal file
View File

@ -0,0 +1,40 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* syntax.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/25 17:40:53 by thorgal #+# #+# */
/* Updated: 2025/05/30 15:16:30 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_token_type classify_token(char *token)
{
if (ft_strcmp(token, "|") == 0)
return (TOKEN_PIPE);
if (ft_strcmp(token, ">") == 0)
return (TOKEN_REDIRECTION_OUT);
if (ft_strcmp(token, ">>") == 0)
return (TOKEN_APPEND);
if (ft_strcmp(token, "<") == 0)
return (TOKEN_REDIRECTION_IN);
if (ft_strcmp(token, "<<") == 0)
return (TOKEN_HEREDOC);
return (TOKEN_WORD);
}
int validate_syntax(char **tokens)
{
if (validate_pipes(tokens))
{
write(STDERR_FILENO, "Syntax error: unexpected pipe\n", 30);
return (1);
}
if (validate_redirections(tokens))
return (2);
return (0);
}

102
src/tokens/token_list.c Normal file
View File

@ -0,0 +1,102 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* token_list.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/06 18:11:25 by tordner #+# #+# */
/* Updated: 2025/04/23 03:06:49 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void free_cmd_node(t_cmd *cmd)
{
int i;
t_redirection *redir;
t_redirection *next_redir;
if (cmd->args)
{
i = 0;
while (cmd->args[i])
free(cmd->args[i++]);
free(cmd->args);
}
redir = cmd->redir;
while (redir)
{
next_redir = redir->next;
free(redir->file);
free(redir);
redir = next_redir;
}
}
t_cmd *create_command_node(void)
{
t_cmd *new_node;
new_node = malloc(sizeof(t_cmd));
if (!new_node)
return (NULL);
new_node->args = NULL;
new_node->redir = NULL;
new_node->next = NULL;
return (new_node);
}
t_redirection *create_redirection_node(int type, char *file)
{
t_redirection *node;
node = malloc(sizeof(t_redirection));
if (!node)
return (NULL);
node->type = type;
node->file = file;
node->next = NULL;
return (node);
}
int add_argument(t_cmd *cmd, char *arg)
{
int count;
char **new_args;
int i;
count = 0;
if (cmd->args)
while (cmd->args[count])
count++;
new_args = (char **)malloc(sizeof(char *) * (count + 2));
if (!new_args)
return (0);
i = -1;
while (++i < count)
new_args[i] = cmd->args[i];
new_args[count] = arg;
new_args[count + 1] = NULL;
free(cmd->args);
cmd->args = new_args;
return (1);
}
void add_redirection(t_cmd *cmd, t_redirection *redir)
{
t_redirection *last;
if (!cmd || !redir)
return ;
if (!cmd->redir)
cmd->redir = redir;
else
{
last = cmd->redir;
while (last->next)
last = last->next;
last->next = redir;
}
}

View File

@ -0,0 +1,65 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tokenize_command.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 00:05:01 by tordner #+# #+# */
/* Updated: 2025/06/03 00:05:13 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static char *process_token(char *token, t_shell *shell)
{
char *expanded;
expanded = NULL;
if (shell->single_quoted_token != 1)
{
expanded = expand_variables(token, shell);
free(token);
shell->single_quoted_token = -1;
return (expanded);
}
return (token);
}
static char **allocate_tokens(int count)
{
char **tokens;
tokens = malloc(sizeof(char *) * (count + 1));
if (!tokens)
return (NULL);
return (tokens);
}
char **tokenize_command(char *input, t_shell *shell)
{
char **tokens;
int count;
int i;
int index;
count = count_tokens(input);
tokens = allocate_tokens(count);
if (!tokens)
return (NULL);
i = 0;
index = 0;
while (i < count)
{
tokens[i] = extract_token(input, &index, shell);
if (!tokens[i])
return (free_tokens(tokens, i));
tokens[i] = process_token(tokens[i], shell);
i++;
}
tokens[i] = NULL;
if (check_quotes(input) == 1)
return (free_tokens(tokens, i));
return (tokens);
}

70
src/tokens/tokens.c Normal file
View File

@ -0,0 +1,70 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tokens.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/03/10 17:47:48 by thorgal #+# #+# */
/* Updated: 2025/06/03 02:42:27 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int is_delimiter(char c)
{
return (c == ' ' || c == '\t' || c == '\0');
}
int is_special(char c)
{
return (c == '|' || c == '<' || c == '>');
}
void skip_delimiters(char *str, int *i)
{
while (str[*i] && is_delimiter(str[*i]))
(*i)++;
}
static int handle_escape_in_quote(char *input, int *i, int *count, char quote)
{
if (quote == '"' && (input[*i + 1] == '"' || input[*i + 1] == '\\'
|| input[*i + 1] == '$' || input[*i + 1] == '`'
|| input[*i + 1] == '\n'))
{
*i += 2;
*count += 2;
return (1);
}
else if (quote == '\'' && input[*i + 1] == '\'')
{
*i += 2;
*count += 2;
return (1);
}
return (0);
}
int extract_quoted_token(char *input, int *index, char quote_char)
{
int count;
count = 0;
(*index)++;
while (input[*index])
{
if (input[*index] == '\\' && input[*index + 1] && \
handle_escape_in_quote(input, index, &count, quote_char))
continue ;
if (input[*index] == quote_char)
{
(*index)++;
return (0);
}
(*index)++;
count++;
}
return (1);
}

114
src/tokens/tokens_list2.c Normal file
View File

@ -0,0 +1,114 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tokens_list2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lfirmin <lfirmin@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/23 02:48:30 by lfirmin #+# #+# */
/* Updated: 2025/04/23 03:17:37 by lfirmin ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int handle_redirection(t_cmd *cmd, char **tokens, int *i)
{
t_redirection *redir;
int type;
int token_type;
token_type = classify_token(tokens[*i]);
if (!tokens[*i + 1])
return (0);
if (token_type == TOKEN_REDIRECTION_IN)
type = 1;
else if (token_type == TOKEN_REDIRECTION_OUT)
type = 2;
else if (token_type == TOKEN_APPEND)
type = 3;
else if (token_type == TOKEN_HEREDOC)
type = 4;
else
type = 0;
redir = create_redirection_node(type, ft_strdup(tokens[*i + 1]));
if (!redir)
return (0);
add_redirection(cmd, redir);
(*i)++;
return (1);
}
t_cmd *init_cmd_segment(t_cmd **cmd_list, char **tokens, int *i)
{
t_cmd *new;
t_cmd *tmp;
if (classify_token(tokens[*i]) == TOKEN_PIPE)
(*i)++;
new = create_command_node();
if (!new)
return (NULL);
if (!*cmd_list)
*cmd_list = new;
else
{
tmp = *cmd_list;
while (tmp->next)
tmp = tmp->next;
tmp->next = new;
}
return (new);
}
int add_token_to_cmd(t_cmd *current, char **tokens, int *i)
{
if (classify_token(tokens[*i]) == TOKEN_WORD)
{
if (!add_argument(current, ft_strdup(tokens[*i])))
return (0);
}
else if (is_redirection(tokens[*i]))
{
if (!handle_redirection(current, tokens, i))
return (0);
}
return (1);
}
t_cmd *parse_tokens_to_list(char **tokens)
{
t_cmd *cmd_list;
t_cmd *current;
int i;
cmd_list = NULL;
current = NULL;
i = 0;
while (tokens[i])
{
if (!current || classify_token(tokens[i]) == TOKEN_PIPE)
{
current = init_cmd_segment(&cmd_list, tokens, &i);
if (!current)
return (free_cmd_list(cmd_list), NULL);
}
if (!add_token_to_cmd(current, tokens, &i))
return (free_cmd_list(cmd_list), NULL);
i++;
}
return (cmd_list);
}
void free_cmd_list(t_cmd *cmd_list)
{
t_cmd *tmp;
while (cmd_list)
{
tmp = cmd_list->next;
free_cmd_node(cmd_list);
free(cmd_list);
cmd_list = tmp;
}
}

73
src/tokens/tokens_utils.c Normal file
View File

@ -0,0 +1,73 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tokens_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/04 17:21:22 by thorgal #+# #+# */
/* Updated: 2025/06/03 00:37:50 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void handle_special_count(char *str, int *i)
{
if ((str[*i] == '<' && str[*i + 1] == '<')
|| (str[*i] == '>' && str[*i + 1] == '>'))
(*i) += 2;
else
(*i)++;
}
int count_tokens(char *str)
{
int i;
int count;
i = 0;
count = 0;
if (!str)
return (0);
while (str[i])
{
skip_delimiters(str, &i);
if (!str[i])
break ;
count++;
if (str[i] == '\'' || str[i] == '\"')
handle_quoted_count(str, &i, str[i]);
else if (is_special(str[i]))
handle_special_count(str, &i);
else
handle_word_count(str, &i);
}
return (count);
}
int handle_quoted_token(char *input, int *index, int *start)
{
*start = *index + 1;
if (extract_quoted_token(input, index, input[*index]) == 1)
return (-1);
return ((*index - 1) - *start);
}
int handle_special_token(char *input, int *index)
{
int token_len;
if ((input[*index] == '<' && input[*index + 1] == '<')
|| (input[*index] == '>' && input[*index + 1] == '>'))
{
(*index) += 2;
token_len = 2;
}
else
{
(*index)++;
token_len = 1;
}
return (token_len);
}

View File

@ -0,0 +1,99 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tokens_utils2.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/23 03:25:24 by lfirmin #+# #+# */
/* Updated: 2025/06/03 00:34:07 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static char *extract_simple_token(char *input, int start, int token_len)
{
char *token;
token = malloc(sizeof(char) * (token_len + 1));
if (!token)
return (NULL);
ft_strlcpy(token, input + start, token_len + 1);
return (token);
}
char *extract_token(char *input, int *index, t_shell *shell)
{
char *token;
int start;
int token_len;
int temp_index;
char quote_char;
shell->single_quoted_token = -1;
temp_index = *index;
while (input[temp_index] && (input[temp_index] == ' ' \
|| input[temp_index] == '\t'))
temp_index++;
token_len = extract_token_len(input, index, &start);
if (token_len == -1)
return (NULL);
if (input[temp_index] == '\'' || input[temp_index] == '\"')
{
if (input[temp_index] == '\'')
shell->single_quoted_token = 1;
quote_char = input[temp_index];
token = extract_quoted_content(input, start, token_len, quote_char);
}
else
token = extract_simple_token(input, start, token_len);
return (token);
}
int check_quotes(char *input)
{
bool in_squote;
bool in_dquote;
int i;
in_squote = false;
in_dquote = false;
i = 0;
while (input[i])
{
if (input[i] == '\\' && input[i + 1])
{
i += 2;
continue ;
}
if (input[i] == '\'' && !in_dquote)
in_squote = !in_squote;
else if (input[i] == '"' && !in_squote)
in_dquote = !in_dquote;
i++;
}
if (in_squote || in_dquote)
return (1);
return (0);
}
void handle_word_count(char *str, int *i)
{
char quote;
while (str[*i] && !is_delimiter(str[*i]) && !is_special(str[*i]))
{
if (str[*i] == '\'' || str[*i] == '\"')
{
quote = str[*i];
(*i)++;
while (str[*i] && str[*i] != quote)
(*i)++;
if (str[*i] == quote)
(*i)++;
}
else
(*i)++;
}
}

24
src/utils/free.c Normal file
View File

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* free.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/11/21 15:38:19 by lfirmin #+# #+# */
/* Updated: 2025/04/18 13:56:26 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void *free_tokens(char **tokens, int count)
{
int i;
i = 0;
while (i < count)
free(tokens[i++]);
free(tokens);
return (NULL);
}

68
src/utils/get_env_value.c Normal file
View File

@ -0,0 +1,68 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_env_value.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/02 23:59:04 by tordner #+# #+# */
/* Updated: 2025/06/03 00:02:52 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static char *handle_special_vars(char *var_name, t_shell *shell)
{
if (!var_name || !shell)
return (NULL);
if (var_name[0] == '$')
var_name++;
if (var_name[0] == '?')
{
printf("%d", shell->exit_status);
return (NULL);
}
return (var_name);
}
static int get_var_name_length(char *var_name)
{
int len;
len = 0;
while (var_name[len] && (ft_isalnum(var_name[len]) || var_name[len] == '_'))
len++;
return (len);
}
static char *search_env(char *var_name, int var_len, char **env)
{
int i;
i = 0;
while (env && env[i])
{
if (ft_strncmp(env[i], var_name, var_len) \
== 0 && env[i][var_len] == '=')
return (env[i] + var_len + 1);
i++;
}
return (NULL);
}
char *get_env_value(char *var_name, t_shell *shell)
{
char *clean_var_name;
int var_len;
if (!var_name || !shell || !shell->env)
return (NULL);
clean_var_name = handle_special_vars(var_name, shell);
if (!clean_var_name)
return (NULL);
var_len = get_var_name_length(clean_var_name);
if (var_len == 0)
return (NULL);
return (search_env(clean_var_name, var_len, shell->env));
}

96
src/utils/utils.c Normal file
View File

@ -0,0 +1,96 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tordner <tordner@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/04 15:49:05 by thorgal #+# #+# */
/* Updated: 2025/06/02 23:59:34 by tordner ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *get_current_dir_name(void)
{
char pwd[PATH_MAX];
char *dir;
if (getcwd(pwd, PATH_MAX) == NULL)
return (strdup("minishell"));
dir = strrchr(pwd, '/');
if (!dir || !dir[1])
return (strdup(pwd));
return (strdup(dir + 1));
}
char *ft_get_env_var(char **env, char *var)
{
int i;
int len;
i = 0;
len = ft_strlen(var);
while (env[i])
{
if (ft_strncmp(env[i], var, len) == 0 && env[i][len] == '=')
return (&env[i][len + 1]);
i++;
}
return (NULL);
}
char **copy_env(char **envp)
{
char **env;
int i;
i = 0;
while (envp[i])
i++;
env = malloc(sizeof(char *) * (i + 1));
if (!env)
return (NULL);
i = 0;
while (envp[i])
{
env[i] = strdup(envp[i]);
if (!env[i])
{
while (--i >= 0)
free(env[i]);
free(env);
return (NULL);
}
i++;
}
env[i] = NULL;
return (env);
}
char **add_env_var(char **env, char *new_var)
{
char **new_env;
int i;
int count;
count = 0;
while (env[count])
count++;
new_env = malloc(sizeof(char *) * (count + 2));
if (!new_env)
return (NULL);
i = 0;
while (i < count)
{
new_env[i] = env[i];
i++;
}
new_env[i] = ft_strdup(new_var);
if (!new_env[i])
return (free(new_env), NULL);
new_env[i + 1] = NULL;
free(env);
return (new_env);
}