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 | std::shared_ptr<const vm_module_t> command_module; | 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 | // First argument is the module to load | 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 | // Pre-load the command module in the VM. | 42 | // Pre-load the command module in the VM. |
| 39 | command_module = vm.load_module(command_module_path->str()); | 43 | command_module = vm.load_module(command_module_path->str()); |
| @@ -41,9 +45,9 @@ namespace · 1 unmodified line | |||
| 41 | // Convert arguments to a list | 45 | // Convert arguments to a list |
| 42 | vm_list_t *args = nullptr; | 46 | vm_list_t *args = nullptr; |
| 43 | vm_list_t *last = nullptr; | 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 | auto arg = new vm_string_t{ std::strlen(tmp), reinterpret_cast<uint8_t *>(tmp) }; | 51 | auto arg = new vm_string_t{ std::strlen(tmp), reinterpret_cast<uint8_t *>(tmp) }; |
| 48 | if (args == nullptr) | 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 | int main(int argc, char* argv[]) | 264 | int main(int argc, char* argv[]) |
| 169 | { | 265 | { |
| 170 | // [TODO] Handle command line arguments | 266 | exec_options options = {}; |
| 171 | assert(argc > 1); | 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 | vm_t vm; | 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 | try | 303 | try |
| 178 | { | 304 | { |
| 179 | // Ignore the process name | 305 | auto entry = create_entry_module(vm, options.vm_args); |
| 180 | auto entry = create_entry_module(vm, argc - 1, argv + 1); | ||
| 181 | 306 | ||
| 182 | vm.exec(std::move(entry)); | 307 | vm.exec(std::move(entry)); |
| 183 | 308 | ||
| 184 | vm.spin_sleep_till_idle(std::chrono::milliseconds(100)); | 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 | return EXIT_FAILURE; | 315 | return EXIT_FAILURE; |
| 191 | } | 316 | } |
| 192 | catch (vm_system_exception &se) | 317 | catch (const vm_system_exception &se) |
| 193 | { | 318 | { |
| 194 | std::cout | 319 | std::cerr |
| 195 | << "Internal exception:\n\t" | 320 | << "Internal exception:\n " |
| 196 | << se.what() | 321 | << se.what() |
| 197 | << std::endl; | 322 | << std::endl; |
| 198 | 323 | ||
| 199 | return EXIT_FAILURE; | 324 | return EXIT_FAILURE; |
| 200 | } | 325 | } |
| 201 | 326 | ||
| 202 | return 0; | 327 | return EXIT_SUCCESS; |
| 203 | } | 328 | } |