From 8d564597fa928ab5d70cdd8e9d0b603c99ebab11 Mon Sep 17 00:00:00 2001 From: nobu Date: Mon, 5 Aug 2013 08:38:39 +0000 Subject: win32.c: conversion to WCHAR * win32/win32.c (rb_w32_write_console): use MultiByteToWideChar() for the last step of conversion to WCHAR, to get rid of warnings from rb_enc_find() in miniruby. [ruby-dev:47584] [Bug #8733] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42385 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- win32/win32.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'win32') diff --git a/win32/win32.c b/win32/win32.c index ab2b64a5e4..587f4cbb1f 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -48,6 +48,7 @@ #endif #include "ruby/win32.h" #include "win32/dir.h" +#include "internal.h" #define isdirsep(x) ((x) == '/' || (x) == '\\') #if defined _MSC_VER && _MSC_VER <= 1200 @@ -466,8 +467,6 @@ get_system_directory(WCHAR *path, UINT len) return GetWindowsDirectoryW(path, len); } -#define numberof(array) (sizeof(array) / sizeof(*array)) - /* License: Ruby's */ VALUE rb_w32_special_folder(int type) @@ -6397,34 +6396,51 @@ rb_w32_write_console(uintptr_t strarg, int fd) HANDLE handle; DWORD dwMode, reslen; VALUE str = strarg; - rb_encoding *utf16 = rb_enc_find("UTF-16LE"); + int encindex; + WCHAR *wbuffer = 0; const WCHAR *ptr, *next; struct constat *s; long len; if (disable) return -1L; handle = (HANDLE)_osfhnd(fd); - if (!GetConsoleMode(handle, &dwMode) || - !rb_econv_has_convpath_p(rb_enc_name(rb_enc_get(str)), "UTF-16LE")) + if (!GetConsoleMode(handle, &dwMode)) return -1L; - str = rb_str_encode(str, rb_enc_from_encoding(utf16), - ECONV_INVALID_REPLACE|ECONV_UNDEF_REPLACE, Qnil); - ptr = (const WCHAR *)RSTRING_PTR(str); - len = RSTRING_LEN(str) / sizeof(WCHAR); s = constat_handle(handle); + encindex = ENCODING_GET(str); + switch (encindex) { + default: + if (!rb_econv_has_convpath_p(rb_enc_name(rb_enc_from_index(encindex)), "UTF-8")) + return -1L; + str = rb_str_conv_enc_opts(str, NULL, rb_enc_from_index(ENCINDEX_UTF_8), + ECONV_INVALID_REPLACE|ECONV_UNDEF_REPLACE, Qnil); + /* fall through */ + case ENCINDEX_US_ASCII: + case ENCINDEX_ASCII: + /* assume UTF-8 */ + case ENCINDEX_UTF_8: + ptr = wbuffer = mbstr_to_wstr(CP_UTF8, RSTRING_PTR(str), RSTRING_LEN(str), &len); + break; + case ENCINDEX_UTF_16LE: + ptr = (const WCHAR *)RSTRING_PTR(str); + len = RSTRING_LEN(str) / sizeof(WCHAR); + break; + } while (len > 0) { long curlen = constat_parse(handle, s, (next = ptr, &next), &len); if (curlen > 0) { if (!WriteConsoleW(handle, ptr, curlen, &reslen, NULL)) { if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) disable = TRUE; - return -1L; + reslen = (DWORD)-1L; + break; } } ptr = next; } RB_GC_GUARD(str); + if (wbuffer) free(wbuffer); return (long)reslen; } -- cgit v1.2.3