first commit

This commit is contained in:
Victor Vobis 2025-06-04 14:58:04 +02:00
commit 814bac23a7
119 changed files with 7545 additions and 0 deletions

112
Makefile Normal file
View File

@ -0,0 +1,112 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: anarama <anarama@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/07/05 12:24:47 by victor #+# #+# #
# Updated: 2025/06/02 18:50:03 by victor ### ########.fr #
# #
# **************************************************************************** #
# COMPILER AND FLAGS
CC := cc
CFLAGS := -Werror -Wall -Wextra
# DIRECTORIES
SRCDIR := src
ASTDIR := ast
BULDINDIR := builtin
OBJDIR := obj
TOKENDIR := tokenizer
BINDIR := bin
SRC := src/commands.c src/environment_variables.c \
src/handle_signals.c src/input.c src/list_memory.c \
src/list.c src/minishell.c \
src/path_utils.c src/termios.c \
src/utils.c src/utils2.c src/utils3.c \
src/environment_variables_manip.c \
src/wildcards.c src/execution.c \
src/non_interactive.c src/wildcards_hanlde_match.c \
src/wildcards_helper.c
PROMPT_SRC := prompt/prompt_input.c prompt/prompt_string_management.c \
prompt/prompt_utils.c prompt/tab_completion.c \
prompt/escape_sequences.c prompt/arrowkeys.c \
prompt/prompt_print.c prompt/tab_get_word.c \
prompt/non_blocking_mode.c prompt/prompt_handle_chars.c \
AST_SRC := ast/ast_utils.c \
ast/handle_command.c ast/handle_fds.c \
ast/parse_tokens.c ast/parser.c \
ast/syntax_check.c ast/handle_redirs.c \
ast/handle_heredoc.c ast/parse_tokens_helper.c \
ast/syntax_check_helper.c ast/buildin.c
TOKEN_SRC := tokenizer/check_special_symbol.c \
tokenizer/create_token_double_special_symbol.c \
tokenizer/create_token_single_special_symbol.c \
tokenizer/create_token_word.c \
tokenizer/create_token.c \
tokenizer/tokenizer.c \
tokenizer/subshell.c tokenizer/evaluate_input.c \
tokenizer/input_skip_patterns.c \
tokenizer/token_heredoc.c \
tokenizer/tokenizer_heredoc_helper.c tokenizer/evaluate_input_helper.c \
tokenizer/evaluate_input_helper2.c
BUILDIN_SRC := builtin/ft_echo.c builtin/ft_env.c \
builtin/ft_pwd.c builtin/ft_unset.c \
builtin/ft_export.c builtin/ft_exit.c \
builtin/ft_cd.c
# OBJECT FILES
OBJ := $(SRC:%.c=$(OBJDIR)/%.o)
AST_OBJ := $(AST_SRC:ast/%.c=$(OBJDIR)/ast/%.o)
BUILDIN_OBJ := $(BUILDIN_SRC:builtin/%.c=$(OBJDIR)/builtin/%.o)
PROMPT_OBJ := $(PROMPT_SRC:prompt/%.c=$(OBJDIR)/prompt/%.o)
TOKEN_OBJ := $(TOKEN_SRC:tokenizer/%.c=$(OBJDIR)/tokenizer/%.o)
NAME := $(BINDIR)/minishell
LIBS := libft/libft.a
# Create object directory if none exists
$(shell mkdir -p $(BINDIR) $(OBJDIR) $(OBJDIR)/ast $(OBJDIR)/src $(OBJDIR)/tokenizer $(OBJDIR)/builtin $(OBJDIR)/prompt)
all: $(NAME)
$(NAME): $(OBJ) $(AST_OBJ) $(TOKEN_OBJ) $(BUILDIN_OBJ) $(PROMPT_OBJ) $(LIBS) minishell.h
$(CC) -static $(CFLAGS) $(OBJ) $(AST_OBJ) $(TOKEN_OBJ) $(BUILDIN_OBJ) $(PROMPT_OBJ) $(LIBS) -o $(NAME)
test: $(TEST_OBJ) $(AST_OBJ) $(TOKEN_OBJ) $(LIBS) minishell.h
$(CC) $(CFLAGS) $(TEST_OBJ) $(AST_OBJ) $(TOKEN_OBJ) $(LIBS) -o $(TEST_NAME)
clean:
make clean -C libft
rm -rf $(OBJ) $(AST_OBJ) $(TEST_OBJ) $(TOKEN_OBJ) $(PROMPT_OBJ) $(BUILDIN_OBJ)
fclean: clean
rm -f $(NAME) $(TEST_NAME)
make fclean -C libft
re: fclean all
$(OBJDIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/builtin/%.o: builtin/%.c
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/prompt/%.o: prompt/%.c
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/ast/%.o: ast/%.c
$(CC) $(CFLAGS) -c $< -o $@
$(OBJDIR)/tokenizer/%.o: tokenizer/%.c
$(CC) $(CFLAGS) -c $< -o $@
$(LIBS):
make bonus -C libft

62
ast/ast_utils.c Normal file
View File

@ -0,0 +1,62 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ast_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/20 17:43:20 by anarama #+# #+# */
/* Updated: 2024/08/16 11:36:37 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
int get_tokens_len(t_token *tokens)
{
int i;
i = 0;
while (tokens[i].token_type != TOKEN_EOL)
{
i++;
}
return (i);
}
char **copy_args(t_ast *node, char **src)
{
char **temp;
node->args = ft_calloc(get_split_size((const char **)src) \
+ 1, sizeof(char *));
if (!node->args)
{
free(node);
perror("calloc in copy args");
lst_memory(NULL, NULL, CLEAN);
}
lst_memory(node->args, free_split, ADD);
temp = node->args;
while (*src)
{
*node->args = ft_strdup(*src);
if (!*node->args)
{
free(node);
perror("strdup in copy args");
lst_memory(NULL, NULL, CLEAN);
}
src++;
node->args++;
}
return (temp);
}
int is_redirection(t_token_type token_type)
{
return (token_type == TOKEN_REDIRECT_IN
|| token_type == TOKEN_REDIRECT_OUT
|| token_type == TOKEN_REDIRECT_APPEND
|| token_type == TOKEN_HEREDOC);
}

28
ast/buildin.c Normal file
View File

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* buildin.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/26 12:39:13 by vvobis #+# #+# */
/* Updated: 2024/08/26 12:39:22 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
bool is_buildin(t_ast *node)
{
if (!node->args || !*node->args)
return (false);
if (ft_memcmp(node->args[0], "echo", ft_strlen("echo") + 1) == 0
|| ft_memcmp(node->args[0], "env", ft_strlen("env") + 1) == 0
|| ft_memcmp(node->args[0], "cd", ft_strlen("cd") + 1) == 0
|| ft_memcmp(node->args[0], "pwd", ft_strlen("pwd") + 1) == 0
|| ft_memcmp(node->args[0], "unset", ft_strlen("unset") + 1) == 0
|| ft_memcmp(node->args[0], "export", ft_strlen("export") + 1) == 0
|| ft_memcmp(node->args[0], "exit", ft_strlen("exit") + 1) == 0)
return (true);
return (false);
}

126
ast/handle_command.c Normal file
View File

@ -0,0 +1,126 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* handle_command.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/25 18:14:10 by anarama #+# #+# */
/* Updated: 2024/08/27 15:22:42 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
bool buildin_apply_pipe(t_ast *node, int32_t *exit_status)
{
if (node->type == NODE_PIPE)
{
ft_dup2(node->pipefd[1], STDOUT_FILENO, "dup2 in buildin_execute");
ft_close(node->pipefd[1], "close in buildin_execute");
}
if (node->has_redir_in || node->has_redir_out)
{
return (handle_fds_child_proccess(node, exit_status));
}
return (true);
}
void execute_parent(t_ast *command, int32_t *exit_status, pid_t pid)
{
command->cpid = pid;
if (command->type == NODE_PIPE)
handle_pipe_in_parent(command);
if (command->has_redir_in || command->has_redir_out)
handle_fds_parent_proccess(command, exit_status);
}
void execute_command( t_ast *command, \
int32_t *exit_status, \
int std[2], \
char *path)
{
pid_t pid;
char **env;
bool should_execute;
should_execute = true;
ft_fork(&pid, "execute command");
if (pid == 0)
{
env = env_static(NULL);
if (command->type == NODE_PIPE)
handle_pipe_in_child(command);
if (command->has_redir_in || command->has_redir_out)
should_execute = handle_fds_child_proccess(command, exit_status);
if (is_buildin(command) && should_execute)
buildin_execute(command, (const char **)env, exit_status);
else if (path && should_execute)
{
execve(path, command->args, (char **)env);
perror("execve");
}
return (lst_memory(NULL, NULL, END), \
close_fds(std), exit(*exit_status));
}
else
execute_parent(command, exit_status, pid);
}
bool buildin_execute( t_ast *node, \
const char **environment, \
int *e)
{
if (!node->args || !*node->args)
return (false);
if (ft_memcmp(node->args[0], "echo", ft_strlen(node->args[0]) + 1) == 0)
return (ft_echo(node->args, e), 1);
else if (ft_memcmp(node->args[0], "env", ft_strlen(node->args[0]) + 1) == 0)
return (ft_env(environment, e), 1);
else if (ft_memcmp(node->args[0], "cd", ft_strlen(node->args[0]) + 1) == 0)
return (ft_cd(environment, \
(const char **)node->args, e), 1);
else if (ft_memcmp(node->args[0], "pwd", ft_strlen(node->args[0]) + 1) == 0)
return (ft_pwd(environment, e), 1);
else if (ft_memcmp(node->args[0], "unset", \
ft_strlen(node->args[0]) + 1) == 0)
return (ft_unset((char **)environment, \
(const char **)node->args, e), 1);
else if (ft_memcmp(node->args[0], "export", \
ft_strlen(node->args[0]) + 1) == 0)
ft_export((const char **)node->args, e);
else if (ft_memcmp(node->args[0], "exit", \
ft_strlen(node->args[0]) + 1) == 0)
return (ft_exit(node, e), *e = 1);
return (0);
}
void handle_command( t_ast *current, \
const char **env, \
int *exit_status, \
int std[2])
{
char *path;
if (current->type == NODE_PIPE)
ft_pipe(current->pipefd, "in handle_command");
check_and_expand_wildcards(&current->args);
if (is_buildin(current) && current->type != NODE_PIPE \
&& current->was_pipe == false)
{
if (buildin_apply_pipe(current, exit_status))
buildin_execute(current, env, exit_status);
}
else
{
path = NULL;
if (current->args && current->args[0] && current->args[0][0])
{
if (!is_buildin(current))
path = find_absolute_path(\
environment_variable_value_get("PATH", \
env), current->args[0], exit_status);
}
execute_command(current, exit_status, std, path);
}
}

83
ast/handle_fds.c Normal file
View File

@ -0,0 +1,83 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* handle_fds.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: andrejarama <andrejarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/25 18:17:10 by anarama #+# #+# */
/* Updated: 2024/08/27 14:14:23 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
bool fd_out(t_ast *command, int *exit_status)
{
if (command->has_redir_out && command->path_file_out)
{
if (command->fd_out > 0)
{
ft_dup2(command->fd_out, STDOUT_FILENO, "in hanlde_fds_child");
}
else
return (*exit_status = 1, false);
}
return (*exit_status = 0, true);
}
bool handle_fds_child_proccess(t_ast *command, int32_t *exit_status)
{
if (command->has_redir_in && command->path_file_in != 0)
{
if (access(command->path_file_in, F_OK) == 0)
{
ft_open(&command->fd_in, command->path_file_in, O_RDONLY, 0644);
if (command->is_heredoc == true)
{
command->is_heredoc = false;
if (unlink(command->path_file_in))
perror("unlink");
ft_free(&command->path_file_in);
}
ft_dup2(command->fd_in, STDIN_FILENO, "in hanlde_fds_child");
}
else
return (p_stderr(2, "minishell: %s: No such file or directory\n", \
command->path_file_in), command->type = NODE_INVALID, \
*exit_status = 1, false);
}
if (command->has_redir_out && command->path_file_out)
return (fd_out(command, exit_status));
return (*exit_status = 0, true);
}
void handle_fds_parent_proccess(t_ast *command, int32_t *exit_status)
{
if (command->has_redir_in)
{
if (command->fd_in == -1 && command->path_file_in == 0)
*exit_status = 1;
if (command->is_heredoc == true && command->path_file_in)
ft_free(&command->path_file_in);
}
if (command->has_redir_out && command->path_file_out && command->fd_out > 0)
{
ft_close(command->fd_out, "in hanlde_fds_parents");
command->fd_out = -1;
}
}
void handle_pipe_in_child(t_ast *command)
{
ft_dup2(command->pipefd[1], STDOUT_FILENO, "dup2 in pipe_child");
ft_close(command->pipefd[0], "close in pipe_child");
ft_close(command->pipefd[1], "close in pipe_child");
}
void handle_pipe_in_parent(t_ast *command)
{
ft_dup2(command->pipefd[0], STDIN_FILENO, "dup2 in pipe_parent");
ft_close(command->pipefd[1], "close in pipe_parent");
ft_close(command->pipefd[0], "close in pipe_parent");
}

85
ast/handle_heredoc.c Normal file
View File

@ -0,0 +1,85 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* handle_heredoc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/21 11:15:25 by vvobis #+# #+# */
/* Updated: 2025/02/15 14:59:42 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void remove_quotes(char *s)
{
uint i;
i = 0;
if (!s)
return ;
while (s[i])
{
if (s[i] == '\'' || s[i] == '\"')
{
ft_memmove(&s[i], &s[i] + 1, ft_strlen(&s[i]));
}
else
i++;
}
}
void print_value(char *value, int fd)
{
if (value && value[ft_strlen(value) - 1] == '\n')
value[ft_strlen(value) - (ft_strlen(value) > 0)] = 0;
ft_putendl_fd(value, fd);
}
bool has_been_done_helper(t_token *token, char *value, \
uint value_length, int fd)
{
char *token_value;
bool has_been_done;
has_been_done = false;
if (token->token_value)
{
token_value = token->token_value;
token->token_type = TOKEN_DONE;
while (token_value && *token_value)
{
if (*token_value++ == '\n')
{
if (ft_strncmp(token_value, value, value_length) == 0 \
&& (*(token_value + value_length) == '\n' \
|| *(token_value + value_length) == '\0'))
{
*token_value = 0;
has_been_done = true;
}
}
}
}
return (print_value(token->token_value, fd), has_been_done);
}
bool heredoc_has_been_done(t_token *token, char *value, int fd)
{
uint32_t value_length;
uint32_t i;
i = 0;
while (token[i].token_type != TOKEN_NEWLINE \
&& token[i].token_type != TOKEN_EOL)
i++;
while ((token[i].token_type == TOKEN_NEWLINE \
|| token[i].token_type == TOKEN_DONE) \
&& token[i].token_type != TOKEN_EOL)
i++;
value_length = ft_strlen(value);
if (token[i].token_type == TOKEN_EOL)
return (false);
return (has_been_done_helper(&token[i], value, value_length, fd));
}

144
ast/handle_redirs.c Normal file
View File

@ -0,0 +1,144 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* handle_redirs.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: andrejarama <andrejarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/22 11:56:47 by anarama #+# #+# */
/* Updated: 2025/02/15 14:59:25 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
#include <fcntl.h>
bool handle_temp(t_token *token)
{
char *was_variable;
int32_t i;
char **temp;
if (token->token_value && token->token_value[0] == '$')
was_variable = token->token_value;
else
was_variable = NULL;
temp = (char **)(char *[]){token->token_value, NULL};
evaluate_input(&temp, &i, 0);
token->token_value = temp[0];
if (was_variable)
if (temp[0][0] == 0)
return (p_stderr(2, \
"minishell: %s: ambiguos redirect\n", was_variable), false);
return (true);
}
void handle_redir_in(t_ast *branch, \
t_token *token, \
t_token *token_next)
{
if (token->token_type == TOKEN_REDIRECT_IN)
{
if (branch->path_file_in == 0 \
|| ft_strncmp(token_next->token_value, branch->path_file_in, \
ft_strlen(branch->path_file_in)) != 0)
{
if (handle_temp(token_next))
{
if (branch->has_redir_in)
ft_close(branch->fd_in, "in hanlde_redir_in");
branch->path_file_in = token_next->token_value;
ft_open(&branch->fd_in, branch->path_file_in, O_RDONLY, 0);
branch->has_redir_in = true;
if (branch->fd_in == -1)
branch->type = NODE_INVALID;
}
else
branch->type = NODE_INVALID;
}
token->token_type = TOKEN_DONE;
token_next->token_type = TOKEN_DONE;
}
}
void handle_redir_out( t_ast *branch, \
t_token *token, \
t_token *token_next)
{
if (token->token_type == TOKEN_REDIRECT_OUT)
{
if (branch->path_file_out == 0 \
|| ft_strncmp(token_next->token_value, branch->path_file_out, \
ft_strlen(branch->path_file_out)) != 0)
{
if (handle_temp(token_next))
{
if (branch->has_redir_out == true)
ft_close(branch->fd_out, "in branch redir_out");
branch->path_file_out = token_next->token_value;
ft_open(&branch->fd_out, branch->path_file_out, \
O_WRONLY | O_CREAT | O_TRUNC, 0644);
branch->has_redir_out = true;
if (branch->fd_out == -1)
branch->type = NODE_INVALID;
}
else
branch->type = NODE_INVALID;
}
token->token_type = TOKEN_DONE;
token_next->token_type = TOKEN_DONE;
}
}
void handle_redir_append(t_ast *branch, \
t_token *token, \
t_token *token_next)
{
if (token->token_type == TOKEN_REDIRECT_APPEND)
{
if (branch->path_file_out == 0 \
|| ft_strncmp(token_next->token_value, branch->path_file_out, \
ft_strlen(branch->path_file_out)) != 0)
{
if (handle_temp(token_next))
{
branch->path_file_out = token_next->token_value;
if (branch->has_redir_out == true)
ft_close(branch->fd_out, "in branch redir_out");
ft_open(&branch->fd_out, branch->path_file_out, \
O_WRONLY | O_CREAT | O_APPEND, 0644);
if (branch->fd_out == -1)
branch->type = NODE_INVALID;
branch->has_redir_out = true;
}
else
branch->type = NODE_INVALID;
}
token->token_type = TOKEN_DONE;
token_next->token_type = TOKEN_DONE;
}
}
void handle_redir_heredoc( t_ast *branch, \
t_token *token, \
uint8_t token_id)
{
if (token->token_type == TOKEN_HEREDOC)
{
branch->path_file_in = ft_strdup((char []){'.', '/', '.', 't', \
'm', 'p', token_id + 33, 0});
branch->is_heredoc = true;
ft_open(&branch->fd_in, branch->path_file_in, O_CREAT | O_WRONLY, 0644);
remove_quotes(token[1].token_value);
if (!heredoc_has_been_done(token, \
token[1].token_value, branch->fd_in) && isatty(0))
{
token_heredoc_get(token, token[1].token_value);
print_value(token->token_value, branch->fd_in);
}
ft_close(branch->fd_in, "fd_in in heredoc");
branch->has_redir_in = true;
token[0].token_type = TOKEN_DONE;
token[1].token_type = TOKEN_DONE;
}
}

125
ast/parse_tokens.c Normal file
View File

@ -0,0 +1,125 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parse_tokens.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/20 17:46:26 by anarama #+# #+# */
/* Updated: 2024/08/27 15:04:45 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
static void parse_branch(t_token *tokens, t_ast *branch)
{
int capacity;
int count;
uint32_t i;
count = 0;
capacity = INITIAL_TOKEN_CAPACITY;
branch->args = ft_calloc(capacity + 1, sizeof(char *));
if (!branch->args)
return (perror("calloc in parse tokens"), \
lst_memory(NULL, NULL, CLEAN));
i = -1;
while (!is_delimiter_token(&tokens[++i]))
{
if (tokens[i].token_type != TOKEN_DONE)
{
fill_args(&branch->args, count++, tokens[i].token_value, &capacity);
tokens[i].token_type = TOKEN_DONE;
}
}
if (tokens[i].token_type == TOKEN_EOL)
return ;
if (branch->type != NODE_INVALID)
branch->type = (t_node_type)tokens[i].token_type;
tokens[i].token_type = TOKEN_DONE;
}
static t_ast collect_redirection(t_token *token, \
int has_syntax_error)
{
uint32_t i;
t_ast branch;
i = 0;
branch = (t_ast){0};
branch.fd_in = STDIN_FILENO;
branch.fd_out = STDOUT_FILENO;
while (!is_delimiter_token(&token[i]) && branch.type != NODE_INVALID)
{
if (token[i + 1].token_type == TOKEN_SEMICOLON)
token[i + 1].token_type = TOKEN_NEWLINE;
if (token[i + 1].token_type == TOKEN_WORD)
{
if (!has_syntax_error)
{
handle_redir_in(&branch, &token[i], &token[i + 1]);
handle_redir_out(&branch, &token[i], &token[i + 1]);
handle_redir_append(&branch, &token[i], &token[i + 1]);
}
}
if (has_syntax_error == 0)
handle_redir_heredoc(&branch, &token[i], i);
i++;
}
return (branch);
}
void check_syntax_errors(t_token *token, int *error_catched)
{
int i;
i = 0;
while (token[i].token_type != TOKEN_NEWLINE \
&& token[i].token_type != TOKEN_EOL \
&& token[i].token_type != TOKEN_SEMICOLON \
&& *error_catched == 0)
{
if (token[i].token_type == TOKEN_REDIRECT_IN \
|| token[i].token_type == TOKEN_REDIRECT_OUT \
|| token[i].token_type == TOKEN_REDIRECT_APPEND \
|| token[i].token_type == TOKEN_HEREDOC)
check_valid_redir(token, i, error_catched);
else if (token[i].token_type == TOKEN_PIPE)
check_valid_pipe(token, i, error_catched);
else if (token[i].token_type == TOKEN_AND \
|| token[i].token_type == TOKEN_OR)
check_valid_logical_operator(token, i, error_catched);
i++;
}
}
t_ast *parse_tokens( t_token *tokens, \
int32_t *exit_status)
{
t_ast *tree;
int i;
uint32_t tree_count;
int has_syntax_error;
if (!tokens)
return (NULL);
i = 0;
tree_count = determine_trees(tokens);
tree = ft_calloc(tree_count + 1, sizeof(t_ast));
lst_memory(tree, tree_destroy, ADD);
tree[tree_count].type = NODE_END;
has_syntax_error = false;
while (tree[i].type != NODE_END && !has_syntax_error)
{
check_syntax_errors(tokens, &has_syntax_error);
tree[i] = collect_redirection(tokens, has_syntax_error);
if (tree[i].type == NODE_INVALID)
*exit_status = 1;
parse_branch(tokens, &tree[i]);
i++;
}
if (has_syntax_error != false)
return (*exit_status = 2, lst_memory(tree, NULL, FREE), NULL);
return (tree);
}

67
ast/parse_tokens_helper.c Normal file
View File

@ -0,0 +1,67 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parse_tokens_helper.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/23 14:36:35 by vvobis #+# #+# */
/* Updated: 2024/08/26 14:22:12 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
uint32_t determine_trees(t_token *tokens)
{
uint32_t tree_count;
uint32_t i;
bool has_heredoc;
i = 0;
tree_count = 1;
has_heredoc = false;
while (tokens[i].token_type != TOKEN_EOL)
{
if (tokens[i].token_type == TOKEN_HEREDOC)
has_heredoc = true;
if (is_delimiter_token(&tokens[i]) || \
(tokens[i].token_type == TOKEN_NEWLINE && has_heredoc == true))
{
has_heredoc = false;
tree_count++;
}
i++;
}
return (tree_count);
}
void tree_destroy(void *tree_ptr)
{
uint32_t i;
t_ast *tree;
i = 0;
tree = (t_ast *)tree_ptr;
while (tree && tree[i].type != NODE_END)
{
if (tree[i].has_redir_out == true)
ft_close(tree[i].fd_out, "fd_out in tree_destroy");
if (tree[i].is_heredoc)
ft_free(&tree->path_file_in);
if (tree[i].args)
ft_free(&tree[i].args);
i++;
}
ft_free(&tree);
}
bool is_delimiter_token(t_token *token)
{
return (token->token_type == TOKEN_EOL \
|| token->token_type == TOKEN_AND \
|| token->token_type == TOKEN_OR \
|| token->token_type == TOKEN_NEWLINE \
|| token->token_type == TOKEN_PIPE \
|| token->token_type == TOKEN_SEMICOLON);
}

44
ast/parser.c Normal file
View File

@ -0,0 +1,44 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/17 13:17:47 by anarama #+# #+# */
/* Updated: 2024/08/10 22:20:35 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void **custom_realloc(void ***args, int old_capacity, int new_capacity)
{
void **new_args;
new_args = ft_calloc(new_capacity + 1, sizeof(void *));
if (!new_args)
{
perror("Malloc failed while reallocing memory");
lst_memory(NULL, NULL, CLEAN);
}
ft_memcpy(new_args, *args, old_capacity * sizeof(void *));
free(*args);
return (new_args);
}
void fill_args(char ***args, int count, char *token_value, int *capacity)
{
if (count >= *capacity)
{
*args = (char **)custom_realloc((void ***)args,
*capacity, *capacity * 2);
if (!args)
{
perror("calloc in parse tokens");
lst_memory(NULL, NULL, CLEAN);
}
*capacity *= 2;
}
(*args)[count] = token_value;
}

117
ast/syntax_check.c Normal file
View File

@ -0,0 +1,117 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* syntax_check.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/04 14:19:12 by anarama #+# #+# */
/* Updated: 2024/08/26 14:18:42 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void check_valid_redir_helper(t_token *token, int index, int *error_catched)
{
if (token[index + 1].token_type == TOKEN_AND
|| token[index + 1].token_type == TOKEN_OR)
{
print_error_logical_operator(token[index + 1].token_type);
*error_catched = 1;
}
else if (token[index + 1].token_type == TOKEN_PIPE)
return (print_error_pipe(), *error_catched = 1, (void)0);
else if (token[index + 1].token_type == TOKEN_REDIRECT_IN \
|| token[index + 1].token_type == TOKEN_REDIRECT_OUT \
|| token[index + 1].token_type == TOKEN_REDIRECT_APPEND \
|| token[index + 1].token_type == TOKEN_HEREDOC)
{
print_error_redir(token[index + 1].token_type);
*error_catched = 1;
}
}
void check_valid_redir(t_token *token, int index, int *error_catched)
{
if (token[index + 1].token_type == TOKEN_EOL \
|| token[index + 1].token_type == TOKEN_NEWLINE \
|| token[index + 1].token_type == 0 \
|| (token[index + 1].token_type == TOKEN_WORD \
&& token[index + 1].token_value == NULL))
{
ft_putendl_fd(\
"minishell: syntax error near unexpected token `newline'", 2);
*error_catched = 1;
}
check_valid_redir_helper(token, index, error_catched);
}
void check_valid_pipe(t_token *token, int index, int *error_catched)
{
if (index == 0 || token[index + 1].token_type == 0 \
|| token[index + 1].token_type == TOKEN_EOL
|| (token[index + 1].token_type == TOKEN_WORD \
&& token[index + 1].token_value == NULL))
{
print_error_pipe();
*error_catched = 1;
}
else if (token[index + 1].token_type == TOKEN_AND
|| token[index + 1].token_type == TOKEN_OR)
{
print_error_logical_operator(token[index + 1].token_type);
*error_catched = 1;
}
else if (token[index + 1].token_type == TOKEN_PIPE)
{
print_error_pipe();
*error_catched = 1;
}
}
void check_valid_logical_operator( t_token *token, \
int index, \
int *error_catched)
{
if (index == 0 || token[index + 1].token_type == TOKEN_EOL \
|| token[index + 1].token_type == TOKEN_NEWLINE \
|| token[index + 1].token_type == 0)
{
print_error_logical_operator(token[index].token_type);
*error_catched = 1;
}
else if (token[index + 1].token_type == TOKEN_AND
|| token[index + 1].token_type == TOKEN_OR)
{
print_error_logical_operator(token[index + 1].token_type);
*error_catched = 1;
}
else if (token[index + 1].token_type == TOKEN_PIPE)
{
print_error_pipe();
*error_catched = 1;
}
}
void check_valid_heredoc(t_token *token, int index, int *error_catched)
{
if (token[index + 1].token_value == 0 \
|| *token[index + 1].token_value == 0 || token[index + 1].token_type == 0)
{
*error_catched = 2;
if (token[index + 1].token_type == TOKEN_AND \
|| token[index + 1].token_type == TOKEN_OR)
print_error_logical_operator(token[index].token_type);
else if (token[index + 1].token_type == TOKEN_PIPE)
print_error_pipe();
else if (token[index + 1].token_type == TOKEN_REDIRECT_IN \
|| token[index + 1].token_type == TOKEN_REDIRECT_OUT \
|| token[index + 1].token_type == TOKEN_REDIRECT_APPEND \
|| token[index + 1].token_type == TOKEN_HEREDOC)
print_error_redir(token[index + 1].token_type);
else
ft_putendl_fd(\
"minishell: syntax error near unexpected token `newline'", 2);
}
}

38
ast/syntax_check_helper.c Normal file
View File

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* syntax_check_helper.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/23 14:38:50 by vvobis #+# #+# */
/* Updated: 2024/08/23 14:40:12 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void print_error_logical_operator(t_token_type token_type)
{
if (token_type == TOKEN_AND)
ft_putendl_fd("minishell: syntax error near unexpected token `&&'", 2);
if (token_type == TOKEN_OR)
ft_putendl_fd("minishell: syntax error near unexpected token `||'", 2);
}
void print_error_pipe(void)
{
ft_putendl_fd("minishell: syntax error near unexpected token `|'", 2);
}
void print_error_redir(t_token_type token_type)
{
if (token_type == TOKEN_REDIRECT_APPEND)
ft_putendl_fd("minishell: syntax error near unexpected token `>>'", 2);
else if (token_type == TOKEN_REDIRECT_IN)
ft_putendl_fd("minishell: syntax error near unexpected token `<'", 2);
else if (token_type == TOKEN_REDIRECT_OUT)
ft_putendl_fd("minishell: syntax error near unexpected token `>'", 2);
else if (token_type == TOKEN_HEREDOC)
ft_putendl_fd("minishell: syntax error near unexpected token `<<'", 2);
}

BIN
bin/minishell Executable file

Binary file not shown.

71
builtin/ft_cd.c Normal file
View File

@ -0,0 +1,71 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_cd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/24 14:10:08 by vvobis #+# #+# */
/* Updated: 2024/08/27 16:57:49 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
static void pwd_update(const char **environment)
{
char *pwd;
char *old_pwd;
pwd = getcwd(NULL, 0);
if (!pwd)
{
perror("getcwd");
lst_memory(NULL, NULL, CLEAN);
}
old_pwd = environment_variable_value_get("PWD", environment);
environment_variable_value_change(environment, "OLDPWD", old_pwd);
environment_variable_value_change(environment, "PWD", pwd);
ft_free(&pwd);
}
void cd_correct(char *args, const char **environment, int *exit_status)
{
char *path;
if (ft_memcmp(args, "-\0", 2) == 0)
{
path = environment_variable_value_get("OLDPWD", environment);
ft_putendl_fd(path, 1);
}
else
path = args;
if (chdir(path) != 0)
return (*exit_status = 1, ft_putstr_fd("minishell: cd: ", 2), \
perror(path));
*exit_status = 0;
}
void ft_cd( const char **environment, \
const char **args, \
int32_t *exit_status)
{
uint32_t args_size;
char *path;
args_size = get_split_size((const char **)args);
if (args_size > 2)
return (*exit_status = 1, \
ft_putendl_fd("minishell: cd: too many arguments", 2));
else if (args_size == 1)
{
path = environment_variable_value_get("HOME", environment);
if (chdir(path) != 0)
return (*exit_status = 1, perror("cd"));
*exit_status = 0;
}
else
cd_correct((char *)args[1], environment, exit_status);
if (*exit_status == 0)
pwd_update((const char **)environment);
}

110
builtin/ft_echo.c Normal file
View File

@ -0,0 +1,110 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_echo.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/24 11:39:04 by vvobis #+# #+# */
/* Updated: 2024/08/22 10:30:26 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void trim_spaces(char *args)
{
uint32_t i;
uint32_t j;
i = 0;
if (!args)
return ;
while (args[i])
{
j = i;
while (ft_isspace(args[j]))
j++;
ft_memmove(&args[i], &args[j - (j > i && i > 0)], \
ft_strlen(&args[i]) + 1);
i++;
}
}
bool is_dash_n(char *arg)
{
uint32_t i;
i = 0;
if (arg[i] && arg[i] == '-')
{
while (arg[i] && arg[++i] == 'n')
;
if (arg[i] == 0)
return (true);
}
return (false);
}
int32_t echo_no_newline(char **args)
{
uint32_t i;
i = 0;
while (args[i] && is_dash_n(args[i]))
i++;
while (args[i])
{
ft_putstr_fd(args[i], 1);
if (*args[i] && args[i + 1])
ft_putchar_fd(' ', 1);
i++;
}
return (0);
}
int32_t echo_newline(char **args, bool is_single)
{
uint32_t i;
i = 0;
while (args[i + 1])
{
if (is_single)
trim_spaces(args[i]);
ft_putstr_fd(args[i], 1);
ft_putchar_fd(' ', 1);
i++;
}
if (is_single)
trim_spaces(args[i]);
if (args[i] && args[i][ft_strlen(args[i]) - \
(ft_strlen(args[i]) > 0)] == '\n')
ft_putstr_fd(args[i], 1);
else
ft_putendl_fd(args[i], 1);
return (0);
}
int32_t ft_echo(char **args, int32_t *exit_status)
{
uint32_t i;
i = 0;
*exit_status = 0;
if (args[1])
{
if (ft_memcmp(args[1], "-n", 2) == 0)
{
while (args[1][++i] == 'n')
;
if (args[1][i] == 0)
return (echo_no_newline(&args[2]), *exit_status = 0);
}
echo_newline(&args[1], 0);
*exit_status = 0;
}
else
ft_putchar_fd('\n', 1);
return (0);
}

24
builtin/ft_env.c Normal file
View File

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_env.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/24 13:56:33 by vvobis #+# #+# */
/* Updated: 2024/08/04 10:31:19 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void ft_env(const char **environment, int32_t *exit_status)
{
if (!environment)
*exit_status = 1;
else
{
*exit_status = 0;
environment_print(environment);
}
}

88
builtin/ft_exit.c Normal file
View File

@ -0,0 +1,88 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_exit.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/24 16:52:07 by vvobis #+# #+# */
/* Updated: 2025/02/15 14:59:55 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
bool check_exit_status(char *status)
{
char *number_string;
int64_t number;
uint8_t is_too_big;
if (!status || !*status)
return (false);
is_too_big = false;
while (*status && *status == '0')
status++;
if (*status == '+' || *status == '0')
status++;
number = ft_atol(status, &is_too_big);
if (is_too_big == true)
return (false);
number_string = ft_ltoa(number);
if (!number_string)
return (perror("malloc"), lst_memory(NULL, NULL, CLEAN), 0);
if (ft_strncmp(status, number_string, ft_strlen(status)) == 0)
return (ft_free(&number_string), true);
ft_free(&number_string);
return (false);
}
bool exit_with_args( char **args, \
bool *invalid_message_print, \
uint32_t args_length, \
int32_t *exit_status)
{
*invalid_message_print = check_exit_status(args[1]);
if (*invalid_message_print && args_length == 2)
*exit_status = ft_atol(args[1], \
(uint8_t *)invalid_message_print);
else if (!*invalid_message_print)
{
*exit_status = 2;
p_stderr(2, "minishell: exit: %s: numeric argument required\n", \
args[1]);
}
else if (*invalid_message_print && args_length > 2)
return (ft_putendl_fd("minishell: exit: too many arguments", \
2), 1);
return (0);
}
uint get_tree_size(t_ast *tree)
{
uint i;
i = 0;
while (tree[i].type != NODE_END)
i++;
return (i);
}
void ft_exit(t_ast *tree, int *exit_status_prev)
{
uint32_t args_length;
int32_t exit_status;
bool invalid_message_print;
exit_status = *exit_status_prev;
args_length = get_split_size((const char **)tree->args);
invalid_message_print = false;
ft_putendl_fd("exit", 2);
if (args_length > 1)
if (exit_with_args(tree->args, &invalid_message_print, \
args_length, &exit_status))
return ;
wait_pids(tree, get_tree_size(tree), tree->cpid, NULL);
lst_memory(NULL, NULL, END);
exit(exit_status % 256);
}

122
builtin/ft_export.c Normal file
View File

@ -0,0 +1,122 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_export.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/24 14:41:32 by vvobis #+# #+# */
/* Updated: 2024/08/19 23:26:58 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
#include <stdint.h>
#include <sys/types.h>
static void print_environment_a_la_export(char **env)
{
char *variable_name;
char *variable_value;
uint32_t i;
i = 0;
while (env[i])
{
variable_name = env[i];
variable_value = ft_strchr(variable_name, '=');
if (variable_value)
{
*variable_value++ = 0;
ft_printf("declare -x %s=\"%s\"\n", variable_name, variable_value);
*--variable_value = '=';
}
else
ft_printf("declare -x %s=\"\"\n", variable_name);
i++;
}
}
static void environment_print_sorted(const char **environment)
{
uint32_t i;
uint32_t length1;
char *tmp;
i = 0;
while (environment[i] && environment[i + 1])
{
tmp = ft_strchr(environment[i], '=');
if (!tmp)
tmp = ft_strchr(environment[i], 0);
length1 = tmp - environment[i];
if (ft_strncmp(environment[i], environment[i + 1], length1) > 0)
{
tmp = (char *)environment[i];
environment[i] = environment[i + 1];
environment[i + 1] = tmp;
environment_print_sorted(environment);
break ;
}
i++;
}
if (environment[i + 1] == NULL)
print_environment_a_la_export((char **)environment);
}
static void print_sorted(const char **environment)
{
char **env;
uint32_t i;
env = ft_calloc(get_split_size(environment) + 1, sizeof(*env));
if (!env)
return (perror("malloc"), lst_memory(NULL, NULL, CLEAN));
i = -1;
while (environment[++i])
env[i] = (char *)environment[i];
environment_print_sorted((const char **)env);
ft_free(&env);
}
bool is_allowed_char(const char *s)
{
uint32_t i;
i = 0;
if (!ft_isalpha(s[i]) && s[i] != '_')
return (false);
i++;
while (s[i] && (ft_isalnum(s[i]) || s[i] == '_'))
i++;
if (s[i] == '=' || s[i] == 0)
return (true);
return (false);
}
void ft_export(const char **args, int32_t *exit_status)
{
uint32_t i;
char *variable_name;
char *variable_value;
char **environment;
environment = env_static(NULL);
if (get_split_size(args) < 2)
return (print_sorted((const char **)environment));
i = 1;
while (args[i])
{
if (!is_allowed_char(args[i]))
return (p_stderr(2, \
"minishell: export: `%s': not a valid identifier\n", \
args[i]), *exit_status = 1, (void)0);
variable_name = (char *)args[i];
variable_value = ft_strchr(args[i], '=');
if (variable_value)
*variable_value++ = 0;
environment_variable_add(&environment, variable_name, variable_value);
i++;
}
*exit_status = 0;
}

28
builtin/ft_pwd.c Normal file
View File

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_pwd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: victor </var/spool/mail/victor> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/24 22:49:03 by victor #+# #+# */
/* Updated: 2024/08/16 23:50:58 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void ft_pwd(const char **environment, int32_t *exit_status)
{
char *pwd;
if (!environment)
*exit_status = 1;
else
{
*exit_status = 0;
pwd = getcwd(NULL, 0);
ft_putendl_fd(pwd, 1);
ft_free(&pwd);
}
}

33
builtin/ft_unset.c Normal file
View File

@ -0,0 +1,33 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_unset.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/24 14:29:41 by vvobis #+# #+# */
/* Updated: 2024/08/10 22:25:27 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void ft_unset(char **envivonment, const char **args, int32_t *exit_status)
{
uint32_t args_size;
uint32_t i;
args_size = get_split_size(args);
if (args_size < 2)
return ;
else if (args[1] && *args[1] == '-')
return (ft_putendl_fd("unset: usage: unset [name ...]", \
*exit_status = 2));
i = 1;
while (args[i])
{
environment_variable_remove(envivonment, args[i]);
i++;
}
*exit_status = 0;
}

40
libft/Makefile Normal file
View File

@ -0,0 +1,40 @@
NAME := libft.a
CC := cc
CFLAGS:= -Wall -Wextra -Werror -g3
SRC := ft_bzero.c ft_isalnum.c ft_isalpha.c ft_isdigit.c \
ft_isprint.c ft_memcpy.c ft_memmove.c ft_memset.c \
ft_strlcat.c ft_strlcpy.c ft_strlen.c \
ft_isascii.c ft_strchr.c ft_strrchr.c ft_strncmp.c \
ft_toupper.c ft_tolower.c ft_memchr.c ft_strnstr.c \
ft_atoi.c ft_memcmp.c ft_calloc.c ft_strdup.c \
ft_substr.c ft_strjoin.c ft_strtrim.c ft_split.c \
ft_itoa.c ft_strmapi.c ft_striteri.c ft_putchar_fd.c \
ft_putstr_fd.c ft_putendl_fd.c ft_putnbr_fd.c \
get_next_line.c get_next_line_utils.c ft_puthex.c \
ft_printf.c ft_putascii.c ft_putptr.c ft_free.c \
ft_atol.c ft_ltoa.c
SRCBON := 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
OBJBON := $(SRC:%.c=%.o) $(SRCBON:%.c=%.o)
OBJ := $(SRC:%.c=%.o)
all: $(NAME)
bonus: $(OBJBON)
ar rcs libft.a $(OBJ) $(OBJBON)
$(NAME): $(OBJ)
ar rcs libft.a $(OBJ)
$(OBJ): $(SRC)
$(CC) -c $(CFLAGS) $(SRC)
re: fclean all
fclean: clean
rm -f $(NAME)
clean:
rm -f $(OBJ) $(OBJBON)

42
libft/ft_atoi.c Normal file
View File

@ -0,0 +1,42 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_atoi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/10 10:49:04 by vvobis #+# #+# */
/* Updated: 2024/08/17 21:39:08 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int is_space(char const c)
{
if ((c >= 9 && c <= 13) || c == ' ')
return (1);
return (0);
}
int ft_atoi(char const *s)
{
int nb;
char const *tmp;
nb = 0;
while (is_space(*s))
s++;
tmp = s;
if (*tmp == '+' || *tmp == '-')
tmp++;
while (*tmp >= '0' && *tmp <= '9')
{
nb *= 10;
nb += (*tmp - '0');
tmp++;
}
if (*s == '-')
nb = -nb;
return (nb);
}

37
libft/ft_atol.c Normal file
View File

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_atol.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/10 10:49:04 by vvobis #+# #+# */
/* Updated: 2024/08/26 21:00:15 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
long ft_atol(char const *s, uint8_t *too_big)
{
unsigned long long nb;
char const *tmp;
nb = 0;
while (is_space(*s))
s++;
tmp = s;
if (*tmp == '+' || *tmp == '-')
tmp++;
while (*tmp >= '0' && *tmp <= '9')
{
nb *= 10;
nb += (*tmp - '0');
tmp++;
if (nb > (uint64_t)LLONG_MAX + (*s == '-'))
return (*too_big == 1);
}
if (*s == '-')
nb = -nb;
return (nb);
}

19
libft/ft_bzero.c Normal file
View File

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_bzero.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 16:04:55 by vvobis #+# #+# */
/* Updated: 2024/04/09 20:54:53 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_bzero(void *s, size_t n)
{
while (n--)
*(char *)s++ = 0;
}

30
libft/ft_calloc.c Normal file
View File

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_calloc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/04 13:44:00 by vvobis #+# #+# */
/* Updated: 2024/04/10 16:39:56 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_calloc(size_t n, size_t s)
{
char *tmp;
unsigned long i;
i = 0;
if (n == 0)
return (malloc(0));
if (SIZE_MAX / n < s)
return (NULL);
tmp = malloc(n * s);
if (tmp)
while (i < n * s)
tmp[i++] = 0;
return ((void *)tmp);
}

19
libft/ft_free.c Normal file
View File

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_free.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/06/13 15:23:16 by vvobis #+# #+# */
/* Updated: 2024/08/10 22:39:49 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_free(void *ptr)
{
free(*(void **)ptr);
*(void **)ptr = NULL;
}

20
libft/ft_isalnum.c Normal file
View File

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isalnum.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 15:59:18 by vvobis #+# #+# */
/* Updated: 2024/04/02 15:59:23 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_isalnum(int c)
{
if (ft_isdigit(c) || ft_isalpha(c))
return (1);
return (0);
}

20
libft/ft_isalpha.c Normal file
View File

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isalpha.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 15:59:49 by vvobis #+# #+# */
/* Updated: 2024/04/02 16:00:04 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_isalpha(int c)
{
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
return (1);
return (0);
}

20
libft/ft_isascii.c Normal file
View File

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isascii.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 19:48:35 by vvobis #+# #+# */
/* Updated: 2024/04/02 19:49:36 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_isascii(int c)
{
if (c >= 0 && c <= 127)
return (1);
return (0);
}

18
libft/ft_isdigit.c Normal file
View File

@ -0,0 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isdigit.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 16:14:56 by vvobis #+# #+# */
/* Updated: 2024/04/02 19:38:45 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
int ft_isdigit(int c)
{
if (c >= '0' && c <= '9')
return (1);
return (0);
}

18
libft/ft_isprint.c Normal file
View File

@ -0,0 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_isprint.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 16:00:49 by vvobis #+# #+# */
/* Updated: 2024/04/02 16:00:52 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
int ft_isprint(int c)
{
if (c >= 32 && c <= 126)
return (1);
return (0);
}

75
libft/ft_itoa.c Normal file
View File

@ -0,0 +1,75 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_itoa.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/05 20:16:48 by vvobis #+# #+# */
/* Updated: 2024/04/11 14:48:59 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
static int get_len(int n)
{
int i;
if (n < 0)
n = -n;
i = 0;
while (n)
{
i++;
n /= 10;
}
return (i);
}
static char *is_negative(int n)
{
int i;
char *num;
i = get_len(n);
num = malloc(sizeof(*num) * i + 2);
if (!num)
return (NULL);
num[i + 1] = 0;
while (n)
{
num[i--] = -(n % 10) + 48;
n /= 10;
}
num[i] = 0x2d;
return (num);
}
static char *is_positive(int n)
{
int i;
char *num;
i = get_len(n);
num = malloc(sizeof(*num) * i + 1);
if (!num)
return (NULL);
num[i--] = 0;
while (n)
{
num[i--] = (n % 10) + 48;
n /= 10;
}
return (num);
}
char *ft_itoa(int n)
{
if (n == 0)
return (ft_strdup("0"));
else if (n < 0)
return (is_negative(n));
else
return (is_positive(n));
}

View File

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstadd_back.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 13:51:32 by vvobis #+# #+# */
/* Updated: 2024/04/09 18:17:12 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_lstadd_back(t_list **lst, t_list *new)
{
t_list *tmp;
if (!new)
return ;
if (*lst)
{
tmp = *lst;
while (tmp->next)
tmp = tmp->next;
tmp->next = new;
}
else
*lst = new;
}

View File

@ -0,0 +1,26 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstadd_front.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 12:53:08 by vvobis #+# #+# */
/* Updated: 2024/04/09 18:17:50 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_lstadd_front(t_list **lst, t_list *new)
{
if (!lst || !new)
return ;
if (!*lst)
*lst = new;
else
{
new->next = *lst;
*lst = new;
}
}

28
libft/ft_lstclear_bonus.c Normal file
View File

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstclear.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 15:44:23 by vvobis #+# #+# */
/* Updated: 2024/04/09 22:35:41 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_lstclear(t_list **lst, void (*del)(void *))
{
t_list *tmp;
if (!*lst || !del || !lst)
return ;
while (*lst)
{
tmp = (*lst)->next;
del((*lst)->content);
free(*lst);
*lst = tmp;
}
}

View File

@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstdelone.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 14:24:03 by vvobis #+# #+# */
/* Updated: 2024/04/09 15:42:04 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_lstdelone(t_list *lst, void (*del)(void *))
{
if (!lst || !del)
return ;
del(lst->content);
free(lst);
}

24
libft/ft_lstiter_bonus.c Normal file
View File

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstiter.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 15:57:51 by vvobis #+# #+# */
/* Updated: 2024/04/09 18:20:05 by vvobis ### ########.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;
}
}

22
libft/ft_lstlast_bonus.c Normal file
View File

@ -0,0 +1,22 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstlast.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 13:47:08 by vvobis #+# #+# */
/* Updated: 2024/04/09 15:11:51 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
t_list *ft_lstlast(t_list *lst)
{
if (!lst)
return (NULL);
while (lst->next)
lst = lst->next;
return (lst);
}

44
libft/ft_lstmap_bonus.c Normal file
View File

@ -0,0 +1,44 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstmap.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 16:18:03 by vvobis #+# #+# */
/* Updated: 2024/04/09 23:40:57 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
static void *free_list(t_list **head, void (*del)(void *), void *fcontent)
{
if (fcontent)
del(fcontent);
ft_lstclear(head, del);
return (NULL);
}
t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *))
{
t_list *tmp;
t_list *head;
void *fcontent;
if (!lst || !f || !del)
return (NULL);
head = NULL;
while (lst)
{
fcontent = f(lst->content);
if (!fcontent)
return (free_list(&head, del, fcontent));
tmp = ft_lstnew(fcontent);
if (!tmp)
return (free_list(&head, del, fcontent));
ft_lstadd_back(&head, tmp);
lst = lst->next;
}
return (head);
}

25
libft/ft_lstnew_bonus.c Normal file
View File

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstnew.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 11:10:05 by vvobis #+# #+# */
/* Updated: 2024/04/09 18:59:48 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
t_list *ft_lstnew(void *content)
{
t_list *tmp;
tmp = malloc(sizeof(*tmp));
if (!tmp)
return (NULL);
tmp->next = NULL;
tmp->content = content;
return (tmp);
}

28
libft/ft_lstsize_bonus.c Normal file
View File

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_lstsize.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 13:43:08 by vvobis #+# #+# */
/* Updated: 2024/04/09 18:21:11 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_lstsize(t_list *lst)
{
int i;
if (!lst)
return (0);
i = 1;
while (lst->next)
{
lst = lst->next;
i++;
}
return (i);
}

75
libft/ft_ltoa.c Normal file
View File

@ -0,0 +1,75 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_ltoi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/05 20:16:48 by vvobis #+# #+# */
/* Updated: 2024/08/23 15:54:04 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
static int get_len(long long n)
{
int i;
if (n < 0)
n = -n;
i = 0;
while (n)
{
i++;
n /= 10;
}
return (i);
}
static char *is_negative(long long n)
{
int i;
char *num;
i = get_len(n);
num = malloc(sizeof(*num) * i + 2);
if (!num)
return (NULL);
num[i + 1] = 0;
while (n)
{
num[i--] = -(n % 10) + 48;
n /= 10;
}
num[i] = 0x2d;
return (num);
}
static char *is_positive(long long n)
{
int i;
char *num;
i = get_len(n);
num = malloc(sizeof(*num) * i + 1);
if (!num)
return (NULL);
num[i--] = 0;
while (n)
{
num[i--] = (n % 10) + 48;
n /= 10;
}
return (num);
}
char *ft_ltoa(long long n)
{
if (n == 0)
return (ft_strdup("0"));
else if (n < 0)
return (is_negative(n));
else
return (is_positive(n));
}

31
libft/ft_memchr.c Normal file
View File

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memchr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/03 15:13:59 by vvobis #+# #+# */
/* Updated: 2024/04/09 20:55:24 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_memchr(void *s, int c, size_t n)
{
unsigned char *p;
size_t i;
i = 0;
p = (unsigned char *)s;
while (i < n)
{
if (p[i] == (unsigned char)c)
return ((void *)&p[i]);
i++;
}
if (p[i - 1] == (unsigned char)c)
return ((void *)&p[i]);
return (NULL);
}

31
libft/ft_memcmp.c Normal file
View File

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memcmp.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/03 15:27:15 by vvobis #+# #+# */
/* Updated: 2024/04/09 19:21:02 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_memcmp(void *s1, void const *s2, size_t n)
{
unsigned char *p1;
unsigned char *p2;
unsigned int i;
p1 = (unsigned char *)s1;
p2 = (unsigned char *)s2;
i = 0;
while (i < n)
{
if (p1[i] != p2[i])
return (p1[i] - p2[i]);
i++;
}
return (0);
}

32
libft/ft_memcpy.c Normal file
View File

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memcpy.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 17:13:18 by vvobis #+# #+# */
/* Updated: 2024/04/09 19:21:29 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_memcpy(void *dest, void const *src, size_t n)
{
char *d;
char *s;
if (n == 0 || (dest == NULL && src == NULL))
return (dest);
if (dest == NULL || src == NULL)
{
*(char *)dest = 1;
*(char *)src = 1;
}
d = (char *) dest;
s = (char *) src;
while (n--)
*d++ = *s++;
return (dest);
}

30
libft/ft_memmove.c Normal file
View File

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memmove.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 17:42:28 by vvobis #+# #+# */
/* Updated: 2024/04/09 19:21:54 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_memmove(void *dest, void const *src, size_t n)
{
unsigned char *d;
unsigned char *s;
if (!dest && !src)
return (dest);
d = (unsigned char *)dest;
s = (unsigned char *)src;
if (s < d)
while (n--)
d[n] = s[n];
else
ft_memcpy(dest, (void *)src, n);
return (dest);
}

23
libft/ft_memset.c Normal file
View File

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memset.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 15:57:27 by vvobis #+# #+# */
/* Updated: 2024/04/03 11:18:10 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void *ft_memset(void *s, int c, size_t n)
{
char *str;
str = (char *)s;
while (n--)
str[n] = c;
return (s);
}

61
libft/ft_printf.c Normal file
View File

@ -0,0 +1,61 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_printf.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/18 17:50:35 by vvobis #+# #+# */
/* Updated: 2024/04/26 16:54:14 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_printf.h"
int handle_arg(va_list args, char format, int *count)
{
if (format == 'd' || format == 'i')
ft_putnbr(va_arg(args, int), count);
else if (format == 'u')
ft_putnbr(va_arg(args, unsigned int), count);
else if (format == 's')
ft_putstr(va_arg(args, char *), count);
else if (format == 'X')
ft_puthex_upper(va_arg(args, unsigned int), count);
else if (format == 'x')
ft_puthex_lower(va_arg(args, unsigned int), count);
else if (format == 'p')
ft_putptr(va_arg(args, void *), count);
else if (format == 'c')
ft_putchar(va_arg(args, int), count);
else if (format == '%')
ft_putchar('%', count);
else
return (0);
return (1);
}
int ft_printf(const char *format, ...)
{
va_list args;
int count;
if (!format)
return (-1);
va_start(args, format);
count = 0;
while (1)
{
while (*format != '%' && *format)
ft_putchar(*format++, &count);
if (!*format)
break ;
else
format++;
if (!*format || !handle_arg(args, *format, &count))
return (-1);
format++;
}
va_end(args);
return (count);
}

29
libft/ft_printf.h Normal file
View File

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_printf.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/18 12:50:35 by vvobis #+# #+# */
/* Updated: 2024/04/18 20:47:09 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef FT_PRINTF_H
# define FT_PRINTF_H
# include <stdarg.h>
# include <stdlib.h>
# include <unistd.h>
int ft_printf(const char *format, ...);
void ft_puthex_lower(unsigned long nbr, int *count);
void ft_puthex_upper(unsigned long nbr, int *count);
void ft_putchar(int c, int *count);
void ft_putnbr(long n, int *count);
void ft_putstr(const char *str, int *count);
void ft_putptr(void *ptr, int *count);
#endif

44
libft/ft_putascii.c Normal file
View File

@ -0,0 +1,44 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putascii.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/18 17:54:53 by vvobis #+# #+# */
/* Updated: 2024/04/18 17:55:04 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_printf.h"
void ft_putchar(int c, int *count)
{
write(1, &c, 1);
*count += 1;
}
void ft_putnbr(long n, int *count)
{
if (n < 0)
ft_putchar(0x2d, count);
if (n <= -10)
ft_putnbr(n / -10, count);
if (n >= 10)
ft_putnbr(n / 10, count);
if (n >= 0)
ft_putchar(n % 10 + 0x30, count);
if (n < 0)
ft_putchar(-(n % -10) + 0x30, count);
}
void ft_putstr(const char *str, int *count)
{
if (!str)
{
*count += ft_printf("(null)");
return ;
}
while (*str)
ft_putchar(*str++, count);
}

18
libft/ft_putchar_fd.c Normal file
View File

@ -0,0 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putchar_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/07 17:34:30 by vvobis #+# #+# */
/* Updated: 2024/04/07 17:53:33 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_putchar_fd(char c, int fd)
{
write(fd, &c, 1);
}

21
libft/ft_putendl_fd.c Normal file
View File

@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putendl_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/07 17:57:33 by vvobis #+# #+# */
/* Updated: 2024/04/07 18:00:49 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_putendl_fd(char *str, int fd)
{
if (!str)
return ;
ft_putstr_fd(str, fd);
ft_putchar_fd(0x0a, fd);
}

33
libft/ft_puthex.c Normal file
View File

@ -0,0 +1,33 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_puthex.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/18 17:52:38 by vvobis #+# #+# */
/* Updated: 2024/04/18 20:46:13 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_printf.h"
void ft_puthex_upper(unsigned long nbr, int *count)
{
char *base_str;
base_str = "0123456789ABCDEF";
if (nbr >= 16)
ft_puthex_upper(nbr / 16, count);
ft_putchar(base_str[(nbr % 16)], count);
}
void ft_puthex_lower(unsigned long nbr, int *count)
{
char *base_str;
base_str = "0123456789abcdef";
if (nbr >= 16)
ft_puthex_lower(nbr / 16, count);
ft_putchar(base_str[(nbr % 16)], count);
}

27
libft/ft_putnbr_fd.c Normal file
View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putnbr_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/07 18:02:14 by vvobis #+# #+# */
/* Updated: 2024/04/11 11:23:10 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_putnbr_fd(int n, int fd)
{
if (n < 0)
ft_putchar_fd(0x2d, fd);
if (n <= -10)
ft_putnbr_fd(n / -10, fd);
if (n >= 10)
ft_putnbr_fd(n / 10, fd);
if (n >= 0)
ft_putchar_fd(n % 10 + 0x30, fd);
if (n < 0)
ft_putchar_fd(-(n % -10) + 0x30, fd);
}

27
libft/ft_putptr.c Normal file
View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putptr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/18 17:53:53 by vvobis #+# #+# */
/* Updated: 2024/04/18 20:44:46 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_printf.h"
void ft_putptr(void *ptr, int *count)
{
void **to_print;
if (!ptr)
{
*count += ft_printf("(nil)");
return ;
}
to_print = &ptr;
*count += ft_printf("0x");
ft_puthex_lower((long)*to_print, count);
}

21
libft/ft_putstr_fd.c Normal file
View File

@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putstr_fd.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/07 17:48:41 by vvobis #+# #+# */
/* Updated: 2024/07/31 10:01:48 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_putstr_fd(const char *str, int fd)
{
if (!str)
return ;
while (*str)
ft_putchar_fd(*str++, fd);
}

84
libft/ft_split.c Normal file
View File

@ -0,0 +1,84 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_split.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/05 20:14:20 by vvobis #+# #+# */
/* Updated: 2024/06/14 16:06:51 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
static int count(char const *s, char const c)
{
int n;
n = 0;
if (*s != c && *s)
n = 1;
while (*s)
{
if (*s == c && *(s + 1) != c && *(s + 1))
n++;
s++;
}
return (n);
}
static int count_sub(char const *s, char const c)
{
int i;
i = 0;
while (*s != c && *s)
{
i++;
s++;
}
return (i);
}
static char **free_all(char **back)
{
char **tmp;
tmp = back;
while (*back)
{
free(*back);
back++;
}
free(tmp);
return (NULL);
}
char **ft_split(char const *s, char const c)
{
char **tmp;
char **back;
if (!s)
return (NULL);
tmp = (char **)ft_calloc(sizeof(*tmp), count(s, c) + 1);
if (!tmp)
return (NULL);
back = tmp;
while (*s && tmp)
{
while (*s == c && *s)
s++;
if (*s)
{
*tmp = ft_substr(s, 0, count_sub(s, c));
if (!*tmp)
return (free_all(back));
}
tmp++;
while (*s != c && *s)
s++;
}
return (back);
}

29
libft/ft_strchr.c Normal file
View File

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strchr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/03 12:20:50 by vvobis #+# #+# */
/* Updated: 2024/04/09 20:54:14 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strchr(char const *s, int c)
{
int i;
i = 0;
while (s[i])
{
if (s[i] == (char)c)
return ((char *)&s[i]);
i++;
}
if ((char)c == 0)
return ((char *)&s[i]);
return (NULL);
}

31
libft/ft_strdup.c Normal file
View File

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strdup.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/04 18:44:05 by vvobis #+# #+# */
/* Updated: 2024/04/12 10:44:23 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strdup(char const *s)
{
char *tmp;
int i;
i = 0;
tmp = ft_calloc(ft_strlen(s) + 1, sizeof(*tmp));
if (!tmp)
return (NULL);
while (s[i])
{
tmp[i] = s[i];
i++;
}
tmp[i] = 0;
return (tmp);
}

27
libft/ft_striteri.c Normal file
View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_striteri.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/07 17:24:08 by vvobis #+# #+# */
/* Updated: 2024/04/09 19:27:07 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
void ft_striteri(char const *s, void (*f)(unsigned int, char *))
{
unsigned int i;
if (!s || !f)
return ;
i = 0;
while (s[i])
{
f(i, (char *)&s[i]);
i++;
}
}

41
libft/ft_strjoin.c Normal file
View File

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strjoin.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/04 19:08:03 by vvobis #+# #+# */
/* Updated: 2024/04/12 10:07:26 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strjoin(char const *s1, char const *s2)
{
char *tmp;
unsigned int i;
unsigned int j;
if (!s1 || !s2)
return (NULL);
tmp = ft_calloc(ft_strlen(s1) + ft_strlen(s2) + 1, sizeof(*tmp));
if (!tmp)
return (NULL);
i = 0;
while (s1[i])
{
tmp[i] = s1[i];
i++;
}
j = 0;
while (s2[j])
{
tmp[i] = s2[j];
i++;
j++;
}
tmp[i] = 0;
return (tmp);
}

37
libft/ft_strlcat.c Normal file
View File

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strlcat.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/04 16:10:59 by vvobis #+# #+# */
/* Updated: 2024/04/10 16:41:14 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
size_t ft_strlcat(char *dest, char const *src, size_t size)
{
size_t dlen;
size_t slen;
if (size == 0)
return (ft_strlen(src));
dlen = ft_strlen(dest);
slen = ft_strlen(src);
if (size <= dlen)
return (slen + size);
if (dlen + slen < size)
{
ft_memcpy(&dest[dlen], src, slen);
dest[dlen + slen] = 0;
}
else
{
ft_memcpy(&dest[dlen], src, size - dlen);
dest[size - 1] = 0;
}
return (dlen + slen);
}

32
libft/ft_strlcpy.c Normal file
View File

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strlcpy.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 19:03:18 by vvobis #+# #+# */
/* Updated: 2024/04/09 19:28:44 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
size_t ft_strlcpy(char *dest, char const *src, size_t size)
{
size_t i;
i = 0;
if (size != 0)
{
while (src[i] != '\0' && i < size - 1)
{
dest[i] = src[i];
i++;
}
dest[i] = '\0';
}
while (src[i] != '\0')
i++;
return (i);
}

29
libft/ft_strlen.c Normal file
View File

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strlen.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/02 16:01:03 by vvobis #+# #+# */
/* Updated: 2024/07/19 11:22:23 by anarama ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
size_t ft_strlen(char const *str)
{
size_t i;
i = 0;
if (!str)
return (0);
while (*str++)
{
i++;
if (i == SIZE_MAX)
break ;
}
return (i);
}

33
libft/ft_strmapi.c Normal file
View File

@ -0,0 +1,33 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strmapi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/07 17:01:35 by vvobis #+# #+# */
/* Updated: 2024/04/12 10:13:57 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strmapi(char const *s, char (*f)(unsigned int, char))
{
char *tmp;
unsigned int i;
if (!s || !f)
return (NULL);
tmp = ft_calloc(ft_strlen(s) + 1, sizeof(*tmp));
if (!tmp)
return (NULL);
i = 0;
while (s[i])
{
tmp[i] = f(i, s[i]);
i++;
}
tmp[i] = 0;
return (tmp);
}

31
libft/ft_strncmp.c Normal file
View File

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strncmp.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/03 13:33:22 by vvobis #+# #+# */
/* Updated: 2024/04/12 10:29:59 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_strncmp(char const *s1, char const *s2, size_t n)
{
size_t i;
if (n == 0)
return (0);
i = 0;
while ((s1[i] || s2[i]) && i < n)
{
if (s1[i] < s2[i])
return ((unsigned char)s1[i] - (unsigned char)s2[i]);
else if (s1[i] > s2[i])
return ((unsigned char)s1[i] - (unsigned char)s2[i]);
i++;
}
return (0);
}

36
libft/ft_strnstr.c Normal file
View File

@ -0,0 +1,36 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strnstr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/03 15:36:41 by vvobis #+# #+# */
/* Updated: 2024/04/10 16:42:02 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strnstr(char const *s1, char const *s2, size_t n)
{
size_t i;
size_t j;
if (!*s2)
return ((char *)s1);
i = 0;
while (i < n && s1[i])
{
j = 0;
if (s1[i + j] == s2[j])
{
while (s1[i + j] == s2[j] && s1[i + j] && i + j < n)
j++;
if (!s2[j])
return ((char *)&s1[i]);
}
i++;
}
return (NULL);
}

33
libft/ft_strrchr.c Normal file
View File

@ -0,0 +1,33 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strrchr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/03 12:20:50 by vvobis #+# #+# */
/* Updated: 2024/04/09 20:54:22 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_strrchr(char const *s, int c)
{
char *n;
int i;
i = 0;
n = NULL;
while (s[i] != 0)
{
if (s[i] == (char)c)
n = (char *)&s[i];
i++;
}
if ((char)c == 0)
return ((char *)&s[i]);
if (n)
return (n);
return (NULL);
}

47
libft/ft_strtrim.c Normal file
View File

@ -0,0 +1,47 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_strtrim.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/04 19:30:35 by vvobis #+# #+# */
/* Updated: 2024/04/15 13:07:55 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
static int is_set(char c, char const *s)
{
while (*s)
if (c == *s++)
return (1);
return (0);
}
static int find_end(char const *s1, char const *set)
{
int i;
i = 0;
while (*s1)
s1++;
while (is_set(*--s1, set))
i++;
return (i);
}
char *ft_strtrim(char const *s1, char const *set)
{
if (!s1)
return (NULL);
if (!set)
return ((char *)s1);
while (is_set(*s1, set) && *s1)
s1++;
if ((int)ft_strlen(s1) > find_end(s1, set))
return (ft_substr(s1, 0, ft_strlen(s1) - find_end(s1, set)));
else
return (ft_calloc(1, 1));
}

41
libft/ft_substr.c Normal file
View File

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_substr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/04 18:58:25 by vvobis #+# #+# */
/* Updated: 2024/04/09 21:50:44 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
char *ft_substr(char const *s, unsigned int start, size_t len)
{
char *tmp;
unsigned int i;
i = 0;
if (!s || start >= ft_strlen(s) || len <= 0)
{
tmp = malloc(1);
if (!tmp)
return (NULL);
tmp[i] = 0;
return (tmp);
}
if (len + start > ft_strlen(s))
len = ft_strlen(s) - start;
tmp = malloc(sizeof(*tmp) * len + 1);
if (!tmp)
return (NULL);
while (i < len && s[i])
{
tmp[i] = s[i + start];
i++;
}
tmp[i] = 0;
return (tmp);
}

20
libft/ft_tolower.c Normal file
View File

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_tolower.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/03 12:01:54 by vvobis #+# #+# */
/* Updated: 2024/04/03 12:15:18 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_tolower(int c)
{
if (c >= 65 && c <= 90)
c += 32;
return (c);
}

20
libft/ft_toupper.c Normal file
View File

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_toupper.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/03 12:18:44 by vvobis #+# #+# */
/* Updated: 2024/04/03 12:19:05 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
int ft_toupper(int c)
{
if (c >= 97 && c <= 122)
c -= 32;
return (c);
}

109
libft/get_next_line.c Normal file
View File

@ -0,0 +1,109 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/18 20:20:17 by vvobis #+# #+# */
/* Updated: 2024/06/14 00:05:31 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
void *buffer_extend(void *ptr_old, size_t size_new, size_t size_old)
{
void *ptr_new;
void *ptr_back;
void *ptr_old_free;
ptr_new = g_calloc(size_new + 1, 1);
if (!ptr_new)
return (free(ptr_old), ptr_old = NULL, NULL);
ptr_back = ptr_new;
ptr_old_free = ptr_old;
while (size_old--)
*(char *)ptr_new++ = *(char *)ptr_old++;
return (free(ptr_old_free), ptr_old_free = NULL, ptr_back);
}
char *handle_no_nl(char **buf, char **left)
{
if (left)
{
free(*left);
*left = NULL;
}
if (!buf)
return (NULL);
if (g_strlen(*buf))
return (*buf);
free(*buf);
*buf = NULL;
return (NULL);
}
char *line_extract(char **buf_joined, char **left, size_t line_len)
{
char *line;
line = g_substr(*buf_joined, 0, line_len);
if (!line)
return (free(*buf_joined), *buf_joined = NULL, (char *)-1);
*left = g_substr(*buf_joined, line_len, g_strlen(*buf_joined) - line_len);
free(*buf_joined);
*buf_joined = NULL;
if (!*left)
return (free(line), line = NULL, (char *)-1);
return (line);
}
char *line_handle(char **buf_fetch)
{
char *buf_joined;
size_t line_len;
static char *left;
if (!buf_fetch)
return (free(left), left = NULL, (char *)-1);
buf_joined = g_strjoin(left, *buf_fetch);
free(*buf_fetch);
*buf_fetch = NULL;
free(left);
left = NULL;
if (!buf_joined)
return ((char *)-1);
line_len = find_newline(buf_joined);
if (line_len)
return (line_extract(&buf_joined, &left, line_len));
return (handle_no_nl(&buf_joined, &left));
}
char *get_next_line(int fd)
{
char *buf;
ssize_t bytes_read;
size_t buf_size_cur;
size_t buf_size_prev;
if (fd < 0)
return (line_handle(NULL), NULL);
buf = g_calloc(sizeof(*buf), BUFFER_SIZE + 1);
buf_size_prev = 0;
buf_size_cur = BUFFER_SIZE;
while (1)
{
if (!buf)
return (line_handle(NULL));
bytes_read = read(fd, buf + buf_size_prev, BUFFER_SIZE);
if (bytes_read < 0)
return (free(buf), buf = NULL, line_handle(NULL));
if (find_newline(buf) || bytes_read == 0)
break ;
buf_size_prev = buf_size_cur;
buf_size_cur += BUFFER_SIZE;
buf = buffer_extend(buf, buf_size_cur, buf_size_prev);
}
return (line_handle(&buf));
}

38
libft/get_next_line.h Normal file
View File

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/15 14:07:36 by vvobis #+# #+# */
/* Updated: 2024/05/27 17:43:21 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef GET_NEXT_LINE_H
# define GET_NEXT_LINE_H
# ifndef BUFFER_SIZE
# define BUFFER_SIZE 50
# endif
# define MAX_FD 1024
# include <stdlib.h>
# include <unistd.h>
# include <fcntl.h>
# include <stdint.h>
char *get_next_line(int fd);
char *g_strjoin(char const *s1, char const *s2);
size_t g_strlen(char const *str);
void *g_calloc(size_t n, size_t s);
char *g_substr(char const *s, unsigned int start, size_t len);
char *line_handle(char **buf_fetch);
size_t find_newline(char *buf);
#endif

118
libft/get_next_line_utils.c Normal file
View File

@ -0,0 +1,118 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/15 14:14:13 by vvobis #+# #+# */
/* Updated: 2024/06/13 23:37:48 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
size_t g_strlen(char const *str)
{
size_t i;
if (!str)
return (0);
i = 0;
while (*str)
{
i++;
str++;
}
return (i);
}
size_t find_newline(char *buf)
{
size_t i;
if (!buf)
return (0);
i = 0;
while (*buf)
{
if (*buf == '\n')
return (i + 1);
i++;
buf++;
}
return (0);
}
char *g_strjoin(char const *s1, char const *s2)
{
char *tmp;
unsigned int i;
unsigned int j;
if (!s2)
return (NULL);
if (!s1)
return (g_substr(s2, 0, g_strlen(s2)));
tmp = g_calloc(g_strlen(s1) + g_strlen(s2) + 1, sizeof(*tmp));
if (!tmp)
return (NULL);
i = 0;
if (s1)
{
while (s1[i])
{
tmp[i] = s1[i];
i++;
}
}
j = 0;
if (s2)
while (s2[j])
tmp[i++] = s2[j++];
return (tmp);
}
char *g_substr(char const *s, unsigned int start, size_t len)
{
char *tmp;
unsigned int i;
i = 0;
if (!s || start >= g_strlen(s) || len <= 0)
{
tmp = malloc(1);
if (!tmp)
return (NULL);
tmp[i] = 0;
return (tmp);
}
if (len + start > g_strlen(s))
len = g_strlen(s) - start;
tmp = g_calloc(len + 1, sizeof(*tmp));
if (!tmp)
return (NULL);
while (i < len && s[i])
{
tmp[i] = s[i + start];
i++;
}
return (tmp);
}
void *g_calloc(size_t n, size_t s)
{
char *tmp;
unsigned long i;
i = 0;
if (n == 0)
return (malloc(0));
if (SIZE_MAX / n < s)
return (NULL);
tmp = malloc(n * s);
if (tmp)
while (i < n * s)
tmp[i++] = 0;
return ((void *)tmp);
}

BIN
libft/libft.a Normal file

Binary file not shown.

97
libft/libft.h Normal file
View File

@ -0,0 +1,97 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* libft.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/09 23:43:36 by vvobis #+# #+# */
/* Updated: 2024/08/23 15:52:33 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef LIBFT_H
# define LIBFT_H
# include <stdlib.h>
# include <unistd.h>
# include <stddef.h>
# include <stdint.h>
# include <limits.h>
# include "ft_printf.h"
# include <stdbool.h>
typedef struct s_list
{
void *content;
struct s_list *next;
} t_list;
/* Input Handeling */
char ***super_split(char **strs, int size, int delimiter);
void *free_super_split(char ***back);
char *get_next_line(int fd);
int ft_isalpha(int c);
int ft_isdigit(int c);
int ft_isalnum(int c);
int ft_isprint(int c);
int ft_isascii(int c);
int is_space(char const c);
/*Memory Management*/
int ft_memcmp(void *s1, void const *s2, size_t n);
void *ft_memset(void *s, int c, size_t n);
void ft_bzero(void *s, size_t n);
void *ft_memcpy(void *dest, void const *src, size_t n);
void *ft_memmove(void *dest, void const *src, size_t n);
void *ft_memchr(void *s, int c, size_t n);
void *ft_calloc(size_t n, size_t s);
/*Info Conversion*/
int ft_atoi(char const *s);
long ft_atol(char const *s, uint8_t *too_big);
char *ft_itoa(int n);
char *ft_ltoa(long long n);
char **ft_split(char const *s, char c);
/*String Manip*/
int ft_toupper(int c);
int ft_tolower(int c);
int ft_strncmp(char const *s1, char const *s2, size_t n);
char *ft_strnstr(char const *s1, char const *s2, size_t n);
char *ft_strchr(char const *s, int c);
char *ft_strrchr(char const *s, int c);
char *ft_strdup(char const *s);
char *ft_substr(char const *s, unsigned int start, size_t len);
char *ft_strjoin(char const *s1, char const *s2);
char *ft_strtrim(char const *s1, char const *set);
char *ft_strmapi(char const *s, char (*f)(unsigned int, char));
void ft_striteri(char const *s, void (*f)(unsigned int, char *));
size_t ft_strlcpy(char *dest, char const *src, size_t size);
size_t ft_strlcat(char *dest, char const *src, size_t size);
size_t ft_strlen(char const *str);
/*List manip*/
int ft_lstsize(t_list *lst);
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 *));
void ft_lstadd_front(t_list **lst, t_list *node_new);
void ft_lstadd_back(t_list **lst, t_list *node_new);
t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *));
t_list *ft_lstnew(void *content);
t_list *ft_lstlast(t_list *lst);
/*Output*/
void ft_putchar_fd(char c, int fd);
void ft_putstr_fd(const char *str, int fd);
void ft_putendl_fd(char *str, int fd);
void ft_putnbr_fd(int n, int fd);
/* safe functions */
void ft_free(void *ptr);
#endif

