mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* random.c: replace with Mersenne Twister RNG.
* eval.c (jump_tag_but_local_jump): preserve retval in LocalJumpError exceptions. * parse.y (command): no more check for "super outside of method". * eval.c (rb_mod_define_method): should set last_class and last_func in the block->frame. * eval.c (error_handle): should handle TAG_THROW as well. * parse.y (yylex): new decimal notation '0d4567'. * parse.y (yylex): new octal notation '0o777'. * parse.y (string_content): every string_content node should return string only. use NODE_EVSTR to coercing. * eval.c (rb_eval): NODE_EVSTR support. * re.c (rb_reg_quote): avoid unnecessary string allocation. * string.c (get_pat): quote metachracters before compiling a string into a regex. * string.c (rb_str_split_m): special treatment of strings of size 1, but AWK emulation. now uses get_pat(). * string.c (rb_str_match_m): quote metacharacters. * string.c (rb_str_match2): ditto. * ext/socket/socket.c (sock_addrinfo): make all 3 versions of getaddrinfo happy. [ruby-core:00184] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2654 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									1d132e648d
								
							
						
					
					
						commit
						7194b66fb2
					
				
					 14 changed files with 462 additions and 207 deletions
				
			
		
							
								
								
									
										52
									
								
								ChangeLog
									
										
									
									
									
								
							
							
						
						
									
										52
									
								
								ChangeLog
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,7 @@
 | 
			
		|||
Fri Jul 26 14:31:06 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* random.c: replace with Mersenne Twister RNG.
 | 
			
		||||
 | 
			
		||||
Fri Jul 26 12:14:48 2002  Minero Aoki  <aamine@loveruby.net>
 | 
			
		||||
 | 
			
		||||
	* parse.y (yylex): modify to accept a code like "m (a){...}".
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +26,24 @@ Thu Jul 25 09:05:02 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>
 | 
			
		|||
 | 
			
		||||
	* misc/ruby-mode.el (ruby-move-to-block): skips RD style comments.
 | 
			
		||||
 | 
			
		||||
Wed Jul 24 09:47:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* eval.c (jump_tag_but_local_jump): preserve retval in
 | 
			
		||||
	  LocalJumpError exceptions.
 | 
			
		||||
 | 
			
		||||
	* parse.y (command): no more check for "super outside of method".
 | 
			
		||||
 | 
			
		||||
	* eval.c (rb_mod_define_method): should set last_class and
 | 
			
		||||
	  last_func in the block->frame.
 | 
			
		||||
 | 
			
		||||
Mon Jul 22 17:23:00 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* eval.c (error_handle): should handle TAG_THROW as well.
 | 
			
		||||
 | 
			
		||||
Fri Jul 19 10:52:32 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* parse.y (yylex): new decimal notation '0d4567'.
 | 
			
		||||
 | 
			
		||||
Thu Jul 18 11:52:02 2002  Shugo Maeda  <shugo@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* lib/net/ftp.rb (set_socket): new method.
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +52,17 @@ Thu Jul 18 06:51:24 2002  Minero Aoki  <aamine@loveruby.net>
 | 
			
		|||
 | 
			
		||||
	* parse.y (yylex): fix typo.
 | 
			
		||||
 | 
			
		||||
Wed Jul 17 18:41:28 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* parse.y (yylex): new octal notation '0o777'.
 | 
			
		||||
 | 
			
		||||
Mon Jul 15 18:36:42 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* parse.y (string_content): every string_content node should
 | 
			
		||||
	  return string only.  use NODE_EVSTR to coercing.
 | 
			
		||||
 | 
			
		||||
	* eval.c (rb_eval): NODE_EVSTR support.
 | 
			
		||||
 | 
			
		||||
Mon Jul 15 10:35:35 2002  Minero Aoki  <aamine@loveruby.net>
 | 
			
		||||
 | 
			
		||||
	* parse.y (heredoc_identifier): fix typo.
 | 
			
		||||
| 
						 | 
				
			
			@ -61,6 +94,20 @@ Fri Jul 12 00:02:50 2002  Nobuyoshi Nakada  <nobu.nokada@softhome.net>
 | 
			
		|||
	* ext/stringio/stringio.c (strio_gets_internal): fixed for record
 | 
			
		||||
	  separator longer than 1.
 | 
			
		||||
 | 
			
		||||
Thu Jul 11 17:59:20 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* re.c (rb_reg_quote): avoid unnecessary string allocation.
 | 
			
		||||
 | 
			
		||||
	* string.c (get_pat): quote metachracters before compiling a
 | 
			
		||||
	  string into a regex.
 | 
			
		||||
 | 
			
		||||
	* string.c (rb_str_split_m): special treatment of strings of size
 | 
			
		||||
	  1, but AWK emulation.  now uses get_pat().
 | 
			
		||||
 | 
			
		||||
	* string.c (rb_str_match_m): quote metacharacters.
 | 
			
		||||
 | 
			
		||||
	* string.c (rb_str_match2): ditto.
 | 
			
		||||
 | 
			
		||||
Thu Jul 11 12:59:23 2002  Shugo Maeda  <shugo@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* lib/resolv.rb: untaint strings read from /etc/hosts and
 | 
			
		||||
| 
						 | 
				
			
			@ -256,6 +303,11 @@ Sun Jun 23 00:19:10 2002  Tadayoshi Funaba  <tadf@dotrb.org>
 | 
			
		|||
	* lib/date.rb, lib/date/format.rb, sample/cal.rb, sample/goodfriday.rb:
 | 
			
		||||
	  updated to the new version (based on date2 3.3).
 | 
			
		||||
 | 
			
		||||
Sat Jun 22 14:41:33 2002  Guy Decoux  <ts@moulon.inra.fr>
 | 
			
		||||
 | 
			
		||||
	* ext/socket/socket.c (sock_addrinfo): make all 3 versions of
 | 
			
		||||
	  getaddrinfo happy.  [ruby-core:00184]
 | 
			
		||||
 | 
			
		||||
Fri Jun 21 18:49:58 2002  Yukihiro Matsumoto  <matz@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* parse.y (yylex): __END__ should not be effective within
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										47
									
								
								LEGAL
									
										
									
									
									
								
							
							
						
						
									
										47
									
								
								LEGAL
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -83,6 +83,53 @@ win32/win32.[ch]:
 | 
			
		|||
    You may distribute under the terms of either the GNU General Public
 | 
			
		||||
    License or the Artistic License, as specified in the perl README file.
 | 
			
		||||
 | 
			
		||||
