ainedit: add --transcode option

Add option to change text encoding of an ain file. E.g.

    ainedit --transcode GBK//TRANSLIT -o out.ain in.ain
This commit is contained in:
Nunuhara Cabbage
2020-02-29 15:07:01 -08:00
parent b7c12b1ce0
commit 2be530b65f
4 changed files with 134 additions and 0 deletions
+15
View File
@@ -34,6 +34,7 @@ static void usage(void)
puts(" -c, --code <jam-file> Update the CODE section (assemble .jam file)");
puts(" -j, --json <json-file> Update AIN file from JSON data");
puts(" -t, --text <text-file> Update strings/messages");
puts(" --transcode <enc> Change the AIN file's text encoding");
puts(" -o, --output <path> Set output file path");
puts(" --raw Read code in raw mode");
puts(" --inline-strings Read code in inline-strings mode");
@@ -49,6 +50,7 @@ enum {
LOPT_CODE,
LOPT_JSON,
LOPT_TEXT,
LOPT_TRANSCODE,
LOPT_OUTPUT,
LOPT_RAW,
LOPT_INLINE_STRINGS,
@@ -78,6 +80,7 @@ int main(int argc, char *argv[])
const char *output_file = NULL;
const char *input_encoding = "UTF-8";
const char *output_encoding = "SJIS-WIN";
bool transcode = false;
uint32_t flags = ASM_NO_STRINGS;
while (1) {
static struct option long_options[] = {
@@ -85,6 +88,7 @@ int main(int argc, char *argv[])
{ "code", required_argument, 0, LOPT_CODE },
{ "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 },
{ "inline-strings", no_argument, 0, LOPT_INLINE_STRINGS },
@@ -115,6 +119,11 @@ int main(int argc, char *argv[])
case LOPT_TEXT:
text_file = optarg;
break;
case LOPT_TRANSCODE:
transcode = true;
input_encoding = "SJIS-WIN";
output_encoding = optarg;
break;
case 'o':
case LOPT_OUTPUT:
output_file = optarg;
@@ -160,6 +169,11 @@ int main(int argc, char *argv[])
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);
}
@@ -172,6 +186,7 @@ int main(int argc, char *argv[])
read_text(text_file, ain);
}
write_ain_file:
NOTICE("Writing AIN file...");
ain_write(output_file, ain);
+3
View File
@@ -57,6 +57,9 @@ void ain_write(const char *filename, struct ain *ain);
// text.c
void read_text(const char *filename, struct ain *ain);
// transcode.c
void ain_transcode(struct ain *ain);
char *encode_text(const char *str);
#endif /* AINEDIT_AINEDIT_H */
+1
View File
@@ -6,6 +6,7 @@ ainedit = ['../../cJSON.c',
'json.c',
'repack.c',
'text.c',
'transcode.c',
]
if flex.found()
+115
View File
@@ -0,0 +1,115 @@
/* Copyright (C) 2019 Nunuhara Cabbage <nunuhara@haniwa.technology>
*
* 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 <http://gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <string.h>
#include "system4.h"
#include "system4/string.h"
#include "ainedit.h"
static char *transcode_cstr(char *str)
{
if (!str)
return NULL;
char *r = encode_text(str);
free(str);
return r;
}
static struct string *transcode_string(struct string *str)
{
char *tmp = encode_text(str->text);
struct string *r = make_string(tmp, strlen(tmp));
free(tmp);
free_string(str);
return r;
}
static void transcode_variable(struct ain_variable *v)
{
v->name = transcode_cstr(v->name);
v->name2 = transcode_cstr(v->name2);
if (v->has_initval && v->type.data == AIN_STRING)
v->initval.s = transcode_cstr(v->initval.s);
}
void ain_transcode(struct ain *ain)
{
for (int i = 0; i < ain->nr_functions; i++) {
struct ain_function *f = &ain->functions[i];
f->name = transcode_cstr(f->name);
for (int i = 0; i < f->nr_vars; i++) {
transcode_variable(&f->vars[i]);
}
}
for (int i = 0; i < ain->nr_globals; i++) {
transcode_variable(&ain->globals[i]);
}
for (int i = 0; i < ain->nr_initvals; i++) {
struct ain_initval *v = &ain->global_initvals[i];
if (v->data_type == AIN_STRING) {
v->string_value = ain->globals[v->global_index].initval.s;
}
}
for (int i = 0; i < ain->nr_structures; i++) {
struct ain_struct *s = &ain->structures[i];
s->name = transcode_cstr(s->name);
for (int i = 0; i < s->nr_members; i++) {
transcode_variable(&s->members[i]);
}
}
for (int i = 0; i < ain->nr_messages; i++) {
ain->messages[i] = transcode_string(ain->messages[i]);
}
for (int i = 0; i < ain->nr_strings; i++) {
ain->strings[i] = transcode_string(ain->strings[i]);
}
for (int i = 0; i < ain->nr_filenames; i++) {
ain->filenames[i] = transcode_cstr(ain->filenames[i]);
}
for (int i = 0; i < ain->nr_function_types; i++) {
struct ain_function_type *f = &ain->function_types[i];
f->name = transcode_cstr(f->name);
for (int i = 0; i < f->nr_variables; i++) {
transcode_variable(&f->variables[i]);
}
}
for (int i = 0; i < ain->nr_delegates; i++) {
struct ain_function_type *f = &ain->delegates[i];
f->name = transcode_cstr(f->name);
for (int i = 0; i < f->nr_variables; i++) {
transcode_variable(&f->variables[i]);
}
}
for (int i = 0; i < ain->nr_global_groups; i++) {
ain->global_group_names[i] = transcode_cstr(ain->global_group_names[i]);
}
for (int i = 0; i < ain->nr_enums; i++) {
struct ain_enum *e = &ain->enums[i];
e->name = transcode_cstr(e->name);
// NOTE: symbols don't matter
}
}