# Repository Guidelines ## Project Structure & Module Organization - `src/` holds the shell implementation, with submodules for `builtins/`, `executor/`, `parser/`, and `variables/`. - `src/builtins/` currently includes: `cd`, `echo`, `env`, `exit`, `export`, `pwd`, `unset`. - `src/executor/` includes pipeline/process orchestration plus file redirections in `redirections.c`. - `include/` contains public headers used across modules. - `lib/` is populated at build time with third-party 42 libraries (libft, get_next_line, ft_printf, ft_args). - `docs/` stores project references and manual test notes (see `docs/tests.md`). - `build/` is the object output directory generated by `make`. ## Build, Test, and Development Commands - `make` or `make all`: build `minishell` (auto-clones required libs into `lib/`). - `make clean`: remove objects in `build/`. - `make fclean`: remove objects and the `minishell` binary (also cleans libs). - `make re`: full rebuild. - `./minishell`: run locally after a build. - `make DEBUG=lldb` or `make DEBUG=valgrind` or `make DEBUG=address`: rebuild with debug/ASan-friendly flags. ## Coding Style & Naming Conventions - The codebase follows 42 **Norminette v4** rules. Run `norminette *.c *.h` (or on specific files) before submitting changes. - Keep file names lowercase with underscores (e.g., `src/builtins/echo/echo.c`). - Keep headers in `include/` and expose only what modules need. - Before adding or changing code, check `allowed.txt` to know which functions are permitted. - Any function not listed in `allowed.txt` is not allowed in this project. ## Parser & Lexer Functionality (Current `src/parser`) - Runtime entrypoint is `parse(line, minishell)` from `src/minishell.c` (`readline -> parse -> execute`). - `parse` calls `lex(line)` and then converts token lists to `t_command` nodes with `parse_tokens`. - `command_new` builds one command from tokens up to `TOKEN_PIPE`. - `words_add` stores consecutive `TOKEN_WORD` tokens in `command->argv` and increments `argc`. - `expand_envs` is currently a TODO (no `$VAR` expansion is applied in parser stage). - Redirection tokens are converted into `t_redirection` and stored in `t_command.redirections`; heredocs are stored in `t_command.heredocs`. - Path resolution is handled in executor (`executor_resolve_command_path`) before `execve`. - `src/parser/lexer.c` provides a separate lexer (`lex`) that tokenizes into `TOKEN_WORD`, `TOKEN_PIPE`, `TOKEN_REDIRECT_IN`, `TOKEN_REDIRECT_OUT`, `TOKEN_APPEND`, and `TOKEN_HEREDOC`. - The lexer tracks single/double quote context so metacharacters inside quotes remain part of words. - Meta runs are read as contiguous chunks in `read_token` (for example, repeated `|`/`<`/`>` are captured as one token value). - Current parser flow consumes lexer output directly. ## Executor Redirections (Current `src/executor`) - File redirections are applied in `src/executor/redirections.c` via `open` + `dup2` before command execution. - Supported file redirections: input `<`, output truncate `>`, output append `>>`. - Redirections are applied for both forked commands (child path) and single builtins executed in parent. - Parent-builtin redirections save/restore `STDIN_FILENO` and `STDOUT_FILENO` after builtin execution. ## Parser & Lexer Known Gaps - Heredoc tokens are parsed and stored, but runtime heredoc execution/input feeding is still pending in executor. - No explicit unmatched-quote syntax error handling is implemented in parser/lexer path. ## Testing Guidelines - There is no automated test runner. Use manual checks in `docs/tests.md` and basic shell behavior checks (pipes, redirects, builtins). - A local builtin edge-case script exists at `tests/builtins_edge_cases.sh` (expects a compiled `./minishell`). - When debugging memory issues, run under valgrind and use the suppression file in `valgrind/readline.supp`. ## Builtins Status - `cd`: handles `HOME` fallback, `cd -` via `OLDPWD`, updates `PWD`/`OLDPWD`, and returns failure on invalid usage (`too many arguments`, missing `HOME`/`OLDPWD`). - `echo`: supports repeated `-n` flags (`-n`, `-nnn`) and prints remaining args preserving spaces between tokens. - `env`: prints current environment as `KEY=VALUE`; returns failure when called with extra arguments. - `exit`: validates numeric argument (with overflow checks), returns `1` on `too many arguments` without exiting, and exits with `2` on non-numeric argument. - `export`: supports `NAME=VALUE` and `NAME` (stored as empty value), validates identifiers, and returns failure when any identifier is invalid. - `pwd`: prints working directory using dynamic `getcwd` and returns failure if `getcwd` fails. - `unset`: validates identifiers and removes matching variables from the environment map. ## Commit & Pull Request Guidelines - Commit messages in this repo use a simple `type: summary` format (examples: `update: ...`, `fix: ...`). Keep summaries short and specific. - For PRs, include: 1. What changed and why. 2. How to test (commands or manual steps). 3. Notes on any parser/executor/builtin behavior changes. ## Configuration Tips - The project depends on `readline`; ensure your system has `libreadline-dev` or equivalent before building.