diff options
| author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-07-09 05:26:54 +0000 |
|---|---|---|
| committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-07-09 05:26:54 +0000 |
| commit | 11466a5e5a063fd7f0125be815d90d8ee36df7de (patch) | |
| tree | 722a07b93029d42c4c3d50733603c46f7dbfde30 | |
| parent | 7ce7d911e6aa0ce0d33d6b52f91b889f203e7271 (diff) | |
| download | ruby-11466a5e5a063fd7f0125be815d90d8ee36df7de.tar.gz | |
several minor fixes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_m17n@2626 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
| -rw-r--r-- | eval.c | 21 | ||||
| -rw-r--r-- | ext/dbm/dbm.c | 2 | ||||
| -rw-r--r-- | ext/dbm/extconf.rb | 53 | ||||
| -rw-r--r-- | ext/readline/extconf.rb | 3 | ||||
| -rw-r--r-- | ext/readline/readline.c | 14 | ||||
| -rw-r--r-- | intern.h | 9 | ||||
| -rw-r--r-- | io.c | 5 | ||||
| -rw-r--r-- | m17n.c | 161 | ||||
| -rw-r--r-- | m17n.h | 11 | ||||
| -rw-r--r-- | numeric.c | 35 | ||||
| -rw-r--r-- | re.c | 31 | ||||
| -rw-r--r-- | regex.c | 41 | ||||
| -rw-r--r-- | regex.h | 7 | ||||
| -rw-r--r-- | ruby.c | 1 | ||||
| -rw-r--r-- | ruby.h | 15 | ||||
| -rw-r--r-- | sprintf.c | 37 | ||||
| -rw-r--r-- | string.c | 207 |
17 files changed, 440 insertions, 213 deletions
@@ -1417,27 +1417,6 @@ ev_const_get(cref, id) } static VALUE -ev_const_set(cref, id, val) - NODE *cref; - ID id; - VALUE val; -{ - NODE *cbase = cref; - - while (cbase && cbase->nd_clss != rb_cObject) { - struct RClass *klass = RCLASS(cbase->nd_clss); - - if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, 0)) { - st_insert(klass->iv_tbl, id, val); - return val; - } - cbase = cbase->nd_next; - } - rb_const_assign(cbase->nd_clss, id, val); - return val; -} - -static VALUE rb_mod_nesting() { NODE *cbase = RNODE(ruby_frame->cbase); diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c index 55c60bf3b3..5218def302 100644 --- a/ext/dbm/dbm.c +++ b/ext/dbm/dbm.c @@ -18,7 +18,7 @@ #ifdef HAVE_SYS_CDEFS_H # include <sys/cdefs.h> #endif -#include <ndbm.h> +#include DBM_HDR #include <fcntl.h> #include <errno.h> diff --git a/ext/dbm/extconf.rb b/ext/dbm/extconf.rb index 9ce235a2b5..0e29eef0ce 100644 --- a/ext/dbm/extconf.rb +++ b/ext/dbm/extconf.rb @@ -1,13 +1,56 @@ require 'mkmf' dir_config("dbm") -if have_library("gdbm", "dbm_open") - gdbm = true + +dblib = with_config("dbm-type", nil) + +$dbm_conf_headers = { + "db" => ["db.h"], + "db1" => ["db1/ndbm.h", "db1.h", "ndbm.h"], + "db2" => ["db2/db.h", "db2.h", "db.h"], + "dbm" => ["ndbm.h"], + "gdbm" => ["gdbm-ndbm.h", "ndbm.h"], +} + +def db_check(db) + $dbm_conf_db_prefix = "" + $dbm_conf_have_gdbm = false + hsearch = "" + + case db + when /^db2?$/ + $dbm_conf_db_prefix = "__db_n" + hsearch = "-DDB_DBM_HSEARCH " + when "gdbm" + $dbm_conf_have_gdbm = true + end + + if have_func(db_prefix("dbm_open")) || have_library(db, db_prefix("dbm_open")) + for hdr in $dbm_conf_headers.fetch(db, ["ndbm.h"]) + if have_header(hdr.dup) + $CFLAGS += " " + hsearch + "-DDBM_HDR='<"+hdr+">'" + return true + end + end + end + return false end -gdbm or have_library("db", "dbm_open") or have_library("dbm", "dbm_open") + +def db_prefix(func) + $dbm_conf_db_prefix+func +end + +if dblib + db_check(dblib) +else + for dblib in %w(db db2 db1 dbm gdbm) + db_check(dblib) and break + end +end + have_header("cdefs.h") have_header("sys/cdefs.h") -if have_header("ndbm.h") and have_func("dbm_open") - have_func("dbm_clearerr") unless gdbm +if have_func(db_prefix("dbm_open")) + have_func(db_prefix("dbm_clearerr")) unless $dbm_conf_have_gdbm create_makefile("dbm") end diff --git a/ext/readline/extconf.rb b/ext/readline/extconf.rb index 7db62745f3..431ed213bb 100644 --- a/ext/readline/extconf.rb +++ b/ext/readline/extconf.rb @@ -9,5 +9,8 @@ have_library("ncurses", "tgetnum") or if have_header("readline/readline.h") and have_header("readline/history.h") and have_library("readline", "readline") + if have_func("rl_filename_completion_function") + $CFLAGS += "-DREADLINE_42_OR_LATER" + end create_makefile("readline") end diff --git a/ext/readline/readline.c b/ext/readline/readline.c index 02b29796af..876207c224 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -15,6 +15,12 @@ static VALUE mReadline; #define COMPLETION_PROC "completion_proc" #define COMPLETION_CASE_FOLD "completion_case_fold" +#ifndef READLINE_42_OR_LATER +# define rl_filename_completion_function filename_completion_function +# define rl_username_completion_function username_completion_function +# define rl_completion_matches completion_matches +#endif + static int readline_event() { @@ -321,8 +327,8 @@ filename_completion_proc_call(self, str) char **matches; int i; - matches = completion_matches(STR2CSTR(str), - filename_completion_function); + matches = rl_completion_matches(STR2CSTR(str), + rl_filename_completion_function); if (matches) { result = rb_ary_new(); for (i = 0; matches[i]; i++) { @@ -348,8 +354,8 @@ username_completion_proc_call(self, str) char **matches; int i; - matches = completion_matches(STR2CSTR(str), - username_completion_function); + matches = rl_completion_matches(STR2CSTR(str), + rl_username_completion_function); if (matches) { result = rb_ary_new(); for (i = 0; matches[i]; i++) { @@ -301,11 +301,12 @@ VALUE rb_f_sprintf _((int, VALUE*)); /* string.c */ struct m17n_encoding *ruby_default_encoding; struct m17n_encoding *rb_m17n_get_encoding _((VALUE obj)); -void rb_m17n_associate_encoding _((VALUE obj, struct m17n_encoding* enc)); -void rb_m17n_enc_check _((VALUE str1, VALUE str2, struct m17n_encoding **encp)); +void rb_m17n_associate_encoding _((VALUE, struct m17n_encoding*)); +void rb_m17n_copy_encoding _((VALUE, VALUE)); +void rb_m17n_enc_check _((VALUE, VALUE, struct m17n_encoding **)); int rb_str_sublen _((VALUE, int)); -VALUE rb_enc_get_encoding _((VALUE obj)); -VALUE rb_enc_set_encoding _((VALUE obj, VALUE encoding)); +VALUE rb_enc_get_encoding _((VALUE)); +VALUE rb_enc_set_encoding _((VALUE, VALUE)); VALUE rb_str_new _((const char*, long)); VALUE rb_str_new2 _((const char*)); VALUE rb_str_new3 _((VALUE)); @@ -1330,10 +1330,10 @@ VALUE rb_io_binmode(io) VALUE io; { -#if defined(NT) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__EMX__) OpenFile *fptr; GetOpenFile(io, fptr); +#if defined(NT) || defined(DJGPP) || defined(__CYGWIN__) || defined(__human68k__) || defined(__EMX__) #ifdef __human68k__ if (fptr->f) fmode(fptr->f, _IOBIN); @@ -1348,6 +1348,7 @@ rb_io_binmode(io) fptr->mode |= FMODE_BINMODE; #endif + fptr->enc = m17n_find_encoding("binary"); return io; } @@ -1668,8 +1669,8 @@ pipe_open(pname, mode) { int modef = rb_io_mode_flags(mode); OpenFile *fptr; - #if defined(NT) || defined(DJGPP) || defined(__human68k__) + FILE *f = popen(pname, mode); if (!f) rb_sys_fail(pname); @@ -6,7 +6,7 @@ $Date$ created at: Thu Dec 28 16:29:43 JST 2000 - Copyright (C) 1993-2001 Yukihiro Matsumoto + Copyright (C) 2000-2001 Yukihiro Matsumoto **********************************************************************/ @@ -21,9 +21,12 @@ #define uchar unsigned char +#define CHAR_IN_RANGE(c, l, h) ((uchar)(c) - (uchar)(l) <= (uchar)(h) - (uchar)(l)) + static int num_encodings = 1; m17n_encoding **m17n_encoding_table = 0; +static int any_swidth _((const uchar *p, const uchar *e, const m17n_encoding* enc)); static int any_strlen _((const uchar *p, const uchar *e, const m17n_encoding* enc)); static uchar *any_nth _((uchar *p, const uchar *e, int n, const m17n_encoding* enc)); @@ -45,6 +48,8 @@ m17n_define_encoding(name) memcpy(enc, m17n_encoding_table[0], sizeof(m17n_encoding)); /* ..but strlen() */ m17n_encoding_func_strlen(enc, any_strlen); + /* ..and swidth() */ + m17n_encoding_func_swidth(enc, any_swidth); /* ..and nth() */ m17n_encoding_func_nth(enc, any_nth); /* mbmaxlen is unknown (i.e. 0) */ @@ -56,6 +61,30 @@ m17n_define_encoding(name) return enc; } +m17n_encoding* +m17n_copy_encoding(name, orig) + const char *name; + m17n_encoding *orig; +{ + m17n_encoding *enc; + + if (!m17n_encoding_table) { + m17n_init(); + } + num_encodings++; + m17n_encoding_table = realloc(m17n_encoding_table, + sizeof(m17n_encoding*)*num_encodings); + enc = malloc(sizeof(m17n_encoding)); + + /* copy table */ + memcpy(enc, orig, sizeof(m17n_encoding)); + enc->name = name; + enc->index = num_encodings-1; + m17n_encoding_table[enc->index] = enc; + + return enc; +} + m17n_encoding * m17n_find_encoding(name) const char *name; @@ -232,6 +261,42 @@ asc_mbcput(c, p, enc) } static int +asc_cwidth(c, enc) + unsigned int c; + const m17n_encoding *enc; +{ + return 1; +} + +static int +asc_swidth(p, e, enc) + const uchar *p, *e; + const m17n_encoding *enc; +{ + return e - p; +} + +static int +any_swidth(p, e, enc) + const uchar *p, *e; + const m17n_encoding *enc; +{ + uchar *s = p; + int c, cw, w = 0; + + while (s<e) { + c = m17n_codepoint(enc, s, e); + cw = m17n_cwidth(enc, c); + if (cw < 0) { + return -w; + } + w += cw; + s += m17n_codelen(enc, c); + } + return w; +} + +static int any_strlen(p, e, enc) const uchar *p, *e; const m17n_encoding *enc; @@ -319,6 +384,17 @@ latin1_ctype(c, code, enc) return latin1_ctype_table[c] & code; } +static int +latin1_cwidth(c, enc) + unsigned int c; + const m17n_encoding *enc; +{ + if (c > 0xff) return -1; + if (latin1_ctype_table[c] & (M17N_P|M17N_U|M17N_L|M17N_N|M17N_S)) + return 1; + return -1; +} + uchar latin1_toupper_table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -404,8 +480,21 @@ eucjp_islead(c, enc) int c; const m17n_encoding *enc; { - if (0xa1 <= c && c <= 0xfe) return 0; - return 1; + return !CHAR_IN_RANGE(c, 0xa1, 0xfe); +} + +static int +eucjp_cwidth(c, enc) + unsigned int c; + const m17n_encoding *enc; +{ + if (c < 0x20) return -1; + if (c < 0x80) { + if (m17n_isprint(enc, c)) return 1; + return -1; + } + if ((c&0xff00) == 0x8e00) return 1; + return 2; } static unsigned int @@ -471,8 +560,8 @@ jis_mbcput(c, p, enc) } } -#define issjis1(c) ((0x81<=(c) && (c)<=0x9f) || (0xe0<=(c) && (c)<=0xfc)) -#define issjis2(c) ((0x40<=(c) && (c)<=0x7e) || (0x80<=(c) && (c)<=0xfc)) +#define issjis1(c) CHAR_IN_RANGE((c)^0x20, 0x81^0x20, 0xfc^0x20) +#define issjis2(c) (CHAR_IN_RANGE((c), 0x40, 0xfc) && (c)!=0x7f) static int sjis_mbclen(c, enc) @@ -487,10 +576,7 @@ sjis_mbcspan(p, e, enc) const uchar *p, *e; const m17n_encoding *enc; { - return issjis1(p[0]) && e-p >= 2 && - issjis2(p[1]) ? 2 : - (p[0] & 0x80) ? 0 : - 1; + return issjis1(p[0]) ? (e-p >= 2 && issjis2(p[1]) ? 2 : 0) : 1; } static int @@ -506,10 +592,32 @@ sjis_ctype(c, code, enc) unsigned int c, code; const m17n_encoding *enc; { - if (0x9f < c && c < 0xe0) return 0120 & code; + if (c > 0xff) return M17N_W & code; + if (0x9f < c && c < 0xe0) return (M17N_W|M17N_P) & code; return asc_ctype_table[c] & code; } +static int +sjis_cwidth(c, enc) + unsigned int c; + const m17n_encoding *enc; +{ + int c1, c2; + + if (c < 0x20) return -1; + if (c < 0x80) { + if (m17n_isprint(enc, c)) return 1; + return -1; + } + c1 = (c >> 8) & 0xff; + if (issjis1(c1)) { + c2 = c & 0xff; + if (issjis2(c2)) return 2; + return -1; + } + return 1; +} + static const uchar utf8_mbctab[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -565,8 +673,7 @@ utf8_islead(c, enc) int c; const m17n_encoding *enc; { - if (c < 0x80 || (c & 0xc0) == 0xc0) return 1; - return 0; + return (c & 0xc0) != 0x80; } static unsigned int @@ -669,12 +776,17 @@ m17n_init() m17n_encoding_func_codepoint(enc, asc_codepoint); m17n_encoding_func_firstbyte(enc, asc_firstbyte); m17n_encoding_func_mbcput(enc, asc_mbcput); + m17n_encoding_func_cwidth(enc, asc_cwidth); + m17n_encoding_func_swidth(enc, asc_swidth); + + enc = m17n_copy_encoding("binary", enc); enc = m17n_define_encoding("latin1"); m17n_encoding_mbmaxlen(enc, 1); m17n_encoding_func_ctype(enc, latin1_ctype); m17n_encoding_func_toupper(enc, latin1_toupper); m17n_encoding_func_tolower(enc, latin1_tolower); + m17n_encoding_func_cwidth(enc, latin1_cwidth); enc = m17n_define_encoding("euc-jp"); m17n_encoding_mbmaxlen(enc, 3); @@ -685,6 +797,7 @@ m17n_init() m17n_encoding_func_codepoint(enc, jis_codepoint); m17n_encoding_func_firstbyte(enc, jis_firstbyte); m17n_encoding_func_mbcput(enc, jis_mbcput); + m17n_encoding_func_cwidth(enc, eucjp_cwidth); enc = m17n_define_encoding("sjis"); m17n_encoding_mbmaxlen(enc, 2); @@ -696,6 +809,7 @@ m17n_init() m17n_encoding_func_codepoint(enc, jis_codepoint); m17n_encoding_func_firstbyte(enc, jis_firstbyte); m17n_encoding_func_mbcput(enc, jis_mbcput); + m17n_encoding_func_cwidth(enc, sjis_cwidth); enc = m17n_define_encoding("utf-8"); m17n_encoding_mbmaxlen(enc, 6); @@ -709,16 +823,29 @@ m17n_init() } int -m17n_memcmp(p1, p2, len, enc) +m17n_casecmp(p1, p2, len, enc) const char *p1, *p2; long len; const m17n_encoding *enc; { - int tmp; + int tmp, clen; + unsigned int a, b; - while (len--) { - if (tmp = m17n_toupper(enc, (unsigned)*p1++) - - m17n_toupper(enc, (unsigned)*p2++)) + while (len > 0) { + clen = m17n_mbcspan(enc, p1, p1+len); + if (clen == 0) return memcmp(p1, p2, len); + if (clen != m17n_mbcspan(enc, p2, p2+len)) { + if ((unsigned)*p1 != (unsigned)*p2) + return ((unsigned)*p1 - (unsigned)*p2); + a = m17n_codepoint(enc, p1, p1+len); + b = m17n_codepoint(enc, p2, p2+len); + return a - b; + } + len -= clen; + a = m17n_codepoint(enc, p1, p1+clen); + b = m17n_codepoint(enc, p2, p2+clen); + p1 += clen; p2 += clen; + if (tmp = m17n_toupper(enc, a) - m17n_toupper(enc, b)) return tmp; } return 0; @@ -46,12 +46,15 @@ typedef struct m17n_encoding { unsigned int (*tolower) _((unsigned int c, const struct m17n_encoding* enc)); unsigned int (*codepoint) _((const unsigned char *p, const unsigned char *e, const struct m17n_encoding* enc)); int (*firstbyte) _((unsigned int c, const struct m17n_encoding* enc)); - void (*mbcput) _((unsigned int c, unsigned char *p, const struct m17n_encoding* enc)); + int (*mbcput) _((unsigned int c, unsigned char *p, const struct m17n_encoding* enc)); + int (*cwidth) _((unsigned int c, const struct m17n_encoding* enc)); + int (*swidth) _((const unsigned char *p, const unsigned char *e, const struct m17n_encoding* enc)); } m17n_encoding; extern m17n_encoding **m17n_encoding_table; m17n_encoding *m17n_define_encoding _((const char *name)); +m17n_encoding *m17n_copy_encoding _((const char *name, m17n_encoding *enc)); #define m17n_encoding_to_index(enc) (enc)->index #define m17n_index_to_encoding(index) m17n_encoding_table[index] @@ -71,6 +74,8 @@ m17n_encoding *m17n_find_encoding _((const char *name)); #define m17n_encoding_func_codepoint(enc,func) (enc)->codepoint = (func) #define m17n_encoding_func_firstbyte(enc,func) (enc)->firstbyte = (func) #define m17n_encoding_func_mbcput(enc,func) (enc)->mbcput = (func) +#define m17n_encoding_func_cwidth(enc,func) (enc)->cwidth = (func) +#define m17n_encoding_func_swidth(enc,func) (enc)->swidth = (func) #define m17n_mbmaxlen(enc) (enc)->mbmaxlen #define m17n_asciicompat(enc) (enc)->asciicompat @@ -83,6 +88,8 @@ m17n_encoding *m17n_find_encoding _((const char *name)); #define m17n_codepoint(enc,p,e) (*(enc)->codepoint)((p),(e),(enc)) #define m17n_firstbyte(enc,c) (*(enc)->firstbyte)((c),(enc)) #define m17n_mbcput(enc,c,p) (*(enc)->mbcput)((c),(p),(enc)) +#define m17n_cwidth(enc,c) (*(enc)->cwidth)((c),(enc)) +#define m17n_swidth(enc,p,e) (*(enc)->swidth)((p),(e),(enc)) #define M17N_U 01 /* Upper case */ #define M17N_L 02 /* Lower case */ @@ -107,6 +114,6 @@ m17n_encoding *m17n_find_encoding _((const char *name)); #define m17n_toupper(enc,c) (*(enc)->toupper)((c),(enc)) #define m17n_tolower(enc,c) (*(enc)->tolower)((c),(enc)) -int m17n_memcmp _((const char *p1, const char *p2, long len, const m17n_encoding *enc)); +int m17n_casecmp _((const char *p1, const char *p2, long len, const m17n_encoding *enc)); #endif /* M17N_H */ @@ -876,16 +876,39 @@ int_succ(num) } static VALUE -int_chr(num) +int_chr(argc, argv, num) + int argc; + VALUE *argv; VALUE num; { - char c; + m17n_encoding *enc; + char *buf; long i = NUM2LONG(num); + int len; - if (i < 0 || 0xff < i) + if (argc > 0) { + VALUE ename; + + rb_scan_args(argc, argv, "1", &ename); + enc = m17n_find_encoding(STR2CSTR(ename)); + } + else { + enc = ruby_default_encoding; + } + if (i < 0) { + error: rb_raise(rb_eRangeError, "%d out of char range", i); - c = i; - return rb_str_new(&c, 1); + } + len = m17n_codelen(enc, i); + if (len == 0 || len > m17n_mbmaxlen(enc)) goto error; + if (len == 1) { + char c = i; + return rb_str_new(&c, 1); + } + buf = ALLOCA_N(char, len); + m17n_mbcput(enc, i, buf); + if (i != m17n_codepoint(enc, buf, buf+len)) goto error; + return rb_str_new(buf, len); } static VALUE @@ -1562,7 +1585,7 @@ Init_Numeric() rb_include_module(rb_cInteger, rb_mPrecision); rb_define_method(rb_cInteger, "succ", int_succ, 0); rb_define_method(rb_cInteger, "next", int_succ, 0); - rb_define_method(rb_cInteger, "chr", int_chr, 0); + rb_define_method(rb_cInteger, "chr", int_chr, -1); rb_define_method(rb_cInteger, "to_i", int_to_i, 0); rb_define_method(rb_cInteger, "to_int", int_to_i, 0); rb_define_method(rb_cInteger, "floor", int_to_i, 0); @@ -70,8 +70,9 @@ rb_reg_expr_str(str, s, len) rb_str_cat(str, p, 1); } else if (ismbchar(*p)) { - rb_str_cat(str, p, mbclen(*p)); - p += mbclen(*p); + int len = m17n_mbcspan(enc, p, pend); + rb_str_cat(str, p, len); + p += len; continue; } else if (m17n_isprint(enc, *p)) { @@ -469,6 +470,7 @@ rb_reg_nth_match(nth, match) len = end - start; str = rb_str_new(RSTRING(RMATCH(match)->str)->ptr + start, len); if (OBJ_TAINTED(match)) OBJ_TAINT(str); + rb_m17n_copy_encoding(str, RMATCH(match)->str); return str; } @@ -483,19 +485,29 @@ VALUE rb_reg_match_pre(match) VALUE match; { + VALUE str; + if (NIL_P(match)) return Qnil; if (RMATCH(match)->BEG(0) == -1) return Qnil; - return rb_str_new(RSTRING(RMATCH(match)->str)->ptr, RMATCH(match)->BEG(0)); + str = rb_str_new(RSTRING(RMATCH(match)->str)->ptr, RMATCH(match)->BEG(0)); + if (OBJ_TAINTED(match)) OBJ_TAINT(str); + rb_m17n_copy_encoding(str, RMATCH(match)->str); + return str; } VALUE rb_reg_match_post(match) VALUE match; { + VALUE str; + if (NIL_P(match)) return Qnil; if (RMATCH(match)->BEG(0) == -1) return Qnil; - return rb_str_new(RSTRING(RMATCH(match)->str)->ptr+RMATCH(match)->END(0), - RSTRING(RMATCH(match)->str)->len-RMATCH(match)->END(0)); + str = rb_str_new(RSTRING(RMATCH(match)->str)->ptr+RMATCH(match)->END(0), + RSTRING(RMATCH(match)->str)->len-RMATCH(match)->END(0)); + if (OBJ_TAINTED(match)) OBJ_TAINT(str); + rb_m17n_copy_encoding(str, RMATCH(match)->str); + return str; } VALUE @@ -761,7 +773,7 @@ rb_reg_initialize_m(argc, argv, self) VALUE *argv; VALUE self; { - m17n_encoding *enc; + m17n_encoding *enc = ruby_default_encoding; VALUE src; int flag = 0; @@ -852,7 +864,7 @@ rb_reg_s_quote(argc, argv) for (; s < send; s++) { if (ismbchar(*s)) { - int n = mbclen(*s); + int n = m17n_mbcspan(enc, s, send); while (n-- && s < send) *t++ = *s++; @@ -917,11 +929,12 @@ rb_reg_regsub(str, src, regs) while (s < e) { char *ss = s; - c = *s++; + c = *s; if (ismbchar(c)) { - s += mbclen(c) - 1; + s += m17n_mbcspan(enc, s, e); continue; } + s++; if (c != '\\' || s == e) continue; if (!val) val = rb_str_new(p, ss-p); @@ -21,7 +21,7 @@ /* Perl5 extension added by matz <matz@caelum.co.jp> */ /* UTF-8 extension added Jan 16 1999 by Yoshida Masato <yoshidam@tau.bekkoame.ne.jp> */ /* modified for Ruby by matz@netlab.co.jp */ -/* M17n modify by matz@zetabits.com */ +/* M17n modify by matz@netlab.jp */ #include "config.h" @@ -371,8 +371,8 @@ enum regexpcode #define PATFETCH_MBC(c) \ do { \ - if (p + mbclen(c) - 1 >= pend) goto end_of_pattern; \ - MBC2WC(c, p, pend); \ + if (m17n_mbcspan(enc, p, pend) == 0) goto end_of_pattern; \ + MBC2WC(c, p, pend); \ } while(0) #define WC2MBC1ST(c) m17n_firstbyte(enc, (c)) @@ -1476,7 +1476,6 @@ re_compile_pattern(pattern, size, bufp) int ch; char is_alnum = STREQ(str, "alnum"); char is_alpha = STREQ(str, "alpha"); - char is_blank = STREQ(str, "blank"); char is_cntrl = STREQ(str, "cntrl"); char is_digit = STREQ(str, "digit"); char is_graph = STREQ(str, "graph"); @@ -2272,20 +2271,19 @@ re_compile_pattern(pattern, size, bufp) bufp->must = calculate_must_string(bufp->buffer, b); } if (bufp->must) { - if (!m17n_islead(enc, bufp->must[1])) { - bufp->options |= RE_OPTIMIZE_NO_BM; - } - else { - int i; - int len = (unsigned char)bufp->must[0]; + int i; + int len = (unsigned char)bufp->must[0]; - for (i=1; i<len; i++) { - if ((unsigned char)bufp->must[i] == 0xff) { - bufp->options |= RE_OPTIMIZE_NO_BM; - break; - } + for (i=1; i<len; i++) { + if ((unsigned char)bufp->must[i] == 0xff) { + bufp->options |= RE_OPTIMIZE_NO_BM; + bufp->options &= ~RE_OPTIMIZE_EXACTN; + break; } } + if (!m17n_islead(enc, bufp->must[1])) { + bufp->options &= ~RE_OPTIMIZE_EXACTN; + } if (!(bufp->options & RE_OPTIMIZE_NO_BM)) { bufp->must_skip = (int *) xmalloc((1 << BYTEWIDTH)*sizeof(int)); bm_init_skip(bufp->must_skip, (unsigned char*)bufp->must+1, @@ -2651,11 +2649,7 @@ re_compile_fastmap(bufp) { case exactn: if (p[1] == 0xff) { - if (TRANSLATE_P()) - fastmap[m17n_toupper(enc, p[2])] = 2; - else - fastmap[p[2]] = 2; - bufp->options |= RE_OPTIMIZE_BMATCH; + fastmap[p[2]] = 2; } else if (TRANSLATE_P()) fastmap[m17n_toupper(enc, p[1])] = 1; @@ -2835,7 +2829,6 @@ re_compile_fastmap(bufp) single-byte chars. We must reject them. */ if (c < 0x100) { fastmap[beg] = 2; - bufp->options |= RE_OPTIMIZE_BMATCH; } else if (ismbchar(beg)) fastmap[beg] = 1; @@ -2939,7 +2932,7 @@ re_adjust_startpos(bufp, string, size, startpos, range) } /* Adjust startpos for mbc string */ - if (enc->index != 0 && startpos>0 && !(bufp->options&RE_OPTIMIZE_BMATCH)) { + if (m17n_mbmaxlen(enc) > 1 && startpos > 0) { int i = 0; if (range > 0) { @@ -3315,7 +3308,7 @@ re_search(bufp, string, size, startpos, range, regs) #define AT_STRINGS_BEG(d) ((d) == string) #define AT_STRINGS_END(d) ((d) == dend) -#define IS_A_LETTER(d) (m17n_mbclen(enc, *d) == 1 ? m17n_iswchar(enc, *d) : 1) +#define IS_A_LETTER(d) m17n_iswchar(enc, m17n_codepoint(enc, d, dend)) #define PREV_IS_A_LETTER(d) ((enc->index == 3)? /* SJIS hack */ \ IS_A_LETTER((d)-(!AT_STRINGS_BEG((d)-1)&& \ ismbchar((d)[-2])?2:1)): \ @@ -3614,7 +3607,7 @@ re_match(bufp, string_arg, size, pos, regs) /* Compare that many; failure if mismatch, else move past them. */ if ((options & RE_OPTION_IGNORECASE) - ? m17n_memcmp(d, d2, mcnt, enc) + ? m17n_casecmp(d, d2, mcnt, enc) : memcmp(d, d2, mcnt)) goto fail; d += mcnt, d2 += mcnt; @@ -84,13 +84,6 @@ #define RE_OPTIMIZE_ANCHOR (RE_MAY_IGNORECASE<<1) #define RE_OPTIMIZE_EXACTN (RE_OPTIMIZE_ANCHOR<<1) #define RE_OPTIMIZE_NO_BM (RE_OPTIMIZE_EXACTN<<1) -#define RE_OPTIMIZE_BMATCH (RE_OPTIMIZE_NO_BM<<1) - -/* For multi-byte char support */ -#define MBCTYPE_ASCII 0 -#define MBCTYPE_EUC 1 -#define MBCTYPE_SJIS 2 -#define MBCTYPE_UTF8 3 #if defined IMPORT || defined USEIMPORTLIB extern __declspec(dllimport) @@ -37,6 +37,7 @@ char *strstr _((const char*,const char*)); #endif #include "util.h" +#include "m17n.h" #ifndef HAVE_STDLIB_H char *getenv(); @@ -34,16 +34,11 @@ extern "C" { #include <stddef.h> #include <stdio.h> -/* need to include <ctype.h> to use these macros */ -#undef ISPRINT -#define ISPRINT(c) isprint((unsigned char)(c)) -#define ISSPACE(c) isspace((unsigned char)(c)) -#define ISUPPER(c) isupper((unsigned char)(c)) -#define ISLOWER(c) islower((unsigned char)(c)) -#define ISALNUM(c) isalnum((unsigned char)(c)) -#define ISALPHA(c) isalpha((unsigned char)(c)) -#define ISDIGIT(c) isdigit((unsigned char)(c)) -#define ISXDIGIT(c) isxdigit((unsigned char)(c)) +#include "m17n.h" +#define ISSPACE(c) m17n_isspace(ruby_default_encoding, (c)) +#define ISALPHA(c) m17n_isalpha(ruby_default_encoding, (c)) +#define ISALNUM(c) m17n_isalnum(ruby_default_encoding, (c)) +#define ISDIGIT(c) m17n_isdigit(ruby_default_encoding, (c)) #ifndef __STDC__ # define volatile @@ -326,28 +326,40 @@ rb_f_sprintf(argc, argv) } len = RSTRING(str)->len; if (flags&(FPREC|FWIDTH)) { - slen = m17n_strlen(enc, RSTRING(str)->ptr, RSTRING(str)->ptr+len); + slen = m17n_swidth(enc, RSTRING(str)->ptr, RSTRING(str)->ptr+len); if (slen < 0) { rb_raise(rb_eArgError, "invalid mbstring sequence"); } } if (flags&FPREC) { if (prec < slen) { + int i, n; char *p; slen = prec; - p = m17n_nth(enc, RSTRING(str)->ptr, - RSTRING(str)->ptr + RSTRING(str)->len, - prec); - if (p == (char*)-1) { - rb_raise(rb_eArgError, "invalid mbstring sequence"); + for (i=1; 1; i++) { + p = m17n_nth(enc, RSTRING(str)->ptr, + RSTRING(str)->ptr + RSTRING(str)->len, + i); + if (p == (char*)-1) { + rb_raise(rb_eArgError, "invalid mbstring sequence"); + } + n = m17n_swidth(enc, RSTRING(str)->ptr, p); + if (n == prec) break; + if (n > prec) { + p = m17n_nth(enc, RSTRING(str)->ptr, + RSTRING(str)->ptr + RSTRING(str)->len, + i-1); + slen = m17n_swidth(enc, RSTRING(str)->ptr, p); + break; + } } len = p - RSTRING(str)->ptr; } } if (flags&FWIDTH) { if (width > slen) { - CHECK(width - slen + len); + CHECK(width + len); width -= slen; if (!(flags&FMINUS)) { while (width--) { @@ -364,7 +376,18 @@ rb_f_sprintf(argc, argv) break; } } + CHECK(len); PUSH(RSTRING(str)->ptr, len); + if (flags&FPREC) { + if (prec > slen) { + int n = prec - slen; + + CHECK(n); + while (n--) { + buf[blen++] = ' '; + } + } + } } break; @@ -87,7 +87,7 @@ str_memcmp(p1, p2, len, enc) if (!ruby_ignorecase) { return memcmp(p1, p2, len); } - return m17n_memcmp(p1, p2, len, enc); + return m17n_casecmp(p1, p2, len, enc); } void @@ -102,16 +102,16 @@ rb_m17n_enc_check(str1, str2, enc) enc2 = rb_m17n_get_encoding(str2); if (enc1->index == 0 && m17n_asciicompat(enc2)) { - *enc = enc2; + if (enc) *enc = enc2; } else if (enc2->index == 0 && m17n_asciicompat(enc1)) { - *enc = enc1; + if (enc) *enc = enc1; } else if (enc1 != enc2) { rb_raise(rb_eArgError, "character encodings differ"); } else { - *enc = enc1; + if (enc) *enc = enc1; } } @@ -237,6 +237,7 @@ rb_str_new4(orig) } OBJ_FREEZE(str); RBASIC(str)->klass = klass; + rb_m17n_copy_encoding(str, orig); return str; } else { @@ -247,9 +248,9 @@ rb_str_new4(orig) str->ptr = str_ptr(orig); RSTRING(orig)->orig = (VALUE)str; str->orig = 0; - rb_m17n_associate_encoding((VALUE)str, rb_m17n_get_encoding(orig)); OBJ_INFECT(str, orig); OBJ_FREEZE(str); + rb_m17n_copy_encoding((VALUE)str, orig); return (VALUE)str; } @@ -416,7 +417,7 @@ rb_str_length(str) } static VALUE -rb_str_size(str) +rb_str_bufsize(str) VALUE str; { return INT2NUM(str_len(str)); @@ -437,6 +438,7 @@ rb_str_plus(str1, str2) { VALUE str3; + rb_m17n_enc_check(str1, str2, 0); if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2); str3 = rb_str_new(0, str_len(str1)+str_len(str2)); memcpy(str_ptr(str3), str_ptr(str1), str_len(str1)); @@ -518,7 +520,7 @@ str_sublen(str, len, enc) int len; m17n_encoding *enc; { - if (m17n_mbmaxlen(enc) == 1) return len; + if (m17n_mbmaxlen(enc) == 1 || len < 0) return len; else { char *p = str_ptr(str); char *e = p + len; @@ -526,7 +528,7 @@ str_sublen(str, len, enc) i = 0; while (p < e) { - p += mbclen(*p); + p += m17n_mbcspan(enc, p, e); i++; } return i; @@ -706,48 +708,16 @@ int rb_str_hash(str) VALUE str; { - m17n_encoding *enc = rb_m17n_get_encoding(str); register long len = str_len(str); register char *p = str_ptr(str); register int key = 0; -#ifdef HASH_ELFHASH - register unsigned int g; - while (len--) { - key = (key << 4) + *p++; - if (g = key & 0xF0000000) - key ^= g >> 24; - key &= ~g; - } -#elif HASH_PERL - if (ruby_ignorecase) { - while (len--) { - key = key*33 + toupper(*p); - p++; - } - } - else { - while (len--) { - key = key*33 + *p++; - } - } - key = key + (key>>5); -#else - if (ruby_ignorecase) { - while (len--) { - key = key*65599 + m17n_toupper(enc, *p); - p++; - } - } - else { - while (len--) { - key = key*65599 + *p; - p++; - } + key = key*65599 + *p; + p++; } key = key + (key>>5); -#endif + return key; } @@ -868,7 +838,7 @@ rb_str_index(str, sub, offset) return offset; } offset++; - s += m17n_mbclen(enc, *s); + s += m17n_mbcspan(enc, s, e); } return -1; } @@ -975,13 +945,14 @@ rb_str_rindex(argc, argv, str) sbeg = str_ptr(str); e = str_end(str); t = str_ptr(sub); - do { + for (;;) { s = str_nth(enc, sbeg, e, pos); if (str_memcmp(s, t, len, enc) == 0) { return INT2NUM(pos); } + if (pos == 0) break; pos--; - } while (sbeg <= s); + } break; case T_FIXNUM: @@ -1048,7 +1019,7 @@ rb_str_succ(orig) e = str_end(str); while (sbeg <= s) { - int c = m17n_codepoint(enc, s, e); + unsigned int c = m17n_codepoint(enc, s, e); if (m17n_isalnum(enc, c)) { if ((c = succ_char(s)) == 0) break; n = s - sbeg; @@ -1321,7 +1292,8 @@ rb_str_aset_m(argc, argv, str) beg = NUM2INT(argv[0]); len = NUM2INT(argv[1]); if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len); - slen = str_strlen(str); + rb_m17n_enc_check(str, argv[2], &enc); + slen = str_strlen(str, enc); if (beg < 0) { beg += slen; } @@ -1334,7 +1306,6 @@ rb_str_aset_m(argc, argv, str) if (beg + len > slen) { len = slen - beg; } - rb_m17n_enc_check(str, argv[2], &enc); b = str_nth(enc, str_ptr(str), str_end(str), beg) - str_ptr(str); l = str_nth(enc, str_ptr(str), str_end(str), beg+len) - str_ptr(str) - b; rb_str_replace(str, b, l, argv[2]); @@ -1527,7 +1498,7 @@ str_gsub(argc, argv, str, bang) * Always consume at least one character of the input string * in order to prevent infinite loops. */ - len = mbclen(str_ptr(str)[END(0)]); + len = m17n_mbcspan(enc, str_ptr(str)+END(0), str_end(str)); if (str_len(str) > END(0)) { memcpy(bp, str_ptr(str)+END(0), len); bp += len; @@ -1772,14 +1743,14 @@ rb_str_inspect(str) m17n_encoding *enc = rb_m17n_get_encoding(str); char *p, *pend; VALUE result = rb_str_new2("\""); - char s[5]; + char s[8]; p = str_ptr(str); pend = p + str_len(str); while (p < pend) { - char c = *p++; + char c = *p; if (ismbchar(c) && p < pend) { - int len = mbclen(c); - rb_str_cat(result, p - 1, len); + int len = m17n_mbcspan(enc, p, pend); + rb_str_cat(result, p, len); p += len - 1; } else if (c == '"'|| c == '\\') { @@ -1822,6 +1793,7 @@ rb_str_inspect(str) sprintf(s, "\\%03o", c & 0377); rb_str_cat2(result, s); } + p++; } rb_str_cat2(result, "\""); @@ -2595,13 +2567,13 @@ rb_str_split_m(argc, argv, str) regs = RMATCH(rb_backref_get())->regs; if (start == end && BEG(0) == END(0)) { if (last_null == 1) { - tmp = rb_str_new(str_ptr(str)+beg, mbclen(str_ptr(str)[beg])); + tmp = rb_str_new(str_ptr(str)+beg, m17n_mbcspan(enc, str_ptr(str)+beg, str_end(str))); rb_m17n_copy_encoding(tmp, str); rb_ary_push(result, tmp); beg = start; } else { - start += mbclen(str_ptr(str)[start]); + start += m17n_mbcspan(enc, str_ptr(str)+start, str_end(str)); last_null = 1; continue; } @@ -2739,6 +2711,25 @@ rb_str_each_byte(str) } static VALUE +rb_str_each_char(str) + VALUE str; +{ + m17n_encoding *enc = rb_m17n_get_encoding(str); + char *p, *pend; + unsigned int c; + + p = RSTRING(str)->ptr; + pend = p + str_len(str); + + while (p < pend) { + c = m17n_codepoint(enc, p, pend); + rb_yield(INT2FIX(c)); + p += m17n_codelen(enc, c); + } + return str; +} + +static VALUE rb_str_chop_bang(str) VALUE str; { @@ -2928,7 +2919,7 @@ scan_once(str, pat, start) /* * Always consume at least one character of the input string */ - *start = END(0)+mbclen(str_ptr(str)[END(0)]); + *start = END(0)+m17n_mbcspan(enc, str_ptr(str)+END(0),str_end(str)); } else { *start = END(0); @@ -3082,41 +3073,76 @@ rb_str_sum(argc, argv, str) } static VALUE -rb_str_ljust(str, w) +space_pad(str, pre, post, c, enc) VALUE str; - VALUE w; + int pre; + int post; + int c; + m17n_encoding *enc; { - long width = NUM2LONG(w); + long width = m17n_swidth(enc, str_ptr(str), str_end(str)); VALUE res; - char *p, *pend; + long offset = 0, capa, i, clen; - if (width < 0 || str_len(str) >= width) return str; - res = rb_str_new(0, width); - memcpy(str_ptr(res), str_ptr(str), str_len(str)); - p = str_end(res); pend = str_ptr(res) + width; - while (p < pend) { - *p++ = ' '; + if (width < 0) return str; /* can't calculate column width */ + + clen = m17n_codelen(enc, c); + capa = str_len(str)+(pre+post)*clen; + res = rb_str_new(0, capa); + rb_m17n_copy_encoding(res, str); + + for (i=0; i<pre; i++) { + if (offset + clen >= capa) { + capa *= 2; + rb_str_resize(res, capa); + } + m17n_mbcput(enc, c, str_ptr(res)+offset); + offset += clen; + } + if (offset + str_len(str) > capa) { + capa *= 2; + rb_str_resize(res, capa); } + memcpy(str_ptr(res)+offset, str_ptr(str), str_len(str)); + offset += str_len(str); + for (i=0; i<post; i++) { + if (offset + clen >= capa) { + capa *= 2; + rb_str_resize(res, capa); + } + m17n_mbcput(enc, c, str_ptr(res)+offset); + offset += clen; + } + rb_str_resize(res, offset); return res; } static VALUE +rb_str_ljust(str, w) + VALUE str; + VALUE w; +{ + m17n_encoding *enc = rb_m17n_get_encoding(str); + long width = NUM2LONG(w); + + if (width < 0) return str; + width -= str_strlen(str, enc); + if (width < 0) return str; + return space_pad(str, 0, width, ' ', enc); +} + +static VALUE rb_str_rjust(str, w) VALUE str; VALUE w; { + m17n_encoding *enc = rb_m17n_get_encoding(str); long width = NUM2LONG(w); - VALUE res; - char *p, *pend; - if (width < 0 || str_len(str) >= width) return str; - res = rb_str_new(0, width); - p = str_ptr(res); pend = p + width - str_len(str); - while (p < pend) { - *p++ = ' '; - } - memcpy(pend, str_ptr(str), str_len(str)); - return res; + if (width < 0) return str; + width -= str_strlen(str, enc); + if (width < 0) return str; + return space_pad(str, width, 0, ' ', enc); } static VALUE @@ -3124,24 +3150,15 @@ rb_str_center(str, w) VALUE str; VALUE w; { + m17n_encoding *enc = rb_m17n_get_encoding(str); long width = NUM2LONG(w); - VALUE res; - char *p, *pend; long n; - if (width < 0 || str_len(str) >= width) return str; - res = rb_str_new(0, width); - n = (width - str_len(str))/2; - p = str_ptr(res); pend = p + n; - while (p < pend) { - *p++ = ' '; - } - memcpy(pend, str_ptr(str), str_len(str)); - p = pend + str_len(str); pend = str_ptr(res) + width; - while (p < pend) { - *p++ = ' '; - } - return res; + if (width < 0) return str; + width -= str_strlen(str, enc); + if (width < 0) return str; + n = width/2; + return space_pad(str, n, width - n, ' ', enc); } void @@ -3163,7 +3180,7 @@ Init_String() rb_include_module(rb_cString, rb_mComparable); rb_include_module(rb_cString, rb_mEnumerable); rb_define_singleton_method(rb_cString, "new", rb_str_s_new, -1); - rb_define_method(rb_cString, "initialize", rb_str_initialize, 1); + rb_define_method(rb_cString, "initialize", rb_str_initialize, -1); rb_define_method(rb_cString, "clone", rb_str_clone, 0); rb_define_method(rb_cString, "dup", rb_str_dup, 0); rb_define_method(rb_cString, "<=>", rb_str_cmp_m, 1); @@ -3177,7 +3194,8 @@ Init_String() rb_define_method(rb_cString, "[]", rb_str_aref_m, -1); rb_define_method(rb_cString, "[]=", rb_str_aset_m, -1); rb_define_method(rb_cString, "length", rb_str_length, 0); - rb_define_method(rb_cString, "size", rb_str_size, 0); + rb_define_method(rb_cString, "size", rb_str_length, 0); + rb_define_method(rb_cString, "buffer_size", rb_str_bufsize, 0); rb_define_method(rb_cString, "empty?", rb_str_empty, 0); rb_define_method(rb_cString, "=~", rb_str_match, 1); rb_define_method(rb_cString, "~", rb_str_match2, 0); @@ -3251,6 +3269,7 @@ Init_String() rb_define_method(rb_cString, "each_line", rb_str_each_line, -1); rb_define_method(rb_cString, "each", rb_str_each_line, -1); rb_define_method(rb_cString, "each_byte", rb_str_each_byte, 0); + rb_define_method(rb_cString, "each_char", rb_str_each_char, 0); rb_define_method(rb_cString, "sum", rb_str_sum, -1); |
