int main(int argc, char* argv[]) { struct errinfo* errval; if (argc != 2) { fprintf(stderr, "usage: dtpp lang < file\n"); return 1; } osutil_setarg0(bautofree(bfromcstr(argv[0]))); if (dsethalt()) { errval = derrinfo(); printf("error occurred while preprocessing:\n"); printf(derrstr[errval->errid], errval->errdata); return 1; } ppimpl(bautofree(bfromcstr("<stdin>")), 0, bautofree(bfromcstr(argv[1])), has_input, input, output); return 0; }
int main(int argc, char* argv[]) { // Define our variables. int nerrors, i; int32_t saved = 0; // The number of words saved during compression and optimization. struct errinfo* errval; const char* prepend = "error: "; const char* warnprefix = "no-"; int msglen; char* msg; int target; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_str* target_arg = arg_str0("l", "link-as", "target", "Link as the specified object, can be 'image', 'static' or 'kernel'."); struct arg_file* symbol_file = arg_file0("s", "symbols", "<file>", "Produce a combined symbol file (~triples memory usage!)."); struct arg_str* symbol_ext = arg_str0(NULL, "symbol-extension", "ext", "When -s is used, specifies the extension for symbol files. Defaults to \"dsym16\"."); struct arg_file* input_files = arg_filen(NULL, NULL, "<file>", 1, 100, "The input object files."); struct arg_file* output_file = arg_file1("o", "output", "<file>", "The output file (or - to send to standard output)."); struct arg_file* kernel_file = arg_file0("k", "kernel", "<file>", "Directly link in the specified kernel."); struct arg_file* jumplist_file = arg_file0("j", "jumplist", "<file>", "Link against the specified jumplist."); struct arg_str* warning_policies = arg_strn("W", NULL, "policy", 0, _WARN_COUNT * 2 + 10, "Modify warning policies."); struct arg_lit* keep_output_arg = arg_lit0(NULL, "keep-outputs", "Keep the .OUTPUT entries in the final static library (used for stdlib)."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions)."); struct arg_lit* no_short_literals_arg = arg_lit0(NULL, "no-short-literals", "Do not compress literals to short literals."); struct arg_int* opt_level = arg_int0("O", NULL, "<level>", "The optimization level."); struct arg_lit* opt_mode = arg_lit0("S", NULL, "Favour runtime speed over size when optimizing."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { show_help, target_arg, keep_output_arg, little_endian_mode, opt_level, opt_mode, no_short_literals_arg, symbol_ext, symbol_file, kernel_file, jumplist_file, warning_policies, output_file, input_files, verbose, quiet, end }; // Parse arguments. nerrors = arg_parse(argc, argv, argtable); version_print(bautofree(bfromcstr("Linker"))); if (nerrors != 0 || show_help->count != 0) { if (show_help->count != 0) arg_print_errors(stdout, end, "linker"); printd(LEVEL_DEFAULT, "syntax:\n dtld"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Set endianness. isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE); // Set up warning policies. dsetwarnpolicy(warning_policies); // Set up error handling. if (dsethalt()) { errval = derrinfo(); // FIXME: Use bstrings here. msglen = strlen(derrstr[errval->errid]) + strlen(prepend) + 1; msg = malloc(msglen); memset(msg, '\0', msglen); strcat(msg, prepend); strcat(msg, derrstr[errval->errid]); printd(LEVEL_ERROR, msg, errval->errdata); // Handle the error. printd(LEVEL_ERROR, "linker: error occurred.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Check to make sure target is correct. if (target_arg->count == 0) target = IMAGE_APPLICATION; else { if (strcmp(target_arg->sval[0], "image") == 0) target = IMAGE_APPLICATION; else if (strcmp(target_arg->sval[0], "static") == 0) target = IMAGE_STATIC_LIBRARY; else if (strcmp(target_arg->sval[0], "kernel") == 0) target = IMAGE_KERNEL; else { // Invalid option. dhalt(ERR_INVALID_TARGET_NAME, NULL); } } // Load all passed objects and use linker bin system to // produce result. bins_init(); for (i = 0; i < input_files->count; i++) if (!bins_load(bautofree(bfromcstr(input_files->filename[i])), symbol_file->count > 0, (symbol_file->count > 0 && symbol_ext->count > 0) ? symbol_ext->sval[0] : "dsym16")) // Failed to load one of the input files. dhalt(ERR_BIN_LOAD_FAILED, input_files->filename[i]); bins_associate(); bins_sectionize(); bins_flatten(bautofree(bfromcstr("output"))); if (target == IMAGE_KERNEL) bins_write_jump(); saved = bins_optimize( opt_mode->count == 0 ? OPTIMIZE_SIZE : OPTIMIZE_SPEED, opt_level->count == 0 ? OPTIMIZE_NONE : opt_level->ival[0]); if (no_short_literals_arg->count == 0 && target != IMAGE_STATIC_LIBRARY) saved += bins_compress(); else if (no_short_literals_arg->count == 0) dwarn(WARN_SKIPPING_SHORT_LITERALS_TYPE, NULL); else dwarn(WARN_SKIPPING_SHORT_LITERALS_REQUEST, NULL); bins_resolve( target == IMAGE_STATIC_LIBRARY, target == IMAGE_STATIC_LIBRARY); bins_save( bautofree(bfromcstr("output")), bautofree(bfromcstr(output_file->filename[0])), target, keep_output_arg->count > 0, symbol_file->count > 0 ? symbol_file->filename[0] : NULL, jumplist_file->count > 0 ? jumplist_file->filename[0] : NULL); bins_free(); if (saved > 0) printd(LEVEL_DEFAULT, "linker: saved %i words during optimization.\n", saved); else if (saved < 0) printd(LEVEL_DEFAULT, "linker: increased by %i words during optimization.\n", -saved); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 0; }
int main(int argc, char* argv[]) { // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_str* type_assembler = arg_str0("t", NULL, "<type>", "The type of assembler to output for."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file (or - to read from standard input)."); struct arg_file* output_file = arg_file1("o", "output", "<file>", "The output file (or - to send to standard output)."); // 20 is maxcount for include directories, this has to be set to some constant number. struct arg_file* include_dirs = arg_filen("I", NULL, "<directory>", 0, 20, "Adds the directory <dir> to the directories to be searched for header files."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { output_file, show_help, type_assembler, include_dirs, input_file, verbose, quiet, end }; // Parse arguments. int nerrors = arg_parse(argc, argv, argtable); version_print(bautofree(bfromcstr("Compiler"))); if (nerrors != 0 || show_help->count != 0) { if (nerrors != 0) arg_print_errors(stderr, end, "compiler"); fprintf(stderr, "syntax:\n dtcc"); arg_print_syntax(stderr, argtable, "\n"); fprintf(stderr, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Run the preprocessor. ppfind_add_path(bautofree(bfromcstr("."))); ppfind_add_path(bautofree(bfromcstr("include"))); ppfind_add_autopath(bautofree(bfromcstr(input_file->filename[0]))); for (int i = 0; i < include_dirs->count; ++i) ppfind_add_path(bautofree(bfromcstr(include_dirs->filename[i]))); bstring pp_result_name = pp_do(bautofree(bfromcstr(input_file->filename[0]))); if (pp_result_name == NULL) { fprintf(stderr, "compiler: invalid result returned from preprocessor.\n"); pp_cleanup(bautofree(pp_result_name)); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Parse C. yyout = stderr; yyin = fopen((const char*)(pp_result_name->data), "r"); if (yyin == NULL) { pp_cleanup(bautofree(pp_result_name)); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } yyparse(); if (yyin != stdin) fclose(yyin); pp_cleanup(bautofree(pp_result_name)); if (program == NULL) { std::cerr << "An error occurred while compiling." << std::endl; arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Assembler type. const char* asmtype = "toolchain"; if (type_assembler->count > 0) asmtype = type_assembler->sval[0]; // Initially save to a temporary file. std::string temp = std::string(tempnam(".", "cc.")); // Generate assembly using the AST. try { AsmGenerator generator(asmtype); AsmBlock* block = program->compile(generator); std::ofstream output(temp.c_str(), std::ios::out | std::ios::trunc); if (output.bad() || output.fail()) { printd(LEVEL_ERROR, "compiler: temporary file not writable.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } output << *block << std::endl; output.close(); delete block; } catch (CompilerException* ex) { std::string msg = ex->getMessage(); std::cerr << "An error occurred while compiling." << std::endl; std::cerr << msg << std::endl; arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Re-open the temporary file for reading. std::ifstream input(temp.c_str(), std::ios::in); if (input.bad() || input.fail()) { printd(LEVEL_ERROR, "compiler: temporary file not readable.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Open the output file. std::ostream* output; if (strcmp(output_file->filename[0], "-") != 0) { // Write to file. output = new std::ofstream(output_file->filename[0], std::ios::out | std::ios::trunc); if (output->bad() || output->fail()) { printd(LEVEL_ERROR, "compiler: output file not readable.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } } else { // Set output to cout. output = &std::cout; } // Copy data. std::copy(std::istreambuf_iterator<char>(input), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(*output)); // Close files and delete temporary. if (strcmp(output_file->filename[0], "-") != 0) { ((std::ofstream*)output)->close(); delete output; } input.close(); unlink(temp.c_str()); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 0; }
int main(int argc, char* argv[]) { // Define our variables. FILE* load; uint16_t flash[0x10000]; char leading[0x100]; unsigned int i; bool uread = true; vm_t* vm; int nerrors; bstring ss, st; host_context_t* dtemu = malloc(sizeof(host_context_t)); const char* warnprefix = "no-"; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file, or - to read from standard input."); struct arg_file* execution_dump_file = arg_file0("e", "execution-dump", "<file>", "Produce a very large execution dump file."); struct arg_lit* debug_mode = arg_lit0("d", "debug", "Show each executed instruction."); struct arg_lit* terminate_mode = arg_lit0("t", "show-on-terminate", "Show state of machine when program is terminated."); struct arg_lit* headless_mode = arg_lit0("h", "headless", "Run machine witout displaying monitor and SPED output"); struct arg_lit* legacy_mode = arg_lit0("l", "legacy", "Automatically initialize hardware to legacy values."); struct arg_str* warning_policies = arg_strn("W", NULL, "policy", 0, _WARN_COUNT * 2 + 10, "Modify warning policies."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions)."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_int* radiation = arg_intn("r", NULL, "<n>", 0, 1, "Radiation factor (higher is less radiation)"); struct arg_lit* catch_fire = arg_lit0("c", "catch-fire", "The virtual machine should catch fire instead of halting."); struct arg_end* end = arg_end(20); void* argtable[] = { input_file, warning_policies, debug_mode, execution_dump_file, terminate_mode, headless_mode, legacy_mode, little_endian_mode, radiation, catch_fire, verbose, quiet, end }; // Parse arguments. nerrors = arg_parse(argc, argv, argtable); if (nerrors != 0 || show_help->count != 0) { if (show_help->count != 0) arg_print_errors(stdout, end, "emulator"); printd(LEVEL_DEFAULT, "syntax:\n dtemu"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Show version information. version_print(bautofree(bfromcstr("Emulator"))); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Set endianness. isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE); // Set up warning policies. dsetwarnpolicy(warning_policies); // Set up error handling. if (dsethalt()) { // Handle the error. dautohandle(); printd(LEVEL_ERROR, "emulator: error occurred.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Zero out the flash space. for (i = 0; i < 0x10000; i++) flash[i] = 0x0; // Zero out the leading space. for (i = 0; i < 0x100; i++) leading[i] = 0x0; // Load from either file or stdin. if (strcmp(input_file->filename[0], "-") != 0) { // Open file. load = fopen(input_file->filename[0], "rb"); if (load == NULL) dhalt(ERR_EMU_LOAD_FILE_FAILED, input_file->filename[0]); } else { // Windows needs stdin in binary mode. #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif // Set load to stdin. load = stdin; } // Read leading component. for (i = 0; i < strlen(ldata_objfmt); i++) leading[i] = fgetc(load); fseek(load, 0, SEEK_SET); // Read up to 0x10000 words. for (i = 0; i < 0x10000 && !feof(load); i++) iread(&flash[i], load); fclose(load); // Check to see if the first X bytes matches the header // for intermediate code and stop if it does. ss = bfromcstr(""); st = bfromcstr(ldata_objfmt); for (i = 0; i < strlen(ldata_objfmt); i++) bconchar(ss, leading[i]); if (biseq(ss, st)) dhalt(ERR_INTERMEDIATE_EXECUTION, NULL); // Set up the host context. glfwInit(); dtemu->create_context = &dtemu_create_context; dtemu->activate_context = &dtemu_activate_context; dtemu->swap_buffers = &dtemu_swap_buffers; dtemu->destroy_context = &dtemu_destroy_context; dtemu->get_ud = &dtemu_get_ud; // And then use the VM. vm = vm_create(); vm->debug = (debug_mode->count > 0); vm_flash(vm, flash); // Set radiation and catch fire settings. if (radiation->count == 1) vm->radiation_factor = radiation->ival[0]; if (catch_fire->count == 1) vm->can_fire = true; // Init hardware. vm_hw_clock_init(vm); if (headless_mode->count < 1) vm->host = dtemu; vm_hw_sped3_init(vm); vm_hw_lem1802_init(vm); vm_hw_m35fd_init(vm); vm_hw_lua_init(vm); if (legacy_mode->count > 0) { for (i = 0; i < vm_hw_count(vm); i++) { hw_t* device = vm_hw_get_device(vm, i); if (device == NULL) continue; if (device->id == 0x7349F615 && device->manufacturer == 0x1C6C8B36) { vm_hw_lem1802_mem_set_screen((struct lem1802_hardware*)device->userdata, 0x8000); break; } } } vm_execute(vm, execution_dump_file->count > 0 ? execution_dump_file->filename[0] : NULL); if (terminate_mode->count > 0) { fprintf(stderr, "\n"); fprintf(stderr, "A: 0x%04X [A]: 0x%04X\n", vm->registers[REG_A], vm->ram[vm->registers[REG_A]]); fprintf(stderr, "B: 0x%04X [B]: 0x%04X\n", vm->registers[REG_B], vm->ram[vm->registers[REG_B]]); fprintf(stderr, "C: 0x%04X [C]: 0x%04X\n", vm->registers[REG_C], vm->ram[vm->registers[REG_C]]); fprintf(stderr, "X: 0x%04X [X]: 0x%04X\n", vm->registers[REG_X], vm->ram[vm->registers[REG_X]]); fprintf(stderr, "Y: 0x%04X [Y]: 0x%04X\n", vm->registers[REG_Y], vm->ram[vm->registers[REG_Y]]); fprintf(stderr, "Z: 0x%04X [Z]: 0x%04X\n", vm->registers[REG_Z], vm->ram[vm->registers[REG_Z]]); fprintf(stderr, "I: 0x%04X [I]: 0x%04X\n", vm->registers[REG_I], vm->ram[vm->registers[REG_I]]); fprintf(stderr, "J: 0x%04X [J]: 0x%04X\n", vm->registers[REG_J], vm->ram[vm->registers[REG_J]]); fprintf(stderr, "PC: 0x%04X SP: 0x%04X\n", vm->pc, vm->sp); fprintf(stderr, "EX: 0x%04X IA: 0x%04X\n", vm->ex, vm->ia); } vm_hw_lua_free(vm); vm_free(vm); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); glfwTerminate(); return 0; }
int main(int argc, char* argv[]) { CURL* curl; bstring command; bstring name; bstring modpath; int all; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_str* cmdopt = arg_str1(NULL, NULL, "<command>", "The command; either 'search', 'install', 'uninstall', 'enable' or 'disable'."); struct arg_str* nameopt = arg_str0(NULL, NULL, "<name>", "The name of the module to search for, install, uninstall, enable or disable."); struct arg_lit* all_flag = arg_lit0("a", "all", "Apply this command to all available / installed modules."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { show_help, cmdopt, all_flag, nameopt, verbose, quiet, end }; // Parse arguments. int nerrors = arg_parse(argc, argv, argtable); if (nerrors != 0 || show_help->count != 0 || (all_flag->count == 0 && nameopt->count == 0)) { if (all_flag->count == 0 && nameopt->count == 0) printd(LEVEL_ERROR, "error: must have either module name or -a."); if (show_help->count != 0) arg_print_errors(stderr, end, "mm"); fprintf(stderr, "syntax:\n dtmm"); arg_print_syntax(stderr, argtable, "\n"); fprintf(stderr, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Show version information. version_print(bautofree(bfromcstr("Module Manager"))); // Set argument 0 and convert parameters. osutil_setarg0(bautofree(bfromcstr(argv[0]))); command = bfromcstr(cmdopt->sval[0]); name = bfromcstr(nameopt->sval[0]); // Initialize curl or exit. curl = curl_easy_init(); if (!curl) { printd(LEVEL_ERROR, "unable to initialize curl.\n"); return 1; } // Ensure module path exists. modpath = osutil_getmodulepath(); if (modpath == NULL) { printd(LEVEL_ERROR, "module path does not exist (searched TOOLCHAIN_MODULES and modules/).\n"); return 1; } bdestroy(modpath); // Convert all flag. all = (all_flag->count > 0); // If all is set, set the name back to "". if (all) bassigncstr(name, ""); // If the name is "all" or "*", handle this as the all // boolean flag. if (biseqcstr(name, "all") || biseqcstr(name, "*")) { bassigncstr(name, ""); all = 1; printd(LEVEL_WARNING, "treating name as -a (all) flag"); } if (biseqcstrcaseless(command, "search") || biseqcstrcaseless(command, "se")) return do_search(curl, name, all); else if (biseqcstrcaseless(command, "install") || biseqcstrcaseless(command, "in")) { if (all) return do_install_all(curl); else return do_install(curl, name); } else if (biseqcstrcaseless(command, "uninstall") || biseqcstrcaseless(command, "rm")) { if (all) return do_uninstall_all(curl); else return do_uninstall(curl, name); } else if (biseqcstrcaseless(command, "enable") || biseqcstrcaseless(command, "en")) { if (all) return do_enable_all(curl); else return do_enable(curl, name); } else if (biseqcstrcaseless(command, "disable") || biseqcstrcaseless(command, "di") || biseqcstrcaseless(command, "dis")) { if (all) return do_disable_all(curl); else return do_disable(curl, name); } else { printd(LEVEL_ERROR, "unknown command (must be search, install, uninstall, enable or disable)."); return 1; } return 0; }
int main(int argc, char* argv[]) { // Define our variables. FILE* load; uint16_t flash[0x10000]; char leading[0x100]; unsigned int i; bool uread = true; vm_t* vm; int nerrors; bstring ss, st; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file, or - to read from standard input."); struct arg_file* execution_dump_file = arg_file0("e", "execution-dump", "<file>", "Produce a very large execution dump file."); struct arg_lit* debug_mode = arg_lit0("d", "debug", "Show each executed instruction."); struct arg_lit* terminate_mode = arg_lit0("t", "show-on-terminate", "Show state of machine when program is terminated."); struct arg_lit* legacy_mode = arg_lit0("l", "legacy", "Automatically initialize hardware to legacy values."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions)."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { input_file, debug_mode, execution_dump_file, terminate_mode, legacy_mode, little_endian_mode, verbose, quiet, end }; // Parse arguments. nerrors = arg_parse(argc, argv, argtable); version_print(bautofree(bfromcstr("Emulator"))); if (nerrors != 0 || show_help->count != 0) { if (show_help->count != 0) arg_print_errors(stdout, end, "emulator"); printd(LEVEL_DEFAULT, "syntax:\n dtemu"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Set endianness. isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE); // Zero out the flash space. for (i = 0; i < 0x10000; i++) flash[i] = 0x0; // Zero out the leading space. for (i = 0; i < 0x100; i++) leading[i] = 0x0; // Load from either file or stdin. if (strcmp(input_file->filename[0], "-") != 0) { // Open file. load = fopen(input_file->filename[0], "rb"); if (load == NULL) { fprintf(stderr, "emulator: unable to load %s from disk.\n", argv[1]); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } } else { // Windows needs stdin in binary mode. #ifdef _WIN32 _setmode(_fileno(stdin), _O_BINARY); #endif // Set load to stdin. load = stdin; } // Read up to 0x10000 words. for (i = 0; i < 0x10000 && !feof(load); i++) iread(&flash[i], load); fclose(load); // Check to see if the first X bytes matches the header // for intermediate code and stop if it does. ss = bfromcstr(""); st = bfromcstr(ldata_objfmt); for (i = 0; i < strlen(ldata_objfmt); i++) bconchar(ss, leading[i]); if (biseq(ss, st)) { fprintf(stderr, "emulator: it appears you passed intermediate code for execution. link\n"); fprintf(stderr, " the input code with the toolchain linker to execute it.\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // And then use the VM. vm = vm_create(); vm->debug = (debug_mode->count > 0); vm_flash(vm, flash); vm_hw_timer_init(vm); vm_hw_io_init(vm); vm_hw_lem1802_init(vm); vm_hw_lua_init(vm); if (legacy_mode->count > 0) { vm_hw_lem1802_mem_set_screen(vm, 0x8000); vm_hw_io_set_legacy(true); } vm_execute(vm, execution_dump_file->count > 0 ? execution_dump_file->filename[0] : NULL); #ifdef __EMSCRIPTEN__ printd(LEVEL_WARNING, "warning: not cleaning up resources in Emscripten.\n"); #else if (terminate_mode->count > 0) { fprintf(stderr, "\n"); fprintf(stderr, "A: 0x%04X [A]: 0x%04X\n", vm->registers[REG_A], vm->ram[vm->registers[REG_A]]); fprintf(stderr, "B: 0x%04X [B]: 0x%04X\n", vm->registers[REG_B], vm->ram[vm->registers[REG_B]]); fprintf(stderr, "C: 0x%04X [C]: 0x%04X\n", vm->registers[REG_C], vm->ram[vm->registers[REG_C]]); fprintf(stderr, "X: 0x%04X [X]: 0x%04X\n", vm->registers[REG_X], vm->ram[vm->registers[REG_X]]); fprintf(stderr, "Y: 0x%04X [Y]: 0x%04X\n", vm->registers[REG_Y], vm->ram[vm->registers[REG_Y]]); fprintf(stderr, "Z: 0x%04X [Z]: 0x%04X\n", vm->registers[REG_Z], vm->ram[vm->registers[REG_Z]]); fprintf(stderr, "I: 0x%04X [I]: 0x%04X\n", vm->registers[REG_I], vm->ram[vm->registers[REG_I]]); fprintf(stderr, "J: 0x%04X [J]: 0x%04X\n", vm->registers[REG_J], vm->ram[vm->registers[REG_J]]); fprintf(stderr, "PC: 0x%04X SP: 0x%04X\n", vm->pc, vm->sp); fprintf(stderr, "EX: 0x%04X IA: 0x%04X\n", vm->ex, vm->ia); } vm_hw_lua_free(vm); vm_hw_timer_free(vm); vm_hw_io_free(vm); vm_hw_lem1802_free(vm); vm_free(vm); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 0; #endif }
int main(int argc, char* argv[]) { int nerrors, w; bstring temp = NULL; const char* warnprefix = "no-"; bool expect_failure; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_lit* expect_failure_lit = arg_lit0("f", "fail", "Expect failure during preprocessing."); struct arg_str* input_lang = arg_str1(NULL, NULL, "<lang>", "The input language."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input preprocessor file."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { show_help, verbose, quiet, expect_failure_lit, input_lang, input_file, end }; // Parse arguments. nerrors = arg_parse(argc, argv, argtable); if (nerrors != 0 || show_help->count != 0) { if (nerrors != 0) arg_print_errors(stdout, end, "libdcpu-pp test suite"); printd(LEVEL_DEFAULT, "syntax:\n dtasm"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); if (show_help->count == 2) { printd(LEVEL_DEFAULT, "defined warnings:\n"); for (w = 0; w < _WARN_COUNT; w++) printd(LEVEL_DEFAULT, " %s\n", dwarnpolicy[w].name); } arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set failure expectation variable. expect_failure = (expect_failure_lit->count > 0); // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Set up error handling. if (dsethalt()) { // Handle the error. dautohandle(); printd(LEVEL_ERROR, "libdcpu-pp test suite: error occurred.\n"); if (temp != NULL) pp_cleanup(bautofree(temp)); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); if (expect_failure) return 0; else return 1; } // Perform preprocessing. ppfind_add_autopath(bautofree(bfromcstr(input_file->filename[0]))); temp = pp_do( bautofree(bfromcstr(input_lang->sval[0])), bautofree(bfromcstr(input_file->filename[0])) ); // Perform parsing. test_success = true; yyin = fopen(temp->data, "r"); yyout = NULL; yyparse(); fclose(yyin); // Cleanup. pp_cleanup(bautofree(temp)); if (test_success && expect_failure) return 1; else if (test_success && !expect_failure) return 0; else if (!test_success && expect_failure) return 0; else return 1; }
int main(int argc, char* argv[]) { bstring ldargs = bfromcstr(""); int i, result; unsigned int match = 0, unmatch = 0; char ca, ce; BFILE* expect; BFILE* actual; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_lit* gen_relocatable = arg_lit0("r", "relocatable", "Generate relocatable code."); struct arg_lit* gen_intermediate = arg_lit0("i", "intermediate", "Generate intermediate code for use with the linker."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization."); struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input assembly file."); struct arg_file* expect_file = arg_file0("e", "expect", "<file>", "The output file that contains expected output."); struct arg_file* actual_file = arg_file1("a", "actual", "<file>", "The output file where actual output will be placed."); struct arg_file* symbols_file = arg_file0("s", "debug-symbols", "<file>", "The debugging symbol output file."); struct arg_lit* fail_opt = arg_lit0("f", "fail", "The assembler is expected to fail and the actual output file should not exist on completion."); struct arg_file* path = arg_file1("p", NULL, "<path>", "The path to the assembler."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { show_help, gen_relocatable, gen_intermediate, little_endian_mode, symbols_file, input_file, expect_file, actual_file, fail_opt, path, verbose, quiet, end }; // Parse arguments. int nerrors = arg_parse(argc, argv, argtable); version_print(bautofree(bfromcstr("Assembler Test Driver"))); if (nerrors != 0 || show_help->count != 0 || (fail_opt->count == 0 && (expect_file->count == 0 || actual_file->count == 0))) { if (show_help->count != 0 && fail_opt->count == 0 && (expect_file->count == 0 || actual_file->count == 0)) printd(LEVEL_ERROR, "error: you must provide either -f or -e and -a.\n"); if (show_help->count != 0) arg_print_errors(stderr, end, "testasm"); printd(LEVEL_DEFAULT, "syntax:\n testasm"); arg_print_syntax(stderr, argtable, "\n"); printd(LEVEL_DEFAULT, "options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Generate the argument list for the assembler. ldargs = bfromcstr(path->filename[0]); binsertch(ldargs, 0, 1, '"'); bconchar(ldargs, '"'); bconchar(ldargs, ' '); // Verbosity options. if (verbose->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < verbose->count; i++) bconchar(ldargs, 'v'); bconchar(ldargs, ' '); } if (quiet->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < quiet->count; i++) bconchar(ldargs, 'q'); bconchar(ldargs, ' '); } // Literal options. if (gen_relocatable->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < gen_relocatable->count; i++) bconchar(ldargs, 'r'); bconchar(ldargs, ' '); } if (gen_intermediate->count > 0) { bconchar(ldargs, '-'); for (i = 0; i < gen_intermediate->count; i++) bconchar(ldargs, 'i'); bconchar(ldargs, ' '); } if (little_endian_mode->count > 0) { for (i = 0; i < little_endian_mode->count; i++) bcatcstr(ldargs, "--little-endian "); } // Unlink the actual file so that if we are expecting // failure, we won't return incorrectly. unlink(actual_file->filename[0]); // Output file. bcatcstr(ldargs, "-o \""); bcatcstr(ldargs, actual_file->filename[0]); bcatcstr(ldargs, "\" "); // Input file. bcatcstr(ldargs, "\""); bcatcstr(ldargs, input_file->filename[0]); bcatcstr(ldargs, "\" "); // Windows needs the whole command wrapped in quotes and slashes to be correct. // See http://stackoverflow.com/questions/2642551/windows-c-system-call-with-spaces-in-command. #ifdef _WIN32 binsertch(ldargs, 0, 1, '"'); bconchar(ldargs, '"'); #endif // Now run the assembler! result = system(ldargs->data); if (result != 0 && fail_opt->count == 0) { // Assembler returned error exit code. printd(LEVEL_ERROR, "error: expected success but assembler returned non-zero exit code (%i).\n", result); return 1; } else if (result == 0 && fail_opt->count >= 1) { // Assembler returned zero when failure was expected. printd(LEVEL_ERROR, "error: expected failure but assembler returned zero exit code.\n"); return 1; } else if (result != 0 && fail_opt->count >= 1) { // Assembler failed and we expected it to. Return success only // if the output file does not exist. actual = bfopen(actual_file->filename[0], "rb"); if (actual != NULL) { printd(LEVEL_ERROR, "error: expected failure but actual output file exists.\n"); bfclose(actual); return 1; } return 0; } // Open expect data. expect = bfopen(expect_file->filename[0], "rb"); if (expect == NULL) { // The expect file was not provided. printd(LEVEL_ERROR, "error: path to expect file does not exist.\n"); return 1; } // Open actual data. actual = bfopen(actual_file->filename[0], "rb"); if (actual == NULL) { // The expect file was not provided. bfclose(expect); printd(LEVEL_ERROR, "error: expected data but actual output file does not exist after running assembler.\n"); return 1; } // Now compare raw bytes. while (true) { if (!bfeof(actual) && !bfeof(expect)) { ca = bfgetc(actual); ce = bfgetc(expect); if (ca == ce) match++; else { printd(LEVEL_WARNING, "warning: byte at 0x%04X is different (got 0x%02X, expected 0x%02X)!\n", bftell(actual), ca, ce); unmatch++; } } else if (!bfeof(actual)) { ca = bfgetc(actual); printd(LEVEL_ERROR, "error: actual output contained trailing byte 0x%02X.\n", (unsigned char)ca); unmatch++; } else if (!bfeof(expect)) { ce = bfgetc(expect); printd(LEVEL_ERROR, "error: expected actual output to contain 0x%02X.\n", (unsigned char)ce); unmatch++; } else break; } if (unmatch > 0) { printd(LEVEL_ERROR, "error: actual output differs from expected output in content (%f%%, %i bytes different).\n", 100.f / (unmatch + match) * unmatch, unmatch); if (bftell(actual) != bftell(expect)) printd(LEVEL_ERROR, "error: actual output differs from expected output in length (%i bytes larger).\n", bftell(actual) - bftell(expect)); bfclose(actual); bfclose(expect); return 1; } // Close files and delete actual because we have // succeeded. bfclose(actual); bfclose(expect); unlink(actual_file->filename[0]); return 0; }
int main(int argc, char** argv) { char* buf; yyscan_t scanner; int nerrors; // Define arguments. struct arg_lit* show_help = arg_lit0("h", "help", "Show this help."); struct arg_str* command_arg = arg_str0("c", NULL, "<command>", "Run a single debugger command and exit with the result."); struct arg_file* symbols_file = arg_file0("s", "symbols", "<file>", "The file to load symbols from."); struct arg_file* input_file = arg_file0(NULL, NULL, "<file>", "The file to initially load."); struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions)."); struct arg_lit* no_attach_mode = arg_lit0("n", "no-attachment", "Do not attach default devices when launched."); struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity."); struct arg_lit* quiet = arg_litn("q", NULL, 0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity."); struct arg_end* end = arg_end(20); void* argtable[] = { show_help, no_attach_mode, command_arg, symbols_file, input_file, little_endian_mode, verbose, quiet, end }; // Parse arguments. nerrors = arg_parse(argc, argv, argtable); version_print(bautofree(bfromcstr("Debugger"))); if (nerrors != 0 || show_help->count != 0) { if (show_help->count != 0) arg_print_errors(stdout, end, "Debugger"); printf("syntax:\n dtdb"); arg_print_syntax(stderr, argtable, "\n"); printf("options:\n"); arg_print_glossary(stderr, argtable, " %-25s %s\n"); arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0])); return 1; } // Set verbosity level. debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); // Set global path variable. osutil_setarg0(bautofree(bfromcstr(argv[0]))); // Set endianness. isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE); // Register signal handler. signal(SIGINT, ddbg_sigint); // Initialize debugger. ddbg_init(); // Initialize devices unless not requested. if (no_attach_mode->count == 0) { ddbg_attach(bfromcstr("clock")); ddbg_attach(bfromcstr("keyboard")); ddbg_attach(bfromcstr("lem1802")); } // Load file if filename is specified. if (input_file->count > 0) { ddbg_load(bfromcstr(input_file->filename[0])); ddbg_flash_vm(); } if (symbols_file->count > 0) ddbg_load_symbols(bfromcstr(symbols_file->filename[0])); // If the user specified a command, execute only that // command and then continue. if (command_arg->count > 0) { ddbg_return_code = 1; // Default is failure. dbg_yylex_init(&scanner); dbg_yy_scan_string(command_arg->sval[0], scanner); dbg_yyparse(scanner); dbg_yylex_destroy(scanner); return ddbg_return_code; } // Create SDP thread if supported. #ifdef FEATURE_SDP pthread_create(&sdp_thread, NULL, (void*)ddbg_sdp_thread, vm); #endif // We always want to show the debugger start message. debug_setlevel(LEVEL_VERBOSE + verbose->count - quiet->count); version_print(bautofree(bfromcstr("Debugger"))); debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count); for (;;) { buf = readline("> "); add_history(buf); dbg_yylex_init(&scanner); dbg_yy_scan_string(buf, scanner); dbg_yyparse(scanner); dbg_yylex_destroy(scanner); } free(buf); return 0; }