From 4f5463b88498f8be2c949d7c42ded094ca97f957 Mon Sep 17 00:00:00 2001 From: Nishi Date: Sun, 5 Jul 2026 04:25:55 +0900 Subject: [PATCH] Add sj4_ime_length --- include/sj4ime/sj4ime.h | 13 +++++- include/sj4lib/sj4lib.h | 3 ++ lib/sj4ime/ime.c | 89 ++++++++++++++++++++++++++++++++--------- lib/sj4lib/sj.c | 11 ++++- src/sj4test2/main.c | 36 ++++++++++++++++- 5 files changed, 129 insertions(+), 23 deletions(-) diff --git a/include/sj4ime/sj4ime.h b/include/sj4ime/sj4ime.h index 11d24ca..5daf175 100644 --- a/include/sj4ime/sj4ime.h +++ b/include/sj4ime/sj4ime.h @@ -9,8 +9,19 @@ extern "C" { typedef struct sj4ime Sj4Ime; -Sj4Ime* sj4_ime(int charset, const char* dict); +typedef void (*Sj4ImePacket)(Sj4Ime* ime, int type, void* data); + +enum SJ4IMEPACKET { + Sj4ImeBeginKanList = 0, + Sj4ImeKanEntry, + Sj4ImeEndKanList +}; + +Sj4Ime* sj4_ime(int charset, const char* dict, Sj4ImePacket packet); void sj4_ime_key(Sj4Ime* ime, int key); +int sj4_ime_length(Sj4Ime* ime); +void* sj4_ime_kouho(Sj4Ime* ime); +void* sj4_ime_kanabuf(Sj4Ime* ime); void* sj4_ime_convbuf(Sj4Ime* ime); #ifdef __cplusplus diff --git a/include/sj4lib/sj4lib.h b/include/sj4lib/sj4lib.h index 62c71ff..4a5b5db 100644 --- a/include/sj4lib/sj4lib.h +++ b/include/sj4lib/sj4lib.h @@ -24,6 +24,8 @@ typedef union sj4kouhobuffer { typedef struct sj4kouho { Sj4KouhoBuffer buffer; + int take; + unsigned char intbuf[SJ4BUFSZ]; } Sj4Kouho; @@ -32,6 +34,7 @@ typedef struct sj4lib Sj4Lib; Sj4Lib* sj4_open(int, const char*); int sj4_getkan(Sj4Lib*, const void*, int len, Sj4Kouho*); int sj4_nextkan(Sj4Lib*); +int sj4_prevkan(Sj4Lib*); void sj4_close(Sj4Lib*); #ifdef __cplusplus diff --git a/lib/sj4ime/ime.c b/lib/sj4ime/ime.c index 066b5f8..395ab6c 100644 --- a/lib/sj4ime/ime.c +++ b/lib/sj4ime/ime.c @@ -13,10 +13,12 @@ struct sj4ime { Sj4Lib* lib; int charset; - Sj4Kouho kouho; - unsigned int last; + Sj4ImePacket packet; - u_char romabuf[7]; + Sj4Kouho kouho; + unsigned int length; + + char romabuf[7]; u_char kanabuf[SJ4BUFSZ]; u_char convbuf[SJ4BUFSZ]; }; @@ -29,7 +31,12 @@ static struct sj4table { #include "KanaTable" }; -Sj4Ime* sj4_ime(int charset, const char* dict) { +#define DISPATCH(x, y) \ + if(ime->packet != NULL) { \ + ime->packet(ime, (x), (y)); \ + } + +Sj4Ime* sj4_ime(int charset, const char* dict, Sj4ImePacket packet) { Sj4Ime* ime; if((ime = calloc(1, sizeof(*ime))) == NULL) return NULL; @@ -41,6 +48,8 @@ Sj4Ime* sj4_ime(int charset, const char* dict) { } ime->charset = charset; + + ime->packet = packet; } static int w_len(wchar_t* wc) { @@ -51,11 +60,11 @@ static int w_len(wchar_t* wc) { return i; } -static int b_len(int charset, Sj4KouhoBuffer* buffer) { +static int b_len(int charset, u_char* buffer) { if(charset == SJ4UTF16) { - return w_len(buffer->utf16); + return w_len((wchar_t*)buffer); } else { - return strlen(buffer->raw); + return strlen(buffer); } } @@ -106,27 +115,50 @@ static void concat_nc(int charset, u_char* out, u_char* in) { #define ZEROBUF memset(&ime->kouho.buffer, 0, sizeof(ime->kouho.buffer)) static void comp(Sj4Ime* ime) { - if(ime->last == 0) { +#if 0 + do { +#endif + if(ime->length == 0) { concat_nc(ime->charset, ime->convbuf, ime->kanabuf); - } else { - concat_nc(ime->charset, ime->convbuf, ime->kouho.buffer.raw); - } - printf("%s\n", ime->convbuf); - ime->kanabuf[0] = 0; - ime->last = 0; +#ifdef UCS + memset(ime->kanabuf, 0, sizeof(wchar_t)); +#else + ime->kanabuf[0] = 0; +#endif + } else { + int sc = ime->charset == SJ4UTF16 ? sizeof(wchar_t) : 1; + + concat_nc(ime->charset, ime->convbuf, ime->kouho.buffer.raw); + + memmove(ime->kanabuf, ime->kanabuf + ime->length * sc, SJ4BUFSZ - ime->length * sc); + memset(ime->kanabuf + SJ4BUFSZ - ime->length * sc, 0, ime->length * sc); + } + + ime->length = 0; ZEROBUF; +#if 0 + } while(b_len(ime->charset, ime->kanabuf) > 0); +#endif } void sj4_ime_key(Sj4Ime* ime, int key) { if(key == '\n') { comp(ime); } else if(key == ' ') { - reconvert: - if(b_len(ime->charset, &ime->kouho.buffer) == 0) { - ime->last = sj4_getkan(ime->lib, ime->kanabuf, strlen(ime->kanabuf), &ime->kouho); + reconvert:; + if(b_len(ime->charset, ime->kouho.buffer.raw) == 0) { + ime->length = sj4_getkan(ime->lib, ime->kanabuf, strlen(ime->kanabuf), &ime->kouho); + + DISPATCH(Sj4ImeBeginKanList, NULL); + do { + DISPATCH(Sj4ImeKanEntry, &ime->kouho); + } while(sj4_nextkan(ime->lib) != 0); + DISPATCH(Sj4ImeEndKanList, NULL); + + ime->length = sj4_getkan(ime->lib, ime->kanabuf, strlen(ime->kanabuf), &ime->kouho); } else { - if((ime->last = sj4_nextkan(ime->lib)) == 0) { + if((ime->length = sj4_nextkan(ime->lib)) == 0) { ZEROBUF; goto reconvert; @@ -135,7 +167,7 @@ void sj4_ime_key(Sj4Ime* ime, int key) { } else if(('a' <= tolower(key) && tolower(key) <= 'z') || key == '~' || key == ',' || key == '.' || key == '[' || key == ']') { int i; - if(ime->last != 0) comp(ime); + if(ime->length != 0) comp(ime); key = toupper(key); @@ -176,9 +208,28 @@ void sj4_ime_key(Sj4Ime* ime, int key) { if(strlen(ime->romabuf) >= 4) { ime->romabuf[0] = 0; } + } else { + char keys[2]; + + keys[0] = key; + keys[1] = 0; + + concat(ime->charset, ime->kanabuf, keys); } } +int sj4_ime_length(Sj4Ime* ime) { + return ime->length; +} + +void* sj4_ime_kouho(Sj4Ime* ime) { + return ime->kouho.buffer.raw; +} + +void* sj4_ime_kanabuf(Sj4Ime* ime) { + return ime->kanabuf; +} + void* sj4_ime_convbuf(Sj4Ime* ime) { return ime->convbuf; } diff --git a/lib/sj4lib/sj.c b/lib/sj4lib/sj.c index b9b9540..e652af5 100644 --- a/lib/sj4lib/sj.c +++ b/lib/sj4lib/sj.c @@ -40,8 +40,9 @@ Sj4Lib* sj4_open(int charset, const char* dic) { #define RUNME(PROC) \ PROC \ + ctx->kouho->take = len; \ \ - len2 = sj4_charset_to(ctx->charset, ctx->kouho->buffer.raw, ctx->kouho->intbuf + sizeof(STDYOUT), strlen(ctx->kouho->intbuf + sizeof(STDYOUT))); \ + len2 = sj4_charset_to(ctx->charset, ctx->kouho->buffer.raw, ctx->kouho->intbuf + sizeof(STDYOUT), strlen(ctx->kouho->intbuf + sizeof(STDYOUT))); \ \ memcpy(ctx->wrkbuf, ctx->inbuf, len); \ len = sj4_charset_to(ctx->charset, ctx->wrk2buf, ctx->wrkbuf, len); \ @@ -81,6 +82,14 @@ int sj4_nextkan(Sj4Lib* ctx) { }); } +int sj4_prevkan(Sj4Lib* ctx) { + int len, len2; + + RUNME({ + len = prevcl(ctx->ctx, ctx->kouho->intbuf, 0); + }); +} + void sj4_close(Sj4Lib* ctx) { free_context(ctx->ctx); free(ctx); diff --git a/src/sj4test2/main.c b/src/sj4test2/main.c index cf36ac1..730db3e 100644 --- a/src/sj4test2/main.c +++ b/src/sj4test2/main.c @@ -5,18 +5,50 @@ #define CHARSET SJ4SJIS #else #define CHARSET SJ4UTF8 + +#include + +#define getch getchar #endif +static void ime_packet(Sj4Ime* ime, int type, void* data) { + printf("%d %p\n", type, data); +} + int main() { - Sj4Ime* ime = sj4_ime(CHARSET, "sj4main.dic"); + Sj4Ime* ime = sj4_ime(CHARSET, "sj4main.dic", ime_packet); char b; + char* conv = sj4_ime_convbuf(ime); + char* kouho = sj4_ime_kouho(ime); if(ime == NULL) { fprintf(stderr, "Failed to create context\n"); return 1; } - while(fread(&b, 1, sizeof(b), stdin)) { +#ifdef _WIN32 +#else + { + struct termios new; + tcgetattr(0, &new); + new.c_lflag &= ~(ICANON | ECHO); + tcsetattr(0, TCSANOW, &new); + } +#endif + + while((b = getch()) != EOF) { sj4_ime_key(ime, b); + + if(conv[0]) { + printf("[%s]\n", conv); + + conv[0] = 0; + } else if(kouho[0]) { + printf("<%s>", kouho); + } + + if(b != '\n' && b != '\n') { + putchar(b); + } } }