diff --git a/include/chewingio.h b/include/chewingio.h index de231cf99..eb880a24b 100644 --- a/include/chewingio.h +++ b/include/chewingio.h @@ -545,6 +545,9 @@ CHEWING_API int chewing_get_phoneSeqLen(const ChewingContext *ctx); CHEWING_API void chewing_set_logger(ChewingContext *ctx, void (*logger) (void *data, int level, const char *fmt, ...), void *data); +CHEWING_API void chewing_set_logger_without_varglist(ChewingContext *ctx, + void (*logger2) (void *data, int level, const char *msg), void *data); + CHEWING_API int chewing_userphrase_enumerate(ChewingContext *ctx); CHEWING_API int chewing_userphrase_has_next(ChewingContext *ctx, unsigned int *phrase_len, unsigned int *bopomofo_len); diff --git a/src/chewingio.c b/src/chewingio.c index 5e6c285a6..6a58f5ad1 100644 --- a/src/chewingio.c +++ b/src/chewingio.c @@ -138,6 +138,29 @@ static void chooseCandidate(ChewingContext *ctx, int toSelect, int key_buf_curso } } +typedef struct { + void (*logger) (void *data, int level, const char *msg); + void *data; +} Data4NoVarArgListLogger; + +static void Logger4NoVarArgList(void *data, int level, const char *fmt, ...) +{ + Data4NoVarArgListLogger *all_data = (Data4NoVarArgListLogger*)data; + char *msg; + int sz; + va_list vl; + + va_start(vl, fmt); + sz = vsnprintf(NULL, 0, fmt, vl); + if (sz > 0) { + msg = ALC(char, sz + 1); + vsnprintf(msg, sz + 1, fmt, vl); + all_data->logger(all_data->data, level, msg); + free(msg); + } + va_end(vl); +} + static void NullLogger(void *data UNUSED, int level UNUSED, const char *fmt UNUSED, ...) { } @@ -394,6 +417,8 @@ CHEWING_API void chewing_delete(ChewingContext *ctx) TerminateUserphrase(ctx->data); TerminateTree(ctx->data); TerminateDict(ctx->data); + if (ctx->data->logger == Logger4NoVarArgList) + free(ctx->data->loggerData); free(ctx->data); } @@ -1876,6 +1901,9 @@ CHEWING_API void chewing_set_logger(ChewingContext *ctx, LOG_API(""); + if (ctx->data->logger == Logger4NoVarArgList) + free(ctx->data->loggerData); + if (!logger) { logger = NullLogger; data = 0; @@ -1884,6 +1912,36 @@ CHEWING_API void chewing_set_logger(ChewingContext *ctx, ctx->data->loggerData = data; } +CHEWING_API void chewing_set_logger_without_varglist(ChewingContext *ctx, + void (*logger2) (void *data, int level, const char *msg), void *data2) +{ + ChewingData *pgdata; + void (*logger) (void *data, int level, const char *fmt, ...) = NullLogger; + void *data = 0; + + if (!ctx) { + return; + } + pgdata = ctx->data; + + LOG_API(""); + + if (ctx->data->logger == Logger4NoVarArgList) + free(ctx->data->loggerData); + + if (logger2) { + Data4NoVarArgListLogger *all_data; + + logger = Logger4NoVarArgList; + all_data = ALC(Data4NoVarArgListLogger, 1); + all_data->logger = logger2; + all_data->data = data2; + data = all_data; + } + ctx->data->logger = logger; + ctx->data->loggerData = data; +} + CHEWING_API int chewing_userphrase_enumerate(ChewingContext *ctx) { ChewingData *pgdata; diff --git a/test/test-logger.c b/test/test-logger.c index 45b34fd41..e0235d9d6 100644 --- a/test/test-logger.c +++ b/test/test-logger.c @@ -32,6 +32,9 @@ void test_set_null_logger() chewing_set_logger(ctx, NULL, 0); type_keystroke_by_string(ctx, "hk4g4"); + chewing_set_logger_without_varglist(ctx, NULL, 0); + type_keystroke_by_string(ctx, "hk4g4"); + chewing_delete(ctx); }