diff --git a/CMakeLists.txt b/CMakeLists.txt index f794962..2940725 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,8 +61,15 @@ if(SJ4_BUILD_TOOLS OR (NOT CMAKE_BINARY_DIR MATCHES CMAKE_CURRENT_SOURCE_DIR AND endif() if(NOT SJ4_GLOBAL) - file(GLOB_RECURSE SJ4TEST_SRCS src/sj4test/**.c) - add_executable(sj4test ${SJ4TEST_SRCS}) + macro(sj4_test name) + file(GLOB_RECURSE ${name}_SRCS src/${name}/**.c) + add_executable(${name} ${${name}_SRCS}) + endmacro() + + sj4_test(sj4test) target_link_libraries(sj4test PRIVATE sj4lib) + + sj4_test(sj4test2) + target_link_libraries(sj4test2 PRIVATE sj4ime) endif() endif() diff --git a/include/sj4charset/sj_charset.h b/include/sj4charset/sj4charset.h similarity index 92% rename from include/sj4charset/sj_charset.h rename to include/sj4charset/sj4charset.h index 31d6eeb..9a44080 100644 --- a/include/sj4charset/sj_charset.h +++ b/include/sj4charset/sj4charset.h @@ -1,5 +1,5 @@ -#ifndef __SJ_CHARSET_H__ -#define __SJ_CHARSET_H__ +#ifndef __SJ4CHARSET_H__ +#define __SJ4CHARSET_H__ #include diff --git a/include/sj4ime/sj4ime.h b/include/sj4ime/sj4ime.h index b85c8e1..0dc9783 100644 --- a/include/sj4ime/sj4ime.h +++ b/include/sj4ime/sj4ime.h @@ -1,6 +1,8 @@ #ifndef __SJ4IME_H__ #define __SJ4IME_H__ +#include + #ifdef __cplusplus extern "C" { #endif @@ -8,6 +10,7 @@ extern "C" { typedef struct sj4ime Sj4Ime; Sj4Ime* sj4_ime(int charset, const char* dict); +void sj4_ime_key(Sj4Ime* ime, int key); #ifdef __cplusplus } diff --git a/include/sj4lib/sj4lib.h b/include/sj4lib/sj4lib.h index 13398f0..1475ed0 100644 --- a/include/sj4lib/sj4lib.h +++ b/include/sj4lib/sj4lib.h @@ -1,7 +1,7 @@ #ifndef __SJ4LIB_H__ #define __SJ4LIB_H__ -#include +#include #include /* increase this as needed... */ diff --git a/lib/sj4charset/conv.c b/lib/sj4charset/conv.c index 67e4f6e..b53498b 100644 --- a/lib/sj4charset/conv.c +++ b/lib/sj4charset/conv.c @@ -1,4 +1,4 @@ -#include "sj_charset.h" +#include "sj4charset.h" #include "sj_euc2ucs.h" #include "sj_ucs2euc.h" diff --git a/lib/sj4ime/KanaTable b/lib/sj4ime/KanaTable index 1ff9e9c..8498305 100644 --- a/lib/sj4ime/KanaTable +++ b/lib/sj4ime/KanaTable @@ -215,7 +215,6 @@ {"QU", "\244\257\244\245", ""}, {"QE", "\244\257\244\247", ""}, {"QO", "\244\257\244\251", ""}, -{"N", "\244\363", ""}, {"NN", "\244\363", ""}, {"KK", "\244\303", "K"}, {"SS", "\244\303", "S"}, diff --git a/lib/sj4ime/ime.c b/lib/sj4ime/ime.c index 96d64ed..6daa10e 100644 --- a/lib/sj4ime/ime.c +++ b/lib/sj4ime/ime.c @@ -1,11 +1,31 @@ #include #include +#include +#include +#include +#include #include +#include struct sj4ime { Sj4Lib* lib; + int charset; + + Sj4Kouho kouho; + unsigned int last; + + u_char romabuf[SJ4BUFSZ]; + u_char kanabuf[SJ4BUFSZ]; +}; + +static struct sj4table { + const char* roma; + u_char* kana; + const char* roma2; +} kanatbl[] = { +#include "KanaTable" }; Sj4Ime* sj4_ime(int charset, const char* dict) { @@ -18,4 +38,110 @@ Sj4Ime* sj4_ime(int charset, const char* dict) { return NULL; } + + ime->charset = charset; +} + +static int w_len(wchar_t* wc) { + int i; + + for(i = 0; wc[i] != 0; i++); + + return i; +} + +static int b_len(int charset, Sj4KouhoBuffer* buffer) { + if(charset == SJ4UTF16) { + return w_len(buffer->utf16); + } else { + return strlen(buffer->raw); + } +} + +static void concat(int charset, u_char* out, u_char* in) { + int i; + +#ifdef UCS + if(charset == SJ4UTF16) { + wchar_t* w_out = (wchar_t*)out; + + i = w_len(w_out); + + w_out[i + sj4_charset_to(charset, (u_char*)(w_out + i), in, strlen(in))] = 0; + } else +#else + { + i = strlen(out); + + out[i + sj4_charset_to(charset, out + i, in, strlen(in))] = 0; + } +#endif +} + +static void comp(Sj4Ime* ime) { + ime->kanabuf[0] = 0; + ime->last = 0; +} + +#define ZEROBUF memset(&ime->kouho.buffer, 0, sizeof(ime->kouho.buffer)) + +void sj4_ime_key(Sj4Ime* ime, int key) { + if(key == '\n') { + comp(ime); + + ZEROBUF; + } else if(key == ' ') { + reconvert: + if((ime->last = b_len(ime->charset, &ime->kouho.buffer)) == 0) { + sj4_getkan(ime->lib, ime->kanabuf, strlen(ime->kanabuf), &ime->kouho); + } else { + if((ime->last = sj4_nextkan(ime->lib)) == 0) { + ZEROBUF; + + goto reconvert; + } + } + + printf("%s\n", ime->kouho.buffer.utf8); + } else if('a' <= tolower(key) && tolower(key) <= 'z') { + int i; + + if(ime->last != 0) comp(ime); + + key = toupper(key); + + if(ime->romabuf[strlen(ime->romabuf) - 1] == 'N' && !(key == 'A' || key == 'I' || key == 'U' || key == 'E' || key == 'O' || key == 'N')) { + ime->romabuf[strlen(ime->romabuf) + 1] = 0; + ime->romabuf[strlen(ime->romabuf)] = 'N'; + } + + ime->romabuf[strlen(ime->romabuf) + 1] = 0; + ime->romabuf[strlen(ime->romabuf)] = key; + + reduce: + for(i = 0; i < sizeof(kanatbl) / sizeof(kanatbl[0]); i++) { + int n = strlen(kanatbl[i].roma); + + if(n > strlen(ime->romabuf)) continue; + + if(memcmp(ime->romabuf, kanatbl[i].roma, n) == 0) { + int j; + + n = strlen(kanatbl[i].roma) - strlen(kanatbl[i].roma2); + + memmove(ime->romabuf - (n < 0 ? n : 0), ime->romabuf + (n > 0 ? n : 0), SJ4BUFSZ - n); + if(n > 0) { + for(j = SJ4BUFSZ - n; j < SJ4BUFSZ; j++) ime->romabuf[j] = 0; + } else { + for(j = 0; j < -n; j++) ime->romabuf[j] = 0; + } + + memcpy(ime->romabuf, kanatbl[i].roma2, strlen(kanatbl[i].roma2)); + + concat(ime->charset, ime->kanabuf, kanatbl[i].kana); + + goto reduce; + } + } + } } diff --git a/lib/sj4lib/sj.c b/lib/sj4lib/sj.c index 02cad21..cd80f3e 100644 --- a/lib/sj4lib/sj.c +++ b/lib/sj4lib/sj.c @@ -2,7 +2,7 @@ #include #include -#include +#include #include diff --git a/src/sj4mkdic/char.c b/src/sj4mkdic/char.c index e8f4582..6e50f54 100644 --- a/src/sj4mkdic/char.c +++ b/src/sj4mkdic/char.c @@ -38,7 +38,7 @@ #include "sj4mkdic.h" -#include "sj_charset.h" +#include "sj4charset.h" int cnvyomi(int code) { u_short hh; diff --git a/src/sj4mkdic/readline.c b/src/sj4mkdic/readline.c index 7af19d0..1ba0bc5 100644 --- a/src/sj4mkdic/readline.c +++ b/src/sj4mkdic/readline.c @@ -154,8 +154,6 @@ skip_blank() { return c; } -#include "sj_charset.h" - static int readhinsi() { static int c = 0; diff --git a/src/sj4test2/main.c b/src/sj4test2/main.c new file mode 100644 index 0000000..cf36ac1 --- /dev/null +++ b/src/sj4test2/main.c @@ -0,0 +1,22 @@ +#include +#include + +#ifdef _WIN32 +#define CHARSET SJ4SJIS +#else +#define CHARSET SJ4UTF8 +#endif + +int main() { + Sj4Ime* ime = sj4_ime(CHARSET, "sj4main.dic"); + char b; + + if(ime == NULL) { + fprintf(stderr, "Failed to create context\n"); + return 1; + } + + while(fread(&b, 1, sizeof(b), stdin)) { + sj4_ime_key(ime, b); + } +}