This repository was archived by the owner on Jul 21, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
144 lines (126 loc) · 4.6 KB
/
Copy pathmain.cpp
File metadata and controls
144 lines (126 loc) · 4.6 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include <utility>
#include <readline/readline.h>
#include <readline/history.h>
#include "command_registry.h"
struct configstr {
std::string name, tagline, author, description, hint, prompt;
std::vector<std::pair<std::string, std::string>> commands;
};
std::string trimmer(const std::string& s) {
size_t start = s.find_first_not_of(" \t");
size_t end = s.find_last_not_of(" \t");
return (start == std::string::npos) ? "" : s.substr(start, end - start + 1);
}
configstr load_config(const std::string& path) {
configstr configuration;
std::ifstream file(path);
if (!file) {
std::cerr << "Warning: I can not open config file: " << path << "\n";
return configuration;
}
bool is_command = false;
std::string line;
while (std::getline(file, line)) {
line = trimmer(line);
if (line.empty() || line[0] == '#') continue;
if (line == "[commands]") { is_command = true; continue; }
size_t eq = line.find('=');
if (eq == std::string::npos) continue;
std::string key = trimmer(line.substr(0, eq));
std::string value = trimmer(line.substr(eq + 1));
if (is_command) {
configuration.commands.emplace_back(key, value);
} else if (key == "name") configuration.name = value;
else if (key == "tagline") configuration.tagline = value;
else if (key == "author") configuration.author = value;
else if (key == "description") configuration.description = value;
else if (key == "hint") configuration.hint = value + " ";
else if (key == "prompt") configuration.prompt = value;
}
return configuration;
}
void banner(const configstr& configuration) {
std::cout << configuration.name << " — " << configuration.tagline << "\n";
std::cout << "by " << configuration.author << "\n";
std::cout << configuration.description << "\n";
std::cout << configuration.hint << "\n";
}
std::vector<std::pair<std::string, std::string>> load_commands(const std::string& path) {
std::vector<std::pair<std::string, std::string>> cmds;
std::ifstream file(path);
if (!file) {
std::cerr << "Warning: I can not open commands file: " << path << "\n";
return cmds;
}
std::string line;
while (std::getline(file, line)) {
line = trimmer(line);
if (line.empty() || line[0] == '#') continue;
size_t sep = line.find(" - ");
if (sep == std::string::npos) continue;
std::string name = trimmer(line.substr(0, sep));
std::string desc = trimmer(line.substr(sep + 3));
cmds.emplace_back(name, desc);
}
return cmds;
}
void print_help(const std::vector<std::pair<std::string, std::string>>& cmds) {
std::cout << "List of commands:\n";
for (const auto& cmd : cmds) {
std::cout << " " << cmd.first << " - " << cmd.second << "\n";
}
}
std::vector<std::pair<std::string, std::string>>& loaded_commands() {
static std::vector<std::pair<std::string, std::string>> cmds;
return cmds;
}
CommandRegistrar reg_help("help", []() {
print_help(loaded_commands());
return true;
});
CommandRegistrar reg_quit("quit", []() { return false; });
CommandRegistrar reg_exit("exit", []() { return false; });
int main() {
configstr configuration = load_config(std::string(APP_ROOT) + "/src/config/iscons.conf");
banner(configuration);
auto commands = load_commands(std::string(APP_ROOT) + "/src/cmds.txt");
loaded_commands() = commands;
bool running = true;
while (running) {
char* line = readline(configuration.prompt.c_str());
if (!line) {
std::cout << "\n";
break;
}
std::string input = trimmer(line);
add_history(line);
free(line);
if (input.empty()) continue;
std::istringstream iss(input);
std::string cmd_name;
iss >> cmd_name;
std::vector<std::string> args;
std::string a;
while (iss >> a) args.push_back(a);
bool unknown = true;
for (const auto& cmd : commands) {
if (cmd.first == cmd_name) { unknown = false; break; }
}
if (unknown) {
std::cerr << "\033[31mError: I cannot find command \"" << cmd_name << "\". Type help for a list!\033[0m\n";
continue;
}
current_args() = args;
auto it = registry().find(cmd_name);
if (it != registry().end()) {
running = it->second();
} else {
std::cout << input << ": not yet implemented\n";
}
}
return 0;
}