random.c
 | 
			
		||||
 | 
			
		||||
  This file is under the new-style BSD license.
 | 
			
		||||
 | 
			
		||||
    A C-program for MT19937, with initialization improved 2002/2/10.
 | 
			
		||||
    Coded by Takuji Nishimura and Makoto Matsumoto.
 | 
			
		||||
    This is a faster version by taking Shawn Cokus's optimization,
 | 
			
		||||
    Matthe Bellew's simplification, Isaku Wada's real version.
 | 
			
		||||
 | 
			
		||||
    Before using, initialize the state by using init_genrand(seed) 
 | 
			
		||||
    or init_by_array(init_key, key_length).
 | 
			
		||||
 | 
			
		||||
    Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
 | 
			
		||||
    All rights reserved.                          
 | 
			
		||||
 | 
			
		||||
    Redistribution and use in source and binary forms, with or without
 | 
			
		||||
    modification, are permitted provided that the following conditions
 | 
			
		||||
    are met:
 | 
			
		||||
 | 
			
		||||
      1. Redistributions of source code must retain the above copyright
 | 
			
		||||
	 notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
      2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
	 notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
	 documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
      3. The names of its contributors may not be used to endorse or promote 
 | 
			
		||||
	 products derived from this software without specific prior written 
 | 
			
		||||
	 permission.
 | 
			
		||||
 | 
			
		||||
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    Any feedback is very welcome.
 | 
			
		||||
    http://www.math.keio.ac.jp/matumoto/emt.html
 | 
			
		||||
    email: matumoto@math.keio.ac.jp
 | 
			
		||||
 | 
			
		||||
st.[ch]:
 | 
			
		||||
x68/*:
 | 
			
		||||
missing/alloca.c:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								ToDo
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								ToDo
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -78,6 +78,7 @@ Standard Libraries
 | 
			
		|||
- Hash::new{default}
 | 
			
		||||
- hash etc. should handle self referenceing array/hash
 | 
			
		||||
- Array#select(n1,n2...) works like Array#indexes(n1,n2...)
 | 
			
		||||
- use Mersenne Twister RNG for random.
 | 
			
		||||
* String#scanf(?)
 | 
			
		||||
* Object#fmt(?)
 | 
			
		||||
* Time::strptime
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								bignum.c
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								bignum.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1675,14 +1675,10 @@ rb_big_abs(x)
 | 
			
		|||
    return x;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* !!!warnig!!!!
 | 
			
		||||
   this is not really a random number!!
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
VALUE
 | 
			
		||||
rb_big_rand(max, rand)
 | 
			
		||||
rb_big_rand(max, rand_buf)
 | 
			
		||||
    VALUE max;
 | 
			
		||||
    double rand;
 | 
			
		||||
    double *rand_buf;
 | 
			
		||||
{
 | 
			
		||||
    VALUE v;
 | 
			
		||||
    long len;
 | 
			
		||||
| 
						 | 
				
			
			@ -1690,7 +1686,7 @@ rb_big_rand(max, rand)
 | 
			
		|||
    len = RBIGNUM(max)->len;
 | 
			
		||||
    v = bignew(len,1);
 | 
			
		||||
    while (len--) {
 | 
			
		||||
	BDIGITS(v)[len] = ((BDIGIT)~0) * rand;
 | 
			
		||||
	BDIGITS(v)[len] = ((BDIGIT)~0) * rand_buf[len];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return rb_big_modulo((VALUE)v, max);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										32
									
								
								eval.c
									
										
									
									
									
								
							
							
						
						
									
										32
									
								
								eval.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1141,6 +1141,17 @@ error_handle(ex)
 | 
			
		|||
	fprintf(stderr, ": retry outside of rescue clause\n");
 | 
			
		||||
	ex = 1;
 | 
			
		||||
	break;
 | 
			
		||||
      case TAG_THROW:
 | 
			
		||||
	if (prot_tag && prot_tag->frame && prot_tag->frame->file) {
 | 
			
		||||
	    fprintf(stderr, "%s:%d: uncaught throw\n",
 | 
			
		||||
		    prot_tag->frame->file, prot_tag->frame->line);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    error_pos();
 | 
			
		||||
	    fprintf(stderr, ": unexpected throw\n");
 | 
			
		||||
	}
 | 
			
		||||
	ex = 1;
 | 
			
		||||
	break;
 | 
			
		||||
      case TAG_RAISE:
 | 
			
		||||
      case TAG_FATAL:
 | 
			
		||||
	if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1354,17 +1365,21 @@ static void
 | 
			
		|||
jump_tag_but_local_jump(state)
 | 
			
		||||
    int state;
 | 
			
		||||
{
 | 
			
		||||
    VALUE val;
 | 
			
		||||
 | 
			
		||||
    if (prot_tag) val = prot_tag->retval;
 | 
			
		||||
    else          val = Qnil;
 | 
			
		||||
    switch (state) {
 | 
			
		||||
      case 0:
 | 
			
		||||
	break;
 | 
			
		||||
      case TAG_RETURN:
 | 
			
		||||
	localjump_error("unexpected return", Qnil);
 | 
			
		||||
	localjump_error("unexpected return", val);
 | 
			
		||||
	break;
 | 
			
		||||
      case TAG_NEXT:
 | 
			
		||||
	localjump_error("unexpected next", Qnil);
 | 
			
		||||
	localjump_error("unexpected next", val);
 | 
			
		||||
	break;
 | 
			
		||||
      case TAG_BREAK:
 | 
			
		||||
	localjump_error("unexpected break", Qnil);
 | 
			
		||||
	localjump_error("unexpected break", val);
 | 
			
		||||
	break;
 | 
			
		||||
      case TAG_REDO:
 | 
			
		||||
	localjump_error("unexpected redo", Qnil);
 | 
			
		||||
| 
						 | 
				
			
			@ -1412,7 +1427,6 @@ rb_eval_cmd(cmd, arg, tcheck)
 | 
			
		|||
    if ((state = EXEC_TAG()) == 0) {
 | 
			
		||||
	val = eval(ruby_top_self, cmd, Qnil, 0, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
 | 
			
		||||
       scope_dup(saved_scope);
 | 
			
		||||
    ruby_scope = saved_scope;
 | 
			
		||||
| 
						 | 
				
			
			@ -3059,6 +3073,10 @@ rb_eval(self, n)
 | 
			
		|||
	result = rb_str_new3(node->nd_lit);
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case NODE_EVSTR:
 | 
			
		||||
	result = rb_obj_as_string(rb_eval(self, node->nd_body));
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case NODE_DSTR:
 | 
			
		||||
      case NODE_DXSTR:
 | 
			
		||||
      case NODE_DREGX:
 | 
			
		||||
| 
						 | 
				
			
			@ -7102,6 +7120,12 @@ rb_mod_define_method(argc, argv, mod)
 | 
			
		|||
	node = NEW_DMETHOD(method_unbind(body));
 | 
			
		||||
    }
 | 
			
		||||
    else if (RDATA(body)->dmark == (RUBY_DATA_FUNC)blk_mark) {
 | 
			
		||||
	struct BLOCK *block;
 | 
			
		||||
 | 
			
		||||
	body = bind_clone(body);
 | 
			
		||||
	Data_Get_Struct(body, struct BLOCK, block);
 | 
			
		||||
	block->frame.last_func = id;
 | 
			
		||||
	block->frame.last_class = mod;
 | 
			
		||||
	node = NEW_BMETHOD(body);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								gc.c
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								gc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -651,7 +651,6 @@ rb_gc_mark_children(ptr)
 | 
			
		|||
	  case NODE_ARRAY:
 | 
			
		||||
	  case NODE_DSTR:
 | 
			
		||||
	  case NODE_DXSTR:
 | 
			
		||||
	  case NODE_EVSTR:
 | 
			
		||||
	  case NODE_DREGX:
 | 
			
		||||
	  case NODE_DREGX_ONCE:
 | 
			
		||||
	  case NODE_FBODY:
 | 
			
		||||
| 
						 | 
				
			
			@ -697,6 +696,7 @@ rb_gc_mark_children(ptr)
 | 
			
		|||
	  case NODE_MODULE:
 | 
			
		||||
	  case NODE_COLON3:
 | 
			
		||||
	  case NODE_OPT_N:
 | 
			
		||||
	  case NODE_EVSTR:
 | 
			
		||||
	    rb_gc_mark((VALUE)obj->as.node.u2.node);
 | 
			
		||||
	    break;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								intern.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								intern.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -89,7 +89,7 @@ VALUE rb_big_and _((VALUE, VALUE));
 | 
			
		|||
VALUE rb_big_or _((VALUE, VALUE));
 | 
			
		||||
VALUE rb_big_xor _((VALUE, VALUE));
 | 
			
		||||
VALUE rb_big_lshift _((VALUE, VALUE));
 | 
			
		||||
VALUE rb_big_rand _((VALUE, double));
 | 
			
		||||
VALUE rb_big_rand _((VALUE, double*));
 | 
			
		||||
/* class.c */
 | 
			
		||||
