From 623f8c8ebfbe307fdf6b5138c25e4620bb08d2a7 Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Fri, 14 Feb 2020 12:11:01 -0800 Subject: [PATCH] aindump/ainedit: clean up command line arguments Use enums for long option values, and run dumps in the order they're specified on the command line. Also, --no-strings mode is made the default and a --inline-strings option is added to get the old (broken) behavior. --- src/aindump/aindump.c | 290 ++++++++++++++++++++++-------------------- src/ainedit/ainedit.c | 40 ++++-- 2 files changed, 182 insertions(+), 148 deletions(-) diff --git a/src/aindump/aindump.c b/src/aindump/aindump.c index ad9abe6..3cc15d2 100644 --- a/src/aindump/aindump.c +++ b/src/aindump/aindump.c @@ -74,24 +74,30 @@ static void usage(void) puts("Usage: aindump "); puts(" Display information from AIN files."); puts(""); + puts("Commonly used options:"); puts(" -h, --help Display this message and exit"); puts(" -c, --code Dump code section"); - puts(" -C, --raw-code Dump code section (raw)"); + puts(" -j, --json Dump to JSON format"); puts(" -t, --text Dump strings and messages, sorted by function"); + puts(" -o, --output Set output file path"); + puts(""); + puts("Less used options:"); + puts(" -C, --raw-code Dump code section (raw)"); puts(" -f, --functions Dump functions section"); puts(" -g, --globals Dump globals section"); puts(" -S, --structures Dump structures section"); puts(" -m, --messages Dump messages section"); + puts(" -s, --strings Dump strings section"); puts(" -l, --libraries Dump libraries section"); + puts(" -F, --filenames Dump filenames"); puts(" --function-types Dump function types section"); puts(" --delegates Dump delegate types section"); puts(" --global-group-names Dump global group names section"); - puts(" -F, --filenames Dump filenames"); puts(" -e, --enums Dump enums section"); puts(" -A, --audit Audit AIN file for xsystem4 compatibility"); puts(" -d, --decrypt Dump decrypted AIN file"); - puts(" -j, --json Dump to JSON format"); puts(" --map Dump AIN file map"); + puts(" --inline-strings Dump code in inline-strings mode"); } static void print_sjis(FILE *f, const char *s) @@ -328,6 +334,9 @@ static void ain_dump_strings(FILE *f, struct ain *ain) static void ain_dump_filenames(FILE *f, struct ain *ain) { + if (!ain->FNAM.present) + guess_filenames(ain); + for (int i = 0; i < ain->nr_filenames; i++) { fprintf(f, "0x%08x:\t", i); print_sjis(f, ain->filenames[i]); @@ -437,9 +446,6 @@ static void ain_dump_map(FILE *f, struct ain *ain) print_section(f, "DELG", &ain->DELG); print_section(f, "OBJG", &ain->OBJG); print_section(f, "ENUM", &ain->ENUM); - - fprintf(f, "FNCT_SIZE = %d\n", ain->delg_size); - fprintf(f, "FNCT.SIZE = %d\n", ain->DELG.size); } static void dump_decrypted(FILE *f, const char *path) @@ -457,132 +463,160 @@ static void dump_decrypted(FILE *f, const char *path) free(ain); } +enum { + LOPT_HELP = 256, + LOPT_AIN_VERSION, + LOPT_CODE, + LOPT_RAW_CODE, + LOPT_JSON, + LOPT_TEXT, + LOPT_OUTPUT, + LOPT_FUNCTIONS, + LOPT_GLOBALS, + LOPT_STRUCTURES, + LOPT_MESSAGES, + LOPT_STRINGS, + LOPT_LIBRARIES, + LOPT_FILENAMES, + LOPT_FUNCTION_TYPES, + LOPT_DELEGATES, + LOPT_GLOBAL_GROUPS, + LOPT_ENUMS, + LOPT_AUDIT, + LOPT_DECRYPT, + LOPT_MAP, + LOPT_INLINE_STRINGS, +}; + int main(int argc, char *argv[]) { - bool dump_version = false; - bool dump_code = false; - bool dump_text = false; - bool dump_functions = false; - bool dump_globals = false; - bool dump_structures = false; - bool dump_messages = false; - bool dump_libraries = false; - bool dump_strings = false; - bool dump_filenames = false; - bool dump_functypes = false; - bool dump_delegates = false; - bool dump_global_group_names = false; - bool dump_enums = false; - bool dump_json = false; - bool dump_map = false; - bool audit = false; bool decrypt = false; char *output_file = NULL; FILE *output = stdout; int err = AIN_SUCCESS; - unsigned int flags = 0; + unsigned int flags = DASM_NO_STRINGS; struct ain *ain; + int dump_targets[256]; + int dump_ptr = 0; + while (1) { static struct option long_options[] = { - { "help", no_argument, 0, 'h' }, - { "ain-version", no_argument, 0, 'V' }, - { "code", no_argument, 0, 'c' }, - { "raw-code", no_argument, 0, 'C' }, - { "text", no_argument, 0, 't' }, - { "functions", no_argument, 0, 'f' }, - { "globals", no_argument, 0, 'g' }, - { "structures", no_argument, 0, 'S' }, - { "messages", no_argument, 0, 'm' }, - { "libraries", no_argument, 0, 'l' }, - { "strings", no_argument, 0, 's' }, - { "filenames", no_argument, 0, 'F' }, - { "function-types", no_argument, 0, 'T' }, - { "delegates", no_argument, 0, 'D' }, - { "global-group-names", no_argument, 0, 'r' }, - { "enums", no_argument, 0, 'e' }, - { "audit", no_argument, 0, 'A' }, - { "decrypt", no_argument, 0, 'd' }, - { "json", no_argument, 0, 'j' }, - { "map", no_argument, 0, 'M' }, - { "no-strings", no_argument, 0, 'R' }, - { "output", required_argument, 0, 'o' }, + { "help", no_argument, 0, LOPT_HELP }, + { "code", no_argument, 0, LOPT_CODE }, + { "raw-code", no_argument, 0, LOPT_RAW_CODE }, + { "json", no_argument, 0, LOPT_JSON }, + { "text", no_argument, 0, LOPT_TEXT }, + { "output", required_argument, 0, LOPT_OUTPUT }, + { "ain-version", no_argument, 0, LOPT_AIN_VERSION }, + { "functions", no_argument, 0, LOPT_FUNCTIONS }, + { "globals", no_argument, 0, LOPT_GLOBALS }, + { "structures", no_argument, 0, LOPT_STRUCTURES }, + { "messages", no_argument, 0, LOPT_MESSAGES }, + { "strings", no_argument, 0, LOPT_STRINGS }, + { "libraries", no_argument, 0, LOPT_LIBRARIES }, + { "filenames", no_argument, 0, LOPT_FILENAMES }, + { "function-types", no_argument, 0, LOPT_FUNCTION_TYPES }, + { "delegates", no_argument, 0, LOPT_DELEGATES }, + { "global-group-names", no_argument, 0, LOPT_GLOBAL_GROUPS }, + { "enums", no_argument, 0, LOPT_ENUMS }, + { "audit", no_argument, 0, LOPT_AUDIT }, + { "decrypt", no_argument, 0, LOPT_DECRYPT }, + { "map", no_argument, 0, LOPT_MAP }, + { "inline-strings", no_argument, 0, LOPT_INLINE_STRINGS }, }; int option_index = 0; int c; - c = getopt_long(argc, argv, "hVcCtfgSmlsFeAdjo:", long_options, &option_index); + c = getopt_long(argc, argv, "hcCjto:VfgSmslFeAd", long_options, &option_index); if (c == -1) break; switch (c) { case 'h': + case LOPT_HELP: usage(); return 0; - case 'V': - dump_version = true; - break; case 'c': - dump_code = true; + case LOPT_CODE: + dump_targets[dump_ptr++] = LOPT_CODE; break; case 'C': - dump_code = true; + case LOPT_RAW_CODE: + dump_targets[dump_ptr++] = LOPT_CODE; flags |= DASM_RAW; break; - case 't': - dump_text = true; - break; - case 'f': - dump_functions = true; - break; - case 'g': - dump_globals = true; - break; - case 'S': - dump_structures = true; - break; - case 'm': - dump_messages = true; - break; - case 'l': - dump_libraries = true; - break; - case 's': - dump_strings = true; - break; - case 'F': - dump_filenames = true; - break; - case 'T': - dump_functypes = true; - break; - case 'D': - dump_delegates = true; - break; - case 'G': - dump_global_group_names = true; - break; - case 'e': - dump_enums = true; - break; - case 'A': - audit = true; - break; - case 'd': - decrypt = true; - break; case 'j': - dump_json = true; + case LOPT_JSON: + dump_targets[dump_ptr++] = LOPT_JSON; break; - case 'M': - dump_map = true; - break; - case 'R': - flags |= DASM_NO_STRINGS; + case 't': + case LOPT_TEXT: + dump_targets[dump_ptr++] = LOPT_TEXT; break; case 'o': + case LOPT_OUTPUT: output_file = xstrdup(optarg); break; + case 'V': + case LOPT_AIN_VERSION: + dump_targets[dump_ptr++] = LOPT_AIN_VERSION; + break; + case 'f': + case LOPT_FUNCTIONS: + dump_targets[dump_ptr++] = LOPT_FUNCTIONS; + break; + case 'g': + case LOPT_GLOBALS: + dump_targets[dump_ptr++] = LOPT_GLOBALS; + break; + case 'S': + case LOPT_STRUCTURES: + dump_targets[dump_ptr++] = LOPT_STRUCTURES; + break; + case 'm': + case LOPT_MESSAGES: + dump_targets[dump_ptr++] = LOPT_MESSAGES; + break; + case 's': + case LOPT_STRINGS: + dump_targets[dump_ptr++] = LOPT_STRINGS; + break; + case 'l': + case LOPT_LIBRARIES: + dump_targets[dump_ptr++] = LOPT_LIBRARIES; + break; + case 'F': + case LOPT_FILENAMES: + dump_targets[dump_ptr++] = LOPT_FILENAMES; + break; + case LOPT_FUNCTION_TYPES: + dump_targets[dump_ptr++] = LOPT_FUNCTION_TYPES; + break; + case LOPT_DELEGATES: + dump_targets[dump_ptr++] = LOPT_DELEGATES; + break; + case LOPT_GLOBAL_GROUPS: + dump_targets[dump_ptr++] = LOPT_GLOBAL_GROUPS; + break; + case 'e': + case LOPT_ENUMS: + dump_targets[dump_ptr++] = LOPT_ENUMS; + break; + case 'A': + case LOPT_AUDIT: + dump_targets[dump_ptr++] = LOPT_AUDIT; + break; + case 'd': + case LOPT_DECRYPT: + decrypt = true; + break; + case LOPT_MAP: + dump_targets[dump_ptr++] = LOPT_MAP; + break; + case LOPT_INLINE_STRINGS: + flags &= ~DASM_NO_STRINGS; + break; case '?': ERROR("Unkown command line argument"); } @@ -613,43 +647,27 @@ int main(int argc, char *argv[]) return 1; } - if (dump_version) - ain_dump_version(output, ain); - if (dump_structures) - ain_dump_structures(output, ain); - if (dump_functypes) - ain_dump_functypes(output, ain, false); - if (dump_delegates) - ain_dump_functypes(output, ain, true); - if (dump_global_group_names) - ain_dump_global_group_names(output, ain); - if (dump_globals) - ain_dump_globals(output, ain); - if (dump_libraries) - ain_dump_libraries(output, ain); - if (dump_functions) - ain_dump_functions(output, ain); - if (dump_messages) - ain_dump_messages(output, ain); - if (dump_strings) - ain_dump_strings(output, ain); - if (dump_filenames) { - if (!ain->FNAM.present) - guess_filenames(ain); - ain_dump_filenames(output, ain); + for (int i = 0; i < dump_ptr; i++) { + switch (dump_targets[i]) { + case LOPT_CODE: disassemble_ain(output, ain, flags); break; + case LOPT_JSON: ain_dump_json(output, ain); break; + case LOPT_TEXT: ain_dump_text(output, ain); break; + case LOPT_AIN_VERSION: ain_dump_version(output, ain); break; + case LOPT_FUNCTIONS: ain_dump_functions(output, ain); break; + case LOPT_GLOBALS: ain_dump_globals(output, ain); break; + case LOPT_STRUCTURES: ain_dump_structures(output, ain); break; + case LOPT_MESSAGES: ain_dump_messages(output, ain); break; + case LOPT_STRINGS: ain_dump_strings(output, ain); break; + case LOPT_LIBRARIES: ain_dump_libraries(output, ain); break; + case LOPT_FILENAMES: ain_dump_filenames(output, ain); break; + case LOPT_FUNCTION_TYPES: ain_dump_functypes(output, ain, false); break; + case LOPT_DELEGATES: ain_dump_functypes(output, ain, true); break; + case LOPT_GLOBAL_GROUPS: ain_dump_global_group_names(output, ain); break; + case LOPT_ENUMS: ain_dump_enums(output, ain); break; + case LOPT_AUDIT: ain_audit(output, ain); break; + case LOPT_MAP: ain_dump_map(output, ain); break; + } } - if (dump_enums) - ain_dump_enums(output, ain); - if (dump_code) - disassemble_ain(output, ain, flags); - if (dump_text) - ain_dump_text(output, ain); - if (dump_json) - ain_dump_json(output, ain); - if (dump_map) - ain_dump_map(output, ain); - if (audit) - ain_audit(output, ain); ain_free(ain); return 0; diff --git a/src/ainedit/ainedit.c b/src/ainedit/ainedit.c index 44d6722..32f6693 100644 --- a/src/ainedit/ainedit.c +++ b/src/ainedit/ainedit.c @@ -33,12 +33,22 @@ static void usage(void) puts(" -t, --text Update strings/messages"); puts(" -o, --output Set output file path"); puts(" --raw Read code in raw mode"); - puts(" --no-strings Read code in no-strings mode"); + puts(" --inline-strings Read code in inline-strings mode"); //puts(" -p,--project Build AIN from project file"); } extern int text_parse(void); +enum { + LOPT_HELP = 256, + LOPT_CODE, + LOPT_JSON, + LOPT_TEXT, + LOPT_OUTPUT, + LOPT_RAW, + LOPT_INLINE_STRINGS, +}; + int main(int argc, char *argv[]) { struct ain *ain; @@ -47,16 +57,16 @@ int main(int argc, char *argv[]) const char *decl_file = NULL; const char *text_file = NULL; const char *output_file = NULL; - uint32_t flags = 0; + uint32_t flags = ASM_NO_STRINGS; while (1) { static struct option long_options[] = { - { "help", no_argument, 0, 'h' }, - { "code", required_argument, 0, 'c' }, - { "json", required_argument, 0, 'j' }, - { "text", required_argument, 0, 't' }, - { "output", required_argument, 0, 'o' }, - { "raw", no_argument, 0, 'R' }, - { "no-strings", no_argument, 0, 'N' }, + { "help", no_argument, 0, LOPT_HELP }, + { "code", required_argument, 0, LOPT_CODE }, + { "json", required_argument, 0, LOPT_JSON }, + { "text", required_argument, 0, LOPT_TEXT }, + { "output", required_argument, 0, LOPT_OUTPUT }, + { "raw", no_argument, 0, LOPT_RAW }, + { "inline-strings", no_argument, 0, LOPT_INLINE_STRINGS }, }; int option_index = 0; int c; @@ -67,25 +77,31 @@ int main(int argc, char *argv[]) switch (c) { case 'h': + case LOPT_HELP: usage(); return 0; case 'c': + case LOPT_CODE: code_file = optarg; break; case 'j': + case LOPT_JSON: decl_file = optarg; break; case 't': + case LOPT_TEXT: text_file = optarg; break; case 'o': + case LOPT_OUTPUT: output_file = optarg; break; - case 'R': + case LOPT_RAW: flags |= ASM_RAW; break; - case 'N': - flags |= ASM_NO_STRINGS; + case LOPT_INLINE_STRINGS: + WARNING("Inline strings mode doesn't quite work yet..."); + flags &= ~ASM_NO_STRINGS; break; case '?': ERROR("Unknown command line argument");