- Entry point is
main()inmain.cpp, which simply constructs anInterfaceobject. The constructor (Interface.cpp) setsparser/commandtonullptrand immediately callsInterface::run(), so control never returns tomain().
- A prompt character (
PSIGN, default$) is stored locally and reused until changed by thepromptcommand. - Each cycle allocates a
PromptCommand(Command.cpp), callsexecute()to print"$ ", deletes the command, then creates a freshParser. - The parser construction (
Parser.cpp) executesstd::cin >> stream, which invokesStream::operator>>to parse one full line, including pipelines. - The parsed data and prompt reference are passed to
PipelineExecutor::run()(PipelineExecutor.cpp). When execution returns, the parser is freed and the loop restarts.
Stream::operator>>(Stream.cpp) reads an entire line, enforcingMAX_SIZE(512 chars) and emitting error code 10 (empty) or 11 (too long) before aborting.Stream::splitdivides the line on|, trimming whitespace to produce pipeline stages.- For each stage
parseRedirectionsextracts trailing< file,> file, or>> filetokens (whitespace optional) and stores them; the remaining text is passed to anInputStream. InputStream::parsewalks tokens, honouring quoted segments. Options (-x) are detected automatically; up to three arguments are captured andexplicitArgumentis flagged when the first argument token is present.- When a pipeline segment contains only whitespace, it is discarded.
- Commands that can consume file/stdin input (
echo,wc,head,batch) defer argument filling until after parsing:- If
< filewas specified and no explicit argument was provided, the file contents are read into the first argument (wrapped in quotes). - If no argument and no
< file, the first pipeline segment can request multi-line input untilEOF/blank line, again quoted.
- If
.txtarguments forecho,wc,head,batch, andtrare detected byisTxtFileCandidateand replaced with aFileStream, which loads file contents and quotes them.trhandles partial inputs: if only the replacement tokens are supplied, the command prompts for text via input redirection or interactive capture (first pipeline segment only).
PipelineExecutorloops over the parsed nodes usingParser::processAll()(which advances throughStreamonce).- Redirection validation occurs before command creation: mixing
<with explicit arguments forecho/wc/head/batchtriggersCommandFactory::handleCommand(SYNTAX_ERROR, ...). CommandFactory::createCommandvalidates options/arguments and returns a concreteCommandornullptron error. Thepromptcommand updates the prompt character and returnsnullptrintentionally.- Output handling:
- If the current segment pipes to the next and no
>is present,std::coutis temporarily redirected to anstd::ostringstreamto capture output. - With
>/>>,std::coutis redirected to a file stream (opened append or truncate). After execution the stream is closed — and if the target ends with.txt, its contents are echoed back to the console.
- If the current segment pipes to the next and no
- Captured pipeline output is quoted and injected into the next
InputStream:trpreserves its optional second/third arguments when rewiring.echo,wc,head, andbatchconsume the quoted text as their primary argument.
- PromptCommand: prints current prompt.
- EchoCommand: requires a quoted argument (or a
.txtfilename that the parser replaces with quoted contents); prints the unwrapped text. Unquoted tokens are rejected by validation. - TimeCommand/DateCommand: print current time (
std::put_time) and compilation date (__DATE__). - ClearCommand: calls
system("cls"). - ExitCommand:
exit(0). - TouchCommand: creates a new
.txtfile (argument must not be quoted and must end with.txt); throws error code 7 if it already exists or 8 if creation fails. - WcCommand: counts words (
-w) or characters (-c, default if omitted). Only-wor-care accepted; surrounding quotes are stripped before counting. - HelpCommand: prints usage help.
- TruncateCommand: truncates an existing
.txtfile viastd::ofstream(..., std::ios::trunc); the file must already exist. - RmCommand: deletes an existing
.txtfile withstd::remove, reporting success or failure. - TrCommand: replaces all occurrences of quoted
whatwith quotedwithinside quotedinput. - HeadCommand: outputs the first
nlines of quoted input; option must be-nfollowed by up to 5 digits (e.g.,-n10). - BatchCommand: splits quoted script text into individual lines, re-parses each line into a
Stream, and executes them with the same validation/pipeline rules (including nested pipelines and redirections).
- Every command has a dedicated
validate*routine enforcing option syntax, argument quoting rules, and file checks (validateFileForOpen). - Errors are reported via
handleCommand, which prints the offending command line fragment, underlines the issue with~, and appends a contextual error message (Error code 1–4). createCommandfalls back toUNKNOWN_COMMANDwhen no handler matches.
- 1 — Invalid argument (validation failure)
- 2 — Invalid option (validation failure)
- 3 — Syntax error (e.g., mixing
<with explicit args for input-defining commands) - 4 — Unknown command (no factory handler)
- 5 — Could not open file: (input redirection / file argument open failure in parser)
- 6 — Error reading from file … (read failure in
FileStream) - 7 — File already exists (from
TouchCommand) - 8 — Could not create/open file (from
TouchCommandcreation or output redirection open failure) - 10 — Empty input line (from
Stream::operator>>) - 11 — Input exceeds MAX_SIZE (from
Stream::operator>>)
Notes:
rmfailure prints a textual message (Error deleting file: …) rather than a numeric code.- In interactive mode, writing to a
.txtvia>/>>echoes the file contents back to stdout; insidebatch, this echo happens only for appends (>>).
- Pipeline splitting is literal on
|and is not quote-aware; a|inside quotes will still split the pipeline. - Redirections are only parsed at the end of a segment; only the last occurrence of a given redirection applies. Stderr redirection is not supported.
- Interactive stdin capture (for
echo,wc,head,batch, and partialtr) occurs only for the first pipeline segment and stops on a blank line or a line equal toEOF. - Piping forwards captured stdout as a single quoted argument to the next command. Only
tr,echo,wc,head, andbatchconsume this injected argument. - Character counting in
wc -cincludes newline characters present in the input. - File-related commands enforce
.txtextensions;truncate/rmalso require the file to exist.
BatchCommand::execute(Command.cpp) iterates lines from its quoted script.- Each line is parsed with a fresh
Streamand executed sequentially, using the same pipeline capture and redirection logic as the interactive path. - Output redirection inside batch commands respects append/truncate modes and echoes appended
.txtfiles back to the console.
- Validation accepts a single character, either bare or quoted (
"$"). Multi-character inputs triggerINVALID_ARGUMENT. - On success the prompt stored in
Interface::runis updated for subsequent iterations; no command object is executed.
main()constructsInterface;Interface::runenters the REPL loop.- Prompt displayed via
PromptCommand. Parserreads input,Streamsplits pipelines, tokenises, and resolves redirections/file injections.PipelineExecutorvalidates each stage, instantiates commands, manages redirection/piping, and executes them.- Outputs and errors surface immediately; prompt reappears until
exitis invoked.
This walkthrough covers every .cpp/.h participant so the CLI can be presented.