Merge branch 'willem'

This commit is contained in:
whaffman 2025-02-28 01:13:31 +01:00
commit 1695b1919f
103 changed files with 2977 additions and 719 deletions

3
.gitignore vendored
View File

@ -4,3 +4,6 @@ a.out
*.o
obj/
.minishell_history
.ms_heredoc
pipetester.c
pipetest

29
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,29 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug minishell",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/debug/minishell",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "Build minishell debug",
"miDebuggerPath": "/usr/bin/gdb",
"logging": {
"engineLogging": true
}
}
]
}

11
.vscode/settings.json vendored
View File

@ -1,5 +1,14 @@
{
"files.associations": {
"minishell.h": "c"
"minishell.h": "c",
"signal.h": "c",
"optional": "c",
"ostream": "c",
"system_error": "c",
"array": "c",
"functional": "c",
"tuple": "c",
"type_traits": "c",
"utility": "c"
}
}

46
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,46 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build minishell",
"type": "shell",
"command": "make",
"args": [],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$gcc"],
"detail": "Generated task for building minishell"
},
{
"label": "Build minishell debug",
"type": "shell",
"command": "make debug",
"args": [],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$gcc"],
"detail": "Generated task for building minishell in debug mode"
},
{
"label": "Run minishell",
"type": "shell",
"command": "./minishell",
"args": [],
"group": {
"kind": "test",
"isDefault": true
},
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"problemMatcher": []
}
]
}

168
Makefile
View File

@ -1,12 +1,12 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# :::::::: #
# Makefile :+: :+: #
# +:+ #
# By: qmennen <qmennen@student.codam.nl> +#+ #
# +#+ #
# Created: 2024/10/15 11:48:46 by whaffman #+# #+# #
# Updated: 2025/02/11 15:06:22 by qmennen ### ########.fr #
# Updated: 2025/02/25 18:15:50 by whaffman ######## odam.nl #
# #
# **************************************************************************** #
@ -15,62 +15,166 @@ NAME = minishell
SRC_PATH = src
INC_PATH = inc
LIB_PATH = lib
BUILD_PATH = build
LIBFT_PATH = $(LIB_PATH)/libft
LIBFT_INC_PATH = $(LIBFT_PATH)/inc
LIBFT = $(LIBFT_PATH)/libft.a
OBJ_PATH = obj
VPATH = src:src/environment:src/prompt:src/lexer:src/token:src/utils:src/executor:src/parser
SOURCES = $(shell basename -a $(shell find $(SRC_PATH) -type f -name "*.c"))
OBJECTS = $(addprefix $(OBJ_PATH)/, $(SOURCES:.c=.o))
DEPENDS = ${OBJECTS:.o=.d}
CC = cc
RM = rm -rf
INCLUDES = -I./$(INC_PATH) -I./$(LIBFT_INC_PATH)
CFLAGS = -Wall -Wextra -Werror -fsanitize=address,undefined -MMD
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
LDLIBS := -L$(LIBFT_PATH) -lft -lreadline
endif
all: $(NAME)
echo $(SOURCES)
# Include sources.mk if it exists
-include sources.mk
$(NAME): $(LIBFT) $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) $(LDLIBS) -o $(NAME)
# Build configurations
BUILD_CONFIGS = release debug asan tsan
-include ${DEPENDS}
release_CFLAGS = -Wall -Werror -Werror -O2
debug_CFLAGS = -Wall -Werror -Werror -g3 -DDEBUG
asan_CFLAGS = -Wall -Werror -Werror -fsanitize=address,leak,undefined -g3
tsan_CFLAGS = -Wall -Werror -Werror -fsanitize=thread -g3
$(LIBFT): $(LIBFT_PATH)
# Targets for each build configuration
define BUILD_TARGETS
$(1)_OBJ_PATH = $(BUILD_PATH)/$(1)/obj
$(1)_DEPENDS = $$(addprefix $$($(1)_OBJ_PATH)/, $$(SOURCES:.c=.d))
$(1)_OBJECTS = $$(addprefix $$($(1)_OBJ_PATH)/, $$(SOURCES:.c=.o))
.PHONY: $(1)
$(1): CFLAGS = $$($(1)_CFLAGS)
$(1): $(BUILD_PATH)/$(1)/$(NAME)
.PHONY: run_$(1)
run_$(1): $(1)
$$(info $$(bold)$$(green)Running $(1)$$(reset))
./$(BUILD_PATH)/$(1)/$(NAME)
$(BUILD_PATH)/$(1)/$(NAME): $(LIBFT) $$($(1)_OBJECTS)
$$(info $$(bold)$$(green)Linking $(1) config$$(reset))
$$(CC) $$(CFLAGS) $$($(1)_OBJECTS) $$(LDLIBS) -o $$@
-include $$($(1)_DEPENDS)
$$($(1)_OBJ_PATH)/%.o: %.c $(LIBFT) | $$($(1)_OBJ_PATH)
$$(CC) $$(CFLAGS) $$(INCLUDES) -MMD -MP -c $$< -o $$@
$$($(1)_OBJ_PATH):
$$(info $$(bold)$$(green)Creating $(1) object directory$$(reset))
mkdir -p $$@
endef
# Copy the release build configuration to the root
$(NAME): $(BUILD_PATH)/release/$(NAME)
$(info $(bold)$(green)Copying release build to root$(reset))
cp $< $@
$(foreach config,$(BUILD_CONFIGS),$(eval $(call BUILD_TARGETS,$(config))))
# Build all configurations
all: release debug asan tsan
$(info $(bold)$(green)All builc config have been build$(reset))
# Build libft
$(LIBFT): $(LIBFT_PATH) submodules
$(info $(bold)$(green)Building libft$(reset))
$(MAKE) -C $(LIBFT_PATH)
$(LIBFT_PATH):
$(info $(bold)$(green)Adding libft submodule$(reset))
git submodule add https://gitea.duinvoetje.nl/willem/libft.git $(LIBFT_PATH)
$(OBJ_PATH):
mkdir -p $@
$(OBJ_PATH)/%.o: %.c $(LIBFT) | $(OBJ_PATH)
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
# Generate sources.mk
sources.mk:
$(info $(bold)$(green)Generating sources.mk$(reset))
@echo "VPATH = $$(find $(SRC_PATH) -type d | tr '\n' ':')" > sources.mk
@echo "SOURCES = $$(find $(SRC_PATH) -type f -name '*.c' -exec basename {} \; | tr '\n' ' ' | fold -s -w 70 | sed 's/$$/ \\/')" >> sources.mk
# Remove build artifacts
clean:
$(RM) $(OBJECTS) $(OBJ_PATH)
$(info $(bold)$(red)Cleaning$(reset))
find $(BUILD_PATH) -type d -name 'obj' -exec $(RM) {} +
$(MAKE) -C $(LIBFT_PATH) clean
# Remove build artifacts and the executable
fclean: clean
$(info $(bold)$(red)Full cleaning$(reset))
$(RM) $(BUILD_PATH)
$(RM) $(NAME)
$(MAKE) -C $(LIBFT_PATH) fclean
re: fclean all
# Rebuild the project
re: fclean
$(info $(bold)$(green)Rebuilding$(reset))
$(MAKE) all $(NAME)
run: all
./$(NAME)
# Run the project with the release build configuration
run: run_release
# Remove sources.mk to force regeneration
srcs:
$(info $(bold)$(green)Regenerating sources.mk on next make$(reset))
$(RM) sources.mk
# Show this help.
help:
@echo "Usage: make [target]"
@echo ""
@echo "Targets:"
@echo " $(green)$(bold)all $(reset)- Build all configurations (release, debug, asan, tsan)"
@echo " $(green)$(bold)clean $(reset)- Remove build artifacts"
@echo " $(green)$(bold)fclean $(reset)- Remove build artifacts and the executable"
@echo " $(green)$(bold)re $(reset)- Rebuild the project"
@echo " $(green)$(bold)run $(reset)- Run the release build"
@echo " $(green)$(bold)srcs $(reset)- Remove sources.mk"
@echo " $(green)$(bold)help $(reset)- Show this help message"
@echo ""
@echo "Build configurations:"
@echo " $(green)$(bold)release $(reset)- Build with release configuration"
@echo " $(green)$(bold)debug $(reset)- Build with debug configuration"
@echo " $(green)$(bold)asan $(reset)- Build with AddressSanitizer configuration"
@echo " $(green)$(bold)tsan $(reset)- Build with ThreadSanitizer configuration"
@echo ""
@echo "Run configurations:"
@echo " $(green)$(bold)run_release $(reset)- Run the release build"
@echo " $(green)$(bold)run_debug $(reset)- Run the debug build"
@echo " $(green)$(bold)run_asan $(reset)- Run the AddressSanitizer build"
@echo " $(green)$(bold)run_tsan $(reset)- Run the ThreadSanitizer build"
@echo ""
@echo "Other targets:"
@echo " $(green)$(bold)submodules $(reset)- Check and reinitialize git submodules"
@echo " $(green)$(bold)libft $(reset)- Build libft"
@echo " $(green)$(bold)sources.mk $(reset)- Generate sources.mk"
@echo ""
.PHONY: submodules
submodules:
$(info $(bold)$(green)Checking and reinitializing submodules$(reset))
@if git submodule status | egrep -q '^[-+]' ; then \
echo "INFO: Need to reinitialize git submodules"; \
git submodule update --init; \
fi
.PHONY: all clean fclean re srcs run help
red:=$(shell tput setaf 1)
green:=$(shell tput setaf 2)
yellow:=$(shell tput setaf 3)
blue:=$(shell tput setaf 4)
magenta:=$(shell tput setaf 5)
cyan:=$(shell tput setaf 6)
white:=$(shell tput setaf 7)
bold:=$(shell tput bold)
underline:=$(shell tput smul)
reset:=$(shell tput sgr0)
.PHONY: all clean fclean re run

77
Makefile.old Normal file
View File

@ -0,0 +1,77 @@
# **************************************************************************** #
# #
# :::::::: #
# Makefile :+: :+: #
# +:+ #
# By: qmennen <qmennen@student.codam.nl> +#+ #
# +#+ #
# Created: 2024/10/15 11:48:46 by whaffman #+# #+# #
# Updated: 2025/02/20 11:10:42 by whaffman ######## odam.nl #
# #
# **************************************************************************** #
NAME = minishell
SRC_PATH = src
INC_PATH = inc
LIB_PATH = lib
LIBFT_PATH = $(LIB_PATH)/libft
LIBFT_INC_PATH = $(LIBFT_PATH)/inc
LIBFT = $(LIBFT_PATH)/libft.a
OBJ_PATH = obj
VPATH = src:src/environment:src/prompt:src/lexer:src/token:src/utils:
VPATH += src/executor:src/parser:src/expander:src/debug:src/signal:src/builtin
SOURCES = $(shell basename -a $(shell find $(SRC_PATH) -type f -name "*.c"))
OBJECTS = $(addprefix $(OBJ_PATH)/, $(SOURCES:.c=.o))
DEPENDS = ${OBJECTS:.o=.d}
CC = cc
RM = rm -rf
INCLUDES = -I./$(INC_PATH) -I./$(LIBFT_INC_PATH)
CFLAGS = -Wall -Wextra -Werror -fsanitize=address,undefined -MMD -g3
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
LDLIBS := -L$(LIBFT_PATH) -lft -lreadline
endif
all: $(NAME)
echo $(SOURCES)
$(NAME): $(LIBFT) $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) $(LDLIBS) -o $(NAME)
-include ${DEPENDS}
$(LIBFT): $(LIBFT_PATH)
$(MAKE) -C $(LIBFT_PATH)
$(LIBFT_PATH):
git submodule add https://gitea.duinvoetje.nl/willem/libft.git $(LIBFT_PATH)
$(OBJ_PATH):
mkdir -p $@
$(OBJ_PATH)/%.o: %.c $(LIBFT) | $(OBJ_PATH)
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
clean:
$(RM) $(OBJECTS) $(OBJ_PATH)
$(MAKE) -C $(LIBFT_PATH) clean
fclean: clean
$(RM) $(NAME)
$(MAKE) -C $(LIBFT_PATH) fclean
re: fclean all
run: all
./$(NAME)
.PHONY: all clean fclean re run

