summaryrefslogtreecommitdiff
path: root/ext/curses
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-07 21:42:24 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-07 21:42:24 +0000
commit80d16e7403e64c5ba19b83046b3530aeaf4ed62b (patch)
tree37c2ea24a1227676244ccdededbcb2c4b0ba1307 /ext/curses
parent551dfe9d8b9877d81b0ca87aff004c11383b698d (diff)
* ext/curses/curses.c: curses encoding should obey locale.
* ext/curses/curses.c (curses_getch): 1.9 getch should return one character string for single byte string. wchar_t support may follow in the future. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@20145 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/curses')
-rw-r--r--ext/curses/curses.c77
-rw-r--r--ext/curses/view.rb2
2 files changed, 62 insertions, 17 deletions
diff --git a/ext/curses/curses.c b/ext/curses/curses.c
index 17a44c0e88..778bee4da9 100644
--- a/ext/curses/curses.c
+++ b/ext/curses/curses.c
@@ -307,13 +307,35 @@ curses_flash(VALUE obj)
return Qnil;
}
+static int
+curses_char(VALUE c)
+{
+ if (FIXNUM_P(c)) {
+ return NUM2INT(c);
+ }
+ else {
+ int cc;
+
+ StringValue(c);
+ if (RSTRING_LEN(c) == 0 || RSTRING_LEN(c) > 1) {
+ rb_raise(rb_eArgError, "string not corresponding a character");
+ }
+ cc = RSTRING_PTR(c)[0];
+ if (cc > 0x7f) {
+ rb_raise(rb_eArgError, "no multibyte string supported (yet)");
+ }
+ return cc;
+ }
+}
+
/* def ungetch */
static VALUE
curses_ungetch(VALUE obj, VALUE ch)
{
#ifdef HAVE_UNGETCH
+ int c = curses_char(ch);
curses_stdscr();
- ungetch(NUM2INT(ch));
+ ungetch(c);
#else
rb_notimplement();
#endif
@@ -375,9 +397,11 @@ curses_insch(VALUE obj, VALUE ch)
static VALUE
curses_addstr(VALUE obj, VALUE str)
{
+ StringValue(str);
+ str = rb_str_export_locale(str);
curses_stdscr();
if (!NIL_P(str)) {
- addstr(STR2CSTR(str));
+ addstr(StringValueCStr(str));
}
return Qnil;
}
@@ -386,9 +410,18 @@ curses_addstr(VALUE obj, VALUE str)
static VALUE
curses_getch(VALUE obj)
{
+ int c;
+
rb_read_check(stdin);
curses_stdscr();
- return UINT2NUM(getch());
+ c = getch();
+ if (c == EOF) return Qnil;
+ if (ISPRINT(c)) {
+ char ch = (char)c;
+
+ return rb_locale_str_new(&ch, 1);
+ }
+ return UINT2NUM(c);
}
/* def getstr */
@@ -403,7 +436,7 @@ curses_getstr(VALUE obj)
#else
getstr(rtn);
#endif
- return rb_tainted_str_new2(rtn);
+ return rb_locale_str_new_cstr(rtn);
}
/* def delch */
@@ -439,16 +472,18 @@ static VALUE
curses_keyname(VALUE obj, VALUE c)
{
#ifdef HAVE_KEYNAME
- const char *name;
+ int cc = curses_char(c);
+ const char *name;
- name = keyname(NUM2INT(c));
- if (name) {
- return rb_str_new2(name);
- } else {
- return Qnil;
- }
+ name = keyname(cc);
+ if (name) {
+ return rb_str_new_cstr(name);
+ }
+ else {
+ return Qnil;
+ }
#else
- return Qnil;
+ return Qnil;
#endif
}
@@ -1048,8 +1083,10 @@ window_addstr(VALUE obj, VALUE str)
if (!NIL_P(str)) {
struct windata *winp;
+ StringValue(str);
+ str = rb_str_export_locale(str);
GetWINDOW(obj, winp);
- waddstr(winp->window, STR2CSTR(str));
+ waddstr(winp->window, StringValueCStr(str));
}
return Qnil;
}
@@ -1067,10 +1104,18 @@ static VALUE
window_getch(VALUE obj)
{
struct windata *winp;
-
+ int c;
+
rb_read_check(stdin);
GetWINDOW(obj, winp);
- return UINT2NUM(wgetch(winp->window));
+ c = wgetch(winp->window);
+ if (c == EOF) return Qnil;
+ if (ISPRINT(c)) {
+ char ch = (char)c;
+
+ return rb_locale_str_new(&ch, 1);
+ }
+ return UINT2NUM(c);
}
/* def getstr */
@@ -1087,7 +1132,7 @@ window_getstr(VALUE obj)
#else
wgetstr(winp->window, rtn);
#endif
- return rb_tainted_str_new2(rtn);
+ return rb_locale_str_new_cstr(rtn);
}
/* def delch */
diff --git a/ext/curses/view.rb b/ext/curses/view.rb
index d9a82a57db..239f414b84 100644
--- a/ext/curses/view.rb
+++ b/ext/curses/view.rb
@@ -48,7 +48,7 @@ while TRUE
explicit = FALSE
n = 0
while TRUE
- c = getch.chr
+ c = getch
if c =~ /[0-9]/
n = 10 * n + c.to_i
else