diff --git "a/\025\002\315L\006" "b/\025\002\315L\006" deleted file mode 100644 index e69de29..0000000 diff --git "a/\037\340\272 \006" "b/\037\340\272 \006" deleted file mode 100644 index e69de29..0000000 diff --git a/.gitignore b/.gitignore index 533c9c8..6dd9549 100644 --- a/.gitignore +++ b/.gitignore @@ -66,4 +66,6 @@ $HOME $USER $USER'$USER' -*.swp \ No newline at end of file +*.swp +*.swo +.vscode/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f66c464 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libft"] + path = libft + url = git@github.com:grignetta/42_libft.git diff --git a/.swo b/.swo deleted file mode 100644 index 89a94b8..0000000 Binary files a/.swo and /dev/null differ diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index c26424e..0000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "c17", - "cppStandard": "gnu++17", - "intelliSenseMode": "linux-gcc-x64" - }, - { - "name": "Path_signals", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [], - "compilerPath": "/usr/bin/clang", - "cStandard": "c17", - "cppStandard": "c++14", - "intelliSenseMode": "linux-clang-x64" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json deleted file mode 100644 index 08d9005..0000000 --- a/.vscode/tasks.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "tasks": [ - { - "type": "cppbuild", - "label": "C/C++: gcc build active file", - "command": "/usr/bin/gcc", - "args": [ - "-fdiagnostics-color=always", - "-g", - "${file}", - "-o", - "${fileDirname}/${fileBasenameNoExtension}" - ], - "options": { - "cwd": "${fileDirname}" - }, - "problemMatcher": [ - "$gcc" - ], - "group": { - "kind": "build", - "isDefault": true - }, - "detail": "Task generated by Debugger." - } - ], - "version": "2.0.0" -} \ No newline at end of file diff --git a/Makefile b/Makefile index 91c6eb3..42aa642 100644 --- a/Makefile +++ b/Makefile @@ -1,90 +1,73 @@ NAME = minishell -HEADER = lexer.h CC = cc -CFLAGS = -g -Wall -Wextra -Werror# -fsanitize=address +CFLAGS = -g -Wall -Wextra -Werror -MMD -MP # -fsanitize=address + +INC_DIR = include +SRC_DIR = src +OBJ_DIR = obj LIBDIR = ./libft -OBJDIR = ./obj LIBFT = $(LIBDIR)/libft.a -SOURCES = env_main.c \ - env_utils.c \ - env_handling.c \ - error_handling.c \ - exec_builtins_exit.c \ - exec_builtins_cd.c \ - exec_builtins_echo.c \ - exec_builtins_env.c \ - exec_builtins_export.c \ - exec_builtins_export_utils.c \ - exec_builtins_pwd.c \ - exec_builtins_unset.c \ - exec_builtins.c \ - execute_node.c \ - execute_node_handle_redirect.c \ - execute_node_handle_redirect_utils.c \ - execute_node_handle_redirect_error.c \ - execute_node_handle_heredoc.c \ - execute_node_handle_heredoc_utils.c \ - execute_node_exec_cmd.c \ - handle_dollar_sign.c \ - handle_dollar_sign_utils.c \ - execute_node_utils.c \ - execute_parse_tree.c \ - execute_pipeline_utils.c \ - free_functions.c \ - lexer_main.c \ - lexer.c \ - main.c \ - main_handle_input.c \ - parser_is_all_rest.c \ - parser_is_cmd_suffix.c \ - parser_main.c \ - parser_utils.c \ - init_1.c \ - init_2.c \ - handle_quotes_main_1.c \ - handle_quotes_main_2.c \ - handle_quotes_utils_1.c \ - handle_quotes_utils_2.c \ - handle_quotes_redirect.c \ - execute_pipeline_utils_1.c \ - execute_node_handle_child_cmd.c \ - execute_node_error_messages.c \ - free_functions_1.c \ - pipeline_here_doc_dol_closed.c \ - pipeline_here_doc_main.c \ - pipeline_here_doc_dol_open.c \ - get_path_for_exec.c \ - get_path_for_exec_utils.c \ - get_path_for_exec_colon.c \ - signals.c \ - - -OBJ = $(addprefix $(OBJDIR)/, $(SOURCES:.c=.o)) +#PRINTFD_DIR := ./printf_fd +#PRINTFD_LIB := $(PRINTFD_DIR)/libprintf_fd.a -all: $(NAME) +# -------- Readline (Linux/macOS) -------- +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Darwin) + RL_INC := -I/opt/homebrew/opt/readline/include + RL_LIB := -L/opt/homebrew/opt/readline/lib -lreadline +else + RL_INC := + RL_LIB := -lreadline +endif + +SRC = $(shell find $(SRC_DIR) -type f -name '*.c') +OBJ = $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRC)) +DEP = $(OBJ:.o=.d) -$(OBJDIR): - mkdir -p $(OBJDIR) +.PHONY: all clean fclean re libs -$(OBJDIR)/%.o: %.c | $(OBJDIR) - $(CC) $(CFLAGS) -o $@ -c $< -I. +all: $(NAME) + +#$(NAME): $(LIBFT) $(PRINTFD_LIB) $(OBJ) +# $(CC) $(CFLAGS) $(OBJ) $(PRINTFD_LIB) -L$(LIBDIR) -lft $(RL_LIB) -o $@ $(NAME): $(LIBFT) $(OBJ) - $(CC) $(CFLAGS) $(OBJ) -L$(LIBDIR) -lft -lreadline -o $(NAME) + $(CC) $(CFLAGS) $(OBJ) -L$(LIBDIR) -lft $(RL_LIB) -o $@ + + +$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR) + @mkdir -p $(dir $@) +# $(CC) $(CFLAGS) -I$(INC_DIR) -I$(LIBDIR) -I$(PRINTFD_DIR) $(RL_INC) -c $< -o $@ + $(CC) $(CFLAGS) -I$(INC_DIR) -I$(LIBDIR) $(RL_INC) -c $< -o $@ + +$(OBJ_DIR): + @mkdir -p $(OBJ_DIR) + +#$(LIBDIR)/.git: +# @git submodule update --init --recursive + +#$(LIBFT): | $(LIBDIR)/.git +# $(MAKE) -C $(LIBDIR) all $(LIBFT): - $(MAKE) -C $(LIBDIR) all + $(MAKE) -C $(LIBDIR) all + -.PHONY: clean fclean all re +#$(PRINTFD_LIB): +# $(MAKE) -C $(PRINTFD_DIR) all clean: - $(MAKE) -C $(LIBDIR) clean - rm -rf $(OBJDIR) + $(MAKE) -C $(LIBDIR) clean +# $(MAKE) -C $(PRINTFD_DIR) clean + rm -rf $(OBJ_DIR) fclean: clean - $(MAKE) -C $(LIBDIR) fclean - rm -rf $(NAME) + $(MAKE) -C $(LIBDIR) fclean +# $(MAKE) -C $(PRINTFD_DIR) fclean + rm -f $(NAME) + +re: fclean all -re: fclean all \ No newline at end of file +-include $(DEP) diff --git a/README.md b/README.md index 3d50785..75b6560 100644 --- a/README.md +++ b/README.md @@ -1 +1,226 @@ -# minishell \ No newline at end of file +# minishell (42cursus) + +> **Passing the Gate.** Minishell is widely seen as the *main threshold* of 42: the first big systems project where you must design, test, and debug a real UNIX program under strict constraints (no leaks, precise signals, exact exit codes, brittle specs). Many students struggle not because it’s “hard C,” but because **small behavioral details** matter and are tested. +> Written in a group together with https://github.com/grignetta + +--- + +## TL;DR +- **Goal:** Re‑implement a tiny Bash‑like shell. +- **You must get right:** parsing, quoting, environment/expansion, redirections, pipelines, builtins, **signals** (Ctrl‑C/D/\), **heredocs**, and **exit codes**. +- **Why this project matters:** It forces you to build a clean architecture (lexer → parser → executor) and to develop production habits: test harnesses, robust error handling, and clean resource management. + +--- + +## Features (Mandatory Scope) +- Prompt loop using **readline** with history. +- **Lexer/Parser** producing a parse tree (or equivalent) that supports: + - Words, operators (`|`, `<`, `>`, `<<`, `>>`), and correct **precedence**. + - **Quotes**: single quotes = literal, double quotes = expand `$` & `$?`. +- **Expansion**: `$VAR`, `$?` (last exit status), rules with quotes. +- **Redirections**: `>`, `>>`, `<`, `<<` (heredoc with optional expansion). +- **Pipelines**: `cmd1 | cmd2 | ...` with correct FD wiring. +- **Builtins** implemented in‑process when appropriate: + - `echo` (with `-n`), `cd`, `pwd`, `export`, `unset`, `env`, `exit`. +- **Signals** & termios behavior matching Bash‐like expectations. +- **No memory leaks** over long interactive sessions; correct cleanup for all code paths + +--- + +## Architecture +``` +include/ # headers +src/ + main/ # entry, init, signals, errors + env/ # env storage & manipulation + lexer/ # tokenization + parser/ # grammar -> AST + expand/ # quotes & $ expansion + exec/ # executor, redirs, pipes + heredoc/ # heredoc management + builtins/ # builtins implementations + path/ # PATH resolution + free/ # cleanup helpers +printf_fd/ # libprintf_fd.a (ft_printf_fd & helpers) +libft/ # standard library with additional functions for this project (libft.a) +tools/suppress/ # sanitizer suppression files (readline, etc.) +``` + +- **Executor rule of thumb:** + - **Single builtin with redirs** → run **in parent** (so it can change shell state). + - **Pipelines / external commands** → run in **children**. + +--- + +## Build & Run +```sh +# clone +git clone https://github.com/michaela811/minishell.git minishell +cd minishell + +# build +make + +# run +./minishell +``` + +### Make targets +- `make` – build `minishell`, `libft.a`, and `libprintf_fd.a`. +- `make clean|fclean|re` – standard hygiene. + +--- + +## The Controls You Must Pass (Signals & TTY behavior) +Getting **Ctrl keys** right is a common failure point. The parent shell and its children must behave differently. + +### Ctrl‑C (SIGINT) +- **At prompt (no child running):** + - Effect: print a newline, **redisplay prompt**, don’t exit. + - **Exit status** becomes `130` for `$?`. + - Implementation: handle SIGINT in the parent (reset current line via readline hooks), do **not** terminate the shell. +- **While a child runs:** + - The **child** receives SIGINT with *default* disposition and terminates. + - The **parent** prints a newline and sets last status to **`130`** (128 + SIGINT). The shell itself stays alive and shows the next prompt. + +**What this means in practice** +- The terminal sends SIGINT to the **foreground process group** (your shell + its children). +- To avoid killing the shell, **parent** installs a custom handler (or temporarily ignores SIGINT) while it **waits** for the child. +- The **child** must have `SIGINT`/`SIGQUIT` restored to **default** before `execve()` so external programs behave normally. +- After `waitpid()`, if the child died from SIGINT, set `$? = 130` and print a newline to keep the prompt on a fresh line. + +**Pipelines** +- All children in the pipeline receive SIGINT. Wait for each PID and set `$?` to the **last command’s** status (commonly `130` if the pipeline was interrupted). + +--- + +### Testing + +#### Manual tests (quick checklist) +- **Ctrl‑C at prompt:** + 1. Run `./minishell`. + 2. Press **Ctrl‑C** once: you should see a newline + fresh prompt. + 3. Type `echo $?` → expect `130`. +- **Ctrl‑C while child runs:** + 1. Type `sleep 5` and press **Enter**. + 2. Press **Ctrl‑C** → the sleep ends immediately. + 3. Type `echo $?` → expect `130`. +- **Ctrl‑\ at prompt:** + 1. Press **Ctrl‑\** → nothing should print, prompt remains. + 2. `echo ok` → prints `ok`. `$?` unchanged. +- **Ctrl‑\ while child runs:** + 1. Run `cat` and press **Enter** (it waits on stdin). + 2. Press **Ctrl‑\** → you should see `Quit: 3` and return to prompt. + 3. `echo $?` → expect `131`. +- **Ctrl‑D at prompt (EOF):** + 1. From a fresh `./minishell`, press **Ctrl‑D** on an empty line. + 2. Shell prints `exit` and terminates. + 3. In your outer shell, run `echo $?` → expect previous minishell status (often `0`). + +#### Pipeline interruption +- Run: `sleep 5 | cat` → press **Ctrl‑C**. +- Expect all children to terminate and `$?` to reflect the **last command** (typically `130`). + +#### Heredoc specifics +- **Unquoted delimiter (expands):** + + ``` + cat <`, error on too many args, numeric parsing as Bash. + +--- + +## Redirections & Pipelines – Common Edge Cases +- Redirect errors (e.g., `cat < nofile`) must not create processes needlessly; print error and set correct status. +- Mix of redirs & pipelines: last command’s exit status propagates to `$?`. +- `cd` with redirs (e.g., `cd > file`) must still run in parent when possible; handle errors before state changes. + +--- + +## Expansion & Quotes – Quick Rules +- Single quotes `'...'` → literal. +- Double quotes `"..."` → expand `$VAR` and `$?`; keep spaces as literal characters. +- Unquoted words are subject to splitting by the parser **before** expansion is resolved into argv; design your lexer/parser so that quotes affect tokenization, not post‑processing hacks. + +--- + +## Memory Hygiene & Leak Suppressions (Valgrind / ASan) +`readline` and other libs often keep allocations until process exit, which show up as leaks unless you filter them. The goal here is to prove **your code** is leak‑free while ignoring 3rd‑party internals. + +### Valgrind (Linux) — recommended +**Typical command you can copy‑paste:** +```sh +valgrind \ + --suppressions=tools/suppress/suppress_lnx \ + --leak-check=full \ + --show-leak-kinds=all \ + --track-origins=yes \ + --trace-children=yes \ + --track-fds=yes \ + ./minishell +``` +**What each flag does:** +- `--suppressions=FILE` – ignore known leaks from libraries (e.g., readline). Put your rules in `tools/suppress/suppress_lnx`. +- `--leak-check=full` – show a full backtrace for each leak. +- `--show-leak-kinds=all` – report **definite / indirect / possible / reachable** (see below). +- `--track-origins=yes` – trace uninitialized values to their origin (slower but super useful). +- `--trace-children=yes` – follow fork/exec children. Good for minishell because you spawn processes (pipes, heredoc helpers). If you only want to check the parent shell, set this to `no`. +- `--track-fds=yes` – report file descriptors not closed at exit. + +**Understanding leak kinds:** +- **definitely lost** – real leaks. Fix these. +- **indirectly lost** – leaked via a leaked parent block. Usually fix. +- **possibly lost** – suspicious pointer arithmetic; investigate. +- **still reachable** – memory held until exit (often okay for libs like readline). + +> **Rule of thumb:** your grade depends on fixing **definite/indirect** leaks and FD leaks in your code paths (normal run, errors, heredoc abort). Suppress (or tolerate as *reachable*) what comes from libraries you don’t control. + +--- + +## Step‑by‑Step Plan to Pass +1. **REPL skeleton** with readline, history, and clean Ctrl‑C/D behavior at prompt. +2. **Lexer** producing tokens (words, ops). Handle quotes during tokenization. +3. **Parser** building an AST/commands list; validate grammar, produce friendly errors. +4. **Executor skeleton** (no pipes/redirs yet): spawn external cmd, run builtins in parent. +5. **PATH resolution** + clear error messages (126/127). +6. **Redirections** (>, >>, <) with FD lifecycle and error propagation. +7. **Pipelines**: connect FDs, collect last status. +8. **Expansion**: `$VAR`, `$?`, quoting rules. +9. **Builtins** complete & consistent (env table, export/unset behavior). +10. **Heredoc** with delimiter rules + SIGINT abort. +11. **Signals in children**: restore defaults; print correct messages. +12. **Cleanups**: sweeping frees on all early‑return/error paths. +13. **Test matrix**: scripts to cover signals, pipes, redirs, heredoc, big env, weird filenames. + +--- + +## Credits +Written by Michaela and https://github.com/grignetta. diff --git a/allocs_and_frees.h b/include/allocs_and_frees.h similarity index 100% rename from allocs_and_frees.h rename to include/allocs_and_frees.h diff --git a/builtins.h b/include/builtins.h similarity index 100% rename from builtins.h rename to include/builtins.h diff --git a/env.h b/include/env.h similarity index 100% rename from env.h rename to include/env.h diff --git a/exec.h b/include/exec.h similarity index 100% rename from exec.h rename to include/exec.h diff --git a/lexer_parser.h b/include/lexer_parser.h similarity index 100% rename from lexer_parser.h rename to include/lexer_parser.h diff --git a/minishell.h b/include/minishell.h similarity index 85% rename from minishell.h rename to include/minishell.h index 8c2a652..909568e 100644 --- a/minishell.h +++ b/include/minishell.h @@ -23,7 +23,8 @@ # include # include # include -# include "libft/libft.h" +# include "libft.h" +# include "ft_printf_fd.h" # include # include # include @@ -32,15 +33,15 @@ # include # include # include -# include -# include -# include -# include -# include -# include -# include -# include -# include +# include "structs.h" +# include "lexer_parser.h" +# include "allocs_and_frees.h" +# include "quotes.h" +# include "env.h" +# include "redirections.h" +# include "utils.h" +# include "exec.h" +# include "builtins.h" # include # include diff --git a/quotes.h b/include/quotes.h similarity index 100% rename from quotes.h rename to include/quotes.h diff --git a/redirections.h b/include/redirections.h similarity index 100% rename from redirections.h rename to include/redirections.h diff --git a/structs.h b/include/structs.h similarity index 100% rename from structs.h rename to include/structs.h diff --git a/utils.h b/include/utils.h similarity index 97% rename from utils.h rename to include/utils.h index 433a8b6..bae3e22 100644 --- a/utils.h +++ b/include/utils.h @@ -11,7 +11,7 @@ /* ************************************************************************** */ int is_directory(const char *path); -int ft_isspace(char c); +int ft_isspace_minishell(char c); int directory_check(char *arg_0); int is_string_numeric(const char *str); int overflow_check(char *result); diff --git a/exec_builtins.c b/src/builtins/exec_builtins.c similarity index 100% rename from exec_builtins.c rename to src/builtins/exec_builtins.c diff --git a/exec_builtins_cd.c b/src/builtins/exec_builtins_cd.c similarity index 100% rename from exec_builtins_cd.c rename to src/builtins/exec_builtins_cd.c diff --git a/exec_builtins_echo.c b/src/builtins/exec_builtins_echo.c similarity index 100% rename from exec_builtins_echo.c rename to src/builtins/exec_builtins_echo.c diff --git a/exec_builtins_env.c b/src/builtins/exec_builtins_env.c similarity index 100% rename from exec_builtins_env.c rename to src/builtins/exec_builtins_env.c diff --git a/exec_builtins_exit.c b/src/builtins/exec_builtins_exit.c similarity index 92% rename from exec_builtins_exit.c rename to src/builtins/exec_builtins_exit.c index 4312340..6df3f36 100644 --- a/exec_builtins_exit.c +++ b/src/builtins/exec_builtins_exit.c @@ -32,7 +32,7 @@ static int handle_exit(char *result, t_exec_vars *vars) int is_string_numeric(const char *str) { - while (ft_isspace((unsigned char)*str)) + while (ft_isspace_minishell((unsigned char)*str)) str++; if (*str == '+' || *str == '-') str++; @@ -44,14 +44,14 @@ int is_string_numeric(const char *str) } while (*str) { - if (!ft_isspace((unsigned char)*str)) + if (!ft_isspace_minishell((unsigned char)*str)) return (0); str++; } return (1); } -int ft_isspace(char c) +int ft_isspace_minishell(char c) { return (c == ' ' || c == '\f' @@ -66,7 +66,7 @@ int overflow_check(char *result) char *end; char *num; - while (isspace((unsigned char)*result)) + while (ft_isspace_minishell((unsigned char)*result)) result++; end = result; if (*result == '+' || *result == '-') @@ -77,7 +77,7 @@ int overflow_check(char *result) end++; while (*end != '\0') { - if (!isspace((unsigned char)*end)) + if (!ft_isspace_minishell((unsigned char)*end)) return (0); end++; } diff --git a/exec_builtins_export.c b/src/builtins/exec_builtins_export.c similarity index 100% rename from exec_builtins_export.c rename to src/builtins/exec_builtins_export.c diff --git a/exec_builtins_export_utils.c b/src/builtins/exec_builtins_export_utils.c similarity index 100% rename from exec_builtins_export_utils.c rename to src/builtins/exec_builtins_export_utils.c diff --git a/exec_builtins_pwd.c b/src/builtins/exec_builtins_pwd.c similarity index 100% rename from exec_builtins_pwd.c rename to src/builtins/exec_builtins_pwd.c diff --git a/exec_builtins_unset.c b/src/builtins/exec_builtins_unset.c similarity index 100% rename from exec_builtins_unset.c rename to src/builtins/exec_builtins_unset.c diff --git a/env_handling.c b/src/env/env_handling.c similarity index 100% rename from env_handling.c rename to src/env/env_handling.c diff --git a/env_main.c b/src/env/env_main.c similarity index 100% rename from env_main.c rename to src/env/env_main.c diff --git a/env_utils.c b/src/env/env_utils.c similarity index 100% rename from env_utils.c rename to src/env/env_utils.c diff --git a/execute_node.c b/src/exec/execute_node.c similarity index 100% rename from execute_node.c rename to src/exec/execute_node.c diff --git a/execute_node_error_messages.c b/src/exec/execute_node_error_messages.c similarity index 100% rename from execute_node_error_messages.c rename to src/exec/execute_node_error_messages.c diff --git a/execute_node_exec_cmd.c b/src/exec/execute_node_exec_cmd.c similarity index 100% rename from execute_node_exec_cmd.c rename to src/exec/execute_node_exec_cmd.c diff --git a/execute_node_handle_child_cmd.c b/src/exec/execute_node_handle_child_cmd.c similarity index 100% rename from execute_node_handle_child_cmd.c rename to src/exec/execute_node_handle_child_cmd.c diff --git a/execute_node_handle_heredoc.c b/src/exec/execute_node_handle_heredoc.c similarity index 100% rename from execute_node_handle_heredoc.c rename to src/exec/execute_node_handle_heredoc.c diff --git a/execute_node_handle_heredoc_utils.c b/src/exec/execute_node_handle_heredoc_utils.c similarity index 100% rename from execute_node_handle_heredoc_utils.c rename to src/exec/execute_node_handle_heredoc_utils.c diff --git a/execute_node_handle_redirect.c b/src/exec/execute_node_handle_redirect.c similarity index 100% rename from execute_node_handle_redirect.c rename to src/exec/execute_node_handle_redirect.c diff --git a/execute_node_handle_redirect_error.c b/src/exec/execute_node_handle_redirect_error.c similarity index 100% rename from execute_node_handle_redirect_error.c rename to src/exec/execute_node_handle_redirect_error.c diff --git a/execute_node_handle_redirect_utils.c b/src/exec/execute_node_handle_redirect_utils.c similarity index 100% rename from execute_node_handle_redirect_utils.c rename to src/exec/execute_node_handle_redirect_utils.c diff --git a/execute_node_utils.c b/src/exec/execute_node_utils.c similarity index 100% rename from execute_node_utils.c rename to src/exec/execute_node_utils.c diff --git a/execute_parse_tree.c b/src/exec/execute_parse_tree.c similarity index 100% rename from execute_parse_tree.c rename to src/exec/execute_parse_tree.c diff --git a/execute_pipeline_utils.c b/src/exec/execute_pipeline_utils.c similarity index 100% rename from execute_pipeline_utils.c rename to src/exec/execute_pipeline_utils.c diff --git a/execute_pipeline_utils_1.c b/src/exec/execute_pipeline_utils_1.c similarity index 100% rename from execute_pipeline_utils_1.c rename to src/exec/execute_pipeline_utils_1.c diff --git a/handle_dollar_sign.c b/src/expand/handle_dollar_sign.c similarity index 100% rename from handle_dollar_sign.c rename to src/expand/handle_dollar_sign.c diff --git a/handle_dollar_sign_utils.c b/src/expand/handle_dollar_sign_utils.c similarity index 100% rename from handle_dollar_sign_utils.c rename to src/expand/handle_dollar_sign_utils.c diff --git a/handle_quotes_main_1.c b/src/expand/handle_quotes_main_1.c similarity index 100% rename from handle_quotes_main_1.c rename to src/expand/handle_quotes_main_1.c diff --git a/handle_quotes_main_2.c b/src/expand/handle_quotes_main_2.c similarity index 100% rename from handle_quotes_main_2.c rename to src/expand/handle_quotes_main_2.c diff --git a/handle_quotes_redirect.c b/src/expand/handle_quotes_redirect.c similarity index 100% rename from handle_quotes_redirect.c rename to src/expand/handle_quotes_redirect.c diff --git a/handle_quotes_utils_1.c b/src/expand/handle_quotes_utils_1.c similarity index 100% rename from handle_quotes_utils_1.c rename to src/expand/handle_quotes_utils_1.c diff --git a/handle_quotes_utils_2.c b/src/expand/handle_quotes_utils_2.c similarity index 100% rename from handle_quotes_utils_2.c rename to src/expand/handle_quotes_utils_2.c diff --git a/free_functions.c b/src/free/free_functions.c similarity index 100% rename from free_functions.c rename to src/free/free_functions.c diff --git a/free_functions_1.c b/src/free/free_functions_1.c similarity index 100% rename from free_functions_1.c rename to src/free/free_functions_1.c diff --git a/pipeline_here_doc_dol_closed.c b/src/heredoc/pipeline_here_doc_dol_closed.c similarity index 100% rename from pipeline_here_doc_dol_closed.c rename to src/heredoc/pipeline_here_doc_dol_closed.c diff --git a/pipeline_here_doc_dol_open.c b/src/heredoc/pipeline_here_doc_dol_open.c similarity index 100% rename from pipeline_here_doc_dol_open.c rename to src/heredoc/pipeline_here_doc_dol_open.c diff --git a/pipeline_here_doc_main.c b/src/heredoc/pipeline_here_doc_main.c similarity index 100% rename from pipeline_here_doc_main.c rename to src/heredoc/pipeline_here_doc_main.c diff --git a/lexer.c b/src/lexer/lexer.c similarity index 100% rename from lexer.c rename to src/lexer/lexer.c diff --git a/lexer_main.c b/src/lexer/lexer_main.c similarity index 100% rename from lexer_main.c rename to src/lexer/lexer_main.c diff --git a/error_handling.c b/src/main/error_handling.c similarity index 100% rename from error_handling.c rename to src/main/error_handling.c diff --git a/init_1.c b/src/main/init_1.c similarity index 100% rename from init_1.c rename to src/main/init_1.c diff --git a/init_2.c b/src/main/init_2.c similarity index 100% rename from init_2.c rename to src/main/init_2.c diff --git a/main.c b/src/main/main.c similarity index 100% rename from main.c rename to src/main/main.c diff --git a/main_handle_input.c b/src/main/main_handle_input.c similarity index 100% rename from main_handle_input.c rename to src/main/main_handle_input.c diff --git a/signals.c b/src/main/signals.c similarity index 100% rename from signals.c rename to src/main/signals.c diff --git a/parser_is_all_rest.c b/src/parser/parser_is_all_rest.c similarity index 100% rename from parser_is_all_rest.c rename to src/parser/parser_is_all_rest.c diff --git a/parser_is_cmd_suffix.c b/src/parser/parser_is_cmd_suffix.c similarity index 100% rename from parser_is_cmd_suffix.c rename to src/parser/parser_is_cmd_suffix.c diff --git a/parser_main.c b/src/parser/parser_main.c similarity index 100% rename from parser_main.c rename to src/parser/parser_main.c diff --git a/parser_utils.c b/src/parser/parser_utils.c similarity index 100% rename from parser_utils.c rename to src/parser/parser_utils.c diff --git a/get_path_for_exec.c b/src/path/get_path_for_exec.c similarity index 100% rename from get_path_for_exec.c rename to src/path/get_path_for_exec.c diff --git a/get_path_for_exec_colon.c b/src/path/get_path_for_exec_colon.c similarity index 100% rename from get_path_for_exec_colon.c rename to src/path/get_path_for_exec_colon.c diff --git a/get_path_for_exec_utils.c b/src/path/get_path_for_exec_utils.c similarity index 100% rename from get_path_for_exec_utils.c rename to src/path/get_path_for_exec_utils.c diff --git a/test_files/empty b/tests/test_files/empty similarity index 100% rename from test_files/empty rename to tests/test_files/empty diff --git a/test_files/file name with spaces b/tests/test_files/file name with spaces similarity index 100% rename from test_files/file name with spaces rename to tests/test_files/file name with spaces diff --git a/test_files/infile b/tests/test_files/infile similarity index 100% rename from test_files/infile rename to tests/test_files/infile diff --git a/test_files/infile_big b/tests/test_files/infile_big similarity index 100% rename from test_files/infile_big rename to tests/test_files/infile_big diff --git a/test_files/invalid_permission b/tests/test_files/invalid_permission similarity index 100% rename from test_files/invalid_permission rename to tests/test_files/invalid_permission diff --git a/test_files/loop b/tests/test_files/loop similarity index 100% rename from test_files/loop rename to tests/test_files/loop diff --git a/test_files/loop.c b/tests/test_files/loop.c similarity index 100% rename from test_files/loop.c rename to tests/test_files/loop.c diff --git a/m_suppress b/tools/suppress/m_suppress similarity index 100% rename from m_suppress rename to tools/suppress/m_suppress diff --git a/suppress b/tools/suppress/suppress similarity index 100% rename from suppress rename to tools/suppress/suppress diff --git a/suppress_lnx b/tools/suppress/suppress_lnx similarity index 100% rename from suppress_lnx rename to tools/suppress/suppress_lnx diff --git a/suppress_mac b/tools/suppress/suppress_mac similarity index 100% rename from suppress_mac rename to tools/suppress/suppress_mac diff --git "a/\250v\242S\006" "b/\250v\242S\006" deleted file mode 100644 index e69de29..0000000 diff --git "a/\271P\315\203\005" "b/\271P\315\203\005" deleted file mode 100644 index e69de29..0000000