View File

@ -4,15 +4,32 @@ A lot of amazing shell stuff
- libreadline-dev
- libncurses-dev
## Comments on work
- Checked if path is a directory and send appropriate message
- `executor_absolute_path` => extracted some code into helpers to make it norminette compliant
- `executor_child` => refactored putstr_fd into error_msg | checked if file on path is exectuable to show permission denied where applicable
- `lexer_token_next` => extracted code for norminette
- `parser` => **A LOT** of work in all files for norminette compliancy
- `expander_parse_string` => Fixed so that $HOME/test.txt returns the correct path and file
## Edge Cases
- `cat $PWD/test` should expand,
- `cd -` : `bash: cd: OLDPWD not set`
- `cd ~` : does not expand ?
## TODO
-[x] Find absolute path for command input ('/', './', 'cmd')
- Add heredoc to tokenizer
-[x] Environment to `t_list`
-[x] Get environment array (export)
-[x] Set environment variable (export)
-[x] Simple builtin export
- Preliminary signals
- Define struct for commands, something like (
- [x] Find absolute path for command input ('/', './', 'cmd')
- [x]Add heredoc to tokenizer
- [x] Environment to `t_list`
- [x] Get environment array (export)
- [x] Set environment variable (export)
- [x] Simple builtin export
- [x] builtins
- [x] Preliminary signals
- [x] Define struct for commands, something like (
```c
typedef struct s_command
{
@ -24,13 +41,38 @@ A lot of amazing shell stuff
} t_command;
```
)
- Make the `executor`, run a command
- Make a parser to create a command list
- Add redirects, appends, pipe etc. File descriptor functions
- Expand \$ vars & support \$?
- [x] Make the `executor`, run a command
- [x] Make a parser to create a command list
- [x] Add redirects, appends, pipe etc. File descriptor functions
a command can have multiple redirects but only the last is used for stdout
Redirects take precedence over pipes, but pipes are still created and managed.
should it close the unused pipe-end?
all redirects are opened and closed, but only last fd is used.
multiple HEREDOCs can be nested, only last is used.
- [x] Expand \$ vars & support \$?
* [x] $var
* [0] $?
- CB command to change banner
- __Bonus:__ Command tree for &&, ||, *
## Signals
### In interactive mode
- `ctrl - C` redisplay prompt status 130
- `ctrl - D` exit shell
- `ctrl - \`
-- Done
### During process
- `ctrl - C` SIGINT to processs status 130
- `ctrl - D`
- `ctrl - \` SIGQUIT to process core dumped status 131
-- Shows ^C
### During HEREDOC
- `ctrl - C` redisplay prompt status 130
- `ctrl - D` SEND EOF error displayed but still works status:0
- `ctrl - \` nothing
## Allowed Functions
### `<readline/readline.h>`

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/04 16:13:11 by whaffman #+# #+# */
/* Updated: 2025/02/06 16:14:44 by qmennen ### ########.fr */
/* Updated: 2025/02/27 16:36:39 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -26,6 +26,7 @@
# include <signal.h>
# include <dirent.h>
# include <termios.h>
# include <limits.h>
# include <term.h>
# include <readline/readline.h>

27
inc/builtin.h Normal file
View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* builtin.h :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:09:02 by whaffman #+# #+# */
/* Updated: 2025/02/26 15:44:47 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#ifndef BUILTIN_H
# define BUILTIN_H
# include "minishell.h"
int is_builtin(char *cmd);
int builtin_router(t_minishell *msh, t_command *cmd);
int builtin_echo(t_minishell *msh, t_command *cmd);
int builtin_cd(t_minishell *msh, t_command *cmd);
int builtin_pwd(t_minishell *msh, t_command *cmd);
int builtin_export(t_minishell *msh, t_command *cmd);
int builtin_unset(t_minishell *msh, t_command *cmd);
int builtin_env(t_minishell *msh, t_command *cmd);
int builtin_exit(t_minishell *msh, t_command *cmd);
#endif // BUILTIN_H

23
inc/debug.h Normal file
View File

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* debug.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/18 20:06:53 by qmennen #+# #+# */
/* Updated: 2025/02/18 20:10:49 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef DEBUG_H
# define DEBUG_H
# include "minishell.h"
void print_commands(void *param);
void token_print(void *param);
void print_redirects(void *param);
void print_freelist(t_minishell *msh);
#endif

View File

@ -6,7 +6,7 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:26:35 by whaffman #+# #+# */
/* Updated: 2025/02/11 15:39:15 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 15:44:49 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
@ -15,13 +15,14 @@
# include "minishell.h"
void environment_add(t_list **environment, char *name, char *value);
void environment_print(t_list *environment);
t_environment *environment_get(t_list *environment, char *name);
void environment_free_list(t_list **environment);
int environment_parse(char **envp, t_list **environment);
char **environment_get_arr(t_list *environment);
void environment_del(t_list **environment, char *name);
void environment_free(void *content);
void environment_add(t_minishell *msh,
char *name, char *value);
void environment_print(t_minishell *msh);
t_environment *environment_get(t_minishell *msh, char *name);
void environment_free_list(t_minishell *msh);
int environment_parse(t_minishell *msh, char **envp);
char **environment_get_arr(t_minishell *msh);
void environment_del(t_minishell *msh, char *name);
void environment_free(t_minishell *msh, void *content);
#endif // ENVIRONMENT_H

View File

@ -6,7 +6,7 @@
/* By: willem <willem@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/08 17:06:07 by willem #+# #+# */
/* Updated: 2025/02/11 17:06:54 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 15:45:17 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
@ -15,6 +15,14 @@
# include "minishell.h"
char *executor_absolute_path(t_list *env, char *cmd);
char *executor_absolute_path(t_minishell *msh, char *cmd);
void executor_child(t_minishell *msh, t_command *command);
pid_t executor_fork(t_minishell *msh, t_command *command);
void executor_create_pipes(t_minishell *msh);
int executor_execute_pipeline(t_minishell *msh);
void executor_close_fds(int n_fds);
int executor_count_fds(t_minishell *msh);
int executor_open_fds(t_list *redirect_list, int og_fd);
void executor_create_redirects(t_minishell *msh);
#endif // EXECUTOR_H

31
inc/expander.h Normal file
View File

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* expander.h :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/18 19:00:51 by qmennen #+# #+# */
/* Updated: 2025/02/26 15:45:19 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#ifndef EXPANDER_H
# define EXPANDER_H
# include "minishell.h"
t_environment *expander_get_var(const char *s, int idx,
t_minishell *msh);
t_list *expander_parse_variables(const char *s,
t_minishell *msh);
char *expander_allocate_memory(
t_minishell *msh,
const char *s,
t_list *variables);
char *expander_parse_string(char *s, t_minishell *msh);
int expander_character_valid(const char c);
int expander_expand_dollar(char *src, char *dest,
int *j, t_list *variables);
#endif

View File

@ -3,10 +3,10 @@
/* :::::::: */
/* minishell.h :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* By: marvin <marvin@student.42.fr> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:13:13 by whaffman #+# #+# */
/* Updated: 2025/02/11 15:50:21 by whaffman ######## odam.nl */
/* Updated: 2025/02/23 12:28:23 by Quinten ######## odam.nl */
/* */
/* ************************************************************************** */
@ -16,11 +16,16 @@
# include "allowed.h"
# include "libft.h"
# include "typedef.h"
# include "signals.h"
# include "environment.h"
# include "prompt.h"
# include "tokenizer.h"
# include "builtin.h"
# include "executor.h"
# include "parser.h"
# include "expander.h"
# include "redirect.h"
# include "debug.h"
# include "utils.h"
# define TRUE 1
@ -38,5 +43,14 @@
# define CYAN "\001\033[0;36m\002"
# define RESET "\001\033[0m\002"
# define PROMPT RESET "🐚" GREEN "minishell" RESET ": "
# define PROMPT_LEN 51
# ifdef DEBUG
# define DEBUG 1
# else
# define DEBUG 0
# endif // DEBUG
void token_print(void *param);
#endif

View File

@ -15,8 +15,11 @@
# include "minishell.h"
t_command *parser_command_new(char *cmd);
char **parser_get_arguments(t_list *list);
t_list *parser_get_commands(t_list *list);
t_command *parser_alloc_command(t_minishell *msh, char *cmd);
t_list *parser_get_commands(t_minishell *msh);
t_list *parser_get_input_redirects(t_list *list);
void parser_create_command(t_minishell *msh, t_command *cmd, t_list **l_tkn);
char **parser_get_arguments(t_list *list, t_minishell *msh);
int parser_validate_command(t_command *command);
#endif

View File

@ -6,7 +6,7 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:35:35 by whaffman #+# #+# */
/* Updated: 2025/02/05 17:05:32 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 15:45:22 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
@ -16,8 +16,8 @@
# include "minishell.h"
void print_banner(void);
char *ft_prompt(t_minishell *minishell);
void ft_write_history(char *line);
void ft_load_history(void);
char *ft_prompt(t_minishell *msh);
void history_write(char *line);
void history_load(void);
#endif // PROMPT_H

27
inc/redirect.h Normal file
View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/23 12:26:29 by Quinten #+# #+# */
/* Updated: 2025/02/27 18:09:47 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#ifndef REDIRECT_H
# define REDIRECT_H
# include "minishell.h"
t_redirect *redirect_new(t_minishell *msh, t_token_type type, char *value);
void redirect_new_error(t_minishell *msh, t_list **redirects, int flag);
int redirect_create(t_minishell *msh, t_list **tokens, t_list **redirects, t_token_type type);
t_list *redirect_get_inputs(t_minishell *msh, t_list *list);
t_list *redirect_get_outputs(t_minishell *msh, t_list *list);
int redirect_is_valid(t_list *lst, t_token *token, int mode);
int redirect_token_type(t_token *token);
int redirect_is_delimiter(t_token *token);
int process_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim);
#endif

25
inc/signals.h Normal file
View File

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* signals.h :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/19 12:26:09 by whaffman #+# #+# */
/* Updated: 2025/02/19 17:30:12 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#ifndef SIGNALS_H
# define SIGNALS_H
# include "minishell.h"
void sigint_heredoc_handler(int signum);
void sigint_minishell_handler(int signum);
void sig_parent_handler(int signum);
void signal_init_child(void);
void signal_init_parent(void);
void signal_init_minishell(void);
#endif // SIGNALS_H

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* tokenizer.h :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* ::: :::::::: */
/* tokenizer.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/05 12:36:00 by whaffman #+# #+# */
/* Updated: 2025/02/05 12:36:01 by whaffman ######## odam.nl */
/* Updated: 2025/02/27 19:03:09 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,18 +16,21 @@
/**
* Lexer
*/
t_lexer *ft_lexer_new(const char *input);
void ft_lexer_free(t_lexer *lexer);
void ft_lexer_readchar(t_lexer *lexer);
char *ft_lexer_readword(t_lexer *lexer);
t_list *ft_parse_input(t_lexer *lexer);
t_lexer *ft_lexer_new(t_minishell *msh);
void ft_lexer_free(t_minishell *msh, t_lexer *lexer);
void lexer_readchar(t_lexer *lexer);
char *lexer_readword(t_minishell *msh, t_lexer *lexer);
t_list *ft_parse_input(t_minishell *msh);
char *lexer_parse_quotes(t_minishell *msh, t_lexer *lexer);
/**
* Token
*/
t_token *ft_token_next(t_lexer *lexer);
t_token *ft_token_new(t_token_type type, char *c, int pos);
void ft_token_free(t_token *token);
void ft_clear_tokenlist(void *content);
t_token *ft_parse_token(t_lexer *lexer);
t_token *ft_token_next(t_minishell *msh, t_lexer *lexer);
t_token *token_new(t_minishell *msh, t_token_type type, char *c, int pos);
void ft_token_free(t_minishell *msh, t_token *token);
void ft_clear_tokenlist(t_minishell *msh, void *content);
t_token *token_parse(t_minishell *msh, t_lexer *lexer);
char *token_type_convert(t_token_type type);
t_token_type token_char_convert(char c, int is_double);
#endif // TOKENIZER_H

View File

@ -3,10 +3,10 @@
/* :::::::: */
/* typedef.h :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 12:36:08 by whaffman #+# #+# */
/* Updated: 2025/02/05 15:25:40 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 17:26:27 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
@ -16,9 +16,13 @@
typedef enum e_token_type
{
T_WORD,
T_DQWORD,
T_SQWORD,
T_PIPE,
T_REDIRECT_IN,
T_REDIRECT_OUT,
T_AND,
T_OR,
T_APPEND_OUT,
T_HEREDOC,
T_EOF,
@ -46,12 +50,23 @@ typedef struct s_lexer
char current_char;
} t_lexer;
typedef struct s_redirect
{
enum e_token_type type;
char *value;
} t_redirect;
typedef struct s_command
{
char *command;
char **args;
t_list *environment;
t_list *redirect_in;
t_list *redirect_out;
int fd_in;
int fd_out;
int n_fds;
int exit_status;
} t_command;
typedef struct s_minishell
@ -61,5 +76,9 @@ typedef struct s_minishell
t_lexer *lexer;
t_list *tokens;
t_list *commands;
t_list *freelist;
int exit_status;
} t_minishell;
typedef int (*t_builtin_fn)(t_minishell *, t_command *);
#endif // TYPEDEF_H

View File

@ -6,19 +6,32 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 16:06:35 by whaffman #+# #+# */
/* Updated: 2025/02/05 16:23:21 by whaffman ######## odam.nl */
/* Updated: 2025/02/20 18:07:19 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#ifndef UTILS_H
# define UTILS_H
void free_minishell_line(t_minishell *minishell);
void free_minishell(t_minishell *minishell);
void free_command_list(void *content);
void free_minishell_line(t_minishell *msh);
void free_minishell(t_minishell **msh);
void free_command_list(t_minishell *msh, void *content);
t_minishell *init_minishell(void);
void print_banner(void);
void print_list(void *content);
void simple_builtins(t_minishell *minishell);
void simple_builtins(t_minishell *msh);
void error_msg(char *func, char *msg);
void check_malloc(t_minishell *msh, void *ptr);
char *ft_strdup_safe(t_minishell *msh, const char *str);
char *ft_substr_safe(t_minishell *msh, const char *str,
unsigned int start, size_t len);
char *ft_strjoin_safe(t_minishell *msh,
const char *s1, const char *s2);
void *malloc_safe(t_minishell *msh, size_t size);
void free_safe(t_minishell *msh, void **ptr);
void free_freelist(t_minishell *msh);
void ft_lstclear_safe(t_minishell *msh, t_list **lst,
void (*del)(t_minishell *msh, void *));
t_list *ft_lstnew_safe(t_minishell *msh, void *content);
#endif // UTILS_H

24
sources.mk Normal file
View File

@ -0,0 +1,24 @@
VPATH = src:src/prompt:src/utils:src/lexer:src/token:src/environment:src/executor:src/parser:src/debug:src/expander:src/builtin:src/signal:src/redirect:
SOURCES = history_load.c history_write.c prompt.c print_banner.c check_malloc.c \
free_command_list.c free_freelist.c free_lexer.c free_minishell.c \
free_safe.c free_token.c free_token_list.c ft_lstclear_safe.c \
ft_lstnew_safe.c ft_strdup_safe.c ft_strjoin_safe.c malloc_safe.c \
error_msg.c free_minishell_line.c ft_substr_safe.c init_minishell.c \
lexer_read_char.c lexer_new.c lexer_parse_input.c lexer_read_word.c \
lexer_token_next.c token_new.c token_parse.c environment_add.c \
environment_del.c environment_free.c environment_free_list.c \
environment_get.c environment_get_arr.c environment_parse.c \
environment_print.c executor_close_fds.c executor_absolute_path.c \
executor_count_fds.c executor_create_pipes.c \
executor_create_redirects.c executor_open_fds.c \
executor_execute_pipeline.c executor_fork.c executor_child.c \
parser_create_command.c parser_get_arguments.c parser_alloc_command.c \
parser_get_commands.c parser_validate_command.c print_commands.c \
print_freelist.c expander_is_character.c expander_expand_dollar.c \
expander_allocate_memory.c expander_get_variable.c \
expander_parse_variables.c expander_parse_string.c is_builtin.c \
simple_builtins.c builtin_cd.c builtin_echo.c builtin_env.c \
builtin_exit.c builtin_export.c builtin_pwd.c builtin_router.c \
builtin_unset.c signal.c signal_init.c.c redirect_get_inputs.c \
redirect_get_outputs.c redirect_new.c redirect_new_error.c \
redirect_process_heredoc.c redirect_valid_type.c main.c \

41
src/builtin/builtin_cd.c Normal file
View File

@ -0,0 +1,41 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* builtin_cd.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:33:07 by whaffman #+# #+# */
/* Updated: 2025/02/26 15:45:55 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int builtin_cd(t_minishell *msh, t_command *cmd)
{
t_environment *env;
char *path;
if (cmd->args[1] == NULL)
{
env = environment_get(msh, "HOME");
if (env == NULL || env->value == NULL)
{
ft_putendl_fd("minishell: cd: HOME not set", STDERR_FILENO);
return (FAILURE);
}
path = env->value;
}
else
path = cmd->args[1];
if (chdir(path) == -1)
{
ft_putstr_fd("minishell: cd: ", STDERR_FILENO);
ft_putstr_fd(path, STDERR_FILENO);
ft_putstr_fd(": ", STDERR_FILENO);
ft_putendl_fd(strerror(errno), STDERR_FILENO);
return (FAILURE);
}
return (SUCCESS);
}

View File

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* builtin_echo.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:33:05 by whaffman #+# #+# */
/* Updated: 2025/02/26 15:46:29 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int builtin_echo(t_minishell *msh, t_command *cmd)
{
int i;
int n_flag;
(void)msh;
i = 1;
n_flag = 0;
if (cmd->args[i] != NULL && ft_strncmp(cmd->args[i], "-n", 3) == 0)
{
n_flag = 1;
i++;
}
while (cmd->args[i] != NULL)
{
printf("%s", cmd->args[i]);
if (cmd->args[i + 1] != NULL)
printf(" ");
i++;
}
if (!n_flag)
printf("\n");
return (SUCCESS);
}

20
src/builtin/builtin_env.c Normal file
View File

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* builtin_env.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:33:02 by whaffman #+# #+# */
/* Updated: 2025/02/26 15:46:55 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int builtin_env(t_minishell *msh, t_command *cmd)
{
(void)cmd;
environment_print(msh);
return (SUCCESS);
}

View File

@ -0,0 +1,43 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* builtin_exit.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:32:59 by whaffman #+# #+# */
/* Updated: 2025/02/26 15:47:14 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
//TODO EXIT last exit status r:20
int builtin_exit(t_minishell *msh, t_command *cmd)
{
int exit_status;
exit_status = 0;
if (ft_count_arr(cmd->args) > 2)
{
ft_putstr_fd("exit\n", STDERR_FILENO);
ft_putstr_fd("minishell: exit: too many arguments\n", STDERR_FILENO);
return (FAILURE);
}
if (ft_count_arr(cmd->args) == 2 && cmd->args[1] != NULL)
{
if (ft_isdigit_str(cmd->args[1]) == FALSE)
{
ft_putstr_fd("exit\n", STDERR_FILENO);
ft_putstr_fd("minishell: exit: ", STDERR_FILENO);
ft_putstr_fd(cmd->args[1], STDERR_FILENO);
ft_putstr_fd(": numeric argument required\n", STDERR_FILENO);
return (FAILURE);
}
exit_status = ft_atoi(cmd->args[1]);
}
free_minishell(&msh);
rl_clear_history();
exit(exit_status);
return (FAILURE);
}

View File

@ -0,0 +1,42 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* builtin_export.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:32:53 by whaffman #+# #+# */
/* Updated: 2025/02/26 15:49:16 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int builtin_export(t_minishell *msh, t_command *cmd)
{
t_environment *env;
char **arr;
int i;
i = 0;
while (cmd->args[++i] != NULL)
{
arr = ft_split(cmd->args[i], '=');
if (arr[1] == NULL)
{
ft_free_arr(arr);
i++;
continue ;
}
env = environment_get(msh, arr[0]);
if (env != NULL)
{
free_safe(msh, (void **)&(env->value));
env->value = ft_strdup_safe(msh, arr[1]);
}
else
environment_add(msh, arr[0], arr[1]);
ft_free_arr(arr);
}
return (SUCCESS);
}

25
src/builtin/builtin_pwd.c Normal file
View File

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* builtin_pwd.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:32:28 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:06:09 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int builtin_pwd(t_minishell *msh, t_command *cmd)
{
char *cwd;
(void)msh;
(void)cmd;
cwd = getcwd(NULL, 0);
printf("%s\n", cwd);
free_safe(msh, (void **)&(cwd));
return (SUCCESS);
}

View File

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* builtin_router.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:12:38 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:06:18 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int builtin_router(t_minishell *msh, t_command *cmd)
{
const t_builtin_fn builtin_fn[] = {
builtin_echo,
builtin_cd,
builtin_pwd,
builtin_export,
builtin_unset,
builtin_env,
builtin_exit};
if (!is_builtin(cmd->args[0]))
return (FALSE);
builtin_fn[is_builtin(cmd->args[0])](msh, cmd);
return (TRUE);
}

View File

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* builtin_unset.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:25:43 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:07:21 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int builtin_unset(t_minishell *msh, t_command *cmd)
{
int i;
i = 1;
while (cmd->args[i] != NULL)
{
if (environment_get(msh, cmd->args[i]) != NULL)
environment_del(msh, cmd->args[i]);
i++;
}
return (SUCCESS);
}

29
src/builtin/is_builtin.c Normal file
View File

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* is_builtin.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 11:03:33 by whaffman #+# #+# */
/* Updated: 2025/02/26 14:42:49 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int is_builtin(char *cmd)
{
const char *builtins[] = {"echo", "cd", "pwd", "export",
"unset", "env", "exit", NULL};
int i;
i = 0;
while (builtins[i])
{
if (ft_strcmp(cmd, builtins[i]) == 0)
return (i);
i++;
}
return (FALSE);
}

View File

@ -0,0 +1,21 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* simple_builtins.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 16:21:39 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:08:49 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void simple_builtins(t_minishell *msh)
{
if (msh->commands == NULL)
return ;
if (!builtin_router(msh, msh->commands->content))
executor_execute_pipeline(msh);
}

View File

@ -0,0 +1,55 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* print_commands.c :+: :+: */
/* +:+ */
/* By: marvin <marvin@student.42.fr> +#+ */
/* +#+ */
/* Created: 2025/02/18 20:06:37 by qmennen #+# #+# */
/* Updated: 2025/02/23 12:43:35 by Quinten ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void print_commands(void *param)
{
t_command *command;
int i;
if (!DEBUG)
return ;
command = (t_command *)param;
if (!command)
return ;
printf("command: %s\n", command->command);
printf("-- Args: ");
i = 0;
while (command->args[i])
printf("%s ", command->args[i++]);
printf("\n");
printf("-- Input redirects:\n");
ft_lstiter(command->redirect_in, print_redirects);
printf("-- Output redirects:\n");
ft_lstiter(command->redirect_out, print_redirects);
}
void print_redirects(void *param)
{
t_redirect *redirect;
redirect = (t_redirect *)param;
if (!redirect)
return ;
printf(" Redirect %i value %s\n", redirect->type, redirect->value);
}
void token_print(void *param)
{
t_token *token;
if (!DEBUG)
return ;
token = (t_token *)param;
printf("token type %i, value %s\n", token->type, token->value);
}

View File

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* print_freelist.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/25 15:46:03 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:08:53 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void print_freelist(t_minishell *msh)
{
t_list *freelist;
int i;
if (!DEBUG)
return ;
i = 0;
freelist = msh->freelist;
while (freelist)
{
printf("%d: %p\n", i, freelist->content);
i++;
freelist = freelist->next;
}
}

View File

@ -6,32 +6,32 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:13:33 by whaffman #+# #+# */
/* Updated: 2025/02/11 17:15:45 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:09:07 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void environment_add(t_list **environment, char *name, char *value)
void environment_add(t_minishell *msh, char *name, char *value)
{
t_environment *new_environment;
t_list *new_node;
t_list **environment;
environment = &msh->environment;
if (name != NULL && value != NULL)
{
new_environment = malloc(sizeof(t_environment));
new_environment = malloc_safe(msh, sizeof(t_environment));
if (new_environment == NULL)
return (perror("malloc"));
new_environment->name = ft_strdup(name);
new_environment->value = ft_strdup(value);
new_node = ft_lstnew(new_environment);
new_environment->name = ft_strdup_safe(msh, name);
new_environment->value = ft_strdup_safe(msh, value);
new_node = ft_lstnew_safe(msh, new_environment);
if (new_node == NULL
|| new_environment->name == NULL
|| new_environment->value == NULL)
{
free(new_environment->name);
free(new_environment->value);
free(new_environment);
environment_free(msh, new_environment);
return (perror("malloc"));
}
ft_lstadd_back(environment, new_node);

View File

@ -6,13 +6,13 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/11 14:17:53 by whaffman #+# #+# */
/* Updated: 2025/02/11 17:20:26 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:09:12 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void environment_del(t_list **environment, char *name)
void environment_del(t_minishell *msh, char *name)
{
t_list *prev;
t_list *current;
@ -21,17 +21,17 @@ void environment_del(t_list **environment, char *name)
prev = NULL;
next = NULL;
current = *environment;
current = msh->environment;
while (current != NULL)
{
env = (t_environment *)current->content;
if (ft_strncmp(env->name, name, ft_strlen(name) + 1) == 0)
{
next = current->next;
environment_free(current->content);
free(current);
environment_free(msh, current->content);
free_safe(msh, (void **)&(current));
if (prev == NULL)
*environment = next;
msh->environment = next;
else
prev->next = next;
return ;

View File

@ -6,18 +6,18 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/11 15:38:43 by whaffman #+# #+# */
/* Updated: 2025/02/11 15:38:48 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:09:17 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void environment_free(void *content)
void environment_free(t_minishell *msh, void *content)
{
t_environment *env;
env = (t_environment *)content;
free(env->name);
free(env->value);
free(env);
free_safe(msh, (void **)&(env->name));
free_safe(msh, (void **)&(env->value));
free_safe(msh, (void **)&(env));
}

View File

@ -6,13 +6,28 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:13:59 by whaffman #+# #+# */
/* Updated: 2025/02/11 17:18:27 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:09:15 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void environment_free_list(t_list **environment)
void environment_free_list(t_minishell *msh)
{
ft_lstclear(environment, environment_free);
t_list **lst;
t_list *next;
lst = &msh->environment;
if (!lst)
return ;
while (*lst)
{
if ((*lst)->next)
next = (*lst)->next;
else
next = NULL;
environment_free(msh, (*lst)->content);
free(*lst);
*lst = next;
}
}

View File

@ -6,16 +6,18 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:15:05 by whaffman #+# #+# */
/* Updated: 2025/02/11 17:04:28 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:09:22 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_environment *environment_get(t_list *environment, char *name)
t_environment *environment_get(t_minishell *msh, char *name)
{
t_environment *env;
t_list *environment;
environment = msh->environment;
while (environment != NULL)
{
env = (t_environment *)environment->content;

View File

@ -6,28 +6,28 @@
/* By: willem <willem@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/08 13:59:48 by willem #+# #+# */
/* Updated: 2025/02/11 17:18:15 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:09:20 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
char **environment_get_arr(t_list *environment)
char **environment_get_arr(t_minishell *msh)
{
char **arr;
t_environment *env;
int i;
t_list *environment;
arr = malloc(sizeof(char *) * (ft_lstsize(environment) + 1));
if (arr == NULL)
return (NULL);
environment = msh->environment;
arr = malloc_safe(msh,
sizeof(char *) * (ft_lstsize(environment) + 1));
i = 0;
while (environment != NULL)
{
env = (t_environment *)environment->content;
arr[i] = malloc(ft_strlen(env->name) + ft_strlen(env->value) + 2);
if (arr[i] == NULL)
return (ft_free_arr(arr), NULL);
arr[i] = malloc_safe(msh,
ft_strlen(env->name) + ft_strlen(env->value) + 2);
ft_strlcpy(arr[i], env->name, ft_strlen(env->name) + 1);
ft_strlcat(arr[i], "=", ft_strlen(env->name) + 2);
ft_strlcat(arr[i], env->value,

View File

@ -3,26 +3,27 @@
/* :::::::: */
/* environment_parse.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 15:52:33 by whaffman #+# #+# */
/* Updated: 2025/02/11 17:18:43 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:09:26 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int environment_parse(char **envp, t_list **environment)
int environment_parse(t_minishell *msh, char **envp)
{
char **env;
*environment = NULL;
if (envp == NULL)
return (FAILURE);
while (*envp != NULL)
{
env = ft_split(*envp, '=');
environment_add(environment, env[0], env[1]);
if (!env)
return (FAILURE);
environment_add(msh, env[0], env[1]);
ft_free_arr(env);
envp++;
}

View File

@ -6,23 +6,18 @@
/* By: willem <willem@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/08 13:52:08 by willem #+# #+# */
/* Updated: 2025/02/11 17:05:10 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:09:35 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void environment_print(t_list *environment)
void environment_print(t_minishell *msh)
{
char **arr;
int i;
arr = environment_get_arr(environment);
if (arr == NULL)
{
perror("malloc");
return ;
}
arr = environment_get_arr(msh);
i = 0;
while (arr[i] != NULL)
{

View File

@ -6,13 +6,41 @@
/* By: willem <willem@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/08 17:00:24 by willem #+# #+# */
/* Updated: 2025/02/11 17:20:17 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:09:42 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *executor_absolute_path(t_list *env, char *cmd)
static char *resolve_relative(t_minishell *msh, char *cmd)
{
char *executable;
if (access(cmd, F_OK) == 0)
{
executable = ft_strdup_safe(msh, cmd);
if (!executable)
return (NULL);
return (executable);
}
return (NULL);
}
static char *resolve_path(t_minishell *msh, char *path, char *cmd)
{
char *executable;
executable = malloc_safe(msh, ft_strlen(path) + ft_strlen(cmd) + 2);
ft_strlcpy(executable, path, ft_strlen(path) + 1);
ft_strlcat(executable, "/", ft_strlen(path) + 2);
ft_strlcat(executable, cmd, ft_strlen(path) + ft_strlen(cmd) + 2);
if (access(executable, F_OK) == 0)
return (executable);
free_safe(msh, (void **)&executable);
return (NULL);
}
char *executor_absolute_path(t_minishell *msh, char *cmd)
{
char **path;
t_environment *path_env;
@ -20,35 +48,17 @@ char *executor_absolute_path(t_list *env, char *cmd)
int i;
if (cmd[0] == '/' || cmd[0] == '.')
{
if (access(cmd, F_OK) == 0)
{
executable = ft_strdup(cmd);
if (!executable)
return (NULL);
return (executable);
}
return (NULL);
}
path_env = environment_get(env, "PATH");
return (resolve_relative(msh, cmd));
path_env = environment_get(msh, "PATH");
if (!path_env)
return (NULL);
path = ft_split(path_env->value, ':');
i = 0;
while (path[i] != NULL)
{
executable = malloc(ft_strlen(path[i]) + ft_strlen(cmd) + 2);
if (!executable)
return (ft_free_arr(path), NULL);
ft_strlcpy(executable, path[i], ft_strlen(path[i]) + 1);
ft_strlcat(executable, "/", ft_strlen(path[i]) + 2);
ft_strlcat(executable, cmd, ft_strlen(path[i]) + ft_strlen(cmd) + 2);
if (access(executable, F_OK) == 0)
{
ft_free_arr(path);
executable = resolve_path(msh, path[i], cmd);
if (executable)
return (executable);
}
free(executable);
i++;
}
return (ft_free_arr(path), NULL);

View File

@ -0,0 +1,50 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* executor_child.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/12 21:25:10 by willem #+# #+# */
/* Updated: 2025/02/27 18:12:48 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static int is_dir(char *path)
{
struct stat path_stats;
if (stat(path, &path_stats) < 0)
{
error_msg("is_dir", "path could not be read");
return (0);
}
return (S_ISDIR(path_stats.st_mode));
}
void executor_child(t_minishell *msh, t_command *command)
{
char *path;
if (command->fd_in != 0)
dup2(command->fd_in, 0);
if (command->fd_out != 1)
dup2(command->fd_out, 1);
executor_close_fds(command->n_fds);
path = executor_absolute_path(msh, command->args[0]);
if (path == NULL || access(path, F_OK | X_OK) != 0)
{
error_msg("minishell", "command not found");
return ;
}
if (is_dir(path))
{
ft_putstr_fd(RED BOLD, 2);
ft_putstr_fd("minishell: ", 2);
ft_putstr_fd(command->args[0], 2);
ft_putstr_fd(": " RESET "Is a directory\n", 2);
}
execve(path, command->args, environment_get_arr(msh));
}

View File

@ -0,0 +1,25 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* executor_close_fds.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/13 13:31:25 by whaffman #+# #+# */
/* Updated: 2025/02/13 15:04:15 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void executor_close_fds(int n_fds)
{
int i;
i = 3;
while (i < n_fds + 3)
{
close(i);
i++;
}
}

View File

@ -0,0 +1,31 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* executor_count_fds.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/21 12:42:26 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:09:45 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int executor_count_fds(t_minishell *msh)
{
int count;
t_list *current;
t_command *command;
current = msh->commands;
count = (ft_lstsize(current) - 1) * 2;
while (current)
{
command = (t_command *)current->content;
count += ft_lstsize(command->redirect_in);
count += ft_lstsize(command->redirect_out);
current = current->next;
}
return (count);
}

View File

@ -0,0 +1,52 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* executor_create_pipes.c :+: :+: */
/* +:+ */
/* By: willem <willem@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/12 21:25:22 by willem #+# #+# */
/* Updated: 2025/02/26 16:10:19 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
/**
* @brief Creates pipes for the executor in the minishell.
*
* This function sets up the necessary pipes for inter-process communication
* within the minishell. It initializes the pipes based on the requirements
* of the minishell structure.
*
* @param minishell A pointer to the t_minishell structure containing the
* necessary information for pipe creation.
*/
void executor_create_pipes(t_minishell *minishell)
{
t_list *current;
t_command *command;
int fd[2];
int fd_in;
const int n_fds = executor_count_fds(minishell);
fd_in = 0;
current = minishell->commands;
while (current)
{
command = (t_command *)current->content;
if (current->next)
{
if (pipe(fd) == -1)
error_msg("pipe", "pipe creation failed");
command->fd_out = fd[1];
}
else
command->fd_out = 1;
command->fd_in = fd_in;
command->n_fds = n_fds;
fd_in = fd[0];
current = current->next;
}
}

View File

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* executor_create_redirects.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/21 13:00:00 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:10:35 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void executor_create_redirects(t_minishell *msh)
{
t_list *current;
t_command *cmd;
current = msh->commands;
while (current)
{
cmd = (t_command *)current->content;
cmd->fd_in = executor_open_fds(cmd->redirect_in, cmd->fd_in);
cmd->fd_out = executor_open_fds(cmd->redirect_out, cmd->fd_out);
current = current->next;
}
}

View File

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* executor_execute_pipeline.c :+: :+: */
/* +:+ */
/* By: willem <willem@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/12 21:25:02 by willem #+# #+# */
/* Updated: 2025/02/26 17:42:46 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int executor_execute_pipeline(t_minishell *msh)
{
t_list *current;
t_command *command;
pid_t last_pid;
int exit_status;
executor_create_pipes(msh);
executor_create_redirects(msh);
current = msh->commands;
last_pid = 0;
while (current)
{
command = (t_command *)current->content;
command->environment = msh->environment;
last_pid = executor_fork(msh, command);
current = current->next;
}
waitpid(last_pid, &exit_status, 0);
msh->exit_status = ((exit_status) & 0xff00) >> 8;
signal_init_minishell();
return (((exit_status) & 0xff00) >> 8);
}

View File

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* executor_fork.c :+: :+: */
/* +:+ */
/* By: willem <willem@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/12 21:24:52 by willem #+# #+# */
/* Updated: 2025/02/26 17:44:36 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
//TODO should parent close the fds?
pid_t executor_fork(t_minishell *msh, t_command *command)
{
pid_t pid;
pid = fork();
if (pid > 0)
{
if (command->fd_in != 0)
close(command->fd_in);
if (command->fd_out != 1)
close(command->fd_out);
signal_init_parent();
}
else if (pid == 0)
{
signal_init_child();
executor_child(msh, command);
exit(127);
}
else
error_msg("minishell", "fork failed");
return (pid);
}

View File

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* executor_open_fds.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/21 12:50:42 by whaffman #+# #+# */
/* Updated: 2025/02/26 15:21:56 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
int executor_open_fds(t_list *redirect_list, int og_fd)
{
t_redirect *redirect;
int fd;
fd = og_fd;
while (redirect_list)
{
redirect = (t_redirect *)redirect_list->content;
if (redirect->type == T_REDIRECT_IN)
fd = open(redirect->value, O_RDONLY);
else if (redirect->type == T_REDIRECT_OUT)
fd = open(redirect->value, O_WRONLY | O_CREAT | O_TRUNC, 0644);
else if (redirect->type == T_APPEND_OUT)
fd = open(redirect->value, O_WRONLY | O_CREAT | O_APPEND, 0644);
if (fd < 0)
{
error_msg("executor_open_fds", "can't open file");
return (og_fd);
}
redirect_list = redirect_list->next;
}
return (fd);
}

View File

@ -0,0 +1,42 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* expander_allocate_memory.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/19 13:57:19 by qmennen #+# #+# */
/* Updated: 2025/02/26 18:05:17 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *expander_allocate_memory(
t_minishell *msh,
const char *s,
t_list *variables)
{
int size;
t_list *current;
t_environment *env;
char *string;
size = 1;
current = variables;
while (current)
{
if (current->content == NULL)
{
current = current->next;
continue ;
}
env = (t_environment *)current->content;
size += (ft_strlen(env->value) - ft_strlen(env->name));
current = current->next;
}
size += ft_strlen(s);
string = malloc_safe(msh, size);
string[0] = 0;
return (string);
}

View File

@ -0,0 +1,47 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* expander_expand_dollar.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/19 15:05:58 by qmennen #+# #+# */
/* Updated: 2025/02/19 15:22:40 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static int get_var_len(const char *source)
{
int i;
i = 1;
while (expander_character_valid(source[i]))
i++;
return (i);
}
int expander_expand_dollar(char *src, char *dest, int *j, t_list *variables)
{
int i;
int v_len;
t_environment *env;
i = 0;
v_len = 0;
if (variables && variables->content)
{
env = (t_environment *)variables->content;
v_len = ft_strlen(env->name);
while (env->value[i])
{
dest[(*j)++] = env->value[i++];
}
}
else
{
v_len = get_var_len(src);
}
return (v_len);
}

View File

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* expander_get_variable.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/19 13:59:03 by qmennen #+# #+# */
/* Updated: 2025/02/26 16:12:29 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_environment *expander_get_var(const char *s, int idx, t_minishell *msh)
{
int i;
t_environment *env;
char *name;
i = 0;
while (expander_character_valid(s[idx + i]))
i++;
name = ft_substr_safe(msh, s, idx, i);
if (!name || !*name)
return (NULL);
env = environment_get(msh, name);
free_safe(msh, (void **)&name);
return (env);
}

View File

@ -0,0 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* expander_is_character.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/19 13:15:11 by qmennen #+# #+# */
/* Updated: 2025/02/19 13:15:55 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int expander_character_valid(const char c)
{
return (ft_isalnum(c) || c == '_');
}

View File

@ -0,0 +1,57 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* expander_parse_string.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/18 19:00:35 by qmennen #+# #+# */
/* Updated: 2025/02/26 22:56:05 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
static void free_variables(t_minishell *msh, t_list *variables)
{
t_list *current;
t_list *last;
current = variables;
while (current)
{
last = current;
current = current->next;
free_safe(msh, (void **)&last);
}
}
//TODO: Figure out why echo "> echo "\as"" breaks
char *expander_parse_string(char *s, t_minishell *msh)
{
t_list *variables;
t_list *current;
char *string;
int i;
int j;
variables = expander_parse_variables(s, msh);
string = expander_allocate_memory(msh, s, variables);
current = variables;
i = 0;
j = 0;
while (s[i])
{
if (s[i] == '$' && s[i + 1] && current)
{
i++;
i += expander_expand_dollar(s + i, string, &j, current);
current = current->next;
}
else
string[j++] = s[i++];
}
string[j] = 0;
free_variables(msh, variables);
return (string);
}

View File

@ -0,0 +1,60 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* expander_parse_variables.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/19 13:58:13 by qmennen #+# #+# */
/* Updated: 2025/02/26 17:41:14 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
static char *ft_itoa_safe(t_minishell *msh, int n)
{
char *str;
str = ft_itoa(n);
check_malloc(msh, str);
return (str);
}
static t_list *create_exit_status_env(t_minishell *msh)
{
t_environment *env;
env = malloc_safe(msh, sizeof(t_environment));
env->name = ft_strdup_safe(msh, "?");
env->value = ft_itoa_safe(msh, msh->exit_status);
return (ft_lstnew_safe(msh, env));
}
t_list *expander_parse_variables(const char *s, t_minishell *msh)
{
int i;
t_list *var_list;
t_environment *env;
i = 0;
var_list = NULL;
while (s[i])
{
if (s[i] == '$')
{
env = expander_get_var(s, i + 1, msh);
if (env)
ft_lstadd_back(&var_list, ft_lstnew_safe(msh, env));
else
{
if (s[i + 1] == '?')
ft_lstadd_back(&var_list, create_exit_status_env(msh));
else
ft_lstadd_back(&var_list, ft_lstnew_safe(msh, NULL));
}
}
i++;
}
return (var_list);
}

View File

@ -1,28 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lexer_new.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* :::::::: */
/* lexer_new.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 19:03:01 by qmennen #+# #+# */
/* Updated: 2025/02/05 19:08:41 by qmennen ### ########.fr */
/* Updated: 2025/02/26 16:13:50 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_lexer *ft_lexer_new(const char *input)
t_lexer *ft_lexer_new(t_minishell *msh)
{
char *input;
t_lexer *lexer;
lexer = malloc(sizeof(t_lexer));
if (!lexer)
{
perror("failed assigning lexer memory");
exit(EXIT_FAILURE);
}
lexer->input = ft_strdup(input);
input = msh->line;
lexer = malloc_safe(msh, sizeof(t_lexer));
lexer->input = ft_strdup_safe(msh, input);
lexer->pos = 0;
lexer->n_pos = 1;
lexer->current_char = '\0';

View File

@ -1,16 +1,17 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lexer_parse_input.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* :::::::: */
/* lexer_parse_input.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 19:09:20 by qmennen #+# #+# */
/* Updated: 2025/02/05 19:09:26 by qmennen ### ########.fr */
/* Updated: 2025/02/26 16:13:54 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
//TODO: Check if unicode support is viable
/**
* @brief Parses the input from the lexer and returns a list of tokens.
@ -23,19 +24,21 @@
* the input to be parsed.
* @return A linked list of tokens parsed from the input.
*/
t_list *ft_parse_input(t_lexer *lexer)
t_list *ft_parse_input(t_minishell *msh)
{
t_list *list;
t_token *token;
t_lexer *lexer;
lexer = msh->lexer;
list = NULL;
while (TRUE)
{
token = ft_token_next(lexer);
if (token->type == T_EOF)
token = ft_token_next(msh, lexer);
if (token->type == T_EOF || token->type == T_ERROR)
break ;
ft_lstadd_back(&list, ft_lstnew(token));
ft_lstadd_back(&list, ft_lstnew_safe(msh, token));
}
ft_token_free(token);
ft_token_free(msh, token);
return (list);
}

View File

@ -0,0 +1,39 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lexer_parse_quotes.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/27 19:02:37 by qmennen #+# #+# */
/* Updated: 2025/02/27 19:26:35 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *lexer_parse_quotes(t_minishell *msh, t_lexer *lexer)
{
int start;
int len;
char qc;
char *word;
qc = lexer->current_char;
word = NULL;
lexer_readchar(lexer);
start = lexer->pos;
while (lexer->current_char != '\0' && lexer->current_char != qc)
lexer_readchar(lexer);
len = lexer->pos - start;
word = malloc_safe(msh, sizeof(char) * len + 1);
ft_strlcpy(word, lexer->input + start, len + 1);
if (lexer->current_char == qc)
lexer_readchar(lexer);
else
{
free_safe(msh, (void **)&word);
return (NULL);
}
return (word);
}

View File

@ -1,18 +1,18 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lexer_readchar.c :+: :+: :+: */
/* lexer_read_char.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/05 19:04:53 by qmennen #+# #+# */
/* Updated: 2025/02/05 19:05:06 by qmennen ### ########.fr */
/* Updated: 2025/02/18 17:02:17 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void ft_lexer_readchar(t_lexer *lexer)
void lexer_readchar(t_lexer *lexer)
{
if ((size_t)lexer->n_pos > ft_strlen(lexer->input))
{

View File

@ -6,58 +6,79 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/05 19:03:47 by qmennen #+# #+# */
/* Updated: 2025/02/05 19:28:17 by qmennen ### ########.fr */
/* Updated: 2025/02/27 19:30:09 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static char *parse_quotes(t_lexer *lexer)
static int match_quotes(t_minishell *msh, t_lexer *lexer)
{
int start;
int len;
char qc;
char *word;
char c;
int i;
int d_qts;
int s_qts;
qc = lexer->current_char;
word = NULL;
ft_lexer_readchar(lexer);
start = lexer->pos;
while (lexer->current_char != '\0' && lexer->current_char != qc)
ft_lexer_readchar(lexer);
len = lexer->pos - start;
word = malloc(sizeof(char) * len + 1);
ft_strlcpy(word, lexer->input + start, len + 1);
if (lexer->current_char == qc)
ft_lexer_readchar(lexer);
else
i = lexer->pos;
c = lexer->input[i];
d_qts = 0;
s_qts = 0;
//TODO: Normalize this validation. Happens a lot
while (ft_isprint(c) && c != '<' && c != '>' && c != '|' && c != '\0' && !ft_isspace(c))
{
free(word);
return (NULL);
if (lexer->input[i] == '\'')
s_qts++;
if (lexer->input[i] == '\'')
d_qts++;
i++;
c = lexer->input[i];
}
return (word);
return ((s_qts % 2) == 0 && (d_qts % 2) == 0);
}
char *ft_lexer_readword(t_lexer *lexer)
static int calculate_word_len(t_minishell *msh, t_lexer *lexer)
{
int i;
int len;
len = 1;
i = lexer->pos;
while (ft_isprint(lexer->input[i]) && lexer->input[i] != '<' && lexer->input[i]!= '>' && lexer->input[i] != '|' && lexer->input[i] != '\0' && !ft_isspace(lexer->input[i]))
{
if(lexer->input[i] != '\'' && lexer->input[i] != '"')
len++;
i++;
}
return (len);
}
char *lexer_readword(t_minishell *msh, t_lexer *lexer)
{
int start;
int len;
char *word;
char c;
start = lexer->pos;
if (lexer->current_char == '"' || lexer->current_char == '\'')
{
return (parse_quotes(lexer));
return (lexer_parse_quotes(msh, lexer));
}
while (ft_isprint(lexer->current_char) && lexer->current_char != '<'
&& lexer->current_char != '>' && lexer->current_char != '|'
&& lexer->current_char != '\0' && !ft_isspace(lexer->current_char)
&& lexer->current_char != '"' && lexer->current_char != '\'')
if (!match_quotes(msh, lexer))
return (NULL);
len = calculate_word_len(msh, lexer);
word = malloc_safe(msh, sizeof(char) * len);
c = lexer->current_char;
len = 0;
while (ft_isprint(c) && c != '<' && c != '>' && c != '|' && c != '\0' && !ft_isspace(c))
{
ft_lexer_readchar(lexer);
if(c != '\'' && c != '"')
word[len++] = lexer->current_char;
lexer_readchar(lexer);
c = lexer->current_char;
}
len = lexer->pos - start;
word = malloc(sizeof(char) * len + 1);
ft_strlcpy(word, lexer->input + start, len + 1);
word[len] = 0;
return (word);
}

View File

@ -1,17 +1,42 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* lexer_token_next.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* :::::::: */
/* lexer_token_next.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:07:58 by qmennen #+# #+# */
/* Updated: 2025/02/05 19:25:35 by qmennen ### ########.fr */
/* Updated: 2025/02/26 16:14:10 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
static t_token_type get_word_type(char c)
{
if (c == '\'')
return (T_SQWORD);
else if (c == '"')
return (T_DQWORD);
else
return (T_WORD);
}
static t_token *process_word(t_minishell *msh, t_lexer *lexer, int pos)
{
t_token_type word_type;
t_token *token;
char *word;
word_type = get_word_type(lexer->current_char);
word = lexer_readword(msh, lexer);
if (!word)
return (token_new(msh, T_ERROR, &(lexer->current_char), pos));
token = token_new(msh, word_type, word, pos);
free_safe(msh, (void **)&word);
return (token);
}
/**
* @brief Retrieves the next token from the lexer.
*
@ -31,30 +56,26 @@
* - If it is a printable character, reads the word and creates a word token.
* - Otherwise, creates an error token.
*/
t_token *ft_token_next(t_lexer *lexer)
t_token *ft_token_next(t_minishell *msh, t_lexer *lexer)
{
t_token *token;
char *word;
int current_pos;
char c;
token = NULL;
while (ft_isspace(lexer->current_char))
ft_lexer_readchar(lexer);
lexer_readchar(lexer);
current_pos = lexer->pos;
if (lexer->current_char == '\0')
token = ft_token_new(T_EOF, NULL, current_pos);
else if (lexer->current_char == '<' || lexer->current_char == '>'
|| lexer->current_char == '|')
token = ft_parse_token(lexer);
c = lexer->current_char;
if (c == '\0')
token = token_new(msh, T_EOF, NULL, current_pos);
else if (c == '<' || c == '>'
|| c == '|')
token = token_parse(msh, lexer);
else if (ft_isprint(lexer->current_char))
{
word = ft_lexer_readword(lexer);
if (!word)
return (ft_token_new(T_ERROR, &lexer->current_char, current_pos));
token = ft_token_new(T_WORD, word, current_pos);
free(word);
}
token = process_word(msh, lexer, current_pos);
else
token = ft_token_new(T_ERROR, NULL, current_pos);
token = token_new(msh, T_ERROR, NULL, current_pos);
c = lexer->current_char;
return (token);
}

View File

@ -6,7 +6,7 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:19:22 by whaffman #+# #+# */
/* Updated: 2025/02/08 14:09:11 by willem ######## odam.nl */
/* Updated: 2025/02/19 17:59:24 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
@ -14,35 +14,31 @@
#include "minishell.h"
#include "utils.h"
static void token_print(void *param)
{
t_token *token;
token = (t_token *)param;
printf("token type %i, value %s\n", token->type, token->value);
}
int main(int argc, char **argv, char **envp)
{
t_minishell *minishell;
t_minishell *msh;
(void)argc;
(void)argv;
print_banner();
ft_load_history();
minishell = init_minishell();
environment_parse(envp, &(minishell->environment));
history_load();
msh = init_minishell();
signal_init_minishell();
environment_parse(msh, envp);
while (TRUE)
{
minishell->line = ft_prompt(minishell);
minishell->lexer = ft_lexer_new(minishell->line);
minishell->tokens = ft_parse_input(minishell->lexer);
ft_lstiter(minishell->tokens, token_print);
// minishell->commands = parser_get_commands(minishell->tokens);
simple_builtins(minishell);
free_minishell_line(minishell);
ft_lstclear(&minishell->commands, free_command_list);
msh->line = ft_prompt(msh);
if (msh->line == NULL)
break ;
msh->lexer = ft_lexer_new(msh);
msh->tokens = ft_parse_input(msh);
ft_lstiter(msh->tokens, token_print);
msh->commands = parser_get_commands(msh);
simple_builtins(msh);
free_minishell_line(msh);
}
free_minishell(minishell);
ft_lstclear_safe(msh, &msh->commands, free_command_list);
free_minishell(&msh);
rl_clear_history();
return (EXIT_SUCCESS);
}

View File

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* parser_new_command.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/11 16:18:21 by qmennen #+# #+# */
/* Updated: 2025/02/26 16:14:31 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_command *parser_alloc_command(t_minishell *msh, char *cmd)
{
t_command *command;
command = malloc_safe(msh, sizeof(t_command));
command->args = NULL;
command->fd_in = 0;
command->fd_out = 1;
command->redirect_in = NULL;
command->redirect_out = NULL;
command->environment = NULL;
command->n_fds = 0;
command->command = cmd;
return (command);
}

View File

@ -0,0 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser_create_command.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/27 13:35:02 by qmennen #+# #+# */
/* Updated: 2025/02/27 13:36:48 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void parser_create_command(t_minishell *msh, t_command *cmd, t_list **l_tkn)
{
cmd->args = parser_get_arguments(*l_tkn, msh);
cmd->redirect_in = redirect_get_inputs(msh, *l_tkn);
cmd->redirect_out = redirect_get_outputs(msh, *l_tkn);
}

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/11 16:20:09 by qmennen #+# #+# */
/* Updated: 2025/02/11 16:26:41 by qmennen ### ########.fr */
/* Updated: 2025/02/27 18:58:48 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,20 +16,45 @@ static int count_cmds(t_list *list)
{
int cmds;
t_list *current;
t_token *token;
cmds = 0;
current = list;
while (current)
{
if (((t_token *)current->content)->type != T_WORD)
token = ((t_token *)current->content);
if (token->type >= 3)
break ;
cmds++;
current = current->next;
}
return (cmds - 1);
return (cmds);
}
char **parser_get_arguments(t_list *list)
static int parser_should_expand(t_list *value)
{
t_token *token;
int i;
token = (t_token *)value->content;
if (!token)
return (0);
i = 0;
if (token->type == T_DQWORD)
{
while (token->value[i])
{
if (token->value[i] == '$' && !expander_character_valid(token->value[i + 1]))
return (0);
i++;
}
return (1);
}
return ((token->type == T_WORD && token->value[0] == '$'
&& token->value[1]));
}
char **parser_get_arguments(t_list *list, t_minishell *msh)
{
t_list *current;
char **args;
@ -37,18 +62,17 @@ char **parser_get_arguments(t_list *list)
int i;
cmds = count_cmds(list);
args = malloc((cmds + 1) * sizeof(char *));
if (!args)
{
perror("malloc");
exit(EXIT_FAILURE);
}
current = list->next;
args = malloc_safe(msh, (cmds + 1) * sizeof(char *));
current = list;
i = -1;
while ((++i) < cmds && current)
{
if (((t_token *)current->content)->type == T_WORD)
args[i] = ft_strdup(((t_token *)current->content)->value);
if (parser_should_expand(current))
args[i] = expander_parse_string(
((t_token *)current->content)->value, msh);
else if (((t_token *)current->content)->type < 3)
args[i] = ft_strdup_safe(msh,
((t_token *)current->content)->value);
current = current->next;
}
args[i] = 0;

View File

@ -6,30 +6,18 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/11 14:06:02 by qmennen #+# #+# */
/* Updated: 2025/02/11 16:25:36 by qmennen ### ########.fr */
/* Updated: 2025/02/27 16:07:54 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static void print_cmds(void *content)
static int is_command_token(t_token *token)
{
t_command *cmd;
int i;
cmd = (t_command *)content;
printf("cmd: %s\n", cmd->command);
printf("args: ");
i = 0;
while (cmd->args[i])
{
printf("%s ", cmd->args[i]);
i++;
}
printf("\n");
return (token->type < 3 || redirect_token_type(token));
}
t_list *parser_get_commands(t_list *list)
t_list *parser_get_commands(t_minishell *msh)
{
t_list *command_list;
t_list *current;
@ -37,20 +25,22 @@ t_list *parser_get_commands(t_list *list)
t_token *token;
command_list = NULL;
if (!list)
if (!msh->tokens)
return (NULL);
current = list;
current = msh->tokens;
while (current)
{
token = (t_token *) current->content;
command = parser_command_new(ft_strdup(token->value));
command->args = parser_get_arguments(current);
ft_lstadd_back(&command_list, ft_lstnew(command));
while (current && ((t_token *)current->content)->type == T_WORD)
command = parser_alloc_command(msh, ft_strdup_safe(msh, token->value));
parser_create_command(msh, command, &current);
if (! parser_validate_command(command))
break ;
ft_lstadd_back(&command_list, ft_lstnew_safe(msh, command));
while (current && is_command_token((t_token *)current->content))
current = current->next;
if (current && ((t_token *)current->content)->type != T_WORD)
if (current && ((t_token *)current->content)->type >= 3)
current = current->next;
}
ft_lstiter(command_list, print_cmds);
ft_lstiter(command_list, print_commands);
return (command_list);
}

View File

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser_validate_command.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/27 16:06:33 by qmennen #+# #+# */
/* Updated: 2025/02/27 16:08:49 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
static int validate_redirects(t_list *lst)
{
t_list *token;
token = lst;
while (token)
{
if (((t_redirect *)token->content)->type == T_ERROR)
return (0);
token = token->next;
}
return (1);
}
int parser_validate_command(t_command *command)
{
int r_in;
int r_out;
r_in = validate_redirects(command->redirect_in);
r_out = validate_redirects(command->redirect_out);
return (r_in && r_out);
}

View File

@ -1,18 +1,18 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* ft_load_history.c :+: :+: */
/* history_load.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 16:44:51 by whaffman #+# #+# */
/* Updated: 2025/02/05 17:11:59 by whaffman ######## odam.nl */
/* Updated: 2025/02/12 12:54:04 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void ft_load_history(void)
void history_load(void)
{
int fd;
char *line;

View File

@ -1,21 +1,22 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* ft_write_history.c :+: :+: */
/* history_write.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 17:12:17 by whaffman #+# #+# */
/* Updated: 2025/02/05 17:12:23 by whaffman ######## odam.nl */
/* Updated: 2025/02/12 12:53:42 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void ft_write_history(char *line)
void history_write(char *line)
{
int fd;
add_history(line);
fd = open(".minishell_history", O_WRONLY | O_APPEND | O_CREAT, 0644);
if (fd < 0)
return ;

View File

@ -6,13 +6,13 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/04 16:13:08 by whaffman #+# #+# */
/* Updated: 2025/02/11 16:06:17 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:15:04 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *get_user(t_list *environment)
char *get_user(t_minishell *msh)
{
const char guest[] = "guest";
int len;
@ -20,73 +20,94 @@ char *get_user(t_list *environment)
char *username;
char *result;
user = environment_get(environment, "USER");
user = environment_get(msh, "USER");
if (user == NULL)
username = (char *)guest;
else
username = user->value;
len = ft_strlen(username) + ft_strlen(PROMPT) + ft_strlen(GREEN) + 1;
result = (char *)malloc(len);
if (result == NULL)
{
perror("malloc");
return (NULL);
}
len = ft_strlen(username) + ft_strlen(PROMPT GREEN) + 1;
result = (char *)malloc_safe(msh, len);
ft_strlcpy(result, GREEN, ft_strlen(GREEN) + 1);
ft_strlcat(result, username, ft_strlen(GREEN) + ft_strlen(username) + 1);
ft_strlcat(result, PROMPT, len);
return (result);
}
char *get_path(t_list *environment)
int get_home_len(t_minishell *msh, char *cwd)
{
char *home;
char *temp;
char *cwd;
t_environment *home;
int home_len;
cwd = getcwd(NULL, 0);
home = environment_get(environment, "HOME")->value;
if (cwd == NULL)
{
perror("getcwd");
return (NULL);
}
if (home && ft_strncmp(cwd, home, ft_strlen(home)) == 0)
{
temp = ft_strjoin("~", cwd + ft_strlen(home));
free(cwd);
cwd = temp;
}
temp = ft_strjoin(BLUE, cwd);
free(cwd);
cwd = ft_strjoin(temp, RESET);
free(temp);
return (cwd);
home = environment_get(msh, "HOME");
home_len = 0;
if (home && !ft_strncmp(cwd, home->value, ft_strlen(home->value)))
home_len = ft_strlen(home->value) - 1;
return (home_len);
}
char *ft_prompt(t_minishell *minishell)
char *get_path_with_home(t_minishell *msh)
{
char *result;
char *cwd;
int len;
int home_len;
cwd = getcwd(NULL, 0);
if (cwd == NULL)
return (perror("getcwd"), NULL);
home_len = get_home_len(msh, cwd);
len = ft_strlen(cwd) - home_len + 1;
result = malloc_safe(msh, len);
if (home_len)
{
ft_strlcpy(result, "~", 2);
ft_strlcat(result, cwd + home_len + 1, len);
}
else
ft_strlcpy(result, cwd, len);
free(cwd);
return (result);
}
char *get_path(t_minishell *msh)
{
char *result;
char *cwd;
int len;
cwd = get_path_with_home(msh);
if (cwd == NULL)
return (NULL);
len = ft_strlen(cwd) + ft_strlen(BLUE RESET "> ") + 1;
result = malloc_safe(msh, len);
ft_strlcpy(result, BLUE, len);
ft_strlcat(result, cwd, len);
ft_strlcat(result, RESET "> ", len);
free_safe(msh, (void **) &cwd);
return (result);
}
char *ft_prompt(t_minishell *msh)
{
char *line;
char *cwd;
char *prompt;
char *user;
char *temp;
cwd = get_path(minishell->environment);
cwd = get_path(msh);
if (cwd == NULL)
return (NULL);
user = get_user(minishell->environment);
temp = ft_strjoin(user, cwd);
free(user);
free(cwd);
prompt = ft_strjoin(temp, "> ");
free(temp);
user = get_user(msh);
if (user == NULL)
return (free(cwd), NULL);
prompt = ft_strjoin_safe(msh, user, cwd);
free_safe(msh, (void **)&user);
free_safe(msh, (void **)&cwd);
rl_on_new_line();
line = readline(prompt);
free(prompt);
if (line != NULL)
{
add_history(line);
ft_write_history(line);
}
free_safe(msh, (void **)&prompt);
if (line == NULL)
return (NULL);
history_write(line);
return (line);
}

View File

@ -0,0 +1,47 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_get_inputs.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/23 12:29:05 by Quinten #+# #+# */
/* Updated: 2025/02/27 18:09:15 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "redirect.h"
static void check_heredoc(t_minishell *msh, t_list *current, t_token *token)
{
if (token->type == T_HEREDOC && redirect_is_valid(current, token, -1))
process_heredoc(msh, token, current->next->content);
}
t_list *redirect_get_inputs(t_minishell *msh, t_list *list)
{
t_list *current;
t_list *redirects;
t_token *token;
int flag;
redirects = NULL;
current = list;
flag = 1;
token = (t_token *)current->content;
while (current && flag && !redirect_is_delimiter(token))
{
token = (t_token *)current->content;
if (token->type != T_REDIRECT_IN && token->type != T_HEREDOC)
{
current = current->next;
continue ;
}
check_heredoc(msh, current, token);
flag = redirect_is_valid(current, token, F_OK | R_OK);
flag && (redirect_create(msh, &current, &redirects, token->type));
current = current->next;
}
redirect_new_error(msh, &redirects, flag);
return (redirects);
}

View File

@ -0,0 +1,40 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_get_outputs.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/23 12:37:24 by Quinten #+# #+# */
/* Updated: 2025/02/27 18:12:04 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_list *redirect_get_outputs(t_minishell *msh, t_list *list)
{
t_list *current;
t_list *redirects;
t_token *token;
int flag;
flag = 1;
redirects = NULL;
current = list;
token = (t_token *)current->content;
while (current && !redirect_is_delimiter(token))
{
token = (t_token *)current->content;
if (token->type != T_REDIRECT_OUT && token->type != T_APPEND_OUT)
{
current = current->next;
continue ;
}
flag = redirect_is_valid(current, token, -1);
flag && (redirect_create(msh, &current, &redirects, token->type));
current = current->next;
}
redirect_new_error(msh, &redirects, flag);
return (redirects);
}

View File

@ -0,0 +1,45 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_new.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/23 12:27:33 by Quinten #+# #+# */
/* Updated: 2025/02/27 18:11:25 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_redirect *redirect_new(t_minishell *msh, t_token_type type, char *value)
{
t_redirect *result;
result = malloc_safe(msh, sizeof(t_redirect));
result->type = type;
result->value = NULL;
if (value)
result->value = value;
return (result);
}
int redirect_create(t_minishell *msh, t_list **tokens, t_list **redirects,
t_token_type type)
{
t_list *new;
t_redirect *redir;
t_token *file_token;
char *file_name;
file_token = (t_token *)((*tokens)->next->content);
file_name = NULL;
if (file_token)
file_name = ft_strdup_safe(msh, file_token->value);
redir = redirect_new(msh, type, file_name);
new = ft_lstnew_safe(msh, redir);
ft_lstadd_back(redirects, new);
if (tokens)
*tokens = (*tokens)->next;
return (1);
}

View File

@ -1,30 +1,25 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser_new_command.c :+: :+: :+: */
/* redirect_new_error.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/11 16:18:21 by qmennen #+# #+# */
/* Updated: 2025/02/11 16:25:12 by qmennen ### ########.fr */
/* Created: 2025/02/26 17:37:12 by qmennen #+# #+# */
/* Updated: 2025/02/27 18:07:25 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_command *parser_command_new(char *cmd)
void redirect_new_error(t_minishell *msh, t_list **redirects, int flag)
{
t_command *command;
t_list *new;
t_redirect *redir;
command = malloc(sizeof(t_command));
if (!command)
{
perror("minishell malloc error");
exit(EXIT_FAILURE);
}
command->args = NULL;
command->fd_in = 0;
command->fd_out = 1;
command->command = cmd;
return (command);
if (flag)
return ;
redir = redirect_new(msh, T_ERROR, NULL);
new = ft_lstnew_safe(msh, redir);
ft_lstadd_back(redirects, new);
}

View File

@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_process_heredoc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/26 16:46:32 by qmennen #+# #+# */
/* Updated: 2025/02/26 16:54:09 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
/**
* process_heredoc - Handles the processing of a heredoc in a minishell.
* @msh: Pointer to the minishell structure.
* @heredoc: Pointer to the token representing the heredoc.
* @delim: Pointer to the token representing the delimiter.
*
* This function reads lines from the standard input until a line matching
* the delimiter is encountered or an end-of-file (EOF) is reached. Each
* line is expanded and written to a temporary file named ".ms_heredoc".
* The function sets the type of the heredoc token to T_REDIRECT_IN and
* updates the delimiter token's value to the temporary file's name.
*
* Return: 1 on success, or a negative value on failure.
*/
int process_heredoc(t_minishell *msh, t_token *heredoc, t_token *delim)
{
char *line;
char *expand;
const int fd = open(".ms_heredoc", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd < 0)
{
error_msg("heredoc", "unable to write to temp file");
return (fd);
}
while (TRUE)
{
line = readline(">");
if ((*line && ft_strcmp(line, delim->value) == 0) || !line)
break ;
if (!*line)
ft_strlcat(line, "\n", 1);
expand = expander_parse_string(line, msh);
ft_putendl_fd(expand, fd);
free_safe(msh, (void **)&expand);
free(line);
}
close(fd);
heredoc->type = T_REDIRECT_IN;
delim->value = ft_strdup_safe(msh, ".ms_heredoc");
return (free(line), 1);
}

View File

@ -0,0 +1,49 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* redirect_valid_type.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/23 12:30:18 by Quinten #+# #+# */
/* Updated: 2025/02/26 17:40:44 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
int redirect_token_type(t_token *token)
{
return (token->type == T_REDIRECT_IN
|| token->type == T_HEREDOC
|| token->type == T_REDIRECT_OUT
|| token->type == T_APPEND_OUT);
}
int redirect_is_valid(t_list *lst, t_token *token, int mode)
{
t_token *next;
if (!lst->next)
return (0);
next = (t_token *)lst->next->content;
if (!next)
{
return (0);
}
if (mode >= 0 && access(next->value, mode) != 0)
{
error_msg("minishell", "unable to write to temp file");
return (0);
}
return (redirect_token_type(token) && next->type < 3);
}
int redirect_is_delimiter(t_token *token)
{
return (token->type == T_PIPE
|| token->type == T_AND
|| token->type == T_OR
|| token->type == T_EOF
|| token->type == T_ERROR);
}

37
src/signal/signal.c Normal file
View File

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* signal.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/19 12:18:47 by whaffman #+# #+# */
/* Updated: 2025/02/26 15:42:30 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void sigint_minishell_handler(int signum)
{
(void)signum;
ft_putstr_fd("\n", 1);
rl_on_new_line();
rl_replace_line("", 0);
rl_redisplay();
}
void sigint_heredoc_handler(int signum)
{
(void)signum;
ft_putstr_fd("\n", 1);
rl_on_new_line();
rl_replace_line("", 0);
exit(130);
}
void sig_parent_handler(int signum)
{
(void)signum;
ft_putstr_fd("\n", 1);
}

View File

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* signal_init.c.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/26 15:39:01 by whaffman #+# #+# */
/* Updated: 2025/02/26 15:39:46 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void signal_init_minishell(void)
{
signal(SIGINT, sigint_minishell_handler);
signal(SIGQUIT, SIG_IGN);
}
void signal_init_parent(void)
{
signal(SIGINT, sig_parent_handler);
signal(SIGQUIT, sig_parent_handler);
}
void signal_init_child(void)
{
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
}
void signal_init_heredoc(void)
{
signal(SIGINT, sigint_heredoc_handler);
signal(SIGQUIT, SIG_IGN);
}

View File

@ -0,0 +1,38 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* token_char_convert.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/27 18:25:34 by qmennen #+# #+# */
/* Updated: 2025/02/27 18:28:13 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
# include "minishell.h"
t_token_type token_char_convert(char c, int is_double)
{
if (c == '<')
{
if (is_double)
return (T_HEREDOC);
return (T_REDIRECT_IN);
}
else if (c == '>')
{
if (is_double)
return (T_APPEND_OUT);
return (T_REDIRECT_OUT);
}
else if (c == '&' && is_double)
return (T_AND);
else if (c == '|')
{
if (is_double)
return (T_OR);
return (T_PIPE);
}
return (T_ERROR);
}

View File

@ -1,31 +1,26 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* token_new.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* :::::::: */
/* token_new.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 19:10:49 by qmennen #+# #+# */
/* Updated: 2025/02/05 19:11:32 by qmennen ### ########.fr */
/* Updated: 2025/02/26 16:15:17 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_token *ft_token_new(t_token_type type, char *c, int pos)
t_token *token_new(t_minishell *msh, t_token_type type, char *c, int pos)
{
t_token *token;
token = malloc(sizeof(t_token));
if (!token)
{
perror("failed assigning token memory");
exit(EXIT_FAILURE);
}
token = malloc_safe(msh, sizeof(t_token));
token->type = type;
token->position = pos;
if (c)
token->value = ft_strdup(c);
token->value = ft_strdup_safe(msh, c);
else
token->value = NULL;
return (token);

View File

@ -6,39 +6,25 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/05 19:10:17 by qmennen #+# #+# */
/* Updated: 2025/02/11 17:38:51 by qmennen ### ########.fr */
/* Updated: 2025/02/27 18:27:40 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_token *ft_parse_token(t_lexer *lexer)
t_token *token_parse(t_minishell *msh, t_lexer *lexer)
{
int is_double;
char c;
t_token *token;
t_token_type type;
token = NULL;
if (lexer->current_char == '|')
{
token = ft_token_new(T_PIPE, "|", lexer->pos);
}
else if (lexer->current_char == '<' && lexer->input[lexer->pos + 1] == '<')
{
token = ft_token_new(T_HEREDOC, "<<", lexer->pos);
ft_lexer_readchar(lexer);
}
else if (lexer->current_char == '<')
{
token = ft_token_new(T_REDIRECT_IN, "<", lexer->pos);
}
else if (lexer->current_char == '>' && lexer->input[lexer->pos + 1] == '>')
{
token = ft_token_new(T_APPEND_OUT, ">>", lexer->pos);
ft_lexer_readchar(lexer);
}
else if (lexer->current_char == '>')
{
token = ft_token_new(T_REDIRECT_OUT, ">", lexer->pos);
}
ft_lexer_readchar(lexer);
c = lexer->current_char;
is_double = lexer->input[lexer->pos + 1] == c;
type = token_char_convert(c, is_double);
token = token_new(msh, type, token_type_convert(type), lexer->pos);
if (is_double)
lexer_readchar(lexer);
lexer_readchar(lexer);
return (token);
}

View File

@ -0,0 +1,32 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* token_type_convert.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/27 18:25:34 by qmennen #+# #+# */
/* Updated: 2025/02/27 18:26:40 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
# include "minishell.h"
char *token_type_convert(t_token_type type)
{
if (type == T_HEREDOC)
return ("<<");
else if (type == T_REDIRECT_IN)
return ("<");
else if (type == T_APPEND_OUT)
return (">>");
else if (type == T_REDIRECT_OUT)
return (">");
else if (type == T_AND)
return ("&&");
else if (type == T_OR)
return ("||");
else if (type == T_PIPE)
return ("|");
return (NULL);
}

37
src/utils/check_malloc.c Normal file
View File

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* check_malloc.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 18:00:10 by whaffman #+# #+# */
/* Updated: 2025/02/20 18:01:08 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void check_malloc(t_minishell *msh, void *ptr)
{
t_list *new;
if (ptr == NULL)
{
error_msg("malloc", "can't allocate memory");
ft_lstclear(&(msh->freelist), free);
exit(1);
}
else
{
new = ft_lstnew(ptr);
if (new == NULL)
{
error_msg("malloc", "can't allocate memory");
ft_lstclear(&(msh->freelist), free);
exit(1);
}
else
ft_lstadd_front(&(msh->freelist), new);
}
}

33
src/utils/error_msg.c Normal file
View File

@ -0,0 +1,33 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* error_msg.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 17:03:13 by whaffman #+# #+# */
/* Updated: 2025/02/20 17:59:36 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void error_msg(char *func, char *msg)
{
if (errno)
perror(RED BOLD "minishell" RESET);
else
{
ft_putstr_fd(RED BOLD "minishell" RESET ": ", 2);
if (func != NULL)
{
ft_putstr_fd(func, 2);
ft_putstr_fd(": ", 2);
}
if (msg != NULL)
ft_putstr_fd(msg, 2);
else
ft_putstr_fd("general error", 2);
ft_putstr_fd("\n", 2);
}
}

View File

@ -1,38 +1,62 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* free_command_list.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* :::::::: */
/* free_command_list.c :+: :+: */
/* +:+ */
/* By: marvin <marvin@student.42.fr> +#+ */
/* +#+ */
/* Created: 2025/02/11 14:24:05 by qmennen #+# #+# */
/* Updated: 2025/02/11 14:27:02 by qmennen ### ########.fr */
/* Updated: 2025/02/23 12:40:17 by Quinten ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
static void free_args(char **args)
static void free_args(t_minishell *msh, char **args)
{
int i;
i = 0;
while (args[i])
{
free(args[i]);
free_safe(msh, (void **)&args[i]);
i++;
}
free(args);
free_safe(msh, (void **)&args);
}
void free_command_list(void *content)
static void free_redirects(t_minishell *msh, t_list *lst)
{
t_redirect *redir;
t_list *current;
t_list *last;
current = lst;
while (current)
{
last = current;
redir = (t_redirect *)current->content;
if (redir && redir->value)
free_safe(msh, (void **)&redir->value);
if (redir)
free_safe(msh, (void **)&redir);
current = current->next;
free_safe(msh, (void **)&last);
}
}
void free_command_list(t_minishell *msh, void *content)
{
t_command *command;
command = (t_command *)content;
if (command->command)
free(command->command);
free_safe(msh, (void **)&(command->command));
if (command->args)
free_args(command->args);
free(command);
free_args(msh, command->args);
if (command->redirect_in)
free_redirects(msh, command->redirect_in);
if (command->redirect_out)
free_redirects(msh, command->redirect_out);
free_safe(msh, (void **)&command);
}

29
src/utils/free_freelist.c Normal file
View File

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* free_freelist.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/25 13:23:30 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:15:29 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void free_freelist(t_minishell *msh)
{
t_list *freelist;
t_list *next;
freelist = msh->freelist;
while (freelist)
{
next = freelist->next;
free(freelist->content);
free(freelist);
freelist = next;
}
msh->freelist = NULL;
}

View File

@ -1,20 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* free_lexer.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* :::::::: */
/* free_lexer.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 19:07:01 by qmennen #+# #+# */
/* Updated: 2025/02/05 19:07:18 by qmennen ### ########.fr */
/* Updated: 2025/02/26 16:15:31 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void ft_lexer_free(t_lexer *lexer)
void ft_lexer_free(t_minishell *msh, t_lexer *lexer)
{
if (lexer->input)
free(lexer->input);
free(lexer);
free_safe(msh, (void **)&(lexer->input));
free_safe(msh, (void **)&lexer);
}

View File

@ -6,17 +6,15 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 16:03:57 by whaffman #+# #+# */
/* Updated: 2025/02/11 15:36:24 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 16:15:42 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void free_minishell(t_minishell *minishell)
void free_minishell(t_minishell **msh)
{
if (minishell->line)
free_minishell_line(minishell);
if (minishell->environment)
environment_free_list(&minishell->environment);
free(minishell);
free_freelist(*msh);
free(*msh);
*msh = NULL;
}

View File

@ -1,25 +1,25 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* free_minishell_line.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* ::: :::::::: */
/* free_minishell_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/02/05 16:01:44 by whaffman #+# #+# */
/* Updated: 2025/02/05 16:02:07 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 14:24:20 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "minishell.h"
void free_minishell_line(t_minishell *minishell)
void free_minishell_line(t_minishell *msh)
{
if (minishell->line)
free(minishell->line);
if (minishell->lexer)
ft_lexer_free(minishell->lexer);
if (minishell->tokens)
ft_lstclear(&minishell->tokens, ft_clear_tokenlist);
if (minishell->commands)
ft_lstclear(&minishell->commands, free_command_list);
if (msh->line)
free(msh->line);
if (msh->lexer)
ft_lexer_free(msh, msh->lexer);
if (msh->tokens)
ft_lstclear_safe(msh, &msh->tokens, ft_clear_tokenlist);
if (msh->commands)
ft_lstclear_safe(msh, &msh->commands, free_command_list);
}

42
src/utils/free_safe.c Normal file
View File

@ -0,0 +1,42 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* free_safe.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/25 15:09:34 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:20:46 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void free_safe(t_minishell *msh, void **ptr)
{
t_list *prev;
t_list *current;
prev = NULL;
current = msh->freelist;
if (*ptr)
{
while (current)
{
if (current->content == *ptr)
{
if (prev)
prev->next = current->next;
else
msh->freelist = current->next;
free(*ptr);
free(current);
return ;
}
prev = current;
current = current->next;
}
error_msg("free_safe", "pointer not found in freelist");
}
*ptr = NULL;
}

View File

@ -1,20 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* free_token.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* :::::::: */
/* free_token.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 19:07:45 by qmennen #+# #+# */
/* Updated: 2025/02/05 19:07:54 by qmennen ### ########.fr */
/* Updated: 2025/02/26 16:16:01 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void ft_token_free(t_token *token)
void ft_token_free(t_minishell *msh, t_token *token)
{
if (token->value)
free(token->value);
free(token);
free_safe(msh, (void **)&token->value);
free_safe(msh, (void **)&token);
}

View File

@ -1,21 +1,21 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* free_token_list.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* :::::::: */
/* free_token_list.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 19:08:14 by qmennen #+# #+# */
/* Updated: 2025/02/05 19:08:31 by qmennen ### ########.fr */
/* Updated: 2025/02/26 16:15:58 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void ft_clear_tokenlist(void *content)
void ft_clear_tokenlist(t_minishell *msh, void *content)
{
t_token *token;
token = (t_token *)content;
ft_token_free(token);
ft_token_free(msh, token);
}

View File

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* ft_lstclear_safe.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/25 16:21:16 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:16:21 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
void ft_lstclear_safe(t_minishell *msh, t_list **lst,
void (*del)(t_minishell *msh, void *))
{
t_list *current;
t_list *next;
current = *lst;
while (current)
{
next = current->next;
del(msh, current->content);
free_safe(msh, (void **)&current);
current = next;
}
*lst = NULL;
}

View File

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* ft_lstnew_safe.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/25 16:47:09 by whaffman #+# #+# */
/* Updated: 2025/02/26 16:16:29 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
t_list *ft_lstnew_safe(t_minishell *msh, void *content)
{
t_list *new;
new = malloc_safe(msh, sizeof(t_list));
new->content = content;
new->next = NULL;
return (new);
}

View File

@ -0,0 +1,22 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* ft_strdup_safe.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 18:01:27 by whaffman #+# #+# */
/* Updated: 2025/02/20 18:04:53 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *ft_strdup_safe(t_minishell *msh, const char *str)
{
char *new_str;
new_str = ft_strdup(str);
check_malloc(msh, new_str);
return (new_str);
}

View File

@ -0,0 +1,22 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* ft_strjoin_safe.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 18:02:31 by whaffman #+# #+# */
/* Updated: 2025/02/20 18:04:23 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *ft_strjoin_safe(t_minishell *msh, const char *s1, const char *s2)
{
char *new_str;
new_str = ft_strjoin(s1, s2);
check_malloc(msh, new_str);
return (new_str);
}

View File

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* ft_strdup_safe.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/20 18:01:27 by whaffman #+# #+# */
/* Updated: 2025/02/20 18:04:53 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
#include "minishell.h"
char *ft_substr_safe(t_minishell *minishell, const char *str,
unsigned int start, size_t len)
{
char *new_str;
new_str = ft_substr(str, start, len);
check_malloc(minishell, new_str);
return (new_str);
}

View File

@ -6,7 +6,7 @@
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/02/05 16:03:03 by whaffman #+# #+# */
/* Updated: 2025/02/05 16:03:15 by whaffman ######## odam.nl */
/* Updated: 2025/02/26 17:39:41 by whaffman ######## odam.nl */
/* */
/* ************************************************************************** */
@ -14,18 +14,20 @@
t_minishell *init_minishell(void)
{
t_minishell *minishell;
t_minishell *msh;
minishell = malloc(sizeof(t_minishell));
if (!minishell)
msh = malloc(sizeof(t_minishell));
if (!msh)
{
perror("failed assigning minishell memory");
perror("failed assigning msh memory");
exit(EXIT_FAILURE);
}
minishell->environment = NULL;
minishell->line = NULL;
minishell->lexer = NULL;
minishell->tokens = NULL;
minishell->commands = NULL;
return (minishell);
msh->environment = NULL;
msh->line = NULL;
msh->lexer = NULL;
msh->tokens = NULL;
msh->commands = NULL;
msh->freelist = NULL;
msh->exit_status = 0;
return (msh);
}

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