-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCommandProcessor.cpp
106 lines (101 loc) · 3.17 KB
/
CommandProcessor.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include <iostream>
#include "CommandProcessor.h"
#include "Flags.h"
#include "Tokenizer.h"
namespace shell
{
CommandProcessor::CommandProcessor(fs::FileSystemManager* fsm) : m_workingDir{ fsm->getMainEnv()->getRoot() },
m_root{ fsm->getMainEnv()->getRoot() }, m_fileSystemManager{ fsm }
{
m_commands["exit"] = CommandExit::factory;
m_commands["logout"] = CommandLogout::factory;
m_commands["ls"] = CommandLs::factory;
m_commands["cd"] = CommandCd::factory;
m_commands["clear"] = CommandClear::factory;
m_commands["mkdir"] = CommandMkdir::factory;
m_commands["rmdir"] = CommandRmdir::factory;
m_commands["touch"] = CommandTouch::factory;
m_commands["echo"] = CommandEcho::factory;
m_commands["cat"] = CommandCat::factory;
m_commands["rm"] = CommandRm::factory;
m_commands["help"] = CommandHelp::factory;
}
fs::AppState CommandProcessor::run()
{
std::cout << "\x1B[2J\x1B[H";
std::string terminalLine;
Tokenizer tokenizer;
auto state = ShellFlag::run;
while (state != ShellFlag::exit and state != ShellFlag::logout)
{
tokenizer.clear();
if (m_root != m_workingDir)
{
std::cout << "/" << m_root->getName()
<< (m_workingDir->getParentPath().empty() ? "" : "/");
}
std::cout << m_workingDir->getParentPath() << "/" << m_workingDir->getName() << " >";
std::getline(std::cin, terminalLine);
terminalLine.append(" ");
if (!tokenizer.process(terminalLine))
{
std::cout << "Invalid syntax\n\n";
continue;
}
auto cmd = findCommand(tokenizer);
if (!cmd)
{
std::cout << "Command not found\n"
<< "type `help` for available commands\n"
<< "type `help [command_name]` for additional information\n\n";
continue;
}
provideResources(cmd.get());
state = cmd->execute(tokenizer);
if (cmd->getWorkingDir())
{
m_workingDir = cmd->getWorkingDir();
}
if (state != ShellFlag::run)
{
std::cout << "Are you sure? (y/N): ";
std::getline(std::cin, terminalLine);
if (!(terminalLine == "y" || terminalLine == "Y"))
{
state = ShellFlag::run;
}
}
}
return state == ShellFlag::exit ? fs::AppState::exiting : fs::AppState::running;
}
void CommandProcessor::provideResources(Command* cmd) const
{
for (const auto& requiredResource : cmd->requiredResources())
{
if (requiredResource == ResourceTypes::root)
{
cmd->setRoot(m_root);
}
else if (requiredResource == ResourceTypes::workingDir)
{
cmd->setWorkingDir(m_workingDir);
}
else if (requiredResource == ResourceTypes::env)
{
cmd->setEnv(m_fileSystemManager->getMainEnv());
}
else if (requiredResource == ResourceTypes::additionalCmd)
{
cmd->setCommands(&m_commands);
}
}
}
std::unique_ptr<Command> CommandProcessor::findCommand(const Tokenizer& tokenizer) const
{
if (const auto it = m_commands.find(tokenizer.getCommandName()); it != m_commands.end())
{
return it->second();
}
return nullptr;
}
} // namespace shell