mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-10-01 11:28:01 +03:00
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.
This commit is contained in:
+154
-136
@@ -74,24 +74,30 @@ static void usage(void)
|
||||
puts("Usage: aindump <options> <ainfile>");
|
||||
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;
|
||||
|
||||
+28
-12
@@ -33,12 +33,22 @@ static void usage(void)
|
||||
puts(" -t, --text <text-file> Update strings/messages");
|
||||
puts(" -o, --output <path> 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 <pje-file> 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");
|
||||
|
||||
Reference in New Issue
Block a user