Remove tabs from all logging
Showing the changes to src/exec/main.cpp (1 of 5 files). Show all
Unified · Split
| @@ -30,10 +30,14 @@ namespace · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | std::shared_ptr<const vm_module_t> command_module; |
| 32 | 32 | |
| 33 | − std::unique_ptr<vm_module_t> create_entry_module(vm_t &vm, int argc, char* argv[]) | |
| 33 | + std::unique_ptr<vm_module_t> create_entry_module(vm_t &vm, const std::vector<char *> &vm_args) | |
| 34 | 34 | { |
| 35 | + if (vm_args.size() == 0) | |
| 36 | + throw vm_user_exception{ "Entry module not supplied" }; | |
| 37 | + | |
| 35 | 38 | // First argument is the module to load |
| 36 | − auto command_module_path = new vm_string_t{ std::strlen(argv[0]), reinterpret_cast<uint8_t *>(argv[0]) }; | |
| 39 | + auto entry_module_path = vm_args[0]; | |
| 40 | + auto command_module_path = new vm_string_t{ std::strlen(entry_module_path), reinterpret_cast<uint8_t *>(entry_module_path) }; | |
| 37 | 41 | |
| 38 | 42 | // Pre-load the command module in the VM. |
| 39 | 43 | command_module = vm.load_module(command_module_path->str()); |
| @@ -41,9 +45,9 @@ namespace · 1 unmodified line | ||
| 41 | 45 | // Convert arguments to a list |
| 42 | 46 | vm_list_t *args = nullptr; |
| 43 | 47 | vm_list_t *last = nullptr; |
| 44 | − for (auto i = 1; i < argc; ++i) | |
| 48 | + for (auto i = std::size_t{ 1 }; i < vm_args.size(); ++i) | |
| 45 | 49 | { |
| 46 | − auto tmp = argv[i]; | |
| 50 | + auto tmp = vm_args[i]; | |
| 47 | 51 | auto arg = new vm_string_t{ std::strlen(tmp), reinterpret_cast<uint8_t *>(tmp) }; |
| 48 | 52 | if (args == nullptr) |
| 49 | 53 | { |
| @@ -165,39 +169,160 @@ namespace · 115 unmodified lines | ||
| 165 | 169 | } |
| 166 | 170 | } |
| 167 | 171 | |
| 172 | +struct arg_exception_t : std::runtime_error | |
| 173 | +{ | |
| 174 | + arg_exception_t(const char *m, const char *arg) | |
| 175 | + : std::runtime_error{ m } | |
| 176 | + , arg{ arg } | |
| 177 | + { } | |
| 178 | + | |
| 179 | + const char * const arg; | |
| 180 | +}; | |
| 181 | + | |
| 182 | +struct exec_options | |
| 183 | +{ | |
| 184 | + std::vector<char *> vm_args; | |
| 185 | + | |
| 186 | + bool print_help; | |
| 187 | + bool quiet_start; | |
| 188 | + bool enabled_debugger; | |
| 189 | + debugger_options debugger; | |
| 190 | +}; | |
| 191 | + | |
| 192 | +void print_banner(const exec_options &options) | |
| 193 | +{ | |
| 194 | + std::cout | |
| 195 | + << "DisVM\n" | |
| 196 | + << "----------------\n" | |
| 197 | + << "Debugger enabled: " << std::boolalpha << options.enabled_debugger << "\n"; | |
| 198 | + | |
| 199 | + if (options.enabled_debugger) | |
| 200 | + std::cout << options.debugger << "\n"; | |
| 201 | + | |
| 202 | + std::cout << std::endl; | |
| 203 | +} | |
| 204 | + | |
| 205 | +void print_help() | |
| 206 | +{ | |
| 207 | + std::cout | |
| 208 | + << "Usage: disvm-exec [-d[e|m|x]*] [-q] [-?] <entry module> <args>*\n" | |
| 209 | + << " d - Enable debugger\n" | |
| 210 | + << " e - Break on entry\n" | |
| 211 | + << " m - Break on module load\n" | |
| 212 | + << " x - Break on exception (first chance)\n" | |
| 213 | + << " q - Suppress banner and configuration\n" | |
| 214 | + << " ? - Print help\n"; | |
| 215 | +} | |
| 216 | + | |
| 217 | +void process_arg(char* arg, std::function<char *()> next, exec_options &options) | |
| 218 | +{ | |
| 219 | + assert(arg != nullptr && next != nullptr); | |
| 220 | + if (arg[0] != '-') | |
| 221 | + { | |
| 222 | + for (; arg != nullptr; arg = next()) | |
| 223 | + options.vm_args.push_back(arg); | |
| 224 | + | |
| 225 | + return; | |
| 226 | + } | |
| 227 | + | |
| 228 | + auto arg_len = std::strlen(arg); | |
| 229 | + if (arg_len < 2) | |
| 230 | + throw arg_exception_t{ "Invalid flag format", arg }; | |
| 231 | + | |
| 232 | + switch (arg[1]) | |
| 233 | + { | |
| 234 | + case 'd': | |
| 235 | + options.enabled_debugger = true; | |
| 236 | + for (auto i = std::size_t{ 2 }; i < arg_len; ++i) | |
| 237 | + { | |
| 238 | + switch (arg[i]) | |
| 239 | + { | |
| 240 | + case 'e': options.debugger.break_on_enter = true; | |
| 241 | + break; | |
| 242 | + case 'm': options.debugger.break_on_module_load = true; | |
| 243 | + break; | |
| 244 | + case 'x': options.debugger.break_on_exception = true; | |
| 245 | + break; | |
| 246 | + } | |
| 247 | + } | |
| 248 | + | |
| 249 | + break; | |
| 250 | + | |
| 251 | + case 'q': | |
| 252 | + options.quiet_start = true; | |
| 253 | + break; | |
| 254 | + | |
| 255 | + case '?': | |
| 256 | + options.print_help = true; | |
| 257 | + break; | |
| 258 | + | |
| 259 | + default: | |
| 260 | + throw arg_exception_t{ "Unknown flag", arg }; | |
| 261 | + } | |
| 262 | +} | |
| 263 | + | |
| 168 | 264 | int main(int argc, char* argv[]) |
| 169 | 265 | { |
| 170 | − // [TODO] Handle command line arguments | |
| 171 | − assert(argc > 1); | |
| 266 | + exec_options options = {}; | |
| 267 | + | |
| 268 | + try | |
| 269 | + { | |
| 270 | + // Ignore the process name | |
| 271 | + auto arg_idx = int{ 1 }; | |
| 272 | + auto next_arg = [&]() | |
| 273 | + { | |
| 274 | + return arg_idx < argc ? argv[arg_idx++] : nullptr; | |
| 275 | + }; | |
| 276 | + | |
| 277 | + for (auto curr_arg = next_arg(); curr_arg != nullptr; curr_arg = next_arg()) | |
| 278 | + process_arg(curr_arg, next_arg, options); | |
| 279 | + } | |
| 280 | + catch (const arg_exception_t &ae) | |
| 281 | + { | |
| 282 | + std::cerr << ae.what(); | |
| 283 | + if (ae.arg != nullptr) | |
| 284 | + std::cerr << ": " << ae.arg << std::endl; | |
| 285 | + | |
| 286 | + return EXIT_FAILURE; | |
| 287 | + } | |
| 288 | + | |
| 289 | + if (!options.quiet_start) | |
| 290 | + print_banner(options); | |
| 291 | + | |
| 292 | + if (options.print_help) | |
| 293 | + { | |
| 294 | + print_help(); | |
| 295 | + return EXIT_SUCCESS; | |
| 296 | + } | |
| 172 | 297 | |
| 173 | 298 | vm_t vm; |
| 174 | 299 | |
| 175 | − //vm.load_tool(std::make_shared<debugger>()); | |
| 300 | + if (options.enabled_debugger) | |
| 301 | + vm.load_tool(std::make_shared<debugger>(options.debugger)); | |
| 176 | 302 | |
| 177 | 303 | try |
| 178 | 304 | { |
| 179 | − // Ignore the process name | |
| 180 | − auto entry = create_entry_module(vm, argc - 1, argv + 1); | |
| 305 | + auto entry = create_entry_module(vm, options.vm_args); | |
| 181 | 306 | |
| 182 | 307 | vm.exec(std::move(entry)); |
| 183 | 308 | |
| 184 | 309 | vm.spin_sleep_till_idle(std::chrono::milliseconds(100)); |
| 185 | 310 | } |
| 186 | − catch (vm_user_exception &ue) | |
| 311 | + catch (const vm_user_exception &ue) | |
| 187 | 312 | { |
| 188 | − std::cout << ue.what() << std::endl; | |
| 313 | + std::cerr << ue.what() << std::endl; | |
| 189 | 314 | |
| 190 | 315 | return EXIT_FAILURE; |
| 191 | 316 | } |
| 192 | − catch (vm_system_exception &se) | |
| 317 | + catch (const vm_system_exception &se) | |
| 193 | 318 | { |
| 194 | − std::cout | |
| 195 | − << "Internal exception:\n\t" | |
| 319 | + std::cerr | |
| 320 | + << "Internal exception:\n " | |
| 196 | 321 | << se.what() |
| 197 | 322 | << std::endl; |
| 198 | 323 | |
| 199 | 324 | return EXIT_FAILURE; |
| 200 | 325 | } |
| 201 | 326 | |
| 202 | − return 0; | |
| 327 | + return EXIT_SUCCESS; | |
| 203 | 328 | } |