/* Copyright (C) 2019 Nunuhara Cabbage * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #include #include #include #include #include #include #include #include "ainedit.h" #include "system4.h" #include "system4/ain.h" #include "jaf.h" static void usage(void) { puts("Usage: ainedit [options...] input-file"); puts(" Edit AIN files."); puts(""); puts(" -h, --help Display this message and exit"); puts(" -p, --project Build AIN from project file"); puts(" -c, --code Update the CODE section (assemble .jam file)"); puts(" --jaf Update AIN file from JAF source code"); puts(" -j, --json Update AIN file from JSON data"); puts(" -t, --text Update strings/messages"); puts(" --transcode Change the AIN file's text encoding"); puts(" -o, --output Set output file path"); puts(" --raw Read code in raw mode"); puts(" --input-encoding Specify the text encoding of the input file(s) (default: UTF-8)"); puts(" --output-encoding Specify the text encoding of the output file (default: CP932)"); puts(" --ain-encoding Specify the text encoding of the input AIN file"); puts(" --ain-version Specify the AIN version (when creating a new AIN file)"); puts(" --silent Don't write messages to stdout"); } extern int text_parse(void); enum { LOPT_HELP = 256, LOPT_PROJECT, LOPT_CODE, LOPT_JAF, LOPT_JSON, LOPT_TEXT, LOPT_TRANSCODE, LOPT_OUTPUT, LOPT_RAW, LOPT_INPUT_ENCODING, LOPT_OUTPUT_ENCODING, LOPT_AIN_ENCODING, LOPT_AIN_VERSION, LOPT_SILENT, }; iconv_t ain_conv; iconv_t print_conv; iconv_t ain_input_conv; char *convert_text(iconv_t cd, const char *str); // encode text for AIN file char *encode_text(const char *str) { return convert_text(ain_conv, str); } char *encode_text_to_input_format(char *str) { return convert_text(ain_input_conv, str); } char *encode_text_for_print(char *str) { return convert_text(print_conv, str); } int main(int argc, char *argv[]) { initialize_instructions(); struct ain *ain; int err = AIN_SUCCESS; const char *project_file = NULL; const char *code_file = NULL; unsigned nr_jaf_files = 0; const char **jaf_files = NULL; const char *decl_file = NULL; const char *text_file = NULL; const char *output_file = NULL; const char *input_encoding = "UTF-8"; const char *output_encoding = "CP932"; const char *ain_encoding = "CP932"; int ain_version = 4; bool transcode = false; uint32_t flags = 0; while (1) { static struct option long_options[] = { { "help", no_argument, 0, LOPT_HELP }, { "project", required_argument, 0, LOPT_PROJECT }, { "code", required_argument, 0, LOPT_CODE }, { "jaf", required_argument, 0, LOPT_JAF }, { "json", required_argument, 0, LOPT_JSON }, { "text", required_argument, 0, LOPT_TEXT }, { "transcode", required_argument, 0, LOPT_TRANSCODE }, { "output", required_argument, 0, LOPT_OUTPUT }, { "raw", no_argument, 0, LOPT_RAW }, { "input-encoding", required_argument, 0, LOPT_INPUT_ENCODING }, { "output-encoding", required_argument, 0, LOPT_OUTPUT_ENCODING }, { "ain-encoding", required_argument, 0, LOPT_AIN_ENCODING }, { "ain-version", required_argument, 0, LOPT_AIN_VERSION }, { "silent", no_argument, 0, LOPT_SILENT }, }; int option_index = 0; int c; c = getopt_long(argc, argv, "hp:c:j:t:o:", long_options, &option_index); if (c == -1) break; switch (c) { case 'h': case LOPT_HELP: usage(); return 0; case 'p': case LOPT_PROJECT: project_file = optarg; break; case 'c': case LOPT_CODE: code_file = optarg; break; case LOPT_JAF: jaf_files = xrealloc_array(jaf_files, nr_jaf_files, nr_jaf_files+1, sizeof(char*)); jaf_files[nr_jaf_files++] = optarg; break; case 'j': case LOPT_JSON: decl_file = optarg; break; case 't': case LOPT_TEXT: text_file = optarg; break; case LOPT_TRANSCODE: transcode = true; input_encoding = "CP932"; output_encoding = optarg; break; case 'o': case LOPT_OUTPUT: output_file = optarg; break; case LOPT_RAW: flags |= ASM_RAW; break; case LOPT_INPUT_ENCODING: input_encoding = optarg; break; case LOPT_OUTPUT_ENCODING: output_encoding = optarg; break; case LOPT_AIN_ENCODING: ain_encoding = optarg; break; case LOPT_AIN_VERSION: ain_version = atoi(optarg); if (ain_version < 4 || ain_version > 12) ERROR("Invalid AIN version (4-12 supported)"); break; case LOPT_SILENT: sys_silent = true; break; case '?': ERROR("Unknown command line argument"); } } argc -= optind; argv += optind; if (argc > 1) { usage(); ERROR("Too many arguments."); } if ((ain_conv = iconv_open(output_encoding, input_encoding)) == (iconv_t)-1) { ERROR("iconv_open: %s", strerror(errno)); } if ((print_conv = iconv_open("UTF-8", input_encoding)) == (iconv_t)-1) { ERROR("iconv_open: %s", strerror(errno)); } if ((ain_input_conv = iconv_open(ain_encoding, input_encoding)) == (iconv_t)-1) { ERROR("iconv_open: %s", strerror(errno)); } if (project_file) { pje_build(project_file, ain_version); return 0; } if (!output_file) { output_file = "out.ain"; } if (!argc) { ain = ain_new(ain_version); } else { if (!(ain = ain_open(argv[0], &err))) { ERROR("Failed to open ain file: %s", ain_strerror(err)); } } if (transcode) { ain_transcode(ain); goto write_ain_file; } if (decl_file) { read_declarations(decl_file, ain); } if (jaf_files) { jaf_build(ain, jaf_files, nr_jaf_files); } if (code_file) { asm_assemble_jam(code_file, ain, flags); } if (text_file) { read_text(text_file, ain); } write_ain_file: NOTICE("Writing AIN file..."); ain_write(output_file, ain); free(jaf_files); ain_free(ain); return 0; }