1
This commit is contained in:
Alex Yatskov 2016-11-19 12:23:06 -08:00
parent 29164873f4
commit 11bc97492f
10 changed files with 216 additions and 108 deletions

View File

@ -2,5 +2,5 @@ cmake_minimum_required(VERSION 3.5)
project(zero-epwing) project(zero-epwing)
include_directories(eb) include_directories(eb)
link_directories(eb/eb/.libs jansson/lib) link_directories(eb/eb/.libs jansson/lib)
add_executable(zero-epwing main.c util.c convert.c hooks.c) add_executable(zero-epwing main.c util.c gaiji.c convert.c hooks.c)
target_link_libraries(zero-epwing libeb.a libz.a libjansson.a) target_link_libraries(zero-epwing libeb.a libz.a libjansson.a)

View File

@ -22,7 +22,11 @@
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
/* Reference: https://stackoverflow.com/questions/2162390/iconv-encoding-conversion-problem */ /*
* Local functions
*/
/* https://stackoverflow.com/questions/2162390/iconv-encoding-conversion-problem */
static char * convert (const char *from_charset, const char *to_charset, const char *input) { static char * convert (const char *from_charset, const char *to_charset, const char *input) {
size_t inleft, outleft, converted = 0; size_t inleft, outleft, converted = 0;
@ -109,6 +113,10 @@ static char * convert (const char *from_charset, const char *to_charset, const c
return output; return output;
} }
/*
* Exported functions
*/
char* eucjp_to_utf8(const char src[]) { char* eucjp_to_utf8(const char src[]) {
return convert("EUC-JP", "UTF-8", src); return convert("EUC-JP", "UTF-8", src);
} }

View File

@ -19,6 +19,10 @@
#ifndef CONVERT_H #ifndef CONVERT_H
#define CONVERT_H #define CONVERT_H
/*
* Functions
*/
char* eucjp_to_utf8(const char src[]); char* eucjp_to_utf8(const char src[]);
#endif #endif /* CONVERT_H */

43
gaiji.c Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
* Author: Alex Yatskov <alex@foosoft.net>
*
* 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 3 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://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "eb/eb/eb.h"
#include "eb/eb/text.h"
#include "gaiji.h"
/*
* Exported functions
*/
void gaiji_build_stub(char text[MAX_STUB_BYTES], int code, const Gaiji_context* context, Gaiji_width width) {
sprintf(text, "!!!");
(void)code;
(void)text;
(void)context;
(void)width;
}
void gaiji_fixup_stub(char output[], int size, const char input[], const Gaiji_context* context) {
(void)output;
(void)size;
(void)input;
(void)context;
}

55
gaiji.h Normal file
View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2016 Alex Yatskov <alex@foosoft.net>
* Author: Alex Yatskov <alex@foosoft.net>
*
* 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 3 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://www.gnu.org/licenses/>.
*/
#ifndef GAIJI_H
#define GAIJI_H
/*
* Constants
*/
#define MAX_STUB_BYTES 9
/*
* Types
*/
typedef struct {
int code;
int bytes;
char stub[MAX_STUB_BYTES];
} Gaiji_entry;
typedef struct {
Gaiji_entry* table;
int count;
} Gaiji_context;
typedef enum {
GAIJI_WIDTH_WIDE,
GAIJI_WIDTH_NARROW,
} Gaiji_width;
/*
* Functions
*/
void gaiji_build_stub(char text[MAX_STUB_BYTES], int code, const Gaiji_context* context, Gaiji_width width);
void gaiji_fixup_stub(char output[], int size, const char input[], const Gaiji_context* context);
#endif /* GAIJI_H */

70
hooks.c
View File

@ -16,12 +16,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <assert.h>
#include "hooks.h" #include "hooks.h"
#include "gaiji.h"
#include "eb/eb/eb.h" #include "eb/eb/eb.h"
#include "eb/eb/text.h" #include "eb/eb/text.h"
/* /*
* Boilerplate * Macros
*/ */
#define HOOK_FUNC_NAME(NAME) hook_##NAME #define HOOK_FUNC_NAME(NAME) hook_##NAME
@ -44,10 +48,8 @@
return 0;\ return 0;\
} }
#define MAX_REPLACEMENT 64
/* /*
* Basic tag printers * Tag printers
*/ */
HOOK_TAGGER(begin_candidate); /* EB_HOOK_BEGIN_CANDIDATE */ HOOK_TAGGER(begin_candidate); /* EB_HOOK_BEGIN_CANDIDATE */
@ -92,7 +94,7 @@ HOOK_TAGGER(wide_jisx0208); /* EB_HOOK_WIDE_JISX0208 */
HOOK_TAGGER(null); /* EB_HOOK_NULL */ HOOK_TAGGER(null); /* EB_HOOK_NULL */
/* /*
* Gaiji processing * Local functions
*/ */
static EB_Error_Code hook_narrow_font( /* EB_HOOK_NARROW_FONT */ static EB_Error_Code hook_narrow_font( /* EB_HOOK_NARROW_FONT */
@ -103,30 +105,14 @@ static EB_Error_Code hook_narrow_font( /* EB_HOOK_NARROW_FONT */
int argc, int argc,
const unsigned int argv[] const unsigned int argv[]
) { ) {
(void)book; assert(argc > 0);
(void)appendix; (void)appendix;
(void)container;
(void)code; (void)code;
(void)argc;
(void)argv;
/* char replacement[MAX_REPLACEMENT] = "?"; */ char stub[MAX_STUB_BYTES];
gaiji_build_stub(stub, argv[0], container, GAIJI_WIDTH_NARROW);
/* /1* Check if there is a UTF-8 replacement for this gaiji code *1/ */ eb_write_text_string(book, stub);
/* if(get_gaiji_replacment_elem(subbook_directory, 'n', (unsigned short)argv[0]) != NULL) */
/* { */
/* sprintf(replacement, "{#n%04X}", argv[0]); */
/* } */
/* else if(gaiji_option == GAIJI_OPTION_HTML_IMG) /1* Add HTML IMG tag *1/ */
/* { */
/* get_character_html_img(replacement, book, SAVE_BMP, SAVE_NARROW, argv[0]); */
/* } */
/* else */
/* { */
/* sprintf(replacement, "?"); */
/* } */
/* eb_write_text_string(book, replacement); */
return 0; return 0;
} }
@ -139,36 +125,20 @@ static EB_Error_Code hook_wide_font( /* EB_HOOK_WIDE_FONT */
int argc, int argc,
const unsigned int argv[] const unsigned int argv[]
) { ) {
(void)book; assert(argc > 0);
(void)appendix; (void)appendix;
(void)container;
(void)code; (void)code;
(void)argc;
(void)argv;
/* char replacement[MAXLEN_PATH] = ""; */ char stub[MAX_STUB_BYTES];
gaiji_build_stub(stub, argv[0], container, GAIJI_WIDTH_WIDE);
/* /1* Check if there is a UTF-8 replacement for this gaiji code *1/ */ eb_write_text_string(book, stub);
/* if(get_gaiji_replacment_elem(subbook_directory, 'w', (unsigned short)argv[0]) != NULL) */
/* { */
/* sprintf(replacement, "{#w%04X}", argv[0]); */
/* } */
/* else if(gaiji_option == GAIJI_OPTION_HTML_IMG) /1* Add HTML IMG tag *1/ */
/* { */
/* get_character_html_img(replacement, book, SAVE_BMP, SAVE_WIDE, argv[0]); */
/* } */
/* else */
/* { */
/* sprintf(replacement, "?"); */
/* } */
/* eb_write_text_string(book, replacement); */
return 0; return 0;
} }
/* /*
* Hook table * Local data
*/ */
static const EB_Hook s_hooks[] = { static const EB_Hook s_hooks[] = {
@ -207,11 +177,11 @@ static const EB_Hook s_hooks[] = {
{ EB_HOOK_END_WAVE, HOOK_FUNC_NAME(end_wave) }, { EB_HOOK_END_WAVE, HOOK_FUNC_NAME(end_wave) },
{ EB_HOOK_GB2312, HOOK_FUNC_NAME(gb2312) }, { EB_HOOK_GB2312, HOOK_FUNC_NAME(gb2312) },
{ EB_HOOK_ISO8859_1, HOOK_FUNC_NAME(iso8859_1) }, { EB_HOOK_ISO8859_1, HOOK_FUNC_NAME(iso8859_1) },
/* { EB_HOOK_NARROW_FONT, HOOK_FUNC_NAME(narrow_font) }, */ { EB_HOOK_NARROW_FONT, HOOK_FUNC_NAME(narrow_font) },
/* { EB_HOOK_NARROW_JISX0208, HOOK_FUNC_NAME(narrow_jisx0208) }, */ /* { EB_HOOK_NARROW_JISX0208, HOOK_FUNC_NAME(narrow_jisx0208) }, */
{ EB_HOOK_NEWLINE, HOOK_FUNC_NAME(newline) }, { EB_HOOK_NEWLINE, HOOK_FUNC_NAME(newline) },
{ EB_HOOK_SET_INDENT, HOOK_FUNC_NAME(set_indent) }, { EB_HOOK_SET_INDENT, HOOK_FUNC_NAME(set_indent) },
/* { EB_HOOK_WIDE_FONT, HOOK_FUNC_NAME(wide_font) }, */ { EB_HOOK_WIDE_FONT, HOOK_FUNC_NAME(wide_font) },
/* { EB_HOOK_WIDE_JISX0208, HOOK_FUNC_NAME(wide_jisx0208) }, */ /* { EB_HOOK_WIDE_JISX0208, HOOK_FUNC_NAME(wide_jisx0208) }, */
{ EB_HOOK_NULL, HOOK_FUNC_NAME(null) }, { EB_HOOK_NULL, HOOK_FUNC_NAME(null) },
}; };

View File

@ -21,6 +21,10 @@
#include "eb/eb/eb.h" #include "eb/eb/eb.h"
/*
* Exported functions
*/
void hooks_install(EB_Hookset* hookset); void hooks_install(EB_Hookset* hookset);
#endif #endif /* HOOKS_H */

16
main.c
View File

@ -16,10 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdio.h>
#include <string.h> #include <string.h>
#include <getopt.h> #include <getopt.h>
#include <stdbool.h>
#include "convert.h" #include "convert.h"
#include "util.h" #include "util.h"
@ -29,9 +27,17 @@
#include "eb/text.h" #include "eb/text.h"
#include "eb/eb/error.h" #include "eb/eb/error.h"
/*
* Constants
*/
#define MAX_HITS 256 #define MAX_HITS 256
static void export_subbook_entries(EB_Book* eb_book, Subbook* subbook) { /*
* Local functions
*/
static void export_subbook_entries(EB_Book* eb_book, EB_Hookset* eb_hookset, Subbook* subbook) {
if (subbook->entry_cap == 0) { if (subbook->entry_cap == 0) {
subbook->entry_cap = 16384; subbook->entry_cap = 16384;
subbook->entries = malloc(subbook->entry_cap * sizeof(Entry)); subbook->entries = malloc(subbook->entry_cap * sizeof(Entry));
@ -169,6 +175,10 @@ static void export_book(const char path[], Book* book) {
while(0); while(0);
} }
/*
* Entry point
*/
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
bool pretty_print = false; bool pretty_print = false;

96
util.c
View File

@ -29,8 +29,62 @@
#include "jansson/include/jansson.h" #include "jansson/include/jansson.h"
/*
* Constants
*/
#define MAX_TEXT 1024 #define MAX_TEXT 1024
/*
* Local functions
*/
static void encode_entry(Entry* entry, json_t* entry_json) {
json_object_set_new(entry_json, "heading", json_string(entry->heading));
json_object_set_new(entry_json, "text", json_string(entry->text));
}
static void encode_subbook(Subbook* subbook, json_t* subbook_json) {
if (subbook->title != NULL) {
json_object_set_new(subbook_json, "title", json_string(subbook->title));
}
if (subbook->copyright != NULL) {
json_object_set_new(subbook_json, "copyright", json_string(subbook->copyright));
}
json_t* entry_json_array = json_array();
for (int i = 0; i < subbook->entry_count; ++i) {
json_t* entry_json = json_object();
encode_entry(subbook->entries + i, entry_json);
json_array_append(entry_json_array, entry_json);
json_decref(entry_json);
}
json_object_set(subbook_json, "entries", entry_json_array);
json_decref(entry_json_array);
}
static void encode_book(Book* book, json_t* book_json) {
json_object_set_new(book_json, "characterCode", json_string(book->character_code));
json_object_set_new(book_json, "discCode", json_string(book->disc_code));
json_t* subbook_json_array = json_array();
for (int i = 0; i < book->subbook_count; ++i) {
json_t* subbook_json = json_object();
encode_subbook(book->subbooks + i, subbook_json);
json_array_append(subbook_json_array, subbook_json);
json_decref(subbook_json);
}
json_object_set(book_json, "subbooks", subbook_json_array);
json_decref(subbook_json_array);
}
/*
* Exported functions
*/
char* read_book_data(EB_Book* book, EB_Hookset* hookset, const EB_Position* position, ReadMode mode) { char* read_book_data(EB_Book* book, EB_Hookset* hookset, const EB_Position* position, ReadMode mode) {
if (eb_seek_text(book, position) != EB_SUCCESS) { if (eb_seek_text(book, position) != EB_SUCCESS) {
return NULL; return NULL;
@ -86,48 +140,6 @@ void free_book(Book* book) {
} }
} }
static void encode_entry(Entry* entry, json_t* entry_json) {
json_object_set_new(entry_json, "heading", json_string(entry->heading));
json_object_set_new(entry_json, "text", json_string(entry->text));
}
static void encode_subbook(Subbook* subbook, json_t* subbook_json) {
if (subbook->title != NULL) {
json_object_set_new(subbook_json, "title", json_string(subbook->title));
}
if (subbook->copyright != NULL) {
json_object_set_new(subbook_json, "copyright", json_string(subbook->copyright));
}
json_t* entry_json_array = json_array();
for (int i = 0; i < subbook->entry_count; ++i) {
json_t* entry_json = json_object();
encode_entry(subbook->entries + i, entry_json);
json_array_append(entry_json_array, entry_json);
json_decref(entry_json);
}
json_object_set(subbook_json, "entries", entry_json_array);
json_decref(entry_json_array);
}
static void encode_book(Book* book, json_t* book_json) {
json_object_set_new(book_json, "characterCode", json_string(book->character_code));
json_object_set_new(book_json, "discCode", json_string(book->disc_code));
json_t* subbook_json_array = json_array();
for (int i = 0; i < book->subbook_count; ++i) {
json_t* subbook_json = json_object();
encode_subbook(book->subbooks + i, subbook_json);
json_array_append(subbook_json_array, subbook_json);
json_decref(subbook_json);
}
json_object_set(book_json, "subbooks", subbook_json_array);
json_decref(subbook_json_array);
}
void dump_book(Book* book, bool pretty_print, FILE* fp) { void dump_book(Book* book, bool pretty_print, FILE* fp) {
json_t* book_json = json_object(); json_t* book_json = json_object();
encode_book(book, book_json); encode_book(book, book_json);

18
util.h
View File

@ -26,11 +26,15 @@
#include "eb/eb/eb.h" #include "eb/eb/eb.h"
/* /*
Dictionary structures * Constants
*/ */
#define MAX_ERROR 256 #define MAX_ERROR 256
/*
* Types
*/
typedef struct { typedef struct {
char* heading; char* heading;
char* text; char* text;
@ -58,19 +62,17 @@ typedef struct {
int subbook_count; int subbook_count;
} Book; } Book;
/*
Book helpers
*/
typedef enum { typedef enum {
READ_MODE_TEXT, READ_MODE_TEXT,
READ_MODE_HEADING, READ_MODE_HEADING,
} ReadMode; } ReadMode;
char* read_book_data(EB_Book* book, EB_Hookset* hookset, const EB_Position* position, ReadMode mode); /*
* Functions
*/
char* read_book_data(EB_Book* book, EB_Hookset* hookset, const EB_Position* position, ReadMode mode);
void free_book(Book* book); void free_book(Book* book);
void dump_book(Book* book, bool pretty_print, FILE* fp); void dump_book(Book* book, bool pretty_print, FILE* fp);
#endif /* UTIL_H */
#endif