VALUE rb_class_boot _((VALUE));
 | 
			
		||||
VALUE rb_class_new _((VALUE));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								node.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								node.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -294,7 +294,7 @@ typedef struct RNode {
 | 
			
		|||
#define NEW_DSTR(s) rb_node_newnode(NODE_DSTR,s,0,0)
 | 
			
		||||
#define NEW_XSTR(s) rb_node_newnode(NODE_XSTR,s,0,0)
 | 
			
		||||
#define NEW_DXSTR(s) rb_node_newnode(NODE_DXSTR,s,0,0)
 | 
			
		||||
#define NEW_EVSTR(s,l) rb_node_newnode(NODE_EVSTR,rb_str_new(s,l),0,0)
 | 
			
		||||
#define NEW_EVSTR(n) rb_node_newnode(NODE_EVSTR,0,(n),0)
 | 
			
		||||
#define NEW_CALL(r,m,a) rb_node_newnode(NODE_CALL,r,m,a)
 | 
			
		||||
#define NEW_FCALL(m,a) rb_node_newnode(NODE_FCALL,0,m,a)
 | 
			
		||||
#define NEW_VCALL(m) rb_node_newnode(NODE_VCALL,0,m,0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -861,6 +861,7 @@ rb_num2long(val)
 | 
			
		|||
      case T_BIGNUM:
 | 
			
		||||
	return rb_big2long(val);
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
      case T_STRING:
 | 
			
		||||
	rb_raise(rb_eTypeError, "no implicit conversion to integer from string");
 | 
			
		||||
	return Qnil;		/* not reached */
 | 
			
		||||
| 
						 | 
				
			
			@ -869,7 +870,7 @@ rb_num2long(val)
 | 
			
		|||
      case T_FALSE:
 | 
			
		||||
	rb_raise(rb_eTypeError, "no implicit conversion to integer from boolean");
 | 
			
		||||
	return Qnil;		/* not reached */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
      default:
 | 
			
		||||
	val = rb_to_int(val);
 | 
			
		||||
	return NUM2LONG(val);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										78
									
								
								parse.y
									
										
									
									
									
								
							
							
						
						
									
										78
									
								
								parse.y
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -369,22 +369,16 @@ stmts		: none
 | 
			
		|||
 | 
			
		||||
stmt		: kALIAS fitem {lex_state = EXPR_FNAME;} fitem
 | 
			
		||||
		    {
 | 
			
		||||
			if (in_def || in_single)
 | 
			
		||||
			    yyerror("alias within method");
 | 
			
		||||
		        $$ = NEW_ALIAS($2, $4);
 | 
			
		||||
		    }
 | 
			
		||||
		| kALIAS tGVAR tGVAR
 | 
			
		||||
		    {
 | 
			
		||||
			if (in_def || in_single)
 | 
			
		||||
			    yyerror("alias within method");
 | 
			
		||||
		        $$ = NEW_VALIAS($2, $3);
 | 
			
		||||
		    }
 | 
			
		||||
		| kALIAS tGVAR tBACK_REF
 | 
			
		||||
		    {
 | 
			
		||||
			char buf[3];
 | 
			
		||||
 | 
			
		||||
			if (in_def || in_single)
 | 
			
		||||
			    yyerror("alias within method");
 | 
			
		||||
			sprintf(buf, "$%c", $3->nd_nth);
 | 
			
		||||
		        $$ = NEW_VALIAS($2, rb_intern(buf));
 | 
			
		||||
		    }
 | 
			
		||||
| 
						 | 
				
			
			@ -395,8 +389,6 @@ stmt		: kALIAS fitem {lex_state = EXPR_FNAME;} fitem
 | 
			
		|||
		    }
 | 
			
		||||
		| kUNDEF undef_list
 | 
			
		||||
		    {
 | 
			
		||||
			if (in_def || in_single)
 | 
			
		||||
			    yyerror("undef within method");
 | 
			
		||||
			$$ = $2;
 | 
			
		||||
		    }
 | 
			
		||||
		| stmt kIF_MOD expr_value
 | 
			
		||||
| 
						 | 
				
			
			@ -632,8 +624,6 @@ command		: operation command_args
 | 
			
		|||
		    }
 | 
			
		||||
		| kSUPER command_args
 | 
			
		||||
		    {
 | 
			
		||||
			if (!compile_for_eval && !in_def && !in_single)
 | 
			
		||||
			    yyerror("super called outside of method");
 | 
			
		||||
			$$ = new_super($2);
 | 
			
		||||
		        fixpos($$, $2);
 | 
			
		||||
		    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1490,8 +1480,6 @@ primary		: literal
 | 
			
		|||
		    }
 | 
			
		||||
		| kDEF fname
 | 
			
		||||
		    {
 | 
			
		||||
			if (in_def || in_single)
 | 
			
		||||
			    yyerror("nested method definition");
 | 
			
		||||
			$<id>$ = cur_mid;
 | 
			
		||||
			cur_mid = $2;
 | 
			
		||||
			in_def++;
 | 
			
		||||
| 
						 | 
				
			
			@ -1658,16 +1646,10 @@ method_call	: operation paren_args
 | 
			
		|||
		    }
 | 
			
		||||
		| kSUPER paren_args
 | 
			
		||||
		    {
 | 
			
		||||
			if (!compile_for_eval && !in_def &&
 | 
			
		||||
		            !in_single && !in_defined)
 | 
			
		||||
			    yyerror("super called outside of method");
 | 
			
		||||
			$$ = new_super($2);
 | 
			
		||||
		    }
 | 
			
		||||
		| kSUPER
 | 
			
		||||
		    {
 | 
			
		||||
			if (!compile_for_eval && !in_def &&
 | 
			
		||||
		            !in_single && !in_defined)
 | 
			
		||||
			    yyerror("super called outside of method");
 | 
			
		||||
			$$ = NEW_ZSUPER();
 | 
			
		||||
		    }
 | 
			
		||||
		;
 | 
			
		||||
