intra to gitea
This commit is contained in:
commit
03b080ed92
|
|
@ -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"
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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]);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
@ -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, "e_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
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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("➜ ❯ "));
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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)++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue