Joedb 9.6.2
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Command_Interpreter.cpp
Go to the documentation of this file.
3
4#include <sstream>
5
6namespace joedb
7{
8 ////////////////////////////////////////////////////////////////////////////
9 void Command_Interpreter::after_command
10 ////////////////////////////////////////////////////////////////////////////
11 (
12 std::ostream &out,
13 int64_t line_number,
14 const std::string &line,
15 const Exception *exception
16 ) const
17 {
18 if (exception)
19 {
20 std::ostringstream error;
21 error << exception->what();
22 error << "\nLine " << line_number << ": " << line << '\n';
23
24 if (rethrow)
25 throw Exception(error.str());
26 else
27 out << "Exception caught: " << error.str();
28 }
29 else if (echo)
30 out << "OK: " << line << '\n';
31 }
32
33 ////////////////////////////////////////////////////////////////////////////
35 ////////////////////////////////////////////////////////////////////////////
36 (
37 const std::string &command,
38 std::istream &parameters,
39 std::istream &in,
40 std::ostream &out
41 )
42 {
43 if (command.empty() || command[0] == '#') /////////////////////////////////
44 {
45 }
46 else if (command == "about") //////////////////////////////////////////////
47 {
48 about_joedb(out);
49 }
50 else if (command == "echo") ///////////////////////////////////////////////
51 {
52 std::string parameter;
53 parameters >> parameter;
54
55 if (parameter == "on")
56 set_echo(true);
57 else if (parameter == "off")
58 set_echo(false);
59 }
60 else if (command == "prompt") /////////////////////////////////////////////
61 {
62 std::string parameter;
63 parameters >> parameter;
64
65 if (parameter == "on")
66 set_prompt(true);
67 else if (parameter == "off")
68 set_prompt(false);
69 }
70 else if (command == "help") ///////////////////////////////////////////////
71 {
72 out << R"RRR(
73General commands
74~~~~~~~~~~~~~~~~
75 about
76 help|?
77 quit
78 abort
79 echo on|off
80 prompt on|off
81
82)RRR";
83
84 return Status::ok;
85 }
86 else if (command == "quit") ///////////////////////////////////////////////
87 return Status::quit;
88 else if (command == "abort") //////////////////////////////////////////////
89 return Status::abort;
90 else
91 return Status::not_found;
92
93 return Status::done;
94 }
95
96 ////////////////////////////////////////////////////////////////////////////
98 ////////////////////////////////////////////////////////////////////////////
99 {
100 add_processor(*static_cast<Command_Processor *>(this));
102
103 ////////////////////////////////////////////////////////////////////////////
105 ////////////////////////////////////////////////////////////////////////////
106 {
107 processors.emplace_back(processor);
108 }
109
110 ////////////////////////////////////////////////////////////////////////////
111 void Command_Interpreter::set_parent(const Command_Interpreter *new_parent)
112 ////////////////////////////////////////////////////////////////////////////
113 {
114 parent = new_parent;
116 if (parent)
117 {
118 echo = parent->echo;
119 rethrow = parent->rethrow;
120 prompt = parent->prompt;
121 }
123
124 ////////////////////////////////////////////////////////////////////////////
125 void Command_Interpreter::write_prompt(std::ostream &out) const
126 ////////////////////////////////////////////////////////////////////////////
127 {
128 out << prompt_string;
129 }
130
131 ////////////////////////////////////////////////////////////////////////////
132 void Command_Interpreter::write_whole_prompt(std::ostream &out) const
133 ////////////////////////////////////////////////////////////////////////////
134 {
135 out << "\x1b[36m";
136
137 if (parent)
138 {
139 parent->write_prompt(out);
140 out << '/';
141 }
142
143 write_prompt(out);
144 out << "> \x1b[0m";
145 out.flush();
146 }
147
148 ////////////////////////////////////////////////////////////////////////////
149 void Command_Interpreter::main_loop(std::istream &in, std::ostream &out)
150 ////////////////////////////////////////////////////////////////////////////
151 {
152 int64_t line_number = 0;
153 bool abort = false;
154
155 while(true)
156 {
157 if (prompt)
159
160 std::string line;
161 if (!std::getline(in, line))
162 break;
163
164 line_number++;
165 std::istringstream iss(line);
166 std::string command;
167 iss >> command;
168
169 if (command == "?")
170 command = "help";
171
172 try
173 {
174 bool found = false;
175 bool quit = false;
176
177 for (const auto &processor: processors)
178 {
179 const Command_Processor::Status status =
180 processor.get().process_command(command, iss, in, out);
181
183 found = true;
184
186 {
187 quit = true;
188 break;
189 }
190
192 {
193 abort = true;
194 break;
195 }
196
198 break;
199 }
200
201 if (!found)
202 {
203 throw Exception
204 (
205 "Unknown command. For a list of available commands, try \"help\"."
206 );
207 }
208
209 after_command(out, line_number, line, nullptr);
210
211 if (quit || abort)
212 break;
213 }
214 catch (const Exception &e)
215 {
216 after_command(out, line_number, line, &e);
217 }
218 }
219
220 if (abort)
221 throw Exception("aborted");
222 }
223}
void set_parent(const Command_Interpreter *new_parent)
void main_loop(std::istream &in, std::ostream &out)
void write_whole_prompt(std::ostream &out) const
Status process_command(const std::string &command, std::istream &parameters, std::istream &in, std::ostream &out) override
void add_processor(Command_Processor &processor)
virtual void write_prompt(std::ostream &out) const
void about_joedb(std::ostream &out)
Definition Blob.h:7