581
minishell.h Normal file
View File

@ -0,0 +1,581 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* minishell.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/05 12:16:38 by victor #+# #+# */
/* Updated: 2024/08/27 17:28:49 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef MINISHELL_H
# define MINISHELL_H
# include <stdbool.h>
# include "libft/libft.h"
# include <unistd.h>
# include <fcntl.h>
# include <sys/types.h>
# include <stdio.h>
# include <dirent.h>
# include <string.h>
# include <stdlib.h>
# include <sys/wait.h>
# include <termios.h>
# include <errno.h>
# include <signal.h>
# include <sys/ioctl.h>
# include <stddef.h>
# include <sys/stat.h>
# define PWD 0
# define CUSTOM 1
# define PROMPT_COMMAND_STACK_SIZE 16
# define PROMPT_INPUT_BUFFER_SIZE 4096
# define CURSOR_MOVE_HOME "\033[H"
# define GREEN "\033[0;32m"
# define RESET "\033[0m"
# define RED "\033[0;31m"
# define CURSOR_MOVE_UP "\033[A"
# define CURSOR_MOVE_DOWN "\033[B"
# define CURSOR_MOVE_RIGHT "\033[C"
# define CURSOR_MOVE_LEFT "\033[D"
# define CURSOR_POSITION_GET "\033[6n"
# define CURSOR_POSITION_SET "\033[%d;%dH"
# define CURSOR_POSITION_SAVE "\033[s"
# define CURSOR_POSITION_RESTORE "\033[u"
# define MAXIMUM_COLUMN 9999
# define MAXIMUM_ROW 9999
# define SCREEN_MAX "\033[9999;9999H"
# define DEL 127
# define EOT 4
# define ESC 27
# define VARIABLE_TOKEN_SIZE 1024
# define SCREEN_DISBLE_WRAPPING "\033[?7l"
# define SCREEN_ENABLE_WRAPPING "\033[?7h"
# define SCREEN_CLEAR_TO_EOL "\033[K"
# define SCREEN_CLEAR "\033[2J"
# define SCREEN_CLEAR_TO_EOF "\033[J"
# define ENVIRONMENT_SIZE 512
# define INITIAL_TOKEN_CAPACITY 16
# define BUFFER_CAPACITY 64
typedef struct s_history_buffer
{
uint write;
uint read;
uint buffer_capacity;
char *buffer[BUFFER_CAPACITY];
} t_history_buffer;
typedef struct s_prompt
{
bool exists;
char *prompt;
t_history_buffer history;
uint32_t cursor_position[2];
void (*prompt_display_func)(char *);
uint32_t prompt_length;
char *command;
} t_prompt;
typedef enum e_token_type
{
TOKEN_WORD = 1,
TOKEN_REDIRECT_OUT,
TOKEN_REDIRECT_IN,
TOKEN_REDIRECT_APPEND,
TOKEN_HEREDOC,
TOKEN_PIPE,
TOKEN_AND,
TOKEN_OR,
TOKEN_NEWLINE,
TOKEN_SEMICOLON,
TOKEN_EOL,
TOKEN_DONE,
} t_token_type;
typedef struct s_token
{
t_token_type token_type;
char *token_value;
} t_token;
typedef struct s_ring_buffer
{
uint write;
uint read;
uint buffer_capacity;
t_token *buffer[BUFFER_CAPACITY];
} t_ring_buffer;
typedef enum t_node_type
{
NODE_NONE,
NODE_END = TOKEN_EOL,
NODE_PIPE = 6,
NODE_LOGICAL_AND,
NODE_LOGICAL_OR,
NODE_NEWLINE,
NODE_INVALID,
} t_node_type;
typedef struct s_ast
{
t_node_type type;
t_token_type token_type;
char **args;
bool is_heredoc;
char *path_file_in;
char *path_file_out;
bool has_redir_in;
bool has_redir_out;
bool was_pipe;
int32_t pipefd[2];
int fd_in;
int fd_out;
pid_t cpid;
} t_ast;
enum e_alloc
{
ADD,
CLEAN,
END,
FREE,
};
typedef struct s_clean
{
void *content;
void (*clean)(void *del);
struct s_clean *next;
} t_clean;
extern int32_t volatile g_signal_flag;
/* Builtins */
int32_t ft_echo(char **args, int32_t *exit_status);
void ft_cd( const char **environment, \
const char **args, \
int32_t *exit_status);
void ft_pwd(const char **env, int32_t *exit_status);
void ft_env(const char **env, int32_t *exit_status);
void ft_unset( char **environment, \
const char **args, \
int32_t *exit_status);
void ft_export(const char **args, int32_t *exit_status);
void ft_exit(t_ast *tree, int *exit_status);
void *ft_realloc(void *ptr, int old_size, int new_size);
/* Commands */
bool is_buildin( t_ast *node);
bool buildin_execute( t_ast *node, \
const char **environment, \
int *exit_status);
void command_execute( char const *command_path, \
char const *argv[], \
char const **env);
void m_tokenizer( const char *input, \
char **env, \
int *exit_status, \
int32_t std[2]);
/* non_interactive */
int32_t minishell_single_command( char *command, \
char **environment, \
int32_t std[2]);
void *ft_realloc_string( char **string, uint32_t *new_size);
char *check_redir_input(void);
void setup_environment( const char **environment);
int setup( uint32_t argc, \
const char **argv, \
char **environment, \
int32_t std[2]);
/* Handle signal */
void handle_sigint(int sig);
void setup_signal_handlers(void);
/* Input */
void free_split(void *back);
uint32_t get_split_size(const char **split);
uint32_t get_split_length(char **split);
int get_amount_tokens(t_token *tokens);
/* List Memory */
void lst_memory(void *mem, void (*del)(void *c), int mode);
int p_stderr(int stderr_fd, const char *error, const char *specifier);
/* List */
t_clean *lst_node_new(void *content, void (*del)(void *));
void lst_node_del(t_clean **lst);
void lst_node_del_clean(t_clean **lst, void *mem);
void lst_list_clean(t_clean **head);
int lst_add_back(t_clean **node, t_clean *node_new);
/* Path Utils */
char *find_absolute_path( const char *path_variable, \
char *input, \
int *exit_status);
/* Prompt */
void prompt_destroy(void *prompt);
t_prompt prompt_create(uint8_t mode);
char *prompt_get(const char *prompt);
uint32_t prompt_display_string_set( t_prompt *prompt, \
const char **environment, \
const char *prompt_string);
void handle_arrow_key_up( t_history_buffer *history, \
char **input, \
uint32_t cursor_position_current[2]);
/* Prompt_print.c */
void prompt_print_custom_string(char *string);
void prompt_print_pwd(char *prompt);
/* Lexer */
void evaluate_input( char **input[], \
int32_t *exit_status, \
bool *error_caught);
uint32_t get_spaces(char *input);
uint32_t determine_variables(char **input);
void split_string_by_space(char *to_split, char **input_new);
void adjust_input(char **input, char *new_string);
uint32_t determine_full_length(char *string, char **environment);
uint32_t evaluate_variable( char ***input, \
int32_t *exit_status);
/* input skip pattern */
bool is_delimiter_variable(char c);
char skip_to_delimiter(char *input_new);
bool skip_single_quotes( char *input, \
uint32_t *i, \
bool *in_double_quotes);
bool evaluate_double_quotes(char *input, uint32_t *i);
bool evaluate_single_quotes(char *input, uint32_t *i);
/* Cursor Manipulation */
void cursor_position_get(uint32_t cursor_position[2]);
void cursor_position_save(void);
void cursor_position_restore(void);
bool handle_escape_sequence( t_prompt *prompt, \
char buffer[], \
char **input, \
uint32_t cursor_position[2]);
char *prompt_get_input( t_prompt *prompt, \
uint32_t prompt_initial_size, \
const char *delimiter);
bool handle_multiple_character( char **input, \
char buffer[], \
uint32_t cursor_position[2], \
uint32_t prompt_length);
/* Prompt Buffer Management */
void prompt_refresh_line( char *input, \
uint32_t cursor_position_base, \
uint32_t cursor_position[2]);
char *prompt_buffer_size_manage( char **input, \
uint32_t old_size, \
uint32_t size_to_add, \
uint32_t scalar);
void prompt_string_insert( char *string_to_insert, \
char **current_input, \
char *position_to_insert, \
uint32_t current_word_length);
bool handle_new_character_to_input( char **input, \
char character, \
uint32_t *cursor_position, \
uint32_t prompt_length);
uint8_t handle_single_char_input( char **input, char buffer[], \
uint32_t cursor_position[2], \
bool *do_refresh);
uint8_t handle_single_char_input( char **input, char buffer[], \
uint32_t cursor_position[2], \
bool *do_refresh);
bool handle_new_character_to_input( char **input, \
char character, \
uint32_t *cursor_position, \
uint32_t prompt_length);
/* Non Blocking mode */
void blocking_mode_toggle(int flag);
/* Tab Completion */
void handle_tab( char **input, t_prompt *prompt);
void handle_tab_no_match( const char *input_path, \
char **env, \
uint32_t cursor_position_current[2], \
t_prompt *prompt);
void handle_tab_yes_match( t_prompt *prompt, \
const char *next_word_match, \
char **input, \
uint32_t current_word_length);
char *determine_word( char *input, \
char **input_path, \
uint32_t cursor_position_current);
void get_next_word_match( char **input, \
t_prompt *prompt, \
char *input_path, \
bool *is_directory);
void handle_rapid_input( char buffer[], \
uint32_t cursor_position[2], \
char **input, \
uint32_t cursor_position_base);
void handle_backspace( char *input, \
uint32_t *cursor_position_current, \
uint32_t input_length_current);
/* Termios */
void terminal_raw_mode_enable(int flag);
void terminal_raw_mode_disable(int flag);
/* Utils */
int ft_close(int fd, const char *specifier);
void ft_pipe(int pipefd[2], const char *specifier);
void ft_dup2(int fd_old, int fd_new, const char *specifier);
void ft_fork(pid_t *pid, const char *specifier);
void ft_open(int *fd, const char *path, int flag, int mode);
int64_t ft_read(int fd, char *character, uint32_t size_read);
void ft_opendir(DIR **directory, const char *directory_path);
void close_fds(void *std_ptr);
/* Wildcards */
void check_and_expand_wildcards(char ***input);
int check_wildcard(char *str);
int get_tokens_count(char **tokens);
/* Wildcards Helper */
int compare_suffix( const char *current_position_in_str, \
const char *current_position_in_pattern);
int handle_prefix( const char *pattern, \
const char *str, \
char *adr_next_wild);
int handle_middle( const char *pattern, const char *str);
char **expand_wildcard( const char *pattern);
/* Environment_variable */
void environment_variable_print( const char *variable, \
const char **environment);
void environment_print( const char **environment);
char **environment_create( const char **env);
void environment_variable_remove( char **environment, \
const char *variable);
void environment_variable_add( char ***environment, \
const char *variable_name, \
const char *variable_value);
char **environment_variable_get( const char *variable, \
const char **environment);
char *environment_variable_value_get( const char *variable, \
const char **environment);
void environment_variable_value_change( const char **environment, \
const char *variable_name, \
const char *variable_value);
char **env_static(char **environment);
/*check_special_symbol.c*/
int is_special_char(char c);
int ft_isspace(char c);
bool is_in_alphabet(char c);
bool unrecognized_input(char c);
/*create_token_double_special_symbol.c*/
int is_double_special(const char *input);
t_token create_token_double_special_symbol(char **input);
bool is_mutliple_lines(char *c);
void remove_qoutes_delimiter(char *delimiter, uint32_t *length);
void token_heredoc_get( t_token *token, const char *delimiter);
/* token_heredoc.c */
char *heredoc_while_tokenizing(char *input);
char *handle_delimiter(char *input, char **temp_move);
char *heredoc_loop( char *input, \
char *temp_move, \
const char *delimiter, \
uint32_t delimiter_length);
/* handle_heredoc.c */
void handle_heredoc(t_token tokens, int32_t fd);
bool heredoc_has_been_done(t_token *token, char *value, int fd);
void print_value(char *value, int fd);
void remove_quotes(char *s);
/*create_token_single_special_symbol.c*/
int is_single_special(const char input);
t_token create_token_single_special_symbol(const char **input);
/*create_token_word.c*/
t_token create_token_word(const char **input);
/*create_token.c*/
t_token create_token(t_token_type token_type, const char *value);
/*env_utils.c*/
void print_tokens(t_token *tokens);
/* subshell.c */
char *execute_subshell(char *input, const char **environement);
/*tokenizer.c*/
t_token *lexical_analysis(char *input);
/* tokenizer_heredoc_helper.c */
void ring_buffer_put( t_ring_buffer *buffer, t_token *entry);
t_token *ring_buffer_get( t_ring_buffer *buffer);
t_token mark_tokens_till_heredoc( char *value, char **input);
void tokenizing_loop( char **input, \
t_token *tokens, \
uint32_t *i, \
t_ring_buffer *heredoc_buffer);
/*ats_print.c*/
void print_ast(t_ast *head);
/*handle_command.c*/
void handle_command( t_ast *current, \
const char **env, \
int *exit_status, \
int std[2]);
void execute_commands( t_ast *tree, \
const char **env, \
int *exit_status, \
int32_t std[2]);
void wait_pids( t_ast *tree, \
uint pid_count, \
pid_t pid_final, \
int32_t *exit_status);
/*handle_fds.c*/
bool handle_fds_child_proccess(t_ast *command, int32_t *exit_status);
void handle_fds_parent_proccess(t_ast *command, int32_t *exit_status);
void handle_pipe_in_child(t_ast *command);
void handle_pipe_in_parent(t_ast *command);
bool buildin_apply_pipe(t_ast *node, int32_t *exit_status);
/*handle_logical_operator.c*/
void handle_logical_operator(t_ast **logical_node, int exit_status);
/* handle_pipes.c */
void handle_pipe(t_ast *pipe_node, int *error_catched);
/*handle_redirs.c*/
void handle_redir_in( t_ast *branch, \
t_token *token, \
t_token *token_next);
void handle_redir_out( t_ast *branch, \
t_token *token, \
t_token *token_next);
void handle_redir_append( t_ast *branch, \
t_token *token, \
t_token *token_next);
void handle_redir_heredoc( t_ast *branch, \
t_token *token, \
uint8_t token_id);
/*parse_tokens.c*/
t_ast *parse_tokens( t_token *tokens, \
int32_t *exit_status);
uint32_t determine_trees(t_token *tokens);
void tree_destroy(void *tree_ptr);
/* Syntac_check.c */
void check_valid_logical_operator( t_token *token, \
int index, \
int *error_catched);
void check_valid_pipe( t_token *token, \
int index, \
int *error_catched);
void check_valid_redir( t_token *token, \
int index, \
int *error_catched);
void print_error_redir( t_token_type token_type);
void print_error_logical_operator( t_token_type token_type);
void restore_fd(int std[2]);
/*parser.c*/
void fill_args( char ***args, \
int count, \
char *token_value, \
int *capacity);
bool is_delimiter_token(t_token *token);
/*syntax_check.c*/
void check_valid_redir( t_token *token, \
int index, \
int *error_catched);
void check_valid_pipe( t_token *token, \
int index, \
int *error_catched);
void check_valid_logical_operator( t_token *token, \
int index, \
int *error_catched);
void check_valid_heredoc(t_token *token, int index, int *error_catched);
/* syntax_check_helper.c */
void print_error_logical_operator(t_token_type token_type);
void print_error_pipe(void);
void print_error_redir(t_token_type token_type);
void free_tokens(void *token_ptr);
#endif