| 
						 | 
				
			
			@ -1936,7 +1918,7 @@ string_content	: tSTRING_CONTENT {$$ = NEW_STR($1);}
 | 
			
		|||
		    {
 | 
			
		||||
			lex_strnest = $<num>1;
 | 
			
		||||
			lex_strterm = $<node>2;
 | 
			
		||||
			$$ = $3;
 | 
			
		||||
		        $$ = NEW_EVSTR($3);
 | 
			
		||||
		    }
 | 
			
		||||
		| tSTRING_DBEG term_push
 | 
			
		||||
		    {
 | 
			
		||||
| 
						 | 
				
			
			@ -1954,6 +1936,7 @@ string_content	: tSTRING_CONTENT {$$ = NEW_STR($1);}
 | 
			
		|||
			    $$ = $$->nd_next;
 | 
			
		||||
			    rb_gc_force_recycle((VALUE)$4);
 | 
			
		||||
			}
 | 
			
		||||
		        $$ = NEW_EVSTR($$);
 | 
			
		||||
		    }
 | 
			
		||||
		;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3570,7 +3553,7 @@ yylex()
 | 
			
		|||
		    pushback(c);
 | 
			
		||||
		    tokfix();
 | 
			
		||||
		    if (toklen() == start) {
 | 
			
		||||
			yyerror("hexadecimal number without hex-digits");
 | 
			
		||||
			yyerror("numeric literal without digits");
 | 
			
		||||
		    }
 | 
			
		||||
		    else if (nondigit) goto trailing_uc;
 | 
			
		||||
		    yylval.val = rb_cstr_to_inum(tok(), 16, Qfalse);
 | 
			
		||||
