Kouhei Sutou
null+****@clear*****
Fri Jun 22 10:00:28 JST 2018
Kouhei Sutou 2018-06-22 10:00:28 +0900 (Fri, 22 Jun 2018) New Revision: de6e9acfe803601d277637896a56a07c9f78ffe6 https://github.com/groonga/groonga/commit/de6e9acfe803601d277637896a56a07c9f78ffe6 Message: windows: support install path that has non-ascii characters again Modified files: lib/ctx_impl_mrb.c lib/mrb.c lib/mrb/mrb_ctx.c lib/mrb/mrb_database.c lib/mrb/mrb_logger.c lib/mrb/mrb_object.c lib/mrb/mrb_query_logger.c lib/mrb/scripts/command_line/grndb.rb lib/plugin.c src/grndb.c Modified: lib/ctx_impl_mrb.c (+22 -4) =================================================================== --- lib/ctx_impl_mrb.c 2018-06-22 09:57:34 +0900 (362877b25) +++ lib/ctx_impl_mrb.c 2018-06-22 10:00:28 +0900 (3b734a0fa) @@ -23,6 +23,7 @@ #ifdef GRN_WITH_MRUBY # include "grn_ctx_impl_mrb.h" +# include "grn_encoding.h" # include "grn_mrb.h" # include "mrb/mrb_converter.h" # include "mrb/mrb_error.h" @@ -98,11 +99,14 @@ static mrb_value mrb_kernel_load(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; - char *path; + char *utf8_path; + const char *path; - mrb_get_args(mrb, "z", &path); + mrb_get_args(mrb, "z", &utf8_path); + path = grn_encoding_convert_to_locale_from_utf8(ctx, utf8_path, -1, NULL); grn_mrb_load(ctx, path); + grn_encoding_converted_free(ctx, path); if (mrb->exc) { mrb_exc_raise(mrb, mrb_obj_value(mrb->exc)); } @@ -126,15 +130,29 @@ mrb_groonga_init(mrb_state *mrb, mrb_value self) { mrb_value load_path; const char *plugins_dir; + const char *utf8_plugins_dir; const char *system_ruby_scripts_dir; + const char *utf8_system_ruby_scripts_dir; load_path = mrb_ary_new(mrb); + plugins_dir = grn_plugin_get_system_plugins_dir(); + utf8_plugins_dir = + grn_encoding_convert_to_utf8_from_locale(ctx, plugins_dir, -1, NULL); mrb_ary_push(mrb, load_path, - mrb_str_new_cstr(mrb, plugins_dir)); + mrb_str_new_cstr(mrb, utf8_plugins_dir)); + grn_encoding_converted_free(ctx, utf8_plugins_dir); + system_ruby_scripts_dir = grn_mrb_get_system_ruby_scripts_dir(ctx); + utf8_system_ruby_scripts_dir = + grn_encoding_convert_to_utf8_from_locale(ctx, + system_ruby_scripts_dir, + -1, + NULL); mrb_ary_push(mrb, load_path, - mrb_str_new_cstr(mrb, system_ruby_scripts_dir)); + mrb_str_new_cstr(mrb, utf8_system_ruby_scripts_dir)); + grn_encoding_converted_free(ctx, utf8_system_ruby_scripts_dir); + mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$LOAD_PATH"), load_path); } Modified: lib/mrb.c (+27 -4) =================================================================== --- lib/mrb.c 2018-06-22 09:57:34 +0900 (6c332163d) +++ lib/mrb.c 2018-06-22 10:00:28 +0900 (f2b0bab84) @@ -18,6 +18,7 @@ #include "grn_mrb.h" #include "grn_ctx_impl.h" +#include "grn_encoding.h" #include "grn_util.h" #include <string.h> @@ -124,7 +125,8 @@ grn_mrb_expand_script_path(grn_ctx *ctx, const char *path, { const char *ruby_scripts_dir; char dir_last_char; - int path_length, max_path_length; + int path_length; + int max_path_length; if (grn_mrb_is_absolute_path(path)) { expanded_path[0] = '\0'; @@ -144,10 +146,17 @@ grn_mrb_expand_script_path(grn_ctx *ctx, const char *path, path_length = strlen(path); max_path_length = PATH_MAX - strlen(expanded_path) - 1; if (path_length > max_path_length) { + const char *grn_encoding_path; + grn_encoding_path = + grn_encoding_convert_from_locale(ctx, + path, + path_length, + NULL); ERR(GRN_INVALID_ARGUMENT, "script path is too long: %d (max: %d) <%s%s>", path_length, max_path_length, - expanded_path, path); + expanded_path, grn_encoding_path); + grn_encoding_converted_free(ctx, grn_encoding_path); return GRN_FALSE; } @@ -197,9 +206,14 @@ grn_mrb_load(grn_ctx *ctx, const char *path) file = grn_fopen(expanded_path, "r"); if (!file) { + const char *grn_encoding_expanded_path; mrb_value exception; + + grn_encoding_expanded_path = + grn_encoding_convert_from_locale(ctx, expanded_path, -1, NULL); SERR("fopen: failed to open mruby script file: <%s>", - expanded_path); + grn_encoding_expanded_path); + grn_encoding_converted_free(ctx, grn_encoding_expanded_path); exception = mrb_exc_new(mrb, E_LOAD_ERROR, ctx->errbuf, strlen(ctx->errbuf)); mrb->exc = mrb_obj_ptr(exception); @@ -218,7 +232,16 @@ grn_mrb_load(grn_ctx *ctx, const char *path) } parser = mrb_parser_new(mrb); - mrb_parser_set_filename(parser, expanded_path); + { + const char *utf8_expanded_path; + utf8_expanded_path = + grn_encoding_convert_to_utf8_from_locale(ctx, + expanded_path, + -1, + NULL); + mrb_parser_set_filename(parser, utf8_expanded_path); + grn_encoding_converted_free(ctx, utf8_expanded_path); + } parser->s = parser->send = NULL; parser->f = file; mrb_parser_parse(parser, NULL); Modified: lib/mrb/mrb_ctx.c (+114 -90) =================================================================== --- lib/mrb/mrb_ctx.c 2018-06-22 09:57:34 +0900 (e4d9eed65) +++ lib/mrb/mrb_ctx.c 2018-06-22 10:00:28 +0900 (2546801ec) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013-2016 Brazil + Copyright(C) 2013-2018 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,7 @@ #include <mruby/variable.h> #include <mruby/string.h> +#include "../grn_encoding.h" #include "../grn_mrb.h" #include "mrb_ctx.h" #include "mrb_bulk.h" @@ -184,22 +185,36 @@ static mrb_value ctx_get_error_message(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; + const char *utf8_message; + mrb_value mrb_message; - return mrb_str_new_cstr(mrb, ctx->errbuf); + utf8_message = grn_encoding_convert_to_utf8(ctx, ctx->errbuf, -1, NULL); + mrb_message = mrb_str_new_cstr(mrb, utf8_message); + grn_encoding_converted_free(ctx, utf8_message); + + return mrb_message; } static mrb_value ctx_set_error_message(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; - mrb_value error_message; - - mrb_get_args(mrb, "S", &error_message); + mrb_value mrb_error_message; + const char *error_message; + size_t error_message_size; + + mrb_get_args(mrb, "S", &mrb_error_message); + error_message = + grn_encoding_convert_from_utf8(ctx, + RSTRING_PTR(mrb_error_message), + RSTRING_LEN(mrb_error_message), + &error_message_size); grn_ctx_log(ctx, "%.*s", - (int)RSTRING_LEN(error_message), - RSTRING_PTR(error_message)); + (int)error_message_size, + error_message); + grn_encoding_converted_free(ctx, error_message); - return error_message; + return mrb_error_message; } static mrb_value @@ -282,491 +297,498 @@ grn_mrb_ctx_check(mrb_state *mrb) struct RClass *error_class = NULL; #define MESSAGE_SIZE 4096 char message[MESSAGE_SIZE]; + const char *utf8_error_message; + + if (ctx->rc == GRN_SUCCESS) { + return; + } + + utf8_error_message = grn_encoding_convert_to_utf8(ctx, ctx->errbuf, -1, NULL); switch (ctx->rc) { case GRN_SUCCESS: - return; + break; case GRN_END_OF_DATA: error_class = mrb_class_get_under(mrb, module, "EndOfData"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "end of data: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_UNKNOWN_ERROR: error_class = mrb_class_get_under(mrb, module, "UnknownError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "unknown error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_OPERATION_NOT_PERMITTED: error_class = mrb_class_get_under(mrb, module, "OperationNotPermitted"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "operation not permitted: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NO_SUCH_FILE_OR_DIRECTORY: error_class = mrb_class_get_under(mrb, module, "NoSuchFileOrDirectory"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "no such file or directory: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NO_SUCH_PROCESS: error_class = mrb_class_get_under(mrb, module, "NoSuchProcess"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "no such process: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_INTERRUPTED_FUNCTION_CALL: error_class = mrb_class_get_under(mrb, module, "InterruptedFunctionCall"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "interrupted function call: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_INPUT_OUTPUT_ERROR: error_class = mrb_class_get_under(mrb, module, "InputOutputError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "input output error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NO_SUCH_DEVICE_OR_ADDRESS: error_class = mrb_class_get_under(mrb, module, "NoSuchDeviceOrAddress"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "no such device or address: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_ARG_LIST_TOO_LONG: error_class = mrb_class_get_under(mrb, module, "ArgListTooLong"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "arg list too long: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_EXEC_FORMAT_ERROR: error_class = mrb_class_get_under(mrb, module, "ExecFormatError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "exec format error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_BAD_FILE_DESCRIPTOR: error_class = mrb_class_get_under(mrb, module, "BadFileDescriptor"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "bad file descriptor: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NO_CHILD_PROCESSES: error_class = mrb_class_get_under(mrb, module, "NoChildProcesses"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "no child processes: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_RESOURCE_TEMPORARILY_UNAVAILABLE: error_class = mrb_class_get_under(mrb, module, "ResourceTemporarilyUnavailable"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "resource temporarily unavailable: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NOT_ENOUGH_SPACE: error_class = mrb_class_get_under(mrb, module, "NotEnoughSpace"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "not enough space: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_PERMISSION_DENIED: error_class = mrb_class_get_under(mrb, module, "PermissionDenied"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "permission denied: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_BAD_ADDRESS: error_class = mrb_class_get_under(mrb, module, "BadAddress"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "bad address: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_RESOURCE_BUSY: error_class = mrb_class_get_under(mrb, module, "ResourceBusy"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "resource busy: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_FILE_EXISTS: error_class = mrb_class_get_under(mrb, module, "FileExists"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "file exists: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_IMPROPER_LINK: error_class = mrb_class_get_under(mrb, module, "ImproperLink"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "improper link: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NO_SUCH_DEVICE: error_class = mrb_class_get_under(mrb, module, "NoSuchDevice"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "no such device: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NOT_A_DIRECTORY: error_class = mrb_class_get_under(mrb, module, "NotDirectory"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "not directory: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_IS_A_DIRECTORY: error_class = mrb_class_get_under(mrb, module, "IsDirectory"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "is directory: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_INVALID_ARGUMENT: error_class = mrb_class_get_under(mrb, module, "InvalidArgument"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "invalid argument: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_TOO_MANY_OPEN_FILES_IN_SYSTEM: error_class = mrb_class_get_under(mrb, module, "TooManyOpenFilesInSystem"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "too many open files in system: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_TOO_MANY_OPEN_FILES: error_class = mrb_class_get_under(mrb, module, "TooManyOpenFiles"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "too many open files: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_INAPPROPRIATE_I_O_CONTROL_OPERATION: error_class = mrb_class_get_under(mrb, module, "InappropriateIOControlOperation"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "inappropriate IO control operation: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_FILE_TOO_LARGE: error_class = mrb_class_get_under(mrb, module, "FileTooLarge"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "file too large: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NO_SPACE_LEFT_ON_DEVICE: error_class = mrb_class_get_under(mrb, module, "NoSpaceLeftOnDevice"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "no space left on device: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_INVALID_SEEK: error_class = mrb_class_get_under(mrb, module, "InvalidSeek"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "invalid seek: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_READ_ONLY_FILE_SYSTEM: error_class = mrb_class_get_under(mrb, module, "ReadOnlyFileSystem"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "read only file system: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_TOO_MANY_LINKS: error_class = mrb_class_get_under(mrb, module, "TooManyLinks"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "too many links: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_BROKEN_PIPE: error_class = mrb_class_get_under(mrb, module, "BrokenPipe"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "broken pipe: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_DOMAIN_ERROR: error_class = mrb_class_get_under(mrb, module, "DomainError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "domain error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_RESULT_TOO_LARGE: error_class = mrb_class_get_under(mrb, module, "ResultTooLarge"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "result too large: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_RESOURCE_DEADLOCK_AVOIDED: error_class = mrb_class_get_under(mrb, module, "ResourceDeadlockAvoided"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "resource deadlock avoided: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NO_MEMORY_AVAILABLE: error_class = mrb_class_get_under(mrb, module, "NoMemoryAvailable"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "no memory available: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_FILENAME_TOO_LONG: error_class = mrb_class_get_under(mrb, module, "FilenameTooLong"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "filename too long: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NO_LOCKS_AVAILABLE: error_class = mrb_class_get_under(mrb, module, "NoLocksAvailable"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "no locks available: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_FUNCTION_NOT_IMPLEMENTED: error_class = mrb_class_get_under(mrb, module, "FunctionNotImplemented"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "function not implemented: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_DIRECTORY_NOT_EMPTY: error_class = mrb_class_get_under(mrb, module, "DirectoryNotEmpty"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "directory not empty: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_ILLEGAL_BYTE_SEQUENCE: error_class = mrb_class_get_under(mrb, module, "IllegalByteSequence"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "illegal byte sequence: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_SOCKET_NOT_INITIALIZED: error_class = mrb_class_get_under(mrb, module, "SocketNotInitialized"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "socket not initialized: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_OPERATION_WOULD_BLOCK: error_class = mrb_class_get_under(mrb, module, "OperationWouldBlock"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "operation would block: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_ADDRESS_IS_NOT_AVAILABLE: error_class = mrb_class_get_under(mrb, module, "AddressIsNotAvailable"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "address is not available: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NETWORK_IS_DOWN: error_class = mrb_class_get_under(mrb, module, "NetworkIsDown"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "network is down: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NO_BUFFER: error_class = mrb_class_get_under(mrb, module, "NoBuffer"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "no buffer: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_SOCKET_IS_ALREADY_CONNECTED: error_class = mrb_class_get_under(mrb, module, "SocketIsAlreadyConnected"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "socket is already connected: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_SOCKET_IS_NOT_CONNECTED: error_class = mrb_class_get_under(mrb, module, "SocketIsNotConnected"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "socket is not connected: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_SOCKET_IS_ALREADY_SHUTDOWNED: error_class = mrb_class_get_under(mrb, module, "SocketIsAlreadyShutdowned"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "socket is already shutdowned: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_OPERATION_TIMEOUT: error_class = mrb_class_get_under(mrb, module, "OperationTimeout"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "operation timeout: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_CONNECTION_REFUSED: error_class = mrb_class_get_under(mrb, module, "ConnectionRefused"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "connection refused: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_RANGE_ERROR: error_class = mrb_class_get_under(mrb, module, "RangeError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "range error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_TOKENIZER_ERROR: error_class = mrb_class_get_under(mrb, module, "TokenizerError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "tokenizer error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_FILE_CORRUPT: error_class = mrb_class_get_under(mrb, module, "FileCorrupt"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "file corrupt: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_INVALID_FORMAT: error_class = mrb_class_get_under(mrb, module, "InvalidFormat"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "invalid format: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_OBJECT_CORRUPT: error_class = mrb_class_get_under(mrb, module, "ObjectCorrupt"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "object corrupt: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_TOO_MANY_SYMBOLIC_LINKS: error_class = mrb_class_get_under(mrb, module, "TooManySymbolicLinks"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "too many symbolic links: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NOT_SOCKET: error_class = mrb_class_get_under(mrb, module, "NotSocket"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "not socket: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_OPERATION_NOT_SUPPORTED: error_class = mrb_class_get_under(mrb, module, "OperationNotSupported"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "operation not supported: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_ADDRESS_IS_IN_USE: error_class = mrb_class_get_under(mrb, module, "AddressIsInUse"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "address is in use: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_ZLIB_ERROR: error_class = mrb_class_get_under(mrb, module, "ZlibError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "zlib error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_LZ4_ERROR: error_class = mrb_class_get_under(mrb, module, "LZ4Error"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "LZ4 error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_STACK_OVER_FLOW: error_class = mrb_class_get_under(mrb, module, "StackOverFlow"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "stack over flow: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_SYNTAX_ERROR: error_class = mrb_class_get_under(mrb, module, "SyntaxError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "syntax error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_RETRY_MAX: error_class = mrb_class_get_under(mrb, module, "RetryMax"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "retry max: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_INCOMPATIBLE_FILE_FORMAT: error_class = mrb_class_get_under(mrb, module, "IncompatibleFileFormat"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "incompatible file format: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_UPDATE_NOT_ALLOWED: error_class = mrb_class_get_under(mrb, module, "UpdateNotAllowed"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "update not allowed: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_TOO_SMALL_OFFSET: error_class = mrb_class_get_under(mrb, module, "TooSmallOffset"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "too small offset: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_TOO_LARGE_OFFSET: error_class = mrb_class_get_under(mrb, module, "TooLargeOffset"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "too large offset: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_TOO_SMALL_LIMIT: error_class = mrb_class_get_under(mrb, module, "TooSmallLimit"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "too small limit: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_CAS_ERROR: error_class = mrb_class_get_under(mrb, module, "CASError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "CAS error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_UNSUPPORTED_COMMAND_VERSION: error_class = mrb_class_get_under(mrb, module, "UnsupportedCommandVersion"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "unsupported command version: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_NORMALIZER_ERROR: error_class = mrb_class_get_under(mrb, module, "NormalizerError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "normalizer error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_TOKEN_FILTER_ERROR: error_class = mrb_class_get_under(mrb, module, "TokenFilterError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "token filter error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_COMMAND_ERROR: error_class = mrb_class_get_under(mrb, module, "CommandError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "command error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_PLUGIN_ERROR: error_class = mrb_class_get_under(mrb, module, "PluginError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "plugin error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_SCORER_ERROR: error_class = mrb_class_get_under(mrb, module, "ScorerError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "scorer error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_CANCEL: error_class = mrb_class_get_under(mrb, module, "Cancel"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "cancel: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_WINDOW_FUNCTION_ERROR: error_class = mrb_class_get_under(mrb, module, "WindowFunctionError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "window function error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; case GRN_ZSTD_ERROR: error_class = mrb_class_get_under(mrb, module, "ZstdError"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "Zstandard error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); break; } @@ -774,8 +796,10 @@ grn_mrb_ctx_check(mrb_state *mrb) error_class = mrb_class_get_under(mrb, module, "Error"); grn_snprintf(message, MESSAGE_SIZE, MESSAGE_SIZE, "unsupported error: <%s>(%d)", - ctx->errbuf, ctx->rc); + utf8_error_message, ctx->rc); } + + grn_encoding_converted_free(ctx, utf8_error_message); #undef MESSAGE_SIZE mrb_raise(mrb, error_class, message); Modified: lib/mrb/mrb_database.c (+13 -5) =================================================================== --- lib/mrb/mrb_database.c 2018-06-22 09:57:34 +0900 (e6e035138) +++ lib/mrb/mrb_database.c 2018-06-22 10:00:28 +0900 (330655511) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2014-2015 Brazil + Copyright(C) 2014-2018 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -27,6 +27,8 @@ #include "mrb_database.h" #include "mrb_converter.h" +#include "../grn_encoding.h" + static struct mrb_data_type mrb_grn_database_type = { "Groonga::Database", NULL @@ -48,11 +50,14 @@ mrb_grn_database_class_open(mrb_state *mrb, mrb_value klass) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *database; - char *path; + char *utf8_path; + const char *path; - mrb_get_args(mrb, "z", &path); + mrb_get_args(mrb, "z", &utf8_path); + path = grn_encoding_convert_to_locale_from_utf8(ctx, utf8_path, -1, NULL); database = grn_db_open(ctx, path); + grn_encoding_converted_free(ctx, path); grn_mrb_ctx_check(mrb); return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, database)); @@ -63,11 +68,14 @@ mrb_grn_database_class_create(mrb_state *mrb, mrb_value klass) { grn_ctx *ctx = (grn_ctx *)mrb->ud; grn_obj *database; - char *path; + char *utf8_path; + const char *path; - mrb_get_args(mrb, "z", &path); + mrb_get_args(mrb, "z", &utf8_path); + path = grn_encoding_convert_to_locale_from_utf8(ctx, utf8_path, -1, NULL); database = grn_db_create(ctx, path, NULL); + grn_encoding_converted_free(ctx, path); grn_mrb_ctx_check(mrb); return mrb_funcall(mrb, klass, "new", 1, mrb_cptr_value(mrb, database)); Modified: lib/mrb/mrb_logger.c (+27 -6) =================================================================== --- lib/mrb/mrb_logger.c 2018-06-22 09:57:34 +0900 (fcdaee3a4) +++ lib/mrb/mrb_logger.c 2018-06-22 10:00:28 +0900 (8cb4ef297) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2014-2017 Brazil + Copyright(C) 2014-2018 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -28,10 +28,22 @@ #include "../grn_mrb.h" #include "mrb_logger.h" +#include "../grn_encoding.h" + static mrb_value logger_s_get_default_path(mrb_state *mrb, mrb_value self) { - return mrb_str_new_cstr(mrb, grn_default_logger_get_path()); + grn_ctx *ctx = (grn_ctx *)mrb->ud; + const char *default_path = grn_default_logger_get_path(); + const char *utf8_default_path; + mrb_value mrb_default_path; + + utf8_default_path = + grn_encoding_convert_to_utf8_from_locale(ctx, default_path, -1, NULL); + mrb_default_path = mrb_str_new_cstr(mrb, utf8_default_path); + grn_encoding_converted_free(ctx, utf8_default_path); + + return mrb_default_path; } static mrb_value @@ -64,13 +76,22 @@ logger_log_raw(mrb_state *mrb, mrb_value self) char *file; mrb_int line; char *method; - char *message; - mrb_int message_size; + char *utf8_message; + mrb_int utf8_message_size; + const char *message; + size_t message_size; mrb_get_args(mrb, "izizs", - &level, &file, &line, &method, &message, &message_size); + &level, &file, &line, &method, &utf8_message, &utf8_message_size); + message = grn_encoding_convert_from_utf8(ctx, + utf8_message, + utf8_message_size, + &message_size); grn_logger_put(ctx, level, file, line, method, - "%.*s", (int)message_size, message); + "%.*s", + (int)message_size, + message); + grn_encoding_converted_free(ctx, message); return self; } Modified: lib/mrb/mrb_object.c (+12 -2) =================================================================== --- lib/mrb/mrb_object.c 2018-06-22 09:57:34 +0900 (c0fd364e3) +++ lib/mrb/mrb_object.c 2018-06-22 10:00:28 +0900 (c44e6006f) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2013-2016 Brazil + Copyright(C) 2013-2018 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -32,6 +32,8 @@ #include "mrb_options.h" #include "mrb_converter.h" +#include "../grn_encoding.h" + static mrb_value object_remove_force(mrb_state *mrb, mrb_value self) { @@ -115,7 +117,15 @@ object_get_path(mrb_state *mrb, mrb_value self) path = grn_obj_path(ctx, object); if (path) { - return mrb_str_new_cstr(mrb, path); + const char *utf8_path; + mrb_value mrb_path; + + utf8_path = + grn_encoding_convert_to_utf8_from_locale(ctx, path, -1, NULL); + mrb_path = mrb_str_new_cstr(mrb, utf8_path); + grn_encoding_converted_free(ctx, utf8_path); + + return mrb_path; } else { return mrb_nil_value(); } Modified: lib/mrb/mrb_query_logger.c (+17 -6) =================================================================== --- lib/mrb/mrb_query_logger.c 2018-06-22 09:57:34 +0900 (b2f5e79ed) +++ lib/mrb/mrb_query_logger.c 2018-06-22 10:00:28 +0900 (2c2374047) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2015 Brazil + Copyright(C) 2015-2018 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -28,6 +28,8 @@ #include "../grn_mrb.h" #include "mrb_query_logger.h" +#include "../grn_encoding.h" + static mrb_value query_logger_need_log_p(mrb_state *mrb, mrb_value self) { @@ -45,12 +47,21 @@ query_logger_log_raw(mrb_state *mrb, mrb_value self) grn_ctx *ctx = (grn_ctx *)mrb->ud; mrb_int flag; char *mark; - char *message; - mrb_int message_size; - - mrb_get_args(mrb, "izs", &flag, &mark, &message, &message_size); + char *utf8_message; + mrb_int utf8_message_size; + const char *message; + size_t message_size; + + mrb_get_args(mrb, "izs", &flag, &mark, &utf8_message, &utf8_message_size); + message = grn_encoding_convert_from_utf8(ctx, + utf8_message, + utf8_message_size, + &message_size); grn_query_logger_put(ctx, flag, mark, - "%.*s", (int)message_size, message); + "%.*s", + (int)message_size, + message); + grn_encoding_converted_free(ctx, message); return self; } Modified: lib/mrb/scripts/command_line/grndb.rb (+13 -12) =================================================================== --- lib/mrb/scripts/command_line/grndb.rb 2018-06-22 09:57:34 +0900 (d7076a13d) +++ lib/mrb/scripts/command_line/grndb.rb 2018-06-22 10:00:28 +0900 (5836431fc) @@ -5,6 +5,7 @@ module Groonga class Grndb def initialize(argv) @program_path, *@arguments = argv + @output = LocaleOutput.new($stderr) @succeeded = true @database_path = nil end @@ -15,9 +16,9 @@ module Groonga begin options = command_line_parser.parse(@arguments) rescue Slop::Error => error - $stderr.puts(error.message) - $stderr.puts - $stderr.puts(command_line_parser.help_message) + @output.puts(error.message) + @output.puts + @output.puts(command_line_parser.help_message) return false end @succeeded @@ -68,9 +69,9 @@ module Groonga def open_database(command, options) arguments = options.arguments if arguments.empty? - $stderr.puts("Database path is missing") - $stderr.puts - $stderr.puts(command.help_message) + @output.puts("Database path is missing") + @output.puts + @output.puts(command.help_message) @succeesed = false return end @@ -80,8 +81,8 @@ module Groonga begin database = Database.open(@database_path) rescue Error => error - $stderr.puts("Failed to open database: <#{@database_path}>") - $stderr.puts(error.message) + @output.puts("Failed to open database: <#{@database_path}>") + @output.puts(error.message) @succeeded = false return end @@ -95,7 +96,7 @@ module Groonga def failed(*messages) messages.each do |message| - $stderr.puts(message) + @output.puts(message) end @succeeded = false end @@ -491,7 +492,7 @@ module Groonga object_basename = File.basename(object_path) object.truncate message = "[#{name}] Truncated broken object: <#{object_path}>" - $stderr.puts(message) + @output.puts(message) logger.log(:info, message) Dir.foreach(object_dirname) do |path| @@ -502,13 +503,13 @@ module Groonga File.unlink(full_path) message = "[#{name}] Removed broken object related file: <#{full_path}>" - $stderr.puts(message) + @output.puts(message) logger.log(:info, message) rescue Error => error message = "[#{name}] Failed to remove broken object related file: " + "<#{full_path}>: #{error.class}: #{error.message}" - $stderr.puts(message) + @output.puts(message) logger.log_error(message) end end Modified: lib/plugin.c (+15 -2) =================================================================== --- lib/plugin.c 2018-06-22 09:57:34 +0900 (4d0c1d2e7) +++ lib/plugin.c 2018-06-22 10:00:28 +0900 (e9d67c125) @@ -18,6 +18,7 @@ #include "grn.h" #include "grn_ctx_impl_mrb.h" +#include "grn_encoding.h" #include "grn_proc.h" #include <groonga/plugin.h> @@ -197,8 +198,20 @@ grn_plugin_call_register_mrb(grn_ctx *ctx, grn_id id, grn_plugin *plugin) arena_index = mrb_gc_arena_save(mrb); plugin_loader_class = mrb_class_get_under(mrb, module, "PluginLoader"); - mrb_funcall(mrb, mrb_obj_value(plugin_loader_class), - "load_file", 1, mrb_str_new_cstr(mrb, ctx->impl->plugin_path)); + { + const char *utf8_path; + mrb_value mrb_path; + utf8_path = + grn_encoding_convert_to_utf8_from_locale(ctx, + ctx->impl->plugin_path, + -1, + NULL); + mrb_path = mrb_str_new_cstr(mrb, utf8_path); + grn_encoding_converted_free(ctx, utf8_path); + mrb_funcall(mrb, mrb_obj_value(plugin_loader_class), + "load_file", + 1, mrb_path); + } mrb_gc_arena_restore(mrb, arena_index); return ctx->rc; } Modified: src/grndb.c (+10 -2) =================================================================== --- src/grndb.c 2018-06-22 09:57:34 +0900 (119805d06) +++ src/grndb.c 2018-06-22 10:00:28 +0900 (ad101a8fc) @@ -1,6 +1,6 @@ /* -*- c-basic-offset: 2 -*- */ /* - Copyright(C) 2014-2017 Brazil + Copyright(C) 2014-2018 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,7 @@ #include <grn_mrb.h> #include <grn_ctx_impl.h> #include <grn_ctx_impl_mrb.h> +#include <grn_encoding.h> #include <mruby/variable.h> #include <mruby/array.h> @@ -60,7 +61,14 @@ run_command(grn_ctx *ctx, int argc, char **argv) mrb_argv = mrb_ary_new_capa(mrb, argc); for (i = 0; i < argc; i++) { - mrb_ary_push(mrb, mrb_argv, mrb_str_new_cstr(mrb, argv[i])); + const char *utf8_arg; + mrb_value mrb_utf8_arg; + + utf8_arg = + grn_encoding_convert_to_utf8_from_locale(ctx, argv[i], -1, NULL); + mrb_utf8_arg = mrb_str_new_cstr(mrb, utf8_arg); + grn_encoding_converted_free(ctx, utf8_arg); + mrb_ary_push(mrb, mrb_argv, mrb_utf8_arg); } mrb_grndb = mrb_funcall(mrb, mrb_grndb_class, "new", 1, mrb_argv); if (mrb->exc) { -------------- next part -------------- HTML����������������������������... URL: https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20180622/b09bea3f/attachment-0001.htm