[Groonga-commit] groonga/groonga at de6e9ac [master] windows: support install path that has non-ascii characters again

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index