84
prompt/arrowkeys.c Normal file
View File

@ -0,0 +1,84 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* arrowkeys.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/08 11:02:39 by victor #+# #+# */
/* Updated: 2024/08/26 18:22:57 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
#include <stdint.h>
void handle_arrow_key_up( t_history_buffer *history,
char **input,
uint32_t cursor_position_current[2])
{
if (cursor_position_current[0] > 0)
ft_putstr_fd(CURSOR_MOVE_UP, 1);
if (history->read == 0)
history->read = history->buffer_capacity - 1;
else
history->read -= 1;
if (history->buffer[history->read] == 0)
{
history->read = (history->read + 1) % history->buffer_capacity;
return ;
}
if (history->buffer[history->write] == 0)
history->buffer[history->write] = *input;
*input = history->buffer[history->read];
cursor_position_current[1] = ft_strlen(*input);
}
static void handle_arrow_key_down( t_history_buffer *history,
uint32_t cursor_position[2],
char **input)
{
if (history->read == history->write)
return ;
history->read = (history->read + 1) % history->buffer_capacity;
*input = history->buffer[history->read];
cursor_position[1] = ft_strlen(*input);
}
static void handle_arrow_key_right( uint32_t *cursor_position_current,
uint32_t prompt_length_current)
{
if (cursor_position_current[1] < prompt_length_current)
cursor_position_current[1]++;
else
ft_putstr_fd(CURSOR_MOVE_LEFT, 1);
}
static void handle_arrow_key_left( uint32_t *cursor_position_current)
{
if (cursor_position_current[1] > 0)
cursor_position_current[1]--;
else
ft_putstr_fd(CURSOR_MOVE_RIGHT, 1);
}
bool handle_escape_sequence( t_prompt *prompt,
char buffer[],
char **input,
uint32_t cursor_position_current[2])
{
uint32_t prompt_length_current;
prompt_length_current = ft_strlen(*input);
if (buffer[0] == 91 && buffer[1] == 65)
return (handle_arrow_key_up(&prompt->history, \
input, cursor_position_current), 1);
else if (buffer[0] == 91 && buffer[1] == 66)
return (handle_arrow_key_down(&prompt->history, \
cursor_position_current, input), 1);
else if (buffer[0] == 91 && buffer[1] == 67)
handle_arrow_key_right(cursor_position_current, prompt_length_current);
else if (buffer[0] == 91 && buffer[1] == 68)
handle_arrow_key_left(cursor_position_current);
return (0);
}

40
prompt/escape_sequences.c Normal file
View File

@ -0,0 +1,40 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* escape_sequences.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/07 19:29:29 by vvobis #+# #+# */
/* Updated: 2024/08/26 17:05:22 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void cursor_position_get(uint32_t cursor_position[2])
{
char cursor_position_str[32];
char *cursor_position_str_ptr;
char *cursor_position_str_ptr2;
int bytes_read;
ft_bzero(&cursor_position_str, 32);
write(1, CURSOR_POSITION_GET, ft_strlen(CURSOR_POSITION_GET));
bytes_read = read(1, cursor_position_str, 32);
if (bytes_read == -1)
return (perror("read"));
cursor_position_str_ptr = cursor_position_str;
cursor_position_str_ptr2 = ft_strchr(cursor_position_str, ';');
if (!cursor_position_str_ptr2)
return ;
*cursor_position_str_ptr2 = 0;
while (!(*cursor_position_str_ptr >= '0'
&& *cursor_position_str_ptr <= '9'))
cursor_position_str_ptr++;
cursor_position[0] = ft_atoi(cursor_position_str_ptr);
cursor_position_str_ptr = cursor_position_str_ptr2 + 1;
cursor_position_str_ptr2 = ft_strchr(cursor_position_str_ptr, 'R');
*cursor_position_str_ptr2 = 0;
cursor_position[1] = ft_atoi(cursor_position_str_ptr);
}

View File

@ -0,0 +1,22 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* non_blocking_mode.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/02 17:14:46 by vvobis #+# #+# */
/* Updated: 2024/08/02 17:16:33 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void blocking_mode_toggle(int flag)
{
if (ioctl(0, FIONBIO, &flag) == -1)
{
perror("ioctl");
exit(1);
}
}

View File

@ -0,0 +1,133 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* prompt_handle_chars.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/02 17:11:28 by vvobis #+# #+# */
/* Updated: 2024/08/24 12:55:44 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
uint8_t handle_single_char_input( char **input, char buffer[], \
uint32_t cursor_position_current[2], \
bool *do_refresh)
{
uint32_t input_length_current;
uint32_t new_buffer_length;
input_length_current = ft_strlen(*input);
new_buffer_length = ft_strlen(buffer);
if (new_buffer_length == 1)
{
if (ft_isprint(buffer[0]) || buffer[0] == '\n')
return (*do_refresh = \
handle_new_character_to_input(input, buffer[0], \
cursor_position_current, input_length_current), 1);
else if (buffer[0] == EOT \
&& (input_length_current == 0 \
|| (*input)[input_length_current - 1] == '\n'))
return (ft_putstr_fd("\n", 1), \
terminal_raw_mode_disable(ECHOCTL), \
g_signal_flag = 2, 1);
}
else
{
*do_refresh = handle_multiple_character(input, buffer, \
cursor_position_current, input_length_current);
return (1);
}
return (0);
}
bool handle_new_character_to_input( char **input,
char character,
uint32_t *cursor_position_current,
uint32_t prompt_length_current)
{
bool do_refresh;
do_refresh = false;
*input = prompt_buffer_size_manage(input, \
prompt_length_current, \
prompt_length_current + 1, \
PROMPT_INPUT_BUFFER_SIZE);
if (cursor_position_current[1] < prompt_length_current)
{
ft_memmove(&(*input)[cursor_position_current[1] + 1], \
&(*input)[cursor_position_current[1]], \
prompt_length_current - cursor_position_current[1]);
do_refresh = true;
}
(*input)[cursor_position_current[1]] = character;
cursor_position_current[1]++;
return (do_refresh);
}
bool handle_multiple_character( char **input,
char buffer[],
uint32_t cursor_position_current[2],
uint32_t prompt_length_current)
{
bool do_refresh;
uint32_t buffer_length;
do_refresh = false;
buffer_length = ft_strlen(buffer);
prompt_buffer_size_manage(input, \
prompt_length_current, \
prompt_length_current \
+ buffer_length + 1, \
PROMPT_INPUT_BUFFER_SIZE);
if (cursor_position_current[1] < prompt_length_current - 1)
{
ft_memmove(&(*input)[cursor_position_current[1] + buffer_length], \
&(*input)[cursor_position_current[1]], \
prompt_length_current - cursor_position_current[1] \
+ buffer_length);
do_refresh = true;
}
ft_memcpy(&(*input)[cursor_position_current[1]], buffer, buffer_length);
(cursor_position_current[1]) += buffer_length;
return (do_refresh);
}
void handle_backspace( char *input,
uint32_t *cursor_position_current,
uint32_t input_length_current)
{
if (cursor_position_current[1] <= 0)
return ;
cursor_position_current[1]--;
ft_memmove(&input[cursor_position_current[1]], \
&input[cursor_position_current[1] + 1], \
input_length_current - cursor_position_current[1]);
ft_putstr_fd(CURSOR_MOVE_LEFT, 1);
}
void handle_rapid_input( char buffer[], \
uint32_t cursor_position[2], \
char **input, \
uint32_t cursor_position_base)
{
int32_t bytes_read;
bool do_refresh;
blocking_mode_toggle(1);
bytes_read = 1;
do_refresh = true;
while (bytes_read > 0)
{
handle_multiple_character(input, buffer, \
cursor_position, \
ft_strlen(*input));
ft_bzero(buffer, 100);
bytes_read = ft_read(0, buffer, 99);
}
blocking_mode_toggle(0);
if (do_refresh)
prompt_refresh_line(*input, cursor_position_base, cursor_position);
}

128
prompt/prompt_input.c Normal file
View File

@ -0,0 +1,128 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* prompt_input.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/07 19:40:20 by vvobis #+# #+# */
/* Updated: 2024/08/27 17:38:01 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
#include <stdbool.h>
#include <stdint.h>
static void handle_accepted_input( t_prompt *prompt, \
uint32_t cursor_position[2], \
char **input, \
char buffer[])
{
bool do_refresh;
do_refresh = true;
if (buffer[0] == ESC)
do_refresh = handle_escape_sequence(prompt, &buffer[1], \
input, cursor_position);
else if (buffer[0] == '\t')
handle_tab(input, prompt);
else if (buffer[0] == DEL)
handle_backspace(*input, cursor_position, \
ft_strlen(*input));
else if (buffer[0] == '\n')
{
handle_new_character_to_input(input, buffer[0], cursor_position, \
ft_strlen(*input));
prompt->prompt_display_func(prompt->prompt);
cursor_position[0]++;
return ;
}
else
handle_single_char_input(input, buffer, cursor_position, &do_refresh);
if (do_refresh == true && g_signal_flag != 2)
prompt_refresh_line(*input, prompt->prompt_length, cursor_position);
}
static bool is_delimiter(char *input, const char *delimiter)
{
char *tmp;
uint32_t delimiter_length;
if (*delimiter == '\n')
return (true);
delimiter_length = ft_strlen(delimiter);
tmp = ft_strrchr(input - (*input == '\n' && ft_strlen(input) > 0), '\n');
if (tmp)
if (tmp++ && ((*tmp == *delimiter && delimiter_length == 1) \
|| ft_strncmp(tmp, delimiter, delimiter_length) == 0))
return (*tmp = 0, true);
if ((*input == *delimiter && delimiter_length == 1) \
|| ft_strncmp(input, delimiter, delimiter_length) == 0)
return (*input = 0, true);
return (false);
}
static char *handle_input( t_prompt *prompt, \
char *input, \
uint32_t cursor_position[2], \
const char *delimiter)
{
char buffer[100];
int64_t bytes_read;
while (1)
{
ft_bzero(buffer, 100);
bytes_read = ft_read(0, buffer, 20);
if (g_signal_flag == 1)
return (ft_putstr_fd("^C\n", 1), NULL);
if (bytes_read > 3)
handle_rapid_input(buffer, cursor_position, &input, \
prompt->prompt_length);
else if (bytes_read >= 1)
{
bytes_read = ft_strlen(buffer);
if (buffer[bytes_read - (bytes_read > 0)] == '\n')
if (is_delimiter(input, delimiter))
break ;
handle_accepted_input(prompt, cursor_position, &input, buffer);
}
if (g_signal_flag == 2)
return (NULL);
}
return (input);
}
static void prompt_handle_history(t_history_buffer *buffer, char *input)
{
buffer->buffer[buffer->write++] = input;
buffer->write %= buffer->buffer_capacity;
buffer->buffer[buffer->write] = 0;
buffer->read = buffer->write;
}
char *prompt_get_input( t_prompt *prompt, \
uint32_t prompt_initial_size, \
const char *delimiter)
{
char *input;
input = ft_calloc(prompt_initial_size, sizeof(*input));
if (!input)
return (perror("malloc"), NULL);
lst_memory(input, free, ADD);
terminal_raw_mode_enable(ECHOCTL | ICANON);
prompt->prompt_display_func(prompt->prompt);
cursor_position_get(prompt->cursor_position);
prompt->cursor_position[1] = 0;
if (!delimiter)
delimiter = "\n";
input = handle_input(prompt, input, prompt->cursor_position, delimiter);
prompt_handle_history(&prompt->history, input);
terminal_raw_mode_disable(ECHO | ECHOCTL | ICANON);
if (!input)
return (NULL);
prompt->command = input;
return (input);
}

25
prompt/prompt_print.c Normal file
View File

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* prompt_print.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/02 16:11:25 by vvobis #+# #+# */
/* Updated: 2024/08/02 16:12:18 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void prompt_print_pwd(char *prompt)
{
ft_putstr_fd(GREEN, 1);
ft_printf("[%s]$ ", prompt);
ft_putstr_fd(RESET, 1);
}
void prompt_print_custom_string(char *string)
{
ft_putstr_fd(string, 1);
}

View File

@ -0,0 +1,72 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* prompt_string_management.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/09 08:16:45 by victor #+# #+# */
/* Updated: 2025/02/15 15:00:14 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
#include <stdint.h>
#include <sys/types.h>
void cursor_position_save(void)
{
ft_putstr_fd(CURSOR_POSITION_SAVE, 1);
}
void cursor_position_restore(void)
{
ft_putstr_fd(CURSOR_POSITION_RESTORE, 1);
}
void cursor_position_set(uint32_t row, uint32_t column)
{
ft_printf(CURSOR_POSITION_SET, row, column);
}
void prompt_refresh_line(char *input, \
uint32_t cursor_position_base, \
uint32_t cursor_position_current[2])
{
uint32_t cursor_position_store;
cursor_position_store = cursor_position_current[1];
cursor_position_set(cursor_position_current[0], cursor_position_base);
ft_putstr_fd(SCREEN_CLEAR_TO_EOL, 1);
ft_putstr_fd(input, 1);
cursor_position_set(cursor_position_current[0], \
cursor_position_current[1] + cursor_position_base);
cursor_position_current[1] = cursor_position_store;
}
char *prompt_buffer_size_manage( char **input, \
uint32_t old_size, \
uint32_t size_to_add, \
uint32_t scalar)
{
char *input_free_ptr;
uint32_t new_size;
if (scalar == 0)
return (*input);
if ((old_size + size_to_add) > \
(scalar * \
((old_size / scalar) + 1)))
{
new_size = old_size + size_to_add;
new_size += new_size % scalar;
input_free_ptr = *input;
*input = ft_calloc(1, new_size + 1);
if (!*input)
return (perror("malloc"), lst_memory(NULL, NULL, CLEAN), NULL);
ft_memcpy(*input, input_free_ptr, old_size);
lst_memory(input_free_ptr, NULL, FREE);
lst_memory(*input, free, ADD);
}
return (*input);
}

81
prompt/prompt_utils.c Normal file
View File

@ -0,0 +1,81 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* prompt_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/07 19:23:40 by anarama #+# #+# */
/* Updated: 2024/08/26 17:47:31 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void prompt_destroy(void *prompt)
{
t_prompt *prompt_ptr;
prompt_ptr = (t_prompt *)prompt;
ft_free(&prompt_ptr);
}
uint32_t prompt_display_string_set( t_prompt *prompt, \
const char **environment, \
const char *prompt_string)
{
char *pwd;
uint32_t prompt_string_length;
if (!prompt_string)
{
pwd = environment_variable_value_get("PWD", environment);
prompt_string_length = ft_strlen(pwd) + 5;
prompt->prompt = pwd;
}
else
{
prompt_string_length = ft_strlen(prompt_string) + 1;
prompt->prompt = (char *)prompt_string;
}
return (prompt_string_length);
}
char *prompt_get(const char *prompt)
{
char *input;
char **environment;
static t_prompt _prompt = {0};
environment = env_static(NULL);
if (!_prompt.exists)
_prompt = prompt_create(PWD);
_prompt.prompt = NULL;
_prompt.prompt_length = prompt_display_string_set(&_prompt, \
(const char **)environment, \
prompt);
prompt_get_input(&_prompt, PROMPT_INPUT_BUFFER_SIZE, "\n");
if (!_prompt.command || !*_prompt.command)
return (NULL);
ft_putstr_fd(SCREEN_CLEAR_TO_EOF, 1);
input = ft_strdup(_prompt.command);
if (!input)
return (perror("malloc"), lst_memory(NULL, NULL, CLEAN), NULL);
lst_memory(input, free, ADD);
return (input);
}
t_prompt prompt_create(uint8_t mode)
{
t_prompt tmp;
tmp = (t_prompt){0};
tmp.history = (t_history_buffer){0};
tmp.history.buffer_capacity = BUFFER_CAPACITY;
tmp.exists = true;
if (mode == PWD)
tmp.prompt_display_func = prompt_print_pwd;
else if (mode == CUSTOM)
tmp.prompt_display_func = prompt_print_custom_string;
return (tmp);
}

118
prompt/tab_completion.c Normal file
View File

@ -0,0 +1,118 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tab_completion.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/08 14:53:58 by victor #+# #+# */
/* Updated: 2025/02/15 22:23:43 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
#include <sys/ioctl.h>
void handle_tab_no_match(const char *input_path, \
char **env, \
uint32_t cursor_position_current[2], \
t_prompt *prompt)
{
struct winsize win;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
cursor_position_save();
ft_putstr_fd(SCREEN_CLEAR_TO_EOF, 0);
ft_putstr_fd("\n\r", 1);
command_execute("/bin/ls", \
(const char *[]){"ls", input_path, NULL}, \
(const char **)env);
cursor_position_restore();
if (cursor_position_current[0] == win.ws_row)
prompt->prompt_display_func(prompt->prompt);
}
void handle_tab_yes_match( t_prompt *prompt, \
const char *next_word_match, \
char **input, \
uint32_t current_word_length)
{
struct winsize win;
ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
handle_multiple_character(input, \
(char *)(next_word_match + current_word_length), \
prompt->cursor_position, ft_strlen(*input));
cursor_position_save();
ft_putstr_fd("\n\r", 1);
ft_putstr_fd(SCREEN_CLEAR_TO_EOF, 0);
cursor_position_restore();
if (prompt->cursor_position[0] == win.ws_row)
prompt->prompt_display_func(prompt->prompt);
}
char *determine_word(char *input, \
char **input_path, \
uint32_t cursor_position_current)
{
char *current_word;
char *current_word_path_end;
char *tmp;
uint32_t i;
i = cursor_position_current - (cursor_position_current > 0);
current_word_path_end = NULL;
while (i > 0 && input[i] != ' ')
i--;
current_word = &input[i + (i > 0)];
tmp = ft_strchr(current_word, '/');
while (tmp)
{
current_word_path_end = tmp;
tmp = ft_strchr(tmp + 1, '/');
}
if (current_word_path_end)
{
*input_path = ft_substr(current_word, 0, \
current_word_path_end - current_word + 1);
current_word = current_word_path_end + 1;
return (current_word);
}
return (current_word);
}
uint32_t find_last_matching_char(const char *current_word, \
const char *next_word_match)
{
uint32_t i;
char *current_word_without_path;
if (!next_word_match)
return (0);
current_word_without_path = ft_strrchr(current_word, '/');
i = 0;
if (current_word_without_path)
while ((current_word_without_path)[i] == next_word_match[i])
i++;
else
while (current_word[i] == next_word_match[i])
i++;
return (i);
}
void handle_tab(char **input, t_prompt *prompt)
{
char *input_path;
char **environment;
bool is_directory;
environment = env_static(NULL);
if (!(*input)[(prompt->cursor_position)[1] \
- ((prompt->cursor_position)[1] > 0)])
return (handle_tab_no_match(".", environment, \
prompt->cursor_position, \
prompt));
input_path = NULL;
is_directory = false;
get_next_word_match(input, prompt, input_path, &is_directory);
}

88
prompt/tab_get_word.c Normal file
View File

@ -0,0 +1,88 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* tab_get_word.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/02 17:00:19 by vvobis #+# #+# */
/* Updated: 2024/08/26 18:22:17 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
static char *find_next_match( char *current_word, \
uint32_t current_word_length, \
DIR *directory_current, \
bool *is_directory)
{
struct dirent *directory_entry;
char *next_word_match;
*is_directory = false;
next_word_match = NULL;
if (!current_word || !directory_current || !*current_word)
return (NULL);
while (1)
{
directory_entry = readdir(directory_current);
if (directory_entry == NULL)
break ;
if (ft_strncmp(current_word, \
directory_entry->d_name, \
current_word_length) == 0)
{
next_word_match = directory_entry->d_name;
if (directory_entry->d_type == DT_DIR)
*is_directory = true;
}
}
return (next_word_match);
}
uint32_t get_current_word_length(char *word)
{
char *word_end;
if (!word)
return (0);
else if (*word == ' ')
return (1);
word_end = ft_strchr(word, ' ');
if (word_end)
return (word_end - word);
return (ft_strlen(word));
}
void get_next_word_match( char **input, \
t_prompt *prompt, \
char *input_path, \
bool *is_directory)
{
DIR *directory_current;
uint32_t current_word_length;
char *next_word_match;
char *current_word;
current_word = determine_word(*input, &input_path, \
prompt->cursor_position[1]);
current_word_length = get_current_word_length(current_word);
if (input_path)
directory_current = opendir(input_path);
else
directory_current = opendir("./");
next_word_match = find_next_match(current_word, current_word_length, \
directory_current, is_directory);
if (!next_word_match)
handle_tab_no_match(input_path, env_static(NULL), \
prompt->cursor_position, prompt);
else
handle_tab_yes_match(prompt, next_word_match, input, \
ft_strlen(current_word));
if (*is_directory)
handle_new_character_to_input(input, '/', prompt->cursor_position, \
ft_strlen(*input));
closedir(directory_current);
ft_free(&input_path);
}

74
src/commands.c Normal file
View File

@ -0,0 +1,74 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* commands.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/06 21:20:49 by victor #+# #+# */
/* Updated: 2024/08/27 17:26:44 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void restore_fd(int std[2])
{
ft_dup2(std[0], STDIN_FILENO, "in restore_fd");
ft_dup2(std[1], STDOUT_FILENO, "in restore_fd");
ft_close(std[0], "in execution");
ft_close(std[1], "in execution");
std[0] = dup(STDIN_FILENO);
std[1] = dup(STDOUT_FILENO);
if (std[0] == -1 || std[1] == -1)
{
perror("dup");
lst_memory(NULL, NULL, CLEAN);
}
}
void close_fds(void *std_ptr)
{
int *std;
std = std_ptr;
ft_close(STDIN_FILENO, "close fds");
ft_close(STDOUT_FILENO, "close fds");
ft_close(STDERR_FILENO, "close fds");
ft_close(std[0], "close fds");
ft_close(std[1], "close fds");
}
void print_tokens(t_token *tokens)
{
int i;
i = 0;
printf("----TOKENS----\n");
while (tokens[i].token_type != TOKEN_EOL)
{
printf("Token: Type=%d, Value=%s\n", \
tokens[i].token_type, tokens[i].token_value);
i++;
}
printf("------------\n");
}
void m_tokenizer( const char *input, char **env, \
int *exit_status, int32_t std[2])
{
t_token *tokens;
t_ast *tree;
if (input)
{
tokens = lexical_analysis((char *)input);
if (tokens)
{
tree = parse_tokens(tokens, exit_status);
if (tree)
execute_commands(tree, (const char **)env, exit_status, std);
lst_memory(tokens, NULL, FREE);
}
}
}

129
src/environment_variables.c Normal file
View File

@ -0,0 +1,129 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* environment_variables.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/16 11:56:00 by vvobis #+# #+# */
/* Updated: 2024/08/19 23:06:52 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
#include <stdint.h>
void environment_print(const char **environment)
{
uint32_t i;
i = 0;
while (environment[i])
{
ft_putendl_fd((char *)environment[i], 1);
i++;
}
}
void environment_variable_print( const char *variable, \
const char **environment)
{
uint32_t i;
uint64_t variable_length;
char *variable_findable_name;
if (!variable || !environment)
return ;
i = 0;
variable_length = ft_strlen(variable);
variable_findable_name = ft_calloc(variable_length + 2, sizeof(*variable));
if (!variable_findable_name)
return (lst_memory(NULL, NULL, CLEAN));
ft_strlcpy(variable_findable_name, variable, variable_length + 1);
ft_strlcpy(variable_findable_name + variable_length, "=", 2);
variable_length = ft_strlen(variable_findable_name);
while (environment[i])
{
if (ft_strncmp(variable_findable_name, environment[i], \
variable_length) == 0)
{
ft_putendl_fd((char *)environment[i] + variable_length, 1);
break ;
}
i++;
}
ft_free((void **)&variable_findable_name);
}
char *environment_variable_value_get( const char *variable, \
const char **environment)
{
uint32_t i;
uint64_t variable_length;
if (!variable || !environment)
return (NULL);
i = 0;
variable_length = ft_strlen(variable);
while (environment[i])
{
if (ft_strncmp(variable, environment[i], \
variable_length) == 0)
if (environment[i][variable_length] == '=')
return ((char *)environment[i] + variable_length + 1);
i++;
}
return (NULL);
}
char **environment_variable_get( const char *variable, \
const char **environment)
{
uint32_t i;
uint64_t variable_length;
char *variable_findable_name;
if (!variable || !environment)
return (NULL);
i = 0;
variable_length = ft_strlen(variable);
variable_findable_name = ft_calloc(variable_length + 2, sizeof(*variable));
if (!variable_findable_name)
return (lst_memory(NULL, NULL, CLEAN), NULL);
ft_strlcpy(variable_findable_name, variable, variable_length + 1);
ft_strlcpy(variable_findable_name + variable_length, "=", 2);
variable_length = ft_strlen(variable_findable_name);
while (environment[i])
{
if (ft_strncmp(variable_findable_name, environment[i], \
variable_length) == 0)
return (ft_free(&variable_findable_name), (char **)&environment[i]);
i++;
}
ft_free(&variable_findable_name);
return (NULL);
}
void environment_variable_value_change( const char **environment, \
const char *variable_name, \
const char *variable_new_value)
{
char **variable_to_change;
char *new_variable;
uint32_t new_variable_length;
variable_to_change = environment_variable_get(variable_name, environment);
if (!variable_to_change)
return ;
new_variable_length = ft_strlen(variable_name) \
+ ft_strlen(variable_new_value) + 2;
new_variable = ft_calloc(new_variable_length, sizeof(*new_variable));
lst_memory(new_variable, free, ADD);
if (!new_variable)
lst_memory(NULL, NULL, CLEAN);
ft_strlcpy(new_variable, variable_name, ft_strlen(variable_name) + 1);
ft_strlcpy(new_variable + ft_strlen(new_variable), "=", 2);
ft_strlcpy(new_variable + ft_strlen(new_variable), variable_new_value, \
ft_strlen(variable_new_value) + 1);
*variable_to_change = new_variable;
}

View File

@ -0,0 +1,130 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* environment_variables_manip.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: vvobis <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/02 17:33:41 by vvobis #+# #+# */
/* Updated: 2024/08/27 15:12:46 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
static void environment_buffer_extend( char ***environment, \
uint32_t environment_length_current)
{
uint32_t environment_size_multiplier;
void *env_ptr;
environment_size_multiplier = environment_length_current / ENVIRONMENT_SIZE;
if ((ENVIRONMENT_SIZE * (environment_size_multiplier \
+ (environment_size_multiplier < 1))) \
< environment_length_current)
{
env_ptr = environment;
*environment = environment_create((const char **)env_ptr);
lst_memory(env_ptr, NULL, FREE);
lst_memory(environment, free_split, ADD);
}
}
char **environment_create(const char **env)
{
char **environment_new;
char *pwd;
uint32_t i;
environment_new = ft_calloc(ENVIRONMENT_SIZE + 1, sizeof(*environment_new));
lst_memory(environment_new, free, ADD);
i = 0;
while (env[i])
{
environment_new[i] = (char *)env[i];
i++;
}
pwd = getcwd(NULL, 0);
if (!pwd)
{
perror("getcwd");
lst_memory(NULL, NULL, CLEAN);
}
environment_variable_value_change((const char **)environment_new, \
"PWD", pwd);
ft_free(&pwd);
return (environment_new);
}
void clear_spaces(char *variable)
{
uint32_t i;
uint32_t j;
i = 0;
while (variable[i])
{
j = 0;
if (variable[i] == ' ')
{
while (variable[i + j] && variable[i + j] == ' ')
j++;
ft_memmove(&variable[i + 1], \
&variable[i + j], ft_strlen(&variable[i]));
}
i++;
}
}
void environment_variable_add( char ***environment,
const char *variable_new_name,
const char *variable_new_value)
{
char *variable_to_add;
uint32_t variable_new_name_length;
uint32_t variable_new_value_length;
uint64_t environment_length_current;
if (environment_variable_get(variable_new_name, \
(const char **)*environment))
return (environment_variable_value_change(\
(const char **)*environment, variable_new_name, variable_new_value));
environment_length_current = get_split_size((const char **)*environment);
environment_buffer_extend(environment, environment_length_current);
variable_new_name_length = ft_strlen(variable_new_name);
variable_new_value_length = ft_strlen(variable_new_value);
variable_to_add = ft_calloc(variable_new_name_length \
+ variable_new_value_length + 2, \
sizeof(*variable_to_add));
lst_memory(variable_to_add, free, ADD);
ft_strlcpy(variable_to_add, variable_new_name, \
ft_strlen(variable_new_name) + 1);
ft_strlcpy(variable_to_add + variable_new_name_length, "=", 2);
if (variable_new_value)
ft_strlcpy(variable_to_add + variable_new_name_length + 1, \
variable_new_value, variable_new_value_length + 1);
clear_spaces(variable_to_add);
(*environment)[environment_length_current] = variable_to_add;
}
void environment_variable_remove(char **environment, const char *variable)
{
uint32_t i;
uint32_t variable_length;
i = 0;
variable_length = ft_strlen(variable);
while (environment[i])
{
if (ft_strncmp(environment[i], (char *)variable, variable_length) == 0)
{
while (environment[i])
{
environment[i] = environment[i + 1];
i++;
}
return ;
}
i++;
}
}

141
src/execution.c Normal file
View File

@ -0,0 +1,141 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* execution.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: victor </var/spool/mail/victor> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/19 22:54:19 by victor #+# #+# */
/* Updated: 2025/02/15 22:23:29 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void command_execute( const char *command_path,
const char **argv,
const char **env)
{
pid_t child_proccess;
ft_fork(&child_proccess, command_path);
if (child_proccess == 0)
{
execve(command_path, (char **)argv, (char **)env);
perror("minishell");
lst_memory(NULL, NULL, CLEAN);
}
else
{
waitpid(child_proccess, NULL, 0);
}
}
void wait_pids(t_ast *tree, uint pid_count, \
pid_t pid_final, int32_t *exit_status)
{
uint i;
int ret_test;
pid_t wait_pid_ret;
i = 0;
while (i <= pid_count)
{
if (tree[i].cpid != 0)
{
wait_pid_ret = wait(&ret_test);
if (wait_pid_ret == -1 && g_signal_flag == 3)
{
ft_putstr_fd("Quit (core dumped)\n", 1);
continue ;
}
else if (wait_pid_ret == -1 && g_signal_flag == 1)
continue ;
else if (wait_pid_ret == -1)
return (perror("wait"), lst_memory(NULL, NULL, CLEAN));
if (wait_pid_ret == pid_final)
*exit_status = WEXITSTATUS(ret_test);
tree[i].cpid = 0;
}
i++;
}
}
static void execution_loop_helper( t_ast *tree, \
uint32_t *i, \
int32_t std[2], \
int32_t *exit_status)
{
if (tree[*i].type != NODE_PIPE)
{
restore_fd(std);
if (tree[*i].cpid != 0)
wait_pids(tree, *i, tree[*i].cpid, exit_status);
}
else
{
ft_dup2(std[1], STDOUT_FILENO, \
"in execution_loop execution_loop_helper");
}
if ((tree[*i].type == NODE_LOGICAL_OR \
&& *exit_status == 0))
(*i)++;
else if ((tree[*i].type == NODE_LOGICAL_AND \
&& *exit_status != 0))
(*i)++;
}
void execution_loop( t_ast *tree, \
const char **env, \
int *exit_status, \
int std[2])
{
bool error_found;
error_found = false;
if (tree->type != NODE_INVALID)
{
if (tree->has_redir_in \
&& tree->path_file_in == 0 \
&& tree->fd_in == -1)
{
return (*exit_status = 1, (void)0);
}
evaluate_input(&tree->args, exit_status, &error_found);
if (tree->args && tree->args[0])
environment_variable_value_change(env, "_", tree->args[0]);
if (*exit_status == -1 || error_found == true)
return (*exit_status = 2, (void)0);
handle_command(tree, env, exit_status, std);
}
}
void execute_commands( t_ast *tree, const char **env, \
int *exit_status, int std[2])
{
uint32_t i;
bool was_pipe;
i = 0;
if (std[0] == -1 || std[1] == -1)
{
perror("dup");
lst_memory(NULL, NULL, CLEAN);
}
was_pipe = false;
while (tree[i].type != NODE_END)
{
if (was_pipe == true)
{
tree[i].was_pipe = true;
was_pipe = false;
}
execution_loop(&tree[i], env, exit_status, std);
execution_loop_helper(tree, &i, std, exit_status);
if (tree[i].type == NODE_PIPE)
was_pipe = true;
i++;
}
restore_fd(std);
}

39
src/handle_signals.c Normal file
View File

@ -0,0 +1,39 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* handle_signals.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/07 14:28:41 by anarama #+# #+# */
/* Updated: 2025/02/15 22:29:27 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void handle_sigint(int sig)
{
if (sig == SIGINT)
{
g_signal_flag = 1;
}
else if (sig == SIGQUIT)
{
g_signal_flag = 3;
}
}
void setup_signal_handlers(void)
{
struct sigaction sa;
bzero(&sa, sizeof(sa));
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = handle_sigint;
sigaction(SIGINT, &sa, NULL);
sigaction(SIGQUIT, &sa, NULL);
sa.sa_handler = SIG_IGN;
sigaction(SIGTSTP, &sa, NULL);
}

71
src/input.c Normal file
View File

@ -0,0 +1,71 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* input.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/14 16:18:42 by vvobis #+# #+# */
/* Updated: 2024/08/19 22:58:56 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void free_split(void *back)
{
char **free_back;
if (!back)
return ;
free_back = (char **)back;
while (*free_back)
{
ft_free((void *)free_back);
free_back++;
}
ft_free(&back);
return ;
}
uint32_t get_split_length(char **split)
{
uint32_t i;
uint32_t k;
uint32_t j;
i = 0;
k = 0;
while (split[i])
{
j = 0;
while (split[i][j++])
k++;
i++;
}
return (k);
}
uint32_t get_split_size(const char **split)
{
uint32_t i;
i = 0;
if (!split)
return (0);
while (split[i])
i++;
return (i);
}
int get_amount_tokens(t_token *tokens)
{
int i;
i = 0;
while (tokens[i].token_type != TOKEN_EOL)
{
i++;
}
return (i);
}

95
src/list.c Normal file
View File

@ -0,0 +1,95 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* list.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/04/27 11:44:46 by vvobis #+# #+# */
/* Updated: 2024/07/30 11:45:03 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
t_clean *lst_node_new(void *content, void (*del)(void *))
{
t_clean *new;
if (!content || !del)
return (NULL);
new = malloc(sizeof(*new));
if (!new)
return (NULL);
new->content = content;
new->clean = del;
new->next = NULL;
return (new);
}
void lst_node_del(t_clean **lst)
{
(*lst)->clean((*lst)->content);
ft_free(&*lst);
}
void lst_node_del_clean(t_clean **lst, void *mem)
{
t_clean *tmp;
t_clean *head;
if (!lst || !*lst)
return ;
head = *lst;
tmp = *lst;
while ((*lst) && (*lst)->next->content != mem)
(*lst) = (*lst)->next;
if (!*lst)
return ;
tmp = *lst;
if ((*lst)->next && (*lst)->next->next)
{
tmp = (*lst)->next->next;
lst_node_del(&(*lst)->next);
(*lst)->next = tmp;
}
else if ((*lst)->next)
lst_node_del(&(*lst)->next);
else
lst_node_del(lst);
*lst = head;
}
void lst_list_clean(t_clean **head)
{
t_clean *tmp;
while (*head)
{
tmp = (*head)->next;
lst_node_del(head);
*head = tmp;
}
free(*head);
}
int lst_add_back(t_clean **node, t_clean *new)
{
t_clean *tmp;
if (!new)
{
perror("malloc");
return (0);
}
if (*node)
{
tmp = *node;
while (tmp->next)
tmp = tmp->next;
tmp->next = new;
}
else
*node = new;
return (1);
}

55
src/list_memory.c Normal file
View File

@ -0,0 +1,55 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* list_memory.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/05 12:21:13 by victor #+# #+# */
/* Updated: 2024/08/24 12:44:14 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void lst_memory(void *mem, void (*del)(void *c), int mode)
{
static t_clean *list;
t_clean *new;
if (mode == CLEAN)
return (terminal_raw_mode_disable(ECHOCTL | ICANON), \
lst_list_clean(&list), exit(EXIT_FAILURE));
if (mode == END)
return (terminal_raw_mode_disable(ECHOCTL | ICANON), \
lst_list_clean(&list));
if (mode == FREE)
return (lst_node_del_clean(&list, mem));
if (!mem)
return (lst_list_clean(&list), perror("malloc"), exit(EXIT_FAILURE));
new = lst_node_new(mem, del);
if (!new)
return (del(mem), lst_list_clean(&list), \
terminal_raw_mode_disable(ECHOCTL | ICANON), \
p_stderr(STDERR_FILENO, "minishell: %s", "lst_node_malloc"), \
perror(""), exit(EXIT_FAILURE));
lst_add_back(&list, new);
}
int p_stderr(int stderr_fd, const char *error, const char *specifier)
{
int old_stdout;
int count;
old_stdout = dup(STDOUT_FILENO);
if (old_stdout == -1)
return (perror("dup"), -1);
if (dup2(stderr_fd, STDOUT_FILENO) == -1)
return (perror("dup2"), close(old_stdout), -1);
count = ft_printf(error, specifier);
ft_close(STDOUT_FILENO, "in p_stderr");
if (dup2(old_stdout, STDOUT_FILENO) == -1)
return (perror("dup2"), close(old_stdout), -1);
ft_close(old_stdout, "in p_stderr");
return (count);
}

43
src/minishell.c Normal file
View File

@ -0,0 +1,43 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* minishell.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/05 12:22:34 by victor #+# #+# */
/* Updated: 2024/08/27 17:12:24 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
int32_t volatile g_signal_flag;
int main(int argc, const char **argv, const char **env)
{
char *command_input;
char **environment;
int32_t exit_status;
int32_t std[2];
environment = environment_create(env);
setup(argc, argv, environment, std);
exit_status = 0;
while (g_signal_flag != 2)
{
g_signal_flag = 0;
env_static(environment);
command_input = prompt_get(NULL);
if (g_signal_flag == 2)
exit_status = 0;
else if (g_signal_flag == 1)
exit_status = 130;
else
m_tokenizer(command_input, environment, &exit_status, std);
if (g_signal_flag == 3)
exit_status = 131;
}
ft_putendl_fd("exit", 2);
return (lst_memory(NULL, NULL, END), exit_status);
}

131
src/non_interactive.c Normal file
View File

@ -0,0 +1,131 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* non_interactive.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: victor </var/spool/mail/victor> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/08/19 23:13:31 by victor #+# #+# */
/* Updated: 2024/08/27 16:58:26 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
int32_t minishell_single_command( char *command, \
char **environment, \
int32_t std[2])
{
int32_t exit_status;
uint32_t input_length;
exit_status = 0;
input_length = ft_strlen(command);
if (input_length)
{
if (command[input_length - 1] == '\n')
command[input_length - 1] = 0;
m_tokenizer(command, environment, &exit_status, std);
}
lst_memory(NULL, NULL, END);
exit(exit_status);
}
void *ft_realloc_string(char **string, uint32_t *new_size)
{
char *tmp;
*new_size += *new_size;
tmp = ft_calloc(*new_size, sizeof(*tmp));
lst_memory(tmp, free, ADD);
ft_memcpy(tmp, *string, ft_strlen(*string));
lst_memory(*string, NULL, FREE);
*string = NULL;
return (tmp);
}
char *check_redir_input(void)
{
char *input;
char buffer[512];
uint32_t capacity;
int64_t bytes_read;
bytes_read = 1;
capacity = 512;
input = ft_calloc(capacity, sizeof(*input));
lst_memory(input, free, ADD);
while (bytes_read)
{
ft_bzero(&buffer, sizeof(buffer));
bytes_read = ft_read(0, buffer, 511);
if (bytes_read > 0)
{
if ((ft_strlen(input) + ft_strlen(buffer)) > capacity)
input = ft_realloc_string(&input, &capacity);
ft_strlcpy(input + ft_strlen(input), \
buffer, ft_strlen(input) + ft_strlen(buffer) + 1);
}
else if (bytes_read < 0)
return (perror("read"), lst_memory(NULL, NULL, CLEAN), NULL);
}
return (input);
}
void setup_environment(const char **environment)
{
char *shlvl;
uint16_t shlvl_value;
g_signal_flag = 0;
env_static((char **)environment);
setup_signal_handlers();
shlvl_value = ft_atoi(environment_variable_value_get("SHLVL", \
(const char **)environment)) + 1;
if (shlvl_value == 1000)
{
ft_putendl_fd("minishell: \
warning: shell level (1000) too high, resetting to 1", 2);
shlvl = ft_strdup("1");
}
else
shlvl = ft_itoa(shlvl_value);
if (!shlvl)
{
perror("malloc");
lst_memory(NULL, NULL, CLEAN);
}
environment_variable_value_change((const char **)environment, \
"SHLVL", shlvl);
ft_free(&shlvl);
}
int setup( uint32_t argc, \
const char **argv, \
char **environment, \
int32_t std[2])
{
char *input;
setup_environment((const char **)environment);
std[0] = dup(STDIN_FILENO);
std[1] = dup(STDOUT_FILENO);
if (std[0] == -1 || std[1] == -1)
return (perror("dup"), lst_memory(NULL, NULL, CLEAN), 1);
lst_memory(std, close_fds, ADD);
if (!isatty(0))
{
input = check_redir_input();
if (input)
minishell_single_command(input, environment, std);
}
else if (argc > 1)
{
if (argc > 2)
return (-1);
else
return (minishell_single_command((char *)argv[1], \
environment, std));
}
return (1);
}

133
src/path_utils.c Normal file
View File

@ -0,0 +1,133 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* path_utils.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/07 19:32:35 by anarama #+# #+# */
/* Updated: 2025/02/15 15:24:08 by victor ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
static int find_longest_path(const char *path)
{
int i;
int ret;
i = 0;
ret = 0;
if (!path)
return (0);
while (*path++)
{
if (*path == ':' || !*path)
{
if (ret < i)
{
ret = i;
i = 0;
}
}
i++;
}
if (ret)
return (ret);
return (i);
}
bool isdir(char *input)
{
struct stat dir;
dir = (struct stat){0};
stat(input, &dir);
if (S_ISDIR(dir.st_mode))
return (true);
return (false);
}
static char *print_error(char *input, int *exit_status)
{
if (input && ft_strchr(input, '/'))
{
if (input && isdir(input))
return (p_stderr(2, "minishell: %s: Is a directory\n", input), \
*exit_status = 126, NULL);
if (access(input, F_OK) == 0)
{
if (access(input, X_OK) == 0)
return (input);
else
{
p_stderr(STDERR_FILENO, "minishell: %s: Permission denied\n", \
input);
*exit_status = 126;
}
}
else
return (p_stderr(STDERR_FILENO, \
"minishell: %s: No such file or directory\n", \
input), *exit_status = 127, NULL);
}
else
return (*exit_status = 127, p_stderr(STDERR_FILENO, \
"minishell: %s: command not found\n", input), NULL);
return (NULL);
}
static char *check_paths( const char *path, \
char *path_abs, \
char *input, \
int *exit_status)
{
char *tmp;
if (ft_memcmp(input, ".", 2) != 0 && ft_memcmp(input, "..", 3) != 0)
{
while (path)
{
tmp = ft_strchr(path, ':');
if (!tmp)
tmp = ft_strchr(path, '\0');
if (tmp)
{
ft_strlcpy(path_abs, path, tmp - path + 1);
ft_strlcat(path_abs, "/", ft_strlen(path_abs) + 2);
ft_strlcat(path_abs, input, \
ft_strlen(input) + ft_strlen(path_abs) + 1);
}
if (access(path_abs, F_OK) == 0)
{
if (access(path_abs, X_OK) == 0)
return (path_abs);
}
path = ft_strchr(path, ':');
if (path)
path++;
}
}
return (print_error(input, exit_status));
}
char *find_absolute_path( const char *path_variable, \
char *input, \
int *exit_status)
{
char *path_abs;
uint32_t path_length;
if (!input)
return (NULL);
if ((input && *input == 0) || ft_strchr(input, '/') || !path_variable)
return (print_error(input, exit_status));
path_variable = ft_strchr(path_variable, '/');
path_length = find_longest_path(path_variable);
if (!path_length)
return (NULL);
path_abs = malloc(path_length + ft_strlen(input) + 2);
lst_memory(path_abs, &free, ADD);
return (check_paths(path_variable, path_abs, input, exit_status));
}

37
src/termios.c Normal file
View File

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* termios.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: anarama <anarama@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/07/16 09:46:56 by vvobis #+# #+# */
/* Updated: 2024/08/04 13:25:04 by vvobis ### ########.fr */
/* */
/* ************************************************************************** */
#include "../minishell.h"
void terminal_raw_mode_enable(int flag)
{
struct termios raw;
if (isatty(0) && isatty(1))
{
tcgetattr(STDIN_FILENO, &raw);
raw.c_lflag &= ~(flag);
tcsetattr(STDIN_FILENO, TCSANOW, &raw);
}
}
void terminal_raw_mode_disable(int flag)
{
struct termios orig;
if (isatty(0) && isatty(1))
{
tcgetattr(STDIN_FILENO, &orig);
orig.c_lflag |= (flag);
tcsetattr(STDIN_FILENO, TCSANOW, &orig);
}
}

Some files were not shown because too many files have changed in this diff Show More