summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-07-09 05:26:54 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-07-09 05:26:54 +0000
commit11466a5e5a063fd7f0125be815d90d8ee36df7de (patch)
tree722a07b93029d42c4c3d50733603c46f7dbfde30
parent7ce7d911e6aa0ce0d33d6b52f91b889f203e7271 (diff)
downloadruby-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.c21
-rw-r--r--ext/dbm/dbm.c2
-rw-r--r--ext/dbm/extconf.rb53
-rw-r--r--ext/readline/extconf.rb3
-rw-r--r--ext/readline/readline.c14
-rw-r--r--intern.h9
-rw-r--r--io.c5
-rw-r--r--m17n.c161
-rw-r--r--m17n.h11
-rw-r--r--numeric.c35
-rw-r--r--re.c31
-rw-r--r--regex.c41
-rw-r--r--regex.h7
-rw-r--r--ruby.c1
-rw-r--r--ruby.h15
-rw-r--r--sprintf.c37
-rw-r--r--string.c207
17 files changed, 440 insertions, 213 deletions
diff --git a/eval.c b/eval.c
index 1775080284..591bd05f30 100644
--- a/eval.c
+++ b/eval.c
@@ -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++) {
diff --git a/intern.h b/intern.h
index 2441070a0a..899503f4f7 100644
--- a/intern.h
+++ b/intern.h
@@ -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));
diff --git a/io.c b/io.c
index f0a237ccbd..5833aaddfd 100644
--- a/io.c
+++ b/io.c
@@ -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);
diff --git a/m17n.c b/m17n.c
index 56170e63e3..20df12cd63 100644
--- a/m17n.c
+++ b/m17n.c
@@ -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;
diff --git a/m17n.h b/m17n.h
index 9aa9bd8318..4807a19420 100644
--- a/m17n.h
+++ b/m17n.h
@@ -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 */
diff --git a/numeric.c b/numeric.c
index 0dd86f0532..5dc9115d45 100644
--- a/numeric.c
+++ b/numeric.c
@@ -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);
diff --git a/re.c b/re.c
index bf5975108c..79bef15fc0 100644
--- a/re.c
+++ b/re.c
@@ -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);
diff --git a/regex.c b/regex.c
index 0ec6fad42f..4ff68c5749 100644
--- a/regex.c
+++ b/regex.c
@@ -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;
diff --git a/regex.h b/regex.h
index bef5bd79ae..83cfe20eb7 100644
--- a/regex.h
+++ b/regex.h
@@ -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)
diff --git a/ruby.c b/ruby.c
index 9649b69af4..0ab63c34d9 100644
--- a/ruby.c
+++ b/ruby.c
@@ -37,6 +37,7 @@ char *strstr _((const char*,const char*));
#endif
#include "util.h"
+#include "m17n.h"
#ifndef HAVE_STDLIB_H
char *getenv();
diff --git a/ruby.h b/ruby.h
index f00f39b935..1d8425506a 100644
--- a/ruby.h
+++ b/ruby.h
@@ -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
diff --git a/sprintf.c b/sprintf.c
index 8f20faff1e..baeb7fb5b9 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -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;
diff --git a/string.c b/string.c
index d5828eda5d..eba3eb431b 100644
--- a/string.c
+++ b/string.c
@@ -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);