int main (int argc, char **argv) { int curr_arg = 1; bool case_sensitive = false; bool is_storage_initialized = false; use_colors = true; extern WORD user_attributes; user_attributes = save_console_attributes (); atexit (restore_console_attributes_at_exit); //if there aren't enough args, show info if (argc < 2) { puts ("SPASM-ng Z80 Assembler by Spencer Putt and Don Straney"); printf ("Version %s (built on %s @ %s)\n", SPASM_NG_VERSION, __DATE__, __TIME__); #ifdef SPASM_NG_GITREV printf ("Git revision %s\n", SPASM_NG_GITREV); #endif #ifdef _M_X64 puts ("64-bit Version"); #endif #ifdef NO_APPSIGN printf ("\nApp signing is NOT available in this build of SPASM.\n"); #endif puts ("\nspasm [options] <input file> <output file>\n"); puts ("Options:\n-E = Assemble eZ80 code\n-T = Generate code listing\n-C = Code counter mode\n-L = Symbol table mode\n-S = Stats mode\n-O = Don't write to output file"); puts ("-I [directory] = Add include directory\n-A = Labels are cAse-sensitive\n-D<name>[=value] = Create a define 'name' [with 'value']"); puts ("-N = Don't use colors for messages"); puts ("-V <Expression> = Pipe expression directly into assembly"); #if defined(_DEBUG) && defined(WIN32) if (IsDebuggerPresent()) { system("PAUSE"); } #endif return EXIT_NORMAL; } //init stuff mode = MODE_NORMAL; in_macro = 0; //otherwise, get any options curr_input_file = strdup("Commandline"); char *starting_input_file = curr_input_file; while (curr_arg < argc) { if (argv[curr_arg][0] == '-' #ifdef _WINDOWS || argv[curr_arg][0] == '/' #endif ) { switch (argv[curr_arg][1]) { //args for different modes case 'O': mode = mode & (~MODE_NORMAL); break; case 'T': mode |= MODE_LIST; break; case 'C': mode |= MODE_CODE_COUNTER; break; case 'L': mode |= MODE_SYMTABLE; break; case 'S': mode |= MODE_STATS; break; case 'E': mode |= MODE_EZ80; all_opcodes = opcode_list_ez80; break; //handle no-colors flag case 'N': use_colors = false; break; //handle include files too case 'I': { char *dir, *p; //make sure there's another argument after it for the include path if (strlen(argv[curr_arg]) > 2) { dir = strdup (&argv[curr_arg][2]); } else { if (curr_arg >= argc - 1) { printf ("%s used without include path\n", argv[curr_arg]); break; } dir = strdup (argv[++curr_arg]); } for (p = strtok (dir, ";,"); p; p = strtok (NULL, ";,")) { include_dirs = list_append (include_dirs, strdup(p)); } free(dir); break; } //and the case-sensitive flag case 'A': case_sensitive = true; break; //handle adding defines case 'D': { char name[256]; char *ptr; define_t *define; if (!is_storage_initialized) { init_storage(); is_storage_initialized = true; } if (strlen (argv[curr_arg]) > 2) { ptr = &argv[curr_arg][2]; } else { if (curr_arg >= argc - 1) { printf ("%s used without define name", argv[curr_arg]); break; } ptr = argv[++curr_arg]; } read_expr (&ptr, name, "="); define = add_define (strdup (name), NULL); if (*skip_whitespace (++ptr) != '\0') define->contents = strdup (ptr); else set_define (define, "1", 1, false); break; } case 'V': { char *line; //check for something after -V if (strlen(argv[curr_arg]) > 2) { line = &argv[curr_arg][2]; } else { //if not lets fail if (curr_arg >= argc - 1) { printf ("%s used without a line to assemble\n", argv[curr_arg]); return EXIT_FATAL_ERROR; } line = argv[++curr_arg]; } mode |= MODE_COMMANDLINE; curr_input_file = strdup("-v"); input_contents = (char *) malloc (strlen(line) + 1 + 2); output_filename = change_extension (curr_input_file, "bin"); strcpy(input_contents, line); strcat(input_contents, "\n"); break; } default: { #ifndef _TEST #ifdef _WINDOWS printf ("Unrecognized option %s\n", argv[curr_arg]); #ifdef SPASM_NG_ENABLE_COM FreeConsole(); return _AtlModule.WinMain(SW_HIDE); #endif #endif #else printf ("Unrecognized option %s\n", argv[curr_arg]); #endif } } } else { //if it's not a flag, then it must be a filename if (curr_input_file && (curr_input_file != starting_input_file) && !output_filename) output_filename = strdup(argv[curr_arg]); else if ((!curr_input_file) || (curr_input_file == starting_input_file)) curr_input_file = strdup(argv[curr_arg]); } curr_arg++; } // Update case sensitivity settings set_case_sensitive (case_sensitive); //check on filenames if (!(mode & MODE_COMMANDLINE) && curr_input_file == starting_input_file) { puts ("No input file specified"); free(starting_input_file); return EXIT_FATAL_ERROR; } if (curr_input_file != starting_input_file) { free(starting_input_file); } if (!output_filename) { output_filename = change_extension (curr_input_file, "bin"); } if (!is_storage_initialized) { init_storage(); is_storage_initialized = true; } output_contents = (unsigned char *) malloc(output_buf_size); ClearSPASMErrorSessions(); int error = run_assembly(); free(output_filename); output_filename = NULL; if (curr_input_file) { free(curr_input_file); curr_input_file = NULL; } if (include_dirs) { list_free(include_dirs, true, NULL); } free(output_contents); output_contents = NULL; ClearSPASMErrorSessions(); free_storage(); #ifdef _WINDOWS _CrtDumpMemoryLeaks(); if (IsDebuggerPresent()) { system("PAUSE"); } #endif return error; }
STDMETHOD(put_CaseSensitive)(VARIANT_BOOL caseSensitive) { set_case_sensitive(caseSensitive == VARIANT_TRUE ? TRUE : FALSE); return S_OK; }