Skip to content

Commit c5d6184

Browse files
committed
Update README.md file
1 parent 6c8a4fa commit c5d6184

File tree

1 file changed

+105
-101
lines changed

1 file changed

+105
-101
lines changed

README.md

Lines changed: 105 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,148 +1,152 @@
1-
[![progress-banner](https://backend.codecrafters.io/progress/shell/b4bb982c-8154-4a14-a2e1-7cfef9a34391)](https://app.codecrafters.io/users/MohaIfk?r=2qF)
2-
3-
# codecrafters-shell-cpp
4-
5-
An enhanced C++ implementation of the "Build Your Own Shell" challenge from
6-
CodeCrafters. This repository contains a small interactive shell (REPL) that
7-
supports builtin commands, executing external programs, basic redirections, and
8-
cross-platform process launching on both POSIX and Windows.
9-
10-
This README documents how to build and run the project, shows usage examples
11-
and explains a number of extensions implemented beyond the minimal starter
12-
requirements.
1+
# codecrafters-shell-cpp — C++ interactive shell
132

14-
## Highlights / Features
3+
[![progress-banner](https://backend.codecrafters.io/progress/shell/b4bb982c-8154-4a14-a2e1-7cfef9a34391)](https://app.codecrafters.io/users/MohaIfk?r=2qF)
154

16-
- Cross-platform: builds and runs on POSIX (Linux/WSL/macOS) and Windows.
17-
- Builtin commands: `echo`, `cd` (supports `~`), `pwd`, `type`, `exit`.
18-
- External program execution (resolves PATH entries).
19-
- Redirections: supports `>`, `>>` and numeric fds like `2>err.txt`.
20-
- Robust argument parsing: single/double quotes, backslash escapes inside and
21-
outside quotes, and error on unclosed quotes.
22-
- Windows-specific support: `.exe/.bat/.cmd` resolution, CreateProcessW based
23-
spawning, and careful argument quoting and UTF-8 -> UTF-16 conversion.
24-
- Scoped redirections for builtins (so builtins honor redirected stdout/stderr).
25-
- `cd` resolves and canonicalizes the target directory and supports `~`.
5+
This repository contains an enhanced C++ implementation of a small interactive
6+
shell (REPL). It started from the CodeCrafters "Build Your Own Shell"
7+
challenge and was extended with command history, tab completion, pipelines,
8+
redirections, cross-platform process spawning and several developer-friendly
9+
helpers.
2610

27-
The implementation files of note are in `src/`:
2811

29-
- `src/main.cpp` — program entrypoint and minimal runner.
30-
- `src/shell.h`, `src/shell.cpp` — shell class, parsing, dispatching, PATH
31-
resolution and builtin implementations.
32-
- `src/utils.h` — process launching (POSIX fork/exec and Windows CreateProcess),
33-
argument parser, home directory lookup, redirection helpers, etc.
12+
## Key features (current)
3413

35-
## What I implemented beyond the starter (quick summary)
14+
- Cross-platform process spawning: POSIX `fork`+`execv` and Windows
15+
`CreateProcessW` implementations.
16+
- Pipeline support (`|`), including proper pipe wiring on POSIX and Windows.
17+
- Redirections: `>`, `>>` and numeric fd redirections (e.g. `2>err.txt`).
18+
- Builtin commands: `echo`, `cd` (supports `~`), `pwd`, `type`, `exit`,
19+
`history` (with `-c`, `-d`, `-r`, `-w`, `-a` subcommands).
20+
- Command history: in-memory list plus optional file persistence controlled by
21+
the `HISTFILE` environment variable.
22+
- Tab completion for commands (uses a cached set of executables + builtins).
23+
- Robust argument parsing including single/double quotes and backslash
24+
escapes; throws on unclosed quotes.
25+
- Terminal raw-mode input and arrow-key navigation for history (POSIX via
26+
`termios`, Windows via `_getch`).
27+
- Scoped redirections for builtins so builtins honor redirection during their
28+
execution.
3629

37-
If you or someone on your team extended the starter, the most notable additions
38-
in this codebase are:
30+
## Project layout (important files)
3931

40-
- Full cross-platform process launching: CreateProcessW for Windows with
41-
careful quoting and UTF-8 to UTF-16 conversion. POSIX uses `fork` + `execv`.
42-
- Argument parser that closely mirrors shell-like quoting behavior (single
43-
quotes, double quotes with limited escaping, and backslash escapes).
44-
- Redirection parsing and handling that supports numeric fds and append
45-
(`>>`) and a `ScopedRedir` helper that temporarily redirects file
46-
descriptors for builtin commands.
47-
- PATH-resolution that tries platform-appropriate executable extensions on
48-
Windows (.exe, .bat, .cmd) and checks executable bit on POSIX.
49-
- Improved `cd` handling: supports `~` and canonicalizes the working
50-
directory (resolving symlinks where possible).
32+
- `src/main.cpp` — program entrypoint.
33+
- `src/shell.h`, `src/shell.cpp` — main shell class, parsing, dispatching,
34+
builtins, pipeline execution, completion and history.
35+
- `src/utils.h` — helpers: `getenv_safe`, `get_home_directory`, `run_program_and_wait`,
36+
`parse_args`, and `ScopedRedir`.
37+
- `src/inputHelper.h` — small cross-platform helper for raw-mode input and
38+
`get_char_raw()` abstraction used by the REPL.
39+
- `CMakeLists.txt` — build configuration.
5140

52-
These features make the shell more robust and suitable for manual testing on
53-
both Windows and POSIX environments.
41+
## Quick developer contract
5442

55-
## Requirements
43+
- Input: user-entered command lines (strings) via a REPL prompt.
44+
- Output: stdout/stderr of builtins and spawned processes; exit status comes
45+
from executed programs (pipelines are executed and waited upon).
46+
- Error modes: parsing errors (e.g. unclosed quotes) raise runtime errors
47+
printed to stderr; spawn errors return messages to stderr.
5648

57-
- C++17 compatible compiler (MSVC, g++, clang++)
58-
- CMake (3.10+ recommended)
59-
- On Windows: Visual Studio or Build Tools (so CMake can generate a Visual
60-
Studio solution or Ninja files). On Linux/WSL: make/ninja + standard build
61-
toolchain.
49+
Edge cases considered: empty lines, unclosed quotes, missing redirection
50+
targets, trying to run non-executable files, and PATH entries with permission
51+
errors (these are skipped during executable cache population).
6252

63-
## Build and run
53+
## Build (Windows and POSIX)
6454

65-
The repository contains a CMake-based build. Example commands below assume you
66-
run them from the repository root.
55+
Requirements: C++20 compiler, CMake (3.10+ recommended).
6756

68-
Windows (recommended via Developer Command Prompt or PowerShell):
57+
Windows (Developer Command Prompt / PowerShell):
6958

7059
```powershell
7160
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
7261
cmake --build build --config Release
73-
# Executable will usually be at build\Release\shell.exe (or the configured target dir)
74-
.
62+
# Executable typically: build\Release\shell.exe
7563
```
7664

7765
WSL / Linux / macOS:
7866

7967
```bash
8068
cmake -S . -B cmake-build-debug-wsl -DCMAKE_BUILD_TYPE=Release
8169
cmake --build cmake-build-debug-wsl -- -j$(nproc)
82-
# Executable will be at cmake-build-debug-wsl/shell
70+
# Executable typically: cmake-build-debug-wsl/shell
8371
```
8472

85-
You can also use the provided `your_program.sh` wrapper if present and
86-
appropriate for your environment (it simply runs the built executable).
73+
There is a helper script `your_program.sh` that can be adapted to run the
74+
built binary in your environment.
8775

88-
## Usage examples
76+
## Runtime usage (examples)
8977

90-
Run the shell (example path depends on your build):
78+
Start the shell and try commands:
9179

9280
```bash
9381
./cmake-build-debug-wsl/shell
9482
# or on Windows
9583
build\Release\shell.exe
9684
```
9785

98-
Once inside the prompt, try examples:
99-
100-
- Builtins:
101-
102-
- echo: `echo hello world`
103-
- pwd: `pwd`
104-
- cd: `cd /tmp` or `cd ~`
105-
- type: `type ls` or `type echo`
106-
- exit: `exit` or `exit 2`
107-
108-
- External commands:
109-
110-
- `ls -la` (POSIX)
111-
- `dir` (Windows cmd builtin via external program resolution if available)
112-
113-
- Redirection examples:
114-
115-
- `echo hi > out.txt` (overwrite)
116-
- `echo again >> out.txt` (append)
117-
- `ls 2> err.txt` (redirect stderr to file)
118-
- `myprog 1>out.txt 2>>err.txt` (mix stdout overwrite + stderr append)
86+
Examples inside the prompt:
87+
88+
- Simple builtins:
89+
- echo: `echo hello world`
90+
- pwd: `pwd`
91+
- cd: `cd /tmp` or `cd ~`
92+
- type: `type ls` or `type echo`
93+
- exit: `exit` or `exit 2`
94+
95+
- History:
96+
- up/down arrows to navigate previous commands (raw-mode input)
97+
- `HISTFILE` env var controls persisted history file path; history is read
98+
at startup and appended on exit (if configured).
99+
- `history` builtin examples: `history`, `history 10`, `history -c`,
100+
`history -d 5`, `history -w historyfile`, `history -r historyfile`,
101+
`history -a historyfile`.
102+
103+
- External programs and completion:
104+
- tab completion for commands (builtins + cached executables from `PATH`).
105+
- `type <name>` reports whether a name is a builtin or prints the resolved
106+
path to an executable.
107+
108+
- Pipelines and redirections:
109+
- `ls -la | grep txt | wc -l`
110+
- `echo hi > out.txt`
111+
- `echo again >> out.txt`
112+
- `ls 2> err.txt`
113+
- `myprog 1>out.txt 2>>err.txt`
119114

120115
Notes:
121116

122117
- Numeric fd redirections are supported (e.g. `2>file` targets stderr).
123118
- Builtins use `ScopedRedir` so redirection affects builtin output as expected.
124119

125-
## Manual tests to verify functionality
120+
## Developer notes — where to look
121+
122+
- Argument parsing: `parse_args` in `src/utils.h`.
123+
- Line parsing into pipeline + redirections: `parse_line_to_pipeline` in
124+
`src/shell.cpp`.
125+
- Pipeline execution: `execute_pipeline` in `src/shell.cpp` (separate
126+
implementations for POSIX and Windows).
127+
- Single-command execution: `execute_simple_command` and `run_program_and_wait`
128+
(`src/utils.h`).
129+
- History and completion: `populate_executable_cache`, `read_history`,
130+
`write_history`, `handle_completion` in `src/shell.cpp`.
131+
- Terminal input: `enableRawMode`, `disableRawMode`, and `get_char_raw` in
132+
`src/inputHelper.h`.
133+
134+
## Limitations and next improvements
126135

127-
1. Build the project (see Build instructions).
128-
2. Start the shell executable.
129-
3. Verify builtins: run `echo`, `pwd`, `cd`, `type`, `exit`.
130-
4. Verify external programs: run `which`/`type` or `ls`/`dir` depending on
131-
platform (or run a small program you compiled and put on PATH).
132-
5. Verify redirections: `echo hello > /tmp/test.txt`, then `cat /tmp/test.txt`.
133-
6. On Windows, test an `.exe` in PATH and a `.bat` script; `type` should show
134-
resolved paths.
136+
- No job control (background `&`, `fg`, `bg`) yet.
137+
- Environment variable and tilde expansion is limited (tilde `~` support in
138+
`cd` only). No `$VAR` expansion or globbing implemented.
139+
- Quoting and escaping aims to be shell-like but is not a full POSIX shell
140+
parser; edge cases may differ from bash/zsh.
135141

136-
## Where to look in the code
142+
Planned/possible next steps (I can implement any of these on request):
137143

138-
- `parse_args` in `src/utils.h` — argument parsing.
139-
- `parse_command_with_redirect` in `src/shell.cpp` — builds `Command` with
140-
argument vector and redirections parsed.
141-
- `run_program_and_wait` in `src/utils.h` — platform-specific spawning.
142-
- `ScopedRedir` in `src/utils.h` — temporarily redirects fds for builtins.
144+
- Add `$VAR` expansion and filename globbing.
145+
- Implement job control and background/foreground management.
146+
- Add unit tests for `parse_args`, `parse_line_to_pipeline` and
147+
`execute_pipeline` behavior.
143148

144149
## License & attribution
145150

146-
This solution is based on the CodeCrafters Shell challenge. Follow the
147-
original challenge terms where applicable when publishing or sharing your
148-
solution.
151+
This project was started from the CodeCrafters Shell challenge. Respect the
152+
original challenge terms when sharing or publishing derived work.

0 commit comments

Comments
 (0)