diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-25 03:29:39 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-25 03:29:39 +0000 |
commit | a25fbe3b3e531bbe479f344af24eaf9d2eeae6ea () | |
tree | 055e58ed569fb28012fadade94f518e0a888e47d | |
parent | 0ada813abfe3a049da29bd423ba34606a00777bd (diff) |
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing. * parse.y (pragma_encoding): encoding specification pragma. * parse.y (rb_intern3): encoding specified symbols. * string.c (rb_str_length): length based on characters. for older behavior, bytesize method added. * string.c (rb_str_index_m): index based on characters. rindex as well. * string.c (succ_char): encoding aware succeeding string. * string.c (rb_str_reverse): reverse based on characters. * string.c (rb_str_inspect): encoding aware string description. * string.c (rb_str_upcase_bang): encoding aware case conversion. downcase, capitalize, swapcase as well. * string.c (rb_str_tr_bang): tr based on characters. delete, squeeze, tr_s, count as well. * string.c (rb_str_split_m): split based on characters. * string.c (rb_str_each_line): encoding aware each_line. * string.c (rb_str_each_char): added. iteration based on characters. * string.c (rb_str_strip_bang): encoding aware whitespace stripping. lstrip, rstrip as well. * string.c (rb_str_justify): encoding aware justifying (ljust, rjust, center). * string.c (str_encoding): get encoding attribute from a string. * re.c (rb_reg_initialize): encoding aware regular expression * sprintf.c (rb_str_format): formatting (i.e. length count) based on characters. * io.c (rb_io_getc): getc to return one-character string. for older behavior, getbyte method added. * ext/stringio/stringio.c (strio_getc): ditto. * io.c (rb_io_ungetc): allow pushing arbitrary string at the current reading point. * ext/stringio/stringio.c (strio_ungetc): ditto. * ext/strscan/strscan.c: encoding support. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
113 files changed, 1423 insertions, 752 deletions
@@ -1,3 +1,63 @@ Sat Aug 25 10:59:19 2007 Koichi Sasada <[email protected]> * cont.c: separate Continuation and Fiber from core. @@ -6,7 +6,7 @@ $Date$ created at: Fri Aug 6 09:46:12 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Fri Jun 10 00:48:55 JST 1994 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 15:05:44 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -25,6 +25,7 @@ OBJS = array.$(OBJEXT) \ compar.$(OBJEXT) \ dir.$(OBJEXT) \ dln.$(OBJEXT) \ enum.$(OBJEXT) \ enumerator.$(OBJEXT) \ error.$(OBJEXT) \ @@ -401,6 +402,7 @@ dmydln.$(OBJEXT): {$(VPATH)}dmydln.c {$(VPATH)}dln.c {$(VPATH)}ruby.h \ {$(VPATH)}config.h {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \ {$(VPATH)}dln.h dmyext.$(OBJEXT): {$(VPATH)}dmyext.c enum.$(OBJEXT): {$(VPATH)}enum.c {$(VPATH)}ruby.h {$(VPATH)}config.h \ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \ {$(VPATH)}node.h {$(VPATH)}util.h @@ -523,7 +525,7 @@ sprintf.$(OBJEXT): {$(VPATH)}sprintf.c {$(VPATH)}ruby.h {$(VPATH)}config.h \ st.$(OBJEXT): {$(VPATH)}st.c {$(VPATH)}config.h {$(VPATH)}st.h {$(VPATH)}defines.h string.$(OBJEXT): {$(VPATH)}string.c {$(VPATH)}ruby.h {$(VPATH)}config.h \ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \ - {$(VPATH)}re.h {$(VPATH)}regex.h struct.$(OBJEXT): {$(VPATH)}struct.c {$(VPATH)}ruby.h {$(VPATH)}config.h \ {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h thread.$(OBJEXT): {$(VPATH)}thread.c {$(VPATH)}eval_intern.h \ @@ -6,7 +6,7 @@ $Date$ created at: Thu Aug 26 14:39:48 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Wed Jan 5 09:51:01 JST 1994 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Tue Jan 18 17:05:06 JST 1994 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Wed Jan 19 16:53:09 JST 1994 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 1 15:15:19 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Mon Aug 9 16:11:34 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -78,8 +78,9 @@ static int code_to_mbclen(OnigCodePoint code) { if (ONIGENC_IS_CODE_ASCII(code)) return 1; - else if ((code & 0xff0000) != 0) return 3; - else if ((code & 0xff00) != 0) return 2; else return 0; } @@ -6,7 +6,7 @@ $Date$ created at: Thu Jun 10 14:22:17 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Thu Mar 31 12:21:29 JST 1994 - Copyright (C) 1993-2001 Yukihiro Matsumoto ************************************************/ @@ -13,7 +13,7 @@ **********************************************************************/ #include "ruby.h" -#include "rubyio.h" #if defined(HAVE_FCNTL_H) || defined(_WIN32) #include <fcntl.h> #elif defined(HAVE_SYS_FCNTL_H) @@ -84,6 +84,18 @@ get_strio(VALUE self) return ptr; } #define StringIO(obj) get_strio(obj) #define CLOSED(ptr) (!((ptr)->flags & FMODE_READWRITE)) @@ -603,7 +615,7 @@ strio_each_byte(VALUE self) /* * call-seq: - * strio.getc -> fixnum or nil * * See IO#getc. */ @@ -611,15 +623,17 @@ static VALUE strio_getc(VALUE self) { struct StringIO *ptr = readable(StringIO(self)); - int c; - char ch; if (ptr->pos >= RSTRING_LEN(ptr->string)) { return Qnil; } - c = RSTRING_PTR(ptr->string)[ptr->pos++]; - ch = c & 0xff; - return rb_str_new(&ch, 1); } /* @@ -671,30 +685,34 @@ static VALUE strio_ungetc(VALUE self, VALUE c) { struct StringIO *ptr = readable(StringIO(self)); - int cc; - long len, pos = ptr->pos; if (NIL_P(c)) return Qnil; if (FIXNUM_P(c)) { - cc = FIX2INT(c); } else { SafeStringValue(c); - if (RSTRING_LEN(c) > 1) { - rb_warn("IO#ungetc pushes back only one byte"); - } - cc = (unsigned char)RSTRING_PTR(c)[0]; } - if (cc != EOF && pos > 0) { - if ((len = RSTRING_LEN(ptr->string)) < pos-- || - (unsigned char)RSTRING_PTR(ptr->string)[pos] != - (unsigned char)cc) { - strio_extend(ptr, pos, 1); - RSTRING_PTR(ptr->string)[pos] = cc; - OBJ_INFECT(ptr->string, self); - } - --ptr->pos; } return Qnil; } @@ -800,7 +818,7 @@ strio_getline(int argc, VALUE *argv, struct StringIO *ptr) e = s + limit; } if (NIL_P(str)) { - str = rb_str_substr(ptr->string, ptr->pos, e - s); } else if ((n = RSTRING_LEN(str)) == 0) { p = s; @@ -816,13 +834,13 @@ strio_getline(int argc, VALUE *argv, struct StringIO *ptr) break; } } - str = rb_str_substr(ptr->string, s - RSTRING_PTR(ptr->string), e - s); } else if (n == 1) { if ((p = memchr(s, RSTRING_PTR(str)[0], e - s)) != 0) { e = p + 1; } - str = rb_str_substr(ptr->string, ptr->pos, e - s); } else { if (n < e - s) { @@ -843,7 +861,7 @@ strio_getline(int argc, VALUE *argv, struct StringIO *ptr) } } } - str = rb_str_substr(ptr->string, ptr->pos, e - s); } ptr->pos = e - RSTRING_PTR(ptr->string); ptr->lineno++; @@ -944,7 +962,7 @@ strio_write(VALUE self, VALUE str) if (TYPE(str) != T_STRING) str = rb_obj_as_string(str); len = RSTRING_LEN(str); - if (!len) return INT2FIX(0); check_modifiable(ptr); olen = RSTRING_LEN(ptr->string); if (ptr->flags & FMODE_APPEND) { @@ -955,7 +973,8 @@ strio_write(VALUE self, VALUE str) } else { strio_extend(ptr, ptr->pos, len); - rb_str_update(ptr->string, ptr->pos, len, str); } OBJ_INFECT(ptr->string, self); ptr->pos += len; @@ -1070,7 +1089,7 @@ strio_read(int argc, VALUE *argv, VALUE self) rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc); } if (NIL_P(str)) { - str = rb_str_substr(ptr->string, ptr->pos, len); } else { long rest = RSTRING_LEN(ptr->string) - ptr->pos; @@ -10,6 +10,7 @@ #include "ruby/ruby.h" #include "ruby/re.h" #define STRSCAN_VERSION "0.7.0" @@ -189,6 +190,7 @@ strscan_initialize(int argc, VALUE *argv, VALUE self) rb_scan_args(argc, argv, "11", &str, &need_dup); StringValue(str); p->str = str; return self; } @@ -652,13 +654,14 @@ strscan_getch(VALUE self) { struct strscanner *p; long len; GET_SCANNER(self, p); CLEAR_MATCH_STATUS(p); if (EOS_P(p)) return Qnil; - len = mbclen(*CURPTR(p)); if (p->curr + len > S_LEN(p)) { len = S_LEN(p) - p->curr; } @@ -7,7 +7,7 @@ * Copyright (C) 2003 why the lucky stiff * * All Base64 code from Ruby's pack.c. - * Ruby is Copyright (C) 1993-2003 Yukihiro Matsumoto */ #include "ruby/ruby.h" @@ -1,3 +1,4 @@ # # animated label widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # animated wave demo (called by 'widget') # @@ -1,3 +1,4 @@ # # arrowhead widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # text (tag bindings) widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # bitmap widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # button widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # checkbutton widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # checkbutton widget demo2 (called by 'widget') # @@ -1,3 +1,4 @@ # # widget demo prompts the user to select a color (called by 'widget') # @@ -1,3 +1,4 @@ # # listbox widget demo 'colors' (called by 'widget') # @@ -1,3 +1,4 @@ # # simple scrollable canvas widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # Canvas Text widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # a dialog box with a local grab (called by 'widget') # @@ -1,3 +1,4 @@ # # a dialog box with a global grab (called by 'widget') # @@ -1,3 +1,4 @@ # # entry (no scrollbars) widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # entry (with scrollbars) widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # entry3.rb -- # # This demonstration script creates several entry widgets whose @@ -1,3 +1,4 @@ # # widget demo prompts the user to select a file (called by 'widget') # @@ -1,3 +1,4 @@ # # floorDisplay widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # floorDisplay widget demo 2 (called by 'widget') # @@ -1,3 +1,4 @@ # # form widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # Ruby/Tk Goldverg demo (called by 'widget') # @@ -1,4 +1,5 @@ #!/usr/bin/env ruby require 'tk' TkButton.new(nil, @@ -1,3 +1,4 @@ require "tkcanvas" if defined?($hscale_demo) && $hscale_deom @@ -1,3 +1,4 @@ # # iconic button widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # two image widgets demo (called by 'widget') # @@ -1,3 +1,4 @@ # # widget demo 'load image' (called by 'widget') # @@ -1,3 +1,4 @@ # image3.rb # # This demonstration script creates a simple collection of widgets @@ -1,3 +1,4 @@ # # canvas item types widget demo (called by 'widget') # @@ -1,4 +1,5 @@ #!/usr/bin/env ruby # # ixset -- # A nice interface to "xset" to change X server settings @@ -1,3 +1,4 @@ # # label widget demo (called by 'widget') # @@ -1,3 +1,5 @@ # labelframe.rb # # This demonstration script creates a toplevel window containing @@ -1,3 +1,4 @@ # # menus widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # menus widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # menus widget demo (called by 'widget') # @@ -1,3 +1,4 @@ require "tkcanvas" def optionMenu(menubutton, varName, firstValue, *rest) @@ -1,3 +1,4 @@ # # message boxes widget demo (called by 'widget') # @@ -1,3 +1,5 @@ # paned1.rb # # This demonstration script creates a toplevel window containing @@ -1,3 +1,5 @@ # paned2.rb -- # # This demonstration script creates a toplevel window containing @@ -1,3 +1,4 @@ # # This demonstration illustrates how Tcl/Tk can be used to construct # simulations of physical systems. @@ -1,3 +1,4 @@ # # 2-D plot widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # widet demo 'puzzle' (called by 'widget') # @@ -1,3 +1,4 @@ # # radiobutton widget demo (called by 'widget') # @@ -1,3 +1,5 @@ # radio2.rb # # This demonstration script creates a toplevel window containing @@ -1,3 +1,5 @@ # radio3.rb # # This demonstration script creates a toplevel window containing @@ -1,4 +1,5 @@ #!/usr/bin/env ruby # # rolodex -- # ���Υ�����ץȤ� Tom LaStrange �� rolodex �ΰ����Ǥ��� @@ -1,3 +1,4 @@ # # ruler widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # listbox widget demo 'sayings' (called by 'widget') # @@ -1,3 +1,4 @@ # # Text Search widget demo (called by 'widget') # @@ -1,3 +1,5 @@ # spin.rb -- # # This demonstration script creates several spinbox widgets. @@ -1,3 +1,4 @@ # # listbox widget demo 'states' (called by 'widget') # @@ -1,3 +1,4 @@ # # text (display styles) widget demo (called by 'widget') # @@ -1,4 +1,5 @@ #!/usr/bin/env ruby # # tcolor -- # ���Υ�����ץȤ�RGB,HSB,CYM�����򥵥ݡ��Ȥ��� @@ -1,3 +1,4 @@ # # text (basic facilities) widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # text (embedded windows) widget demo (called by 'widget') # @@ -1,3 +1,4 @@ # # text (embedded windows) widget demo 2 (called by 'widget') # @@ -1,3 +1,5 @@ # unicodeout.rb -- # # This demonstration script shows how you can produce output (in label @@ -1,3 +1,4 @@ require "tkcanvas" if defined?($vscale_demo) && $vscale_demo @@ -1,4 +1,5 @@ #!/usr/bin/env ruby # �������������� ( tk.rb �Υ����ɻ��� encoding ����/����˻Ȥ��� ) $KCODE = 'euc' @@ -1,4 +1,5 @@ #!/usr/bin/env ruby require 'tk' require 'tkextlib/vu/charts' @@ -6,7 +6,7 @@ $Date$ created at: Mon Nov 15 12:24:34 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Tue Oct 5 09:44:46 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Mon Nov 22 18:51:18 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Thu Jun 10 14:22:17 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -337,7 +337,7 @@ RUBY_EXTERN VALUE rb_default_rs; RUBY_EXTERN VALUE rb_output_rs; VALUE rb_io_write(VALUE, VALUE); VALUE rb_io_gets(VALUE); -VALUE rb_io_getc(VALUE); VALUE rb_io_ungetc(VALUE, VALUE); VALUE rb_io_close(VALUE); VALUE rb_io_flush(VALUE); @@ -444,7 +444,7 @@ VALUE rb_reg_last_match(VALUE); VALUE rb_reg_match_pre(VALUE); VALUE rb_reg_match_post(VALUE); VALUE rb_reg_match_last(VALUE); -VALUE rb_reg_new(const char*, long, int); VALUE rb_reg_match(VALUE, VALUE); VALUE rb_reg_match2(VALUE); int rb_reg_options(VALUE); @@ -498,6 +498,7 @@ VALUE rb_str_unlocktmp(VALUE); VALUE rb_str_dup_frozen(VALUE); VALUE rb_str_plus(VALUE, VALUE); VALUE rb_str_times(VALUE, VALUE); VALUE rb_str_substr(VALUE, long, long); void rb_str_modify(VALUE); VALUE rb_str_freeze(VALUE); @@ -6,7 +6,7 @@ $Date$ created at: Fri Nov 12 16:47:09 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -22,6 +22,7 @@ extern "C" { #include <stdio.h> #include <errno.h> #if defined(HAVE_STDIO_EXT_H) #include <stdio_ext.h> @@ -44,6 +45,7 @@ typedef struct rb_io_t { int rbuf_off; int rbuf_len; int rbuf_capa; } rb_io_t; #define HAVE_RB_IO_T 1 @@ -6,7 +6,7 @@ $Date$ created at: Fri May 28 15:14:02 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Thu Sep 30 14:18:32 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -5,7 +5,7 @@ $Author$ $Date$ - Copyright (C) 1993-2005 Yukihiro Matsumoto **********************************************************************/ @@ -29,10 +29,8 @@ extern "C" { ONIG_EXTERN OnigEncoding OnigEncDefaultCharEncoding; -#undef ismbchar -#define ismbchar(c) (mbclen((c)) != 1) -#define mbclen(c) \ - ONIGENC_MBC_ENC_LEN(OnigEncDefaultCharEncoding, (UChar* )(&c)) #endif /* ifndef ONIG_RUBY_M17N */ @@ -5,7 +5,7 @@ $Author$ created at: Thu Jun 10 14:26:32 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -455,6 +455,7 @@ struct RString { (!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \ RSTRING(str)->as.ary : \ RSTRING(str)->as.heap.ptr) struct RArray { struct RBasic basic; @@ -598,6 +599,32 @@ enum ruby_value_flags { #define FL_USER6 RUBY_FL_USER6 RUBY_FL_USER7 = (1<<(FL_USHIFT+7)), #define FL_USER7 RUBY_FL_USER7 }; #define SPECIAL_CONST_P(x) (IMMEDIATE_P(x) || !RTEST(x)) @@ -667,6 +694,7 @@ void rb_gc_unregister_address(VALUE*); ID rb_intern(const char*); ID rb_intern2(const char*, long); const char *rb_id2name(ID); ID rb_to_id(VALUE); VALUE rb_id2str(ID); @@ -6,7 +6,7 @@ $Date$ created at: Wed Aug 16 01:15:38 JST 1995 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Thu Mar 9 11:55:53 JST 1995 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Tue Dec 28 16:01:58 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -406,7 +406,7 @@ toregexp (VALUE val) { volatile VALUE tmp = str; /* for GC */ - val = rb_reg_new(RSTRING_PTR(str), RSTRING_LEN(str), flag); } /** @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 15 18:08:59 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -278,27 +278,38 @@ io_unread(rb_io_t *fptr) return; } -static int -io_ungetc(int c, rb_io_t *fptr) { if (fptr->rbuf == NULL) { fptr->rbuf_off = 0; fptr->rbuf_len = 0; - fptr->rbuf_capa = 8192; fptr->rbuf = ALLOC_N(char, fptr->rbuf_capa); } - if (c < 0 || fptr->rbuf_len == fptr->rbuf_capa) { - return -1; - } if (fptr->rbuf_off == 0) { - if (fptr->rbuf_len) - MEMMOVE(fptr->rbuf+1, fptr->rbuf, char, fptr->rbuf_len); - fptr->rbuf_off = 1; } - fptr->rbuf_off--; - fptr->rbuf_len++; - fptr->rbuf[fptr->rbuf_off] = c; - return c; } static rb_io_t * @@ -875,16 +886,10 @@ rb_io_rewind(VALUE io) } static int -io_getc(rb_io_t *fptr) { int r; - if (fptr->fd == 0 && (fptr->mode & FMODE_TTY) && TYPE(rb_stdout) == T_FILE) { - rb_io_t *ofp; - GetOpenFile(rb_stdout, ofp); - if (ofp->mode & FMODE_TTY) { - rb_io_flush(rb_stdout); - } - } if (fptr->rbuf == NULL) { fptr->rbuf_off = 0; fptr->rbuf_len = 0; @@ -906,9 +911,7 @@ io_getc(rb_io_t *fptr) if (r == 0) return -1; /* EOF */ } - fptr->rbuf_off++; - fptr->rbuf_len--; - return (unsigned char)fptr->rbuf[fptr->rbuf_off-1]; } /* @@ -947,20 +950,16 @@ VALUE rb_io_eof(VALUE io) { rb_io_t *fptr; - int ch; GetOpenFile(io, fptr); rb_io_check_readable(fptr); if (READ_DATA_PENDING(fptr)) return Qfalse; READ_CHECK(fptr); - ch = io_getc(fptr); - - if (ch != EOF) { - io_ungetc(ch, fptr); - return Qfalse; } - return Qtrue; } /* @@ -1167,13 +1166,9 @@ io_fread(VALUE str, long offset, rb_io_t *fptr) } rb_thread_wait_fd(fptr->fd); rb_io_check_closed(fptr); - c = io_getc(fptr); - if (c < 0) { break; } - RSTRING_PTR(str)[offset++] = c; - if (offset > RSTRING_LEN(str)) break; - n--; } return len - n; } @@ -1599,9 +1594,7 @@ appendline(rb_io_t *fptr, int delim, VALUE *strp, long *lp) } rb_thread_wait_fd(fptr->fd); rb_io_check_closed(fptr); - c = io_getc(fptr); - limit--; - if (c < 0) { *lp = limit; return c; } @@ -1640,10 +1633,8 @@ swallow(rb_io_t *fptr, int term) } rb_thread_wait_fd(fptr->fd); rb_io_check_closed(fptr); - c = io_getc(fptr); - if (c != term) { - io_ungetc(c, fptr); - return Qtrue; } } while (c != EOF); return Qfalse; @@ -2020,20 +2011,24 @@ static VALUE rb_io_each_byte(VALUE io) { rb_io_t *fptr; - int c; RETURN_ENUMERATOR(io, 0, 0); GetOpenFile(io, fptr); for (;;) { rb_io_check_readable(fptr); READ_CHECK(fptr); - c = io_getc(fptr); - if (c < 0) { break; } - rb_yield(INT2FIX(c & 0xff)); - } return io; } @@ -2070,54 +2065,54 @@ rb_io_bytes(VALUE str) return rb_enumeratorize(str, ID2SYM(rb_intern("each_byte")), 0, 0); } -VALUE -rb_io_getc(VALUE io) -{ - rb_io_t *fptr; - int c; - - GetOpenFile(io, fptr); - rb_io_check_readable(fptr); - - READ_CHECK(fptr); - c = io_getc(fptr); - - if (c < 0) { - return Qnil; - } - return INT2FIX(c & 0xff); -} - /* * call-seq: - * ios.getc => string or nil - * * Reads a one-character string from <em>ios</em>. Returns * <code>nil</code> if called at end of file. - * * f = File.new("testfile") * f.getc #=> "8" * f.getc #=> "1" */ -VALUE -rb_io_getc_m(VALUE io) { - char ch; rb_io_t *fptr; - int c; GetOpenFile(io, fptr); rb_io_check_readable(fptr); READ_CHECK(fptr); - c = io_getc(fptr); - - if (c < 0) { - return Qnil; } - ch = c & 0xff; - return rb_str_new(&ch, 1); } int @@ -2139,14 +2134,74 @@ rb_getc(FILE *f) * call-seq: * ios.readchar => string * - * Reads a character as with <code>IO#getc</code>, but raises an * <code>EOFError</code> on end of file. */ static VALUE rb_io_readchar(VALUE io) { - VALUE c = rb_io_getc_m(io); if (NIL_P(c)) { rb_eof_error(); @@ -2173,25 +2228,24 @@ rb_io_readchar(VALUE io) VALUE rb_io_ungetc(VALUE io, VALUE c) { rb_io_t *fptr; - int cc; GetOpenFile(io, fptr); rb_io_check_readable(fptr); if (NIL_P(c)) return Qnil; if (FIXNUM_P(c)) { - cc = FIX2INT(c); } else { SafeStringValue(c); - if (RSTRING_LEN(c) > 1) { - rb_warn("IO#ungetc pushes back only one byte"); - } - cc = (unsigned char)RSTRING_PTR(c)[0]; - } - if (io_ungetc(cc, fptr) == EOF && cc != EOF) { - rb_raise(rb_eIOError, "ungetc failed"); } return Qnil; } @@ -5465,7 +5519,29 @@ argf_getc(void) ch = rb_funcall3(current_file, rb_intern("getc"), 0, 0); } else { - ch = rb_io_getc_m(current_file); } if (NIL_P(ch) && next_p != -1) { argf_close(current_file); @@ -5479,10 +5555,32 @@ argf_getc(void) static VALUE argf_readchar(void) { VALUE c; NEXT_ARGF_FORWARD(0, 0); - c = argf_getc(); if (NIL_P(c)) { rb_eof_error(); } @@ -5780,8 +5878,10 @@ Init_IO(void) rb_define_method(rb_cIO, "write", io_write, 1); rb_define_method(rb_cIO, "gets", rb_io_gets_m, -1); rb_define_method(rb_cIO, "readline", rb_io_readline, -1); - rb_define_method(rb_cIO, "getc", rb_io_getc_m, 0); rb_define_method(rb_cIO, "readchar", rb_io_readchar, 0); rb_define_method(rb_cIO, "ungetc",rb_io_ungetc, 1); rb_define_method(rb_cIO, "<<", rb_io_addstr, 1); rb_define_method(rb_cIO, "flush", rb_io_flush, 0); @@ -5851,7 +5951,9 @@ Init_IO(void) rb_define_singleton_method(argf, "gets", rb_f_gets, -1); rb_define_singleton_method(argf, "readline", rb_f_readline, -1); rb_define_singleton_method(argf, "getc", argf_getc, 0); rb_define_singleton_method(argf, "readchar", argf_readchar, 0); rb_define_singleton_method(argf, "tell", argf_tell, 0); rb_define_singleton_method(argf, "seek", argf_seek_m, -1); rb_define_singleton_method(argf, "rewind", argf_rewind, 0); @@ -6,7 +6,7 @@ $Date$ created at: Fri Aug 19 13:19:58 JST 1994 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Thu Apr 27 16:30:01 JST 1995 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -1105,7 +1105,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) { volatile VALUE str = r_bytes(arg); int options = r_byte(arg); - v = r_entry(rb_reg_new(RSTRING_PTR(str), RSTRING_LEN(str), options), arg); } break; @@ -6,7 +6,7 @@ $Date$ created at: Tue Jan 25 14:12:56 JST 1994 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Fri Aug 13 18:33:09 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Thu Jul 15 12:01:24 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Thu Feb 10 15:17:05 JST 1994 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Fri May 28 18:02:42 JST 1993 - Copyright (C) 1993-2004 Yukihiro Matsumoto **********************************************************************/ @@ -20,6 +20,8 @@ #include "ruby/intern.h" #include "ruby/node.h" #include "ruby/st.h" #include <stdio.h> #include <errno.h> #include <ctype.h> @@ -255,8 +257,13 @@ struct parser_params { VALUE parsing_thread; int toplevel_p; #endif }; #ifdef YYMALLOC void *rb_parser_malloc(struct parser_params *, size_t); void *rb_parser_realloc(struct parser_params *, void *, size_t); @@ -3555,7 +3562,7 @@ strings : string /*%%%*/ NODE *node = $1; if (!node) { - node = NEW_STR(rb_str_new(0, 0)); } else { node = evstr2dstr(node); @@ -3594,7 +3601,7 @@ xstring : tXSTRING_BEG xstring_contents tSTRING_END /*%%%*/ NODE *node = $2; if (!node) { - node = NEW_XSTR(rb_str_new(0, 0)); } else { switch (nd_type(node)) { @@ -3605,7 +3612,7 @@ xstring : tXSTRING_BEG xstring_contents tSTRING_END nd_set_type(node, NODE_DXSTR); break; default: - node = NEW_NODE(NODE_DXSTR, rb_str_new(0, 0), 1, NEW_LIST(node)); break; } } @@ -3622,20 +3629,18 @@ regexp : tREGEXP_BEG xstring_contents tREGEXP_END int options = $3; NODE *node = $2; if (!node) { - node = NEW_LIT(reg_compile("", 0, options)); } else switch (nd_type(node)) { case NODE_STR: { VALUE src = node->nd_lit; nd_set_type(node, NODE_LIT); - node->nd_lit = reg_compile(RSTRING_PTR(src), - RSTRING_LEN(src), - options); } break; default: - node = NEW_NODE(NODE_DSTR, rb_str_new(0, 0), 1, NEW_LIST(node)); case NODE_DSTR: if (options & RE_OPTION_ONCE) { nd_set_type(node, NODE_DREGX_ONCE); @@ -3880,7 +3885,7 @@ dsym : tSYMBEG xstring_contents tSTRING_END nd_set_type($$, NODE_LIT); break; default: - $$ = NEW_NODE(NODE_DSYM, rb_str_new(0, 0), 1, NEW_LIST($$)); break; } } @@ -4518,7 +4523,7 @@ ripper_dis_scan_event(struct parser_params *parser, int t) if (lex_p < parser->tokp) rb_raise(rb_eRuntimeError, "lex_p < tokp"); if (lex_p == parser->tokp) return; - str = rb_str_new(parser->tokp, lex_p - parser->tokp); yylval.val = ripper_dis1(parser, ripper_token2eventid(t), str); ripper_flush(parser); } @@ -4552,7 +4557,11 @@ ripper_dis_delayed_token(struct parser_params *parser, int t) /* As in Harbison and Steele. */ # define SIGN_EXTEND_CHAR(c) ((((unsigned char)(c)) ^ 128) - 128) #endif -#define is_identchar(c) (SIGN_EXTEND_CHAR(c)!=-1&&(ISALNUM(c) || (c) == '_' || ismbchar(c))) static int parser_yyerror(struct parser_params *parser, const char *msg) @@ -4596,7 +4605,7 @@ parser_yyerror(struct parser_params *parser, const char *msg) rb_compile_error_append("%s", buf); } #else - dis1(parse_error, rb_str_new2(msg)); #endif /* !RIPPER */ return 0; } @@ -4634,7 +4643,7 @@ yycompile(struct parser_params *parser, const char *f, int line) if (!compile_for_eval && rb_safe_level() == 0) { ruby_debug_lines = ruby_suppress_tracing(debug_lines, (VALUE)f); if (ruby_debug_lines && line > 1) { - VALUE str = rb_str_new(0,0); n = line - 1; do { rb_ary_push(ruby_debug_lines, str); @@ -4660,7 +4669,15 @@ yycompile(struct parser_params *parser, const char *f, int line) tree = NEW_NIL(); } if (ruby_eval_tree_begin) { - tree->nd_body = NEW_PRELUDE(ruby_eval_tree_begin, tree->nd_body); } return tree; } @@ -4682,7 +4699,7 @@ lex_get_str(struct parser_params *parser, VALUE s) if (*end++ == '\n') break; } lex_gets_ptr = end - RSTRING_PTR(s); - return rb_str_new(beg, end - beg); } static VALUE @@ -5173,8 +5190,8 @@ parser_tokadd_string(struct parser_params *parser, } } } - else if (ismbchar(uc)) { - int i, len = mbclen(uc)-1; for (i = 0; i < len; i++) { tokadd(c); @@ -5252,7 +5269,7 @@ parser_parse_string(struct parser_params *parser, NODE *quote) } tokfix(); - set_yylval_str(rb_str_new(tok(), toklen())); return tSTRING_CONTENT; } @@ -5278,8 +5295,7 @@ parser_heredoc_identifier(struct parser_params *parser) tokadd(func); term = c; while ((c = nextc()) != -1 && c != term) { - uc = (unsigned int)c; - len = mbclen(uc); do {tokadd(c);} while (--len > 0 && (c = nextc()) != -1); } if (c == -1) { @@ -5289,8 +5305,7 @@ parser_heredoc_identifier(struct parser_params *parser) break; default: - uc = (unsigned int)c; - if (!is_identchar(uc)) { pushback(c); if (func & STR_FUNC_INDENT) { pushback('-'); @@ -5301,11 +5316,9 @@ parser_heredoc_identifier(struct parser_params *parser) term = '"'; tokadd(func |= str_dquote); do { - uc = (unsigned int)c; - len = mbclen(uc); do {tokadd(c);} while (--len > 0 && (c = nextc()) != -1); - } while ((c = nextc()) != -1 && - (uc = (unsigned char)c, is_identchar(uc))); pushback(c); break; } @@ -5317,7 +5330,7 @@ parser_heredoc_identifier(struct parser_params *parser) len = lex_p - lex_pbeg; lex_goto_eol(parser); lex_strterm = rb_node_newnode(NODE_HEREDOC, - rb_str_new(tok(), toklen()), /* nd_lit */ len, /* nd_nth */ lex_lastline); /* nd_orig */ nd_set_line(lex_strterm, ruby_sourceline); @@ -5410,7 +5423,7 @@ parser_here_document(struct parser_params *parser, NODE *here) if (str) rb_str_cat(str, p, pend - p); else - str = rb_str_new(p, pend - p); if (pend < lex_pend) rb_str_cat(str, "\n", 1); lex_goto_eol(parser); if (nextc() == -1) { @@ -5436,13 +5449,13 @@ parser_here_document(struct parser_params *parser, NODE *here) pushback(c); if ((c = tokadd_string(func, '\n', 0, NULL)) == -1) goto error; if (c != '\n') { - set_yylval_str(rb_str_new(tok(), toklen())); return tSTRING_CONTENT; } tokadd(nextc()); if ((c = nextc()) == -1) goto error; } while (!whole_match_p(eos, len, indent)); - str = rb_str_new(tok(), toklen()); } heredoc_restore(lex_strterm); lex_strterm = NEW_STRTERM(-1, 0, 0); @@ -5487,6 +5500,7 @@ pragma_encoding(struct parser_params *parser, const char *name, const char *val) if (parser && parser->line_count != (parser->has_shebang ? 2 : 1)) return; rb_set_kcode(val); } struct pragma { @@ -5540,7 +5554,7 @@ parser_pragma(struct parser_params *parser, const char *str, int len) #define str_copy(_s, _p, _n) ((_s) \ ? (rb_str_resize((_s), (_n)), \ MEMCPY(RSTRING_PTR(_s), (_p), char, (_n)), (_s)) \ - : ((_s) = rb_str_new((_p), (_n)))) if (len <= 7) return Qfalse; if (!(beg = pragma_marker(str, len))) return Qfalse; @@ -5934,8 +5948,7 @@ parser_yylex(struct parser_params *parser) compile_error(PARSER_ARG "incomplete character syntax"); return 0; } - uc = (unsigned char)c; - if (ISSPACE(c)){ if (!IS_ARG()){ int c2 = 0; switch (c) { @@ -5968,8 +5981,8 @@ parser_yylex(struct parser_params *parser) return '?'; } newtok(); - if (ismbchar(uc)) { - int i, len = mbclen(uc)-1; tokadd(c); for (i = 0; i < len; i++) { @@ -5977,7 +5990,8 @@ parser_yylex(struct parser_params *parser) tokadd(c); } } - else if ((ISALNUM(c) || c == '_') && lex_p < lex_pend && is_identchar(*lex_p)) { goto ternary; } else if (c == '\\') { @@ -5988,7 +6002,7 @@ parser_yylex(struct parser_params *parser) tokadd(c); } tokfix(); - set_yylval_str(rb_str_new(tok(), toklen())); lex_state = EXPR_ENDARG; return tCHAR; @@ -6544,8 +6558,7 @@ parser_yylex(struct parser_params *parser) } else { term = nextc(); - uc = (unsigned char)c; - if (ISALNUM(term) || ismbchar(uc)) { yyerror("unknown type of %string"); return 0; } @@ -6625,8 +6638,7 @@ parser_yylex(struct parser_params *parser) switch (c) { case '_': /* $_: last read line string */ c = nextc(); - uc = (unsigned char)c; - if (is_identchar(uc)) { tokadd('$'); tokadd('_'); break; @@ -6660,8 +6672,7 @@ parser_yylex(struct parser_params *parser) tokadd('$'); tokadd(c); c = nextc(); - uc = (unsigned char)c; - if (is_identchar(uc)) { tokadd(c); } else { @@ -6703,8 +6714,7 @@ parser_yylex(struct parser_params *parser) return tNTH_REF; default: - uc = (unsigned char)c; - if (!is_identchar(uc)) { pushback(c); return '$'; } @@ -6730,8 +6740,7 @@ parser_yylex(struct parser_params *parser) } return 0; } - uc = (unsigned char)c; - if (!is_identchar(uc)) { pushback(c); return '@'; } @@ -6753,9 +6762,8 @@ parser_yylex(struct parser_params *parser) break; default: - uc = (unsigned char)c; - if (!is_identchar(uc)) { - compile_error(PARSER_ARG "Invalid char `\\%03o' in expression", c); goto retry; } @@ -6763,21 +6771,18 @@ parser_yylex(struct parser_params *parser) break; } - uc = (unsigned char)c; do { tokadd(c); - if (ismbchar(uc)) { - int i, len = mbclen(uc)-1; - for (i = 0; i < len; i++) { - c = nextc(); - tokadd(c); - } } c = nextc(); - uc = (unsigned char)c; - } while (is_identchar(uc)); - if ((c == '!' || c == '?') && is_identchar(tok()[0]) && !peek('=')) { tokadd(c); } else { @@ -7214,7 +7219,7 @@ gettable_gen(struct parser_params *parser, ID id) return NEW_FALSE(); } else if (id == keyword__FILE__) { - return NEW_STR(rb_str_new2(ruby_sourcefile)); } else if (id == keyword__LINE__) { return NEW_LIT(INT2FIX(ruby_sourceline)); @@ -8115,8 +8120,7 @@ dvar_curr_gen(struct parser_params *parser, ID id) static VALUE reg_compile_gen(struct parser_params* parser, const char *ptr, long len, int options) { - VALUE rb_reg_compile(const char *, long, int); - VALUE re = rb_reg_compile(ptr, len, (options) & ~RE_OPTION_ONCE); if (NIL_P(re)) { RB_GC_GUARD(re) = rb_obj_as_string(rb_errinfo()); @@ -8316,7 +8320,7 @@ internal_id_gen(struct parser_params *parser) } static int -is_special_global_name(const char *m) { switch (*m) { case '~': case '*': case '$': case '?': case '!': case '@': @@ -8328,11 +8332,11 @@ is_special_global_name(const char *m) break; case '-': ++m; - if (is_identchar(*m)) m += mbclen(*m); break; default: - if (!ISDIGIT(*m)) return 0; - do ++m; while (ISDIGIT(*m)); } return !*m; } @@ -8342,6 +8346,7 @@ rb_symname_p(const char *name) { const char *m = name; int localid = Qfalse; if (!m) return Qfalse; switch (*m) { @@ -8349,7 +8354,7 @@ rb_symname_p(const char *name) return Qfalse; case '$': - if (is_special_global_name(++m)) return Qtrue; goto id; case '@': @@ -8396,10 +8401,10 @@ rb_symname_p(const char *name) break; default: - localid = !ISUPPER(*m); id: - if (*m != '_' && !ISALPHA(*m) && !ismbchar(*m)) return Qfalse; - while (is_identchar(*m)) m += mbclen(*m); if (localid) { switch (*m) { case '!': case '?': case '=': ++m; @@ -8411,7 +8416,7 @@ rb_symname_p(const char *name) } ID -rb_intern2(const char *name, long len) { const char *m = name; VALUE str; @@ -8429,13 +8434,13 @@ rb_intern2(const char *name, long len) last = len-1; id = 0; - switch (*name) { case '$': id |= ID_GLOBAL; - if (is_special_global_name(++m)) goto new_id; break; case '@': - if (name[1] == '@') { m++; id |= ID_CLASS; } @@ -8445,20 +8450,21 @@ rb_intern2(const char *name, long len) m++; break; default: - if (name[0] != '_' && ISASCII(name[0]) && !ISALNUM(name[0])) { /* operators */ int i; for (i=0; op_tbl[i].token; i++) { - if (*op_tbl[i].name == *name && - strcmp(op_tbl[i].name, name) == 0) { id = op_tbl[i].token; goto id_register; } } } - if (name[last] == '=') { /* attribute assignment */ id = rb_intern2(name, last); if (id > tLAST_TOKEN && !is_attrset_id(id)) { @@ -8467,7 +8473,7 @@ rb_intern2(const char *name, long len) } id = ID_ATTRSET; } - else if (ISUPPER(name[0])) { id = ID_CONST; } else { @@ -8475,9 +8481,9 @@ rb_intern2(const char *name, long len) } break; } - if (!ISDIGIT(*m)) { - while (m <= name + last && is_identchar(*m)) { - m += mbclen(*m); } } if (m - name < len) id = ID_JUNK; @@ -8492,11 +8498,23 @@ rb_intern2(const char *name, long len) } ID rb_intern(const char *name) { return rb_intern2(name, strlen(name)); } VALUE rb_id2str(ID id) { @@ -8662,6 +8680,7 @@ parser_initialize(struct parser_params *parser) #ifdef YYMALLOC parser->heap = NULL; #endif } extern void rb_mark_source_filename(char *); @@ -9013,27 +9032,27 @@ ripper_compile_error(struct parser_params *parser, const char *fmt, ...) static void ripper_warn0(struct parser_params *parser, const char *fmt) { - rb_funcall(parser->value, rb_intern("warn"), 1, rb_str_new2(fmt)); } static void ripper_warnI(struct parser_params *parser, const char *fmt, int a) { rb_funcall(parser->value, rb_intern("warn"), 2, - rb_str_new2(fmt), INT2NUM(a)); } static void ripper_warnS(struct parser_params *parser, const char *fmt, const char *str) { rb_funcall(parser->value, rb_intern("warn"), 2, - rb_str_new2(fmt), rb_str_new2(str)); } static void ripper_warning0(struct parser_params *parser, const char *fmt) { - rb_funcall(parser->value, rb_intern("warning"), 1, rb_str_new2(fmt)); } #if 0 /* unused in ripper right now */ @@ -9041,7 +9060,7 @@ static void ripper_warningS(struct parser_params *parser, const char *fmt, const char *str) { rb_funcall(parser->value, rb_intern("warning"), 2, - rb_str_new2(fmt), rb_str_new2(str)); } #endif @@ -9094,7 +9113,7 @@ ripper_initialize(int argc, VALUE *argv, VALUE self) parser->parser_lex_input = src; parser->eofp = Qfalse; if (NIL_P(fname)) { - fname = rb_str_new2("(ripper)"); } else { StringValue(fname); @@ -6,7 +6,7 @@ $Date$ created at: Tue Jan 26 02:40:41 2000 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 14:30:50 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Fri Dec 24 16:39:21 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Thu Aug 19 17:46:47 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -5,12 +5,13 @@ $Author$ created at: Mon Aug 9 18:24:49 JST 1993 - Copyright (C) 1993-2006 Yukihiro Matsumoto **********************************************************************/ #include "ruby/ruby.h" #include "ruby/re.h" #include "regint.h" #include <ctype.h> @@ -289,23 +290,27 @@ kcode_to_arg_value(unsigned int kcode) static void set_re_kcode_by_option(struct RRegexp *re, int options) { switch (options & ARG_KCODE_MASK) { case ARG_KCODE_NONE: - FL_UNSET(re, KCODE_MASK); FL_SET(re, KCODE_FIXED); break; case ARG_KCODE_EUC: - FL_UNSET(re, KCODE_MASK); FL_SET(re, KCODE_EUC); FL_SET(re, KCODE_FIXED); break; case ARG_KCODE_SJIS: - FL_UNSET(re, KCODE_MASK); - FL_SET(re, KCODE_SJIS); FL_SET(re, KCODE_FIXED); break; case ARG_KCODE_UTF8: - FL_UNSET(re, KCODE_MASK); FL_SET(re, KCODE_UTF8); FL_SET(re, KCODE_FIXED); break; @@ -315,6 +320,9 @@ set_re_kcode_by_option(struct RRegexp *re, int options) FL_SET(re, reg_kcode); break; } } static int @@ -371,15 +379,9 @@ kcode_reset_option(void) int rb_reg_mbclen2(unsigned int c, VALUE re) { - int len; unsigned char uc = (unsigned char)c; - if (!FL_TEST(re, KCODE_FIXED)) - return mbclen(uc); - kcode_set_option(re); - len = mbclen(uc); - kcode_reset_option(); - return len; } static void @@ -393,16 +395,17 @@ rb_reg_check(VALUE re) static void rb_reg_expr_str(VALUE str, const char *s, long len) { const char *p, *pend; int need_escape = 0; p = s; pend = p + len; while (p<pend) { - if (*p == '/' || (!ISPRINT(*p) && !ismbchar(*p))) { need_escape = 1; break; } - p += mbclen(*p); } if (!need_escape) { rb_str_buf_cat(str, s, len); @@ -411,7 +414,7 @@ rb_reg_expr_str(VALUE str, const char *s, long len) p = s; while (p<pend) { if (*p == '\\') { - int n = mbclen(p[1]) + 1; rb_str_buf_cat(str, p, n); p += n; continue; @@ -421,15 +424,15 @@ rb_reg_expr_str(VALUE str, const char *s, long len) rb_str_buf_cat(str, &c, 1); rb_str_buf_cat(str, p, 1); } - else if (ismbchar(*p)) { - rb_str_buf_cat(str, p, mbclen(*p)); - p += mbclen(*p); continue; } - else if (ISPRINT(*p)) { rb_str_buf_cat(str, p, 1); } - else if (!ISSPACE(*p)) { char b[8]; sprintf(b, "\\%03o", *p & 0377); @@ -621,21 +624,13 @@ rb_reg_raise(const char *s, long len, const char *err, VALUE re) rb_raise(rb_eRegexpError, "%s: %s", err, RSTRING_PTR(desc)); } -static VALUE -rb_reg_error_desc(const char *s, long len, int options, onig_errmsg_buffer err) { - char opts[6]; - VALUE desc = rb_str_buf_new2(err); - - rb_str_buf_cat2(desc, ": /"); - rb_reg_expr_str(desc, s, len); - opts[0] = '/'; - option_to_str(opts + 1, options); - strlcat(opts, arg_kcode(options), sizeof(opts)); - rb_str_buf_cat2(desc, opts); - return rb_exc_new3(rb_eRegexpError, desc); } /* * call-seq: * rxp.casefold? => true or false @@ -1489,7 +1484,7 @@ match_inspect(VALUE match) VALUE rb_cRegexp; static int -rb_reg_initialize(VALUE obj, const char *s, long len, int options, onig_errmsg_buffer err) { struct RRegexp *re = RREGEXP(obj); @@ -1504,7 +1499,12 @@ rb_reg_initialize(VALUE obj, const char *s, long len, re->ptr = 0; re->str = 0; - set_re_kcode_by_option(re, options); if (options & ARG_KCODE_MASK) { kcode_set_option((VALUE)re); @@ -1525,6 +1525,13 @@ rb_reg_initialize(VALUE obj, const char *s, long len, return 0; } static VALUE rb_reg_s_alloc(VALUE klass) { @@ -1539,27 +1546,35 @@ rb_reg_s_alloc(VALUE klass) } VALUE -rb_reg_new(const char *s, long len, int options) { VALUE re = rb_reg_s_alloc(rb_cRegexp); onig_errmsg_buffer err; - if (rb_reg_initialize(re, s, len, options, err) != 0) { - rb_exc_raise(rb_reg_error_desc(s, len, options, err)); } return re; } VALUE -rb_reg_compile(const char *s, long len, int options) { VALUE re = rb_reg_s_alloc(rb_cRegexp); onig_errmsg_buffer err; - if (rb_reg_initialize(re, s, len, options, err) != 0) { - rb_set_errinfo(rb_reg_error_desc(s, len, options, err)); - return Qnil; } FL_SET(re, REG_LITERAL); return re; @@ -1581,8 +1596,7 @@ rb_reg_regcomp(VALUE str) case_cache = ruby_ignorecase; kcode_cache = reg_kcode; - return reg_cache = rb_reg_new(RSTRING_PTR(save_str), RSTRING_LEN(save_str), - ruby_ignorecase); } static int @@ -1843,9 +1857,8 @@ static VALUE rb_reg_initialize_m(int argc, VALUE *argv, VALUE self) { onig_errmsg_buffer err; - const char *s; - long len; int flags = 0; if (argc == 0 || argc > 3) { rb_raise(rb_eArgError, "wrong number of arguments"); @@ -1859,8 +1872,8 @@ rb_reg_initialize_m(int argc, VALUE *argv, VALUE self) if (FL_TEST(argv[0], KCODE_FIXED)) { flags |= re_to_kcode_arg_value(argv[0]); } - s = RREGEXP(argv[0])->str; - len = RREGEXP(argv[0])->len; } else { if (argc >= 2) { @@ -1873,11 +1886,10 @@ rb_reg_initialize_m(int argc, VALUE *argv, VALUE self) flags &= ~ARG_KCODE_MASK; flags |= char_to_arg_kcode((int )kcode[0]); } - s = StringValuePtr(argv[0]); - len = RSTRING_LEN(argv[0]); } - if (rb_reg_initialize(self, s, len, flags, err) != 0) { - rb_exc_raise(rb_reg_error_desc(s, len, flags, err)); } return self; } @@ -1885,6 +1897,7 @@ rb_reg_initialize_m(int argc, VALUE *argv, VALUE self) VALUE rb_reg_quote(VALUE str) { char *s, *send, *t; VALUE tmp; int c; @@ -1893,8 +1906,8 @@ rb_reg_quote(VALUE str) send = s + RSTRING_LEN(str); for (; s < send; s++) { c = *s; - if (ismbchar(*s)) { - int n = mbclen(*s); while (n-- && s < send) s++; @@ -1922,8 +1935,8 @@ rb_reg_quote(VALUE str) for (; s < send; s++) { c = *s; - if (ismbchar(*s)) { - int n = mbclen(*s); while (n-- && s < send) *t++ = *s++; @@ -2146,9 +2159,8 @@ rb_reg_init_copy(VALUE copy, VALUE re) rb_reg_check(re); s = RREGEXP(re)->str; len = RREGEXP(re)->len; - options = rb_reg_options(re); - if (rb_reg_initialize(copy, s, len, options, err) != 0) { - rb_exc_raise(rb_reg_error_desc(s, len, options, err)); } return copy; } @@ -2160,20 +2172,20 @@ rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs, VALUE regexp) char *p, *s, *e; unsigned char uc; int no; - p = s = RSTRING_PTR(str); e = s + RSTRING_LEN(str); while (s < e) { - char *ss = s; - uc = (unsigned char)*s++; - if (ismbchar(uc)) { - s += mbclen(uc) - 1; continue; } - if (uc != '\\' || s == e) continue; if (!val) { val = rb_str_buf_new(ss-p); @@ -2203,8 +2215,7 @@ rb_reg_regsub(VALUE str, VALUE src, struct re_registers *regs, VALUE regexp) name_end = name = s + 1; while (name_end < e) { if (*name_end == '>') break; - uc = (unsigned char)*name_end; - name_end += mbclen(uc); } if (name_end < e) { no = name_to_backref_number(regs, regexp, name, name_end); @@ -127,6 +127,7 @@ #define onig_st_nothing_key_free st_nothing_key_free #define onig_st_is_member st_is_member #else #define st_init_table onig_st_init_table @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 12:47:31 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -676,7 +676,7 @@ proc_options(int argc, char **argv) case 'F': if (*++s) { - rb_fs = rb_reg_new(s, strlen(s), 0); } break; @@ -962,10 +962,14 @@ load_file(VALUE parser, const char *fname, int script) rb_raise(rb_eLoadError, "no Ruby script found in input"); } - c = rb_io_getc(f); if (c == INT2FIX('#')) { - c = rb_io_getc(f); - if (c == INT2FIX('!') && !NIL_P(line = rb_io_gets(f))) { if ((p = strstr(RSTRING_PTR(line), "ruby")) == 0) { /* not ruby script, kick the program */ char **argv; @@ -1011,8 +1015,7 @@ load_file(VALUE parser, const char *fname, int script) } /* push back shebang for pragma may exist in next line */ - rb_io_ungetc(f, INT2FIX('\n')); - rb_io_ungetc(f, INT2FIX('!')); } else if (!NIL_P(c)) { rb_io_ungetc(f, c); @@ -6,7 +6,7 @@ $Date$ created at: Tue Dec 20 10:13:44 JST 1994 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 15 10:39:26 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -14,7 +14,7 @@ #include "ruby/ruby.h" #include "ruby/re.h" -#include <ctype.h> #include <math.h> #include <stdarg.h> @@ -115,7 +115,7 @@ sign_bits(int base, const char *p) ((nth >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[nth]) #define GETNUM(n, val) \ - for (; p < end && ISDIGIT(*p); p++) { \ int next_n = 10 * n + (*p - '0'); \ if (next_n / 10 != n) {\ rb_raise(rb_eArgError, #val " too big"); \ @@ -254,6 +254,7 @@ rb_f_sprintf(int argc, const VALUE *argv) VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt) { const char *p, *end; char *buf; int blen, bsiz; @@ -286,6 +287,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) --argv; if (OBJ_TAINTED(fmt)) tainted = 1; StringValue(fmt); fmt = rb_str_new4(fmt); p = RSTRING_PTR(fmt); end = p + RSTRING_LEN(fmt); @@ -311,7 +313,7 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) retry: switch (*p) { default: - if (ISPRINT(*p)) rb_raise(rb_eArgError, "malformed format string - %%%c", *p); else rb_raise(rb_eArgError, "malformed format string"); @@ -409,24 +411,38 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) { VALUE val = GETARG(); VALUE tmp; - char c; tmp = rb_check_string_type(val); if (!NIL_P(tmp)) { - if (RSTRING_LEN(tmp) != 1) { rb_raise(rb_eArgError, "%%c requires a character"); } - c = RSTRING_PTR(tmp)[0]; } else { - c = NUM2INT(val) & 0xff; } if (!(flags & FWIDTH)) { - PUSH(&c, 1); } else { - FILL(' ', width); - buf[blen - ((flags & FMINUS) ? width : 1)] = c; } } break; @@ -435,30 +451,42 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) case 'p': { VALUE arg = GETARG(); - long len; if (*p == 'p') arg = rb_inspect(arg); str = rb_obj_as_string(arg); if (OBJ_TAINTED(str)) tainted = 1; len = RSTRING_LEN(str); if (flags&FPREC) { - if (prec < len) { - len = prec; } } /* need to adjust multi-byte string pos */ if (flags&FWIDTH) { - if (width > len) { - CHECK(width); - width -= len; if (!(flags&FMINUS)) { while (width--) { buf[blen++] = ' '; } } memcpy(&buf[blen], RSTRING_PTR(str), len); blen += len; if (flags&FMINUS) { while (width--) { buf[blen++] = ' '; } @@ -666,8 +694,9 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt) if (*p == 'X') { char *pp = s; - while (*pp) { - *pp = toupper(*pp); pp++; } } @@ -6,7 +6,7 @@ $Date$ created at: Mon Aug 9 17:12:58 JST 1993 - Copyright (C) 1993-2006 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -14,6 +14,7 @@ #include "ruby/ruby.h" #include "ruby/re.h" #define BEG(no) regs->beg[no] #define END(no) regs->end[no] @@ -30,6 +31,7 @@ VALUE rb_cSymbol; #define STR_TMPLOCK FL_USER7 #define STR_NOEMBED FL_USER1 #define STR_ASSOC FL_USER3 #define STR_SHARED_P(s) FL_ALL(s, STR_NOEMBED|ELTS_SHARED) #define STR_ASSOC_P(s) FL_ALL(s, STR_NOEMBED|STR_ASSOC) @@ -90,11 +92,6 @@ VALUE rb_cSymbol; }\ } while (0) -char * -rb_str_ptr(VALUE str) { - return RSTRING_PTR(str); -} - VALUE rb_fs; static inline void @@ -160,6 +157,15 @@ rb_str_new(const char *ptr, long len) } VALUE rb_str_new2(const char *ptr) { if (!ptr) { @@ -203,6 +209,7 @@ str_new3(VALUE klass, VALUE str) RSTRING(str2)->as.heap.aux.shared = str; FL_SET(str2, ELTS_SHARED); } return str2; } @@ -233,6 +240,7 @@ str_new4(VALUE klass, VALUE str) FL_SET(str, ELTS_SHARED); RSTRING(str)->as.heap.aux.shared = str2; } OBJ_INFECT(str2, str); return str2; } @@ -392,18 +400,48 @@ rb_str_init(int argc, VALUE *argv, VALUE str) return str; } /* * call-seq: * str.length => integer * - * Returns the length of <i>str</i>. */ static VALUE rb_str_length(VALUE str) { - long len = RSTRING_LEN(str); - return LONG2NUM(len); } /* @@ -438,8 +476,10 @@ VALUE rb_str_plus(VALUE str1, VALUE str2) { VALUE str3; StringValue(str2); str3 = rb_str_new(0, RSTRING_LEN(str1)+RSTRING_LEN(str2)); memcpy(RSTRING_PTR(str3), RSTRING_PTR(str1), RSTRING_LEN(str1)); memcpy(RSTRING_PTR(str3) + RSTRING_LEN(str1), @@ -448,6 +488,7 @@ rb_str_plus(VALUE str1, VALUE str2) if (OBJ_TAINTED(str1) || OBJ_TAINTED(str2)) OBJ_TAINT(str3); return str3; } @@ -481,8 +522,8 @@ rb_str_times(VALUE str, VALUE times) RSTRING_PTR(str), RSTRING_LEN(str)); } RSTRING_PTR(str2)[RSTRING_LEN(str2)] = '\0'; - OBJ_INFECT(str2, str); return str2; } @@ -504,8 +545,10 @@ rb_str_times(VALUE str, VALUE times) static VALUE rb_str_format_m(VALUE str, VALUE arg) { - if (TYPE(arg) == T_ARRAY) { - return rb_str_format(RARRAY_LEN(arg), RARRAY_PTR(arg), str); } return rb_str_format(1, &arg, str); } @@ -632,19 +675,66 @@ rb_str_s_try_convert(VALUE dummy, VALUE str) return rb_check_string_type(str); } VALUE rb_str_substr(VALUE str, long beg, long len) { VALUE str2; if (len < 0) return Qnil; - if (beg > RSTRING_LEN(str)) return Qnil; if (beg < 0) { - beg += RSTRING_LEN(str); if (beg < 0) return Qnil; } - if (beg + len > RSTRING_LEN(str)) { - len = RSTRING_LEN(str) - beg; } if (len < 0) { len = 0; @@ -652,16 +742,11 @@ rb_str_substr(VALUE str, long beg, long len) if (len == 0) { str2 = rb_str_new5(str,0,0); } - else if (len > RSTRING_EMBED_LEN_MAX && - beg + len == RSTRING_LEN(str) && !STR_ASSOC_P(str)) { - str2 = rb_str_new4(str); - str2 = str_new3(rb_obj_class(str2), str2); - RSTRING(str2)->as.heap.ptr += RSTRING_LEN(str2) - len; - RSTRING(str2)->as.heap.len = len; - } else { - str2 = rb_str_new5(str, RSTRING_PTR(str)+beg, len); } OBJ_INFECT(str2, str); return str2; @@ -848,7 +933,10 @@ rb_str_buf_append(VALUE str, VALUE str2) VALUE rb_str_append(VALUE str, VALUE str2) { StringValue(str2); rb_str_modify(str); if (RSTRING_LEN(str2) > 0) { if (STR_ASSOC_P(str)) { @@ -863,6 +951,7 @@ rb_str_append(VALUE str, VALUE str2) } } OBJ_INFECT(str, str2); return str; } @@ -875,8 +964,8 @@ rb_str_append(VALUE str, VALUE str2) * str.concat(obj) => str * * Append---Concatenates the given object to <i>str</i>. If the object is a - * <code>Fixnum</code> between 0 and 255, it is converted to a character before - * concatenation. * * a = "hello " * a << "world" #=> "hello world" @@ -887,11 +976,17 @@ VALUE rb_str_concat(VALUE str1, VALUE str2) { if (FIXNUM_P(str2)) { - int i = FIX2INT(str2); - if (0 <= i && i <= 0xff) { /* byte */ - char c = i; - return rb_str_cat(str1, &c, 1); } } return rb_str_append(str1, str2); } @@ -1048,6 +1143,7 @@ rb_str_cmp(VALUE str1, VALUE str2) long len; int retval; len = lesser(RSTRING_LEN(str1), RSTRING_LEN(str2)); retval = rb_memcmp(RSTRING_PTR(str1), RSTRING_PTR(str2), len); if (retval == 0) { @@ -1079,6 +1175,7 @@ rb_str_equal(VALUE str1, VALUE str2) } return rb_equal(str2, str1); } if (RSTRING_LEN(str1) == RSTRING_LEN(str2) && rb_str_cmp(str1, str2) == 0) { return Qtrue; @@ -1194,15 +1291,23 @@ static long rb_str_index(VALUE str, VALUE sub, long offset) { long pos; if (offset < 0) { - offset += RSTRING_LEN(str); if (offset < 0) return -1; } - if (RSTRING_LEN(str) - offset < RSTRING_LEN(sub)) return -1; - if (RSTRING_LEN(sub) == 0) return offset; pos = rb_memsearch(RSTRING_PTR(sub), RSTRING_LEN(sub), - RSTRING_PTR(str)+offset, RSTRING_LEN(str)-offset); if (pos < 0) return pos; return pos + offset; } @@ -1240,7 +1345,7 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str) pos = 0; } if (pos < 0) { - pos += RSTRING_LEN(str); if (pos < 0) { if (TYPE(sub) == T_REGEXP) { rb_backref_set(Qnil); @@ -1253,19 +1358,9 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str) case T_REGEXP: pos = rb_reg_adjust_startpos(sub, str, pos, 0); pos = rb_reg_search(sub, str, pos, 0); break; - case T_FIXNUM: { - int c = FIX2INT(sub); - long len = RSTRING_LEN(str); - char *p = RSTRING_PTR(str); - - for (;pos<len;pos++) { - if ((unsigned char)p[pos] == c) return LONG2NUM(pos); - } - return Qnil; - } - default: { VALUE tmp; @@ -1279,6 +1374,7 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str) /* fall through */ case T_STRING: pos = rb_str_index(str, sub, pos); break; } @@ -1289,29 +1385,33 @@ rb_str_index_m(int argc, VALUE *argv, VALUE str) static long rb_str_rindex(VALUE str, VALUE sub, long pos) { - long len = RSTRING_LEN(sub); - char *s, *sbeg, *t; /* substring longer than string */ - if (RSTRING_LEN(str) < len) return -1; - if (RSTRING_LEN(str) - pos < len) { - pos = RSTRING_LEN(str) - len; } sbeg = RSTRING_PTR(str); - s = RSTRING_PTR(str) + pos; t = RSTRING_PTR(sub); - if (len) { - while (sbeg <= s) { - if (rb_memcmp(s, t, len) == 0) { - return s - RSTRING_PTR(str); - } - s--; } - return -1; - } - else { - return pos; } } @@ -1338,11 +1438,11 @@ static VALUE rb_str_rindex_m(int argc, VALUE *argv, VALUE str) { VALUE sub; - VALUE position; long pos; - if (rb_scan_args(argc, argv, "11", &sub, &position) == 2) { - pos = NUM2LONG(position); if (pos < 0) { pos += RSTRING_LEN(str); if (pos < 0) { @@ -1360,9 +1460,13 @@ rb_str_rindex_m(int argc, VALUE *argv, VALUE str) switch (TYPE(sub)) { case T_REGEXP: if (RREGEXP(sub)->len) { pos = rb_reg_adjust_startpos(sub, str, pos, 1); pos = rb_reg_search(sub, str, pos, 1); } if (pos >= 0) return LONG2NUM(pos); break; @@ -1382,23 +1486,6 @@ rb_str_rindex_m(int argc, VALUE *argv, VALUE str) pos = rb_str_rindex(str, sub, pos); if (pos >= 0) return LONG2NUM(pos); break; - - case T_FIXNUM: { - int c = FIX2INT(sub); - char *p = RSTRING_PTR(str) + pos; - char *pbeg = RSTRING_PTR(str); - - if (pos == RSTRING_LEN(str)) { - if (pos == 0) return Qnil; - --p; - } - while (pbeg <= p) { - if ((unsigned char)*p == c) - return LONG2NUM((char*)p - RSTRING_PTR(str)); - p--; - } - return Qnil; - } } return Qnil; } @@ -1462,7 +1549,7 @@ rb_str_match_m(int argc, VALUE *argv, VALUE str) return rb_funcall2(get_pat(re, 0), rb_intern("match"), argc, argv); } -static char succ_char(char *s) { char c = *s; @@ -1515,8 +1602,9 @@ succ_char(char *s) VALUE rb_str_succ(VALUE orig) { VALUE str; - char *sbeg, *s; int c = -1; long n = 0; @@ -1524,10 +1612,13 @@ rb_str_succ(VALUE orig) OBJ_INFECT(str, orig); if (RSTRING_LEN(str) == 0) return str; sbeg = RSTRING_PTR(str); s = sbeg + RSTRING_LEN(str) - 1; while (sbeg <= s) { - if (ISALNUM(*s)) { if ((c = succ_char(s)) == 0) break; n = s - sbeg; } @@ -1642,13 +1733,9 @@ rb_str_aref(VALUE str, VALUE indx) idx = FIX2LONG(indx); num_index: - if (idx < 0) { - idx = RSTRING_LEN(str) + idx; - } - if (idx < 0 || RSTRING_LEN(str) <= idx) { - return Qnil; - } - return rb_str_substr(str, idx, 1); case T_REGEXP: return rb_str_subpat(str, indx, 0); @@ -1664,14 +1751,14 @@ rb_str_aref(VALUE str, VALUE indx) long beg, len; VALUE tmp; - switch (rb_range_beg_len(indx, &beg, &len, RSTRING_LEN(str), 0)) { case Qfalse: break; case Qnil: return Qnil; default: tmp = rb_str_substr(str, beg, len); - OBJ_INFECT(tmp, indx); return tmp; } } @@ -1745,27 +1832,8 @@ rb_str_aref_m(int argc, VALUE *argv, VALUE str) } static void -rb_str_splice(VALUE str, long beg, long len, VALUE val) { - if (len < 0) rb_raise(rb_eIndexError, "negative length %ld", len); - - StringValue(val); - rb_str_modify(str); - - if (RSTRING_LEN(str) < beg) { - out_of_range: - rb_raise(rb_eIndexError, "index %ld out of string", beg); - } - if (beg < 0) { - if (-beg > RSTRING_LEN(str)) { - goto out_of_range; - } - beg += RSTRING_LEN(str); - } - if (RSTRING_LEN(str) < beg + len) { - len = RSTRING_LEN(str) - beg; - } - if (len < RSTRING_LEN(val)) { /* expand string */ RESIZE_CAPA(str, RSTRING_LEN(str) + RSTRING_LEN(val) - len + 1); @@ -1776,7 +1844,7 @@ rb_str_splice(VALUE str, long beg, long len, VALUE val) RSTRING_PTR(str) + beg + len, RSTRING_LEN(str) - (beg + len)); } - if (RSTRING_LEN(str) < beg && len < 0) { MEMZERO(RSTRING_PTR(str) + RSTRING_LEN(str), char, -len); } if (RSTRING_LEN(val) > 0) { @@ -1789,6 +1857,41 @@ rb_str_splice(VALUE str, long beg, long len, VALUE val) OBJ_INFECT(str, val); } void rb_str_update(VALUE str, long beg, long len, VALUE val) { @@ -1822,7 +1925,8 @@ rb_str_subpat_set(VALUE str, VALUE re, int nth, VALUE val) } end = RMATCH(match)->END(nth); len = end - start; - rb_str_splice(str, start, len, val); } static VALUE @@ -1834,16 +1938,7 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val) case T_FIXNUM: idx = FIX2LONG(indx); num_index: - if (RSTRING_LEN(str) <= idx) { - out_of_range: - rb_raise(rb_eIndexError, "index %ld out of string", idx); - } - if (idx < 0) { - if (-idx > RSTRING_LEN(str)) - goto out_of_range; - idx += RSTRING_LEN(str); - } - rb_str_splice(str, idx, 1, val); return val; case T_REGEXP: @@ -1855,14 +1950,15 @@ rb_str_aset(VALUE str, VALUE indx, VALUE val) if (beg < 0) { rb_raise(rb_eIndexError, "string not matched"); } - rb_str_splice(str, beg, RSTRING_LEN(indx), val); return val; default: /* check if indx is Range */ { long beg, len; - if (rb_range_beg_len(indx, &beg, &len, RSTRING_LEN(str), 2)) { rb_str_splice(str, beg, len, val); return val; } @@ -2352,6 +2448,7 @@ rb_str_replace(VALUE str, VALUE str2) } OBJ_INFECT(str, str2); return str; } @@ -2396,58 +2493,83 @@ rb_str_chr(VALUE str) /* * call-seq: - * str.reverse! => str * - * Reverses <i>str</i> in place. */ static VALUE -rb_str_reverse_bang(VALUE str) { - char *s, *e; - char c; if (RSTRING_LEN(str) > 1) { - rb_str_modify(str); - s = RSTRING_PTR(str); - e = s + RSTRING_LEN(str) - 1; - while (s < e) { - c = *s; - *s++ = *e; - *e-- = c; } } - return str; } /* * call-seq: - * str.reverse => new_str * - * Returns a new string with the characters from <i>str</i> in reverse order. - * - * "stressed".reverse #=> "desserts" */ static VALUE -rb_str_reverse(VALUE str) { - VALUE obj; - char *s, *e, *p; - - if (RSTRING_LEN(str) <= 1) return rb_str_dup(str); - obj = rb_str_new5(str, 0, RSTRING_LEN(str)); - s = RSTRING_PTR(str); e = s + RSTRING_LEN(str) - 1; - p = RSTRING_PTR(obj); - while (e >= s) { - *p++ = *e--; } - OBJ_INFECT(obj, str); - - return obj; } @@ -2469,12 +2591,6 @@ rb_str_include(VALUE str, VALUE arg) { long i; - if (FIXNUM_P(arg)) { - if (memchr(RSTRING_PTR(str), FIX2INT(arg), RSTRING_LEN(str))) - return Qtrue; - return Qfalse; - } - StringValue(arg); i = rb_str_index(str, arg, 0); @@ -2561,7 +2677,22 @@ rb_str_to_s(VALUE str) return str; } -#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) /* * call-seq: @@ -2578,69 +2709,71 @@ rb_str_to_s(VALUE str) VALUE rb_str_inspect(VALUE str) { char *p, *pend; - VALUE result = rb_str_buf_new2("\""); - char s[5]; - p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); while (p < pend) { - char c = *p++; - if (ismbchar(c) && p < pend) { - int len = mbclen(c); - rb_str_buf_cat(result, p - 1, len); - p += len - 1; - } - else if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p, pend))) { - s[0] = '\\'; s[1] = c; - rb_str_buf_cat(result, s, 2); - } - else if (ISPRINT(c)) { - s[0] = c; - rb_str_buf_cat(result, s, 1); } else if (c == '\n') { - s[0] = '\\'; s[1] = 'n'; - rb_str_buf_cat(result, s, 2); } else if (c == '\r') { - s[0] = '\\'; s[1] = 'r'; - rb_str_buf_cat(result, s, 2); } else if (c == '\t') { - s[0] = '\\'; s[1] = 't'; - rb_str_buf_cat(result, s, 2); } else if (c == '\f') { - s[0] = '\\'; s[1] = 'f'; - rb_str_buf_cat(result, s, 2); } else if (c == '\013') { - s[0] = '\\'; s[1] = 'v'; - rb_str_buf_cat(result, s, 2); } else if (c == '\010') { - s[0] = '\\'; s[1] = 'b'; - rb_str_buf_cat(result, s, 2); } else if (c == '\007') { - s[0] = '\\'; s[1] = 'a'; - rb_str_buf_cat(result, s, 2); } else if (c == 033) { - s[0] = '\\'; s[1] = 'e'; - rb_str_buf_cat(result, s, 2); } else { - sprintf(s, "\\%03o", c & 0377); - rb_str_buf_cat2(result, s); } } - rb_str_buf_cat2(result, "\""); OBJ_INFECT(result, str); return result; } /* * call-seq: @@ -2653,6 +2786,7 @@ rb_str_inspect(VALUE str) VALUE rb_str_dump(VALUE str) { long len; char *p, *pend; char *q, *qend; @@ -2675,7 +2809,7 @@ rb_str_dump(VALUE str) break; default: - if (ISPRINT(c)) { len++; } else { @@ -2701,9 +2835,6 @@ rb_str_dump(VALUE str) if (IS_EVSTR(p, pend)) *q++ = '\\'; *q++ = '#'; } - else if (ISPRINT(c)) { - *q++ = c; - } else if (c == '\n') { *q++ = '\\'; *q++ = 'n'; @@ -2736,6 +2867,9 @@ rb_str_dump(VALUE str) *q++ = '\\'; *q++ = 'e'; } else { *q++ = '\\'; sprintf(q, "%03o", c&0xff); @@ -2745,6 +2879,8 @@ rb_str_dump(VALUE str) *q++ = '"'; OBJ_INFECT(result, str); return result; } @@ -2761,20 +2897,22 @@ rb_str_dump(VALUE str) static VALUE rb_str_upcase_bang(VALUE str) { char *s, *send; int modify = 0; rb_str_modify(str); - s = RSTRING_PTR(str); send = s + RSTRING_LEN(str); while (s < send) { - if (ismbchar(*s)) { - s+=mbclen(*s) - 1; - } - else if (ISLOWER(*s)) { - *s = toupper(*s); modify = 1; } - s++; } if (modify) return str; @@ -2815,20 +2953,22 @@ rb_str_upcase(VALUE str) static VALUE rb_str_downcase_bang(VALUE str) { char *s, *send; int modify = 0; rb_str_modify(str); - s = RSTRING_PTR(str); send = s + RSTRING_LEN(str); while (s < send) { - if (ismbchar(*s)) { - s+=mbclen(*s) - 1; - } - else if (ISUPPER(*s)) { - *s = tolower(*s); modify = 1; } - s++; } if (modify) return str; @@ -2874,24 +3014,29 @@ rb_str_downcase(VALUE str) static VALUE rb_str_capitalize_bang(VALUE str) { char *s, *send; int modify = 0; rb_str_modify(str); if (RSTRING_LEN(str) == 0 || !RSTRING_PTR(str)) return Qnil; - s = RSTRING_PTR(str); send = s + RSTRING_LEN(str); - if (ISLOWER(*s)) { - *s = toupper(*s); modify = 1; } - while (++s < send) { - if (ismbchar(*s)) { - s+=mbclen(*s) - 1; - } - else if (ISUPPER(*s)) { - *s = tolower(*s); modify = 1; } } if (modify) return str; return Qnil; @@ -2932,24 +3077,27 @@ rb_str_capitalize(VALUE str) static VALUE rb_str_swapcase_bang(VALUE str) { char *s, *send; int modify = 0; rb_str_modify(str); - s = RSTRING_PTR(str); send = s + RSTRING_LEN(str); while (s < send) { - if (ismbchar(*s)) { - s+=mbclen(*s) - 1; - } - else if (ISUPPER(*s)) { - *s = tolower(*s); modify = 1; } - else if (ISLOWER(*s)) { - *s = toupper(*s); modify = 1; } - s++; } if (modify) return str; @@ -2985,24 +3133,21 @@ struct tr { }; static int -trnext(struct tr *t) { for (;;) { if (!t->gen) { if (t->p == t->pend) return -1; - if (t->p < t->pend - 1 && *t->p == '\\') { - t->p++; - } - t->now = *(USTR)t->p++; if (t->p < t->pend - 1 && *t->p == '-') { t->p++; if (t->p < t->pend) { - if (t->now > *(USTR)t->p) { - t->p++; - continue; - } t->gen = 1; - t->max = *(USTR)t->p++; } } return t->now; @@ -3022,11 +3167,12 @@ static VALUE rb_str_delete_bang(int,VALUE*,VALUE); static VALUE tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) { struct tr trsrc, trrepl; int cflag = 0; - int trans[256]; - int i, c, modify = 0; char *s, *send; StringValue(src); StringValue(repl); @@ -3039,73 +3185,138 @@ tr_trans(VALUE str, VALUE src, VALUE repl, int sflag) if (RSTRING_LEN(repl) == 0) { return rb_str_delete_bang(1, &src, str); } trrepl.p = RSTRING_PTR(repl); trrepl.pend = trrepl.p + RSTRING_LEN(repl); trsrc.gen = trrepl.gen = 0; trsrc.now = trrepl.now = 0; trsrc.max = trrepl.max = 0; if (cflag) { - for (i=0; i<256; i++) { - trans[i] = 1; - } - while ((c = trnext(&trsrc)) >= 0) { - trans[c & 0xff] = -1; } - while ((c = trnext(&trrepl)) >= 0) /* retrieve last replacer */; - for (i=0; i<256; i++) { - if (trans[i] >= 0) { - trans[i] = trrepl.now; - } - } } else { int r; - for (i=0; i<256; i++) { - trans[i] = -1; - } - while ((c = trnext(&trsrc)) >= 0) { - r = trnext(&trrepl); if (r == -1) r = trrepl.now; - trans[c & 0xff] = r; } } rb_str_modify(str); - s = RSTRING_PTR(str); send = s + RSTRING_LEN(str); if (sflag) { - char *t = s; - int c0, last = -1; while (s < send) { - c0 = *s++; - if ((c = trans[c0 & 0xff]) >= 0) { - if (last == c) continue; - last = c; - *t++ = c & 0xff; modify = 1; } else { - last = -1; - *t++ = c0; } } - if (RSTRING_LEN(str) > (t - RSTRING_PTR(str))) { - STR_SET_LEN(str, (t - RSTRING_PTR(str))); - modify = 1; - *t = '\0'; } } else { while (s < send) { - if ((c = trans[*s & 0xff]) >= 0) { - *s = c & 0xff; modify = 1; } - s++; } } if (modify) return str; @@ -3155,34 +3366,32 @@ rb_str_tr(VALUE str, VALUE src, VALUE repl) } static void -tr_setup_table(VALUE str, char table[256], int init) { - char buf[256]; struct tr tr; - int i, c; - int cflag = 0; tr.p = RSTRING_PTR(str); tr.pend = tr.p + RSTRING_LEN(str); tr.gen = tr.now = tr.max = 0; if (RSTRING_LEN(str) > 1 && RSTRING_PTR(str)[0] == '^') { - cflag = 1; tr.p++; } - if (init) { - for (i=0; i<256; i++) { - table[i] = 1; } } - for (i=0; i<256; i++) { - buf[i] = cflag; - } - while ((c = trnext(&tr)) >= 0) { - buf[c & 0xff] = !cflag; - } - for (i=0; i<256; i++) { - table[i] = table[i] && buf[i]; - } } @@ -3197,10 +3406,10 @@ tr_setup_table(VALUE str, char table[256], int init) static VALUE rb_str_delete_bang(int argc, VALUE *argv, VALUE str) { char *s, *send, *t; - char squeez[256]; int modify = 0; - int init = 1; int i; if (argc < 1) { @@ -3210,20 +3419,28 @@ rb_str_delete_bang(int argc, VALUE *argv, VALUE str) VALUE s = argv[i]; StringValue(s); - tr_setup_table(s, squeez, init); - init = 0; } rb_str_modify(str); s = t = RSTRING_PTR(str); if (!s || RSTRING_LEN(str) == 0) return Qnil; - send = s + RSTRING_LEN(str); while (s < send) { - if (squeez[*s & 0xff]) modify = 1; - else - *t++ = *s; - s++; } *t = '\0'; STR_SET_LEN(str, t - RSTRING_PTR(str)); @@ -3267,37 +3484,43 @@ rb_str_delete(int argc, VALUE *argv, VALUE str) static VALUE rb_str_squeeze_bang(int argc, VALUE *argv, VALUE str) { - char squeez[256]; char *s, *send, *t; - int c, save, modify = 0; - int init = 1; int i; if (argc == 0) { - for (i=0; i<256; i++) { - squeez[i] = 1; - } } else { for (i=0; i<argc; i++) { VALUE s = argv[i]; StringValue(s); - tr_setup_table(s, squeez, init); - init = 0; } } rb_str_modify(str); s = t = RSTRING_PTR(str); if (!s || RSTRING_LEN(str) == 0) return Qnil; - send = s + RSTRING_LEN(str); save = -1; while (s < send) { - c = *s++ & 0xff; - if (c != save || !squeez[c]) { - *t++ = save = c; } } *t = '\0'; if (t - RSTRING_PTR(str) != RSTRING_LEN(str)) { @@ -3390,9 +3613,9 @@ rb_str_tr_s(VALUE str, VALUE src, VALUE repl) static VALUE rb_str_count(int argc, VALUE *argv, VALUE str) { - char table[256]; char *s, *send; - int init = 1; int i; if (argc < 1) { @@ -3402,18 +3625,24 @@ rb_str_count(int argc, VALUE *argv, VALUE str) VALUE s = argv[i]; StringValue(s); - tr_setup_table(s, table, init); - init = 0; } s = RSTRING_PTR(str); if (!s || RSTRING_LEN(str) == 0) return INT2FIX(0); - send = s + RSTRING_LEN(str); i = 0; while (s < send) { - if (table[*s++ & 0xff]) { i++; } } return INT2NUM(i); } @@ -3464,6 +3693,7 @@ rb_str_count(int argc, VALUE *argv, VALUE str) static VALUE rb_str_split_m(int argc, VALUE *argv, VALUE str) { VALUE spat; VALUE limit; int awk_split = Qfalse; @@ -3482,6 +3712,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) i = 1; } if (NIL_P(spat)) { if (!NIL_P(rb_fs)) { spat = rb_fs; @@ -3508,13 +3739,14 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) beg = 0; if (awk_split) { char *ptr = RSTRING_PTR(str); - long len = RSTRING_LEN(str); - char *eptr = ptr + len; int skip = 1; - for (end = beg = 0; ptr<eptr; ptr++) { if (skip) { - if (ISSPACE(*ptr)) { beg++; } else { @@ -3524,7 +3756,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) } } else { - if (ISSPACE(*ptr)) { rb_ary_push(result, rb_str_substr(str, beg, end-beg)); skip = 1; beg = end + 1; @@ -3534,6 +3766,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) end++; } } } } else { @@ -3542,6 +3775,7 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) int last_null = 0; struct re_registers *regs; while ((end = rb_reg_search(spat, str, start, 0)) >= 0) { regs = RMATCH(rb_backref_get())->regs; if (start == end && BEG(0) == END(0)) { @@ -3550,11 +3784,12 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str) break; } else if (last_null == 1) { - rb_ary_push(result, rb_str_substr(str, beg, mbclen2(RSTRING_PTR(str)[beg],spat))); beg = start; } else { - start += mbclen2(RSTRING_PTR(str)[start],spat); last_null = 1; continue; } @@ -3652,9 +3887,10 @@ rb_str_split(VALUE str, const char *sep0) static VALUE rb_str_each_line(int argc, VALUE *argv, VALUE str) { VALUE rs; int newline; - char *p = RSTRING_PTR(str), *pend = p + RSTRING_LEN(str), *s; char *ptr = p; long len = RSTRING_LEN(str), rslen; VALUE line; @@ -3662,7 +3898,6 @@ rb_str_each_line(int argc, VALUE *argv, VALUE str) if (rb_scan_args(argc, argv, "01", &rs) == 0) { rs = rb_rs; } - RETURN_ENUMERATOR(str, argc, argv); if (NIL_P(rs)) { @@ -3670,28 +3905,28 @@ rb_str_each_line(int argc, VALUE *argv, VALUE str) return str; } StringValue(rs); rslen = RSTRING_LEN(rs); if (rslen == 0) { newline = '\n'; } else { - newline = RSTRING_PTR(rs)[rslen-1]; } - for (s = p, p += rslen; p < pend; p++) { - if (rslen == 0 && *p == '\n') { - if (*++p != '\n') continue; - while (*p == '\n') p++; - } - if (RSTRING_PTR(str) < p && p[-1] == newline && - (rslen <= 1 || - rb_memcmp(RSTRING_PTR(rs), p-rslen, rslen) == 0)) { - line = rb_str_new5(str, s, p - s); OBJ_INFECT(line, str); rb_yield(line); str_mod_check(str, ptr, len); - s = p; } } if (s != pend) { @@ -3745,6 +3980,44 @@ rb_str_each_byte(VALUE str) /* * call-seq: * str.chop! => str or nil * @@ -3918,13 +4191,21 @@ rb_str_chomp(int argc, VALUE *argv, VALUE str) static VALUE rb_str_lstrip_bang(VALUE str) { char *s, *t, *e; s = RSTRING_PTR(str); if (!s || RSTRING_LEN(str) == 0) return Qnil; - e = t = s + RSTRING_LEN(str); /* remove spaces at head */ - while (s < t && ISSPACE(*s)) s++; if (s > RSTRING_PTR(str)) { rb_str_modify(str); @@ -3972,21 +4253,30 @@ rb_str_lstrip(VALUE str) static VALUE rb_str_rstrip_bang(VALUE str) { char *s, *t, *e; - s = RSTRING_PTR(str); if (!s || RSTRING_LEN(str) == 0) return Qnil; - e = t = s + RSTRING_LEN(str); - - /* remove trailing '\0's */ - while (s < t && t[-1] == '\0') t--; - - /* remove trailing spaces */ - while (s < t && ISSPACE(*(t-1))) t--; if (t < e) { rb_str_modify(str); - STR_SET_LEN(str, t-s); RSTRING_PTR(str)[RSTRING_LEN(str)] = '\0'; return str; } @@ -4054,10 +4344,12 @@ rb_str_strip(VALUE str) static VALUE scan_once(VALUE str, VALUE pat, long *start) { VALUE result, match; struct re_registers *regs; long i; if (rb_reg_search(pat, str, *start, 0) >= 0) { match = rb_backref_get(); regs = RMATCH(match)->regs; @@ -4066,7 +4358,7 @@ scan_once(VALUE str, VALUE pat, long *start) * Always consume at least one character of the input string */ if (RSTRING_LEN(str) > END(0)) - *start = END(0)+mbclen2(RSTRING_PTR(str)[END(0)],pat); else *start = END(0)+1; } @@ -4251,7 +4543,7 @@ rb_str_intern(VALUE s) if (OBJ_TAINTED(str) && rb_safe_level() >= 1) { rb_raise(rb_eSecurityError, "Insecure: can't intern tainted string"); } - id = rb_intern2(RSTRING_PTR(str), RSTRING_LEN(str)); return ID2SYM(id); } @@ -4335,65 +4627,81 @@ rb_str_sum(int argc, VALUE *argv, VALUE str) static VALUE rb_str_justify(int argc, VALUE *argv, VALUE str, char jflag) { VALUE w; - long width, flen = 0; VALUE res; - char *p, *pend, *f = " "; - long n; - VALUE pad; rb_scan_args(argc, argv, "11", &w, &pad); width = NUM2LONG(w); if (argc == 2) { StringValue(pad); f = RSTRING_PTR(pad); flen = RSTRING_LEN(pad); if (flen == 0) { rb_raise(rb_eArgError, "zero width padding"); } } - if (width < 0 || RSTRING_LEN(str) >= width) return rb_str_dup(str); - res = rb_str_new5(str, 0, width); p = RSTRING_PTR(res); - if (jflag != 'l') { - n = width - RSTRING_LEN(str); - pend = p + ((jflag == 'r') ? n : n/2); if (flen <= 1) { - while (p < pend) { - *p++ = *f; - } } else { - char *q = f; - while (p + flen <= pend) { - memcpy(p,f,flen); - p += flen; - } - while (p < pend) { - *p++ = *q++; - } } } - memcpy(p, RSTRING_PTR(str), RSTRING_LEN(str)+1); - if (jflag != 'r') { - p += RSTRING_LEN(str); pend = RSTRING_PTR(res) + width; if (flen <= 1) { - while (p < pend) { - *p++ = *f; - } } else { - while (p + flen <= pend) { - memcpy(p,f,flen); - p += flen; - } - while (p < pend) { - *p++ = *f++; - } } } OBJ_INFECT(res, str); - if (flen > 0) OBJ_INFECT(res, pad); return res; } @@ -4493,6 +4801,7 @@ rb_str_partition(VALUE str, VALUE sep) failed: return rb_ary_new3(3, str, rb_str_new(0,0),rb_str_new(0,0)); } if (regex) { sep = rb_str_subpat(str, sep, 0); if (pos == 0 && RSTRING_LEN(sep) == 0) goto failed; @@ -4534,11 +4843,13 @@ rb_str_rpartition(VALUE str, VALUE sep) rb_raise(rb_eTypeError, "type mismatch: %s given", rb_obj_classname(sep)); } pos = rb_str_rindex(str, sep, pos); } if (pos < 0) { return rb_ary_new3(3, rb_str_new(0,0),rb_str_new(0,0), str); } if (regex) { sep = rb_reg_nth_match(0, rb_backref_get()); } @@ -4563,6 +4874,7 @@ rb_str_start_with(int argc, VALUE *argv, VALUE str) for (i=0; i<argc; i++) { VALUE tmp = rb_check_string_type(argv[i]); if (NIL_P(tmp)) continue; if (RSTRING_LEN(str) < RSTRING_LEN(tmp)) continue; if (rb_memcmp(RSTRING_PTR(str), RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0) return Qtrue; @@ -4585,6 +4897,7 @@ rb_str_end_with(int argc, VALUE *argv, VALUE str) for (i=0; i<argc; i++) { VALUE tmp = rb_check_string_type(argv[i]); if (NIL_P(tmp)) continue; if (RSTRING_LEN(str) < RSTRING_LEN(tmp)) continue; if (rb_memcmp(RSTRING_PTR(str) + RSTRING_LEN(str) - RSTRING_LEN(tmp), RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0) @@ -4603,6 +4916,12 @@ rb_str_setter(VALUE val, ID id, VALUE *var) } /********************************************************************** * Document-class: Symbol * @@ -4910,6 +5229,7 @@ Init_String(void) rb_define_method(rb_cString, "insert", rb_str_insert, 2); rb_define_method(rb_cString, "length", rb_str_length, 0); rb_define_method(rb_cString, "size", rb_str_length, 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, "match", rb_str_match_m, -1); @@ -4994,6 +5314,7 @@ Init_String(void) rb_define_method(rb_cString, "each_line", rb_str_each_line, -1); rb_define_method(rb_cString, "each_byte", rb_str_each_byte, 0); rb_define_method(rb_cString, "sum", rb_str_sum, -1); @@ -5003,6 +5324,8 @@ Init_String(void) rb_define_method(rb_cString, "partition", rb_str_partition, 1); rb_define_method(rb_cString, "rpartition", rb_str_rpartition, 1); id_to_s = rb_intern("to_s"); rb_fs = Qnil; @@ -5042,4 +5365,6 @@ Init_String(void) rb_define_method(rb_cSymbol, "downcase", sym_downcase, 0); rb_define_method(rb_cSymbol, "capitalize", sym_capitalize, 0); rb_define_method(rb_cSymbol, "swapcase", sym_swapcase, 0); } @@ -6,7 +6,7 @@ $Date$ created at: Tue Mar 22 18:44:30 JST 1995 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Tue Dec 28 14:31:59 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Fri Mar 10 17:22:34 JST 1995 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ @@ -6,7 +6,7 @@ $Date$ created at: Tue Apr 19 23:55:15 JST 1994 - Copyright (C) 1993-2003 Yukihiro Matsumoto Copyright (C) 2000 Network Applied Communication Laboratory, Inc. Copyright (C) 2000 Information-technology Promotion Agency, Japan @@ -6,7 +6,7 @@ $Date$ created at: Thu Sep 30 20:08:01 JST 1993 - Copyright (C) 1993-2003 Yukihiro Matsumoto **********************************************************************/ |