| 
						 | 
				
			
			@ -3600,8 +3583,44 @@ yylex()
 | 
			
		|||
		    yylval.val = rb_cstr_to_inum(tok(), 2, Qfalse);
 | 
			
		||||
		    return tINTEGER;
 | 
			
		||||
		}
 | 
			
		||||
		if (c >= '0' && c <= '7' || c == '_') {
 | 
			
		||||
		if (c == 'd' || c == 'D') {
 | 
			
		||||
		    /* decimal */
 | 
			
		||||
		    c = nextc();
 | 
			
		||||
		    if (ISDIGIT(c)) {
 | 
			
		||||
			do {
 | 
			
		||||
			    if (c == '_') {
 | 
			
		||||
				if (nondigit) break;
 | 
			
		||||
				nondigit = c;
 | 
			
		||||
				continue;
 | 
			
		||||
			    }
 | 
			
		||||
			    if (!ISDIGIT(c)) break;
 | 
			
		||||
			    nondigit = 0;
 | 
			
		||||
			    tokadd(c);
 | 
			
		||||
			} while (c = nextc());
 | 
			
		||||
		    }
 | 
			
		||||
		    pushback(c);
 | 
			
		||||
		    tokfix();
 | 
			
		||||
		    if (toklen() == start) {
 | 
			
		||||
			yyerror("numeric literal without digits");
 | 
			
		||||
		    }
 | 
			
		||||
		    else if (nondigit) goto trailing_uc;
 | 
			
		||||
		    yylval.val = rb_cstr_to_inum(tok(), 10, Qfalse);
 | 
			
		||||
		    return tINTEGER;
 | 
			
		||||
		}
 | 
			
		||||
		if (c == '_') {
 | 
			
		||||
		    /* 0_0 */
 | 
			
		||||
		    goto octal_number;
 | 
			
		||||
		}
 | 
			
		||||
		if (c == 'o' || c == 'O') {
 | 
			
		||||
		    /* prefixed octal */
 | 
			
		||||
		    c = nextc();
 | 
			
		||||
		    if (c == '_') {
 | 
			
		||||
			yyerror("numeric literal without digits");
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
		if (c >= '0' && c <= '7') {
 | 
			
		||||
		    /* octal */
 | 
			
		||||
		  octal_number:
 | 
			
		||||
	            do {
 | 
			
		||||
			if (c == '_') {
 | 
			
		||||
			    if (nondigit) break;
 | 
			
		||||
| 
						 | 
				
			
			@ -4299,24 +4318,26 @@ block_append(head, tail)
 | 
			
		|||
    return head;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* append item to the list */
 | 
			
		||||
static NODE*
 | 
			
		||||
list_append(head, tail)
 | 
			
		||||
    NODE *head, *tail;
 | 
			
		||||
list_append(list, item)
 | 
			
		||||
    NODE *list, *item;
 | 
			
		||||
{
 | 
			
		||||
    NODE *last;
 | 
			
		||||
 | 
			
		||||
    if (head == 0) return NEW_LIST(tail);
 | 
			
		||||
    if (list == 0) return NEW_LIST(item);
 | 
			
		||||
 | 
			
		||||
    last = head;
 | 
			
		||||
    last = list;
 | 
			
		||||
    while (last->nd_next) {
 | 
			
		||||
	last = last->nd_next;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    last->nd_next = NEW_LIST(tail);
 | 
			
		||||
    head->nd_alen += 1;
 | 
			
		||||
    return head;
 | 
			
		||||
    last->nd_next = NEW_LIST(item);
 | 
			
		||||
    list->nd_alen += 1;
 | 
			
		||||
    return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* concat two lists */
 | 
			
		||||
static NODE*
 | 
			
		||||
list_concat(head, tail)
 | 
			
		||||
    NODE *head, *tail;
 | 
			
		||||
| 
						 | 
				
			
			@ -4439,6 +4460,7 @@ literal_append(head, tail)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* concat two string literals */
 | 
			
		||||
static NODE *
 | 
			
		||||
literal_concat(head, tail)
 | 
			
		||||
    NODE *head, *tail;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										235
									
								
								random.c
									
										
									
									
									
								
							
							
						
						
									
										235
									
								
								random.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -10,6 +10,131 @@
 | 
			
		|||
 | 
			
		||||
**********************************************************************/
 | 
			
		||||
 | 
			
		||||
/* 
 | 
			
		||||
This is based on trimmed version of MT19937.  To get the original version,
 | 
			
		||||
contact <http://www.math.keio.ac.jp/~matumoto/emt.html>.
 | 
			
		||||
 | 
			
		||||
The original copyright notice follows.
 | 
			
		||||
 | 
			
		||||
   A C-program for MT19937, with initialization improved 2002/2/10.
 | 
			
		||||
   Coded by Takuji Nishimura and Makoto Matsumoto.
 | 
			
		||||
   This is a faster version by taking Shawn Cokus's optimization,
 | 
			
		||||
   Matthe Bellew's simplification, Isaku Wada's real version.
 | 
			
		||||
 | 
			
		||||
   Before using, initialize the state by using init_genrand(seed) 
 | 
			
		||||
   or init_by_array(init_key, key_length).
 | 
			
		||||
 | 
			
		||||
   Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
 | 
			
		||||
   All rights reserved.                          
 | 
			
		||||
 | 
			
		||||
   Redistribution and use in source and binary forms, with or without
 | 
			
		||||
   modification, are permitted provided that the following conditions
 | 
			
		||||
   are met:
 | 
			
		||||
 | 
			
		||||
     1. Redistributions of source code must retain the above copyright
 | 
			
		||||
        notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
     2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
        notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
        documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
     3. The names of its contributors may not be used to endorse or promote 
 | 
			
		||||
        products derived from this software without specific prior written 
 | 
			
		||||
        permission.
 | 
			
		||||
 | 
			
		||||
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | 
			
		||||
   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | 
			
		||||
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | 
			
		||||
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 | 
			
		||||
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 | 
			
		||||
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 | 
			
		||||
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 | 
			
		||||
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 | 
			
		||||
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 | 
			
		||||
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 | 
			
		||||
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   Any feedback is very welcome.
 | 
			
		||||
   http://www.math.keio.ac.jp/matumoto/emt.html
 | 
			
		||||
   email: matumoto@math.keio.ac.jp
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/* Period parameters */  
 | 
			
		||||
#define N 624
 | 
			
		||||
#define M 397
 | 
			
		||||
#define MATRIX_A 0x9908b0dfUL   /* constant vector a */
 | 
			
		||||
#define UMASK 0x80000000UL /* most significant w-r bits */
 | 
			
		||||
#define LMASK 0x7fffffffUL /* least significant r bits */
 | 
			
		||||
#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
 | 
			
		||||
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
 | 
			
		||||
 | 
			
		||||
static unsigned long state[N]; /* the array for the state vector  */
 | 
			
		||||
static int left = 1;
 | 
			
		||||
static int initf = 0;
 | 
			
		||||
static unsigned long *next;
 | 
			
		||||
 | 
			
		||||
/* initializes state[N] with a seed */
 | 
			
		||||
static void
 | 
			
		||||
init_genrand(s)
 | 
			
		||||
    unsigned long s;
 | 
			
		||||
{
 | 
			
		||||
    int j;
 | 
			
		||||
    state[0]= s & 0xffffffffUL;
 | 
			
		||||
    for (j=1; j<N; j++) {
 | 
			
		||||
        state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j); 
 | 
			
		||||
        /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
 | 
			
		||||
        /* In the previous versions, MSBs of the seed affect   */
 | 
			
		||||
        /* only MSBs of the array state[].                        */
 | 
			
		||||
        /* 2002/01/09 modified by Makoto Matsumoto             */
 | 
			
		||||
        state[j] &= 0xffffffffUL;  /* for >32 bit machines */
 | 
			
		||||
    }
 | 
			
		||||
    left = 1; initf = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
next_state()
 | 
			
		||||
{
 | 
			
		||||
    unsigned long *p=state;
 | 
			
		||||
    int j;
 | 
			
		||||
 | 
			
		||||
    /* if init_genrand() has not been called, */
 | 
			
		||||
    /* a default initial seed is used         */
 | 
			
		||||
    if (initf==0) init_genrand(5489UL);
 | 
			
		||||
 | 
			
		||||
    left = N;
 | 
			
		||||
    next = state;
 | 
			
		||||
    
 | 
			
		||||
    for (j=N-M+1; --j; p++) 
 | 
			
		||||
        *p = p[M] ^ TWIST(p[0], p[1]);
 | 
			
		||||
 | 
			
		||||
    for (j=M; --j; p++) 
 | 
			
		||||
        *p = p[M-N] ^ TWIST(p[0], p[1]);
 | 
			
		||||
 | 
			
		||||
    *p = p[M-N] ^ TWIST(p[0], state[0]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* generates a random number on [0,1)-real-interval */
 | 
			
		||||
static double
 | 
			
		||||
genrand_real()
 | 
			
		||||
{
 | 
			
		||||
    unsigned long y;
 | 
			
		||||
 | 
			
		||||
    if (--left == 0) next_state();
 | 
			
		||||
    y = *next++;
 | 
			
		||||
 | 
			
		||||
    /* Tempering */
 | 
			
		||||
    y ^= (y >> 11);
 | 
			
		||||
    y ^= (y << 7) & 0x9d2c5680UL;
 | 
			
		||||
    y ^= (y << 15) & 0xefc60000UL;
 | 
			
		||||
    y ^= (y >> 18);
 | 
			
		||||
 | 
			
		||||
    return (double)y * (1.0/4294967296.0); 
 | 
			
		||||
    /* divided by 2^32 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* These real versions are due to Isaku Wada, 2002/01/09 added */
 | 
			
		||||
 | 
			
		||||
#include "ruby.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_UNISTD_H
 | 
			
		||||
| 
						 | 
				
			
			@ -27,84 +152,33 @@ struct timeval {
 | 
			
		|||
#endif
 | 
			
		||||
#endif /* NT */
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_STDLIB_H
 | 
			
		||||
# include <stdlib.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Prefer to use drand48, otherwise use random, or rand as a last resort.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef HAVE_DRAND48
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_DRAND48_DECL
 | 
			
		||||
double drand48 _((void));
 | 
			
		||||
void srand48 _((long));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define SRANDOM(s)	srand48((long)(s))
 | 
			
		||||
#define RANDOM_NUMBER	drand48()
 | 
			
		||||
 | 
			
		||||
#else /* not HAVE_DRAND48 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * The largest number returned by the random number generator is
 | 
			
		||||
 * RANDOM_MAX.  If we're using `rand' it's RAND_MAX, but if we're
 | 
			
		||||
 * using `random' it's 2^31-1.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef RANDOM_MAX
 | 
			
		||||
# ifndef HAVE_RANDOM
 | 
			
		||||
#  define RANDOM_MAX	RAND_MAX
 | 
			
		||||
# else
 | 
			
		||||
#  define RANDOM_MAX	2147483647.0
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_RANDOM
 | 
			
		||||
 | 
			
		||||
#define RANDOM	random
 | 
			
		||||
#define SRANDOM	srandom
 | 
			
		||||
 | 
			
		||||
#else /* HAVE_RANDOM */
 | 
			
		||||
 | 
			
		||||
#define RANDOM	rand
 | 
			
		||||
#define SRANDOM	srand
 | 
			
		||||
 | 
			
		||||
#endif /* HAVE_RANDOM */
 | 
			
		||||
 | 
			
		||||
/* 0 <= RANDOM_NUMBER < 1 */
 | 
			
		||||
#define RANDOM_NUMBER (((double)RANDOM())/((double)RANDOM_MAX+1))
 | 
			
		||||
 | 
			
		||||
#endif /* not HAVE_DRAND48 */
 | 
			
		||||
 | 
			
		||||
static int first = 1;
 | 
			
		||||
#ifdef HAVE_INITSTATE
 | 
			
		||||
static char state[256];
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
rand_init(seed)
 | 
			
		||||
    long seed;
 | 
			
		||||
    unsigned long seed;
 | 
			
		||||
{
 | 
			
		||||
    int old;
 | 
			
		||||
    static unsigned int saved_seed;
 | 
			
		||||
    static unsigned long saved_seed;
 | 
			
		||||
    unsigned long old;
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_INITSTATE
 | 
			
		||||
    if (first == 1) {
 | 
			
		||||
	initstate(1, state, sizeof state);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	setstate(state);
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    first = 0;
 | 
			
		||||
 | 
			
		||||
    SRANDOM(seed);
 | 
			
		||||
    init_genrand(seed);
 | 
			
		||||
    old = saved_seed;
 | 
			
		||||
    saved_seed = seed;
 | 
			
		||||
 | 
			
		||||
    return old;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static unsigned long
 | 
			
		||||
random_seed()
 | 
			
		||||
{
 | 
			
		||||
    static int n = 0;
 | 
			
		||||
    struct timeval tv;
 | 
			
		||||
 | 
			
		||||
    gettimeofday(&tv, 0);
 | 
			
		||||
    return tv.tv_sec ^ tv.tv_usec ^ getpid() ^ n++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
rb_f_srand(argc, argv, obj)
 | 
			
		||||
    int argc;
 | 
			
		||||
| 
						 | 
				
			
			@ -112,18 +186,14 @@ rb_f_srand(argc, argv, obj)
 | 
			
		|||
    VALUE obj;
 | 
			
		||||
{
 | 
			
		||||
    VALUE sd;
 | 
			
		||||
    unsigned int seed, old;
 | 
			
		||||
    unsigned long seed, old;
 | 
			
		||||
 | 
			
		||||
    rb_secure(4);
 | 
			
		||||
    if (rb_scan_args(argc, argv, "01", &sd) == 0) {
 | 
			
		||||
	static int n = 0;
 | 
			
		||||
	struct timeval tv;
 | 
			
		||||
 | 
			
		||||
	gettimeofday(&tv, 0);
 | 
			
		||||
	seed = tv.tv_sec ^ tv.tv_usec ^ getpid() ^ n++;
 | 
			
		||||
	seed = random_seed();
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	seed = NUM2UINT(sd);
 | 
			
		||||
	seed = NUM2ULONG(sd);
 | 
			
		||||
    }
 | 
			
		||||
    old = rand_init(seed);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -141,10 +211,7 @@ rb_f_rand(argc, argv, obj)
 | 
			
		|||
 | 
			
		||||
    rb_scan_args(argc, argv, "01", &vmax);
 | 
			
		||||
    if (first) {
 | 
			
		||||
	struct timeval tv;
 | 
			
		||||
 | 
			
		||||
	gettimeofday(&tv, 0);
 | 
			
		||||
	rand_init(tv.tv_sec ^ tv.tv_usec ^ getpid());
 | 
			
		||||
	rand_init(random_seed());
 | 
			
		||||
    }
 | 
			
		||||
    switch (TYPE(vmax)) {
 | 
			
		||||
      case T_FLOAT:
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +222,15 @@ rb_f_rand(argc, argv, obj)
 | 
			
		|||
	vmax = rb_dbl2big(RFLOAT(vmax)->value);
 | 
			
		||||
	/* fall through */
 | 
			
		||||
      case T_BIGNUM:
 | 
			
		||||
	return rb_big_rand(vmax, RANDOM_NUMBER);
 | 
			
		||||
        {
 | 
			
		||||
	    long len = RBIGNUM(vmax)->len;
 | 
			
		||||
	    double *buf = ALLOCA_N(double, len);
 | 
			
		||||
 | 
			
		||||
	    while (len--) {
 | 
			
		||||
		buf[len] = genrand_real();
 | 
			
		||||
	    }
 | 
			
		||||
	    return rb_big_rand(vmax, buf);
 | 
			
		||||
	}
 | 
			
		||||
      case T_NIL:
 | 
			
		||||
	max = 0;
 | 
			
		||||
	break;
 | 
			
		||||
| 
						 | 
				
			
			@ -165,11 +240,11 @@ rb_f_rand(argc, argv, obj)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    if (max == 0) {
 | 
			
		||||
	return rb_float_new(RANDOM_NUMBER);
 | 
			
		||||
	return rb_float_new(genrand_real());
 | 
			
		||||
    }
 | 
			
		||||
    val = max*RANDOM_NUMBER;
 | 
			
		||||
    if (max < 0) max = -max;
 | 
			
		||||
    val = max*genrand_real();
 | 
			
		||||
 | 
			
		||||
    if (val < 0) val = -val;
 | 
			
		||||
    return LONG2NUM(val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										60
									
								
								re.c
									
										
									
									
									
								
							
							
						
						
									
										60
									
								
								re.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1170,26 +1170,39 @@ rb_reg_initialize_m(argc, argv, self)
 | 
			
		|||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
rb_reg_s_quote(argc, argv)
 | 
			
		||||
    int argc;
 | 
			
		||||
    VALUE *argv;
 | 
			
		||||
VALUE
 | 
			
		||||
rb_reg_quote(str)
 | 
			
		||||
    VALUE str;
 | 
			
		||||
{
 | 
			
		||||
    VALUE str, kcode;
 | 
			
		||||
    int kcode_saved = reg_kcode;
 | 
			
		||||
    char *s, *send, *t;
 | 
			
		||||
    VALUE tmp;
 | 
			
		||||
    int c;
 | 
			
		||||
 | 
			
		||||
    rb_scan_args(argc, argv, "11", &str, &kcode);
 | 
			
		||||
    if (!NIL_P(kcode)) {
 | 
			
		||||
	rb_set_kcode(StringValuePtr(kcode));
 | 
			
		||||
	curr_kcode = reg_kcode;
 | 
			
		||||
	reg_kcode = kcode_saved;
 | 
			
		||||
    }
 | 
			
		||||
    StringValue(str);
 | 
			
		||||
    s = RSTRING(str)->ptr;
 | 
			
		||||
    send = s + RSTRING(str)->len;
 | 
			
		||||
    for (; s < send; s++) {
 | 
			
		||||
	c = *s;
 | 
			
		||||
	if (ismbchar(c)) {
 | 
			
		||||
	    int n = mbclen(c);
 | 
			
		||||
 | 
			
		||||
	    while (n-- && s < send)
 | 
			
		||||
		s++;
 | 
			
		||||
	    s--;
 | 
			
		||||
	    continue;
 | 
			
		||||
	}
 | 
			
		||||
	switch (c) {
 | 
			
		||||
	  case '\t': case '\f': case '\r': case '\n':
 | 
			
		||||
	  case '[': case ']': case '{': case '}':
 | 
			
		||||
	  case '(': case ')': case '|': case '-':
 | 
			
		||||
	  case '*': case '.': case '\\':
 | 
			
		||||
	  case '?': case '+': case '^': case '$':
 | 
			
		||||
	  case ' ': case '#':
 | 
			
		||||
	    goto meta_found;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
    return str;
 | 
			
		||||
 | 
			
		||||
  meta_found:
 | 
			
		||||
    tmp = rb_str_new(0, RSTRING(str)->len*2);
 | 
			
		||||
    t = RSTRING(tmp)->ptr;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1230,12 +1243,31 @@ rb_reg_s_quote(argc, argv)
 | 
			
		|||
	}
 | 
			
		||||
	*t++ = c;
 | 
			
		||||
    }
 | 
			
		||||
    kcode_reset_option();
 | 
			
		||||
    rb_str_resize(tmp, t - RSTRING(tmp)->ptr);
 | 
			
		||||
    OBJ_INFECT(tmp, str);
 | 
			
		||||
    return tmp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
rb_reg_s_quote(argc, argv)
 | 
			
		||||
    int argc;
 | 
			
		||||
    VALUE *argv;
 | 
			
		||||
{
 | 
			
		||||
    VALUE str, kcode;
 | 
			
		||||
    int kcode_saved = reg_kcode;
 | 
			
		||||
 | 
			
		||||
    rb_scan_args(argc, argv, "11", &str, &kcode);
 | 
			
		||||
    if (!NIL_P(kcode)) {
 | 
			
		||||
	rb_set_kcode(StringValuePtr(kcode));
 | 
			
		||||
	curr_kcode = reg_kcode;
 | 
			
		||||
	reg_kcode = kcode_saved;
 | 
			
		||||
    }
 | 
			
		||||
    StringValue(str);
 | 
			
		||||
    str = rb_reg_quote(str);
 | 
			
		||||
    kcode_reset_option();
 | 
			
		||||
    return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
rb_kcode()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								re.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								re.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -33,6 +33,7 @@ int rb_reg_search _((VALUE, VALUE, int, int));
 | 
			
		|||
VALUE rb_reg_regsub _((VALUE, VALUE, struct re_registers *));
 | 
			
		||||
int rb_reg_adjust_startpos _((VALUE, VALUE, int, int));
 | 
			
		||||
void rb_match_busy _((VALUE));
 | 
			
		||||
VALUE rb_reg_quote _((VALUE));
 | 
			
		||||
 | 
			
		||||
EXTERN int ruby_ignorecase;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										144
									
								
								string.c
									
										
									
									
									
								
							
							
						
						
									
										144
									
								
								string.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -889,16 +889,44 @@ rb_str_index_m(argc, argv, str)
 | 
			
		|||
    return INT2NUM(pos);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static long
 | 
			
		||||
rb_str_rindex(str, sub, pos)
 | 
			
		||||
    VALUE str, sub;
 | 
			
		||||
    long pos;
 | 
			
		||||
{
 | 
			
		||||
    long len = RSTRING(sub)->len;
 | 
			
		||||
    char *s, *sbeg, *t;
 | 
			
		||||
 | 
			
		||||
    /* substring longer than string */
 | 
			
		||||
    if (RSTRING(str)->len < len) return -1;
 | 
			
		||||
    if (RSTRING(str)->len - pos < len) {
 | 
			
		||||
	pos = RSTRING(str)->len - len;
 | 
			
		||||
    }
 | 
			
		||||
    sbeg = RSTRING(str)->ptr;
 | 
			
		||||
    s = RSTRING(str)->ptr + pos;
 | 
			
		||||
    t = RSTRING(sub)->ptr;
 | 
			
		||||
    if (len) {
 | 
			
		||||
	while (sbeg <= s) {
 | 
			
		||||
	    if (rb_memcmp(s, t, len) == 0) {
 | 
			
		||||
		return s - RSTRING(str)->ptr;
 | 
			
		||||
	    }
 | 
			
		||||
	    s--;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
	return pos;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
rb_str_rindex(argc, argv, str)
 | 
			
		||||
rb_str_rindex_m(argc, argv, str)
 | 
			
		||||
    int argc;
 | 
			
		||||
    VALUE *argv;
 | 
			
		||||
    VALUE str;
 | 
			
		||||
{
 | 
			
		||||
    VALUE sub;
 | 
			
		||||
    VALUE position;
 | 
			
		||||
    int pos, len;
 | 
			
		||||
    char *s, *sbeg, *t;
 | 
			
		||||
    int pos;
 | 
			
		||||
 | 
			
		||||
    if (rb_scan_args(argc, argv, "11", &sub, &position) == 2) {
 | 
			
		||||
	pos = NUM2INT(position);
 | 
			
		||||
| 
						 | 
				
			
			@ -927,26 +955,8 @@ rb_str_rindex(argc, argv, str)
 | 
			
		|||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_STRING:
 | 
			
		||||
	len = RSTRING(sub)->len;
 | 
			
		||||
	/* substring longer than string */
 | 
			
		||||
	if (RSTRING(str)->len < len) return Qnil;
 | 
			
		||||
	if (RSTRING(str)->len - pos < len) {
 | 
			
		||||
	    pos = RSTRING(str)->len - len;
 | 
			
		||||
	}
 | 
			
		||||
	sbeg = RSTRING(str)->ptr;
 | 
			
		||||
	s = RSTRING(str)->ptr + pos;
 | 
			
		||||
	t = RSTRING(sub)->ptr;
 | 
			
		||||
	if (len) {
 | 
			
		||||
	    while (sbeg <= s) {
 | 
			
		||||
		if (rb_memcmp(s, t, len) == 0) {
 | 
			
		||||
		    return INT2NUM(s - RSTRING(str)->ptr);
 | 
			
		||||
		}
 | 
			
		||||
		s--;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    return INT2NUM(pos);
 | 
			
		||||
	}
 | 
			
		||||
	pos = rb_str_rindex(str, sub, pos);
 | 
			
		||||
	if (pos >= 0) return INT2NUM(pos);
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      case T_FIXNUM:
 | 
			
		||||
| 
						 | 
				
			
			@ -996,7 +1006,7 @@ rb_str_match2(str)
 | 
			
		|||
    VALUE str;
 | 
			
		||||
{
 | 
			
		||||
    StringValue(str);
 | 
			
		||||
    return rb_reg_match2(rb_reg_regcomp(str));
 | 
			
		||||
    return rb_reg_match2(rb_reg_regcomp(rb_reg_quote(str)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
| 
						 | 
				
			
			@ -1007,7 +1017,7 @@ rb_str_match_m(str, re)
 | 
			
		|||
 | 
			
		||||
    if (!NIL_P(str2)) {
 | 
			
		||||
	StringValue(re);
 | 
			
		||||
	re = rb_reg_regcomp(re);
 | 
			
		||||
	re = rb_reg_regcomp(rb_reg_quote(re));
 | 
			
		||||
    }
 | 
			
		||||
    return rb_funcall(re, rb_intern("match"), 1, str);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1397,19 +1407,29 @@ static VALUE
 | 
			
		|||
get_pat(pat)
 | 
			
		||||
    VALUE pat;
 | 
			
		||||
{
 | 
			
		||||
    VALUE val;
 | 
			
		||||
 | 
			
		||||
    switch (TYPE(pat)) {
 | 
			
		||||
      case T_REGEXP:
 | 
			
		||||
	break;
 | 
			
		||||
	return pat;
 | 
			
		||||
 | 
			
		||||
      case T_STRING:
 | 
			
		||||
	pat = rb_reg_regcomp(pat);
 | 
			
		||||
	break;
 | 
			
		||||
 | 
			
		||||
      default:
 | 
			
		||||
	/* type failed */
 | 
			
		||||
	Check_Type(pat, T_REGEXP);
 | 
			
		||||
	val = rb_check_convert_type(pat, T_STRING, "String", "to_str");
 | 
			
		||||
	if (NIL_P(val)) {
 | 
			
		||||
	    Check_Type(pat, T_REGEXP);
 | 
			
		||||
	}
 | 
			
		||||
	pat = val;
 | 
			
		||||
    }
 | 
			
		||||
    return pat;
 | 
			
		||||
    val = rb_reg_quote(pat);
 | 
			
		||||
#if RUBY_VERSION_CODE < 180
 | 
			
		||||
    if (val != pat) {
 | 
			
		||||
	rb_warn("string pattern instead of regexp; metacharacters no longer effective");
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    return rb_reg_regcomp(val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
| 
						 | 
				
			
			@ -2449,7 +2469,7 @@ rb_str_split_m(argc, argv, str)
 | 
			
		|||
{
 | 
			
		||||
    VALUE spat;
 | 
			
		||||
    VALUE limit;
 | 
			
		||||
    int char_sep = -1;
 | 
			
		||||
    int awk_split = Qfalse;
 | 
			
		||||
    long beg, end, i = 0;
 | 
			
		||||
    int lim = 0;
 | 
			
		||||
    VALUE result, tmp;
 | 
			
		||||
| 
						 | 
				
			
			@ -2466,67 +2486,51 @@ rb_str_split_m(argc, argv, str)
 | 
			
		|||
	    spat = rb_fs;
 | 
			
		||||
	    goto fs_set;
 | 
			
		||||
	}
 | 
			
		||||
	char_sep = ' ';
 | 
			
		||||
	awk_split = Qtrue;
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
      fs_set:
 | 
			
		||||
	switch (TYPE(spat)) {
 | 
			
		||||
	  case T_STRING:
 | 
			
		||||
	    if (RSTRING(spat)->len == 1) {
 | 
			
		||||
		char_sep = (unsigned char)RSTRING(spat)->ptr[0];
 | 
			
		||||
	if (TYPE(spat) == T_STRING && RSTRING(spat)->len == 1) {
 | 
			
		||||
	    if (RSTRING(spat)->ptr[0] == ' ') {
 | 
			
		||||
		awk_split = Qtrue;
 | 
			
		||||
	    }
 | 
			
		||||
	    else {
 | 
			
		||||
		spat = rb_reg_regcomp(spat);
 | 
			
		||||
		spat = rb_reg_regcomp(rb_reg_quote(spat));
 | 
			
		||||
	    }
 | 
			
		||||
	    break;
 | 
			
		||||
	  case T_REGEXP:
 | 
			
		||||
	    break;
 | 
			
		||||
	  default:
 | 
			
		||||
	    rb_raise(rb_eArgError, "bad separator");
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    spat = get_pat(spat);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    result = rb_ary_new();
 | 
			
		||||
    beg = 0;
 | 
			
		||||
    if (char_sep >= 0) {
 | 
			
		||||
    if (awk_split) {
 | 
			
		||||
	char *ptr = RSTRING(str)->ptr;
 | 
			
		||||
	long len = RSTRING(str)->len;
 | 
			
		||||
	char *eptr = ptr + len;
 | 
			
		||||
	int skip = 1;
 | 
			
		||||
 | 
			
		||||
	if (char_sep == ' ') {	/* AWK emulation */
 | 
			
		||||
	    int skip = 1;
 | 
			
		||||
 | 
			
		||||
	    for (end = beg = 0; ptr<eptr; ptr++) {
 | 
			
		||||
		if (skip) {
 | 
			
		||||
		    if (ISSPACE(*ptr)) {
 | 
			
		||||
			beg++;
 | 
			
		||||
		    }
 | 
			
		||||
		    else {
 | 
			
		||||
			end = beg+1;
 | 
			
		||||
			skip = 0;
 | 
			
		||||
		    }
 | 
			
		||||
	for (end = beg = 0; ptr<eptr; ptr++) {
 | 
			
		||||
	    if (skip) {
 | 
			
		||||
		if (ISSPACE(*ptr)) {
 | 
			
		||||
		    beg++;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
		    if (ISSPACE(*ptr)) {
 | 
			
		||||
			rb_ary_push(result, rb_str_substr(str, beg, end-beg));
 | 
			
		||||
			skip = 1;
 | 
			
		||||
			beg = end + 1;
 | 
			
		||||
			if (!NIL_P(limit) && lim <= ++i) break;
 | 
			
		||||
		    }
 | 
			
		||||
		    else {
 | 
			
		||||
			end++;
 | 
			
		||||
		    }
 | 
			
		||||
		    end = beg+1;
 | 
			
		||||
		    skip = 0;
 | 
			
		||||
		}
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    for (end = beg = 0; ptr<eptr; ptr++) {
 | 
			
		||||
		if (*ptr == (char)char_sep) {
 | 
			
		||||
	    else {
 | 
			
		||||
		if (ISSPACE(*ptr)) {
 | 
			
		||||
		    rb_ary_push(result, rb_str_substr(str, beg, end-beg));
 | 
			
		||||
		    skip = 1;
 | 
			
		||||
		    beg = end + 1;
 | 
			
		||||
		    if (!NIL_P(limit) && lim <= ++i) break;
 | 
			
		||||
		}
 | 
			
		||||
		end++;
 | 
			
		||||
		else {
 | 
			
		||||
		    end++;
 | 
			
		||||
		}
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -3178,7 +3182,7 @@ Init_String()
 | 
			
		|||
    rb_define_method(rb_cString, "next!", rb_str_succ_bang, 0);
 | 
			
		||||
    rb_define_method(rb_cString, "upto", rb_str_upto_m, 1);
 | 
			
		||||
    rb_define_method(rb_cString, "index", rb_str_index_m, -1);
 | 
			
		||||
    rb_define_method(rb_cString, "rindex", rb_str_rindex, -1);
 | 
			
		||||
    rb_define_method(rb_cString, "rindex", rb_str_rindex_m, -1);
 | 
			
		||||
    rb_define_method(rb_cString, "replace", rb_str_replace, 1);
 | 
			
		||||
 | 
			
		||||
    rb_define_method(rb_cString, "to_i", rb_str_to_i, -1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue