summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYasuhiro Matsumoto <[email protected]>2015-09-11 11:12:03 +0900
committerYasuhiro Matsumoto <[email protected]>2015-09-11 11:12:03 +0900
commit8277e950eee4e8c6135eca281a7d5ca91077d2b4 (patch)
treeb8c78e65be2d634694eed3ae12f72b6076631fe1
parent3ed8e7fbb24886619f6e7aa2e9be1d0dd0609feb (diff)
downloadmruby-8277e950eee4e8c6135eca281a7d5ca91077d2b4.tar.gz
mruby-8277e950eee4e8c6135eca281a7d5ca91077d2b4.zip
Support windows locale
Add mrb_utf8_from_locale, mrb_utf8_free, mrb_locale_from_utf8, mrb_locale_free. Just works for windows.
-rw-r--r--include/mruby.h12
-rw-r--r--mrbgems/mruby-bin-mirb/tools/mirb/mirb.c10
-rw-r--r--mrbgems/mruby-bin-mruby/tools/mruby/mruby.c11
-rw-r--r--mrbgems/mruby-print/src/print.c13
-rw-r--r--src/string.c63
5 files changed, 99 insertions, 10 deletions
diff --git a/include/mruby.h b/include/mruby.h
index b4ec13fdc..dedbd0748 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -292,6 +292,18 @@ MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*);
MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len);
#define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit))
+#ifdef _WIN32
+char* mrb_utf8_from_locale(const char *p, size_t len);
+char* mrb_locale_from_utf8(const char *p, size_t len);
+#define mrb_locale_free(p) free(p)
+#define mrb_utf8_free(p) free(p)
+#else
+#define mrb_utf8_from_locale(p, l) (p)
+#define mrb_locale_from_utf8(p, l) (p)
+#define mrb_locale_free(p)
+#define mrb_utf8_free(p)
+#endif
+
MRB_API mrb_state* mrb_open(void);
MRB_API mrb_state* mrb_open_allocf(mrb_allocf, void *ud);
MRB_API mrb_state* mrb_open_core(mrb_allocf, void *ud);
diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
index 0f3649a35..37fda352c 100644
--- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
+++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
@@ -366,6 +366,8 @@ main(int argc, char **argv)
ai = mrb_gc_arena_save(mrb);
while (TRUE) {
+ char *utf8;
+
#ifndef ENABLE_READLINE
print_cmdline(code_block_open);
@@ -415,17 +417,21 @@ main(int argc, char **argv)
strcpy(ruby_code, last_code_line);
}
+ utf8 = mrb_utf8_from_locale(ruby_code, -1);
+ if (!utf8) abort();
+
/* parse code */
parser = mrb_parser_new(mrb);
if (parser == NULL) {
fputs("create parser state error\n", stderr);
break;
}
- parser->s = ruby_code;
- parser->send = ruby_code + strlen(ruby_code);
+ parser->s = utf8;
+ parser->send = utf8 + strlen(utf8);
parser->lineno = cxt->lineno;
mrb_parser_parse(parser, cxt);
code_block_open = is_code_block_open(parser);
+ mrb_utf8_free(utf8);
if (code_block_open) {
/* no evaluation of code */
diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
index 5ca744388..cc1ca3055 100644
--- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
+++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c
@@ -191,7 +191,11 @@ main(int argc, char **argv)
ARGV = mrb_ary_new_capa(mrb, args.argc);
for (i = 0; i < args.argc; i++) {
- mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, args.argv[i]));
+ char* utf8 = mrb_utf8_from_locale(args.argv[i], -1);
+ if (utf8) {
+ mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8));
+ mrb_utf8_free(utf8);
+ }
}
mrb_define_global_const(mrb, "ARGV", ARGV);
@@ -222,7 +226,10 @@ main(int argc, char **argv)
v = mrb_load_file_cxt(mrb, args.rfp, c);
}
else {
- v = mrb_load_string_cxt(mrb, args.cmdline, c);
+ char* utf8 = mrb_utf8_from_locale(args.cmdline, -1);
+ if (!utf8) abort();
+ v = mrb_load_string_cxt(mrb, utf8, c);
+ mrb_utf8_free(utf8);
}
mrbc_context_free(mrb, c);
diff --git a/mrbgems/mruby-print/src/print.c b/mrbgems/mruby-print/src/print.c
index 673ba2172..e7e21dd4b 100644
--- a/mrbgems/mruby-print/src/print.c
+++ b/mrbgems/mruby-print/src/print.c
@@ -1,17 +1,18 @@
#include "mruby.h"
#include "mruby/string.h"
#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
static void
printstr(mrb_state *mrb, mrb_value obj)
{
- char *s;
- mrb_int len;
-
if (mrb_string_p(obj)) {
- s = RSTRING_PTR(obj);
- len = RSTRING_LEN(obj);
- fwrite(s, len, 1, stdout);
+ char* ptr = mrb_locale_from_utf8(RSTRING_PTR(obj), RSTRING_LEN(obj));
+ if (ptr) {
+ fwrite(ptr, strlen(ptr), 1, stdout);
+ mrb_locale_free(ptr);
+ }
}
}
diff --git a/src/string.c b/src/string.c
index 08caf3bae..e93fd4606 100644
--- a/src/string.c
+++ b/src/string.c
@@ -43,6 +43,69 @@ mrb_str_strlen(mrb_state *mrb, struct RString *s)
return max;
}
+#ifdef _WIN32
+#include <windows.h>
+
+char*
+mrb_utf8_from_locale(const char *str, size_t len)
+{
+ wchar_t* wcsp;
+ char* mbsp;
+ size_t mbssize, wcssize;
+
+ if (len == 0)
+ return strdup("");
+ if (len == -1)
+ len = strlen(str);
+ wcssize = MultiByteToWideChar(GetACP(), 0, str, len, NULL, 0);
+ wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t));
+ if (!wcsp)
+ return NULL;
+ wcssize = MultiByteToWideChar(GetACP(), 0, str, len, wcsp, wcssize + 1);
+ wcsp[wcssize] = 0;
+
+ mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL);
+ mbsp = (char*) malloc((mbssize + 1));
+ if (!mbsp) {
+ free(wcsp);
+ return NULL;
+ }
+ mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL);
+ mbsp[mbssize] = 0;
+ free(wcsp);
+ return mbsp;
+}
+
+char*
+mrb_locale_from_utf8(const char *utf8, size_t len)
+{
+ wchar_t* wcsp;
+ char* mbsp;
+ size_t mbssize, wcssize;
+
+ if (len == 0)
+ return strdup("");
+ if (len == -1)
+ len = strlen(utf8);
+ wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0);
+ wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t));
+ if (!wcsp)
+ return NULL;
+ wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, wcsp, wcssize + 1);
+ wcsp[wcssize] = 0;
+ mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL);
+ mbsp = (char*) malloc((mbssize + 1));
+ if (!mbsp) {
+ free(wcsp);
+ return NULL;
+ }
+ mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL);
+ mbsp[mbssize] = 0;
+ free(wcsp);
+ return mbsp;
+}
+#endif
+
static inline void
resize_capa(mrb_state *mrb, struct RString *s, mrb_int capacity)
{