summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-01-16 12:19:22 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1998-01-16 12:19:22 +0000
commitfd1d8cdc09ed86e4a0812120a17ff0d7b04adcaf (patch)
tree341289a84a427f1e92425c7ebf82d2f1733e9a40
parentf12baed5df6d3c213dd75d2f0d9f36bb179fb843 (diff)
*** empty log message ***
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/RUBY@11 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog4398
-rw-r--r--MANIFEST26
-rw-r--r--Makefile.in128
-rw-r--r--README69
-rw-r--r--README.jp73
-rw-r--r--array.c548
-rw-r--r--bignum.c358
-rw-r--r--class.c341
-rw-r--r--defines.h2
-rw-r--r--dir.c40
-rw-r--r--dln.c71
-rw-r--r--enum.c68
-rw-r--r--env.h6
-rw-r--r--error.c25
-rw-r--r--eval.c1576
-rw-r--r--ext/Setup2
-rw-r--r--ext/curses/curses.c67
-rw-r--r--ext/dbm/dbm.c8
-rw-r--r--ext/dbm/depend2
-rw-r--r--ext/etc/depend2
-rw-r--r--ext/extmk.rb.in76
-rw-r--r--ext/extmk.rb.nt115
-rw-r--r--ext/fcntl/depend2
-rw-r--r--ext/kconv/depend2
-rw-r--r--ext/kconv/kconv.c122
-rw-r--r--ext/md5/depend2
-rw-r--r--ext/socket/depend2
-rw-r--r--ext/socket/extconf.rb17
-rw-r--r--ext/socket/socket.c404
-rw-r--r--ext/tkutil/depend2
-rw-r--r--file.c277
-rw-r--r--gc.c168
-rw-r--r--hash.c360
-rw-r--r--inits.c36
-rw-r--r--io.c303
-rw-r--r--io.h7
-rw-r--r--lib/cgi-lib.rb77
-rw-r--r--lib/finalize.rb36
-rw-r--r--lib/mailread.rb43
-rw-r--r--lib/sync.rb90
-rw-r--r--lib/tk.rb573
-rw-r--r--lib/tktext.rb4
-rw-r--r--math.c52
-rw-r--r--missing/dir.h63
-rw-r--r--missing/nt.c15
-rw-r--r--missing/nt.h137
-rw-r--r--missing/setenv.c74
-rw-r--r--node.h43
-rw-r--r--numeric.c176
-rw-r--r--object.c393
-rw-r--r--pack.c133
-rw-r--r--parse.y838
-rw-r--r--process.c132
-rw-r--r--random.c3
-rw-r--r--range.c3
-rw-r--r--re.c409
-rw-r--r--re.h7
-rw-r--r--regex.h9
-rw-r--r--ruby.c137
-rw-r--r--ruby.h150
-rw-r--r--sample/exyacc.rb2
-rw-r--r--sample/fact.rb10
-rw-r--r--sample/mkproto.rb2
-rw-r--r--sample/ruby-mode.el11
-rw-r--r--sample/test.rb244
-rw-r--r--sample/tkhello.rb17
-rw-r--r--sample/uumerge.rb36
-rw-r--r--sprintf.c12
-rw-r--r--string.c790
-rw-r--r--struct.c127
-rw-r--r--time.c65
-rw-r--r--top.sed6
-rw-r--r--util.c54
-rw-r--r--variable.c395
-rw-r--r--version.c2
-rw-r--r--version.h4
-rw-r--r--win32/Makefile42
-rw-r--r--win32/ruby.def439
78 files changed, 7824 insertions, 7736 deletions
diff --git a/ChangeLog b/ChangeLog
index 8c4a1ea..029e200 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4305 +1,831 @@
-Thu Dec 25 17:06:30 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
+Fri Jan 16 00:43:43 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
- * version 1.0-971225
+ * ruby.h (CLONESETUP): copies its singleton classes too.
- * some minor bug fixes.
+ * class.c (singleton_class_attached): saves binded object in the
+ singleton classes.
-Tue Dec 9 17:54:56 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
+ * eval.c (rb_eval): calls singleton_method_added even in the
+ singleton class clauses.
- * version 1.0-971209
+Fri Jan 15 23:22:43 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * sample/ruby-mode.el (ruby-expr-beg): forgot to handle modifiers.
-
- * parse.y (tokadd): token buffer overrun.
-
-Thu Dec 4 14:29:59 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-971204
-
-Mon Dec 1 15:24:41 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * compar.c (cmp_between): wrong comparison made.
-
-Wed Nov 26 18:18:05 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * numeric.c (fix2str): enlarge buffer to prevent overflow on some
- machines.
-
-Tue Nov 25 15:03:28 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-971125
-
-Fri Nov 21 13:17:12 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (yylex): skip multibyte characters in comments.
-
-Wed Nov 19 17:19:20 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (call_args): wrong node generation.
-
-Tue Nov 18 13:59:59 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-971118
-
-Tue Nov 18 10:13:08 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * regex.c (re_compile_pattern): insert initialize code for jump_n,
- before entering loops.
-
-Sat Nov 15 00:11:36 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * io.c (io_s_popen): "rb" detection
-
-Wed Nov 12 13:44:47 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * time.c: remove coerce from Time class.
-
-Wed Nov 2 16:00:00 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * string.c (str_sub_s): "".sub! "", "" => "\000"
-
-Thu Oct 30 16:54:01 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * string.c (str_chop_bang): "".chop caused SEGV.
-
-Mon Oct 27 13:49:13 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/extmk.rb.in: library may have pathname contains `.'
-
- * eval.c (rb_rescue): should not protect SystemError.
-
-Thu Oct 23 11:17:44 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * range.c (range_eqq): fixnum check for last needed too.
-
-Wed Oct 22 12:52:30 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * array.c (ary_join): call ary_join() recursively for the 1st
- array element.
-
-Tue Oct 21 13:31:29 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-971021
-
-Mon Oct 20 12:18:29 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ruby.c (load_file): wrong condition for #! check with -x.
-
- * file.c (file_s_dirname): did return "" for "/a".
-
-Fri Oct 17 14:29:09 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * bignum.c (bigadd): some undefined side effect order assumed.
-
-Wed Oct 15 18:08:37 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-971015
-
-Fri Oct 3 10:51:10 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-971003
-
- * eval.c (ruby_options): f_require() called too early.
-
- * eval.c (rb_provide): module extentions should always be `.o'.
-
-Thu Oct 2 17:59:18 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/marshal/marshal.c (r_object): remove temporal regist for
- structs. (caused problem if structs form cycles.)
-
- * version 1.0-971002
-
-Wed Oct 1 14:01:49 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/marshal/marshal.c (w_byte): argument must be char.
-
-Wed Oct 1 10:30:22 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ext/marshal/marshal.c (marshal_dump): try to set binmode.
-
- * ext/marshal/marshal.c (r_object): forgot to re-regist structs in
- the object table.
-
- * eval.c (ruby_options): call Init_ext() before any require()
- calls by `-r'.
-
-Tue Sep 30 14:51:07 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-970930
-
-Fri Sep 30 14:29:22 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/marshal/marshal.c (w_object): marshal dumped core.
-
-Tue Sep 30 10:27:39 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * sample/test.rb: bignum test suits added.
-
-Mon Sep 29 13:37:58 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (forbid_setid): forbid some options in suid mode.
-
-Mon Sep 27 09:53:48 1997 EGUCHI Matsumoto <eguchi@shizuokanet.or.jp>
-
- * bignum.c: modified for speeding.
-
-Fri Sep 26 18:27:59 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * sample/from.rb: some extensions.
-
-Mon Sep 29 13:15:56 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (lhs): no more syntax error on `obj.CONSTANT = value'.
-
-Fri Sep 26 14:41:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (ruby_run): deferred calling Init_ext() just before eval_node.
-
-Fri Sep 26 13:27:24 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * io.c (io_isatty): forgot to return TRUE value.
-
-Fri Sep 25 11:10:58 1997 EGUCHI Osamu <eguchi@shizuokanet.or.jp>
-
- * eval.c: use _setjmp/_longjmp instead of setjmp/longjmp on some
- platforms.
-
-Wed Sep 24 17:43:13 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (Init_String): String#taint and String#taint? added.
-
-Wed Sep 24 00:57:00 1997 Katsuyuki Okabe <HGC02147@niftyserve.or.jp>
-
- * X68000 patch.
-
-Tue Sep 23 20:42:30 1997 EGUCHI Osamu <eguchi@shizuokanet.or.jp>
-
- * parse.y (node_newnode): SEGV on null node setup.
-
-Mon Sep 22 11:22:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * ruby.c (ruby_prog_init): wrong safe condition check.
-
-Sun Sep 21 14:46:02 1997 MAEDA shugo <shugo@po.aianet.ne.jp>
-
- * error.c (exc_inspect): garbage added to classpath.
-
-Fri Sep 19 11:49:23 1997 <matz@netlab.co.jp>
-
- * version 1.0-970919
-
- * parse.y (newtok): forgot to adjust buffer size when shrinking
- the token buffer.
-
- * enum.c (enum_find): rb_eval_cmd() does not return value.
-
- * io.c (pipe_open): close fds on pipe exec. fcntl(fd, F_SETFD, 1)
- no longer used.
-
-Tue Sep 16 17:54:25 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * file.c (f_test): problem if wrong command specified.
-
- * ruby.c (ruby_prog_init): close stdaux and stdprn for MSDOS.
-
- * ruby.c (ruby_prog_init): should not add path from environment
- variable, if ruby is running under seuid.
-
- * process.c (init_ids): check suid check for setuid/seteuid etc.
-
-Mon Sep 15 00:42:04 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * regex.c (re_compile_pattern): \w{3} and \W{3} did not work.
-
-Thu Sep 11 10:31:48 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-970911
-
- * ext/socket/socket.c (sock_new): no setbuf() for NT.
-
- * io.c (rb_fopen,rb_fdopen): set close-on-exec for every fd.
-
-Wed Sep 10 15:55:31 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-970910
-
- * ext/marshal/marshal.c (r_bytes0): extra big length check.
-
-Tue Sep 9 16:27:14 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (pipe_fptr_atexit): clean up popen()'ed fptr.
-
- * error.c (set_syserr): some system has error code that is bigger
- than sys_nerr. grrr.
-
-Tue Sep 9 16:27:14 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-970909
-
- * error.c (set_syserr): some system has error code that is bigger
- than sys_nerr. grrr.
-
-Wed Sep 3 18:11:00 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-970903
-
- * eval.c (f_load): expand path if fname begins with `~'.
-
-Mon Sep 1 13:42:48 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_call): alias occured in the module body caused SEGV.
-
-Fri Aug 29 11:10:21 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (yylex): spaces can follow =begin/=end.
-
- * variable.c (find_class_path): look for class_tbl also for
- unnamed fundamental classes, such as Object, String, etc.
-
- * variable.c (rb_name_class): can't name class before String class
- is initilialized.
-
- * inits.c (rb_call_inits): unrecognized dependency from GC to
- Array.
-
- * variable.c (find_class_path): could not find class if Object's
- iv_tbl is NULL.
-
-Thu Aug 28 13:12:05 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * parse.y (yylex): revised `=begin' skip code.
-
- * eval.c (is_defined): separated from rb_eval().
-
-Wed Aug 27 11:32:42 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * variable.c (fc_i): some classes/modules does not have iv_tbl.
-
- * variable.c (find_class_path): avoid inifinite loop.
-
-Tue Aug 26 13:43:47 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_eval): undef'ing non-existing method will raise
- NameError exception.
-
- * object.c (class_s_new): needed to create metaclass too.
-
- * eval.c (error_print): no class name print for anonymous class.
-
- * eval.c (rb_longjmp): proper exception raised if raise() called
- without arguments, with $! or $@ set.
-
- * object.c (Init_Object): superclass()'s method argument setting
- was wrong again.
-
-Mon Aug 25 11:53:11 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * sample/ruby-mode.el (ruby-parse-region): auto-indent now
- supports "\\" in the strings.
-
- * struct.c (struct_getmember): new API to get member value from C
- language side.
-
-Fri Aug 22 14:26:40 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (error_print): modified exception print format.
-
-Thu Aug 21 16:10:58 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * sample/ruby-mode.el (ruby-calculate-indent): wrong indent level
- calculated with keyword operators.
-
-Thu Aug 21 11:55:41 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-970821
-
-Thu Aug 21 11:36:58 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * parse.y (arg): ary[0] += 1 cause SEGV
-
-Wed Aug 20 14:24:42 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-970820
-
- * eval.c (rb_call): infinite loop bug
-
-Tue Aug 19 00:15:38 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * version 1.0-970819
-
- * eval.c (rb_call): did not raise ArgumentError if too many
- arguments more than optional arguments (without rest arg).
-
- * eval.c (rb_eval): did not work well for op_asgn2 (attribute
- self assignment).
-
-Mon Aug 18 09:25:56 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (inspect_i): did not display T_DATA instance variables.
-
- * parse.y: provides more accurate line number information.
-
- * eval.c (thread_value): include value's backtrace information in
- the variable `$@'.
-
- * eval.c (f_abort): print backtrace and exit.
-
-Sat Aug 16 00:17:44 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (class_s_new): do not make subclass of singleton class.
-
-Fri Aug 15 15:49:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (call_trace_func): block context switch in the trace
- function.
-
- * eval.c (rb_eval): clear method cache at class extention.
-
-Fri Aug 15 19:40:43 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * ext/socket/socket.c (Init_socket): small typo caused SEGV.
-
-Tue Aug 12 16:02:18 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * variable.c: option variables: $-0, $-p(readonly), $-v,
- $-I(load_path), $-a(readonly), $-K, $-d, $-F, $-i, $-l.
-
- * parse.y (yylex): ignore rd (ruby document) in the code.
-
-Mon Aug 11 12:37:58 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * re.c (Init_Regexp): $-K as alias to the $KCODE.
-
- * io.c (Init_IO): new virtual variable $-i for the value of -i
- option.
-
- * enum.c (Init_Enumerable): include? as alias of member?
-
-Fri Aug 8 11:16:50 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * io.c (io_foreach): now the record separator can be specified.
-
- * io.c (io_s_readlines): new method to read in whole file (or
- command output) from path.
-
- * ext/socket/socket.c (Init_socket): recvfrom did not work.
-
- * ext/socket/socket.c (sock_send): forgot to check nil for false
- value.
-
-Thu Aug 7 11:40:01 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (Init_Object): remove private_attr/public_attr.
-
-Wed Aug 6 14:21:36 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * object.c (mod_attr): forgot to check nil for false value.
-
-Mon Aug 4 11:50:28 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * variable.c (rb_class_path): scan class constants for anonymous
- classes/modules to make up pathes.
-
-Wed Jul 30 08:45:12 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (rb_eval): stop to cache const value in nodes.
-
-Sat Jul 26 03:17:22 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * numeric.c (flo_to_s): wrong .0 at end.
-
-Sat Jul 26 00:36:36 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * eval.c (error_print): always print exception type in the
- toplevel exception handler.
-
- * string.c (str_hash): wrong hash value.
-
-Thu Jul 24 11:05:51 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-
- * string.c (uscore_get): proper error message for unset $_.
-
-Wed Jul 23 09:56:55 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * object.c (obj_methods): returns list of method names of the
- specified object.
-
- * class.c (mod_instance_methods): returns list of method names of
- the class instnace.
-
-Fri Jul 11 22:38:55 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * object.c (class_superclass): returns class's superclass
- itself. (1.1)
-
- * object.c (obj_type): returns object's class itself. (1.1)
-
- * class.c (mod_included_modules): list included modules.
-
- * object.c (class_superclass): raises error for Object.
-
-Thu Jul 3 09:54:02 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (SETUP_ARGS): save source position, remove nd_line().
-
- * eval.c (rb_call): replace modulo by bit-masking.
-
- * eval.c (POP_SCOPE): force recycle scope object to reduce gc rate.
-
- * gc.c (obj_free): aboid calling run_final() when no finalizer is set.
-
- * eval.c (PUSH_VARS): do not allocate the dynamic scope's end-mark
- object.
-
-Wed Jul 2 14:25:07 1997 KIMURA Koichi <kkimura@pure.cpdc.canon.co.jp>
-
- * Native mswin32 support.
-
-Tue Jul 1 09:59:00 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970701
-
- * parse.y (mrhs): allow rest-star(*) in right hand side.
-
-Tue Jun 24 19:04:31 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970624
-
-Sat Jun 20 22:22:51 1997 Michio "Karl" Jinbo <karl@marcer.nagaokaut.ac.jp>
-
- * eval.c: freebsd 3.0 <sys/select.h> support.
-
-Fri Jun 20 01:24:45 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970620
-
- * gc.c: eliminate uninitilalized field of Hash, Array etc., to
- avoid dumping core.
-
-Thu Jun 19 01:29:44 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970619
-
- * string.c (str_split_method): wrong limit.
-
-Sat Jun 14 01:54:16 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * class.c (rb_singleton_class): no singleton for special
- constants (now raises exception).
-
- * eval.c (ruby_init): cbase in TOPLEVEL_BINDING need to be
- initialized.
-
-Sat Jun 14 01:01:16 1997 maeda shugo <shugo@po.aianet.ne.jp>
-
- * array.c (sort_2): wrong comparison.
-
-Sat Jun 14 00:53:44 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * hash.c (hash_foreach): safe iteration.
-
-Fri Jun 13 14:04:56 1997 Michio "Karl" Jinbo <karl@marcer.nagaokaut.ac.jp>
-
- * configure.in: -Bshareable option for netbsd.
-
-Fri Jun 13 01:16:22 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * io.c (pipe_open): call io_unbuffered() only for writable pipes.
-
-Thu Jun 12 01:14:15 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970612
-
- * ext/socket/socket.c (sock_new): use io_unbuffered().
-
- * ext/marshal/marshal.c (w_long): compact long format, which
- supports 64 bit architectures (unless longs are >32 bit size).
-
- * ext/marshal/marshal.c: allows recursive data for marshaling.
-
- * parse.y (rb_intern): raise exception for non-internable string.
-
- * ext/marshal/marshal.c (marshal_load): allows direct loading from
- strings.
-
- * ext/marshal/marshal.c (marshal_dump): allows direct dump to strings.
-
- * ext/marshal/marshal.c (marshal_dump): interface changed.
-
-Wed Jun 11 18:26:00 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * gc.c (rb_newobj): remove needless memset().
-
-Mon Jun 9 13:03:43 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_eval): reduce condition checks from while/until loop.
-
- * eval.c (rb_eval): wrong jump point for `next'.
-
-Fri Jun 6 11:47:39 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.c (ruby_set_argv): initialize dln_argv0 for dln_a_out.
-
- * ext/socket/socket.c (open_unix): display path name for exceptions.
-
- * ruby.c (proc_options): option -S did not work well.
-
-Fri May 30 02:14:44 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970530
-
- * eval.c (eval): set $! properly if exception raised in eval().
-
- * io.c (io_write): now handles non T_FILE object.
-
- * io.c (io_defset): $< can be anything which has `write' method.
-
-Thu May 29 15:40:22 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (eval): $@ is always an array (not string).
-
- * pack.c (pack_unpack): avoid corrupting memory for unexpected
- input strings.
-
-Wed May 28 12:46:13 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970528
-
- * process.c (rb_waitpid): do not block other threads.
-
-Tue May 27 12:02:31 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (ruby_init): split initialize and processing command line
- options.
-
- * ruby.c (ruby_options): ruby_init(0, 0, envp) dumps core.
-
-Tue May 20 18:59:45 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * variable.c (rb_ivar_set): invalid instance variable access for
- built-in object raises TypeError.
-
-Fri May 16 17:32:21 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970516
-
- * dir.c (push_globs): was freeing non heap pointer.
-
- * gc.c: remove some duplicated prototypes.
-
- * ext/kconv/kconv.c: fix prototypes.
-
-Fri May 9 11:38:59 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970509
-
- * gc.c (obj_free): avoid free(NULL).
-
- * eval.c (rb_check_safe_str): argument missing for TypeError().
-
-Thu May 8 01:14:28 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (file_s_dirname): need to return "." for path without
- slashes.
-
-Wed May 7 19:18:48 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * process.c (f_fork): child processe does not inherit parent's
- itimer setting on linux. call setitimer() again in the child
- process.
-
-Sat May 3 02:49:43 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/curses/curses.c: modified for portability and add to the
- standard distribution.
-
-Wed Apr 30 00:34:00 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (file_s_size): returns 0 for empty files (not FALSE).
-
-Fri Apr 25 02:17:50 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970425
-
- * eval.c (f_load): free unused name-table.
-
- * eval.c (f_load): copy local variable name-table.
-
- * gc.c (obj_free): avoid free(NULL).
-
- * eval.c (rb_eval): forgot to make link from the scope object to
- NODE_SCOPE. It may crash the interpreter.
-
-Thu Apr 24 00:35:09 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * random.c (f_srand): save old seed anyway. srand() returns no
- value on some systems.
-
- * gc.c (obj_free): avoid double free of the local variable name
- table.
-
- * parse.y (top_local_setup): modify realloc to handle offset.
-
-Tue Apr 22 12:58:26 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970422
-
-Thu Apr 17 00:40:51 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * configure.in (rb_cv_bsdpgrp): proper check for BSD
- setpgrp/setpgrp.
-
-Wed Apr 16 16:14:02 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (proc_call): proc called in other thread must be orphan.
-
-Tue Apr 15 10:46:31 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970415
-
- * gc.c (obj_free): NODE_SCOPE marked from SCOPE object.
-
- * gc.c (gc_mark): some nodes marked wrong.
-
- * process.c (proc_getpgrp): wrong argument
-
-Fri Apr 14 18:32:42 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970414
-
-Fri Apr 12 01:20:12 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.h: String pointer changed to unsigned char.
-
-Fri Apr 11 10:27:29 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970411
-
- * Makefile.in: create libruby.a before linking ruby.
-
- * string.c (str_strip_bang): >0x80 characters for isspace().
-
- * eval.c (proc_call): set safe-level temporally
-
- * eval.c (proc_s_new): save safe-level in the proc context.
-
- * eval.c (rb_eval): no class/module extention in safe mode.
-
-Thu Apr 10 02:10:41 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * gc.c (gc_mark): remove some pointer checks for speeding up.
-
- * ruby.c (ruby_options): set $0 temporally for -r option.
-
- * eval.c: built-in security feature.
-
- * gc.c (gc_sweep): do not free nodes during compile.
-
- * parse.y (yycompile): set flag when compiling.
-
-Wed Apr 9 10:19:02 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.c: forgot to include <ctype.h> for isspace().
-
- * file.c: provide S_ISREG for some platforms.
-
- * io.c (Init_IO): added some $< operations.
-
- * lib/ping.rb: check host upness using TCP echo.
-
-Tue Apr 8 00:10:15 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * io.c (arg_read): bug with 0 length input.
-
-Mon Apr 7 11:36:16 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/fcntl/fcntl.c: module for fcntl constants.
-
- * eval.c (rb_alias): bug when original was an alias.
-
- * parse.y (primary): syntax to access singleton class.
-
- * eval.c (mod_public_method): method's to specify visibitily of
- the class methods. make_method_{public,private} removed.
-
-Fri Apr 4 21:43:57 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970404
-
- * gc.c (obj_free): finalizer added for experiment.
-
-Thu Apr 3 02:12:31 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_schedule): make Fatal rise on main_thread on
- deadlocks.
-
- * eval.c (thread_join): raise ThreadError instead of Fatal, in
- case of deadlock.
-
- * regex.c (re_compile_fastmap): uninitialized local variable.
-
- * parse.y (parse_regx): new option //[nes] to specify character
- code for regexp literals. Last specified code option is valid.
-
- * re.c (reg_s_new): addtional 3rd argument to specify compiled
- regexp's character code.
-
- * re.c (reg_new_1): regexp character code can be specified for
- each regexp object.
-
-Wed Apr 2 14:51:06 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_create): handle uncaught throw.
-
- * eval.c (thread_create): halt on some deadlock conditions.
-
- * regex.c (is_in_list): wrong result for non-mbc higher-byte
- characters.
-
- * regex.c (re_match): wrong skip for multi-byte characters.
-
- * regex.c (re_compile_fastmap): wrong fastmap in non-mbc mode.
-
- * hash.c (Init_Hash): hash compatible features added to ENV.
-
-Tue Apr 1 15:24:06 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (obj_extend): remove Object#extend as an iterator which
- is in experimental state, since it unveils internal singleton
- classes.
-
-Mon Mar 31 14:29:39 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970331
-
-Sun Mar 30 19:40:57 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * parse.y (terms): avoided win32 gcc's optimization bug.
-
-Sat Mar 29 11:21:58 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * struct.c (make_struct): St[val,..] creates new structure.
-
-Fri Mar 28 11:24:51 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (obj_make_private): new method make_method_{public,private}
- to change visibility of singleton methods.
-
- * regex.c (re_compile_pattern): enables numeric literal >= 0x80 in
- the character class.
-
- * regex.c (re_compile_pattern): enabled numeric literal >= 0x80,
- in multibyte mode.
-
- * regex.c (re_compile_fastmap): modified exantn and charset(_not)
- to set fastmap for higher bytes properly.
-
- * regex.c (is_in_list): now matches numeric literals.
-
-Thu Mar 27 13:34:20 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * pack.c (pack_unpack): extra null byte after unpacked string.
-
-Wed Mar 26 15:20:34 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * regex.c (re_compile_pattern): register numbers must be fit in a
- byte (0 <= regnum <= 0xff).
-
- * regex.c (re_compile_fastmap): forgot to set mbchar map for
- charset_not if RE_MBCTYPE is on.
-
- * regex.c (re_compile_pattern): set list bits for multi-byte
- characters for \W, \S, \D in range expression.
-
- * object.c (obj_is_kind_of): defined that nil itself is kind of
- nil. TRUE is kind of TRUE, FALSE is kind of FALSE likewise.
- This change makes `obj.kind_of?(eval(obj.type))' always true.
-
-Tue Mar 25 14:08:43 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * lib/English.rb: provides nicer English alias for the variables.
-
- * parse.y (expr): alias $var1 $var2 makes alias of the global
- variable.
-
-Mon Mar 24 18:23:20 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970324
-
-Thu Mar 20 22:04:59 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (mod_modfunc): forget to clear method cache.
-
-Wed Mar 19 17:06:55 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (program): set methods' default private/public status
- correctly under eval().
-
- * eval.c (eval): set the_class correctly while evaluating string.
-
-Tue Mar 18 12:23:53 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (eval): yield can be called from eval().
-
- * version 1.0-970318
-
- * parse.y (program): regexp in condition expression should do
- matching operation with $_.
-
- * re.c (reg_regsub): wrong substitution.
-
-Fri Mar 14 14:36:28 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * hash.c (hash_invert): returns value to key mapping of the
- associative array.
-
- * ext/socket/extconf.rb: set environment variable SOCKS_SERVER to
- compile with libsocks.a.
-
- * ext/socket/socket.c (socks_s_open): SOCKSsocket class to access
- internet via SOCKS library.
-
- * sprintf.c (f_sprintf): unsigned formats display leading double
- dots for imaginary sequence of signed bit to the left.
-
- * sprintf.c (f_sprintf): correct width and precision formatting
- for big integers.
-
- * parse.y (yylex): enables negative hex/octal numbers and `_' in
- non-decimal numbers.
-
- * sprintf.c (f_sprintf): %u added for unsigned decimal format.
-
-Thu Mar 13 10:24:27 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sprintf.c (f_sprintf): wrong output for bignums.
-
- * array.c (ary_reverse_each): iterates in reverse order.
-
- * pack.c (pack_unpack): L unpacked signed long.
-
- * io.c (f_backquote): now returns an empty string for no output.
-
-Wed Mar 12 10:20:30 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/socks/socks.c: socket module with socks library.
-
-Mon Mar 10 20:44:22 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * re.c (reg_regsub): \& for substitution. \`, \', and \+ are
- avaiable also.
-
-Thu Mar 6 01:47:03 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970306
-
- * sample/rubydb.el (gud): ruby debugger emacs interface
-
- * lib/debug.rb: ruby debugger
-
- * parse.y (exprs): more accurate line number display.
-
-Wed Mar 5 21:31:46 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970305
-
-Tue Mar 4 12:28:32 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.c (proc_options): search through RUBYPATH and PATH for
- option -S.
-
-Mon Mar 3 22:44:55 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_status): returns nil for exception terminated
- threads.
-
- * eval.c (thread_value): re-raise exceptions.
-
-Sat Mar 1 00:59:47 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_eval): restore $! value after rescue clause, to
- re-raise exceptions correctly.
-
-Fri Feb 28 16:43:38 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970228
-
-Thu Feb 27 11:23:41 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_yield_0): redo raises exception
-
- * eval.c (thread_schedule): bug in interrupt handling by rescue.
-
-Wed Feb 26 00:55:36 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (eval): forgot to restore dynamic local variable
- bindings.
-
-Tue Feb 25 11:22:08 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/aix_ld.rb: AIX dynamic load support (not tested).
-
- * eval.c (rb_eval): wrong return value for defined? super.
-
- * error.c (exception): more error check.
-
- * re.c (reg_regsub): wrong substitution when sub expanded to null
- string.
-
-Fri Feb 21 13:01:47 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970221
-
- * eval.c (f_require): volatile added. register variable was
- recycled, so that GC did not mark that variable.
-
- * object.c (Init_Object): forget to mark main object (was mostly
- ok, but made trouble with early GC.)
-
-Thu Feb 20 11:50:50 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970220
-
-Thu Feb 20 11:25:50 1997 Yasuo OHBA <jammy@shljapan.co.jp>
-
- * lib/date.rb: update
-
-Thu Feb 20 08:25:57 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (yylex): forgot tokfix() before rb_intern().
-
- * lib/tk.rb (TkVariable): give up using trace_var.
-
-Wed Feb 19 00:24:35 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970219
-
- * pack.c (pack_pack): packed by null for A specifier. must be
- space filled.
-
- * pack.c (pack_unpack): bug in skipping spaces
-
- * gc.c (xmalloc): garbage collect for every 4 Meg. allocation.
-
- * string.c (str_split_method): limit worked wrong way.
-
- * io.c (io_gets_method): misunderstand 0xff in binary files when
- $/ == nil.
-
- * re.c (reg_regsub): re-implement.
-
- * ext/socket/socket.c (thread_connect): remove O_NONBLOCK, which
- is not defined on some platform like NeXT.
-
-Mon Feb 17 13:08:30 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970217
-
- * object.c (mod_eqq): === extended for subclass check (to use case
- as typecase).
-
-Sat Feb 15 02:07:22 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * regex.c (re_compile_pattern): wrong match backref at end of pattern.
-
- * io.c (arg_read): now works beyond end of file.
-
-Thu Feb 13 16:21:24 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (expr): return/yield now accept normal argument format.
-
- * parse.y (yylex): a star in `yield *x' must not be multiplication
- operator.
-
-Wed Feb 12 15:06:44 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * time.c (time_plus): bug in simple addition.
-
- * eval.c (thread_raise): raise exceptions from outside.
-
- * eval.c (Init_Thread): Thread#alive? -- alias for Thread#status.
-
-Mon Feb 10 00:38:55 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.h (Data_Make_Struct): rename macros.
-
-Sun Feb 8 11:48:13 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * io.c (f_syscall): argument offset was wrong.
-
-Fri Feb 7 18:01:17 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970207
-
- * eval.c: add volatiles to avoid variable crobbering by longjmp().
-
- * eval.c (f_raise): 1st argument can be the GlobalExit object now.
-
- * array.c (ary_unshift): no longer accept more than 2 args.
-
- * eval.c (f_raise): bug if 2nd argument is the exception.
-
-Tue Feb 4 00:37:29 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970204
-
- * eval.c (eval): check compile errors by nerrs.
-
- * eval.c (rb_eval): check syntax error by nerrs, not by the return
- value, which may be NULL.
-
- * eval.c (compile): Do not clear errinfo.
-
-Mon Feb 3 10:13:06 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (obj_extend): move real inclusion to Module#extend_object
- to allow redfinition.
-
- * object.c (Init_Object): Kernel class is now Module. Object class
- became the true root class.
-
- * object.c (obj_inspect): remove useless buffer.
-
- * hash.c (any_cmp): disable interrupts and context switching.
-
- * st.c: remove ALLOW_INTS to disable interrupt during operations.
-
-Fri Jan 31 22:10:08 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * hash.c (hash_rehash): re-register all key-value.
-
-Thu Jan 30 02:14:49 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * io.c (io_reopen): re-implement according to clone() way.
-
- * io.c (io_clone): copy IO object.
-
- * struct.c (struct_eql): compare elements by eql?.
-
- * io.c (io_mode_flags): detect "rb", "wb" etc.
-
- * io.h (FMODE_BINMODE): added.
-
- * ext/socket/socket.c (Init_socket): undef BasicSocket.new
-
- * file.c (Init_File): File.new(path[,mode])
-
- * io.c (Init_IO): IO.new(fd[,mode])
-
- * eval.c (rb_method_boundp): forgot to enable priv argument.
-
- * object.c (Init_Object): remove `=~' from Kernel class.
-
- * ext/socket/socket.c (open_inet): initialize sockaddr before
- calling bind(2).
-
- * sample/ruby-mode.el (ruby-calculate-indent): skip comment lines
-
-Wed Jan 29 18:43:22 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (Init_Thread): DEFER_INTS during initializing threads.
-
- * hash.c (Init_Hash): Hash#eql? checks for object identity.
-
- * eval.c (thread_set_critical): wrong value assigned.
-
-Mon Jan 27 16:10:51 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * io.c (io_print): remove print_on().
-
- * eval.c (f_missing): proper error message for undefined method
- without argument
-
-Sat Jan 25 23:32:32 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_sub_s): false alert - sub() does not modify string.
-
- * array.c (ary_times): negative multiplication detected
-
- * string.c (str_times): negative multiplication detected
-
-Fri Jan 24 10:51:39 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * time.c (time_arg): month -> 0 == "jan" == "1" == "01", little bit
- confusing but wanted to conform japanese style.
-
- * version 1.0-970124
-
-Fri Jan 24 09:52:49 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * util.c (_fixpath): supports SJIS filenames on DJGPP.
-
-Thu Jan 23 16:52:06 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * README.EXT: update. partially translated into English.
-
- * ext/extmk.rb.in: inherit $LDFLAGS to the final link.
-
- * ext/socket/socket.c (Init_socket): add various constants.
-
-Mon Jan 23 11:40:59 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * eval.c (Init_Thread): allocate main_thread first to avoid crash.
-
-Thu Jan 23 02:09:26 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * gc.c (ObjectSpace): API modified. each_object method will do all
- the iteration.
-
- * eval.c (proc_call): wrong return from nested lambda.
-
- * ext/GD/GD.c: debugged.
-
-Wed Jan 22 16:12:25 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970122
-
- * gc.c (gc_mark): forgot to mark match->str.
-
- * ext/GD/GD.c: GD interface module.
-
- * eval.c (PUSH_BLOCK): wrong value pushed as the block level.
-
-Mon Jan 20 14:01:31 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_run): no context switch in the critical section.
-
-Mon Jan 20 09:40:59 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * utils.c: supports 8+3 filenames
-
-Sat Jan 18 01:23:03 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970118
-
- * regex.c (PATFETCH): need cast to unsigned char.
-
- * io.c (io_ctl): bug in case when arg is not a string.
-
- * lib/tk.rb: forgot that Kernel#type returns the class name now.
-
- * regex.c (re_search): "abc\n" =~ "^$" should not match.
-
-Fri Jan 17 12:31:37 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970117
-
- * ruby.c (ruby_options): constant PLATFORM, which is in the {cpu}-{os}
- form, defined.
-
- * configure.in: platform infomation embedded in the interpreter.
-
- * regex.c (re_search): /^$/ did not match to "" by wrong exit condition.
-
- * lib/thread.rb: re-write Mutex/Queue based on Thread.critical.
-
- * eval.c (thread_set_critical): remove Thread.exclusive, add
- Thread.critical = TRUE/FALSE instead.
-
- * re.c (reg_search): re-compile pattern if needed
-
- * regex.c (PATFETCH): do translate at compile time
-
-Thu Jan 16 00:49:10 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * gc.c (gc_mark_frame): forgot to mark frame->cbase.
-
- * regex.c (re_compile_pattern): /a$|b)/ causes error.
-
- * regex.c (re_compile_pattern): /(^|b)/ causes error.
-
- * version 1.0-970116
-
- * re.c (Init_Regexp): set RE_CONTEXTUAL_INVALID_OPS flag.
-
-Tue Jan 14 02:09:06 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (proc_call): Proc#callをイテレータとして呼んだ時に対応
-
- * configure.in: nextstep対応?
-
- * eval.c (rb_eval): a[b]=cで無駄な配列を割り当てない
-
- * eval.c (f_send): イテレータとして呼ばれたらイテレータとしてメソッ
- ドを呼ぶ.
-
- * string.c (str_new4): match共有用の生成関数
-
- * re.c (reg_search): matchの実体(文字列)をマッチを行った文字列と
- copy-on-writeで共有
-
- * string.c (str_hash): toupperをかける条件が違っていた
-
- * array.c (sort_2): FixnumとStringを特別扱いして高速化
-
-Mon Jan 13 11:03:53 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_create): threadが生成されるまで割込みを設定しない
-
- * eval.c (Init_Thread): 割込みタイミングを100msecに
-
-Sat Jan 11 00:17:05 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * regex.c (re_search): マッチに失敗する場合があった(本当に直ったか?)
-
- * io.c (io_ioctl,io_fcntl): 第2引数を省略可能に
-
- * io.c (io_ioctl,io_fcntl): 戻り値がIOだった.整数(システムコール
- の戻り値)を返すようにした.
-
- * io.c (io_ctl): 引数が整数の時に対応
-
- * io.c (io_fcntl): file.cから移動
-
-Fri Jan 10 17:01:47 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-970110
-
- * ext/socket/socket.c (thread_connect): open(connect(2))で他の
- threadをブロックしないように
-
- * eval.c (thread_create): exitでないときにexitだと思い込む
-
-Mon Jan 6 17:42:22 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_sub_s): 文字列長より長いoffsetの検出
-
- * regex.c (re_search): 空にマッチするパターン後の$で失敗
-
-Thu Jan 2 16:36:23 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (file_reopen): Fileのreopen(pathまたはIOで指定).
-
- * io.c (io_reopen): IOのreopen(IOで指定) -- change classつき
-
-Wed Jan 1 11:09:01 1997 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * io.c (f_select): timeoutでnilを返す
-
-Fri Dec 27 13:06:44 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (file_s_open): サブクラスではそのクラスのインスタンスを返
- すように.
-
-Fri Dec 27 08:58:27 1996 ono@isl.nara.sharp.co.jp
-
- * numeric.c (flo_to_s): index()を使わない.strstr()に.
-
-Thu Dec 26 01:34:17 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * lib/tk.rb: placeが使えるように
-
- * pack.c (endian): マクロDYNAMIC_ENDIANを指定すると実行時にendian
- を判定するように.
-
- * eval.c (thread_alloc): 初期化忘れのメンバがあった.
-
-Wed Dec 25 00:33:19 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 1.0-961225
-
- * io.c (Init_IO): newを無効化
-
- * lib/tkthcore.rb: tk_call "global $foo; set foo 5"などもできるように
-
- * eval.c (thread_restore_context): $~, $_でスタックを壊していた
-
- * process.c (rb_waitpid): threadに一応対応
-
-Tue Dec 24 15:20:58 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.4-961224
-
- * configure.in: charがunsignedかどうかもチェック
-
- * regex.c (SIGN_EXTEND_CHAR): __CHAR_UNSIGNED__にも対応
-
- * pack.c (pack_unpack): 明示的にsigned charを指定.
-
-Mon Dec 23 14:41:23 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.c (load_file): 標準入力からのスクリプトで一時ファイルを使わ
- ないように
-
- * object.c (f_integer): `0x', `0'などでbaseを解釈するように.
-
-Fri Dec 20 01:44:39 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * Makefile.in (flock.o): flockに対応
-
-Thu Dec 19 20:13:32 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.4-961219
-
-Wed Dec 18 00:06:48 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * glob.c (glob_filename): strrchrがマクロの場合に対応
-
- * configure.in: <sys/select.h>をチェック
-
- * ext/kconv/kconv.c: 1.62ベースに
-
- * ext/kconv/kconv.c: Kconvモジュール
-
- * string.c (str_substr): lenが元の文字列より長い時に対応
-
- * parse.y (iterator): 「$bar do .. end」などは許さないように
-
- * parse.y (iterator): FID(foo!,foo?)をdo形式のイテレータにできる.
-
- * missing/flock.c (flock): lockf()を使って代替
-
- * file.c (file_flock): flockを実装
-
-Tue Dec 17 12:13:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.4-961217
-
-Fri Dec 13 02:05:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * configure.in: RUBYLIBのカレントを後回し(@mix/awk offline)
-
- * dln.c: AIXに対応した?(@mix/awk offline)
-
- * eval.c (thread_schedule): critical sectionでも明示的なコンテキス
- トスイッチは起きないとまずい
-
- * re.c (reg_search): matchに失敗した時に$~をnilに.
-
- * re.c (reg_search): 毎回matchを生成するように
-
-Thu Dec 12 17:03:30 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * numeric.c (flo_to_s): 2.0.to_s -> 2.0に
-
- * eval.c (thread_save_context): $_, $~をthread毎に保存
-
- * eval.c (thread_kill): main threadではexit(0)
-
- * string.c (str_split_method): 間違った結果を返していた
-
-Thu Dec 12 15:32:48 1996 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * dir.c: CYGWIN32対応
-
- * ext/socket/socket.c: CYGWIN32対応
-
- * io.c: CYGWIN32対応
-
-Thu Dec 12 14:43:51 1996 Jun Kuroda <j_kuro@pluto.ai.kutech.ac.jp>
-
- * lib/tk.rb: wish4.2も探索候補に含める
-
- * config.guess: JCC対応
-
-Thu Dec 12 00:41:17 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.4-961212
-
- * parse.y (parse_string): """..."""はやはり無くすことにした
-
- * parse.y (parse_regx): %r|...|でterminatorを \ でエスケープできる
- ように
-
- * signal.c (posix_signal): sigactionを使うsignal
-
- * configure.in: posix signal/bsd signalの検出
-
-Wed Dec 11 17:47:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_schedule): critical sectionではコンテキストスイッ
- チが起きないように
-
- * lib/thread.rb: SharedMutexクラス
-
- * lib/jcode.rb: String#scanを使うように
-
-Tue Dec 10 12:21:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.3-961210
-
- * string.c (str_split_method): 正規表現に()を含む時にバグ
-
- * lib/jcode.rb: ちょっとましになった
-
- * string.c (tr_setup_table): 置換文字が短すぎる(2文字)のときのバグ
-
-Mon Dec 9 11:38:04 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_scan): 文字列のマッチを行う.イテレータとしても動
- 作する
-
- * regex.c (re_copy_registers): allocatedが初期化されていなかった
-
- * re.c (match_to_s): $~の文字列化
-
- * re.c (match_to_a): $~を配列化できるように
-
- * re.c (match_getter): レジスタが初期化されていなかった
-
-Thu Dec 5 11:06:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_split_method): マッチしなかった括弧は空文字列を
- pushするべきではない
-
- * string.c (str_succ): アルファベットを含まない文字に対応
-
-Wed Dec 4 10:48:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.3-961204
-
- * io.c (io_binmode): DJGPPでのbinmode対応
-
- * sprintf.c (f_sprintf): intの範囲の数値は直接sprintfで変換する
-
- * sprintf.c (f_sprintf): "%02s"に頼らない
-
- * re.c (reg_search): indexでSEGV
-
-Tue Dec 3 10:09:36 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.3-961203
-
- * ext/extmk.rb.in (install): INSTALL_DATAからINSTALLに変更
-
- * dln.c: hpux対応
-
- * string.c (str_aset_method): 負の値を含む範囲でも例外を起こさない
-
- * array.c (ary_replace): 負の値を含む範囲でも例外を起こさない
-
- * array.c (beg_len): beg==endの時,長さ0に
-
-Mon Dec 2 14:07:12 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * configure.in: HP shl対応
-
- * string.c (str_upto): beg > endの時無限ループに落ちるのを止めた
-
- * range.c (range_each): String#uptoが再定義された場合に対応
-
- * string.c (str_split_method): "ABC".split(/(B)/)が誤動作
-
-Sat Nov 30 01:43:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_eval): undefでSEGV
-
-Fri Nov 29 12:17:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/ruby-mode.el (ruby-parse-region): %Q#..#などに対応.しか
- し,区切り文字が演算子で行末にある場合には対応できなかった.
-
- * re.c (reg_raise): 例外でもスラッシュをエスケープ
-
- * re.c (reg_inspect): スラッシュをエスケープ
-
- * parse.y (parse_string): `%[QqXxRr](.)..\1'なる文字列形式(テスト
- 採用)
-
- * parse.y (parse_qstring): '''...'''の形式
-
- * ext/dbm/dbm.c (Init_dbm): 述語key?,value?の追加
-
- * ext/dbm/dbm.c (Init_dbm): includes->include?
-
- * hash.c (Init_Hash): 述語key?,value?,include?の追加
-
- * eval.c (rb_eval): unlessでelse節が実行されない(うーん)
-
- * string.c (str_sub_iter_s): イテレータブロック内でマッチが行われ
- ると位置がずれる(時に無限ループに落ちる)
-
- * string.c (str_resize): lenが0の時sizeの調整が行われなかった
-
-Thu Nov 28 00:59:54 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.3-961128
-
- * parse.y (parse_string): 3-quote styleの文字列(例:"""abc"d"e""")
-
- * configure.in (EXTSTATIC): extを静的にリンクする時にはrubyはdllを
- 使うように
-
- * io.c (Init_IO): getsの引数が間違っていた
-
- * string.c (str_each_line): RSを明示的に指定できるように
-
-Wed Nov 27 12:37:46 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.3-961127
-
- * eval.c (rb_eval): iver defined? でselfを指定するのを忘れた
-
- * io.c: gets等でRSを明示的に指定できるように
-
- * ext/extmk.rb.in (install): static linkに失敗
-
-Tue Nov 26 10:33:04 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.3-961126
-
- * string.c (str_sub_s): 置換後の文字列長さが間違っていた
-
-Mon Nov 25 09:11:22 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * numeric.c (fix_rshift): 32以上の右シフトで0を返すように(Cの
- rshiftは(x>>(y%32))を返していた).
-
- * string.c (str_gsub): 置換が行われない場合があった
-
- * string.c (str_resize): 本当に必要な時だけrealloc
-
-Thu Nov 21 04:13:21 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * configure.in (EXTSTATIC): --with-static-linked-extで全てのモジュー
- ルを静的リンクするように
-
- * pack.c (pack_unpack): 行末の改行がない時にもチェックサムをスキッ
- プするように
-
-Wed Nov 20 96 21:42:51 1996 Yasuo OHBA <jammy@shljapan.co.jp>xc
-
- * configure.in: freebsd対応
-
-Wed Nov 20 10:24:24 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/extmk.rb.in (install): 通常リンク用のLDFLAGSとダイナミックリ
- ンク用のDLDFALGSを分離
-
- * ext/extmk.rb.in (install): コンパイルの成功したものを静的リンク
- のリストに追加する
-
- * eval.c (f_missing): オブジェクトの文字列表現が長すぎる時バッファ
- を書き潰していた
-
- * process.c (proc_exec_v): forkした後例外を発生させてはいけない
-
-Tue Nov 19 13:28:15 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.3-961119
-
- * eval.c (mod_method_defined): Module#method_defined? の追加
-
- * parse.y (call_args): 引数が唯一のコマンドコールである時のバグ(戻
- り値が展開されてしまう)
-
-Mon Nov 18 13:28:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_sub): 失敗した時にnilを返していた
-
- * string.c (str_split_method): 検索開始位置が移動してなかった
-
- * ext/socket/socket.c (sock_s_getservbyaname): まだ間違っていた
-
- * version 0.99.3-961118
-
- * string.c (str_sub_s): 元の文字列を置換するのを止めた
-
- * pack.c (encodes): 領域外をアクセスしていた
-
-Fri Nov 15 17:10:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * bignum.c (big_divmod): Bignumが引数の場合の対応忘れ
-
- * sample/ruby-mode.el (ruby-expr-beg): word?形式への対応が不完全
-
-Wed Nov 13 15:42:40 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_tr_s_bang): tr_sでtrが行われていなかった
-
- * eval.c (rb_eval): autoloadクラスのチェック
-
- * string.c (f_sub): subがsub!と同じ動作になっていた
-
- * eval.c (thread_sleep): stopとsleepの分離
-
-Mon Nov 11 13:53:19 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.3-961111
-
- * numeric.c (fix_step): to, stepが整数以外の場合に対応
-
- * eval.c (rb_call): dynamic varがdynamic scopingになっていた(これ
- はまずい)
-
- * string.c (str_chop_bang): 長さ0の文字列のchopで,領域外のアクセ
- スが発生していた.
-
- * parse.y (yyerror): 割り当てた領域外をアクセスしていた
-
-Fri Nov 8 11:54:46 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_yield): scopeをheapにコピー
-
-Thu Nov 7 09:56:53 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * numeric.c (num_coerce): とりあえず両辺をFloatに変換することに
-
-Wed Nov 6 10:45:13 1996 Yasuo OHBA <jammy@shljapan.co.jp>
-
- * lib/parsearg.rb: 第2引数を変更.
-
-Tue Nov 5 14:21:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.3-961105
-
-Sat Nov 2 01:11:40 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * bignum.c (big_pow): typo (dy -> dx)
-
- * bignum.c (big_divmod): 知らない型はfloatに変換してみる
-
- * numeric.c (fix_lshift): 境界条件のバグ(負になっていた)
-
- * bignum.c (big_pow): 無駄なfloatへの変換をなくした
-
- * math.c (math_atan2): typo(x -> y)
-
-Fri Nov 1 15:30:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/socket/socket.c (sock_gethostname): gethostnameがない時には
- unameを使ってホスト名を得る
-
- * ext/etc/etc.c (etc_getlogin): getloginがNULLを返しても環境変数を
- 調べるように
-
- * object.c (krn_clone): オブジェクトのフラグもコピー
-
- * hash.c (rb_cmp): ハッシュの比較を`=='でなく`eql?'に変更
-
- * math.c (Need_Float): Float()を使って変換する
-
- * compar.c (cmp_gt): 以前の右辺を返す仕様の名残が残っていた
-
-Thu Oct 31 12:55:51 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * ruby.c (proc_options): -S does not recognize PATH.
- * version 0.99.3-961031
+Thu Jan 15 02:03:12 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
- * numeric.c (Init_Numeric): typo
+ * eval.c (rb_clear_cache_by_id): clear only affected cache
+ entries.
- * eval.c (error_print): 長すぎるtrace backを途中省略する
+Wed Jan 14 02:14:48 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
- * regex.c (re_compile_pattern): 全角のrangeに対応
+ * ext/socket/socket.c: new UDP/IP socket classes.
-Wed Oct 30 03:03:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+Tue Jan 13 10:00:18 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
- * version 0.99.3-961030
+ * string.c (str_cmp): ignorecase($=) works wrong.
- * io.c (f_ungetc): 関数を追加
+Fri Jan 9 13:19:55 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c (dyna_var_asgn): return値忘れ
+ * eval.c (f_missing): class name omitted from the error message.
-Tue Oct 29 10:05:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * error.c (exc_inspect): description changed.
- * string.c (f_split): 関数splitを追加
+ * string.c (Init_String): GlobalExit's superclass did not filled,
+ since GlobalExit created earlier than String.
- * eval.c (rb_call): ネストした外側のクラス/モジュールの定数を参照
- できるように
+Thu Jan 8 12:10:09 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
-Mon Oct 28 09:51:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * parse.y (aryset): expr in the brackets can be null.
- * string.c (str_sub): offsetが文字の末尾にある時のチェック
+Wed Jan 7 21:13:56 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
- * regex.c (re_match): 割り当てるレジスタの数が1多かった
+ * io.c (io_reopen): keep stderr unclosed.
- * io.c (io_gets): $/ = ""の動作をperlに合わせる(awkとはちょっと違
- うらしい)
+ * io.c (io_errset): keep stderr unclosed.
- * io.c (io_gets): $/ = nilの時少し高速化
+Tue Jan 6 00:27:43 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
- * string.c (str_split_method): 括弧がnullにマッチした時にも無視し
- ないように
+ * parse.y: syntax modified for `while expr do .. end' etc.
- * string.c (str_split_method): 括弧にマッチした分はlimitの数に含め
- ないように.
+ * process.c (f_exec,f_system): can supply arbitrary name for the
+ new process.
- * numeric.c (num_coerce_bin): coerceの定義を変更,2要素の配列
- [x,y]を返すように
+Mon Jan 5 16:59:13 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * sample/ruby-mode.el (ruby-calculate-indent): "do |aa|"の対応を改
- 善した.
+ * file.c (file_s_basename): removes any extention by ".*".
-Sat Oct 26 01:43:51 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+Sun Jan 4 19:36:22 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * ext/marshal/marshal.c (w_object): ビルトインクラスのサブクラスを
- 正しく復旧できるように
+ * parse.y (yylex): needed to update lex_p (reading point).
- * ext/marshal/marshal.c (w_object): ユーザ定義dumpの優先
+Sat Jan 3 19:14:14 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * numeric.c (flo_coerce): Float()を使って定義
+ * class.c,object.c: duplicate defines mKernel and cFinxnum.
- * numeric.c (Init_Numeric): Numericのnewのundefはまずい
+Fri Jan 2 20:38:59 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
- * ext/marshal/marshal.c (w_symbol): シンボルの内容(文字列)は一度し
- かファイルに書き出さない.
+ * ext/curses/curses.c (NUM2CHAR): uses the first character for
+ string arguments.
- * sample/ruby-mode.el (ruby-parse-region): if/while修飾子に対応し
- なくなっていた
+ * array.c (ary_fill): did not extend array for ranges.
- * bignum.c (Init_Bignum): Bignum.newを除く
+ * array.c (beg_len): did not return end pos bigger than size.
- * eval.c (rb_eval): 引数評価後にファイル名と行番号を再設定
+Fri Jan 2 02:09:16 1998 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * numeric.c (flo_div): typo
+ * dir.c (dir_s_chdir): bug in nil check.
- * sample/ruby-mode.el (ruby-parse-region): def /, def `に対応
+ * array.c (ary_fill): bug in nil check.
-Fri Oct 25 09:26:29 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+Tue Dec 30 11:46:23 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * sample/ruby-mode.el (ruby-calculate-indent): "do |aa|"に対応
+ * hash.c (env_path_tainted): checks directories in PATH
+ environment variable are not world writable.
- * array.c (ary_aset): indexがfixnumの場合ちょっと高速化
+ * ruby.c (load_file): invoke specified interpreter if the #! line
+ does not contain the word `ruby'.
- * eval.c (thread_fd_writable): 書き込み前のselectチェック
+Fri Dec 26 03:26:41 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * array.c (ary_assoc): 無限ループに落ちた
+ * string.c (uscore_get): type information included in the error
+ message.
- * eval.c (thread_wait_for): selectがエラー終了した時,linux以外で
- の動作が正しくなかった.
+ * variable.c (f_untrace_var): does not free trace-data within
+ trace procedure.
-Thu Oct 24 08:26:48 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+Thu Dec 25 02:50:29 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c (backtrace): `$@'を文字列から配列に変更した.
+ * version 1.1b3 released.
- * eval.c (eval): eval中の例外発生位置を保存する
+ * ruby.h: inlining some functions on gcc 2.x
- * bignum.c (bigsub): オペランドの大小比較の失敗
+Tue Dec 23 02:47:33 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * re.c (reg_search): 直接参照がない時にも`$~'がセットされるように
+ * eval.c (rb_eval): public/private information kept in the current
+ scope, to remove undesired state from the class/module.
-Wed Oct 23 10:40:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * time.c (time_strftime): remove hidden limit of 100 bytes of
+ result string, using malloc'ed buffer.
- * version 0.99.2-961023
+ * hash.c (hash_update): merges the contents of another hash,
+ overriding existing keys.
- * ext/marshal/marshal.c (r_bytes): mallocをやめ,allocaを使う
+ * regex.c (must_instr): totally re-written.
- * sample/ruby-mode.el (ruby-calculate-indent): 括弧の対応を変更.
- ()内ではインデントをレベルを合わせるように
+ * io.c (read_all): try to allocate proper sized buffer using
+ fstat(2) for speedup.
-Tue Oct 22 12:59:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+Sat Dec 20 00:27:28 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * hash.c (hash_s_new): sizeを指定できるように
+ * regex.c (must_instr): need to skip 2 bytes for mbchars.
- * ext/marshal/marshal.c (w_object): dumpする深さ制限を指定できるよ
- うに
+Fri Dec 19 01:18:29 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * array.c (ary_s_new): sizeを指定した時の初期化忘れ
+ * version 1.1b2 released.
- * object.c (f_float): big2dblの宣言忘れ.
+ * eval.c (check_errat): check and convert (if necessary) traceback
+ information before assigning to the variable $@.
- * bignum.c (bigsub): 大きさの近いBignum同士の演算で結果が負になる
- 場合に間違いがあった.
+ * eval.c (f_raise): optional third argument to specify traceback
+ information.
- * array.c (ary_aset): 置換先と置換元が同じ長さの時内容を
- shift(memmove)しないように.
+ * io.c (f_open): prevent infinite recursive call.
- * ext/marshal/marshal.c (marshal_dump): ファイルフォーマットにバー
- ジョンを埋め込むように
+Thu Dec 18 19:33:47 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * ext/marshal/marshal.c (tmpnam): linux-aout-dln用に定義
+ * string.c (str_rindex): now accepts regexp as index.
-Mon Oct 21 08:40:20 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+Thu Dec 18 18:42:50 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * ext/socket/socket.c (sock_s_gethostbyname): hostent構造体の情報
- を返す
- (sock_s_gethostbyaddr): IPアドレスからhostent構造体を得る
- (sock_s_getservbyaname): getservbyname(3)
+ * ext/socket/extconf.rb: modified to detect win32 socket lib.
-Fri Oct 18 10:37:36 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+Thu Dec 18 00:25:03 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * sample/ruby-mode.el (ruby-indent-to): 移動先カラムが負になるバグ
+ * re.c (reg_equal): checks for source and casefold and kcode matching.
- * eval.c (compile): evalで元ソースの行番号でエラーを表示する
+ * marshal.c: became built-in module.
-Thu Oct 17 09:52:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * ext/marshal/marshal.c (r_object): displays struct name for
+ non-compatible struct.
- * eval.c (eval): evalで文法エラーがあった時にSEGV
+ * string.c (str_index_method): now searches character (fixnum) in
+ the string.
- * lib/safe.rb: Restricted.evalの中だけ制限を加える.
+ * string.c (str_include): redefine `include?'.
- * eval.c (error_print): バックトレースの出力.callerで例外発生位置
- を調整した時に問題が出る(そんなことをしなければ良いのだが…)
+ * regex.c (re_match): start_nowidth saves current stack position
+ to stop_nowidth.
- * eval.c (make_backtrace): バックトレースの生成
+ * regex.c (re_compile_pattern): add space to stop_nowidth to save
+ runtime stack position.
-Wed Oct 16 12:56:22 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+Tue Dec 16 14:57:43 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * ruby-man-0.99.2-jp/index.html: 日本語版ドキュメントの完成(長かった…)
+ * string.c (scan_once): wrong exception for regexp that match with
+ null string (use substr instead of subseq).
- * re.c (reg_regcomp): $=がnilの時の処理
+Sat Dec 13 00:13:32 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * string.c (f_chop): $_に対するchop
+ * parse.y (expr): remove bare assocs from expr rule.
-Tue Oct 15 11:04:23 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * rbconfig.rb: renamed from config.rb (it was too generic name).
- * version 0.99.2-961015
+Fri Dec 12 00:50:25 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Mon Oct 14 18:22:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * parse.y (expr): warns if BEGIN or END appear in the method
+ bodies.
- * eval.c (thread_schedule): BOW対応.selectが-1を返した時にバグ(実
- はdo .. whileがcontinueで先頭にジャンプすると思い込んでいた.条
- 件の直前だったのね ^^);;;;;
+ * string.c (str_match): calls y =~ x if y is neither String nor
+ Regexp so that eregex.rb works.
- * sample/ruby-mode.el (ruby-mode-syntax-table): ?のsyntaxが"/"では
- まずいらしい
+ * eval.c (f_at_exit): to register end proc.
- * hash.c (rb_hash): name conflict
+ * class.c (rb_define_module_function): define 'function' method
+ for the Module, not private method.
-Fri Oct 11 00:23:05 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * class.c (rb_define_function): function to define `function' method.
- * version 0.99.2-961011
+ * eval.c (rb_eval): inherit visibility from superclass's method
+ except when it is set to `function'
- * ext/marshal/marshal.c (w_object): 結局動いていなかった循環オブジェ
- クト対応を外した.
+ * eval.c (rb_eval): new visibility status `function'.
- * hash.c (rb_hash): Fixnumと文字列の高速化
+ * parse.y (yycompile): do not clear eval_tree. thus enable multipe
+ command line script by optn `-e'.
- * ext/marshal/marshal.c (w_object): 無駄なデータの削除(フォーマッ
- トの非互換性)
+ * eval.c (rb_eval): END execute just once.
- * io.c (io_readline): 戻り値の不備
+ * parse.y (expr): BEGIN/END built in the syntax.
- * ext/marshal/marshal.c (marshal_dumps): MSDOS対応
+Thu Dec 11 13:14:35 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * ruby.c (load_file): MSDOS対応
+ * object.c (mod_le): Module (or Class) comparison.
-Wed Oct 9 17:46:27 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * eval.c (rb_remove_method): raises NameError if named method does
+ not exist.
- * ext/extmk.rb.in (install): 無駄なコピーを避ける
-
- * string.c (str_sub_method): マッチがなかった時のString#subの値が
- 違っていた.
-
- * eval.c (obj_extend): extendした時にobject_extendedを呼ぶように
-
-Tue Oct 8 00:55:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_alloc): 割当の平均化
-
- * eval.c (thread_schedule): joinのバグを修正
-
- * eval.c (thread_wait_for): selectへの割込みなどに対応
-
- * eval.c (thread_select): linuxのselectの挙動に対応(timeoutが変化
- する)
-
-Mon Oct 7 09:47:19 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.2-961007
-
- * eval.c (PUSH_BLOCK): the_classの保存を忘れていた.
-
- * ext/dbm/dbm.c (fdbm_store): sizeの保存する場所が間違っていた
-
- * ext/socket/socket.c (s_accept): thread対応していなかった
-
-Sat Oct 5 01:32:27 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * io.c (io_readchar): EOFで例外を発生させる
-
-Fri Oct 4 11:59:54 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/marshal/marshal.c (w_object): HashとObjectの復旧に必要なハッ
- シュテーブルが渡されていなかった.
-
- * variable.c (rb_path2class): ユーザ定義クラスの復旧に失敗していた
-
- * variable.c (rb_path2class): クラスが存在しない時のエラーをFatal
- からNameErrorへ.
-
- * range.c (range_s_new): first,lastが両方Numericの時エラーになって
- いた.
-
- * range.c: start->first, end->last
-
-Wed Oct 2 02:02:46 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c: DJGPPでchmod,chownを使えるように(ってDOSにchownがあるのか?)
-
- * class.c (rb_singleton_class): ビルトインクラスもextendしたり特異
- メソッドを追加したりできるように
-
- * variable.c (rb_set_class_path): ユーザ定義のトップレベルクラスに
- pathを設定しない
-
- * eval.c (eval): 例外がRuntimeErrorに化けていた
-
- * eval.c (eval): eval中の例外の表現の改善
-
- * eval.c (eval): eval_with_bindingとの一本化
-
- * eval.c (rb_eval): クラス/モジュール定義の中から定義中のクラス/モ
- ジュールが参照できるように
-
-Tue Oct 1 01:40:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.2-961001
-
- * parse.y: cur_crefが2度宣言されていた
-
- * signal.c (trap): SIGSEGV,SIGBUSのない機種に対応
-
- * io.c (Init_IO): 引数タイプの指定間違い
-
-Mon Sep 30 15:28:00 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.2-960930
-
- * config.guess,config.sub: $host_osが正しく設定されない
-
- * eval.c (rb_eval): yieldで正しくないselfが設定されていた
-
- * eval.c (ruby_run): toplevelの例外処理のバグ
-
-Mon Sep 30 09:13:26 1996 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * djgpp対応
-
-Sat Sep 28 02:45:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.2-960928
-
- * sample/ruby-mode.el (ruby-beginning-of-block): ブロックの先頭に
- 移動(正しくインデントしていないと動作しない)
- (ruby-end-of-block): 同上
-
- * eval.c (class_s_new): Class#newがイテレータとして呼ばれた時は
- initializeもイテレータとして呼ばれるように
-
- * signal.c (sigsegv): SEGVでbacktraceを表示するように
-
-Fri Sep 27 09:51:07 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.2-960927
-
- * eval.c (error_print): 引数のないraiseでメッセージが正しく表示さ
- れるように.
-
- * eval.c (rb_longjmp): mesgがnilの時RuntimeErrorを生成する.
-
- * eval.c (f_raise): 引数がない時に対応
-
- * eval.c (thread_mark): stack上にないデータのアドレス変換を行って
- いた.
-
- * eval.c (Init_Thread): 割込みの間隔が1秒と長すぎた.
-
-Thu Sep 26 16:02:45 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_schedule): 一度ペンディングになるとフラグがクリア
- されていなかった.
-
- * process.c (rb_proc_exec): system/execの引数が空文字列であった場
- 合,例外を発生すべきだった.
-
- * config.sub/config.guess: 新しいものに置き換え
-
-Thu Sep 26 15:41:35 1996 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-
- * io.c (next_argv): -i.bakをBOWとDOSに対応.
-
-Thu Sep 26 01:31:43 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * io.c (io_sysread): EOFで例外
-
- * io.c (f_readline): EOFで例外を発生するように.getsは互換性のため
- nilを返すままにする
-
- * eval.c (proc_call): lambdaからのreturnでIN_BLOCKフラグが立ったま
- まだった
-
- * eval.c (PUSH_BLOCK2): threadに対応するためBlockを一度stackにコピー
-
-Wed Sep 25 11:54:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (method_call): Const::method()形式を使えるようにしてみた.
- 引数括弧は省略できない.
-
- * sample/test.rb: Process.killの存在を確かめてからテストを行う
-
- * eval.c (eval_with_binding): 第2引数としてbinding(またはlambda)を
- 与えるとその環境でevalを実行するようにした
-
- * eval.c (f_binding): 現在のbindingを返す関数
-
- * eval.c: block構造体にthe_classを保存するメンバを追加
-
- * process.c (Init_process): kill,wait,waitpidをProcessに移動
-
-Tue Sep 24 02:44:43 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/ruby-mode.el: いろいろ問題が多いので以前の高速化は破棄.
- 別のアプローチを使った.
-
- * lib/tk.rb (Tk.pack): 複数のウィンドウを受け付けるpack
-
-Sat Sep 21 11:08:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (exprs): 空文も受け付けるように文法を変更.今までは改行
- の連続だけが許されていた.
-
-Fri Sep 20 11:39:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * Failの大半を名前つき例外に変更.
-
- * re.c (Init_Regexp): 名前つき例外を導入.
-
- * eval.c (f_missing): Objectはinspectしない.
-
- * object.c (inspect_i): Object#inspectでloopに対応.
-
- * regex.c (re_search): /^$/が""にマッチしなかった.
-
-Thu Sep 19 19:25:12 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * regex.c (re_search): /^$/が非空行にマッチしていた.
-
-Tue Sep 17 10:28:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.2-960917
-
-Mon Sep 16 10:47:56 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/ruby-mode.el (ruby-calculate-indent): 演算子継続の場合の
- 文字列の判定のバグ
-
- * sample/ruby-mode.el (ruby-calculate-indent): elseなどの次の行の
- インデント計算を正しく.
-
-Sat Sep 14 08:37:19 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.2-960914
-
-Fri Sep 13 08:06:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/socket/socket.c (tcpaddr): port番号にntohsをつけ忘れ
-
- * dln.c (link_undef): テーブルの種類が間違っていた.
-
- * bignum.c (bigadd): 引き算が発生する時に計算違いが起きていた.
-
- * parse.y (iter_do_block): do..endでもdynamic variableを.
-
- * bignum.c (big_pow): より正確な計算を(整数同士ではfloatに変換しな
- い).
-
-Thu Sep 12 13:11:55 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * variable.c (rb_set_class_path): Stringクラスが初期化される前に
- Stringを作っていた.組込みクラスにはpathはいらない
-
- * parse.y (yylex): 0.1が0になっていた
-
- * parse.y (yylex): 行番号の不整合
-
- * gc.c (oblist_live_obj): 今「生きている」全部のオブジェクトを返す
- イテレータ.そのクラス(またはサブクラス)の全部のインスタンスを返
- すeach_object_ofも定義した.
-
- * class.c (rb_define_class_id): 無駄なクラスを割り当てていた.結果
- として未初期化のクラスオブジェクトが存在していた.
-
-Wed Sep 11 00:56:23 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (yylex): octalの定数の検出をより正確に(090はエラーとか).
-
- * bignum.c (big_minus): yがxより大きい場合にエラー.
-
- * parse.y (yylex): エラー行番号の表示をより正確に
-
- * sample/ruby-mode.el (ruby-expr-beg): 変数名が1文字の時誤動作して
- いた.
-
- * sample/ruby-mode.el (ruby-calculate-indent): ?/でループに落ちい
- たバグを修正.
-
- * enum.c (enum_min,enum_max): sortのようにイテレータとしても動作す
- るように.
-
- * enum.c (enum_find_all): typo
-
-Tue Sep 10 12:07:12 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * node.h (nd_line): NODEのlineをflagsに押し込めてオブジェクトサイ
- ズを小さくした.制限:32bit intのマシンの場合,ファイルの行数が
- 32767を越えると正常に表示されない.
-
- * st.c: hashとcompareの関数メンバを構造体にパック,クラス的な使い
- 方を行う.1 tableあたり4 byteの節約.
-
-Mon Sep 9 16:35:54 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (file_truncate): 提供されない時には特別な例外を発生するよ
- うに.
-
- * eval.c (Init_Proc): 不適切な位置のlocal-jumpを例外に.
-
-Sat Sep 7 17:06:15 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (proc_call): まだスコープがスタック上にある時には局所脱出
- を有効にする.これで,procを生成してcallすることは,スコープを脱
- 出しない限り,yieldと同じ意味を持つことになる.
-
-Fri Sep 6 13:30:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/ruby-mode.el (ruby-indent-to): インデントが変わらない時に
- はバッファを変更しない.
- (ruby-calculate-indent): まず文字列の内部か判断してから,前の行
- からパーズを行う.defunが大きくなった時の高速化.
- (ruby-in-string-p): 文字列の内部かどうかを判断する関数(以前の
- parseから分離)
- (ruby-parse-region): 文字列に対する処理をはずす.
- (ruby-beginning-of-block): ブロックの先頭に
- (ruby-end-of-block): ブロックの末尾に(遅い…)
-
-Thu Sep 5 14:23:07 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (file_s_split): [dirname,basename]にsplitする.
-
- * eval.c (rb_eval): evalの中でも定数の値が正しくなるように.これで
- 定数に関しては静的なスコープが保証されるようになった.
-
- * st.c (rehash): ハッシュ拡大の系数を2から1.79に.割算がより良い値
- を返すように.
-
-Thu Sep 5 00:32:07 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (class_superclass) クラスのスーパークラスを返すメソッド.
-
-Wed Sep 4 16:54:56 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * random.c (f_rand): Bignumやlongの範囲を越えるFloatに対する乱数も
- 発生できるように.
-
- * struct.c (struct_alloc): Fatalではなく例外を発生させるように(通
- 常の使用で発生しうる).
-
- * struct.c (struct_s_members): Structの特異メソッドではなく,生成
- されたStructクラスの特異メソッドにした.
-
- * st.c (st_init_table): ruby専用にパラメタを固定にした(サイ
- ズが減った)
-
-Mon Sep 2 11:37:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * array.c (ary_shift): capaがあまりにも大きい時には領域をREALLOC
- (ary_pop): 同上
-
- * string.c (str_inspect): multibyte character 対応にミス.
- (str_inspect): unsigned charにしないと符号展開されてしまう
-
- * parse.y (primary): `::'をprimaryに移動 Foo::Bar.Bazがエラーにな
- らないように.
+ * ext/curses/curses.c: remove CHECK macro for BSD curses.
- * parse.y (primary): オペレータ形式の特異メソッドが定義できない
-
- * random.c (f_rand): maxが0の時に対応
-
- * io.c (io_printf): 関数を定義していたがインタプリタに登録していな
- かった.
-
- * file.c (file_s_basename): 第2引数が無い時にエラー.
-
-Thu Aug 29 10:49:40 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (expr): イテレータの新形式に「method do .. end」形式を採
- 用した.もちろん昔の形式も有効.
-
- * sample/ruby-mode.el (ruby-calculate-indent): endの数の方が多い場
- 合にもエラーを起こさないように.
-
-Wed Aug 28 09:41:36 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * numeric.c (upto,downto,step,times): 対象がfixnumの範囲を越えても
- 動作するように.
-
-Mon Aug 26 10:04:37 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * missing/setenv.c (envix): typo(missing `== 0' for memcmp)
-
- * dir.c (dir_foreach): foreach(dir open -> read loop -> closeまで)
-
- * io.c (io_foreach): foreach(file open -> read loop -> closeまで)
-
- * Fatalのうち捕捉可能ないくつかを例外に.
-
-Sat Aug 24 23:56:37 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * bignum.c (bigdivmod): FIX2INT -> INT2FIX 大間違い
-
-Fri Aug 23 18:13:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * regex.c (re_free_registers): allocateしていない時には当然 free
- してはいけない.
-
-Thu Aug 22 01:20:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_create): 外側から強制終了させられたthreadは
- cleanupする必要が無い.
-
-Wed Aug 21 09:57:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_create): threadを終了させた大域脱出の情報を
- main_threadに渡すように.
-
- * parse.y (call_args): 最終引数に括弧を省略したメソッド呼出しを置
- けるように(例: print foo bar, baz == print(foo(bar,baz)))
-
-Tue Aug 20 13:37:16 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (masign): 多重代入とrest引数の動作を合わせて空の配列を代
- 入するように.
-
- * parse.y (arg): defined?の強度をもうちょっと強く
-
- * eval.c (error_print): -wで例外名も表示するように
-
- * eval.c (rb_eval): 新構文に対応
- (handle_rescue): 捕捉する例外を kind_of? で同定
-
- * parse.y (primary): rescueの構文を変更(同定引数の追加,複数rescue)
-
- * Fail()のかなりを適当な例外を使うように
-
- * eval.c (thread_interrupt): Interrupt(今はnon-local jump)は
- main-threadに送られるように.
-
- * eval.c (rb_longjmp): $! の内容を文字列から例外クラスに変更
- (rb_raise): rb_fail から名称変更
- (rb_interrupt): 例外化
- (rb_exit): 例外化
-
- * error.c (Init_Exception): 例外クラスの新設(文字列のサブクラス)
-
-Mon Aug 19 19:40:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * signal.c (trap): 古いハンドラを返すように.
-
-Wed Aug 14 00:07:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_trap_eval): ハンドラのためにthreadをforkすることを止
- めた.
-
- * eval.c (thread_mark): thread毎の $!, $@ をマークし忘れ
-
- * ext/dbm/dbm.c (fdbm_delete): イテレータとして呼ばれた場合,要素
- が無ければブロックを評価する.
-
- * hash.c (hash_delete): イテレータとして呼ばれた場合,要素が無けれ
- ばブロックを評価する.
-
- * array.c (ary_delete): イテレータとして呼ばれた場合,要素が無けれ
- ばブロックを評価する.
-
- * eval.c (rb_interrupt): SIGINTのデフォルトをexitから特別な大域脱
- 出に.やはり割り込まれた位置の表示が無いのは寂しいので.
-
-Tue Aug 13 01:34:00 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_exit): sub-thread内でのexitもstatusを保存するように
- (thread_create): 自thread内のexitに対応
-
- * signal.c (sighandle): SIGINTのデフォルトハンドラはexitするように
- (以前は例外を発生していた).
-
- * 例外の一部をFatalに.
-
- * string.c (str_aset): 文字列の置換の対象が部分文字列でなかった時,
- 例外を発生させないように
-
- * eval.c (proc_call): Procの中からbreak/nextは通し,他のものは通さ
- ないように
-
-Mon Aug 12 14:15:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * object.c (krn_type): 文字列を返す
-
- * eval.c (thread_create): sub-thread内でのexitに対応
-
- * numeric.c (fix_type): 文字列を返す
-
- * io.c (f_p): デバッグ用データ表示メソッド
-
- * eval.c (f_missing): nil/TRUE/FALSEを特別扱い
-
- * string.c (str_inspect): 長い文字列を短縮表示.inspectの働きを
- human readable stringの生成に統一(re-generatable string は正式に
- 無くなった).
-
-Sat Aug 10 16:54:21 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * object.c (Init_Object): kernel/nil/false/trueのクラス名を変更(小
- 文字に),rubyスクリプトからアクセスできないように.
-
- * eval.c (rb_eval): CONSTANTのアクセス先を単純化.crefを使わない.
-
- * eval.c (f_eval): 特異メソッド内でも定数の値が正しくなるように
-
-Fri Aug 9 12:23:17 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * array.c (ary_concat): append -> concat Stringに合わせた
-
- * parse.y (yylex): `$;'が使えなかった.
-
- * array.c (ary_push_method): 複数引数を受け付けるように.
- (ary_unshift): 複数引数を受け付けるように.
-
- * io.c (io_popen): IO.popenでcommand pipeが開けるように.
-
- * object.c (Init_Object): KernelとNilをruby scriptからアクセスでき
- ないように.
-
-Thu Aug 8 01:21:47 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * object.c (f_integer): 整数への変換関数
- (f_float): 実数への変換関数
- (f_string): 文字列への変換関数
- (f_array): 配列への変換関数
-
- * bignum.c (big_to_i): FIXNUMの範囲でない時はBignumのまま返すよう
- に変更.
-
-Wed Aug 7 09:28:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99.1-960807
-
- * parse.y (mlhs): 「*foo = 1,2,3」タイプの多重代入も可能に.
-
- * object.c (Init_Object): クラスTrue/Falseをruby scriptからアクセ
- スできないように.
-
- * object.c (nil_inspect): inspect表現は"nil"に
-
- * io.c (io_print): nilのprintをnilに.
-
- * object.c (nil_to_s): nilの文字列表現を""に.
-
-Tue Aug 6 01:12:32 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * dir.c (dir_s_open): file descripterが足りない時にはgcしてからも
- う一度openしてみる.
-
- * io.c (rb_fopen): すべてのfopen()についてfile descripterが足りな
- い時にはgcしてからもう一度openしてみる.
-
- * ext/socket/socket.c (Init_socket): 定数の追加.
-
- * sample/ruby-mode.el (ruby-indent-to): インデント後のカーソル位置
- の調整を正しく.
-
- * gc.c (gc): 割込みチェックを行わない(Cコードの中で安心して
- malloc()が使えなくなるので).
-
- * st.c (call_hash_func): signalとthreadによる割込みに対応.
-
- * sig.h (DEFER_INTS): 割込み禁止区間の指定
-
- * eval.c (f_require): threadによるrequireの競合に対応(最初の
- requireが終了するまで他のthreadは待つ).
-
- * bignum.c (str2inum): 0x80000000の値が負になっていた
-
- * sprintf.c (f_sprintf): 文字列末尾,行末の単独の`%'に対応
-
- * bignum.c (big_cmp): 比較の結果が逆になる時があった.
-
-Mon Aug 5 10:58:13 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * process.c (proc_exec_v): 例外のメッセージを分かりやすく.
-
- * ext/dbm/dbm.c (fdbm_store): nilを格納すると要素の削除になる
-
- * ext/dbm/dbm.c: サイズをキャッシュ.
-
-Sat Aug 3 01:52:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_fail): `fail'が引数無しで呼ばれた時だけ以前の`$@'を保
- 存するように.
-
- * eval.c (f_fail): frameの調整
-
-Fri Aug 2 11:26:21 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/socket/socket.c (bsock_setopt): valとしてTRUE/FALSE/Fixnumも
- 受け付けるように.
-
- * ext/socket/socket.c (Init_socket): SO_REUSEADDR等の定数の追加
-
- * ext/md5/md5init.c: md5モジュール(初の複数ファイルからなるモジュー
- ルでもある)
-
- * ruby.h (Make_Data_Struct): Data: objectのinstance変数に格納 ->
- Data型のObjectに(Dir,Time,Proc,Thread,DBM)
-
-Thu Aug 1 11:38:44 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/dbm/dbm.c (fdbm_store): valueが文字で無い時に対応
-
-Wed Jul 31 10:53:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/socket/socket.c (open_inet): htonsが必要であった
- (tcpaddr): ntohlで変換した
-
- * process.c (rb_proc_exec): execvp -> execv
-
-Tue Jul 30 17:48:33 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c: `$?'をthread localに
-
- * Makefile.in (install): install時にstripを行う
-
- * configure.in: install時のstripの検出
-
- * configure.in: NEXTSTEP対応
-
- * version 0.99.1-960730
-
-Tue Jul 30 16:40:35 1996 SHIROYAMA Takayuki <psi@fortune.nest.or.jp>
-
- * dln.c (dln_load): NeXT dln(mach-o)対応.configureは未対応
-
-Tue Jul 30 09:46:51 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * process.c (f_system): 複数引数もとれるように
-
- * process.c (f_exec): 複数引数もとれるように
-
- * array.c (ary_append): 配列(またはEnum)の要素を破壊的に追加
-
- * array.c (ary_plus): Enumはその要素を追加
-
- * file.c (file_s_open): File.openを追加
-
- * struct.c (struct_new): FIX2INTを忘れていた
-
- * file.c (Init_File): exists? -> exist?
-
- * object.c (obj_is_kind_of): is_kind_of? -> kind_of?, is_a?
-
- * object.c (obj_is_instance_of): is_instance_of? -> instance_of?
-
-Mon Jul 29 16:40:02 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (parse_regx): 式展開を行った場合,casefoldの設定ができて
- いなかった.
-
- * object.c (true_type): TRUE/FALSEにtypeを実装.
-
- * parse.y (read_escape): 3文字以内のoctalに対応(\0とか)
-
-Fri Jul 26 00:31:45 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * array.c (ary_reverse_bang): in-placeで配列を反転させる
- (ary_sort_bang): in-placeでsortする
- (ary_sort): sortした配列を返すように
- (ary_delete_at): 指定した位置の要素を削除する
-
- * eval.c (rb_call): stack深さチェックを毎回は行わないように
-
- * error.c (Warning): 実行中のwarningが表示されていなかった
-
- * eval.c (compile): 例外発生を分離.
-
- * eval.c (f_eval): 変数rb_in_evalを正しく管理するように
-
- * ext/dbm/dbm.c (fdbm_store): 格納するkeyを文字列に変換
-
- * eval.c (rb_call): 無限再帰のチェックを大域脱出を行うC methodにも
- 対応させた.threadのstack深さチェックルーチンを流用.
-
- * parse.y (yylex): 第1引数のunary -/+の判定が間違っていた.
-
- * parse.y (yylex): unary +で数字を余計に読んでいた(ex. +5 -> 55)
-
-Thu Jul 25 12:15:04 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (yylex): 曖昧でない引数に対して警告を出していた.
-
- * eval.c (iterator_p): 引数で呼んでも正しい結果を返すように.
-
- * parse.y: break/next/redo/retryのメソッド化.
-
- * sample/ruby-mode.el (ruby-calculate-indent): nestのチェックミス
-
- * sample/ruby-mode.el (ruby-parse-region): 予約語のチェックを強化
-
- * parse.y (primary): unless/untilの復活
-
-Tue Jul 23 18:50:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * array.c (Array#empty?), Hash.c (Hash#empty?), ext/dbm/dbm.c (DBM#empty?):
- 空の判定述語
-
- * eval.c (f_unless): ifの逆をするイテレータ
-
- * eval.c (f_until): whileの逆をするイテレータ
-
- * parse.y: notの優先順位をand/orより高く
-
- * parse.y (expr): `!'を引数括弧を省略したcallでも有効に
-
-Mon Jul 22 10:15:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99-960722
-
- * array.c (ary_print_on): OFSのNILチェックが不完全
-
- * ruby.c (load_file): 標準入力からのスクリプトが空の時に対応.
-
- * ruby.c (proc_options): -wでは引数無しの時には標準入力からスクリ
- プトをとる(-vではたんに終了する).
-
- * array.c (ary_compact): nilの要素を取り除くメソッド
-
- * array.c (ary_nitems): nilでない要素を数えるメソッド
-
-Sun Jul 20 00:51:53 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.c (proc_options): -w optionを追加
-
- * parse.y: {}が閉じていない時には展開しない文字列を
-
-Fri Jul 19 16:16:05 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99-960719
-
- * lib/find.rb: 石塚版(pruneの拡張付き)
-
- * file.c (test_l): lstatで調べないとね.
-
- * eval.c (f_throw): 第2引数を省略可能に.
-
- * parse.y (str_extend): {}のネストに対応
-
-Thu Jul 18 18:25:46 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99-960718
-
- * parse.y (str_extend): 文字列中の式展開に \" ' ` / を含む事ができ
- るように.
-
-Tue Jul 16 15:55:31 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/ruby-mode.el (ruby-parse-region): 正規表現内のエスケープ
- に対応
-
- * version 0.99-960716
-
-Fri Jul 12 10:06:19 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * io.c (f_select): 引数のclose check.
-
- * ruby.c (load_file): #!行の引数チェックを第1引数に限定(実をいうと
- DOS改行対策)
-
-Wed Jul 10 17:18:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99-960710
-
- * time.c (time_s_timegm/time_s_timelocal): 時間を生成するメソッド
-
-Mon Jun 17 15:59:20 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99-960617
-
- * parse.y (yyerror): エラー表示の簡略化.
-
-Wed Jun 12 14:11:01 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * signal.c (rb_trap_exit): trap 0はthreadを生成せずに処理する.
-
-Fri Jun 7 10:17:01 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * array.c/hash.c (indexes): 配列1引数のパターンを無くした.配列の
- 場合は`*ary'を使ってもらおう.
-
- * eval.c (thread_wait_threads): main_threadが終了する前に他の
- threadを待つ(強制的には終了させない).
- (ruby_run): 他のthreadを待っている間にシグナルが来たら,全thread
- を強制終了させる.
-
- * eval.c (rb_fail): メソッド名を`$!'に埋め込む.
-
- * eval.c (thread_create): main_threadのコンテクストがセーブされな
- い場合があった.
-
- * process.c (f_sleep): 時間を指定せず,threadがひとつしかない状況
- にも対応.
-
- * eval.c (thread_create): create後,fnを呼び出す前にcontext switch
- が起きると違うcontextでfnが実行されてしまうバグ.
-
-Mon Jun 3 08:03:17 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * struct.c (struct_s_def): メンバの指定を文字列,シンボル(FIXNUM)
- 双方で可能にした.
-
- * ext/etc/etc.c (Init_etc): 構造体オブジェクトをGCから保護した.
-
- * error.c (rb_sys_fail): nil/FALSEを引数として受け付けるように.
-
-Thu May 30 16:19:08 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_select): EINTRに対応.
-
-Wed May 29 11:04:51 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (f_catch): catch/throwを実装した.
-
-Tue May 28 13:30:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99-960528
-
- * eval.c (thread_cleanup): main threadが終了すると他のthreadも終了
- することの明確化.
-
- * signal.c (trap): SIGINTのデフォルトの設定ミス(本当にSIG_DFLでは
- まずかった).rubyではちゃんとハンドルしないと.
-
- * eval.c (thread_interrupt): SIGINTはmain_threadに例外を発生させる
- ように.
-
-Mon May 27 15:13:31 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_status): threadの状態を返すメソッド.threadの終了
- を待たない.
-
- * eval.c (thread_value): 一種のpromiseを実装するためのメソッド.
-
- * eval.c (thread_join): 待っているthreadが例外を起こした時には,
- joinがその例外を発生するように.
-
- * eval.c (thread_create): threadでの例外をpropagateしないように.
-
-Fri May 24 10:47:53 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * enum.c (Init_Enumerable): `size' as alias to the `length'
-
- * eval.c (thread_save_context): `$@', `$!'をスレッド毎にセーブ.
-
- * eval.c (superclass): エラー表示をより親切に.
-
-Thu May 23 10:38:41 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.99-960523
-
- * eval.c (superclass): エラー時にスーパークラス名を(分かれば)表示
- するように.
-
-Wed May 22 19:48:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (superclass): スーパークラスの指定子を`:'から`<'に変更.
-
-Tue May 21 09:27:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * lib/thread.rb: threadをサポートするクラス(Mutex, Queue).
-
-Mon May 20 09:39:49 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * time.c (time_cmp): 浮動小数点数も扱えるように.
- (time_minus): Time - Timeが浮動小数点数を返すように.
-
-Fri May 17 15:40:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * process.c (rb_proc_exec): Thread対応時にexecの直前に
- ITIMER_VIRTUALをリセットする.
-
-Tue May 14 02:12:44 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * signal.c (sighandle): SIGINTに対してデフォルトで例外を発生させる
- のをやめ,status 130でexitするようにした.
-
- * eval.c (thread_schedule): Threadのバグはほとんどとれたようだ.
-
-Fri May 10 11:21:08 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (thread_schedule): ユーザレベルThread機能.効率はともかく
- 移植性はある.今後,thread間の通信機能を実装する予定.
-
-Thu May 2 21:22:31 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * time.c (time_timeval): struct timevalを直接返すように(static変数
- を使わない).
-
-Wed May 1 17:27:32 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * process.c (f_sleep): 整数以外のtimeを指定できるように.
-
-Thu Apr 25 08:19:15 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (file_s_dirname): ファイル名が"/"を含まない時,"."を返す
- ように(GNU dirnameの仕様).
-
- * file.c (file_s_basename): まだnilと0を混同しているソースが残って
- いた.
-
- * parse.y (exprs): エラーリカバリを追加.
-
-Wed Apr 24 15:51:05 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_chop_bang): CRLFの場合2 bytesをchop!するように.
-
- * ext/socket/socket.c (tcp_svr_s_open): まだnilと0を混同しているソー
- スが残っていた.
-
-Tue Apr 23 18:14:25 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * pack.c (pack_pack): "A/a"のバグ.余計なpaddingが入っていた.
-
-Thu Apr 18 13:02:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * configure.in: アーキテクチャ依存部を別ディレクトリにインストール
- するように.
-
- * parse.y (yyerror): エラー発生時にエラー行とその位置を表示するよ
- うに.
-
-Wed Apr 17 14:22:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * defines.h: SAFE_SIGHANDLEを無くし,危険な選択はできないように.
-
- * io.c (io_ungetc): 新機能.
-
- * ruby.c (load_file): ファイルからの読み込み方式が変わったのに対応.
-
- * parse.y (compile_file): ファイルからの入力を一度全部読み込むのを
- 止めて,getsを使うことにした.
-
-Wed Apr 10 17:40:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.98
-
-Tue Apr 9 09:54:30 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (iter_block): イテレータブロックの指定をメソッド呼び出し
- に限定.文法の明確化.
-
- * eval.c (rb_eval): 条件式の正規表現の比較をinline化.
-
- * eval.c (rb_eval): defined? の 定義情報(種別)を文字列で返す.
-
- * node.h: NODE_BEGIN -> NODE_RESCUE, NODE_ENSUREに分離.
-
- * eval.c (rb_eval): option -n/-pのトップレベルループのinline展開.
-
- * parse.y (cond0): 条件式中の文字列は比較の対象としない
-
-Wed Mar 27 12:33:54 1996 Tairo Nomura <tairo@hucom.tp.titech.ac.jp>
-
- * defines.h: NeXT対応
-
-Wed Mar 27 10:02:44 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y: 予約語の変更 continue -> next
-
-Mon Mar 25 07:34:37 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (parse_regx): o(once)オプションを追加.
-
-Fri Mar 22 14:25:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.97d
-
- * eval.c (dyna_var_defined): 動的ローカル変数の定義チェック用ルー
- チン.
-
- * parse.y (gettable): eval()の中での動的ローカル変数(既に値を持っ
- ているもの)の検出に失敗していた.
-
-Tue Mar 19 10:46:47 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.97c
-
- * re.c (reg_s_new): compile時にsegmentation fault.
-
- * parse.y (str_extend): いつもevalするように.
-
-Wed Mar 13 11:00:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (str_extend): 文字列中の式展開の不備を無くした.
-
- * parse.y: 下手なエラーリカバリを外した.
-
-Tue Mar 12 12:30:20 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rescue): 間違ってensureでも例外を捕捉していた.
-
-Wed Mar 6 12:11:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (var_extend): 変数展開"#{}"で,任意の式を書けるようにし
- た,これで「変数」展開では無くなっちゃったなあ.
-
- * regex.c (init_syntax_once): `_'をwordに追加.
-
- * regex.c (re_compile_pattern): `\w',`\W'の判定をsyntax tableを使
- うように.
-
-Tue Feb 27 10:15:32 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * object.c (obj_inspect): 表示するインスタンス変数が無い時には,
- to_sを使う.
-
- * configure.in: dlnの検出を自動的に.
-
-Mon Feb 26 19:55:33 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.c (readin): read(2)で一度にファイルが読み込めない場合に対応.
-
-Sat Feb 24 14:47:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.97b
-
-Fri Feb 23 11:26:02 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * class.c (rb_define_module): C言語で定義されたモジュールのPATHの
- 設定忘れ.文字列化でcore dump.
-
- * eval.c (mod_include): 戻り値をnilに.
-
- * version 0.97a
-
-Thu Feb 22 21:03:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * array.c (ary_times): 「配列*文字列」がjoinと同じ働きをするように.
-
-Wed Feb 21 11:18:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * configure.in : fileCountをcache.
-
- * configure.in : LinuxでELF環境を自動的に検出できるよう.
-
-Tue Feb 20 11:18:09 1996 Mitsuhide Satou <mit-sato@aries.bekkoame.or.jp>
-
- * FreeBSD dynamic link対応.
-
-Fri Feb 16 08:50:01 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * object.c (obj_inspect): インスタンス変数を持たないオブジェクトも
- 正しく表示されるように.
-
-Wed Feb 14 16:56:44 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_eval): 条件式の`2..2'など左辺成立直後に右辺が成立する
- パターンにバグ.
-
-Tue Feb 13 18:22:22 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.97
-
-Fri Feb 9 21:32:55 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * lib/tkscrollbox.rb: スクロールでtclの設定を行い,ruby<->wishの不
- 要な通信を無くした.
-
-Wed Feb 7 10:26:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_aref): indexをunsigned intでとっていた.
-
- * string.c (str_aref): 範囲外のindexに対してnilを返す.
-
- * parse.y (special_local_set): `$_'が宣言無しに使われた場合に対応.
- 関数をvariable.cから移動.
-
- * string.c (str_sub): 置換開始位置が間違っていた.
-
-Tue Feb 6 16:17:31 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/ruby-mode.el (ruby-parse-region): コメントの読み飛ばしの
- バグ.
-
-Fri Feb 2 18:35:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * variable.c (lastline_get): `$_'を`$~'と同じようにSCOPEローカルな
- 変数にした.
-
-Thu Feb 1 14:14:07 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c: statのcacheをやめた.
-
-Wed Jan 31 07:13:08 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (proc_s_new): procの中でyieldを呼ばれた時にcore dumpして
- いた.とりあえず例外を発生させる.
-
- * variable.c (rb_class2path): singleton classに対応.
-
- * ext/etc/etc.c (Init_etc): struct_defineのターミネータがnilだった
- (0でなければならない).
-
- * ext/marshal/marshal.c: TRUE/FALSEを吐き出せるように.
-
- * eval.c (rb_get_method_body): キャッシュのalias対応,いままでは
- aliasはキャッシュに入っていなかった.
-
-Tue Jan 30 09:55:13 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_eval): NODE_BLOCK - tail recursive(というほどでもない
- が).
-
- * io.c (io_pipe): pipe(2)を実装した.
-
- * eval.c (rb_eval): Qselfをなくした.thread対応への第一歩.先は遠
- いが….
-
- * eval.c (proc_call): procの中でのreturnはprocの終了を意味するよう
- に.ただし,procからのyieldの中でのreturnは例外を発生する.
-
-Wed Jan 24 11:33:48 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.96a
+Thu Dec 11 12:44:01 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * dir.c (dir_each): `$_'の値を変更するのをやめた.
+ * pack.c: sun4 cc patch
- * io.c (f_readlines): nilとFALSEの分離のあおりで無限ループに落ちて
- いた.
+Wed Dec 10 15:21:36 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * ruby.c (ruby_options): $0の設定ミス.
+ * ext/marshal/marshal.c (marshal_load): can supply evolution proc
+ object as optional second argument.
-Tue Jan 23 15:28:21 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * re.c (reg_source): get source string of the regular expression.
- * eval.c (rb_eval): ``は文字列を引数とするメソッド(`)呼び出しのシ
- ンタックスシュガーであるとした.
+Tue Dec 9 10:05:17 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * ruby.c (addpath): `-I'オプションでディレクトリが「前に」追加され
- るように変更.
+ * version 1.1b1 released.
-Fri Jan 19 11:23:12 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * dln.c (load_1): N_INDR対応(出来たような気がする).
-
-Thu Jan 18 18:14:20 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.texi: FALSEとnilの分離を反映した.
-
-Tue Jan 16 17:39:23 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.96 - とりあえずnilとFALSEを区別する版
-
-Wed Jan 10 15:31:48 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * re.c (reg_match): マッチしなかった時の戻り値はFALSE.
-
- * object.c (rb_equal): `0 == nil'がTRUEになるバグ.
-
-Tue Jan 9 00:44:58 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * nilとFALSEが分離可能に変更.
-
- * nilとFALSEと0の区別を厳密に.
-
- * struct.c (struct_new): 引数を0で終る必要が無くなった.
-
- * object.c (inspect_i): オブジェクトのチェックのバグ(Fixnumでcore
- dumpしていた).
-
- * range.c (range_to_s): Rangeの表示を改善.
-
- * object.c (true_inspect): TRUEの表示を`TRUE'に.
-
-Mon Jan 8 15:02:33 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * numeric.c (fix_mul): divide by zero errorが発生した(オーバーフロー
- 検出のバグ)
-
- * texinfo.texをパッケージに含めた.
-
-Sun Dec 31 00:08:49 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_eval): `::'では,そのクラスで定義された定数を参照する
- ように変更.
-
- * string.c (Init_String): eachをeach_lineに戻した.
-
-Thu Dec 28 12:31:55 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_eval): caseの演算子を`=~'から`==='に.
-
- * variable.c (rb_const_set): クラス定数の再定義を許す(同じクラスで
- は不可).警告は出す.
-
-Wed Dec 27 13:27:52 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.95c
-
- * ext/tkutil/tkutil.c: wishがあってもなくても一応コンパイルだけは
- するように.
-
- * lib/tk.rb: 環境変数PATHから{wish|wish4.0}を探すように.
-
-Tue Dec 26 01:03:42 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/ruby-mode.el (ruby-parse-region): 正規表現の検出強化.
-
- * numeric.c (fix_mul): 乗算のオーバーフロー検出アルゴリズムのバグ.
-
- * ext/extmk.rb.in: ./install-shを使う場合のPATHを調整.
-
- * Makefile.in (install): lib/*.rbを一つずつインストール.
-
- * io.c (io_each_line): イテレータの戻り値をnilで統一.
-
-Fri Dec 22 10:34:32 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.95b
-
- * variable.c (f_untrace_var): 第2引数を指定すると特定のtraceを削除
- できるように.
-
- * variable.c (f_trace_var): 第2引数がnilの時,traceを削除する.
-
- * lib/tk.rb (file_readable/file_writable): 第2引数をnilにすること
- によるevent handlerの削除.
-
- * parse.y (variable): ドキュメントに`__FILE__'と`__LINE__'が残って
- いた.`caller(0)'で代用したはずだったのに.
-
- * eval.c (f_eval): $!のリセット.
-
- * error.c (err_sprintf): 勝手に"\n"を付加するのを止めた.
-
- * parse.y (f_arglist): 引数リスト直後のif/whileの読み間違い.
- lex_stateの値が設定されていなかった.
-
-Thu Dec 21 00:56:57 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.95a - ^^;;;
-
- * lib/tkscrollbox.rb: パッケージに入ってなかった.
-
- * configure.in: FILE structureのチェックにバグ.
-
- * Makefile.in (clean): ext以下をinstallしていた.
-
- * ext/socket/extconf.rb: Solarisにおける-lnlsのチェック.
-
- * array.c (beg_len): バグがあった….悲しい.
-
- * version 0.95 - fj.sourcesに
-
- * eval.c (rb_eval): rescueのロジックをrb_rescue()に一元化.
-
-Wed Dec 20 19:30:58 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * Makefile.in: 不要なコンパイルの回避(より完全に).
-
- * class.c (singleton_class_new): `single'->`singleton'
-
-Tue Dec 19 07:14:33 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * io.c (closed?): IOがcloseされているかどうかを知る述語.
-
- * parse.y (primary): 特異メソッドの引数のlex_stateが不適切.
-
- * lib/tk.rb: tcl->rubyの変換関数の用意.
-
- * ext/extmk.rb.in (install): installの2重コンパイルの回避.
-
- * array.c (range_beg_len): range指定の不適切なエラーを訂正.
-
- * string.c (str_aref): range指定のバグを削除.
-
- * lib/tk.rb (tk_split_list): Tclのリストに対応.
-
-Mon Dec 18 09:58:12 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.94
-
- * dln.c (dln_load): HP対応(未確認)
-
- * eval.c (Init_Proc): BlockをProcに改名.
-
-Sat Dec 16 13:46:14 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_eval): retryでイテレータの再実行ができるように.
-
-Fri Dec 15 17:14:30 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c: proc:lambdaの親しみやすい別名
-
-Thu Dec 14 17:21:55 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (dyna_var_asgn): イテレータブロック内で最初に初期化された
- ローカル変数の有効範囲をそのブロック内に限定.これでlambdaと呼べ
- ないことはない.
-
-Wed Dec 13 02:30:58 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * gc.c: autoloadのマークミス.
-
- * lib/tk.rb: wishからの複数行の戻り値に対応
-
- * lib/tkcomposite.rb: 複合widget
-
- * variable.c (rb_class2path): ICLASSに対応してなかった.
-
- * eval.c (ruby_run): exit(0)のバグ
-
-Sat Dec 9 01:21:24 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/marshal/marshal.c (dumps|load): 文字列に対する入出力を可能に
- した(ただし実はファイル経由なのだ).
-
-Fri Dec 8 18:29:11 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/marshal/marshal.c: シンボルを一度だけ初期化する.
-
-Thu Dec 7 07:58:50 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (yylex): 第1引数の正規表現の認識にエラーがあった.同時に
- 状態数を減らした.
-
- * string.c (str_sub): 置換でスキップ幅が大きすぎた.
-
-Wed Dec 6 15:14:23 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_sub_method): sub/gsub(!なし)は置換が行なわれなかっ
- た時,置換前の文字列を返す.
-
-Tue Dec 5 00:55:15 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (yylex): 括弧を省略した時の引数展開の`*'に対応.
-
- * eval.c (ruby_run): EXITハンドラ内での例外に対応.
-
- * bignum.c (big_cmp): BignumとFixnumの比較で落ちる.
-
-Mon Dec 4 14:21:18 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (call_op): コンパイル時の定数式の展開をやめた.労多くし
- て益少ないと判断したので.
-
-Thu Nov 30 01:35:15 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * lib/tk.rb: {Radio,Check}Buttonのvariableの実装.
-
- * eval.c (rb_yield_0): Block.callがネストした時のバグ.
-
- * io.c (f_select): 常に配列3つをふくむ配列を返すように
-
- * lib/tk.rb: fileeventをruby側で実装.
-
-Wed Nov 29 17:53:23 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * variable.c (rb_ivar_get): selfを常に指定するように.
-
-Tue Nov 14 00:07:29 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * lib/tk.rb: Tk4.0対応
-
-Mon Nov 13 16:23:32 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.93
-
-Thu Nov 9 23:26:01 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * gc.c (gc_mark): モジュールのMixinのマーク忘れ.
-
- * parse.y (f_arglist): メソッド定義の引数を括弧で括らなくても良い
- ようにした.
-
-Wed Nov 8 00:17:51 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_yield_0): 未初期化のローカル変数があった.
-
- * eval.c (rb_eval): pendig signalのチェックをeval実行後に行うよう
- にした.でないとシグナルの発生と検出が遠く離れてしまう事がある.
-
- * parse.y: class文のsuperclass部を定数から式に拡張した.
-
- * lib/tk.rb: Tkのほぼ全ウィンドウクラスに対応.キャンバスとテキス
- ト上のオブジェクトが残っている.
-
-Tue Nov 7 08:18:37 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * signal.c (trap): ブロックを指定できるように.
-
-Mon Nov 6 16:44:00 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (f_caller): 呼出元の情報を得る.
-
- * ext/tkutil/tkutil.c: wishのstderr出力を監視することで,エラー処
- 理を行う.
-
- * ext/tkutil/tkutil.c: wishとの通信部をCで記述.
-
-Sat Nov 4 01:12:59 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/ruby-mode.el (ruby-calculate-indent): インデントの計算を
- もう少しスマートにした(正規表現のチェック,継続行のチェック).
-
- * eval.c (rb_call): 無限再帰を避けるため,関数のネストレベルの制限
- を行なう.
-
- * lib/tk.rb: Tkインターフェース.まだ不完全だが.
-
- * eval.c (rb_yield_0): 空のBlockのバグ.
-
- * sample/ruby-mode.el (ruby-calculate-indent): 行末の演算子による
- 行継続に対応.
-
-Fri Nov 3 12:56:21 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_call): 本体が空の関数の実行にバグ.
-
- * parse.y (var_extend): 文字列の末尾の変数展開のバグ.
-
- * variable.c (rb_gvar_set): traceの評価時にに変数値を与えるように.
-
- * eval.c (f_require): ruby scriptのrequireにbug.
-
- * variable.c (rb_const_get): モジュールのinclude対策.
-
-Thu Oct 19 13:56:06 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * dln.c (dln_load): HP対応でのtypo.
-
-Wed Oct 18 17:39:39 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.92
-
- * object.c (krn_type): オブジェクトの動的な型を返すメソッド.
-
-Tue Oct 17 00:48:18 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.c (proc_options): -X オプション.chdirだけを行う.
-
- * re.c (reg_search): 漢字コードを途中で変更できるように.コンパイ
- ル時のコードが変更された時にはマッチの直前に正規表現の再コンパイ
- ルを行う.定数KCODEから変数$KCODEへ.
-
- * parse.y: ()のなかにcompexprを許す.
-
- * re.c (reg_search): メモリリークを直した.
-
-Fri Oct 13 13:19:19 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (str_sub): 文字列置換にバグ.
-
- * string.c (str_strip_bang): 文字列の後ろの長さの調整が行われてい
- なかった.
-
- * re.c (reg_search): $&, $1...はローカルに束縛するようになった.呼
- び出したメソッドでのマッチは現スコープの$&などの値に影響しない.
- マッチの情報をスコープ外で得たいときには$~を使って束縛情報を持ち
- 出す必要がある.
-
-Thu Oct 12 00:33:33 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * re.c (reg_search): String:split, String:indexでは$&, $1...が変化
- しないようにした.
-
- * io.c (rb_str_setter): setterの仕様が変更になっていた.
-
- * variable.c (f_trace_var): 第2引数を省略してイテレータとして呼べ
- るように.
-
-Wed Oct 11 11:50:59 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.91
-
- * variable.c (var_setter): 引数が間違っていた.致命的バグ.
-
- * io.c (pipe_open): $stderrの値が変更されている時にはそちらを
- 子プロセスのstderrに設定する.
-
-Mon Oct 9 13:06:33 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * object.c (mod_to_s): モジュール内のモジュールは`::'を使った表現
- で表示されるように.
-
- * variable.c (rb_gvar_set): 代入によるループが発生しないように,
- trace内での代入ではtraceを評価しない.
-
- * struct.c (struct_equal): structのequal判定にクラスの一致を含めた.
-
-Sat Oct 7 00:18:32 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_eval): defined?の機能を拡張(yieldのチェック,superの
- 存在など).
-
-Fri Oct 6 12:06:47 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.90
-
- * st.c (st_foreach): 要素を削除した時に要素数が変化していなかった.
-
- * hash.c (hash_values): バグ修正.keysを返していた….
-
- * parse.y (call_op): defined? の引数では定数の畳み込みを行わない
- (チェックする前にコンパイルエラーになっては困る).
-
- * スコープ生成の一部見直し.
-
-Thu Oct 5 00:29:43 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * 関数とクラスの命名規則を変更した.関数名,変数名の全面書き換え.
-
- * gc.c (looks_pointerp): ヒープチェックの高速化.
-
- * struct.c (Fstruct_aset): 構造体に対する`[]='.
- (struct_set): 構造体メンバに対する代入.
-
-Wed Oct 4 09:54:07 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.89
-
- * eval.c (Frequire): ダイナミックロードのエラーチェックを厳しく.
-
- * struct.c: structの構造を完全に書き換えた.以前は順序付きの
- id->valueの連想配列であったが,今度は構造体毎に新しいクラスを生
- 成するようにした.
-
- * parse.y: `::'の意味をAssocの生成からクラス(モジュール)内の定数ア
- クセスへ変更.
-
- * assoc.c: なくす.
-
-Tue Oct 3 13:31:08 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * variable.c (Ftrace_var): trace_var, 大域変数への書き込みhookを設
- 定する.
-
- * variable.c: global_entryの構成を書き換えた.これでtrace_varを実
- 装できる.
-
- * file.c (Ffile_stat): "&"で直前のfstatの結果も参照できるように.
-
-Fri Sep 29 14:15:13 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.88
-
- * dln.c (dln_load): AIXとHPに対応したコードを入れた(動作は未確認).
-
- * ext/extmk.rb.in: 必要に応じて,定数EXTLIBを定義するように.
-
- * dln.c (dln_load): dln独立に書き換える.将来の拡張用.
- (load_1): dln_a_outにおいてソースコードでライブラリを明示的にロー
- ドする必要がないように変更した.
-
-Thu Sep 28 13:31:37 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/ruby-mode.el: もっとましなhilit19対応(正規表現).
-
-Wed Sep 27 04:12:44 1995 Takahasi Mamoru <taka@soum.co.jp>
-
- * sample/test.rb: echoで-nを使わないように(SysV対策).
-
- * ext/extmk.rb.in: sub -> sub!
-
-Tue Sep 26 19:12:42 1995 Yasuo OHBA <jammy@csg.mes.co.jp>
-
- * dln.c (dln_find_1): `.', `..'から始まるパスに対応した.
-
-Mon Sep 25 12:33:03 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.87
-
-Sat Sep 23 10:00:18 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (Fmod_modfunc): メソッドをprivateにし,同時に特異メソッド
- も定義するメソッド.パッケージ的使い方のモジュール用.
-
-Fri Sep 22 11:02:44 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * lib/find.rb: findを提供するライブラリ
-
- * variable.c (rb_define_variable): hookの設定を分離.
- (add_hook): 1変数に対して複数のhookを設定できるように.
-
-Thu Sep 21 00:22:11 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (Fstr_frozen): 文字列が更新不可かどうかをチェックする述
- 語メソッド.
-
- * hash.c (Fhash_aset): keyが文字列の時,キーの内容が変化しないよう
- に,dupしてfreezeする.
-
-Wed Sep 20 16:12:44 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.86
-
- * ext/extmk.rb.in (have_header): キャッシュにバグ.
-
- * ext/extmk.rb.in (have_library): 引数の順序が変わった.
-
-Thu Sep 14 18:00:59 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * object.c (obj_is_instance_of): is_member_ofから名称変更.
-
- Wed Sep 13 15:44:35 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (Fstr_tr_bang): 範囲外の文字に対する変換バグ.
-
-Tue Sep 12 14:27:58 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (Sfile_expand_path): expand_file_name -> expand_pathに名
- 称変更.
-
- * enum.c (Fenum_member): includes? -> member? に名称変更.
-
- * string.c (Fstr_each_byte): StringはByteArrayであるという基本に戻っ
- て,eachの定義をeach_byteに変更した.今までのeachはeach_lineでア
- クセスできる.
-
-Mon Sep 11 18:31:17 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (cache_stat): ファイル名として"&"を指定すると直前の
- stat(2)の結果を再利用するように.
-
-Fri Sep 8 14:18:51 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ruby.texi: `!', `?'に対応してアップデート.
-
- * parse.y: defined -> defined?
-
- * file.c: FileOpの一文字メソッドをなくす.一文字テストはtestメソッ
- ドにまかせる.
-
- * parse.y (yylex): 変数名の後ろに`?'も許す.述語メソッドの後ろに
- `?'を追加する.
-
-Thu Sep 7 20:01:33 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c: 文字列の中身を更新するメソッドの名前の終りに`!'を付加.
- `!'の無いバージョンも用意した.
-
- * parse.y: 変数名の後ろに`!'を許す.
-
-Wed Sep 6 14:12:19 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.85
-
- * string.c (Fstr_dup): 文字列の複製を作る
- (Fstr_freeze): 文字列の更新不可属性を設定できるように.
- (Fsub/Fgsub): $_の内容をdupしてから置換を行うように.
-
- * ruby.h (CLONESETUP): flagsの状態もコピー
-
-Tue Sep 5 01:27:50 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * sample/test.rb: 失敗の検出を厳しく.
-
-Fri Aug 25 14:31:02 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * process.c (Ffork): イテレータとしても動作するように.
-
- * version 0.84
-
- * signal.c (sig_beg): ハンドラが設定されている時には再設定しない.
-
- * ext/extmk.rb.in (create_makefile): shared objectのリンクの際に
- `-l'オプションを指定するように.
-
- * signal.c (trap): `EXIT'で終了処理を行う設定が出来る.
-
-Wed Aug 16 00:13:22 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * signal.c (sig_beg): デフォルトではbegin節の中でだけSIGINTを捕捉
- するように変更.
-
- * io.c (io_ctl): fcntlを持たないシステムにも対応.
-
- * 各ディレクトリに分散していたMANIFESTをまとめた.拡張モジュール毎
- には必要.
-
- * string.c (Sstr_new,str_sub,Fstr_crypt): 引数を自動的に文字列に変
- 換するように.
-
-Sat Aug 12 00:44:02 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * string.c (Fstr_crypt): PD cryptを用意した.
-
-Fri Aug 11 14:37:03 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * assoc.c (Fassoc_clone): assocもcloneできるように.
-
- * io.c: マクロREAD_DATA_PENDINGの定義を変更(Linux対応)
-
- * io.c (io_fptr_finalize): fptrの開放時の処理を指定できるように.
-
-Wed Aug 9 16:52:41 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * eval.c (rb_provided): 複数のfeatureをロードすると無限ループに落
- ちるという単純な(しかし凶悪な)ミス.
-
- * ext/extmk.rb.in (install): dlopen対応を行った.今までdlnにしか十
- 分に対応していなかった.
-
-Tue Aug 8 14:17:06 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.83
-
-Mon Aug 7 12:47:41 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y: resque -> rescue.恥ずかしいがtypoを残しておくわけには
- いかないよなあ.なんで今まで気がつかなかったのか….
-
-Thu Aug 3 18:18:05 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * missing/nt.c: NT移植用の関数群をまとめた.
-
- * variable.c (rb_const_get): また例外を発生するようにした.defined
- がある以上例外を発生させない理由がないので(例外が発生した方がタ
- イプミスの検出などの点で有利).
-
- * variable.c (Fautoload): autoloadを実装.今度は使えるか.
-
-Mon Jul 31 15:44:21 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (arg_ambiguous): 第1引数のあいまいさを警告(-vオプション
- で有効).
-
- * eval.c (rb_eval): `-v'オプションをつけて`def'が呼ばれると不必要
- なエラーメッセージが出た.
-
- * parse.y (yylex): メソッドの第1引数の判定をもうちょっと賢くした.
-
-Fri Jul 28 19:04:43 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * parse.y (yylex): `+/-/['の直前に空白が来るかどうかで動作を変更し
- た(混乱のもとか?)
-
-Wed Jul 26 09:21:23 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.82a
-
- * sprintf.c (Fsprintf): `%s'で'\0'を含む文字列に対応.
-
- * pack.c (Fpck_pack): packの要素確保のバグ.
-
- * eval.c (Floop): 無限ループのイテレータ.
-
- * io.c (next_argv): 存在しないファイル名が指定された時のエラー処理
- が行われていなかった.
-
-Mon Jul 24 17:37:34 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.82
-
- * ext/extmk.rb.in (install): 拡張モジュールをstatic linkする場合は
- そのモジュールが既にrequireされたのと同じようにfeatureを設定する.
- これで拡張モジュールの機能が必要な時には(static linkされているか
- どうかにかかわらず)requireすればよくなる.
-
- * eval.c (Frequire): `$"'に格納する文字列をフルパスでなくフィーチャ
- 名とする.rubyスクリプトをロードした時には`.rb',オブジェクトを
- ロードした時には`.o'をフィーチャ名に付加する.lispのrequireと
- provideの働きに(少し)近い.
-
-Thu Jul 20 12:50:05 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * Makefile.in (test): make testができるように.
-
- * struct.c (struct_new): typo.
-
- * eval.c (rb_eval): `defined'を追加.メソッド/変数/定数の定義状態
- を知る事が出来る.
-
-Wed Jul 19 18:04:01 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.81
-
-Mon Jul 17 14:53:51 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * variable.c (rb_const_get): 未初期化のCONSTANTの値をnilにした.し
- かし,今後また例外に戻す可能性はある.要はoptionalなクラス/モジュー
- ルが存在するかチェックしたいだけなんだな.
-
- * st.c (int): grow_factorを固定にした(大嶋さんのマシンに対応).
-
-Fri Jul 14 00:48:40 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * ext/extmk.rb.in: キャッシュのバグを修正.
-
- * parse.y (var_extend): #{$数字}に対応した.
-
- * dln.c (dln_load_1): `Init_FILENAME'だけを有効に.`init_*'は今後
- 実行しない.
-
- * ext/etc/etc.c : Etcモジュールを拡張モジュールとして分離.実はNT
- 対応への布石だったりするかもしれない.
-
-Tue Jul 11 17:12:48 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * gcc -Wallで出たwarningを元にソースを変更.
-
- * signal.c (trap): typo.
-
-Fri Jul 7 10:08:51 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * version 0.80
-
- * ruby.texi: texinfo documentを提供.specとruby.1は無くなった.
-
- * signal.c (Ftrap): 割込み禁止中の例外発生に対応.
-
- * eval.c (Flambda): Blockオブジェクトを返す.Block.newと同義.
-
-Thu Jul 6 00:35:03 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * signal.c (Ftrap): SIG_DFLの処理を変更.SIGINTへのデフォルトハン
- ドラを用意(例外を発生する).
-
- * file.c (Sfile_expand_fname): パス名を絶対パスに展開するメソッド.
- (Sfile_basename): basenameを得るメソッド.拡張子も外せる.
- (Sfile_dirname): basenameの反対.
-
- * eval.c (rb_call): argument評価中の例外発生に対応.
-
- * file.c (Ftest): `M', `A', `C'を追加.
-
-Tue Jul 4 12:36:33 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
-
- * file.c (Ftest): ファイルテスト用メソッド.
-
- * ruby.c (proc_options): `-r'オプションを追加.
-
- * parse.y (f_args): デフォルト引数を追加.
-
- * eval.c (rb_call): 該当する引数が無い時,rest引数の値をnilに.
-
- * numeric.c (num_equal): 数値以外との比較で例外が発生していた.
- FALSEを返すように.
-
- * eval.c (masign): 多重代入のrest部の動作がおかしかった.
+ * parse.y (tokadd): token buffer overrun.
-Sat Jun 17 01:03:16 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * ruby.c (ruby_prog_init): forgot to protect rb_argv0 from gc.
- * parse.y (gettable): 未初期化のローカル変数の参照(独立した識別子)
- は正式にメソッド呼び出しとした.
+ * eval.c (ruby_run): call finalizers at process termination.
- * parse.y (read_escape): tokenbufを使わないように修正.それにとも
- ない,`\C-x',`\M-x'などのエスケープ表現を復活.これでドキュメン
- トと実際の処理系が一致した.
+ * gc.c (gc_call_finalizer_at_exit): call free proc for every Data
+ Wrapper, and finalizer for specified objects at termination.
-Thu Jun 15 15:42:00 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * version.c (show_version): version format changed.
- * re.c (re_regcomp): cacheのチェックを改善.
+ * regex.c (re_match): wrong match with non-greedy if they appear
+ more than once in regular expressions.
-Mon Jun 12 18:50:51 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * sample/ruby-mode.el (ruby-expr-beg): forgot to handle modifiers.
- * version 0.79
+Mon Dec 8 19:00:15 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Sat Jun 10 00:25:01 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * io.c (io_puts): just put a newline if no argument given.
- * re.c (re_regcomp): cache判定に`$='の値も反映させた.
+ * ext/tcltklib/tcltklib.c (lib_mainloop): thread-aware tk handle
+ when $tk_thread_safe is set.
- * sample/test.rb: test suite作成.
+ * ext/tcltklib/tcltklib.c (lib_mainloop): use Tcl_DoOneEvent()
+ instead of Tk_MainLoop().
-Fri Jun 9 15:58:34 1995 Yukihiro Matsumoto <matz@ix-02>
+Mon Dec 6 07:11:16 1997 MAEDA shugo <shugo@po.aianet.ne.jp>
- * re.c (re_regcomp): cacheの判定が間違っていた.
+ * io.c (io_puts): core dumped without any argument.
-Fri Jun 9 00:01:35 1995 Yukihiro Matsumoto (matz@dyna)
+Fri Dec 5 18:17:17 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c (rb_yield): block構造体に初期化していないメンバ(iter)があっ
- たのでイテレータのネストが正しく動作しなかった.
+ * eval.c (mod_remove_method): remove (not undef) a method from the
+ class/module.
-Thu Jun 8 00:59:03 1995 Yukihiro Matsumoto (matz@dyna)
+ * variable.c (obj_remove_instance_variable): method to remove
+ instance variables.
- * re.c (=~): String以外との比較がFALSEを返すように(例外を発生して
- いた).
+Thu Dec 4 13:50:29 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * extmk.rb.in: 判定した値をファイルにキャッシュするようにした.
+ * version 1.1b0 released.
- * assoc.c (to_a): to_aメソッドが再定義されていなかった.
-
- * eval.c (rb_eval): 初期化されていないローカル変数へのアクセスを引
- 数の無いメソッド呼び出しと解釈する.ただし,(現状では)メソッドが
- 定義されていない場合,エラーにせず変数未初期化のwaringを出して
- nilを返している.「ruby -pe print」などが実行できるという意味で
- はありがたいこの仕様は,しかし今後の検討が必要である.-- メソッ
- ド呼び出しとするのを止めるか(以前の仕様),いつもメソッド呼び出し
- とする(未定義ならばエラー)か,今の仕様で行くか.
+ * string.c (str_aref): called str_index for regexp.
- * eval.c (rb_eval): 初期化されていないローカル変数へのアクセスで
- (evalなどで)初期化された事が分かった時には以後初期化されたローカ
- ル変数とみなす.
+Mon Dec 1 15:24:41 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Wed Jun 7 11:58:12 1995 Yukihiro Matsumoto <matz@ix-02>
+ * compar.c (cmp_between): wrong comparison made.
- * eval.c (rb_fail): 例外処理後も`$!'をクリアしないように.
- (rb_fail): `$!'変数に最後に改行を追加しない.
+Wed Nov 26 18:18:05 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * io.c (Fprint): privateメソッドに変更.引数を取らない時の動作を変
- 更(`$_'を出力する).
- (Fio_print): 出力先指定のprintメソッド.
- (Fio_printf): 出力先指定のprintfメソッド.
+ * lib/mkmf.rb: generate Makefile for extention modules out of ruby
+ source tree. use like `ruby -r mkmf extconf.rb'.
- * parse.y: not演算子の追加.優先順位の低い`!'演算子.
+ * numeric.c (fix2str): enlarge buffer to prevent overflow on some
+ machines.
-Mon Jun 5 19:00:55 1995 Yukihiro Matsumoto <matz@ix-02>
+ * parse.y (here_document): wrong line number generated after here-doc.
- * version 0.78
+Fri Nov 21 13:17:12 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Fri Jun 2 17:52:03 1995 Yukihiro Matsumoto <matz@ix-02>
+ * parse.y (yylex): skip multibyte characters in comments.
- * ruby.c (proc_options): -Iオプションで`$:'への追加される順番を修
- 正した.
+Wed Nov 19 17:19:20 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Fri Jun 2 00:36:34 1995 Yukihiro Matsumoto (matz@dyna)
+ * object.c (nil_to_a): nil.to_a => [].
- * parse.y: while修飾子の動作を通常のwhileと同じにした.ただし,
- begin式へのwhile修飾子だけはdo..while型のループとなる.
+ * parse.y (call_args): wrong node generation.
-Wed May 31 18:36:30 1995 Yukihiro Matsumoto <matz@ix-02>
+Tue Nov 18 10:13:08 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * version 0.77
+ * array.c (Init_Array): Array#=== works as Array#include?
-Mon May 29 18:39:37 1995 Yukihiro Matsumoto <matz@ix-02>
+ * regex.c (re_compile_pattern): insert initialize code for jump_n,
+ before entering loops.
- * ext/extmk.rb.in (install): 拡張モジュールもインストールできるよ
- うに.
+ * re.c (reg_search): does not save registers unless $& etc appear
+ in the script.
-Fri May 26 14:43:01 1995 Yukihiro Matsumoto <matz@ix-02>
+Mon Nov 17 13:01:43 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * process.c (Fsystem): 戻り値をサブプロセスの失敗/成功を表す真偽値
- にした.終了ステータスは`$?'で得る.
+ * eval.c (is_defined): add defined? check for receivers and
+ arguments for calls.
-Tue May 23 10:58:11 1995 Yukihiro Matsumoto <matz@ix-02>
+ * re.c (reg_search): cache last match object.
- * string.c (Fstr_upto): 無限ループに陥らないように.
+ * re.c (match_aref): $[0] etc. are available.
- * parse.y (cond): `||'などの右辺に制御式が書けるように,条件式がか
- ならずしも値を持たなくても良いようにした.
+Sat Nov 15 00:11:36 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * ext/marshal/marshal.c: オブジェクトの読み書きをメソッドの再定義
- でコントロールできるように.インスタンスが`_dump_to'というメソッ
- ドを定義している時はそちらを使うように.
+ * io.c (io_s_popen): "rb" detection
- * ext/extmk.rb.in: static linkも設定できるような仕様にした.
- ext/Setupというファイルにディレクトリ名を記述するとそのディレク
- トリに存在するモジュールはstatic linkされる(はず).
+Fri Nov 14 18:28:40 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c (rb_eval): `..'を文法に組み込み,`..'と`...'の動作をperl
- に合わせた.
+ * string.c (scan_once): returns whole match if the pattern does
+ not contain any parentheses.
-Sat May 20 01:22:48 1995 Yukihiro Matsumoto (matz@dyna)
+Thu Nov 13 14:39:06 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * io.c (select): timeout時と割込み時の動作の明確化.
+ * string.c (str_sub): returns copy of the receiver string, even if
+ any substitution occurred.
-Fri May 19 15:33:23 1995 Yukihiro Matsumoto <matz@ix-02>
+ * regex.c (re_compile_pattern): no-width match by (?=..), (?!..).
- * version 0.76
+Wed Nov 12 13:44:47 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Fri May 19 00:48:08 1995 Yukihiro Matsumoto (matz@dyna)
+ * time.c: remove coerce from Time class.
- * string.c (Fstr_each): イテレータブロック中で文字列の変更が行われ
- たかどうかをチェック.ポインタの値が変わっていれば例外を発生する.
+ * regex.c (re_match): non-greedy match by ??, *? +?, {n,m}?.
- * ruby-mode.el: ruby-electric-braceの新設.
+Mon Nov 10 11:24:51 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Thu May 18 12:27:23 1995 Yukihiro Matsumoto <matz@ix-02>
+ * regex.c (re_compile_pattern): non-resitering parens (?:..).
- * string.c (Fstr_tr): trの置換対象に`\0'を含む時に正しく置換を行わ
- ないバグがあった.更に置換文字列をASCII順に指定しないと動作しな
- い問題もあった.結果としてtrを書き換えたので,copyrightの問題は
- 無くなった(と思う).
+ * regex.c (re_compile_pattern): new meta character \< (wordbeg)
+ and \> (wordend).
- * gc.c (gc): the_scopeをマークしていなかったので,ローカル変数の指
- しているオブジェクトが間違って開放される場合があった.
+ * regex.c (re_compile_pattern): embedded comment for regular
+ expression by (?#...).
- * gc.c (mark_locations_array): 若干の高速化.
+Fri Nov 7 16:58:24 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Mon May 15 11:43:49 1995 Yukihiro Matsumoto <matz@ix-02>
+ * regex.c (re_compile_pattern): perl5 regxp \A and \Z available.
- * ext/extmk.rb.in: Dynamic Loadモジュールのコンパイル用チェックを
- 行うruby script.autoconfに近い感覚で使える.新しいモジュールを
- 提供したい人はextの下にディレクトリを作るだけで良い.必須のファ
- イルはファイル名の一覧を記録した`MANIFEST'というファイルのみ.必
- 要に応じて`depend'(ファイルの依存関係を記述するファイル gcc -MM
- の出力),`extconf.rb'(コンパイル用にライブラリと関数の存在チェッ
- クするファイル)を用意できる.
+ * regex.c (re_compile_pattern): can expand compile stack dynamically.
- * eval.c (rb_call): rubyメソッドの引数チェック時に未初期化の
- jmp_bufを使用していた.
+ * regex.c (PUSH_FAILURE_POINT): wrong compare condition.
- * parse.y: `or'と`and'の優先順位を同じにした.
+Wed Nov 2 16:00:00 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-Wed May 3 18:21:36 1995 Yukihiro Matsumoto (matz@dyna)
+ * string.c (str_sub_s): "".sub! "", "" => "\000"
- * dln.c: Linuxでは`__.SYMDEF/'であった.
+Fri Oct 31 15:52:10 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * dln.c: system callのエラーチェックを忘れていた.
+ * parse.y (assoc): keyword assoc like {fg->"black"}.
-Wed Apr 26 09:50:56 1995 Yukihiro Matsumoto (matz@ix-02)
+Thu Oct 30 17:33:38 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * parse.y: イテレータブロックの変数宣言を`|'で括るようにした.これ
- でイテレータ変数がない時は宣言そのものを省略できる.文法の変更は
- 久しぶりだ.
+ * io.c (io_println): print with newline, which is not affected by
+ the values of $/ and $\.
-Tue Apr 25 12:04:17 1995 Yukihiro Matsumoto (matz@ix-02)
+Thu Oct 30 16:54:01 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * eval.c(require): loadからダイナミックロードの機能を移してきた.
- さらに拡張子の補完機能を追加してユーザがdln/dlopenの差を意識する
- 必要のないようにした.
+ * string.c (str_chop_bang): "".chop caused SEGV.
- * string.c(sub,sub): イテレータとしても動作するように.
+ * string.c (str_chomp_bang): method to chop out last newline.
- * object.c: init_object -> initialize.
+Mon Oct 27 13:49:13 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Mon Apr 24 14:22:39 1995 Yukihiro Matsumoto (matz@ix-02)
+ * ext/extmk.rb.in: library may have pathname contains `.'
- * NEWS-OS 3.4対応
+ * eval.c (rb_rescue): should not protect SystemError.
- * io.c: Solarisのstdioの動作が違うようだ.signalでEOFを返してしま
- う….perlでも同様の問題がある.
+Fri Oct 24 10:58:53 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Fri Apr 21 20:04:39 1995 Yukihiro Matsumoto (matz@ix-02)
+ * io.c (io_s_with_open_stream): ensures to close stream.
- * version 0.75
+Thu Oct 23 11:17:44 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * signal.c: trapがなくなっていた.うーむ.
+ * io.c (io_errset): value of $stderr can be changed (to any IO
+ object).
- * configure: Solaris 2.3対応.
+ * io.c (next_argv): $< can be anything that responds to `write'.
- * io.c: #elifのないcppもある.
+ * file.c (file_s_with_open_file): ensures to close file.
- * dir.c: autoconf 2.xへの対応が不十分
+ * error.c (exception): create error under the current class/module.
-Thu Apr 20 12:31:24 1995 Yukihiro Matsumoto (matz@ix-02)
+ * range.c (range_eqq): fixnum check for last needed too.
- * version 0.74
+Wed Oct 22 12:52:30 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * env.h, gc.c, regex.c: IRIXへの移植対応
+ * ext/socket/socket.c: Socket::Constants added.
- * configure: dlopen用にpicを生成するoptionの検出のため,システムタ
- イプをチェックするように.
+ * file.c: File::Constants added for inclusion.
-Tue Apr 18 19:08:17 1995 Yukihiro Matsumoto (matz@ix-02)
+ * array.c (ary_join): call ary_join() recursively for the 1st
+ array element.
- * gc.c(xrealloc): ptr=nilの時,malloc()と同じ働きを
+Mon Oct 20 12:18:29 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * array.c(astore): 空の配列の0番目の要素に代入するとsize=0で
- realloc()を呼んでいた.
+ * ruby.c (load_file): wrong condition for #! check with -x.
- * configure, glob.c: Solaris 2.xでコンパイルできるように
+ * file.c (file_s_dirname): did return "" for "/a".
-Mon Apr 10 18:36:06 1995 Yukihiro Matsumoto (matz@ix-02)
+Fri Oct 17 14:29:09 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * version 0.73
+ * ruby.c: now works on alpha-linux.
-Fri Apr 7 13:51:08 1995 Yukihiro Matsumoto (matz@ix-02)
+ * bignum.c (bigadd): some undefined side effect order assumed.
- * cons.c->assoc.c: consの余計な機能は外してpairとしての機能だけを
- 残した.Enumerableをincludeするのもやめた.
+Wed Oct 15 17:49:24 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * string.c(esub): 文字列置換イテレータ.perlのs///eの相当する.
+ * intern.h: function prototypes added.
-Wed Apr 5 11:35:21 1995 Yukihiro Matsumoto (matz@ix-02)
+Mon Oct 13 16:54:18 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * version 0.72
+ * class.c (rb_define_class_id): call superclass's `inherited'
+ method when making subclasses.
- * EWS4800対応
+ * parse.y (nextc): clear lex_lastline at the end of file.
- * file.c: utimesがない時はutimeを使うように.
+ * object.c (Init_Object): need to undef Class#append_features.
-Mon Apr 3 15:19:41 1995 Yukihiro Matsumoto (matz@ix-02)
+ * eval.c (rb_eval): no warning on extending classes or modules.
- * version 0.71
+Thu Oct 9 11:17:50 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * regexp.c(re_match): バグがあった.match_2を削除した時にenbugして
- いたのだった.
+ * eval.c (error_print): the exception name follows after the error
+ message.
-Mon Mar 27 15:41:43 1995 Yukihiro Matsumoto (matz@ix-02)
+ * eval.c (compile_error): error message slightly changed.
- * dict.c: Dict->Hashに全面的に移行.
+ * parse.y (nextc): script parsing will be terminated by __END__ at
+ beginning of line.
-Thu Mar 23 20:30:00 1995 Yukihiro Matsumoto (matz@ix-02)
+ * eval.c (compile_error): `__END__' is no longer a keyword.
- * dbm.c,socket.c: extディレクトリに分離.
+ * parse.y (nextc): protect lastline read from script stream.
- * configure: dln周りのチェックの強化
+Tue Oct 7 14:06:06 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * dln.c: initの呼び出しをdlopen()版に合わせた.
+ * version 1.1 alpha9 released.
-Mon Mar 20 17:45:08 1995 Yukihiro Matsumoto (matz@ix-02)
+ * eval.c (mod_append_features): renamed from extend_class.
- * configure: autoconf 2.2に対応(一部).
+ * eval.c (rb_eval): defining method calls `method_added'.
-Fri Mar 17 15:56:44 1995 Yukihiro Matsumoto (matz@ix-02)
+ * eval.c (ruby_options): exception while processing options must
+ terminate the interpreter.
- * dln.c: dlopenのあるマシンではそちらを使うように.ただし,ちゃん
- と動いているかどうかは自信がない.
+ * error.c (Init_Exception): wrong method configuration. `new'
+ should have been a singleton method.
- * regex.c: virtual concatinationをやめた.
+Mon Oct 6 18:55:38 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Thu Mar 16 11:32:57 1995 Yukihiro Matsumoto (matz@ix-02)
+ * ext/kconv/kconv.c (kconv_guess): code to guess character code
+ from string.
- * version 0.70
+Mon Oct 6 18:38:17 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * eval.c,regex.c: gccでのコンパイルエラー.
+ * pack.c: now encode/decode base64 by `m' template.
- * io.c: inplace-editで拡張子が指定されない場合,もとのファイルを削
- 除する.
+Fri Oct 3 10:51:10 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Wed Mar 15 14:59:18 1995 Yukihiro Matsumoto (matz@ix-02)
+ * MANIFEST: needed to include lex.c in the distribution.
- * version 0.69
+ * eval.c (ruby_options): f_require() called too early.
- * eval.c(method_missing): unknownから名称変更.
+ * eval.c (rb_provide): module extentions should always be `.o'.
- * eval.c(single_method_added): 特異メソッドが定義された時に呼ばれ
- るメソッド.hookとして使える.実際に定義される直前に呼ばれる.
+Thu Oct 2 11:38:31 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Tue Mar 14 14:46:44 1995 Yukihiro Matsumoto (matz@ix-02)
+ * version 1.1 alpha8 released.
- * ruby.c(proc_options): 引数の解析を自分でやることにより引数指定の
- 方法がperlに近付いた.getopt_longはもう使わない.
+ * ext/marshal/marshal.c (r_object): remove temporal regist for
+ structs. (caused problem if structs form cycles.)
- * dir.c(glob): `{}'のネストを許すようにした.
+ * parse.y (match_gen): static binding for match(=~) calls
+ with regexp literals.
-Mon Mar 13 17:56:25 1995 Yukihiro Matsumoto (matz@ix-02)
+Wed Oct 1 15:26:55 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * glob.c: Glob(ワイルドカードオブジェクト)はなくなった.ワイルドカー
- ドの展開はDir.glob(文字列)を使う.ワイルドカードのマッチは正規表
- 現で代用.
+ * eval.c: protect retval in struct tag from GC for C_ALLOCA.
-Fri Mar 10 18:35:46 1995 Yukihiro Matsumoto (matz@ix-02)
+ * eval.c: no more pointer value from setjmp/longjmp.
- * eval.c: Mathのようなモジュールは自分自身でextendする.
+Wed Oct 1 14:01:49 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * eval.c: クラスやモジュールを定義する時,既に同名のものがあれば追
- 加定義となるように.ただし.superクラスの違いなどはチェックする.
+ * ext/marshal/marshal.c (w_byte): argument must be char.
- * regex.c: debug.
+Wed Oct 1 10:30:22 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * math.c: 定数PIとEを定義.
+ * variable.c (mod_const_at): global constants now belongs to the
+ class Object.
-Thu Mar 9 21:35:12 1995 Yukihiro Matsumoto (matz@ix-02)
+ * object.c (Init_Object): new global constant NIL.
- * regex.c: EUC,SJISモードでは0x80以上の8進,16進リテラルを禁止.
+ * ext/marshal/marshal.c (marshal_dump): try to set binmode.
- * regex.c: クラス内でも数値リテラル・文字クラスが使えるようした.
+ * ext/marshal/marshal.c (r_object): forgot to re-regist structs in
+ the object table.
-Wed Mar 8 17:39:05 1995 Yukihiro Matsumoto (matz@ix-02)
+ * eval.c (ruby_options): call Init_ext() before any require()
+ calls by `-r'.
- * regex.c: \200など括弧の数以上の表現は8進リテラルと解釈する.ただ
- し,\1から\9までは例外.
+Fri Sep 30 14:29:22 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * regex.c: \9以上のリファレンスも有効にした.
+ * ext/marshal/marshal.c (w_object): marshal dumped core.
-Tue Mar 7 14:26:01 1995 Yukihiro Matsumoto (matz@ix-02)
+Tue Sep 30 10:27:39 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c(public/private): スコープ制御メソッドの名称変更.静的なア
- クセスも出来るようにしてみたが,不採用.
+ * sample/test.rb: bignum test suits added.
-Mon Mar 6 19:34:32 1995 Yukihiro Matsumoto (matz@ix-02)
+ * eval.c (rb_eval): new pseudo variable `true' and `false'.
- * eval.c(inlcude): メソッド化.動的にモジュールをインクルードでき
- るように.さらに任意のオブジェクトにもモジュールをインクルードで
- きるメソッド `extend'も用意した.
+ * parse.y: new keywords `true' and `false' added.
- * parse.y: 文法からincludeを削除.メソッド化.
+Mon Sep 29 13:37:58 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Tue Feb 28 15:35:10 1995 Yukihiro Matsumoto (matz@ix-02)
+ * ruby.c (forbid_setid): forbid some options in suid mode.
- * parse.y: 配列,連想配列の最後に`,'をおけるように.
+ * ruby.h (NUM2DBL): new macro to convert into doubles.
-Fri Feb 24 13:15:43 1995 Yukihiro Matsumoto (matz@ix-02)
+Mon Sep 27 09:53:48 1997 EGUCHI Osamu <eguchi@shizuokanet.or.jp>
- * version 0.68
+ * bignum.c: modified for speeding.
-Thu Feb 23 11:19:19 1995 Yukihiro Matsumoto (matz@ix-02)
+Fri Sep 26 18:27:59 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * eval.c: resque節のselfの値が間違っていた.
+ * sample/from.rb: some extensions.
- * eval.c(rb_clear_cache): キャッシュのクリアし忘れがあった.
+Mon Sep 29 13:15:56 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c: 定数のスコープをクラス内の静的スコープに変更した.これに
- よって,特異メソッドから参照される定数は,レシーバのクラスではな
- く,定義されたスコープのクラスの定数となる.
+ * parse.y (lhs): no more syntax error on `obj.CONSTANT = value'.
-Wed Feb 22 00:51:38 1995 Yukihiro Matsumoto (matz@dyna)
+Fri Sep 26 14:41:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * regex.c: ignorecaseを正規表現のコンパイル前に指定しないと正しく
- 動作しない.修正.
+ * eval.c (ruby_run): deferred calling Init_ext() just before eval_node.
- * string.c(toupper,tolower): bug fix.
+Fri Sep 26 13:27:24 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
- * ENV,VERSION: readonly変数から定数へ.
+ * io.c (io_isatty): forgot to return TRUE value.
-Tue Feb 21 18:56:56 1995 Yukihiro Matsumoto (matz@ix-02)
+Fri Sep 25 11:10:58 1997 EGUCHI Osamu <eguchi@shizuokanet.or.jp>
- * io.c(STDIN, STDOUT, STDERR): 定数として定義.
+ * eval.c: use _setjmp/_longjmp instead of setjmp/longjmp on some
+ platforms.
- * io.c(select): bug fix.
+Wed Sep 24 17:43:13 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * version 0.67
+ * string.c (Init_String): String#taint and String#taint? added.
-Mon Feb 20 16:10:14 1995 Yukihiro Matsumoto (matz@ix-02)
+ * class.c (mod_ancestors): ancestors include the class itself.
- * parse.y(yylex): 定数を`%識別子'から,第1文字が大文字の識別子に変
- 更.それにともないクラスは定数となった.
+Wed Sep 24 00:57:00 1997 Katsuyuki Okabe <HGC02147@niftyserve.or.jp>
- * eval.c: クラス定義内のselfがクラス定義外部のthe_classだった.
+ * X68000 patch.
- * variable.c(rb_name_class): クラス名をインスタンス変数に格納する.
+Tue Sep 23 20:42:30 1997 EGUCHI Osamu <eguchi@shizuokanet.or.jp>
-Thu Feb 16 15:36:17 1995 Yukihiro Matsumoto (matz@ix-02)
+ * parse.y (node_newnode): SEGV on null node setup.
- * parse.y: BLOCKをbraceで表現する文法に変更したものを作ってみる.
- MLに提示してみるが反応がない.
+Mon Sep 22 11:22:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * object.c(do,forever): なくした.
+ * ruby.c (ruby_prog_init): wrong safe condition check.
-Wed Feb 15 13:20:49 1995 Yukihiro Matsumoto (matz@ix-02)
+Sun Sep 21 14:46:02 1997 MAEDA shugo <shugo@po.aianet.ne.jp>
- * re.c(new): 第2引数が与えられて,かつnilでないときだけ設定するよ
- うに(以前はnilの時にも設定を行なっていた).
+ * error.c (exc_inspect): garbage added to classpath.
- * parse.y(parse_regexp): 正規表現リテラルで大文字小文字を無視する
- かどうか指定できるように.
+Fri Sep 19 11:49:23 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Tue Feb 14 00:55:33 1995 Yukihiro Matsumoto (matz@dyna)
+ * parse.y (newtok): forgot to adjust buffer size when shrinking
+ the token buffer.
- * parse.y: (compexpr) -> (expr).
+ * enum.c (enum_find): rb_eval_cmd() does not return value.
-Fri Feb 10 16:30:00 1995 Yukihiro Matsumoto (matz@ix-02)
+ * io.c (pipe_open): close fds on pipe exec. fcntl(fd, F_SETFD, 1)
+ no longer used.
- * ruby.c(load_file): scriptを読み込む時だけ"#!"の解析を行うように.
+Tue Sep 16 17:54:25 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * ruby.c(readin): ファイル読み込み時に先頭に"#!"があり,その行が
- "ruby"という文字列を含む時,rubyに引数が与えられていれば,その引
- 数も有効になる.
+ * file.c (f_test): problem if wrong command specified.
- * parse.y(yylex): コメント行の終りが`\'であった時,次の行に継続し
- ているとみなすようにした.
+ * ruby.c (ruby_prog_init): close stdaux and stdprn for MSDOS.
-Thu Feb 9 16:18:37 1995 Yukihiro Matsumoto (matz@ix-02)
+ * ruby.c (ruby_prog_init): should not add path from environment
+ variable, if ruby is running under seuid.
- * version 0.66
+ * process.c (init_ids): check suid check for setuid/seteuid etc.
- * parse.y: protectをbeginに変更.begin..endは例外処理だけでなく,
- 文括弧としても働くことになった.
+Mon Sep 15 00:42:04 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-Wed Feb 1 19:48:24 1995 Yukihiro Matsumoto (matz@ix-02)
+ * regex.c (re_compile_pattern): \w{3} and \W{3} did not work.
- * version 0.65
+Thu Sep 11 10:31:48 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * string.c(str_replace): 置き換える文字列の長さが等しい時メモリコ
- ピーをしない.
+ * version 1.1 alpha7 released.
- * string.c(rindex): バグ修正.
+ * ext/socket/socket.c (sock_new): no setbuf() for NT.
-Mon Jan 30 11:23:05 1995 Yukihiro Matsumoto (matz@ix-02)
+ * io.c (rb_fopen,rb_fdopen): set close-on-exec for every fd.
- * parse.y(value_expr): ifのチェックを追加.
+Wed Sep 10 15:55:31 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * gc.c(gc_mark): free cellの扱いにバグ.
+ * ext/marshal/marshal.c (r_bytes0): extra big length check.
- * parse.y: 文法の変更(よりシンプルに).例外を減らした.
+Tue Sep 9 16:27:14 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Thu Jan 26 00:52:55 1995 Yukihiro Matsumoto (matz@dyna)
+ * io.c (pipe_fptr_atexit): clean up popen()'ed fptr.
- * parse.y: 引数として連想配列を置くことができるように.この場合,
- 連想配列リテラルが最終引数となる.
+ * error.c (set_syserr): some system has error code that is bigger
+ than sys_nerr. grrr.
- * parse.y: 配列参照の`[]'内が空でもよいことにした.
+Mon Sep 8 18:33:33 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Tue Jan 24 14:45:15 1995 Yukihiro Matsumoto (matz@ix-02)
+ * io.c (io_s_new): dereferenced nil for optional mode.
- * class.c(rb_include_module): `-v'を指定した時にはincludeしたモジュー
- ルとクラス定数が衝突していないかチェックする.
+Fri Sep 5 10:26:03 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Mon Jan 23 10:42:09 1995 Yukihiro Matsumoto (matz@ix-02)
+ * class.c (class_instance_methods): do not include methods which
+ are changed to private in subclasses.
- * parse.y(rb_class2name): メタクラスに関するbug fix.
+Thu Sep 4 12:38:53 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * dict.c: Dict[..]で辞書の生成が出来るように.
+ * variable.c (f_global_variables): list name of the global
+ variables.
- * array.c: Array[..]で配列の生成が出来るように.
+ * object.c (obj_id): returns unique integer.
- * parse.y: 辞書の表現として{a,b,..}という形式も許すように.
+Wed Sep 3 14:05:16 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Fri Jan 20 10:28:38 1995 Yukihiro Matsumoto (matz@ix-02)
+ * version 1.1 alpha6 released.
- * re.c(Regexp.quote): 正規表現をエスケープするメソッド.
+ * eval.c (mod_s_constants): context sensitive constant list.
- * 無駄なrb_intern()を減らした.
+ * variable.c (mod_constants): no more `all' option.
- * parse.y: `!', `!=', `!~'を特殊演算子にする.よってこれらは再定義
- できなくなった.
+ * variable.c (mod_const_of): the values for autoload classes are
+ their name strings.
-Wed Jan 18 13:20:41 1995 Yukihiro Matsumoto (matz@ix-02)
+ * class.c (class_instance_methods): no special treatment for
+ singleton classes.
- * parse.y: 文法の整理(unless,untilをなくした).
+ * object.c (obj_singleton_methods): returns list of singleton
+ method names.
-Tue Jan 17 11:11:27 1995 Yukihiro Matsumoto (matz@ix-02)
+ * parse.y (yylex): no here document after `class' keyword.
- * eval.c: defでメソッド再定義時にはスーパークラスのメソッドの可視
- 性を継承する.最初の定義の時は今までと同じデフォルト(トップレベ
- ルで関数的,クラス定義内で通常メソッド).
+ * eval.c (f_load): expand path if fname begins with `~'.
- * object.c(Class#new): オブジェクトの生成時に関数的メソッド
- init_objectが必ず呼ばれるように変更.
+Tue Sep 2 13:19:48 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c: 未定義のメソッドに対してunknownメソッドが呼ばれるように
- なった.エラー表示が今までと同じになるようにenvを調節している.
+ * class.c (ins_methods_i): do not list undef'ed methods.
-Fri Jan 13 14:40:30 1995 Yukihiro Matsumoto (matz@ix-02)
+Mon Sep 1 13:42:48 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * gc.c: gcを若干書き換えて整理した.が,あまり変化はなかったようだ.
+ * version 1.1 alpha5 released.
- * parse.y(yylex): symbolを\symから:symに変更した.
+ * object.c (mod_attr_reader): create methods to define attribute
+ reader/write/accessor.
-Thu Jan 12 01:39:28 1995 Yukihiro Matsumoto (matz@dyna)
+ * class.c (rb_define_attr): always defines accessors.
- * eval.c: 新規関数 rb_eval_string().
+ * eval.c (rb_call): alias occured in the module body caused SEGV.
- * gc.c: gc_mark()を一部非再帰化.
+ * parse.y: did not generate here document strings properly.
- * variable.c(rb_ivar_{get,set}): インスタンス変数のアクセス周りで
- チェックが足りなかった.
+Mon Sep 1 11:43:57 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
+
+ * parse.y (yylex): heredoc dropped an extra character.
- * variable.c: クラス定数とインスタンス変数でハッシュテーブルを共有
- するようにした.
+Fri Aug 29 11:10:21 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * ruby.h: iv_tblをRBasicからRObjectとRClassへ移動した.これにより,
- ObjectとClass,Moduleしかインスタンス変数を持てなくなる.が,メモ
- リ効率は若干向上する.
+ * class.c (class_instance_methods): same method names should not
+ appear more than twice.
-Tue Jan 10 00:58:20 1995 Yukihiro Matsumoto (matz@dyna)
+ * parse.y (yylex): spaces can follow =begin/=end.
- * 0.64 released
+ * variable.c (find_class_path): look for class_tbl also for
+ unnamed fundamental classes, such as Object, String, etc.
- * eval.c: レシーバと引数は常にiterではない.
+ * variable.c (rb_name_class): can't name class before String class
+ is initilialized.
- * cons.c(aref,aset): negative offset対応.
+ * inits.c (rb_call_inits): unrecognized dependency from GC to
+ Array.
-Mon Jan 9 14:40:39 1995 Yukihiro Matsumoto (matz@ix-02)
+ * variable.c (find_class_path): could not find class if Object's
+ iv_tbl is NULL.
- * parse.y: foo{..}の形式において,fooをローカル変数やクラス名では
- なく,引数なしの関数型メソッド呼び出しとみなすようにした.
+Thu Aug 28 13:12:05 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * list.c -> cons.c: 名称変更(クラス名も).
+ * version 1.1 alpha4 released.
- * list.c: a::b::c::nilをリスト(a b c)とみなすlisp形式から,a::b::c
- をリスト(a b c)とみなすruby形式に変更.[], []=, eachもそれに会わ
- せた仕様とする.
+ * variable.c (mod_constants): wrong condition for singleton
+ class.
- * list.c: consペアとしての機能を強調.仕様変更.
+ * parse.y (yylex): revised `=begin' skip code.
-Sat Jan 7 01:26:26 1995 Yukihiro Matsumoto (matz@dyna)
+ * parse.y (here_document): forgot to free(eos).
- * eval.c: 自己代入の不具合修正.
+ * parse.y (yylex): spaces after `<<' prohibited for here
+ documents to avoid confusing with operator `<<'.
- * eval.c(masign): 多重代入が配列もリストもとれるようにした.
+ * eval.c (is_defined): separated from rb_eval().
- * list.c: assocを2要素の配列からList(CONSペア)に変更した.
+Wed Aug 27 11:32:42 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Fri Jan 6 13:42:12 1995 Yukihiro Matsumoto (matz@ix-02)
+ * version 1.1 alpha3 released.
- * parse.y: a[b]+=cやa.b+=cなどの自己代入形式で,aやbを2度評価しな
- くなった.
+ * variable.c (mod_name): returns name of the class/module.
- * eval.c: iterator設定のバグフィックス.
+ * parse.y (here_document): finally here document available now.
- * list.c: Listクラスを新設.
+ * variable.c (fc_i): some classes/modules does not have iv_tbl.
-Thu Jan 5 13:55:00 1995 Yukihiro Matsumoto (matz@ix-02)
+ * variable.c (find_class_path): avoid inifinite loop.
- * parse.y: SCOPEのメモリリークをなくした.
+Tue Aug 26 13:43:47 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c: built-inメソッドへの引数の引き渡し方を変更して,配列の生
- 成数を減らした.
+ * eval.c (rb_eval): undef'ing non-existing method will raise
+ NameError exception.
- * re.c: match-dataを毎回生成することをやめた.`$~'をアクセスした時
- にon-demandで生成する.
+ * object.c (class_s_new): needed to create metaclass too.
- * string.c etc: 不必要なmemmoveをmemcpyに置換.
+ * eval.c (error_print): no class name print for anonymous class.
- * parse.y: =~, !~は副作用があるのでコンパイル時に展開できない.
+ * eval.c (rb_longjmp): proper exception raised if raise() called
+ without arguments, with $! or $@ set.
-Tue Jan 3 02:04:36 1995 Yukihiro Matsumoto (matz@dyna)
+ * object.c (Init_Object): superclass()'s method argument setting
+ was wrong again.
- * eval.c: rest引数のbug fix.
+ * class.c (mod_anscestors): list superclasses and included modules
+ in priority order.
- * eval.c,gc.c: scopeをオブジェクトにした.
+Mon Aug 25 11:53:11 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c: envとscopeの扱いを変更した.
+ * version 1.1 alpha2 released.
-Wed Dec 28 09:46:57 1994 Yukihiro Matsumoto (matz@ix-02)
+ * sample/ruby-mode.el (ruby-parse-region): auto-indent now
+ supports "\\" in the strings.
- * parse.y: evalでローカル変数が追加された場合に対応した.
+ * struct.c (struct_getmember): new API to get member value from C
+ language side.
- * parse.y: 演算子を含むaliasのbug fix.
+Sat Aug 23 21:39:05 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Tue Dec 27 16:45:20 1994 Yukihiro Matsumoto (matz@ix-02)
+ * parse.y (asignable): remove unnecessary local variable
+ initialize by nil.
- * parse.y: def A Bをalias A Bに変更.
+Fri Aug 22 14:26:40 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c: alias関係のbug修正.nodeをオブジェクト化した時にenbugし
- たようだ.
+ * eval.c (error_print): modified exception print format.
- * signal.c: システムコールの再定義を止めた.
+Thu Aug 21 16:10:58 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * io.c(select): write/exceptのフラグ設定にバグ.
+ * sample/ruby-mode.el (ruby-calculate-indent): wrong indent level
+ calculated with keyword operators.
- * Makefile.in: static link用オプションをMake変数として独立させた.
+Thu Aug 21 11:36:58 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-Tue Dec 20 00:46:19 1994 Yukihiro Matsumoto (matz@dyna)
+ * parse.y (arg): ary[0] += 1 cause SEGV
- * 0.63 released
+Wed Aug 20 17:28:50 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c(rb_call): superの呼び出しで落ちる.argc, argvの設定を忘れ
- ていた.
+ * ruby.c (ruby_process_options): require() all modules after
+ processing all options
- * parse.y(read_escape): 展開エラー.
+ * process.c (rb_proc_exec): more security checks added.
- * variable.c: 定義済みの変数のhookを変更しないように.
+ * process.c (rb_proc_exec): insecure path on exec.
-Mon Dec 19 12:01:10 1994 Yukihiro Matsumoto (matz@ix-02)
+ * hash.c (f_getenv): PATH modification security check.
- * parse.y(cond): 条件式に代入式が置かれた場合,`-v'オプションで警
- 告が出るように.
+Tue Aug 19 00:15:38 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * parse.y(**): 冪乗演算子`**'の優先順位を単項演算子より高くした.
+ * version 1.1 alpha1 released.
- * parse.y(and,or): 優先順位の低い演算子`and', `or'.
+ * eval.c (mod_eval): work as normal eval() if second binding
+ argument given.
- * 0.62 released.
+ * eval.c (rb_call): did not raise ArgumentError if too many
+ arguments more than optional arguments (without rest arg).
- * eval.c: 不必要になったPUSH_ENV, POP_ENVを減らした.
+ * eval.c (rb_eval): did not work well for op_asgn2 (attribute
+ self assignment).
- * env.h: ENVIONからselfをはずした.PUSH_ENVはsuperの準備のためだけ
- に用いることにした.
+ * eval.c (Init_Thread): returns main thread.
- * eval.c: 下記のオブジェクト化で遅くなった実行速度をもとに戻した.
+Mon Aug 18 09:25:56 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Mon Dec 17 23:01:10 1994 Yukihiro Matsumoto (matz@ix-02)
+ * object.c (inspect_i): did not display T_DATA instance variables.
- * eval.c: env.{argv,argc}とscope.local_varsのオブジェクト化.
+ * parse.y: provides more accurate line number information.
- * eval.c: 1スコープ内で複数Blockを生成したときのバグを修正.
+ * eval.c (thread_value): include value's backtrace information in
+ the variable `$@'.
-Fri Dec 16 15:52:06 1994 Yukihiro Matsumoto (matz@ix-02)
+ * eval.c (f_abort): print backtrace and exit.
- * parse.y: `&&'と`||'の両辺はいつでも条件式とした.
+Sat Aug 16 00:17:44 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Thu Dec 15 00:16:04 1994 Yukihiro Matsumoto (matz@dyna)
+ * eval.c (class_new_instance): do not make instance from virtual
+ classes.
- * eval.c(Block): Blockオブジェクトを実現.
+ * object.c (class_s_new): do not make subclass of singleton class.
- * node.h: NODE_QLISTはなくなった.
+Fri Aug 15 15:49:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * eval.c(rb_call): 引数への代入を名前で一つずつ代入するのをやめて,
- 一度にコピーするようにした.
+ * eval.c (call_trace_func): block context switch in the trace
+ function.
- * eval.c(rb_call): rubyで記述されたメソッドへの引数渡しをinline化.
+ * eval.c (rb_eval): clear method cache at class extention.
- * eval.c: イテレータ判定処理の全面書き換え.不適切なイテレータ呼び
- 出しをなくした.例えば「[foo(),bar()]{i|baz(i)}」でfooもbarもイ
- テレータとして呼び出され*ない*.
+ * object.c (obj_type): returns object's class even if it defines
+ singleton methods.
- * eval.c(rb_call): SCOPE処理をinline化.メソッド呼び出しの若干の高
- 速化.
+Fri Aug 15 19:40:43 1997 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
-Wed Dec 14 18:09:33 1994 Yukihiro Matsumoto (matz@ix-02)
+ * ext/socket/socket.c (Init_socket): small typo caused SEGV.
- * node.h: nodeもオブジェクトにする.よってGCで回収される.
+Wed Aug 13 17:51:46 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
-Thu Dec 8 14:17:29 1994 Yukihiro Matsumoto (matz@ix-02)
+ * version 1.1 alpha0 released.
- * 0.60 released - alpha test baseline.
diff --git a/MANIFEST b/MANIFEST
index 1ae2adc..2bdaf29 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,3 +1,4 @@
+COPYING
ChangeLog
MANIFEST
Makefile.in
@@ -32,10 +33,16 @@ glob.c
hash.c
inits.c
install-sh
+instruby.rb
+intern.h
io.c
io.h
+keywords
+lex.c
main.c
+marshal.c
math.c
+mkconfig.rb
node.h
numeric.c
object.c
@@ -51,6 +58,7 @@ regex.h
ruby.1
ruby.c
ruby.h
+rubytest.rb
sig.h
signal.c
sprintf.c
@@ -78,34 +86,41 @@ lib/cgi-lib.rb
lib/complex.rb
lib/date.rb
lib/debug.rb
+lib/delegate.rb
lib/e2mmap.rb
-lib/e2mmap1_0.rb
+lib/eregex.rb
lib/find.rb
lib/finalize.rb
lib/ftplib.rb
+lib/ftools.rb
lib/getopts.rb
+lib/importenv.rb
lib/jcode.rb
lib/mailread.rb
lib/mathn.rb
lib/matrix.rb
+lib/mkmf.rb
lib/mutex_m.rb
lib/observer.rb
+lib/ostruct.rb
lib/parsearg.rb
lib/parsedate.rb
lib/ping.rb
+lib/pstore.rb
lib/rational.rb
+lib/shellwords.rb
lib/sync.rb
lib/thread.rb
lib/thwait.rb
lib/tk.rb
-lib/tkcore.rb
lib/tkcanvas.rb
lib/tkclass.rb
+lib/tkdialog.rb
lib/tkentry.rb
lib/tkscrollbox.rb
lib/tktext.rb
-lib/tkthcore.rb
lib/tracer.rb
+lib/weakref.rb
missing/alloca.c
missing/crypt.c
missing/dir.h
@@ -126,6 +141,7 @@ missing/strtol.c
missing/strtoul.c
missing/x68.c
sample/biorhythm.rb
+sample/cbreak.rb
sample/clnt.rb
sample/dbmtest.rb
sample/dir.rb
@@ -141,7 +157,6 @@ sample/freq.rb
sample/from.rb
sample/fullpath.rb
sample/getopts.test
-sample/io.rb
sample/less.rb
sample/list.rb
sample/list2.rb
@@ -155,6 +170,7 @@ sample/occur.rb
sample/occur2.rb
sample/philos.rb
sample/pi.rb
+sample/rbc.rb
sample/rcs.awk
sample/rcs.dat
sample/rcs.rb
@@ -180,6 +196,8 @@ win32/Makefile
win32/config.h
win32/ntsetup.bat
win32/ruby.def
+win32/sdbm.c
+win32/sdbm.h
x68/fconvert.c
x68/select.c
x68/_dtos18.c
diff --git a/Makefile.in b/Makefile.in
index ee0ac1f..3c616d9 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -7,9 +7,6 @@ VPATH = @srcdir@:@srcdir@/missing
CC = @CC@
YACC = @YACC@
-INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_DATA = @INSTALL_DATA@
PURIFY =
@SET_MAKE@
@@ -18,14 +15,6 @@ LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@
LIBS = @LIBS@ $(EXTLIBS)
MISSING = @LIBOBJS@ @ALLOCA@
-program_transform_name = -e @program_transform_name@
-RUBY_INSTALL_NAME = `t='$(program_transform_name)'; echo ruby | sed $$t`
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-bindir = @bindir@
-libdir = @libdir@/$(RUBY_INSTALL_NAME)
-
binsuffix = @binsuffix@
#### End of system configuration section. ####
@@ -33,7 +22,7 @@ binsuffix = @binsuffix@
LIBRUBY = libruby.a
-EXTOBJS = dmyext.o
+EXTOBJS =
MAINOBJ = main.o
@@ -54,6 +43,7 @@ OBJS = array.o \
inits.o \
io.o \
math.o \
+ marshal.o \
numeric.o \
object.o \
pack.o \
@@ -75,15 +65,12 @@ OBJS = array.o \
version.o \
$(MISSING)
-all: miniruby$(binsuffix) @srcdir@/ext/Setup
- @if test -z "$$UNDER_EXTMAKE_RB"; \
- then echo "Compiling ext modules"; \
- UNDER_EXTMAKE_RB=yes; export UNDER_EXTMAKE_RB; \
- cd ext; ../miniruby ./extmk.rb @EXTSTATIC@; fi
+all: miniruby$(binsuffix) rbconfig.rb
+ @cd ext; ../miniruby$(binsuffix) ./extmk.rb @EXTSTATIC@
-miniruby$(binsuffix): $(OBJS) $(MAINOBJ) $(EXTOBJS)
+miniruby$(binsuffix): $(OBJS) $(MAINOBJ) dmyext.o
@rm -f $@
- $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(LIBS) -o miniruby
+ $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(OBJS) dmyext.o $(LIBS) -o miniruby
ruby$(binsuffix): $(LIBRUBY) $(MAINOBJ) $(EXTOBJS)
@rm -f $@
@@ -93,36 +80,31 @@ $(LIBRUBY): $(OBJS) dmyext.o
@AR@ rcu $(LIBRUBY) $(OBJS) dmyext.o
@-@RANLIB@ $(LIBRUBY) 2> /dev/null || true
-install:; $(INSTALL_PROGRAM) ruby$(binsuffix) $(bindir)/$(RUBY_INSTALL_NAME)$(binsuffix)
- @-@STRIP@ $(bindir)/$(RUBY_INSTALL_NAME)$(binsuffix)
- @test -d $(libdir) || mkdir $(libdir)
- cd ext; ../miniruby ./extmk.rb install
- @for rb in `grep '^lib/' @srcdir@/MANIFEST`; do \
- $(INSTALL_DATA) @srcdir@/$$rb $(libdir); \
- done
+install: rbconfig.rb
+ ./miniruby$(binsuffix) $(srcdir)/instruby.rb
-clean:; @rm -f $(OBJS) $(LIBRUBY) $(MAINOBJ)
+clean:; @rm -f $(OBJS) $(LIBRUBY) $(MAINOBJ) rbconfig.rb
@rm -f ext/extinit.c ext/extinit.o dmyext.o
- cd ext; ../miniruby ./extmk.rb clean
+ @if test -f ./miniruby; then cd ext; ../miniruby ./extmk.rb clean; fi
realclean: clean
- @rm -f Makefile ext/extmk.rb ext/config.cache parse.c
+ @rm -f Makefile ext/extmk.rb ext/config.cache
@rm -f config.cache config.h config.log config.status
- @rm -f core ruby$(binsuffix) miniruby$(binsuffix) parse.c *~ *.core gmon.out
-
-test:; @-./ruby @srcdir@/sample/test.rb > ./ruby_test 2>&1; \
- if grep '^end of test' ./ruby_test > /dev/null; then \
- echo "test succeeded"; \
- else \
- grep '^sample/test.rb' ./ruby_test; \
- grep '^not' ./ruby_test; \
- echo "test failed";\
- fi;\
- rm -f ./ruby_test
+ @rm -f parse.c lex.c *~ core *.core gmon.out
+ @rm -f ruby$(binsuffix) miniruby$(binsuffix)
+
+test: miniruby$(binsuffix)
+ @./miniruby$(binsuffix) $(srcdir)/rubytest.rb
+
+rbconfig.rb: config.status miniruby$(binsuffix)
+ @./miniruby$(binsuffix) $(srcdir)/mkconfig.rb rbconfig.rb
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
+lex.c: keywords
+ gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$$ keywords > lex.c
+
parse.c: parse.y
$(YACC) $<
mv -f y.tab.c parse.c
@@ -178,42 +160,40 @@ x68.o: @srcdir@/missing/x68.c
# Prevent GNU make v3 from overflowing arg limit on SysV.
.NOEXPORT:
###
-parse.o : parse.y ruby.h defines.h config.h env.h node.h st.h regex.h
+parse.o : parse.y ruby.h defines.h config.h intern.h env.h node.h st.h regex.h lex.c
###
-array.o: array.c ruby.h config.h defines.h
-bignum.o: bignum.c ruby.h config.h defines.h
-class.o: class.c ruby.h config.h defines.h node.h st.h
-compar.o: compar.c ruby.h config.h defines.h
-dir.o: dir.c ruby.h config.h defines.h
+array.o: array.c ruby.h config.h defines.h intern.h
+bignum.o: bignum.c ruby.h config.h defines.h intern.h
+class.o: class.c ruby.h config.h defines.h intern.h node.h st.h
+compar.o: compar.c ruby.h config.h defines.h intern.h
+dir.o: dir.c ruby.h config.h defines.h intern.h
dln.o: dln.c config.h defines.h dln.h st.h
dmyext.o: dmyext.c
-enum.o: enum.c ruby.h config.h defines.h
-error.o: error.c ruby.h config.h defines.h env.h
-eval.o: eval.c ruby.h config.h defines.h env.h node.h sig.h st.h dln.h
-file.o: file.c ruby.h config.h defines.h io.h sig.h
-fnmatch.o: fnmatch.c config.h fnmatch.h
-gc.o: gc.c ruby.h config.h defines.h env.h sig.h st.h node.h re.h regex.h
-glob.o: glob.c config.h fnmatch.h
-hash.o: hash.c ruby.h config.h defines.h st.h
-inits.o: inits.c ruby.h config.h defines.h
-io.o: io.c ruby.h config.h defines.h io.h sig.h
+enum.o: enum.c ruby.h config.h defines.h intern.h
+error.o: error.c ruby.h config.h defines.h intern.h env.h
+eval.o: eval.c ruby.h config.h defines.h intern.h env.h node.h sig.h st.h dln.h
+file.o: file.c ruby.h config.h defines.h intern.h io.h sig.h
+gc.o: gc.c ruby.h config.h defines.h intern.h env.h sig.h st.h node.h re.h regex.h
+hash.o: hash.c ruby.h config.h defines.h intern.h st.h
+inits.o: inits.c ruby.h config.h defines.h intern.h
+io.o: io.c ruby.h config.h defines.h intern.h io.h sig.h
main.o: main.c
-math.o: math.c ruby.h config.h defines.h
-numeric.o: numeric.c ruby.h config.h defines.h
-object.o: object.c ruby.h config.h defines.h st.h
-pack.o: pack.c ruby.h config.h defines.h
-process.o: process.c ruby.h config.h defines.h sig.h st.h
-random.o: random.c ruby.h config.h defines.h
-range.o: range.c ruby.h config.h defines.h
-re.o: re.c ruby.h config.h defines.h re.h regex.h
-regex.o: regex.c config.h defines.h regex.h util.h
-ruby.o: ruby.c ruby.h config.h defines.h re.h regex.h dln.h
-signal.o: signal.c ruby.h config.h defines.h sig.h
-sprintf.o: sprintf.c ruby.h config.h defines.h
+marshal.o: marshal.c ruby.h config.h defines.h intern.h io.h sig.h st.h
+math.o: math.c ruby.h config.h defines.h intern.h
+numeric.o: numeric.c ruby.h config.h defines.h intern.h
+object.o: object.c ruby.h config.h defines.h intern.h st.h
+pack.o: pack.c ruby.h config.h defines.h intern.h
+process.o: process.c ruby.h config.h defines.h intern.h sig.h st.h
+random.o: random.c ruby.h config.h defines.h intern.h
+range.o: range.c ruby.h config.h defines.h intern.h
+re.o: re.c ruby.h config.h defines.h intern.h re.h regex.h
+ruby.o: ruby.c ruby.h config.h defines.h intern.h re.h regex.h dln.h
+signal.o: signal.c ruby.h config.h defines.h intern.h sig.h
+sprintf.o: sprintf.c ruby.h config.h defines.h intern.h
st.o: st.c config.h st.h
-string.o: string.c ruby.h config.h defines.h re.h regex.h
-struct.o: struct.c ruby.h config.h defines.h
-time.o: time.c ruby.h config.h defines.h
-util.o: util.c defines.h config.h util.h
-variable.o: variable.c ruby.h config.h defines.h env.h st.h
-version.o: version.c ruby.h config.h defines.h version.h
+string.o: string.c ruby.h config.h defines.h intern.h re.h regex.h
+struct.o: struct.c ruby.h config.h defines.h intern.h
+time.o: time.c ruby.h config.h defines.h intern.h
+util.o: util.c defines.h intern.h config.h util.h
+variable.o: variable.c ruby.h config.h defines.h intern.h env.h st.h
+version.o: version.c ruby.h config.h defines.h intern.h version.h
diff --git a/README b/README
index 6583bc8..d41fb9f 100644
--- a/README
+++ b/README
@@ -5,7 +5,7 @@ easy object-oriented programming. It has many features to
process text files and to do system management tasks (as in
perl). It is simple, straight-forward, and extensible.
-* Features of ruby
+* Features of Ruby
+ Simple Syntax
+ *Normal* Object-Oriented features(ex. class, method calls)
@@ -17,17 +17,15 @@ perl). It is simple, straight-forward, and extensible.
+ Dynamic Loading of Object files(on some architecture)
+ Highly Portable(works on many UNIX machines)
-* How to get ruby
+* How to get Ruby
-** by ftp
-
-The ruby distribution can be found on
+The Ruby distribution can be found on
ftp://ftp.netlab.co.jp/pub/lang/ruby/
* How to compile and install
-This is what you need to do to compile and install ruby:
+This is what you need to do to compile and install Ruby:
1. Run ./configure, which will generate config.h and Makefile.
@@ -41,40 +39,61 @@ This is what you need to do to compile and install ruby:
4. Run make.
- 5. Optionally, run 'make test' to check that the compiled ruby
+ 5. Optionally, run 'make test' to check that the compiled Ruby
interpreter works well. If you see the message "test succeeded",
- your ruby works as it should.
+ your Ruby works as it should (hopefully).
6. Run 'make install'
-If you fail to compile ruby, please send the detailed error report with
+If you fail to compile Ruby, please send the detailed error report with
the error log and machine/OS type, to help others.
* Copying
-Ruby is copyrighted by Yukihiro Matsumoto <matz@ruby.club.co.jp>.
+Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
+You can redistribute it and/or modify it under either the terms of the GPL
+(see COPYING file), or the conditions below:
+
+ 1. You may make and give away verbatim copies of the source form of the
+ software without restriction, provided that you duplicate all of the
+ original copyright notices and associated disclaimers.
+
+ 2. You may modify your copy of the software in any way, provided that
+ you do at least ONE of the following:
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet
+ or an equivalent medium, or by allowing the author to include your
+ modifications in the software.
+
+ b) use the modified software only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided.
+
+ d) make other distribution arrangements with the author.
-This source is distributed under the conditions blow:
+ 3. You may distribute the software in object code or executable
+ form, provided that you do at least ONE of the following:
- 1. You may make and give away verbatim copies of the source form of
- the software without restriction, provided that you do not modify
- the original distribution files.
+ a) distribute the executables and library files of the software,
+ together with instructions (in the manual page or equivalent)
+ on where to get the original distribution.
- If you want to distribute the modified version in any way, contact
- the author.
+ b) accompany the distribution with the machine-readable source of
+ the software.
- 2. You may distribute the software in object code or executable
- form, provided that you distribute it with instructions on where
- to get the software.
+ c) give non-standard executables non-standard names, with
+ instructions on where to get the original software
+ distribution.
- 3. You may modify the software in any way, provided that you do not
- distribute the modified version.
+ d) make other distribution arrangements with the author.
4. You may modify and include the part of the software into any other
software (possibly commercial). But some files in the distribution
are not written by the author, so that they are not under this terms.
- They are gc.c(partly),utils.c(partly), regex.[ch],fnmatch.[ch],
- glob.c, st.[ch] and somme files under the ./missing directory. See
+ They are gc.c(partly), utils.c(partly), regex.[ch], fnmatch.[ch],
+ glob.c, st.[ch] and some files under the ./missing directory. See
each files for the copying condition.
5. The scripts and library files supplied as input to or produced as
@@ -88,9 +107,9 @@ This source is distributed under the conditions blow:
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
PURPOSE.
-* ruby home-page
+* Ruby home-page
- The URL of the ruby home-page is:
+The URL of the Ruby home-page is:
http://www.netlab.co.jp/ruby/
diff --git a/README.jp b/README.jp
index 8a10010..00822a3 100644
--- a/README.jp
+++ b/README.jp
@@ -9,6 +9,7 @@ Rubyはテキスト処理関係の能力などに優れ,perlと同じくらい強力
です.さらにシンプルな文法と,例外処理やイテレータなどの機構
によって,より分かりやすいプログラミングが出来ます.
+
* Rubyの特長.
+ シンプルな文法
@@ -21,6 +22,7 @@ Rubyはテキスト処理関係の能力などに優れ,perlと同じくらい強力
+ ダイナミックローディング (アーキテクチャによる)
+ 移植性が高い.多くのUNIX上で動く
+
* 入手法
** ftpで
@@ -29,6 +31,7 @@ Rubyはテキスト処理関係の能力などに優れ,perlと同じくらい強力
ftp://ftp.netlab.co.jp/pub/lang/ruby/
+
* ホームページ
RubyのホームページのURLは
@@ -37,6 +40,7 @@ Rubyはテキスト処理関係の能力などに優れ,perlと同じくらい強力
です.
+
* メイリングリスト
Rubyに関わる話題のためのメイリングリストを開設しました.ア
@@ -46,6 +50,7 @@ Rubyはテキスト処理関係の能力などに優れ,perlと同じくらい強力
です.このアドレスにメイルを送れば,自動的に登録されます.
+
* コンパイル・インストール
以下の手順で行ってください.
@@ -80,13 +85,14 @@ Rubyはテキスト処理関係の能力などに優れ,perlと同じくらい強力
シン,OSの種類を含むできるだけ詳しいレポートを作者に送ってく
ださると他の方のためにもなります.
+
* 移植
UNIXであればconfigureがほとんどの差異を吸収してくれるはずで
すが,思わぬ見落としがあった場合(あるに違いない),作者にその
ことをレポートすれば,解決できるかも知れません.
-アークテクチャにもっとも依存するのはGC部です.rubyのGCは対象
+アークテクチャにもっとも依存するのはGC部です.RubyのGCは対象
のアーキテクチャがsetjmp()によって全てのレジスタを jmp_bufに
格納することと,jmp_bufとスタックが32bitアラインメントされて
いることを仮定しています.特に前者が成立しない場合の対応は非
@@ -95,50 +101,63 @@ UNIXであればconfigureがほとんどの差異を吸収してくれるはずで
クするコードを追加するだけで済みます.「defined(THINK_C)」で
括られている部分を参考にしてください
-# 実際にはrubyはThink Cではコンパイルできません.
+# 実際にはRubyはThink Cではコンパイルできません.
レジスタウィンドウを持つCPUでは,レジスタウィンドウをスタッ
クにフラッシュするアセンブラコードを追加する必要があるかも知
れません.
+
* 配布条件
-作者は以下の条件のもとにrubyを配布します.
+RUbyはフリーソフトウェアです.GPL(the GNU General Public
+Licence)または以下に示す条件でRubyを再配布できます.GPLにつ
+いてはCOPYINGファイルを参照して下さい.
+
+ 1. 複製は制限なく自由です.
+
+ 2. 以下の条件のいずれかを満たす時に手元のRubyのソースを自
+ 由に変更できます.
+
+ (a) ネットニューズにポストしたり,作者に変更を送付する
+ などの方法で,変更を公開する
+
+ (b) 変更したRubyを自分の所属する組織内部だけで使う
- + 再配布
+ (c) 変更点を明示したうえ,ソフトウェアの名前を変更する.
+ そのソフトウェアを配布する時にはもとのRubyも同時に
+ 配布する
- 配布した状態を維持する限り自由です.変更を行ったものを再
- 配布することを希望する時には作者に連絡してください.
+ (d) その他の変更条件を作者と合意する
- 変更を行なわないrubyをコンパイルしたバイナリの配布は禁止
- しませんが,バイナリを受け取った人がソースを入手できるよ
- うに,ソースの入手法を明示してください.
+ 3. 以下の条件のいずれかを満たす時にRubyをオブジェクトコー
+ ドや実行形式でも配布できます.
- + 変更
+ (a) バイナリを受け取った人がソースを入手できるようにソー
+ スの入手法を明示する
- 再配布を行わない限り,いかなる目的であれ自由です.ただし,
- 機能拡張やバグ修正は作者へのフィードバックを期待します
- (もちろん強制ではありません).
+ (b) 機械可読なソースコードを添付する
- + 他のプログラムへの引用
+ (c) 変更を行ったバイナリは名前を変更したうえ,ソースの
+ 入手法を明示する
- いかなる目的であれ自由です.ただし,rubyに含まれる他の作
- 者によるコードは,それぞれの作者の意向による制限が加えら
- れます.具体的にはgc.c(一部),util.c(一部),regex.[ch],
- fnmatch.[ch],glob.c,st.[ch]と./missingディレクトリ下の
- ファイル群が該当します.
+ (d) その他の配布条件を作者と合意する
- + Rubyスクリプトの権利
+ 4. 他のプログラムへの引用はいかなる目的であれ自由です.た
+ だし,Rubyに含まれる他の作者によるコードは,それぞれの
+ 作者の意向による制限が加えられます.具体的にはgc.c(一部),
+ util.c(一部),st.[ch],regex.[ch], fnmatch.[ch], glob.c
+ および./missingディレクトリ下のファイル群が該当します.
- 全てのrubyスクリプトの権利はそれぞれの著作者に属します.
- 作者はこれらに関して一切の権利を主張しません.またrubyに
- 組み込むための拡張モジュールに関しても同様です.
+ 5. Rubyへの入力となるスクリプトおよび,Rubyからの出力の権
+ 利はRubyの作者ではなく,それぞれの入出力を生成した人に
+ 属します.また,Rubyに組み込むための拡張モジュールにつ
+ いても同様です.
- + 無保証
+ 6. Rubyは無保証です.作者はRubyをサポートする意志はありま
+ すが,Ruby自身のバグあるいはRubyスクリプトのバグなどか
+ ら発生するいかなる損害に対しても責任を持ちません.
- Rubyは無保証です.作者はrubyをサポートする意志はあります
- が,ruby自身のバグあるいはrubyスクリプトのバグなどから発
- 生するいかなる損害に対しても責任を持ちません.
* 著者
diff --git a/array.c b/array.c
index 39e10a3..388fb05 100644
--- a/array.c
+++ b/array.c
@@ -12,9 +12,8 @@
#include "ruby.h"
-VALUE cArray;
-VALUE rb_to_a();
+VALUE cArray;
#define ARY_DEFAULT_SIZE 16
@@ -90,22 +89,22 @@ ary_new3(n, va_alist)
va_dcl
{
va_list ar;
- struct RArray* ary;
+ VALUE ary;
int i;
if (n < 0) {
IndexError("Negative number of items(%d)", n);
}
- ary = (struct RArray*)ary_new2(n<ARY_DEFAULT_SIZE?ARY_DEFAULT_SIZE:n);
+ ary = ary_new2(n<ARY_DEFAULT_SIZE?ARY_DEFAULT_SIZE:n);
va_start(ar);
for (i=0; i<n; i++) {
- ary->ptr[i] = va_arg(ar, VALUE);
+ RARRAY(ary)->ptr[i] = va_arg(ar, VALUE);
}
va_end(ar);
- ary->len = n;
- return (VALUE)ary;
+ RARRAY(ary)->len = n;
+ return ary;
}
VALUE
@@ -113,27 +112,27 @@ ary_new4(n, elts)
int n;
VALUE *elts;
{
- struct RArray* ary;
+ VALUE ary;
- ary = (struct RArray*)ary_new2(n);
- MEMCPY(ary->ptr, elts, VALUE, n);
- ary->len = n;
+ ary = ary_new2(n);
+ MEMCPY(RARRAY(ary)->ptr, elts, VALUE, n);
+ RARRAY(ary)->len = n;
- return (VALUE)ary;
+ return ary;
}
VALUE
assoc_new(car, cdr)
VALUE car, cdr;
{
- struct RArray* ary;
+ VALUE ary;
- ary = (struct RArray*)ary_new2(2);
- ary->ptr[0] = car;
- ary->ptr[1] = cdr;
- ary->len = 2;
+ ary = ary_new2(2);
+ RARRAY(ary)->ptr[0] = car;
+ RARRAY(ary)->ptr[1] = cdr;
+ RARRAY(ary)->len = 2;
- return (VALUE)ary;
+ return ary;
}
static VALUE
@@ -179,7 +178,7 @@ ary_s_create(argc, argv, class)
void
ary_store(ary, idx, val)
- struct RArray *ary;
+ VALUE ary;
int idx;
VALUE val;
{
@@ -188,69 +187,69 @@ ary_store(ary, idx, val)
IndexError("negative index for array");
}
- if (idx >= ary->capa) {
- ary->capa = idx + ARY_DEFAULT_SIZE;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
+ if (idx >= RARRAY(ary)->capa) {
+ RARRAY(ary)->capa = idx + ARY_DEFAULT_SIZE;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
}
- if (idx > ary->len) {
- memclear(ary->ptr+ary->len, idx-ary->len+1);
+ if (idx > RARRAY(ary)->len) {
+ memclear(RARRAY(ary)->ptr+RARRAY(ary)->len, idx-RARRAY(ary)->len+1);
}
- if (idx >= ary->len) {
- ary->len = idx + 1;
+ if (idx >= RARRAY(ary)->len) {
+ RARRAY(ary)->len = idx + 1;
}
- ary->ptr[idx] = val;
+ RARRAY(ary)->ptr[idx] = val;
}
VALUE
ary_push(ary, item)
- struct RArray *ary;
+ VALUE ary;
VALUE item;
{
- ary_store(ary, ary->len, item);
- return (VALUE)ary;
+ ary_store(ary, RARRAY(ary)->len, item);
+ return ary;
}
static VALUE
ary_push_method(argc, argv, ary)
int argc;
VALUE *argv;
- struct RArray *ary;
+ VALUE ary;
{
while (argc--) {
- ary_store(ary, ary->len, *argv++);
+ ary_store(ary, RARRAY(ary)->len, *argv++);
}
- return (VALUE)ary;
+ return ary;
}
VALUE
ary_pop(ary)
- struct RArray *ary;
+ VALUE ary;
{
- if (ary->len == 0) return Qnil;
- if (ary->len * 10 < ary->capa && ary->capa > ARY_DEFAULT_SIZE) {
- ary->capa = ary->len * 2;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
+ if (RARRAY(ary)->len == 0) return Qnil;
+ if (RARRAY(ary)->len * 10 < RARRAY(ary)->capa && RARRAY(ary)->capa > ARY_DEFAULT_SIZE) {
+ RARRAY(ary)->capa = RARRAY(ary)->len * 2;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
}
- return ary->ptr[--ary->len];
+ return RARRAY(ary)->ptr[--RARRAY(ary)->len];
}
VALUE
ary_shift(ary)
- struct RArray *ary;
+ VALUE ary;
{
VALUE top;
- if (ary->len == 0) return Qnil;
+ if (RARRAY(ary)->len == 0) return Qnil;
- top = ary->ptr[0];
- ary->len--;
+ top = RARRAY(ary)->ptr[0];
+ RARRAY(ary)->len--;
/* sliding items */
- MEMMOVE(ary->ptr, ary->ptr+1, VALUE, ary->len);
- if (ary->len * 10 < ary->capa && ary->capa > ARY_DEFAULT_SIZE) {
- ary->capa = ary->len * 2;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
+ MEMMOVE(RARRAY(ary)->ptr, RARRAY(ary)->ptr+1, VALUE, RARRAY(ary)->len);
+ if (RARRAY(ary)->len * 10 < RARRAY(ary)->capa && RARRAY(ary)->capa > ARY_DEFAULT_SIZE) {
+ RARRAY(ary)->capa = RARRAY(ary)->len * 2;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
}
return top;
@@ -258,65 +257,64 @@ ary_shift(ary)
VALUE
ary_unshift(ary, item)
- struct RArray *ary;
- int item;
+ VALUE ary, item;
{
ary_modify(ary);
- if (ary->len >= ary->capa) {
- ary->capa+=ARY_DEFAULT_SIZE;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
+ if (RARRAY(ary)->len >= RARRAY(ary)->capa) {
+ RARRAY(ary)->capa+=ARY_DEFAULT_SIZE;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
}
/* sliding items */
- MEMMOVE(ary->ptr+1, ary->ptr, VALUE, ary->len);
+ MEMMOVE(RARRAY(ary)->ptr+1, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
- ary->len++;
- return ary->ptr[0] = item;
+ RARRAY(ary)->len++;
+ return RARRAY(ary)->ptr[0] = item;
}
VALUE
ary_entry(ary, offset)
- struct RArray *ary;
+ VALUE ary;
int offset;
{
- if (ary->len == 0) return Qnil;
+ if (RARRAY(ary)->len == 0) return Qnil;
if (offset < 0) {
- offset = ary->len + offset;
+ offset = RARRAY(ary)->len + offset;
}
- if (offset < 0 || ary->len <= offset) {
+ if (offset < 0 || RARRAY(ary)->len <= offset) {
return Qnil;
}
- return ary->ptr[offset];
+ return RARRAY(ary)->ptr[offset];
}
static VALUE
ary_subseq(ary, beg, len)
- struct RArray *ary;
+ VALUE ary;
int beg, len;
{
- struct RArray *ary2;
+ VALUE ary2;
if (beg < 0) {
- beg = ary->len + beg;
+ beg = RARRAY(ary)->len + beg;
if (beg < 0) beg = 0;
}
if (len < 0) {
- IndexError("negative length %d", ary->len);
+ IndexError("negative length %d", RARRAY(ary)->len);
}
if (len == 0) {
return ary_new2(0);
}
- if (beg + len > ary->len) {
- len = ary->len - beg;
+ if (beg + len > RARRAY(ary)->len) {
+ len = RARRAY(ary)->len - beg;
}
- ary2 = (struct RArray*)ary_new2(len);
- MEMCPY(ary2->ptr, ary->ptr+beg, VALUE, len);
- ary2->len = len;
+ ary2 = ary_new2(len);
+ MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr+beg, VALUE, len);
+ RARRAY(ary2)->len = len;
- return (VALUE)ary2;
+ return ary2;
}
static VALUE
@@ -346,7 +344,6 @@ beg_len(range, begp, lenp, len)
end = len + end;
if (end < 0) end = -1;
}
- if (end > len) end = len;
if (beg > end) {
*lenp = 0;
}
@@ -357,11 +354,11 @@ beg_len(range, begp, lenp, len)
return TRUE;
}
-static VALUE
+VALUE
ary_aref(argc, argv, ary)
int argc;
VALUE *argv;
- struct RArray *ary;
+ VALUE ary;
{
VALUE arg1, arg2;
int beg, len;
@@ -381,7 +378,7 @@ ary_aref(argc, argv, ary)
}
else {
/* check if idx is Range */
- if (beg_len(arg1, &beg, &len, ary->len)) {
+ if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) {
return ary_subseq(ary, beg, len);
}
}
@@ -393,13 +390,13 @@ ary_aref(argc, argv, ary)
static VALUE
ary_index(ary, val)
- struct RArray *ary;
+ VALUE ary;
VALUE val;
{
int i;
- for (i=0; i<ary->len; i++) {
- if (rb_equal(ary->ptr[i], val))
+ for (i=0; i<RARRAY(ary)->len; i++) {
+ if (rb_equal(RARRAY(ary)->ptr[i], val))
return INT2FIX(i);
}
return Qnil;
@@ -407,7 +404,7 @@ ary_index(ary, val)
static VALUE
ary_indexes(ary, args)
- struct RArray *ary, *args;
+ VALUE ary, args;
{
VALUE *p, *pend;
VALUE new_ary;
@@ -417,9 +414,9 @@ ary_indexes(ary, args)
return ary_new2(0);
}
- new_ary = ary_new2(args->len);
+ new_ary = ary_new2(RARRAY(args)->len);
- p = args->ptr; pend = p + args->len;
+ p = RARRAY(args)->ptr; pend = p + RARRAY(args)->len;
while (p < pend) {
ary_store(new_ary, i++, ary_entry(ary, NUM2INT(*p)));
p++;
@@ -429,49 +426,49 @@ ary_indexes(ary, args)
static void
ary_replace(ary, beg, len, rpl)
- struct RArray *ary, *rpl;
+ VALUE ary, rpl;
int beg, len;
{
ary_modify(ary);
if (TYPE(rpl) != T_ARRAY) {
- rpl = (struct RArray*)rb_to_a(rpl);
+ rpl = rb_Array(rpl);
}
if (beg < 0) {
- beg = ary->len + beg;
+ beg = RARRAY(ary)->len + beg;
if (beg < 0) beg = 0;
}
- if (beg >= ary->len) {
- len = beg + rpl->len;
- if (len >= ary->capa) {
- ary->capa=len;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
+ if (beg >= RARRAY(ary)->len) {
+ len = beg + RARRAY(rpl)->len;
+ if (len >= RARRAY(ary)->capa) {
+ RARRAY(ary)->capa=len;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
}
- memclear(ary->ptr+ary->len, beg-ary->len);
- MEMCPY(ary->ptr+beg, rpl->ptr, VALUE, rpl->len);
- ary->len = len;
+ memclear(RARRAY(ary)->ptr+RARRAY(ary)->len, beg-RARRAY(ary)->len);
+ MEMCPY(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, RARRAY(rpl)->len);
+ RARRAY(ary)->len = len;
}
else {
int alen;
- if (beg + len > ary->len) {
- len = ary->len - beg;
+ if (beg + len > RARRAY(ary)->len) {
+ len = RARRAY(ary)->len - beg;
}
if (len < 0) {
- IndexError("negative length %d", ary->len);
+ IndexError("negative length %d", RARRAY(ary)->len);
}
- alen = ary->len + rpl->len - len;
- if (alen >= ary->capa) {
- ary->capa=alen;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
+ alen = RARRAY(ary)->len + RARRAY(rpl)->len - len;
+ if (alen >= RARRAY(ary)->capa) {
+ RARRAY(ary)->capa=alen;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
}
if (len != RARRAY(rpl)->len) {
- MEMMOVE(ary->ptr+beg+rpl->len, ary->ptr+beg+len,
- VALUE, ary->len-(beg+len));
- ary->len = alen;
+ MEMMOVE(RARRAY(ary)->ptr+beg+RARRAY(rpl)->len, RARRAY(ary)->ptr+beg+len,
+ VALUE, RARRAY(ary)->len-(beg+len));
+ RARRAY(ary)->len = alen;
}
- MEMCPY(ary->ptr+beg, rpl->ptr, VALUE, rpl->len);
+ MEMCPY(RARRAY(ary)->ptr+beg, RARRAY(rpl)->ptr, VALUE, RARRAY(rpl)->len);
}
}
@@ -479,10 +476,9 @@ static VALUE
ary_aset(argc, argv, ary)
int argc;
VALUE *argv;
- struct RArray *ary;
+ VALUE ary;
{
- VALUE arg1, arg2;
- struct RArray *arg3;
+ VALUE arg1, arg2, arg3;
int offset;
int beg, len;
@@ -490,13 +486,13 @@ ary_aset(argc, argv, ary)
beg = NUM2INT(arg1);
len = NUM2INT(arg2);
ary_replace(ary, beg, len, arg3);
- return (VALUE)arg3;
+ return arg3;
}
else if (FIXNUM_P(arg1)) {
offset = FIX2INT(arg1);
goto fixnum;
}
- else if (beg_len(arg1, &beg, &len, ary->len)) {
+ else if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) {
/* check if idx is Range */
ary_replace(ary, beg, len, arg2);
return arg2;
@@ -508,7 +504,7 @@ ary_aset(argc, argv, ary)
offset = NUM2INT(arg1);
fixnum:
if (offset < 0) {
- offset = ary->len + offset;
+ offset = RARRAY(ary)->len + offset;
}
ary_store(ary, offset, arg2);
return arg2;
@@ -516,23 +512,23 @@ ary_aset(argc, argv, ary)
VALUE
ary_each(ary)
- struct RArray *ary;
+ VALUE ary;
{
int i;
- for (i=0; i<ary->len; i++) {
- rb_yield(ary->ptr[i]);
+ for (i=0; i<RARRAY(ary)->len; i++) {
+ rb_yield(RARRAY(ary)->ptr[i]);
}
return Qnil;
}
static VALUE
ary_each_index(ary)
- struct RArray *ary;
+ VALUE ary;
{
int i;
- for (i=0; i<ary->len; i++) {
+ for (i=0; i<RARRAY(ary)->len; i++) {
rb_yield(INT2FIX(i));
}
return Qnil;
@@ -540,69 +536,76 @@ ary_each_index(ary)
static VALUE
ary_reverse_each(ary)
- struct RArray *ary;
+ VALUE ary;
{
- int len = ary->len;
+ int len = RARRAY(ary)->len;
while (len--) {
- rb_yield(ary->ptr[len]);
+ rb_yield(RARRAY(ary)->ptr[len]);
}
return Qnil;
}
static VALUE
ary_length(ary)
- struct RArray *ary;
+ VALUE ary;
{
- return INT2FIX(ary->len);
+ return INT2FIX(RARRAY(ary)->len);
}
static VALUE
ary_empty_p(ary)
- struct RArray *ary;
+ VALUE ary;
{
- if (ary->len == 0)
+ if (RARRAY(ary)->len == 0)
return TRUE;
return FALSE;
}
static VALUE
ary_clone(ary)
- struct RArray *ary;
+ VALUE ary;
{
- VALUE ary2 = ary_new2(ary->len);
+ VALUE ary2 = ary_new2(RARRAY(ary)->len);
CLONESETUP(ary2, ary);
- MEMCPY(RARRAY(ary2)->ptr, ary->ptr, VALUE, ary->len);
- RARRAY(ary2)->len = ary->len;
+ MEMCPY(RARRAY(ary2)->ptr, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
+ RARRAY(ary2)->len = RARRAY(ary)->len;
return ary2;
}
+static VALUE
+ary_dup(ary)
+ VALUE ary;
+{
+ return ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr);
+}
+
extern VALUE OFS;
VALUE
ary_join(ary, sep)
- struct RArray *ary;
- struct RString *sep;
+ VALUE ary;
+ VALUE sep;
{
int i;
VALUE result, tmp;
- if (ary->len == 0) return str_new(0, 0);
+ if (RARRAY(ary)->len == 0) return str_new(0, 0);
- switch (TYPE(ary->ptr[0])) {
+ switch (TYPE(RARRAY(ary)->ptr[0])) {
case T_STRING:
- result = str_dup(ary->ptr[0]);
+ result = str_dup(RARRAY(ary)->ptr[0]);
break;
case T_ARRAY:
- result = ary_join(ary->ptr[0], sep);
+ result = ary_join(RARRAY(ary)->ptr[0], sep);
break;
default:
- result = obj_as_string(ary->ptr[0]);
+ result = obj_as_string(RARRAY(ary)->ptr[0]);
break;
}
- for (i=1; i<ary->len; i++) {
- tmp = ary->ptr[i];
+ for (i=1; i<RARRAY(ary)->len; i++) {
+ tmp = RARRAY(ary)->ptr[i];
switch (TYPE(tmp)) {
case T_STRING:
break;
@@ -612,7 +615,7 @@ ary_join(ary, sep)
default:
tmp = obj_as_string(tmp);
}
- if (!NIL_P(sep)) str_cat(result, sep->ptr, sep->len);
+ if (!NIL_P(sep)) str_cat(result, RSTRING(sep)->ptr, RSTRING(sep)->len);
str_cat(result, RSTRING(tmp)->ptr, RSTRING(tmp)->len);
if (str_tainted(tmp)) str_taint(result);
}
@@ -624,7 +627,7 @@ static VALUE
ary_join_method(argc, argv, ary)
int argc;
VALUE *argv;
- struct RArray *ary;
+ VALUE ary;
{
VALUE sep;
@@ -644,35 +647,19 @@ ary_to_s(ary)
return str;
}
-VALUE
-ary_print_on(ary, port)
- struct RArray *ary;
- VALUE port;
-{
- int i;
-
- for (i=0; i<ary->len; i++) {
- if (!NIL_P(OFS) && i>0) {
- io_write(port, OFS);
- }
- io_write(port, ary->ptr[i]);
- }
- return port;
-}
-
static VALUE
ary_inspect(ary)
- struct RArray *ary;
+ VALUE ary;
{
int i, len;
VALUE s, str;
- if (ary->len == 0) return str_new2("[]");
+ if (RARRAY(ary)->len == 0) return str_new2("[]");
str = str_new2("[");
len = 1;
- for (i=0; i<ary->len; i++) {
- s = rb_inspect(ary->ptr[i]);
+ for (i=0; i<RARRAY(ary)->len; i++) {
+ s = rb_inspect(RARRAY(ary)->ptr[i]);
if (i > 0) str_cat(str, ", ", 2);
str_cat(str, RSTRING(s)->ptr, RSTRING(s)->len);
len += RSTRING(s)->len + 2;
@@ -690,26 +677,14 @@ ary_to_a(ary)
}
VALUE
-rb_to_a(obj)
- VALUE obj;
-{
- if (TYPE(obj) == T_ARRAY) return obj;
- obj = rb_funcall(obj, rb_intern("to_a"), 0);
- if (TYPE(obj) != T_ARRAY) {
- Bug("`to_a' did not return Array");
- }
- return obj;
-}
-
-VALUE
ary_reverse(ary)
- struct RArray *ary;
+ VALUE ary;
{
VALUE *p1, *p2;
VALUE tmp;
- p1 = ary->ptr;
- p2 = p1 + ary->len - 1; /* points last item */
+ p1 = RARRAY(ary)->ptr;
+ p2 = p1 + RARRAY(ary)->len - 1; /* points last item */
while (p1 < p2) {
tmp = *p1;
@@ -718,12 +693,12 @@ ary_reverse(ary)
p1++; p2--;
}
- return (VALUE)ary;
+ return ary;
}
static VALUE
ary_reverse_method(ary)
- struct RArray *ary;
+ VALUE ary;
{
return ary_reverse(ary_clone(ary));
}
@@ -757,11 +732,11 @@ sort_2(a, b)
VALUE
ary_sort_bang(ary)
- struct RArray *ary;
+ VALUE ary;
{
ary_modify(ary);
- qsort(ary->ptr, ary->len, sizeof(VALUE), iterator_p()?sort_1:sort_2);
- return (VALUE)ary;
+ qsort(RARRAY(ary)->ptr, RARRAY(ary)->len, sizeof(VALUE), iterator_p()?sort_1:sort_2);
+ return ary;
}
VALUE
@@ -773,25 +748,25 @@ ary_sort(ary)
VALUE
ary_delete(ary, item)
- struct RArray *ary;
+ VALUE ary;
VALUE item;
{
int i1, i2;
ary_modify(ary);
- for (i1 = i2 = 0; i1 < ary->len; i1++) {
- if (rb_equal(ary->ptr[i1], item)) continue;
+ for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
+ if (rb_equal(RARRAY(ary)->ptr[i1], item)) continue;
if (i1 != i2) {
- ary->ptr[i2] = ary->ptr[i1];
+ RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1];
}
i2++;
}
- if (ary->len == i2) {
+ if (RARRAY(ary)->len == i2) {
if (iterator_p()) rb_yield(item);
return Qnil;
}
else {
- ary->len = i2;
+ RARRAY(ary)->len = i2;
}
return item;
@@ -799,7 +774,7 @@ ary_delete(ary, item)
VALUE
ary_delete_at(ary, at)
- struct RArray *ary;
+ VALUE ary;
VALUE at;
{
int i1, i2, pos;
@@ -807,184 +782,184 @@ ary_delete_at(ary, at)
ary_modify(ary);
pos = NUM2INT(at);
- for (i1 = i2 = 0; i1 < ary->len; i1++) {
+ for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
if (i1 == pos) {
- del = ary->ptr[i1];
+ del = RARRAY(ary)->ptr[i1];
continue;
}
if (i1 != i2) {
- ary->ptr[i2] = ary->ptr[i1];
+ RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1];
}
i2++;
}
- ary->len = i2;
+ RARRAY(ary)->len = i2;
return del;
}
static VALUE
ary_delete_if(ary)
- struct RArray *ary;
+ VALUE ary;
{
int i1, i2;
ary_modify(ary);
- for (i1 = i2 = 0; i1 < ary->len; i1++) {
- if (rb_yield(ary->ptr[i1])) continue;
+ for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
+ if (rb_yield(RARRAY(ary)->ptr[i1])) continue;
if (i1 != i2) {
- ary->ptr[i2] = ary->ptr[i1];
+ RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1];
}
i2++;
}
- ary->len = i2;
+ RARRAY(ary)->len = i2;
- return (VALUE)ary;
+ return ary;
}
#if 0
static VALUE
ary_replace(ary)
- struct RArray *ary;
+ VALUE ary;
{
int i;
- for (i = 0; i < ary->len; i++) {
- ary->ptr[i] = rb_yield(ary->ptr[i]);
+ for (i = 0; i < RARRAY(ary)->len; i++) {
+ RARRAY(ary)->ptr[i] = rb_yield(RARRAY(ary)->ptr[i]);
}
- return (VALUE)ary;
+ return ary;
}
#endif
static VALUE
ary_clear(ary)
- struct RArray *ary;
+ VALUE ary;
{
- ary->len = 0;
- if (ARY_DEFAULT_SIZE*3 < ary->capa) {
- ary->capa = ARY_DEFAULT_SIZE * 2;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
+ RARRAY(ary)->len = 0;
+ if (ARY_DEFAULT_SIZE*3 < RARRAY(ary)->capa) {
+ RARRAY(ary)->capa = ARY_DEFAULT_SIZE * 2;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
}
- return (VALUE)ary;
+ return ary;
}
static VALUE
ary_fill(argc, argv, ary)
int argc;
VALUE *argv;
- struct RArray *ary;
+ VALUE ary;
{
VALUE item, arg1, arg2;
int beg, len, end;
VALUE *p, *pend;
rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
- if (NIL_P(arg2) && beg_len(arg1, &beg, &len, ary->len)) {
+ if (NIL_P(arg2) && beg_len(arg1, &beg, &len, RARRAY(ary)->len)) {
/* beg and len set already */
}
else {
beg = NUM2INT(arg1);
if (beg < 0) {
- beg = ary->len + beg;
+ beg = RARRAY(ary)->len + beg;
if (beg < 0) beg = 0;
}
- if (arg2) {
+ if (!NIL_P(arg2)) {
len = NUM2INT(arg2);
}
else {
- len = ary->len - beg;
+ len = RARRAY(ary)->len - beg;
}
}
end = beg + len;
- if (end > ary->len) {
- if (end >= ary->capa) {
- ary->capa=end;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
+ if (end > RARRAY(ary)->len) {
+ if (end >= RARRAY(ary)->capa) {
+ RARRAY(ary)->capa=end;
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa);
}
- if (beg > ary->len) {
- memclear(ary->ptr+ary->len, end-ary->len);
+ if (beg > RARRAY(ary)->len) {
+ memclear(RARRAY(ary)->ptr+RARRAY(ary)->len, end-RARRAY(ary)->len);
}
- ary->len = end;
+ RARRAY(ary)->len = end;
}
- p = ary->ptr + beg; pend = p + len;
+ p = RARRAY(ary)->ptr + beg; pend = p + len;
while (p < pend) {
*p++ = item;
}
- return (VALUE)ary;
+ return ary;
}
VALUE
ary_plus(x, y)
- struct RArray *x, *y;
+ VALUE x, y;
{
- struct RArray *z;
+ VALUE z;
if (TYPE(y) != T_ARRAY) {
- return ary_plus(x, rb_to_a(y));
+ return ary_plus(x, rb_Array(y));
}
- z = (struct RArray*)ary_new2(x->len + y->len);
- MEMCPY(z->ptr, x->ptr, VALUE, x->len);
- MEMCPY(z->ptr+x->len, y->ptr, VALUE, y->len);
- z->len = x->len + RARRAY(y)->len;
- return (VALUE)z;
+ z = ary_new2(RARRAY(x)->len + RARRAY(y)->len);
+ MEMCPY(RARRAY(z)->ptr, RARRAY(x)->ptr, VALUE, RARRAY(x)->len);
+ MEMCPY(RARRAY(z)->ptr+RARRAY(x)->len, RARRAY(y)->ptr, VALUE, RARRAY(y)->len);
+ RARRAY(z)->len = RARRAY(x)->len + RARRAY(y)->len;
+ return z;
}
VALUE
ary_concat(x, y)
- struct RArray *x, *y;
+ VALUE x, y;
{
VALUE *p, *pend;
if (TYPE(y) != T_ARRAY) {
- return ary_concat(x, rb_to_a(y));
+ return ary_concat(x, rb_Array(y));
}
- p = y->ptr;
- pend = p + y->len;
+ p = RARRAY(y)->ptr;
+ pend = p + RARRAY(y)->len;
while (p < pend) {
- ary_store(x, x->len, *p);
+ ary_store(x, RARRAY(x)->len, *p);
p++;
}
- return (VALUE)x;
+ return x;
}
static VALUE
ary_times(ary, times)
- struct RArray *ary;
+ VALUE ary;
VALUE times;
{
- struct RArray *ary2;
+ VALUE ary2;
int i, len;
if (TYPE(times) == T_STRING) {
return ary_join(ary, times);
}
- len = NUM2INT(times) * ary->len;
- ary2 = (struct RArray*)ary_new2(len);
- ary2->len = len;
+ len = NUM2INT(times) * RARRAY(ary)->len;
+ ary2 = ary_new2(len);
+ RARRAY(ary2)->len = len;
if (len < 0) {
ArgError("negative argument");
}
- for (i=0; i<len; i+=ary->len) {
- MEMCPY(ary2->ptr+i, ary->ptr, VALUE, ary->len);
+ for (i=0; i<len; i+=RARRAY(ary)->len) {
+ MEMCPY(RARRAY(ary2)->ptr+i, RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
}
- return (VALUE)ary2;
+ return ary2;
}
VALUE
ary_assoc(ary, key)
- struct RArray *ary;
+ VALUE ary;
VALUE key;
{
VALUE *p, *pend;
- p = ary->ptr; pend = p + ary->len;
+ p = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
while (p < pend) {
if (TYPE(*p) == T_ARRAY
&& RARRAY(*p)->len > 1
@@ -997,12 +972,12 @@ ary_assoc(ary, key)
VALUE
ary_rassoc(ary, value)
- struct RArray *ary;
+ VALUE ary;
VALUE value;
{
VALUE *p, *pend;
- p = ary->ptr; pend = p + ary->len;
+ p = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
while (p < pend) {
if (TYPE(*p) == T_ARRAY
&& RARRAY(*p)->len > 1
@@ -1015,14 +990,14 @@ ary_rassoc(ary, value)
static VALUE
ary_equal(ary1, ary2)
- struct RArray *ary1, *ary2;
+ VALUE ary1, ary2;
{
int i;
if (TYPE(ary2) != T_ARRAY) return FALSE;
- if (ary1->len != ary2->len) return FALSE;
- for (i=0; i<ary1->len; i++) {
- if (!rb_equal(ary1->ptr[i], ary2->ptr[i]))
+ if (RARRAY(ary1)->len != RARRAY(ary2)->len) return FALSE;
+ for (i=0; i<RARRAY(ary1)->len; i++) {
+ if (!rb_equal(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i]))
return FALSE;
}
return TRUE;
@@ -1030,14 +1005,15 @@ ary_equal(ary1, ary2)
static VALUE
ary_eql(ary1, ary2)
- struct RArray *ary1, *ary2;
+ VALUE ary1, ary2;
{
int i;
if (TYPE(ary2) != T_ARRAY) return FALSE;
- if (ary1->len != ary2->len) return FALSE;
- for (i=0; i<ary1->len; i++) {
- if (!rb_eql(ary1->ptr[i], ary2->ptr[i]))
+ if (RARRAY(ary1)->len != RARRAY(ary2)->len)
+ return FALSE;
+ for (i=0; i<RARRAY(ary1)->len; i++) {
+ if (!rb_eql(RARRAY(ary1)->ptr[i], RARRAY(ary2)->ptr[i]))
return FALSE;
}
return TRUE;
@@ -1045,25 +1021,25 @@ ary_eql(ary1, ary2)
static VALUE
ary_hash(ary)
- struct RArray *ary;
+ VALUE ary;
{
int h, i;
- h = ary->len;
- for (i=0; i<ary->len; i++) {
- h ^= rb_hash(ary->ptr[i]);
+ h = RARRAY(ary)->len;
+ for (i=0; i<RARRAY(ary)->len; i++) {
+ h ^= rb_hash(RARRAY(ary)->ptr[i]);
}
return INT2FIX(h);
}
VALUE
ary_includes(ary, item)
- struct RArray *ary;
+ VALUE ary;
VALUE item;
{
int i;
- for (i=0; i<ary->len; i++) {
- if (rb_equal(ary->ptr[i], item)) {
+ for (i=0; i<RARRAY(ary)->len; i++) {
+ if (rb_equal(RARRAY(ary)->ptr[i], item)) {
return TRUE;
}
}
@@ -1072,34 +1048,34 @@ ary_includes(ary, item)
static VALUE
ary_diff(ary1, ary2)
- struct RArray *ary1, *ary2;
+ VALUE ary1, ary2;
{
VALUE ary3;
int i;
Check_Type(ary2, T_ARRAY);
ary3 = ary_new();
- for (i=0; i<ary1->len; i++) {
- if (ary_includes(ary2, ary1->ptr[i])) continue;
- if (ary_includes(ary3, ary1->ptr[i])) continue;
- ary_push(ary3, ary1->ptr[i]);
+ for (i=0; i<RARRAY(ary1)->len; i++) {
+ if (ary_includes(ary2, RARRAY(ary1)->ptr[i])) continue;
+ if (ary_includes(ary3, RARRAY(ary1)->ptr[i])) continue;
+ ary_push(ary3, RARRAY(ary1)->ptr[i]);
}
return ary3;
}
static VALUE
ary_and(ary1, ary2)
- struct RArray *ary1, *ary2;
+ VALUE ary1, ary2;
{
VALUE ary3;
int i;
Check_Type(ary2, T_ARRAY);
ary3 = ary_new();
- for (i=0; i<ary1->len; i++) {
- if (ary_includes(ary2, ary1->ptr[i])
- && !ary_includes(ary3, ary1->ptr[i])) {
- ary_push(ary3, ary1->ptr[i]);
+ for (i=0; i<RARRAY(ary1)->len; i++) {
+ if (ary_includes(ary2, RARRAY(ary1)->ptr[i])
+ && !ary_includes(ary3, RARRAY(ary1)->ptr[i])) {
+ ary_push(ary3, RARRAY(ary1)->ptr[i]);
}
}
return ary3;
@@ -1107,63 +1083,63 @@ ary_and(ary1, ary2)
static VALUE
ary_or(ary1, ary2)
- struct RArray *ary1, *ary2;
+ VALUE ary1, ary2;
{
VALUE ary3;
int i;
if (TYPE(ary2) != T_ARRAY) {
- if (ary_includes(ary1, ary2)) return (VALUE)ary1;
+ if (ary_includes(ary1, ary2)) return ary1;
else return ary_plus(ary1, ary2);
}
ary3 = ary_new();
- for (i=0; i<ary1->len; i++) {
- if (!ary_includes(ary3, ary1->ptr[i]))
- ary_push(ary3, ary1->ptr[i]);
+ for (i=0; i<RARRAY(ary1)->len; i++) {
+ if (!ary_includes(ary3, RARRAY(ary1)->ptr[i]))
+ ary_push(ary3, RARRAY(ary1)->ptr[i]);
}
- for (i=0; i<ary2->len; i++) {
- if (!ary_includes(ary3, ary2->ptr[i]))
- ary_push(ary3, ary2->ptr[i]);
+ for (i=0; i<RARRAY(ary2)->len; i++) {
+ if (!ary_includes(ary3, RARRAY(ary2)->ptr[i]))
+ ary_push(ary3, RARRAY(ary2)->ptr[i]);
}
return ary3;
}
static VALUE
ary_compact_bang(ary)
- struct RArray *ary;
+ VALUE ary;
{
VALUE *p, *t, *end;
ary_modify(ary);
- p = t = ary->ptr;
- end = p + ary->len;
+ p = t = RARRAY(ary)->ptr;
+ end = p + RARRAY(ary)->len;
while (t < end) {
if (NIL_P(*t)) t++;
else *p++ = *t++;
}
- ary->len = ary->capa = (p - ary->ptr);
- REALLOC_N(ary->ptr, VALUE, ary->len);
+ RARRAY(ary)->len = RARRAY(ary)->capa = (p - RARRAY(ary)->ptr);
+ REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->len);
- return (VALUE)ary;
+ return ary;
}
static VALUE
ary_compact(ary)
- struct RArray *ary;
+ VALUE ary;
{
return ary_compact_bang(ary_clone(ary));
}
static VALUE
ary_nitems(ary)
- struct RArray *ary;
+ VALUE ary;
{
int n = 0;
VALUE *p, *pend;
- p = ary->ptr;
- pend = p + ary->len;
+ p = RARRAY(ary)->ptr;
+ pend = p + RARRAY(ary)->len;
while (p < pend) {
if (!NIL_P(*p)) n++;
p++;
@@ -1209,6 +1185,7 @@ Init_Array()
rb_define_method(cArray, "index", ary_index, 1);
rb_define_method(cArray, "indexes", ary_indexes, -2);
rb_define_method(cArray, "clone", ary_clone, 0);
+ rb_define_method(cArray, "dup", ary_dup, 0);
rb_define_method(cArray, "join", ary_join_method, -1);
rb_define_method(cArray, "reverse", ary_reverse_method, 0);
rb_define_method(cArray, "reverse!", ary_reverse, 0);
@@ -1223,6 +1200,7 @@ Init_Array()
rb_define_method(cArray, "clear", ary_clear, 0);
rb_define_method(cArray, "fill", ary_fill, -1);
rb_define_method(cArray, "include?", ary_includes, 1);
+ rb_define_method(cArray, "===", ary_includes, 1);
rb_define_method(cArray, "assoc", ary_assoc, 1);
rb_define_method(cArray, "rassoc", ary_rassoc, 1);
diff --git a/bignum.c b/bignum.c
index 7b9581c..17d9c83 100644
--- a/bignum.c
+++ b/bignum.c
@@ -18,8 +18,8 @@ VALUE cBignum;
#define BDIGITS(x) RBIGNUM(x)->digits
#define BITSPERDIG (sizeof(USHORT)*CHAR_BIT)
#define BIGRAD (1L << BITSPERDIG)
-#define DIGSPERLONG ((UINT)(sizeof(long)/sizeof(USHORT)))
-#define BIGUP(x) ((unsigned long)(x) << BITSPERDIG)
+#define DIGSPERINT ((UINT)(sizeof(INT)/sizeof(USHORT)))
+#define BIGUP(x) ((UINT)(x) << BITSPERDIG)
#define BIGDN(x) ((x) >> BITSPERDIG)
#define BIGLO(x) ((x) & (BIGRAD-1))
@@ -42,19 +42,19 @@ bignew_1(class, len, sign)
VALUE
big_clone(x)
- struct RBignum *x;
+ VALUE x;
{
- VALUE z = bignew_1(CLASS_OF(x), x->len, x->sign);
+ VALUE z = bignew_1(CLASS_OF(x), RBIGNUM(x)->len, RBIGNUM(x)->sign);
- MEMCPY(BDIGITS(z), BDIGITS(x), USHORT, x->len);
- return (VALUE)z;
+ MEMCPY(BDIGITS(z), BDIGITS(x), USHORT, RBIGNUM(x)->len);
+ return z;
}
void
big_2comp(x) /* get 2's complement */
- struct RBignum *x;
+ VALUE x;
{
- UINT i = x->len;
+ UINT i = RBIGNUM(x)->len;
USHORT *ds = BDIGITS(x);
long num;
@@ -64,26 +64,26 @@ big_2comp(x) /* get 2's complement */
num += (long)ds[i];
ds[i++] = BIGLO(num);
num = BIGDN(num);
- } while (i < x->len);
+ } while (i < RBIGNUM(x)->len);
if (ds[0] == 1 || ds[0] == 0) {
- for (i=1;i<x->len;i++) {
+ for (i=1;i<RBIGNUM(x)->len;i++) {
if (ds[i] != 0) return;
}
- REALLOC_N(BDIGITS(x), USHORT, x->len++);
+ REALLOC_N(BDIGITS(x), USHORT, RBIGNUM(x)->len++);
ds = BDIGITS(x);
- ds[x->len-1] = 1;
+ ds[RBIGNUM(x)->len-1] = 1;
}
}
static VALUE
bignorm(x)
- struct RBignum *x;
+ VALUE x;
{
- UINT len = x->len;
+ UINT len = RBIGNUM(x)->len;
USHORT *ds = BDIGITS(x);
while (len-- && !ds[len]) ;
- x->len = ++len;
+ RBIGNUM(x)->len = ++len;
if (len*sizeof(USHORT) < sizeof(VALUE) ||
(len*sizeof(USHORT) == sizeof(VALUE) &&
@@ -92,19 +92,19 @@ bignorm(x)
while (len--) {
num = BIGUP(num) + ds[len];
}
- if (x->sign) {
+ if (RBIGNUM(x)->sign) {
if (POSFIXABLE(num)) return INT2FIX(num);
}
else if (NEGFIXABLE(-num)) return INT2FIX(-num);
}
- return (VALUE)x;
+ return x;
}
VALUE
big_norm(x)
VALUE x;
{
- return bignorm(x);
+ return bignorm(RBIGNUM(x));
}
VALUE
@@ -113,38 +113,38 @@ uint2big(n)
{
UINT i = 0;
USHORT *digits;
- struct RBignum *big;
+ VALUE big;
i = 0;
- big = (struct RBignum*)bignew(DIGSPERLONG, 1);
+ big = bignew(DIGSPERINT, 1);
digits = BDIGITS(big);
- while (i < DIGSPERLONG) {
+ while (i < DIGSPERINT) {
digits[i++] = BIGLO(n);
n = BIGDN(n);
}
- i = DIGSPERLONG;
+ i = DIGSPERINT;
while (i-- && !digits[i]) ;
- big->len = i+1;
- return (VALUE)big;
+ RBIGNUM(big)->len = i+1;
+ return big;
}
VALUE
int2big(n)
- int n;
+ INT n;
{
- int neg = 0;
- struct RBignum *big;
+ INT neg = 0;
+ VALUE big;
if (n < 0) {
n = -n;
neg = 1;
}
- big = (struct RBignum*)uint2big(n);
+ big = uint2big(n);
if (neg) {
- big->sign = 0;
+ RBIGNUM(big)->sign = 0;
}
- return (VALUE)big;
+ return big;
}
VALUE
@@ -157,7 +157,7 @@ uint2inum(n)
VALUE
int2inum(n)
- int n;
+ INT n;
{
if (FIXABLE(n)) return INT2FIX(n);
return int2big(n);
@@ -209,7 +209,7 @@ str2inum(str, base)
if (POSFIXABLE(val)) {
if (sign) return INT2FIX(val);
else {
- int result = -(int)val;
+ INT result = -(INT)val;
return INT2FIX(result);
}
}
@@ -219,7 +219,7 @@ str2inum(str, base)
return big;
}
}
- len = (len/(sizeof(USHORT)*CHAR_BIT))+1;
+ len = (len/BITSPERDIG)+1;
z = bignew(len, sign);
zds = BDIGITS(z);
@@ -264,7 +264,7 @@ str2inum(str, base)
static char hexmap[] = "0123456789abcdef";
VALUE
big2str(x, base)
- struct RBignum *x;
+ VALUE x;
int base;
{
VALUE t;
@@ -276,7 +276,7 @@ big2str(x, base)
if (FIXNUM_P(x)) {
return fix2str(x, base);
}
- i = x->len;
+ i = RBIGNUM(x)->len;
if (i == 0) return str_new2("0");
if (base == 10) {
j = (sizeof(USHORT)/sizeof(char)*CHAR_BIT*i*241L)/800+2;
@@ -305,7 +305,7 @@ big2str(x, base)
ss = str_new(0, j);
s = RSTRING(ss)->ptr;
- s[0] = x->sign ? '+' : '-';
+ s[0] = RBIGNUM(x)->sign ? '+' : '-';
while (i && j) {
int k = i;
unsigned long num = 0;
@@ -324,8 +324,8 @@ big2str(x, base)
}
}
while (s[j] == '0') j++;
- RSTRING(ss)->len -= x->sign?j:j-1;
- memmove(x->sign?s:s+1, s+j, RSTRING(ss)->len);
+ RSTRING(ss)->len -= RBIGNUM(x)->sign?j:j-1;
+ memmove(RBIGNUM(x)->sign?s:s+1, s+j, RSTRING(ss)->len);
s[RSTRING(ss)->len] = '\0';
return ss;
@@ -333,17 +333,17 @@ big2str(x, base)
static VALUE
big_to_s(x)
- struct RBignum *x;
+ VALUE x;
{
return big2str(x, 10);
}
-int
+INT
big2int(x)
- struct RBignum *x;
+ VALUE x;
{
- unsigned long num;
- UINT len = x->len;
+ UINT num;
+ UINT len = RBIGNUM(x)->len;
USHORT *ds;
if (len > sizeof(long)/sizeof(USHORT))
@@ -354,7 +354,7 @@ big2int(x)
num = BIGUP(num);
num += ds[len];
}
- if (!x->sign) return -num;
+ if (!RBIGNUM(x)->sign) return -num;
return num;
}
@@ -393,16 +393,16 @@ dbl2big(d)
double
big2dbl(x)
- struct RBignum *x;
+ VALUE x;
{
double d = 0.0;
- UINT i = x->len;
+ UINT i = RBIGNUM(x)->len;
USHORT *ds = BDIGITS(x);
while (i--) {
d = ds[i] + BIGRAD*d;
}
- if (!x->sign) d = -d;
+ if (!RBIGNUM(x)->sign) d = -d;
return d;
}
@@ -415,13 +415,13 @@ big_to_f(x)
static VALUE
big_cmp(x, y)
- struct RBignum *x, *y;
+ VALUE x, y;
{
- int xlen = x->len;
+ int xlen = RBIGNUM(x)->len;
switch (TYPE(y)) {
case T_FIXNUM:
- y = (struct RBignum*)int2big(FIX2INT(y));
+ y = int2big(FIX2INT(y));
break;
case T_BIGNUM:
@@ -431,18 +431,18 @@ big_cmp(x, y)
return num_coerce_bin(x, y);
}
- if (x->sign > y->sign) return INT2FIX(1);
- if (x->sign < y->sign) return INT2FIX(-1);
- if (xlen < y->len)
- return (x->sign) ? INT2FIX(-1) : INT2FIX(1);
- if (xlen > y->len)
- return (x->sign) ? INT2FIX(1) : INT2FIX(-1);
+ if (RBIGNUM(x)->sign > RBIGNUM(y)->sign) return INT2FIX(1);
+ if (RBIGNUM(x)->sign < RBIGNUM(y)->sign) return INT2FIX(-1);
+ if (xlen < RBIGNUM(y)->len)
+ return (RBIGNUM(x)->sign) ? INT2FIX(-1) : INT2FIX(1);
+ if (xlen > RBIGNUM(y)->len)
+ return (RBIGNUM(x)->sign) ? INT2FIX(1) : INT2FIX(-1);
while(xlen-- && (BDIGITS(x)[xlen]==BDIGITS(y)[xlen]));
if (-1 == xlen) return INT2FIX(0);
return (BDIGITS(x)[xlen] > BDIGITS(y)[xlen]) ?
- (x->sign ? INT2FIX(1) : INT2FIX(-1)) :
- (x->sign ? INT2FIX(-1) : INT2FIX(1));
+ (RBIGNUM(x)->sign ? INT2FIX(1) : INT2FIX(-1)) :
+ (RBIGNUM(x)->sign ? INT2FIX(-1) : INT2FIX(1));
}
static VALUE
@@ -455,26 +455,26 @@ big_eq(x, y)
static VALUE
big_uminus(x)
- struct RBignum *x;
+ VALUE x;
{
VALUE z = big_clone(x);
- RBIGNUM(z)->sign = !x->sign;
+ RBIGNUM(z)->sign = !RBIGNUM(x)->sign;
return bignorm(z);
}
static VALUE
big_neg(x)
- struct RBignum *x;
+ VALUE x;
{
VALUE z = big_clone(x);
- UINT i = x->len;
+ UINT i = RBIGNUM(x)->len;
USHORT *ds = BDIGITS(z);
- if (!x->sign) big_2comp(z);
+ if (!RBIGNUM(x)->sign) big_2comp(z);
while (i--) ds[i] = ~ds[i];
- if (x->sign) big_2comp(z);
+ if (RBIGNUM(x)->sign) big_2comp(z);
RBIGNUM(z)->sign = !RBIGNUM(z)->sign;
return bignorm(z);
@@ -482,19 +482,19 @@ big_neg(x)
static VALUE
bigsub(x, y)
- struct RBignum *x, *y;
+ VALUE x, y;
{
- struct RBignum *z = 0;
+ VALUE z = 0;
USHORT *zds;
long num;
UINT i;
- i = x->len;
+ i = RBIGNUM(x)->len;
/* if x is larger than y, swap */
- if (x->len < y->len) {
+ if (RBIGNUM(x)->len < RBIGNUM(y)->len) {
z = x; x = y; y = z; /* swap x y */
}
- else if (x->len == y->len) {
+ else if (RBIGNUM(x)->len == RBIGNUM(y)->len) {
while (i > 0) {
i--;
if (BDIGITS(x)[i] > BDIGITS(y)[i]) {
@@ -507,20 +507,20 @@ bigsub(x, y)
}
}
- z = (struct RBignum*)bignew(x->len, (z == 0)?1:0);
+ z = bignew(RBIGNUM(x)->len, (z == 0)?1:0);
zds = BDIGITS(z);
- for (i = 0, num = 0; i < y->len; i++) {
+ for (i = 0, num = 0; i < RBIGNUM(y)->len; i++) {
num += (long)BDIGITS(x)[i] - BDIGITS(y)[i];
zds[i] = BIGLO(num);
num = BIGDN(num);
}
- while (num && i < x->len) {
+ while (num && i < RBIGNUM(x)->len) {
num += BDIGITS(x)[i];
zds[i++] = BIGLO(num);
num = BIGDN(num);
}
- while (i < x->len) {
+ while (i < RBIGNUM(x)->len) {
zds[i] = BDIGITS(x)[i];
i++;
}
@@ -530,39 +530,40 @@ bigsub(x, y)
static VALUE
bigadd(x, y, sign)
- struct RBignum *x, *y;
+ VALUE x, y;
char sign;
{
- struct RBignum *z;
+ VALUE z;
long num;
UINT i, len;
- if (x->sign == (y->sign ^ sign)) {
- if (y->sign == sign) return bigsub(y, x);
+
+ if (RBIGNUM(x)->sign == (RBIGNUM(y)->sign ^ sign)) {
+ if (RBIGNUM(y)->sign == sign) return bigsub(y, x);
return bigsub(x, y);
}
- if (x->len > y->len) {
- len = x->len + 1;
+ if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
+ len = RBIGNUM(x)->len + 1;
+ z = x; x = y; y = z;
}
else {
- len = y->len + 1;
+ len = RBIGNUM(y)->len + 1;
}
- z = (struct RBignum*)bignew(len, sign==y->sign);
+ z = bignew(len, sign==RBIGNUM(y)->sign);
- if (x->len > y->len) {
- struct RBignum* t = x; x = y; y = t;
- }
- for (i = 0, num = 0; i < x->len; i++) {
- num += (long)(BDIGITS(x)[i]) + BDIGITS(y)[i];
+ len = RBIGNUM(x)->len;
+ for (i = 0, num = 0; i < len; i++) {
+ num += (long)(BDIGITS(x)[i] + BDIGITS(y)[i]);
BDIGITS(z)[i] = BIGLO(num);
num = BIGDN(num);
}
- while (num && i < y->len) {
+ len = RBIGNUM(y)->len;
+ while (num && i < len) {
num += BDIGITS(y)[i];
BDIGITS(z)[i++] = BIGLO(num);
num = BIGDN(num);
}
- while (i < y->len) {
+ while (i < len) {
BDIGITS(z)[i] = BDIGITS(y)[i];
i++;
}
@@ -611,17 +612,17 @@ big_minus(x, y)
VALUE
big_mul(x, y)
- struct RBignum *x, *y;
+ VALUE x, y;
{
UINT i = 0, j;
unsigned long n = 0;
VALUE z;
USHORT *zds;
- if (FIXNUM_P(x)) x = (struct RBignum*)int2big(FIX2INT(x));
+ if (FIXNUM_P(x)) x = int2big(FIX2INT(x));
switch (TYPE(y)) {
case T_FIXNUM:
- y = (struct RBignum*)int2big(FIX2INT(y));
+ y = int2big(FIX2INT(y));
break;
case T_BIGNUM:
@@ -634,15 +635,15 @@ big_mul(x, y)
return num_coerce_bin(x, y);
}
- j = x->len + y->len + 1;
- z = bignew(j, x->sign==y->sign);
+ j = RBIGNUM(x)->len + RBIGNUM(y)->len + 1;
+ z = bignew(j, RBIGNUM(x)->sign==RBIGNUM(y)->sign);
zds = BDIGITS(z);
while (j--) zds[j] = 0;
- for (i = 0; i < x->len; i++) {
+ for (i = 0; i < RBIGNUM(x)->len; i++) {
unsigned long dd = BDIGITS(x)[i];
if (dd == 0) continue;
n = 0;
- for (j = 0; j < y->len; j++) {
+ for (j = 0; j < RBIGNUM(y)->len; j++) {
int ee = n + dd * BDIGITS(y)[j];
n = zds[i + j] + ee;
if (ee) zds[i + j] = BIGLO(n);
@@ -658,10 +659,10 @@ big_mul(x, y)
static void
bigdivmod(x, y, div, mod)
- struct RBignum *x, *y;
+ VALUE x, y;
VALUE *div, *mod;
{
- UINT nx = x->len, ny = y->len, i, j;
+ UINT nx = RBIGNUM(x)->len, ny = RBIGNUM(y)->len, i, j;
VALUE z;
USHORT *xds, *yds, *zds, *tds;
unsigned long t2;
@@ -688,17 +689,17 @@ bigdivmod(x, y, div, mod)
}
if (div) *div = bignorm(z);
if (mod) {
- if (!y->sign) t2 = -t2;
+ if (!RBIGNUM(y)->sign) t2 = -t2;
*mod = INT2FIX(t2);
}
return;
}
- z = bignew(nx==ny?nx+2:nx+1, x->sign==y->sign);
+ z = bignew(nx==ny?nx+2:nx+1, RBIGNUM(x)->sign==RBIGNUM(y)->sign);
zds = BDIGITS(z);
if (nx==ny) zds[nx+1] = 0;
while (!yds[ny-1]) ny--;
if ((dd = BIGRAD/(int)(yds[ny-1]+1)) != 1) {
- y = (struct RBignum*)big_clone(y);
+ y = big_clone(y);
tds = BDIGITS(y);
j = 0;
num = 0;
@@ -771,7 +772,7 @@ bigdivmod(x, y, div, mod)
}
}
RBIGNUM(*mod)->len = ny;
- RBIGNUM(*mod)->sign = y->sign;
+ RBIGNUM(*mod)->sign = RBIGNUM(y)->sign;
*mod = bignorm(*mod);
}
}
@@ -897,7 +898,7 @@ big_pow(x, y)
VALUE
big_and(x, y)
- struct RBignum *x, *y;
+ VALUE x, y;
{
VALUE z;
USHORT *ds1, *ds2, *zds;
@@ -905,35 +906,35 @@ big_and(x, y)
char sign;
if (FIXNUM_P(y)) {
- y = (struct RBignum*)int2big(FIX2INT(y));
+ y = int2big(FIX2INT(y));
}
else {
Check_Type(y, T_BIGNUM);
}
- if (!y->sign) {
- y = (struct RBignum*)big_clone(y);
+ if (!RBIGNUM(y)->sign) {
+ y = big_clone(y);
big_2comp(y);
}
- if (!x->sign) {
- x = (struct RBignum*)big_clone(x);
+ if (!RBIGNUM(x)->sign) {
+ x = big_clone(x);
big_2comp(x);
}
- if (x->len > y->len) {
- l1 = y->len;
- l2 = x->len;
+ if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
+ l1 = RBIGNUM(y)->len;
+ l2 = RBIGNUM(x)->len;
ds1 = BDIGITS(y);
ds2 = BDIGITS(x);
- sign = y->sign;
+ sign = RBIGNUM(y)->sign;
}
else {
- l1 = x->len;
- l2 = y->len;
+ l1 = RBIGNUM(x)->len;
+ l2 = RBIGNUM(y)->len;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
- sign = x->sign;
+ sign = RBIGNUM(x)->sign;
}
- z = bignew(l2, x->sign && y->sign);
+ z = bignew(l2, RBIGNUM(x)->sign && RBIGNUM(y)->sign);
zds = BDIGITS(z);
for (i=0; i<l1; i++) {
@@ -948,7 +949,7 @@ big_and(x, y)
VALUE
big_or(x, y)
- struct RBignum *x, *y;
+ VALUE x, y;
{
VALUE z;
USHORT *ds1, *ds2, *zds;
@@ -956,35 +957,35 @@ big_or(x, y)
char sign;
if (FIXNUM_P(y)) {
- y = (struct RBignum*)int2big(FIX2INT(y));
+ y = int2big(FIX2INT(y));
}
else {
Check_Type(y, T_BIGNUM);
}
- if (!y->sign) {
- y = (struct RBignum*)big_clone(y);
+ if (!RBIGNUM(y)->sign) {
+ y = big_clone(y);
big_2comp(y);
}
- if (!x->sign) {
- x = (struct RBignum*)big_clone(x);
+ if (!RBIGNUM(x)->sign) {
+ x = big_clone(x);
big_2comp(x);
}
- if (x->len > y->len) {
- l1 = y->len;
- l2 = x->len;
+ if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
+ l1 = RBIGNUM(y)->len;
+ l2 = RBIGNUM(x)->len;
ds1 = BDIGITS(y);
ds2 = BDIGITS(x);
- sign = y->sign;
+ sign = RBIGNUM(y)->sign;
}
else {
- l1 = x->len;
- l2 = y->len;
+ l1 = RBIGNUM(x)->len;
+ l2 = RBIGNUM(y)->len;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
- sign = x->sign;
+ sign = RBIGNUM(x)->sign;
}
- z = bignew(l2, x->sign || y->sign);
+ z = bignew(l2, RBIGNUM(x)->sign || RBIGNUM(y)->sign);
zds = BDIGITS(z);
for (i=0; i<l1; i++) {
@@ -1000,7 +1001,7 @@ big_or(x, y)
VALUE
big_xor(x, y)
- struct RBignum *x, *y;
+ VALUE x, y;
{
VALUE z;
USHORT *ds1, *ds2, *zds;
@@ -1008,37 +1009,37 @@ big_xor(x, y)
char sign;
if (FIXNUM_P(y)) {
- y = (struct RBignum*)int2big(FIX2INT(y));
+ y = int2big(FIX2INT(y));
}
else {
Check_Type(y, T_BIGNUM);
}
- if (!y->sign) {
- y = (struct RBignum*)big_clone(y);
+ if (!RBIGNUM(y)->sign) {
+ y = big_clone(y);
big_2comp(y);
}
- if (!x->sign) {
- x = (struct RBignum*)big_clone(x);
+ if (!RBIGNUM(x)->sign) {
+ x = big_clone(x);
big_2comp(x);
}
- if (x->len > y->len) {
- l1 = y->len;
- l2 = x->len;
+ if (RBIGNUM(x)->len > RBIGNUM(y)->len) {
+ l1 = RBIGNUM(y)->len;
+ l2 = RBIGNUM(x)->len;
ds1 = BDIGITS(y);
ds2 = BDIGITS(x);
- sign = y->sign;
+ sign = RBIGNUM(y)->sign;
}
else {
- l1 = x->len;
- l2 = y->len;
+ l1 = RBIGNUM(x)->len;
+ l2 = RBIGNUM(y)->len;
ds1 = BDIGITS(x);
ds2 = BDIGITS(y);
- sign = x->sign;
+ sign = RBIGNUM(x)->sign;
}
- x->sign = x->sign?1:0;
- y->sign = y->sign?1:0;
- z = bignew(l2, !(x->sign ^ y->sign));
+ RBIGNUM(x)->sign = RBIGNUM(x)->sign?1:0;
+ RBIGNUM(y)->sign = RBIGNUM(y)->sign?1:0;
+ z = bignew(l2, !(RBIGNUM(x)->sign ^ RBIGNUM(y)->sign));
zds = BDIGITS(z);
for (i=0; i<l1; i++) {
@@ -1056,21 +1057,20 @@ static VALUE big_rshift();
VALUE
big_lshift(x, y)
- struct RBignum *x;
- VALUE y;
+ VALUE x, y;
{
USHORT *xds, *zds;
int shift = NUM2INT(y);
- UINT s1 = shift/(sizeof(USHORT)*CHAR_BIT);
- UINT s2 = shift%(sizeof(USHORT)*CHAR_BIT);
+ UINT s1 = shift/BITSPERDIG;
+ UINT s2 = shift%BITSPERDIG;
VALUE z;
unsigned long num = 0;
UINT len, i;
if (shift < 0) return big_rshift(x, INT2FIX(-shift));
xds = BDIGITS(x);
- len = x->len;
- z = bignew(len+s1+1, x->sign);
+ len = RBIGNUM(x)->len;
+ z = bignew(len+s1+1, RBIGNUM(x)->sign);
zds = BDIGITS(z);
for (i=0; i<s1; i++) {
*zds++ = 0;
@@ -1086,27 +1086,27 @@ big_lshift(x, y)
static VALUE
big_rshift(x, y)
- struct RBignum *x;
- VALUE y;
+ VALUE x, y;
{
USHORT *xds, *zds;
int shift = NUM2INT(y);
- UINT s1 = shift/(sizeof(USHORT)*CHAR_BIT);
- UINT s2 = shift%(sizeof(USHORT)*CHAR_BIT);
+ UINT s1 = shift/BITSPERDIG;
+ UINT s2 = shift%BITSPERDIG;
VALUE z;
unsigned long num = 0;
- UINT i = x->len, j;
+ UINT i = RBIGNUM(x)->len;
+ UINT j;
if (shift < 0) return big_lshift(x, INT2FIX(-shift));
- if (s1 > x->len) {
- if (x->sign)
+ if (s1 > RBIGNUM(x)->len) {
+ if (RBIGNUM(x)->sign)
return INT2FIX(0);
else
return INT2FIX(-1);
}
xds = BDIGITS(x);
- i = x->len; j = i - s1;
- z = bignew(j, x->sign);
+ i = RBIGNUM(x)->len; j = i - s1;
+ z = bignew(j, RBIGNUM(x)->sign);
zds = BDIGITS(z);
while (i--, j--) {
num = (num | xds[i]) >> s2;
@@ -1118,24 +1118,23 @@ big_rshift(x, y)
static VALUE
big_aref(x, y)
- struct RBignum *x;
- VALUE y;
+ VALUE x, y;
{
USHORT *xds;
int shift = NUM2INT(y);
UINT s1, s2;
if (shift < 0) return INT2FIX(0);
- s1 = shift/(sizeof(USHORT)*CHAR_BIT);
- s2 = shift%(sizeof(USHORT)*CHAR_BIT);
+ s1 = shift/BITSPERDIG;
+ s2 = shift%BITSPERDIG;
- if (!x->sign) {
- if (s1 >= x->len) return INT2FIX(1);
- x = (struct RBignum*)big_clone(x);
+ if (!RBIGNUM(x)->sign) {
+ if (s1 >= RBIGNUM(x)->len) return INT2FIX(1);
+ x = big_clone(x);
big_2comp(x);
}
else {
- if (s1 >= x->len) return INT2FIX(0);
+ if (s1 >= RBIGNUM(x)->len) return INT2FIX(0);
}
xds = BDIGITS(x);
if (xds[s1] & (1<<s2))
@@ -1145,13 +1144,13 @@ big_aref(x, y)
static VALUE
big_hash(x)
- struct RBignum *x;
+ VALUE x;
{
int i, len, key;
USHORT *digits;
key = 0; digits = BDIGITS(x);
- for (i=0,len=x->len; i<x->len; i++) {
+ for (i=0,len=RBIGNUM(x)->len; i<RBIGNUM(x)->len; i++) {
key ^= *digits++;
}
return INT2FIX(key);
@@ -1159,8 +1158,7 @@ big_hash(x)
static VALUE
big_coerce(x, y)
- struct RBignum *x;
- VALUE y;
+ VALUE x, y;
{
if (FIXNUM_P(y)) {
return assoc_new(int2big(FIX2INT(y)), x);
@@ -1173,11 +1171,11 @@ big_coerce(x, y)
static VALUE
big_abs(x)
- struct RBignum *x;
+ VALUE x;
{
- if (!x->sign) {
- x = (struct RBignum*)big_clone(x);
- x->sign = 1;
+ if (!RBIGNUM(x)->sign) {
+ x = big_clone(x);
+ RBIGNUM(x)->sign = 1;
}
return (VALUE)x;
}
@@ -1188,12 +1186,12 @@ big_abs(x)
VALUE
big_rand(max)
- struct RBignum *max;
+ VALUE max;
{
struct RBignum *v;
int len;
- len = max->len;
+ len = RBIGNUM(max)->len;
v = RBIGNUM(bignew(len,1));
while (len--) {
#ifdef HAVE_RANDOM
@@ -1208,9 +1206,9 @@ big_rand(max)
static VALUE
big_size(big)
- struct RBignum *big;
+ VALUE big;
{
- return INT2FIX(big->len*2);
+ return INT2FIX(RBIGNUM(big)->len*sizeof(USHORT));
}
void
diff --git a/class.c b/class.c
index b78b2aa..13c9298 100644
--- a/class.c
+++ b/class.c
@@ -22,28 +22,27 @@ extern VALUE cModule;
VALUE
class_new(super)
- struct RClass *super;
+ VALUE super;
{
- NEWOBJ(cls, struct RClass);
- OBJSETUP(cls, cClass, T_CLASS);
+ NEWOBJ(klass, struct RClass);
+ OBJSETUP(klass, cClass, T_CLASS);
- cls->super = super;
- cls->iv_tbl = 0;
- cls->m_tbl = 0; /* safe GC */
- cls->m_tbl = new_idhash();
+ klass->super = super;
+ klass->iv_tbl = 0;
+ klass->m_tbl = 0; /* safe GC */
+ klass->m_tbl = new_idhash();
- return (VALUE)cls;
+ return (VALUE)klass;
}
VALUE
singleton_class_new(super)
- struct RClass *super;
+ VALUE super;
{
- struct RClass *cls = (struct RClass*)class_new(super);
-
- FL_SET(cls, FL_SINGLETON);
+ VALUE klass = class_new(super);
- return (VALUE)cls;
+ FL_SET(klass, FL_SINGLETON);
+ return klass;
}
static int
@@ -57,40 +56,50 @@ clone_method(mid, body, tbl)
}
VALUE
-singleton_class_clone(class)
- struct RClass *class;
+singleton_class_clone(klass)
+ VALUE klass;
{
- if (!FL_TEST(class, FL_SINGLETON))
- return (VALUE)class;
+ if (!FL_TEST(klass, FL_SINGLETON))
+ return klass;
else {
/* copy singleton(unnamed) class */
NEWOBJ(clone, struct RClass);
- CLONESETUP(clone, class);
+ CLONESETUP(clone, klass);
- clone->super = class->super;
+ clone->super = RCLASS(klass)->super;
clone->iv_tbl = 0;
clone->m_tbl = 0;
clone->m_tbl = new_idhash();
- st_foreach(class->m_tbl, clone_method, clone->m_tbl);
+ st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl);
FL_SET(clone, FL_SINGLETON);
return (VALUE)clone;
}
}
+void
+singleton_class_attached(klass, obj)
+ VALUE klass, obj;
+{
+ if (FL_TEST(klass, FL_SINGLETON))
+ rb_iv_set(klass, "__attached__", obj);
+}
+
VALUE
rb_define_class_id(id, super)
ID id;
- struct RBasic *super;
+ VALUE super;
{
- struct RClass *cls;
+ VALUE klass;
- if (!super) super = (struct RBasic*)cClass;
- cls = (struct RClass*)class_new(super);
- rb_name_class(cls, id);
+ if (!super) super = cObject;
+ klass = class_new(super);
+ rb_name_class(klass, id);
/* make metaclass */
- RBASIC(cls)->class = singleton_class_new(super->class);
+ RBASIC(klass)->class = singleton_class_new(RBASIC(super)->class);
+ singleton_class_attached(RBASIC(klass)->class, klass);
+ rb_funcall(super, rb_intern("inherited"), 1, klass);
- return (VALUE)cls;
+ return (VALUE)klass;
}
VALUE
@@ -98,14 +107,14 @@ rb_define_class(name, super)
char *name;
VALUE super;
{
- VALUE class;
+ VALUE klass;
ID id;
id = rb_intern(name);
- class = rb_define_class_id(id, super);
- st_add_direct(rb_class_tbl, id, class);
+ klass = rb_define_class_id(id, super);
+ st_add_direct(rb_class_tbl, id, klass);
- return class;
+ return klass;
}
VALUE
@@ -114,15 +123,15 @@ rb_define_class_under(under, name, super)
char *name;
VALUE super;
{
- VALUE class;
+ VALUE klass;
ID id;
id = rb_intern(name);
- class = rb_define_class_id(id, super);
- rb_const_set(under, id, class);
- rb_set_class_path(class, under, name);
+ klass = rb_define_class_id(id, super);
+ rb_const_set(under, id, klass);
+ rb_set_class_path(klass, under, name);
- return class;
+ return klass;
}
VALUE
@@ -144,11 +153,11 @@ rb_define_module_id(id)
ID id;
{
extern st_table *rb_class_tbl;
- struct RClass *mdl = (struct RClass*)module_new();
+ VALUE mdl = module_new();
rb_name_class(mdl, id);
- return (VALUE)mdl;
+ return mdl;
}
VALUE
@@ -181,31 +190,31 @@ rb_define_module_under(under, name)
return module;
}
-static struct RClass *
+static VALUE
include_class_new(module, super)
- struct RClass *module, *super;
+ VALUE module, super;
{
- NEWOBJ(cls, struct RClass);
- OBJSETUP(cls, cClass, T_ICLASS);
+ NEWOBJ(klass, struct RClass);
+ OBJSETUP(klass, cClass, T_ICLASS);
- cls->m_tbl = module->m_tbl;
- cls->iv_tbl = module->iv_tbl;
- cls->super = super;
+ klass->m_tbl = RCLASS(module)->m_tbl;
+ klass->iv_tbl = RCLASS(module)->iv_tbl;
+ klass->super = super;
if (TYPE(module) == T_ICLASS) {
- RBASIC(cls)->class = RBASIC(module)->class;
+ RBASIC(klass)->class = RBASIC(module)->class;
}
else {
- RBASIC(cls)->class = (VALUE)module;
+ RBASIC(klass)->class = module;
}
- return cls;
+ return (VALUE)klass;
}
void
-rb_include_module(class, module)
- VALUE class, module;
+rb_include_module(klass, module)
+ VALUE klass, module;
{
- struct RClass *p;
+ VALUE p;
if (NIL_P(module)) return;
@@ -217,71 +226,233 @@ rb_include_module(class, module)
Check_Type(module, T_MODULE);
}
- if (class == module) return;
+ if (klass == module) return;
rb_clear_cache();
while (module) {
/* ignore if the module included already in superclasses */
- for (p = RCLASS(class)->super; p; p = p->super) {
- if (BUILTIN_TYPE(p) == T_ICLASS && p->m_tbl == RCLASS(module)->m_tbl)
+ for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
+ if (BUILTIN_TYPE(p) == T_ICLASS &&
+ RCLASS(p)->m_tbl == RCLASS(module)->m_tbl)
return;
}
- RCLASS(class)->super = include_class_new(module, RCLASS(class)->super);
- class = (VALUE)RCLASS(class)->super;
- module = (VALUE)RCLASS(module)->super;
+ RCLASS(klass)->super =
+ include_class_new(module, RCLASS(klass)->super);
+ klass = RCLASS(klass)->super;
+ module = RCLASS(module)->super;
+ }
+}
+
+VALUE
+mod_included_modules(mod)
+ VALUE mod;
+{
+ VALUE ary = ary_new();
+ VALUE p;
+
+ for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
+ if (BUILTIN_TYPE(p) == T_ICLASS) {
+ ary_push(ary, RBASIC(p)->class);
+ }
}
+ return ary;
+}
+
+VALUE
+mod_ancestors(mod)
+ VALUE mod;
+{
+ VALUE ary = ary_new();
+ VALUE p;
+
+ for (p = mod; p; p = RCLASS(p)->super) {
+ if (BUILTIN_TYPE(p) == T_ICLASS) {
+ ary_push(ary, RBASIC(p)->class);
+ }
+ else {
+ ary_push(ary, p);
+ }
+ }
+ return ary;
+}
+
+static int
+ins_methods_i(key, body, ary)
+ ID key;
+ NODE *body;
+ VALUE ary;
+{
+ if (!body->nd_noex) {
+ VALUE name = str_new2(rb_id2name(key));
+
+ if (!ary_includes(ary, name)) {
+ if (!body->nd_body) {
+ ary_push(ary, Qnil);
+ }
+ ary_push(ary, name);
+ }
+ }
+ else if (nd_type(body->nd_body) == NODE_ZSUPER) {
+ ary_push(ary, Qnil);
+ ary_push(ary, str_new2(rb_id2name(key)));
+ }
+ return ST_CONTINUE;
+}
+
+static int
+ins_methods_priv_i(key, body, ary)
+ ID key;
+ NODE *body;
+ VALUE ary;
+{
+ if (!body->nd_body) {
+ ary_push(ary, Qnil);
+ ary_push(ary, str_new2(rb_id2name(key)));
+ }
+ else if (body->nd_noex) {
+ VALUE name = str_new2(rb_id2name(key));
+
+ if (!ary_includes(ary, name)) {
+ ary_push(ary, name);
+ }
+ }
+ else if (nd_type(body->nd_body) == NODE_ZSUPER) {
+ ary_push(ary, Qnil);
+ ary_push(ary, str_new2(rb_id2name(key)));
+ }
+ return ST_CONTINUE;
+}
+
+static VALUE
+method_list(mod, option, func)
+ VALUE mod;
+ int option;
+ int (*func)();
+{
+ VALUE ary;
+ VALUE klass;
+ VALUE *p, *q, *pend;
+
+ ary = ary_new();
+ for (klass = mod; klass; klass = RCLASS(klass)->super) {
+ st_foreach(RCLASS(klass)->m_tbl, func, ary);
+ if (!option) break;
+ }
+ p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
+ while (p < pend) {
+ if (*p == Qnil) {
+ p+=2;
+ continue;
+ }
+ *q++ = *p++;
+ }
+ RARRAY(ary)->len = q - RARRAY(ary)->ptr;
+ return ary;
+}
+
+VALUE
+class_instance_methods(argc, argv, mod)
+ int argc;
+ VALUE *argv;
+ VALUE mod;
+{
+ VALUE option;
+
+ rb_scan_args(argc, argv, "01", &option);
+ return method_list(mod, RTEST(option), ins_methods_i);
+}
+
+VALUE
+class_private_instance_methods(argc, argv, mod)
+ int argc;
+ VALUE *argv;
+ VALUE mod;
+{
+ VALUE option;
+
+ rb_scan_args(argc, argv, "01", &option);
+ return method_list(mod, RTEST(option), ins_methods_priv_i);
+}
+
+VALUE
+obj_singleton_methods(obj)
+ VALUE obj;
+{
+ VALUE ary;
+ VALUE klass;
+ VALUE *p, *q, *pend;
+
+ ary = ary_new();
+ klass = CLASS_OF(obj);
+ while (klass && FL_TEST(klass, FL_SINGLETON)) {
+ st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
+ klass = RCLASS(klass)->super;
+ }
+ p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
+ while (p < pend) {
+ if (*p == Qnil) {
+ p+=2;
+ continue;
+ }
+ *q++ = *p++;
+ }
+ RARRAY(ary)->len = q - RARRAY(ary)->ptr;
+
+ return ary;
}
void
-rb_define_method_id(class, name, func, argc)
- struct RClass *class;
+rb_define_method_id(klass, name, func, argc)
+ VALUE klass;
ID name;
VALUE (*func)();
int argc;
{
- rb_add_method(class, name, NEW_CFUNC(func, argc), NOEX_PUBLIC);
+ rb_add_method(klass, name, NEW_CFUNC(func, argc), NOEX_PUBLIC);
}
void
-rb_define_method(class, name, func, argc)
- VALUE class;
+rb_define_method(klass, name, func, argc)
+ VALUE klass;
char *name;
VALUE (*func)();
int argc;
{
- rb_add_method(class, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC);
+ rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC);
}
void
-rb_undef_method(class, name)
- VALUE class;
+rb_undef_method(klass, name)
+ VALUE klass;
char *name;
{
- rb_add_method(class, rb_intern(name), 0, NOEX_PUBLIC);
+ rb_add_method(klass, rb_intern(name), 0, NOEX_PUBLIC);
}
void
-rb_define_private_method(class, name, func, argc)
- struct RClass *class;
+rb_define_private_method(klass, name, func, argc)
+ VALUE klass;
char *name;
VALUE (*func)();
int argc;
{
- rb_add_method(class, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);
+ rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE);
}
VALUE
rb_singleton_class(obj)
- struct RBasic *obj;
+ VALUE obj;
{
- if (rb_special_const_p((VALUE)obj)) {
+ if (rb_special_const_p(obj)) {
TypeError("cannot define singleton");
}
- if (FL_TEST(obj->class, FL_SINGLETON)) {
- return (VALUE)obj->class;
+ if (FL_TEST(RBASIC(obj)->class, FL_SINGLETON)) {
+ return (VALUE)RBASIC(obj)->class;
}
- return obj->class = singleton_class_new(obj->class);
+ RBASIC(obj)->class = singleton_class_new(RBASIC(obj)->class);
+ singleton_class_attached(RBASIC(obj)->class, obj);
+ return RBASIC(obj)->class;
}
void
@@ -305,7 +476,7 @@ rb_define_module_function(module, name, func, argc)
rb_define_singleton_method(module, name, func, argc);
}
-VALUE mKernel;
+extern VALUE mKernel;
void
rb_define_global_function(name, func, argc)
@@ -317,18 +488,18 @@ rb_define_global_function(name, func, argc)
}
void
-rb_define_alias(class, name1, name2)
- VALUE class;
+rb_define_alias(klass, name1, name2)
+ VALUE klass;
char *name1, *name2;
{
- rb_alias(class, rb_intern(name1), rb_intern(name2));
+ rb_alias(klass, rb_intern(name1), rb_intern(name2));
}
void
-rb_define_attr(class, id, pub)
- VALUE class;
+rb_define_attr(klass, id, read, write)
+ VALUE klass;
ID id;
- int pub;
+ int read, write;
{
char *name;
char *buf;
@@ -341,11 +512,11 @@ rb_define_attr(class, id, pub)
attreq = rb_intern(buf);
sprintf(buf, "@%s", name);
attriv = rb_intern(buf);
- if (!rb_method_boundp(class, attr, NOEX_PRIVATE)) {
- rb_add_method(class, attr, NEW_IVAR(attriv), 0);
+ if (read) {
+ rb_add_method(klass, attr, NEW_IVAR(attriv), 0);
}
- if (pub && !rb_method_boundp(class, attreq, NOEX_PRIVATE)) {
- rb_add_method(class, attreq, NEW_ATTRSET(attriv), 0);
+ if (write) {
+ rb_add_method(klass, attreq, NEW_ATTRSET(attriv), 0);
}
}
diff --git a/defines.h b/defines.h
index 74736ad..a24f9eb 100644
--- a/defines.h
+++ b/defines.h
@@ -38,7 +38,7 @@
#define FLUSH_REGISTER_WINDOWS /* empty */
#endif
-#ifdef __human68k__
+#if defined(__human68k__) || defined(__CYGWIN32__)
#undef HAVE_RANDOM
#undef HAVE_SETITIMER
#endif
diff --git a/dir.c b/dir.c
index d8f56f5..29ce261 100644
--- a/dir.c
+++ b/dir.c
@@ -13,15 +13,16 @@
#include "ruby.h"
#include <sys/types.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+#include <sys/stat.h>
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#else
# define MAXPATHLEN 1024
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#if HAVE_DIRENT_H
# include <dirent.h>
@@ -60,22 +61,21 @@ free_dir(dir)
static VALUE
dir_s_open(dir_class, dirname)
- VALUE dir_class;
- struct RString *dirname;
+ VALUE dir_class, dirname;
{
VALUE obj;
DIR *dirp;
Check_SafeStr(dirname);
- dirp = opendir(dirname->ptr);
+ dirp = opendir(RSTRING(dirname)->ptr);
if (dirp == NULL) {
if (errno == EMFILE || errno == ENFILE) {
- gc();
- dirp = opendir(dirname->ptr);
+ gc_gc();
+ dirp = opendir(RSTRING(dirname)->ptr);
}
if (dirp == NULL) {
- rb_sys_fail(dirname->ptr);
+ rb_sys_fail(RSTRING(dirname)->ptr);
}
}
@@ -178,7 +178,7 @@ dir_s_chdir(argc, argv, obj)
rb_secure(2);
rb_scan_args(argc, argv, "01", &path);
- if (path) {
+ if (!NIL_P(path)) {
Check_SafeStr(path);
dist = RSTRING(path)->ptr;
}
@@ -259,13 +259,12 @@ dir_s_mkdir(argc, argv, obj)
static VALUE
dir_s_rmdir(obj, dir)
- VALUE obj;
- struct RString *dir;
+ VALUE obj, dir;
{
rb_secure(2);
Check_SafeStr(dir);
- if (rmdir(dir->ptr) < 0)
- rb_sys_fail(dir->ptr);
+ if (rmdir(RSTRING(dir)->ptr) < 0)
+ rb_sys_fail(RSTRING(dir)->ptr);
return TRUE;
}
@@ -342,18 +341,18 @@ push_braces(ary, s)
}
static VALUE
-dir_s_glob(dir, str)
- VALUE dir;
- struct RString *str;
+dir_s_glob(dir, vstr)
+ VALUE dir, vstr;
{
char *p, *pend;
char buf[MAXPATHLEN];
char *t, *t0;
int nest;
VALUE ary;
+ struct RString *str;
- Check_SafeStr(str);
-
+ Check_SafeStr(vstr);
+ str = RSTRING(vstr);
ary = ary_new();
p = str->ptr;
@@ -386,8 +385,7 @@ dir_s_glob(dir, str)
static VALUE
dir_foreach(io, dirname)
- VALUE io;
- struct RString *dirname;
+ VALUE io, dirname;
{
VALUE dir;
diff --git a/dln.c b/dln.c
index 23edc6f..f4ab012 100644
--- a/dln.c
+++ b/dln.c
@@ -24,6 +24,12 @@ char *dln_argv0;
#include <alloca.h>
#endif
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# include <strings.h>
+#endif
+
void *xmalloc();
void *xcalloc();
void *xrealloc();
@@ -47,15 +53,8 @@ void *xrealloc();
# include <unistd.h>
#endif
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else
-# include <strings.h>
-#endif
-
#ifndef NT
char *strdup();
-
char *getenv();
#endif
@@ -1069,7 +1068,6 @@ dln_sym(name)
#ifdef _AIX
#include <ctype.h> /* for isdigit() */
#include <errno.h> /* for global errno */
-#include <string.h> /* for strerror() */
#include <sys/ldr.h>
#endif
@@ -1077,6 +1075,10 @@ dln_sym(name)
/*#include <mach-o/rld.h>*/
#endif
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
static char *
dln_strerror()
{
@@ -1104,6 +1106,20 @@ dln_strerror()
#ifdef USE_DLN_DLOPEN
return (char*)dlerror();
#endif
+
+#ifdef _WIN32
+ static char message[1024];
+ FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ message,
+ sizeof message,
+ NULL);
+
+ return message;
+#endif
}
@@ -1159,6 +1175,43 @@ void
dln_load(file)
char *file;
{
+#ifdef _WIN32
+ HINSTANCE handle;
+ char winfile[255];
+ void (*init_fct)();
+ char buf[MAXPATHLEN];
+
+ /* Load the file as an object one */
+ init_funcname(buf, file);
+
+#ifdef __CYGWIN32__
+ cygwin32_conv_to_win32_path(file, winfile);
+#else
+ strcpy(winfile, file);
+#endif
+
+ /* Load file */
+ if ((handle =
+ LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) {
+ printf("LoadLibraryExA\n");
+ goto failed;
+ }
+
+#ifdef __CYGWIN32__
+ init_fct = (void(*)())GetProcAddress(handle, "impure_setup");
+
+ if (init_fct)
+ init_fct(_impure_ptr);
+#endif
+
+ if ((init_fct = (void(*)())GetProcAddress(handle, buf)) == NULL) {
+ printf("GetProcAddress %s\n", buf);
+ goto failed;
+ }
+ /* Call the init code */
+ (*init_fct)();
+ return;
+#else
#ifdef USE_DLN_A_OUT
if (load(file) == -1) {
goto failed;
@@ -1175,7 +1228,6 @@ dln_load(file)
{
void *handle;
void (*init_fct)();
- int len = strlen(file);
# ifndef RTLD_LAZY
# define RTLD_LAZY 1
@@ -1280,6 +1332,7 @@ dln_load(file)
#endif
#endif /* USE_DLN_A_OUT */
+#endif
#if !defined(_AIX) && !defined(NeXT)
failed:
LoadError("%s - %s", dln_strerror(), file);
diff --git a/enum.c b/enum.c
index 5074170..d8e2fcd 100644
--- a/enum.c
+++ b/enum.c
@@ -15,29 +15,31 @@
VALUE mEnumerable;
static ID id_each, id_eqq, id_cmp;
-void
+VALUE
rb_each(obj)
VALUE obj;
{
- rb_funcall(obj, id_each, 0, 0);
+ return rb_funcall(obj, id_each, 0, 0);
}
-static void
+static VALUE
grep_i(i, arg)
VALUE i, *arg;
{
if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) {
ary_push(arg[1], i);
}
+ return Qnil;
}
-static void
+static VALUE
grep_iter_i(i, pat)
VALUE i, pat;
{
if (RTEST(rb_funcall(pat, id_eqq, 1, i))) {
rb_yield(i);
}
+ return Qnil;
}
static VALUE
@@ -52,7 +54,7 @@ enum_grep(obj, pat)
VALUE tmp, arg[2];
arg[0] = pat; arg[1] = tmp = ary_new();
- rb_iterate(rb_each, obj, grep_i, arg);
+ rb_iterate(rb_each, obj, grep_i, (VALUE)arg);
return tmp;
}
@@ -63,7 +65,7 @@ struct find_arg {
VALUE val;
};
-static void
+static VALUE
find_i(i, arg)
VALUE i;
struct find_arg *arg;
@@ -71,14 +73,15 @@ find_i(i, arg)
if (RTEST(rb_yield(i))) {
arg->found = TRUE;
arg->val = i;
- rb_break();
+ rb_iter_break();
}
+ return Qnil;
}
static VALUE
enum_find(argc, argv, obj)
int argc;
- VALUE argv;
+ VALUE* argv;
VALUE obj;
{
struct find_arg arg;
@@ -86,7 +89,7 @@ enum_find(argc, argv, obj)
rb_scan_args(argc, argv, "01", &if_none);
arg.found = FALSE;
- rb_iterate(rb_each, obj, find_i, &arg);
+ rb_iterate(rb_each, obj, find_i, (VALUE)&arg);
if (arg.found) {
return arg.val;
}
@@ -96,13 +99,14 @@ enum_find(argc, argv, obj)
return Qnil;
}
-static void
+static VALUE
find_all_i(i, tmp)
VALUE i, tmp;
{
if (RTEST(rb_yield(i))) {
ary_push(tmp, i);
}
+ return Qnil;
}
static VALUE
@@ -117,7 +121,7 @@ enum_find_all(obj)
return tmp;
}
-static void
+static VALUE
collect_i(i, tmp)
VALUE i, tmp;
{
@@ -127,6 +131,7 @@ collect_i(i, tmp)
if (RTEST(retval)) {
ary_push(tmp, retval);
}
+ return Qnil;
}
static VALUE
@@ -141,11 +146,12 @@ enum_collect(obj)
return tmp;
}
-static void
+static VALUE
reverse_i(i, tmp)
VALUE i, tmp;
{
ary_unshift(tmp, i);
+ return Qnil;
}
static VALUE
@@ -160,11 +166,12 @@ enum_reverse(obj)
return tmp;
}
-static void
+static VALUE
enum_all(i, ary)
VALUE i, ary;
{
ary_push(ary, i);
+ return Qnil;
}
static VALUE
@@ -186,7 +193,7 @@ enum_sort(obj)
return ary_sort(enum_to_a(obj));
}
-static void
+static VALUE
min_i(i, min)
VALUE i, *min;
{
@@ -199,9 +206,10 @@ min_i(i, min)
if (FIX2INT(cmp) < 0)
*min = i;
}
+ return Qnil;
}
-static void
+static VALUE
min_ii(i, min)
VALUE i, *min;
{
@@ -214,6 +222,7 @@ min_ii(i, min)
if (FIX2INT(cmp) < 0)
*min = i;
}
+ return Qnil;
}
static VALUE
@@ -222,11 +231,11 @@ enum_min(obj)
{
VALUE min = Qnil;
- rb_iterate(rb_each, obj, iterator_p()?min_ii:min_i, &min);
+ rb_iterate(rb_each, obj, iterator_p()?min_ii:min_i, (VALUE)&min);
return min;
}
-static void
+static VALUE
max_i(i, max)
VALUE i, *max;
{
@@ -239,9 +248,10 @@ max_i(i, max)
if (FIX2INT(cmp) > 0)
*max = i;
}
+ return Qnil;
}
-static void
+static VALUE
max_ii(i, max)
VALUE i, *max;
{
@@ -254,6 +264,7 @@ max_ii(i, max)
if (FIX2INT(cmp) > 0)
*max = i;
}
+ return Qnil;
}
static VALUE
@@ -262,7 +273,7 @@ enum_max(obj)
{
VALUE max = Qnil;
- rb_iterate(rb_each, obj, iterator_p()?max_ii:max_i, &max);
+ rb_iterate(rb_each, obj, iterator_p()?max_ii:max_i, (VALUE)&max);
return max;
}
@@ -272,18 +283,19 @@ struct i_v_pair {
int found;
};
-static void
+static VALUE
index_i(item, iv)
VALUE item;
struct i_v_pair *iv;
{
if (rb_equal(item, iv->v)) {
iv->found = 1;
- rb_break();
+ rb_iter_break();
}
else {
iv->i++;
}
+ return Qnil;
}
static VALUE
@@ -295,20 +307,21 @@ enum_index(obj, val)
iv.i = 0;
iv.v = val;
iv.found = 0;
- rb_iterate(rb_each, obj, index_i, &iv);
+ rb_iterate(rb_each, obj, index_i, (VALUE)&iv);
if (iv.found) return INT2FIX(iv.i);
return Qnil; /* not found */
}
-static void
+static VALUE
member_i(item, iv)
VALUE item;
struct i_v_pair *iv;
{
if (rb_equal(item, iv->v)) {
iv->i = 1;
- rb_break();
+ rb_iter_break();
}
+ return Qnil;
}
static VALUE
@@ -319,17 +332,18 @@ enum_member(obj, val)
iv.i = 0;
iv.v = val;
- rb_iterate(rb_each, obj, member_i, &iv);
+ rb_iterate(rb_each, obj, member_i, (VALUE)&iv);
if (iv.i) return TRUE;
return FALSE;
}
-static void
+static VALUE
length_i(i, length)
VALUE i;
int *length;
{
(*length)++;
+ return Qnil;
}
VALUE
@@ -338,7 +352,7 @@ enum_length(obj)
{
int length = 0;
- rb_iterate(rb_each, obj, length_i, &length);
+ rb_iterate(rb_each, obj, length_i, (VALUE)&length);
return INT2FIX(length);
}
diff --git a/env.h b/env.h
index fb7b941..ebcfcc5 100644
--- a/env.h
+++ b/env.h
@@ -15,7 +15,7 @@ extern struct FRAME {
int argc;
VALUE *argv;
ID last_func;
- struct RClass *last_class;
+ VALUE last_class;
VALUE cbase;
struct FRAME *prev;
char *file;
@@ -23,6 +23,8 @@ extern struct FRAME {
int iter;
} *the_frame;
+void gc_mark_frame _((struct FRAME *));
+
extern struct SCOPE {
struct RBasic super;
ID *local_tbl;
@@ -36,7 +38,7 @@ extern struct SCOPE {
extern int rb_in_eval;
-extern struct RClass *the_class;
+extern VALUE the_class;
struct RVarmap {
struct RBasic super;
diff --git a/error.c b/error.c
index 39e63dd..7163f62 100644
--- a/error.c
+++ b/error.c
@@ -102,7 +102,7 @@ Warning(fmt, va_alist)
char buf[BUFSIZ];
va_list args;
- if (!verbose) return;
+ if (!RTEST(verbose)) return;
sprintf(buf, "warning: %s", fmt);
@@ -225,11 +225,10 @@ exc_new2(etype, s)
VALUE
exc_new3(etype, str)
- VALUE etype;
- struct RString *str;
+ VALUE etype, str;
{
Check_Type(str, T_STRING);
- return exc_new(etype, str->ptr, str->len);
+ return exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len);
}
static VALUE
@@ -251,14 +250,20 @@ static VALUE
exc_inspect(exc)
VALUE exc;
{
- struct RString *classpath = RSTRING(rb_class_path(CLASS_OF(exc)));
- VALUE str = str_new(classpath->ptr, classpath->len);
+ VALUE str, klass;
- str_cat(str, ":", 1);
+ klass = CLASS_OF(exc);
if (RSTRING(exc)->len == 0) {
- str_cat(str, "\"\"", 2);
+ return rb_class_path(klass);
}
+
+ str = str_new2("#<");
+ klass = rb_class_path(klass);
+ str_cat(str, RSTRING(klass)->ptr, RSTRING(klass)->len);
+ str_cat(str, ":", 1);
str_cat(str, RSTRING(exc)->ptr, RSTRING(exc)->len);
+ str_cat(str, ">", 1);
+
return str;
}
@@ -285,7 +290,7 @@ exception(argc, argv)
}
}
for (i=0; i<argc; i++) {
- v = rb_define_class(rb_id2name(rb_to_id(argv[i])), eException);
+ v = rb_define_class_under(the_class, rb_id2name(rb_to_id(argv[i])), eException);
}
return v;
}
@@ -327,7 +332,7 @@ Init_Exception()
eNameError = rb_define_class("NameError", eException);
eIndexError = rb_define_class("IndexError", eException);
eNotImpError = rb_define_class("NotImplementError", eException);
- eLoadError = rb_define_class("LoadError", eException);
+ eLoadError = rb_define_class("LoadError", eException);
eRuntimeError = rb_define_class("RuntimeError", eException);
eSecurityError = rb_define_class("SecurityError", eException);
diff --git a/eval.c b/eval.c
index 92113a7..42617c2 100644
--- a/eval.c
+++ b/eval.c
@@ -20,12 +20,14 @@
#include "st.h"
#include "dln.h"
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
+#ifndef HAVE_STRING_H
char *strrchr();
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#ifndef setjmp
#ifdef HAVE__SETJMP
#define setjmp(env) _setjmp(env)
@@ -34,9 +36,13 @@ char *strrchr();
#endif
extern VALUE cData;
+
VALUE cProc;
-static VALUE proc_call();
-static VALUE f_binding();
+static VALUE proc_call _((VALUE,VALUE));
+static VALUE f_binding _((VALUE));
+static void f_END _((void));
+
+#define SCOPE_PRIVATE FL_USER4
#define CACHE_SIZE 0x200
#define CACHE_MASK 0x1ff
@@ -45,8 +51,8 @@ static VALUE f_binding();
struct cache_entry { /* method hash table. */
ID mid; /* method's id */
ID mid0; /* method's original id */
- struct RClass *class; /* receiver's class */
- struct RClass *origin; /* where method defined */
+ VALUE class; /* receiver's class */
+ VALUE origin; /* where method defined */
NODE *method;
int noex;
};
@@ -65,29 +71,58 @@ rb_clear_cache()
}
}
+static void
+rb_clear_cache_by_id(id)
+ ID id;
+{
+ struct cache_entry *ent, *end;
+
+ ent = cache; end = ent + CACHE_SIZE;
+ while (ent < end) {
+ if (ent->mid == id) {
+ ent->mid = 0;
+ }
+ ent++;
+ }
+}
+
void
rb_add_method(class, mid, node, noex)
- struct RClass *class;
+ VALUE class;
ID mid;
NODE *node;
int noex;
{
NODE *body;
- if (NIL_P(class)) class = (struct RClass*)cObject;
+ if (NIL_P(class)) class = cObject;
body = NEW_METHOD(node, noex);
- st_insert(class->m_tbl, mid, body);
+ st_insert(RCLASS(class)->m_tbl, mid, body);
+}
+
+void
+rb_remove_method(class, mid)
+ VALUE class;
+ ID mid;
+{
+ NODE *body;
+
+ if (!st_delete(RCLASS(class)->m_tbl, &mid, &body)) {
+ NameError("method `%s' not defined in %s",
+ rb_id2name(mid), rb_class2name(class));
+ }
+ rb_clear_cache_by_id(mid);
}
static NODE*
search_method(class, id, origin)
- struct RClass *class, **origin;
+ VALUE class, *origin;
ID id;
{
NODE *body;
- while (!st_lookup(class->m_tbl, id, &body)) {
- class = class->super;
+ while (!st_lookup(RCLASS(class)->m_tbl, id, &body)) {
+ class = (VALUE)RCLASS(class)->super;
if (!class) return 0;
}
@@ -97,14 +132,14 @@ search_method(class, id, origin)
static NODE*
rb_get_method_body(classp, idp, noexp)
- struct RClass **classp;
+ VALUE *classp;
ID *idp;
int *noexp;
{
ID id = *idp;
- struct RClass *class = *classp;
+ VALUE class = *classp;
+ VALUE origin;
NODE *body;
- struct RClass *origin;
struct cache_entry *ent;
if ((body = search_method(class, id, &origin)) == 0) {
@@ -119,12 +154,14 @@ rb_get_method_body(classp, idp, noexp)
body = body->nd_body;
if (nd_type(body) == NODE_FBODY) {
ent->mid = id;
- *classp = ent->origin = (struct RClass*)body->nd_orig;
+ *classp = body->nd_orig;
+ ent->origin = body->nd_orig;
*idp = ent->mid0 = body->nd_mid;
body = ent->method = body->nd_head;
}
else {
- *classp = ent->origin = origin;
+ *classp = (VALUE)origin;
+ ent->origin = origin;
ent->mid = ent->mid0 = id;
ent->method = body;
}
@@ -135,10 +172,10 @@ rb_get_method_body(classp, idp, noexp)
void
rb_alias(class, name, def)
- struct RClass *class;
+ VALUE class;
ID name, def;
{
- struct RClass *origin;
+ VALUE origin;
NODE *orig, *body;
if (name == def) return;
@@ -156,16 +193,16 @@ rb_alias(class, name, def)
if (nd_type(body) == NODE_FBODY) { /* was alias */
body = body->nd_head;
def = body->nd_mid;
- origin = (struct RClass*)body->nd_orig;
+ origin = body->nd_orig;
}
- st_insert(class->m_tbl, name,
+ st_insert(RCLASS(class)->m_tbl, name,
NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex));
}
static void
rb_export_method(class, name, noex)
- struct RClass *class;
+ VALUE class;
ID name;
int noex;
{
@@ -178,14 +215,14 @@ rb_export_method(class, name, noex)
}
if (!body) {
NameError("undefined method `%s' for `%s'",
- rb_id2name(name), rb_class2name((VALUE)class));
+ rb_id2name(name), rb_class2name(class));
}
if (body->nd_noex != noex) {
- if (class == origin) {
+ if (class == (VALUE)origin) {
body->nd_noex = noex;
}
else {
- rb_clear_cache();
+ rb_clear_cache_by_id(name);
rb_add_method(class, name, NEW_ZSUPER(), noex);
}
}
@@ -193,7 +230,7 @@ rb_export_method(class, name, noex)
static VALUE
method_boundp(class, id, ex)
- struct RClass *class;
+ VALUE class;
ID id;
int ex;
{
@@ -208,18 +245,19 @@ method_boundp(class, id, ex)
}
int
-rb_method_boundp(class, id, priv)
+rb_method_boundp(class, id, ex)
VALUE class;
ID id;
- int priv;
+ int ex;
{
- if (method_boundp(class, id, priv?NOEX_PRIVATE:NOEX_PUBLIC))
+ if (method_boundp(class, id, ex))
return TRUE;
return FALSE;
}
-static ID init, eqq, each, aref, aset;
+static ID init, eqq, each, aref, aset, match;
VALUE errinfo = Qnil, errat = Qnil;
+extern NODE *eval_tree0;
extern NODE *eval_tree;
extern int nerrs;
@@ -244,15 +282,15 @@ static struct FRAME *top_frame;
static struct SCOPE *top_scope;
#define PUSH_FRAME() { \
- struct FRAME _frame; \
- _frame.prev = the_frame; \
- _frame.file = sourcefile; \
- _frame.line = sourceline; \
- _frame.iter = the_iter->iter; \
- _frame.cbase = the_frame->cbase; \
- the_frame = &_frame; \
+ struct FRAME *_frame = ALLOCA_N(struct FRAME,1);\
+ _frame->prev = the_frame; \
+ _frame->file = sourcefile; \
+ _frame->line = sourceline; \
+ _frame->iter = the_iter->iter; \
+ _frame->cbase = the_frame->cbase; \
+ the_frame = _frame; \
-#define POP_FRAME() the_frame = _frame.prev; }
+#define POP_FRAME() the_frame = _frame->prev; }
struct BLOCK {
NODE *var;
@@ -260,8 +298,8 @@ struct BLOCK {
VALUE self;
struct FRAME frame;
struct SCOPE *scope;
- struct RClass *class;
- int level;
+ VALUE class;
+ struct tag *tag;
int iter;
struct RVarmap *d_vars;
#ifdef THREAD
@@ -271,26 +309,26 @@ struct BLOCK {
} *the_block;
#define PUSH_BLOCK(v,b) { \
- struct BLOCK _block; \
- _block.level = (int)prot_tag; \
- _block.var = v; \
- _block.body = b; \
- _block.self = self; \
- _block.frame = *the_frame; \
- _block.class = the_class; \
- _block.frame.file = sourcefile; \
- _block.frame.line = sourceline; \
- _block.scope = the_scope; \
- _block.d_vars = the_dyna_vars; \
- _block.prev = the_block; \
- _block.iter = the_iter->iter; \
- the_block = &_block; \
+ struct BLOCK *_block = ALLOCA_N(struct BLOCK,1);\
+ _block->tag = prot_tag; \
+ _block->var = v; \
+ _block->body = b; \
+ _block->self = self; \
+ _block->frame = *the_frame; \
+ _block->class = the_class; \
+ _block->frame.file = sourcefile; \
+ _block->frame.line = sourceline; \
+ _block->scope = the_scope; \
+ _block->d_vars = the_dyna_vars; \
+ _block->prev = the_block; \
+ _block->iter = the_iter->iter; \
+ the_block = _block;
#define PUSH_BLOCK2(b) { \
- struct BLOCK _block; \
- _block = *b; \
- _block.prev = the_block; \
- the_block = &_block;
+ struct BLOCK *_block = ALLOCA_N(struct BLOCK,1);\
+ *_block = *b; \
+ _block->prev = the_block; \
+ the_block = _block;
#define POP_BLOCK() \
the_block = the_block->prev; \
@@ -378,35 +416,53 @@ static struct iter {
the_iter = _iter.prev; \
}
+#ifdef C_ALLOCA
+/* need to protect retval in struct tag from GC. */
+#define tag_retval_dcl VALUE *dd_retval
+#define tag_retval_init VALUE _tag_retval = Qnil;\
+ _tag->dd_retval = &_tag_retval;
+#define tag_retval dd_retval[0]
+#else
+#define tag_retval_dcl VALUE retval
+#define tag_retval_init _tag->retval = Qnil
+#define tag_retval retval
+#endif
+
static struct tag {
jmp_buf buf;
struct FRAME *frame;
struct iter *iter;
+ ID tag;
+ tag_retval_dcl;
+ ID dst;
struct tag *prev;
} *prot_tag;
-#define PUSH_TAG() { \
- struct tag _tag; \
- _tag.frame = the_frame; \
- _tag.iter = the_iter; \
- _tag.prev = prot_tag; \
- prot_tag = &_tag;
+#define PUSH_TAG(ptag) { \
+ struct tag *_tag = ALLOCA_N(struct tag,1);\
+ tag_retval_init; \
+ _tag->frame = the_frame; \
+ _tag->iter = the_iter; \
+ _tag->prev = prot_tag; \
+ _tag->tag_retval = Qnil; \
+ _tag->tag = ptag; \
+ _tag->dst = 0; \
+ prot_tag = _tag;
-#define EXEC_TAG() ((NODE*)setjmp(prot_tag->buf))
+#define PROT_NONE 0
+#define PROT_FUNC -1
+#define PROT_THREAD -2
+
+#define EXEC_TAG() setjmp(prot_tag->buf)
#define JUMP_TAG(st) { \
the_frame = prot_tag->frame; \
the_iter = prot_tag->iter; \
- longjmp(prot_tag->buf,(int)(st)); \
+ longjmp(prot_tag->buf,(st)); \
}
-#define JUMP_TAG3(val,data1,data2) \
- JUMP_TAG(node_newnode(NODE_TAG,(val),(data1),(data2)))
-
-#define JUMP_TAG2(val,data) JUMP_TAG3((val),(data),0)
-
#define POP_TAG() \
- prot_tag = _tag.prev; \
+ prot_tag = _tag->prev; \
}
#define TAG_RETURN 0x1
@@ -417,13 +473,12 @@ static struct tag {
#define TAG_RAISE 0x6
#define TAG_THROW 0x7
#define TAG_FATAL 0x8
+#define TAG_MASK 0xf
-#define IN_BLOCK 0x10
-
-struct RClass *the_class;
+VALUE the_class;
-#define PUSH_CLASS() { \
- struct RClass *_class = the_class; \
+#define PUSH_CLASS() { \
+ VALUE _class = the_class; \
#define POP_CLASS() the_class = _class; }
@@ -581,23 +636,35 @@ error_print()
fprintf(stderr, ": unhandled exception\n");
}
else {
- PUSH_TAG();
- if (EXEC_TAG() == 0) {
- VALUE epath = rb_class_path(eclass);
- if (RSTRING(epath)->ptr[0] != '#') {
- fprintf(stderr, ": ");
- fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
- }
- }
- POP_TAG();
+ VALUE epath;
- if (RSTRING(errinfo)->len > 0) {
+ epath = rb_class_path(eclass);
+ if (RSTRING(errinfo)->len == 0) {
fprintf(stderr, ": ");
- fwrite(RSTRING(errinfo)->ptr, 1, RSTRING(errinfo)->len, stderr);
- }
- if (RSTRING(errinfo)->ptr[RSTRING(errinfo)->len - 1] != '\n') {
+ fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
putc('\n', stderr);
}
+ else {
+ unsigned char *tail = 0;
+ int len = RSTRING(errinfo)->len;
+
+ if (RSTRING(epath)->ptr[0] == '#') epath = 0;
+ if (tail = strchr(RSTRING(errinfo)->ptr, '\n')) {
+ len = tail - RSTRING(errinfo)->ptr;
+ tail++; /* skip newline */
+ }
+ fprintf(stderr, ": ");
+ fwrite(RSTRING(errinfo)->ptr, 1, len, stderr);
+ if (epath) {
+ fprintf(stderr, " (");
+ fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
+ fprintf(stderr, ")\n");
+ }
+ if (tail) {
+ fwrite(tail, 1, RSTRING(errinfo)->len-len-1, stderr);
+ putc('\n', stderr);
+ }
+ }
}
if (!NIL_P(errat)) {
@@ -608,6 +675,7 @@ error_print()
#define TRACE_HEAD 8
#define TRACE_TAIL 5
+ ep = RARRAY(errat);
for (i=1; i<ep->len; i++) {
fprintf(stderr, "\tfrom %s\n", RSTRING(ep->ptr[i])->ptr);
if (i == TRACE_HEAD && ep->len > TRACE_MAX) {
@@ -624,12 +692,18 @@ extern char **environ;
#endif
char **origenviron;
+void rb_call_inits _((void));
+void init_stack _((void));
+void init_heap _((void));
+void Init_ext _((void));
+void gc_call_finalizer_at_exit _((void));
+
void
ruby_init()
{
static struct FRAME frame;
static struct iter iter;
- NODE *state;
+ int state;
the_frame = top_frame = &frame;
the_iter = &iter;
@@ -641,11 +715,13 @@ ruby_init()
the_scope->local_vars = 0;
the_scope->local_tbl = 0;
top_scope = the_scope;
+ /* default visibility is private at toplevel */
+ FL_SET(top_scope, SCOPE_PRIVATE);
- PUSH_TAG()
+ PUSH_TAG(PROT_NONE)
if ((state = EXEC_TAG()) == 0) {
rb_call_inits();
- the_class = (struct RClass*)cObject;
+ the_class = cObject;
the_frame->cbase = (VALUE)node_newnode(NODE_CREF,cObject,0,0);
rb_define_global_const("TOPLEVEL_BINDING", f_binding(TopSelf));
ruby_prog_init();
@@ -663,16 +739,17 @@ ruby_options(argc, argv)
int argc;
char **argv;
{
- NODE *state;
+ int state;
- PUSH_TAG()
+ PUSH_TAG(PROT_NONE)
if ((state = EXEC_TAG()) == 0) {
NODE *save;
- Init_ext();
- ext_init = 1;
ruby_process_options(argc, argv);
save = eval_tree;
+ eval_tree = 0;
+ Init_ext();
+ ext_init = 1;
rb_require_modules();
eval_tree = save;
}
@@ -690,6 +767,12 @@ eval_node(self)
VALUE result = Qnil;
NODE *tree;
+ if (eval_tree0) {
+ tree = eval_tree0;
+ eval_tree0 = 0;
+ rb_eval(self, tree);
+ }
+
if (!eval_tree) return Qnil;
tree = eval_tree;
@@ -709,18 +792,20 @@ static VALUE thread_current();
static int exit_status;
+static void exec_end_proc();
+
void
ruby_run()
{
- NODE *state;
- static NODE *ex;
+ int state;
+ static int ex;
if (nerrs > 0) exit(nerrs);
init_stack();
errat = Qnil; /* clear for execution */
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
PUSH_ITER(ITER_NOT);
if ((state = EXEC_TAG()) == 0) {
if (!ext_init) Init_ext();
@@ -730,7 +815,7 @@ ruby_run()
POP_TAG();
if (state && !ex) ex = state;
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
PUSH_ITER(ITER_NOT);
if ((state = EXEC_TAG()) == 0) {
rb_trap_exit();
@@ -738,6 +823,8 @@ ruby_run()
thread_cleanup();
thread_wait_other_threads();
#endif
+ exec_end_proc();
+ gc_call_finalizer_at_exit();
}
else {
ex = state;
@@ -745,12 +832,10 @@ ruby_run()
POP_ITER();
POP_TAG();
- if (!ex) {
+ switch (ex & 0xf) {
+ case 0:
exit(0);
- }
- switch (ex->nd_tag) {
- case IN_BLOCK|TAG_RETURN:
case TAG_RETURN:
error_pos();
fprintf(stderr, "unexpected return\n");
@@ -761,7 +846,6 @@ ruby_run()
fprintf(stderr, "unexpected next\n");
exit(1);
break;
- case IN_BLOCK|TAG_BREAK:
case TAG_BREAK:
error_pos();
fprintf(stderr, "unexpected break\n");
@@ -785,13 +869,8 @@ ruby_run()
error_print();
exit(1);
break;
- case TAG_THROW:
- error_pos();
- fprintf(stderr, "uncaught throw `%s'\n", rb_id2name(ex->nd_tlev));
- exit(1);
- break;
default:
- Bug("Unknown longjmp status %d", ex->nd_tag);
+ Bug("Unknown longjmp status %d", ex);
break;
}
}
@@ -804,9 +883,12 @@ compile_error(at)
mesg = errinfo;
nerrs = 0;
- errinfo = exc_new2(eSyntaxError, "compile error in ");
- str_cat(errinfo, at, strlen(at));
- str_cat(errinfo, ":\n", 2);
+ errinfo = exc_new2(eSyntaxError, "compile error");
+ if (at) {
+ str_cat(errinfo, " in ", 4);
+ str_cat(errinfo, at, strlen(at));
+ }
+ str_cat(errinfo, "\n", 1);
str_cat(errinfo, RSTRING(mesg)->ptr, RSTRING(mesg)->len);
rb_raise(errinfo);
}
@@ -829,23 +911,23 @@ void
rb_eval_cmd(cmd, arg)
VALUE cmd, arg;
{
- NODE *state;
+ int state;
struct SCOPE *saved_scope;
volatile int safe = rb_safe_level();
if (TYPE(cmd) != T_STRING) {
- if (obj_is_kind_of(cmd, cProc)) {
- proc_call(cmd, arg);
- return;
- }
+ Check_Type(arg, T_ARRAY);
+ rb_funcall2(cmd, rb_intern("call"),
+ RARRAY(arg)->len, RARRAY(arg)->ptr);
+ return;
}
PUSH_CLASS();
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
saved_scope = the_scope;
the_scope = top_scope;
- the_class = (struct RClass*)cObject;
+ the_class = cObject;
if (str_tainted(cmd)) {
safe_level = 5;
}
@@ -859,8 +941,9 @@ rb_eval_cmd(cmd, arg)
POP_TAG();
POP_CLASS();
- if (state == 0) return;
- switch (state->nd_tag) {
+ switch (state) {
+ case 0:
+ break;
case TAG_RETURN:
Raise(eLocalJumpError, "unexpected return");
break;
@@ -887,9 +970,9 @@ rb_trap_eval(cmd, sig)
VALUE cmd;
int sig;
{
- NODE *state;
+ int state;
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
rb_eval_cmd(cmd, ary_new3(1, INT2FIX(sig)));
}
@@ -905,25 +988,23 @@ superclass(self, node)
VALUE self;
NODE *node;
{
- VALUE val = 0;
- NODE *state;
+ VALUE val = 0; /* OK */
+ int state;
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
val = rb_eval(self, node);
}
POP_TAG();
- if (state) {
- if (state->nd_tag == TAG_RAISE) {
- superclass_error:
- switch (nd_type(node)) {
- case NODE_COLON2:
- TypeError("undefined superclass `%s'", rb_id2name(node->nd_mid));
- case NODE_CVAR:
- TypeError("undefined superclass `%s'", rb_id2name(node->nd_vid));
- default:
- TypeError("superclass undefined");
- }
+ if (state == TAG_RAISE) {
+ superclass_error:
+ switch (nd_type(node)) {
+ case NODE_COLON2:
+ TypeError("undefined superclass `%s'", rb_id2name(node->nd_mid));
+ case NODE_CVAR:
+ TypeError("undefined superclass `%s'", rb_id2name(node->nd_vid));
+ default:
+ TypeError("superclass undefined");
}
JUMP_TAG(state);
}
@@ -974,6 +1055,64 @@ ev_const_get(cref, id)
return rb_const_get(cref->nd_clss, id);
}
+static VALUE
+mod_nesting()
+{
+ NODE *cbase = (NODE*)the_frame->cbase;
+ VALUE ary = ary_new();
+
+ while (cbase && cbase->nd_clss != cObject) {
+ ary_push(ary, cbase->nd_clss);
+ cbase = cbase->nd_next;
+ }
+ return ary;
+}
+
+static VALUE
+mod_s_constants()
+{
+ NODE *cbase = (NODE*)the_frame->cbase;
+ VALUE ary = ary_new();
+
+ while (cbase && cbase->nd_clss != cObject) {
+ mod_const_at(cbase->nd_clss, ary);
+ cbase = cbase->nd_next;
+ }
+
+ mod_const_of(((NODE*)the_frame->cbase)->nd_clss, ary);
+ return ary;
+}
+
+static VALUE
+mod_remove_method(mod, name)
+ VALUE mod, name;
+{
+ rb_remove_method(mod, rb_to_id(name));
+ return mod;
+}
+
+static VALUE
+mod_undef_method(mod, name)
+ VALUE mod, name;
+{
+ ID id = rb_to_id(name);
+
+ rb_add_method(mod, id, 0, NOEX_PUBLIC);
+ rb_clear_cache_by_id(id);
+ return mod;
+}
+
+static VALUE
+mod_alias_method(mod, new, old)
+ VALUE mod, new, old;
+{
+ ID id = rb_to_id(new);
+
+ rb_alias(mod, id, rb_to_id(old));
+ rb_clear_cache_by_id(id);
+ return mod;
+}
+
#define SETUP_ARGS(anode) {\
NODE *n = anode;\
if (!n) {\
@@ -983,15 +1122,16 @@ ev_const_get(cref, id)
else if (nd_type(n) == NODE_ARRAY) {\
argc=n->nd_alen;\
if (argc > 0) {\
- int i;\
+ char *file = sourcefile;\
int line = sourceline;\
+ int i;\
n = anode;\
argv = ALLOCA_N(VALUE,argc);\
for (i=0;i<argc;i++) {\
argv[i] = rb_eval(self,n->nd_head);\
n=n->nd_next;\
}\
- sourcefile = anode->file;\
+ sourcefile = file;\
sourceline = line;\
}\
else {\
@@ -1001,26 +1141,49 @@ ev_const_get(cref, id)
}\
else {\
VALUE args = rb_eval(self,n);\
+ char *file = sourcefile;\
int line = sourceline;\
if (TYPE(args) != T_ARRAY)\
- args = rb_to_a(args);\
+ args = rb_Array(args);\
argc = RARRAY(args)->len;\
argv = ALLOCA_N(VALUE, argc);\
MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\
- sourcefile = anode->file;\
+ sourcefile = file;\
sourceline = line;\
}\
}
-int
-rb_test_false_or_nil(v)
- VALUE v;
-{
- return (v != Qnil) && (v != FALSE);
-}
-
#define MATCH_DATA the_scope->local_vars[node->nd_cnt]
+static char* is_defined _((VALUE, NODE*, char*));
+
+static char*
+arg_defined(self, node, buf, type)
+ VALUE self;
+ NODE *node;
+ char *buf;
+ char *type;
+{
+ int argc;
+ int i;
+
+ if (!node) return type; /* no args */
+ if (nd_type(node) == NODE_ARRAY) {
+ argc=node->nd_alen;
+ if (argc > 0) {
+ for (i=0;i<argc;i++) {
+ if (!is_defined(self, node->nd_head, buf))
+ return 0;
+ node = node->nd_next;
+ }
+ }
+ }
+ else if (!is_defined(self, node, buf)) {
+ return 0;
+ }
+ return type;
+}
+
static char*
is_defined(self, node, buf)
VALUE self;
@@ -1028,16 +1191,17 @@ is_defined(self, node, buf)
char *buf;
{
VALUE val; /* OK */
- NODE *state;
-
- node = node->nd_head;
+ int state;
switch (nd_type(node)) {
case NODE_SUPER:
case NODE_ZSUPER:
if (the_frame->last_func == 0) return 0;
- else if (method_boundp(the_frame->last_class->super,
+ else if (method_boundp(RCLASS(the_frame->last_class)->super,
the_frame->last_func, 1)) {
+ if (nd_type(node) == NODE_SUPER) {
+ return arg_defined(self, node->nd_args, buf, "super");
+ }
return "super";
}
break;
@@ -1048,7 +1212,8 @@ is_defined(self, node, buf)
goto check_bound;
case NODE_CALL:
- PUSH_TAG();
+ if (!is_defined(self, node->nd_recv, buf)) return 0;
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
val = rb_eval(self, node->nd_recv);
val = CLASS_OF(val);
@@ -1058,12 +1223,15 @@ is_defined(self, node, buf)
return 0;
}
check_bound:
- if (method_boundp(val, node->nd_mid,
- nd_type(node)== NODE_CALL)) {
- return "method";
+ if (method_boundp(val, node->nd_mid, nd_type(node)== NODE_CALL)) {
+ return arg_defined(self, node->nd_args, buf, "method");
}
break;
+ case NODE_MATCH2:
+ case NODE_MATCH3:
+ return "method";
+
case NODE_YIELD:
if (iterator_p()) {
return "yield";
@@ -1076,6 +1244,12 @@ is_defined(self, node, buf)
case NODE_NIL:
return "nil";
+ case NODE_TRUE:
+ return "true";
+
+ case NODE_FALSE:
+ return "false";
+
case NODE_ATTRSET:
case NODE_OP_ASGN1:
case NODE_OP_ASGN2:
@@ -1110,7 +1284,7 @@ is_defined(self, node, buf)
break;
case NODE_COLON2:
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
val = rb_eval(self, node->nd_head);
}
@@ -1143,7 +1317,7 @@ is_defined(self, node, buf)
break;
default:
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
rb_eval(self, node);
}
@@ -1163,17 +1337,16 @@ static void blk_free();
static VALUE
set_trace_func(obj, trace)
- VALUE obj;
- struct RData *trace;
+ VALUE obj, trace;
{
if (NIL_P(trace)) {
trace_func = 0;
return Qnil;
}
- if (TYPE(trace) != T_DATA || trace->dfree != blk_free) {
+ if (TYPE(trace) != T_DATA || RDATA(trace)->dfree != blk_free) {
TypeError("trace_func needs to be Proc");
}
- return trace_func = (VALUE)trace;
+ return trace_func = trace;
}
static void
@@ -1184,7 +1357,7 @@ call_trace_func(event, file, line, self, id)
VALUE self;
ID id;
{
- NODE *state;
+ int state;
volatile VALUE trace;
struct FRAME *prev;
@@ -1198,12 +1371,12 @@ call_trace_func(event, file, line, self, id)
prev = the_frame;
PUSH_FRAME();
- *the_frame = *_frame.prev;
+ *the_frame = *_frame->prev;
the_frame->prev = prev;
the_frame->line = sourceline = line;
the_frame->file = sourcefile = file;
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
proc_call(trace, ary_new3(5, str_new2(event),
str_new2(sourcefile),
@@ -1221,12 +1394,13 @@ call_trace_func(event, file, line, self, id)
if (state) JUMP_TAG(state);
}
+static void return_value _((VALUE val));
static VALUE
rb_eval(self, node)
VALUE self;
NODE * volatile node;
{
- NODE *state;
+ int state;
volatile VALUE result = Qnil;
#define RETURN(v) { result = (v); goto finish; }
@@ -1234,10 +1408,6 @@ rb_eval(self, node)
again:
if (!node) RETURN(Qnil);
-#if 0
- sourceline = nd_line(node);
- sourcefile = node->file;
-#endif
switch (nd_type(node)) {
case NODE_BLOCK:
while (node) {
@@ -1246,6 +1416,12 @@ rb_eval(self, node)
}
break;
+ case NODE_POSTEXE:
+ f_END();
+ nd_set_type(node, NODE_NIL); /* exec just once */
+ result = Qnil;
+ break;
+
/* begin .. end without clauses */
case NODE_BEGIN:
node = node->nd_body;
@@ -1256,6 +1432,26 @@ rb_eval(self, node)
result = reg_match2(node->nd_head->nd_lit);
break;
+ /* nodes for speed-up(literal match) */
+ case NODE_MATCH2:
+ result = reg_match(rb_eval(self,node->nd_recv),
+ rb_eval(self,node->nd_value));
+ break;
+
+ /* nodes for speed-up(literal match) */
+ case NODE_MATCH3:
+ {
+ VALUE r = rb_eval(self,node->nd_recv);
+ VALUE l = rb_eval(self,node->nd_value);
+ if (TYPE(r) == T_STRING) {
+ result = reg_match(l, r);
+ }
+ else {
+ result = rb_funcall(r, match, 1, l);
+ }
+ }
+ break;
+
/* nodes for speed-up(top-level loop for -n/-p) */
case NODE_OPT_N:
while (!NIL_P(f_gets())) {
@@ -1269,7 +1465,14 @@ rb_eval(self, node)
case NODE_NIL:
RETURN(Qnil);
+ case NODE_TRUE:
+ RETURN(TRUE);
+
+ case NODE_FALSE:
+ RETURN(FALSE);
+
case NODE_IF:
+ sourceline = nd_line(node);
if (RTEST(rb_eval(self, node->nd_cond))) {
node = node->nd_body;
}
@@ -1293,9 +1496,10 @@ rb_eval(self, node)
tag = node->nd_head;
while (tag) {
if (trace_func) {
- call_trace_func("line", tag->file, nd_line(tag),
+ call_trace_func("line", tag->nd_file, nd_line(tag),
self, the_frame->last_func);
}
+ sourceline = nd_line(tag);
if (RTEST(rb_funcall2(rb_eval(self, tag->nd_head),eqq,1,&val))){
node = node->nd_body;
goto again;
@@ -1308,8 +1512,10 @@ rb_eval(self, node)
RETURN(Qnil);
case NODE_WHILE:
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
+ PUSH_TAG(PROT_NONE);
+ switch (state = EXEC_TAG()) {
+ case 0:
+ sourceline = nd_line(node);
if (node->nd_state && !RTEST(rb_eval(self, node->nd_cond)))
goto while_out;
do {
@@ -1318,20 +1524,18 @@ rb_eval(self, node)
while_next:
;
} while (RTEST(rb_eval(self, node->nd_cond)));
- }
- else {
- switch (state->nd_tag) {
- case TAG_REDO:
- state = 0;
- goto while_redo;
- case TAG_NEXT:
- state = 0;
- goto while_next;
- case TAG_BREAK:
- state = 0;
- default:
- break;
- }
+ break;
+
+ case TAG_REDO:
+ state = 0;
+ goto while_redo;
+ case TAG_NEXT:
+ state = 0;
+ goto while_next;
+ case TAG_BREAK:
+ state = 0;
+ default:
+ break;
}
while_out:
POP_TAG();
@@ -1341,8 +1545,9 @@ rb_eval(self, node)
RETURN(Qnil);
case NODE_UNTIL:
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
+ PUSH_TAG(PROT_NONE);
+ switch (state = EXEC_TAG()) {
+ case 0:
if (node->nd_state && RTEST(rb_eval(self, node->nd_cond)))
goto until_out;
do {
@@ -1351,20 +1556,18 @@ rb_eval(self, node)
until_next:
;
} while (!RTEST(rb_eval(self, node->nd_cond)));
- }
- else {
- switch (state->nd_tag) {
- case TAG_REDO:
- state = 0;
- goto until_redo;
- case TAG_NEXT:
- state = 0;
- goto until_next;
- case TAG_BREAK:
- state = 0;
- default:
- break;
- }
+ break;
+
+ case TAG_REDO:
+ state = 0;
+ goto until_redo;
+ case TAG_NEXT:
+ state = 0;
+ goto until_next;
+ case TAG_BREAK:
+ state = 0;
+ default:
+ break;
}
until_out:
POP_TAG();
@@ -1376,11 +1579,9 @@ rb_eval(self, node)
case NODE_ITER:
case NODE_FOR:
{
- int tag_level;
-
iter_retry:
PUSH_BLOCK(node->nd_var, node->nd_body);
- PUSH_TAG();
+ PUSH_TAG(PROT_FUNC);
state = EXEC_TAG();
if (state == 0) {
@@ -1391,34 +1592,37 @@ rb_eval(self, node)
}
else {
VALUE recv;
+ char *file = sourcefile;
int line = sourceline;
recv = rb_eval(self, node->nd_iter);
PUSH_ITER(ITER_PRE);
- sourcefile = node->file;
+ sourcefile = file;
sourceline = line;
result = rb_call(CLASS_OF(recv),recv,each,0,0,0);
POP_ITER();
}
}
+ else if (the_block->tag->dst == state) {
+ state &= TAG_MASK;
+ if (state == TAG_RETURN) {
+ result = prot_tag->tag_retval;
+ }
+ }
POP_TAG();
- tag_level = the_block->level;
POP_BLOCK();
- if (state == 0) break;
- switch (state->nd_tag) {
+ switch (state) {
+ case 0:
+ break;
+
case TAG_RETRY:
goto iter_retry;
- case IN_BLOCK|TAG_BREAK:
- if (state->nd_tlev != tag_level) {
- JUMP_TAG(state);
- }
+ case TAG_BREAK:
result = Qnil;
break;
- case IN_BLOCK|TAG_RETURN:
- if (state->nd_tlev == tag_level) {
- state->nd_tag &= ~IN_BLOCK;
- }
+ case TAG_RETURN:
+ return_value(result);
/* fall through */
default:
JUMP_TAG(state);
@@ -1426,6 +1630,22 @@ rb_eval(self, node)
}
break;
+ case NODE_BREAK:
+ JUMP_TAG(TAG_BREAK);
+ break;
+
+ case NODE_NEXT:
+ JUMP_TAG(TAG_NEXT);
+ break;
+
+ case NODE_REDO:
+ JUMP_TAG(TAG_REDO);
+ break;
+
+ case NODE_RETRY:
+ JUMP_TAG(TAG_RETRY);
+ break;
+
case NODE_YIELD:
result = rb_yield_0(rb_eval(self, node->nd_stts), 0);
break;
@@ -1435,44 +1655,42 @@ rb_eval(self, node)
{
volatile VALUE e_info = errinfo, e_at = errat;
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
result = rb_eval(self, node->nd_head);
}
POP_TAG();
- if (state) {
- if (state->nd_tag == TAG_RAISE) {
- NODE * volatile resq = node->nd_resq;
- while (resq) {
- if (handle_rescue(self, resq)) {
+ if (state == TAG_RAISE) {
+ NODE * volatile resq = node->nd_resq;
+ while (resq) {
+ if (handle_rescue(self, resq)) {
+ state = 0;
+ PUSH_TAG(PROT_NONE);
+ if ((state = EXEC_TAG()) == 0) {
+ result = rb_eval(self, resq->nd_body);
+ }
+ POP_TAG();
+ if (state == 0) {
+ errinfo = e_info;
+ errat = e_at;
+ }
+ else if (state == TAG_RETRY) {
state = 0;
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- result = rb_eval(self, resq->nd_body);
- }
- POP_TAG();
- if (state == 0) {
- errinfo = e_info;
- errat = e_at;
- }
- else if (state->nd_tag == TAG_RETRY) {
- state = 0;
- goto retry_entry;
- }
- break;
+ goto retry_entry;
}
- resq = resq->nd_head; /* next rescue */
+ break;
}
+ resq = resq->nd_head; /* next rescue */
}
- if (state) {
- JUMP_TAG(state);
- }
+ }
+ if (state) {
+ JUMP_TAG(state);
}
}
break;
case NODE_ENSURE:
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
result = rb_eval(self, node->nd_head);
}
@@ -1539,7 +1757,10 @@ rb_eval(self, node)
break;
case NODE_RETURN:
- JUMP_TAG2(TAG_RETURN,(node->nd_stts)?rb_eval(self, node->nd_stts):Qnil);
+ if (node->nd_stts) {
+ return_value(rb_eval(self, node->nd_stts));
+ }
+ JUMP_TAG(TAG_RETURN);
break;
case NODE_CALL:
@@ -1586,7 +1807,7 @@ rb_eval(self, node)
}
PUSH_ITER(the_iter->iter?ITER_PRE:ITER_NOT);
- result = rb_call(the_frame->last_class->super, self,
+ result = rb_call(RCLASS(the_frame->last_class)->super, self,
the_frame->last_func, argc, argv, 1);
POP_ITER();
}
@@ -1597,7 +1818,7 @@ rb_eval(self, node)
VALUE save = the_frame->cbase;
PUSH_SCOPE();
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if (node->nd_rval) the_frame->cbase = (VALUE)node->nd_rval;
if (node->nd_tbl) {
VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1);
@@ -1694,7 +1915,8 @@ rb_eval(self, node)
val = rb_eval(self, node->nd_value);
/* check for static scope constants */
- if (verbose && ev_const_defined(the_frame->cbase, node->nd_vid)) {
+ if (RTEST(verbose) &&
+ ev_const_defined(the_frame->cbase, node->nd_vid)) {
Warning("already initialized constant %s",
rb_id2name(node->nd_vid));
}
@@ -1826,6 +2048,7 @@ rb_eval(self, node)
else {
if (nd_type(list->nd_head) == NODE_EVSTR) {
rb_in_eval++;
+ eval_tree = 0;
list->nd_head = compile(list->nd_head->nd_lit);
rb_in_eval--;
if (nerrs > 0) {
@@ -1884,15 +2107,27 @@ rb_eval(self, node)
body = search_method(the_class, node->nd_mid, &origin);
if (body) {
if (origin == (VALUE)the_class) {
- Warning("redefine %s", rb_id2name(node->nd_mid));
+ Warning("discarding old %s", rb_id2name(node->nd_mid));
}
- rb_clear_cache();
+ rb_clear_cache_by_id(node->nd_mid);
}
- if (body) noex = body->nd_noex;
- else noex = node->nd_noex; /* default(1 for toplevel) */
-
+ if (FL_TEST(the_scope,SCOPE_PRIVATE)) {
+ noex = NOEX_PRIVATE;
+ }
+ else {
+ noex = NOEX_PUBLIC;
+ }
rb_add_method(the_class, node->nd_mid, node->nd_defn, noex);
+ if (FL_TEST(the_class, FL_SINGLETON)) {
+ VALUE recv = rb_iv_get(the_class, "__attached__");
+ rb_funcall(recv, rb_intern("singleton_method_added"),
+ 1, INT2FIX(node->nd_mid));
+ }
+ else {
+ rb_funcall(the_class, rb_intern("method_added"),
+ 1, INT2FIX(node->nd_mid));
+ }
result = Qnil;
}
break;
@@ -1920,17 +2155,17 @@ rb_eval(self, node)
if (st_lookup(RCLASS(class)->m_tbl, node->nd_mid, &body)) {
Warning("redefine %s", rb_id2name(node->nd_mid));
}
- rb_clear_cache();
+ rb_clear_cache_by_id(node->nd_mid);
+ rb_add_method(class, node->nd_mid, node->nd_defn, NOEX_PUBLIC);
rb_funcall(recv, rb_intern("singleton_method_added"),
1, INT2FIX(node->nd_mid));
- rb_add_method(class, node->nd_mid, node->nd_defn, NOEX_PUBLIC);
result = Qnil;
}
break;
case NODE_UNDEF:
{
- struct RClass *origin;
+ VALUE origin;
NODE *body;
body = search_method(the_class, node->nd_mid, &origin);
@@ -1938,7 +2173,7 @@ rb_eval(self, node)
NameError("undefined method `%s' for class `%s'",
rb_id2name(node->nd_mid), rb_class2name((VALUE)the_class));
}
- rb_clear_cache();
+ rb_clear_cache_by_id(node->nd_mid);
rb_add_method(the_class, node->nd_mid, 0, NOEX_PUBLIC);
result = Qnil;
}
@@ -1946,6 +2181,8 @@ rb_eval(self, node)
case NODE_ALIAS:
rb_alias(the_class, node->nd_new, node->nd_old);
+ rb_funcall(the_class, rb_intern("method_added"),
+ 1, INT2FIX(node->nd_mid));
result = Qnil;
break;
@@ -1956,8 +2193,7 @@ rb_eval(self, node)
case NODE_CLASS:
{
- VALUE super, class;
- struct RClass *tmp;
+ VALUE super, class, tmp;
if (node->nd_super) {
super = superclass(self, node->nd_super);
@@ -1982,7 +2218,7 @@ rb_eval(self, node)
while (TYPE(tmp) == T_ICLASS) {
tmp = RCLASS(tmp)->super;
}
- if (tmp != RCLASS(super)) {
+ if (tmp != super) {
TypeError("superclass mismatch for %s",
rb_id2name(node->nd_cname));
}
@@ -1991,7 +2227,6 @@ rb_eval(self, node)
Raise(eSecurityError, "extending class prohibited");
}
rb_clear_cache();
- Warning("extending class %s", rb_id2name(node->nd_cname));
}
else {
if (!super) super = cObject;
@@ -2000,7 +2235,7 @@ rb_eval(self, node)
rb_set_class_path(class,the_class,rb_id2name(node->nd_cname));
}
- result = module_setup(class, node->nd_body);
+ return module_setup(class, node->nd_body);
}
break;
@@ -2019,7 +2254,6 @@ rb_eval(self, node)
if (safe_level >= 4) {
Raise(eSecurityError, "extending module prohibited");
}
- Warning("extending module %s", rb_id2name(node->nd_cname));
}
else {
module = rb_define_module_id(node->nd_cname);
@@ -2047,8 +2281,8 @@ rb_eval(self, node)
}
if (FL_TEST(CLASS_OF(class), FL_SINGLETON)) {
rb_clear_cache();
+ class = rb_singleton_class(class);
}
- class = rb_singleton_class(class);
result = module_setup(class, node->nd_body);
}
@@ -2057,7 +2291,7 @@ rb_eval(self, node)
case NODE_DEFINED:
{
char buf[20];
- char *desc = is_defined(self, node, buf);
+ char *desc = is_defined(self, node->nd_head, buf);
if (desc) result = str_new2(desc);
else result = FALSE;
@@ -2065,7 +2299,7 @@ rb_eval(self, node)
break;
case NODE_NEWLINE:
- sourcefile = node->file;
+ sourcefile = node->nd_file;
sourceline = node->nd_nth;
if (trace_func) {
call_trace_func("line", sourcefile, sourceline,
@@ -2087,16 +2321,18 @@ module_setup(module, node)
VALUE module;
NODE * volatile node;
{
- NODE *state;
+ int state;
VALUE save = the_frame->cbase;
VALUE result; /* OK */
+ char *file = sourcefile;
+ int line = sourceline;
/* fill c-ref */
node->nd_clss = module;
node = node->nd_body;
PUSH_CLASS();
- the_class = (struct RClass*)module;
+ the_class = module;
PUSH_SCOPE();
if (node->nd_rval) the_frame->cbase = node->nd_rval;
@@ -2112,10 +2348,10 @@ module_setup(module, node)
the_scope->local_tbl = 0;
}
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
if (trace_func) {
- call_trace_func("class", node->file, nd_line(node),
+ call_trace_func("class", file, line,
the_class, the_frame->last_func);
}
result = rb_eval((VALUE)the_class, node->nd_body);
@@ -2123,10 +2359,10 @@ module_setup(module, node)
POP_TAG();
POP_SCOPE();
POP_CLASS();
+
the_frame->cbase = save;
if (trace_func) {
- call_trace_func("end", node->file, nd_line(node), 0,
- the_frame->last_func);
+ call_trace_func("end", file, line, 0, the_frame->last_func);
}
if (state) JUMP_TAG(state);
@@ -2213,51 +2449,53 @@ f_abort()
}
void
-rb_break()
+rb_iter_break()
{
- JUMP_TAG2(TAG_BREAK, 0);
+ JUMP_TAG(TAG_BREAK);
}
-static VALUE
-f_break()
-{
- JUMP_TAG2(TAG_BREAK, 0);
-}
-
-static VALUE
-f_next()
-{
- JUMP_TAG2(TAG_NEXT, 0);
-}
+#ifdef __GNUC__
+static volatile voidfn rb_longjmp;
+#endif
-static VALUE
-f_redo()
-{
- JUMP_TAG2(TAG_REDO, 0);
-}
+static VALUE make_backtrace();
static VALUE
-f_retry()
+check_errat(val)
+ VALUE val;
{
- JUMP_TAG2(TAG_RETRY, 0);
-}
+ int i;
+ static char *err = "value of $@ must be Array of String";
-#ifdef __GNUC__
-static volatile voidfn rb_longjmp;
-#endif
+ if (!NIL_P(val)) {
+ int t = TYPE(val);
-static VALUE make_backtrace();
+ if (t == T_STRING) return ary_new3(1, val);
+ if (t != T_ARRAY) {
+ TypeError(err);
+ }
+ for (i=0;i<RARRAY(val)->len;i++) {
+ if (TYPE(RARRAY(val)->ptr[i]) != T_STRING) {
+ TypeError(err);
+ }
+ }
+ }
+ return val;
+}
static void
-rb_longjmp(tag, mesg)
+rb_longjmp(tag, mesg, at)
int tag;
- VALUE mesg;
+ VALUE mesg, at;
{
if (NIL_P(errinfo) && NIL_P(mesg)) {
errinfo = exc_new(eRuntimeError, 0, 0);
}
- if (sourcefile && (NIL_P(errat) || !NIL_P(mesg))) {
+ if (!NIL_P(at)) {
+ errat = check_errat(at);
+ }
+ else if (sourcefile && (NIL_P(errat) || !NIL_P(mesg))) {
errat = make_backtrace();
}
@@ -2271,21 +2509,21 @@ rb_longjmp(tag, mesg)
str_freeze(errinfo);
}
- JUMP_TAG2(tag, 0);
+ JUMP_TAG(tag);
}
void
rb_raise(mesg)
VALUE mesg;
{
- rb_longjmp(TAG_RAISE, mesg);
+ rb_longjmp(TAG_RAISE, mesg, Qnil);
}
void
rb_fatal(mesg)
VALUE mesg;
{
- rb_longjmp(TAG_FATAL, mesg);
+ rb_longjmp(TAG_FATAL, mesg, Qnil);
}
void
@@ -2299,17 +2537,18 @@ f_raise(argc, argv)
int argc;
VALUE *argv;
{
- VALUE arg1, arg2;
+ VALUE arg1, arg2, arg3;
VALUE etype, mesg;
int n;
etype = eRuntimeError;
mesg = Qnil;
- switch (n = rb_scan_args(argc, argv, "02", &arg1, &arg2)) {
+ switch (n = rb_scan_args(argc, argv, "03", &arg1, &arg2, &arg3)) {
case 1:
mesg = arg1;
break;
case 2:
+ case 3:
etype = arg1;
if (obj_is_kind_of(etype, eGlobalExit)) {
etype = CLASS_OF(etype);
@@ -2317,7 +2556,7 @@ f_raise(argc, argv)
else {
Check_Type(etype, T_CLASS);
}
- mesg = arg2;
+ mesg = arg2;
break;
}
@@ -2329,8 +2568,8 @@ f_raise(argc, argv)
}
PUSH_FRAME(); /* fake frame */
- *the_frame = *_frame.prev->prev;
- rb_raise(mesg);
+ *the_frame = *_frame->prev->prev;
+ rb_longjmp(TAG_RAISE, mesg, arg3);
POP_FRAME();
}
@@ -2354,11 +2593,12 @@ rb_yield_0(val, self)
volatile VALUE self;
{
NODE *node;
- NODE *state;
volatile VALUE result = Qnil;
struct BLOCK *block;
struct SCOPE *old_scope;
struct FRAME frame;
+ int state;
+ static USHORT serial = 1;
if (!iterator_p()) {
Raise(eLocalJumpError, "yield called out of iterator");
@@ -2384,21 +2624,21 @@ rb_yield_0(val, self)
assign(self, block->var, val);
}
PUSH_ITER(block->iter);
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
redo:
if (!node) {
result = Qnil;
}
else if (nd_type(node) == NODE_CFUNC) {
- result = (*node->nd_cfnc)(val, node->nd_argc, self);
+ result = (*node->nd_cfnc)(val, node->nd_tval, self);
}
else {
result = rb_eval(self, node);
}
}
else {
- switch (state->nd_tag) {
+ switch (state) {
case TAG_REDO:
state = 0;
goto redo;
@@ -2408,8 +2648,9 @@ rb_yield_0(val, self)
break;
case TAG_BREAK:
case TAG_RETURN:
- state->nd_tlev = block->level;
- state->nd_tag = IN_BLOCK|state->nd_tag;
+ state |= (serial++ << 8);
+ state |= 0x10;
+ block->tag->dst = state;
break;
default:
break;
@@ -2452,7 +2693,7 @@ massign(self, node, val)
if (val) {
if (TYPE(val) != T_ARRAY) {
- val = rb_to_a(val);
+ val = rb_Array(val);
}
len = RARRAY(val)->len;
for (i=0; list && i<len; i++) {
@@ -2535,49 +2776,48 @@ assign(self, lhs, val)
VALUE
rb_iterate(it_proc, data1, bl_proc, data2)
VALUE (*it_proc)(), (*bl_proc)();
- void *data1, *data2;
+ VALUE data1, data2;
{
- NODE *state;
+ int state;
volatile VALUE retval = Qnil;
NODE *node = NEW_CFUNC(bl_proc, data2);
VALUE self = TopSelf;
- int tag_level;
iter_retry:
PUSH_ITER(ITER_PRE);
PUSH_BLOCK(0, node);
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
state = EXEC_TAG();
if (state == 0) {
retval = (*it_proc)(data1);
}
+ if (the_block->tag->dst == state) {
+ state &= TAG_MASK;
+ if (state == TAG_RETURN) {
+ retval = prot_tag->tag_retval;
+ }
+ }
POP_TAG();
-
- tag_level = the_block->level;
POP_BLOCK();
POP_ITER();
- if (state) {
- switch (state->nd_tag) {
- case TAG_RETRY:
- goto iter_retry;
+ switch (state) {
+ case 0:
+ break;
- case IN_BLOCK|TAG_BREAK:
- if (state->nd_tlev != tag_level) {
- JUMP_TAG(state);
- }
- retval = Qnil;
- break;
+ case TAG_RETRY:
+ goto iter_retry;
- case IN_BLOCK|TAG_RETURN:
- if (state->nd_tlev == tag_level) {
- state->nd_tag &= ~IN_BLOCK;
- }
- /* fall through */
- default:
- JUMP_TAG(state);
- }
+ case TAG_BREAK:
+ retval = Qnil;
+ break;
+
+ case TAG_RETURN:
+ return_value(retval);
+ /* fall through */
+ default:
+ JUMP_TAG(state);
}
return retval;
}
@@ -2609,37 +2849,35 @@ handle_rescue(self, node)
VALUE
rb_rescue(b_proc, data1, r_proc, data2)
VALUE (*b_proc)(), (*r_proc)();
- void *data1, *data2;
+ VALUE data1, data2;
{
- NODE *state;
+ int state;
volatile VALUE result;
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
retry_entry:
result = (*b_proc)(data1);
}
- else {
- if (state->nd_tag == TAG_RAISE) {
- if (r_proc) {
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- result = (*r_proc)(data2, errinfo);
- }
- POP_TAG();
- if (state && state->nd_tag == TAG_RETRY) {
- state = 0;
- goto retry_entry;
- }
+ else if (state == TAG_RAISE && obj_is_kind_of(errinfo, eException)) {
+ if (r_proc) {
+ PUSH_TAG(PROT_NONE);
+ if ((state = EXEC_TAG()) == 0) {
+ result = (*r_proc)(data2, errinfo);
}
- else {
- result = Qnil;
+ POP_TAG();
+ if (state == TAG_RETRY) {
state = 0;
- }
- if (state == 0) {
- errat = Qnil;
+ goto retry_entry;
}
}
+ else {
+ result = Qnil;
+ state = 0;
+ }
+ if (state == 0) {
+ errat = Qnil;
+ }
}
POP_TAG();
if (state) JUMP_TAG(state);
@@ -2649,13 +2887,14 @@ rb_rescue(b_proc, data1, r_proc, data2)
VALUE
rb_ensure(b_proc, data1, e_proc, data2)
- VALUE (*b_proc)(), (*e_proc)();
- void *data1, *data2;
+ VALUE (*b_proc)();
+ void (*e_proc)();
+ VALUE data1, data2;
{
- NODE *state;
+ int state;
volatile VALUE result = Qnil;
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
result = (*b_proc)(data1);
}
@@ -2706,20 +2945,20 @@ f_missing(argc, argv, obj)
}
if (desc) {
if (last_call_status & CSTAT_NOEX) {
- format = "private method `%s' called for %s(%s)";
+ format = "private method `%s' called for %s";
}
else if (iterator_p()) {
- format = "undefined iterator `%s' for %s(%s)";
+ format = "undefined iterator `%s' for %s";
}
else if (last_call_status & CSTAT_VCALL) {
char *mname = rb_id2name(id);
if (('a' <= mname[0] && mname[0] <= 'z') || mname[0] == '_') {
- format = "undefined local variable or method `%s' for %s(%s)";
+ format = "undefined local variable or method `%s' for %s";
}
}
if (!format) {
- format = "undefined method `%s' for %s(%s)";
+ format = "undefined method `%s' for %s";
}
if (RSTRING(desc)->len > 65) {
desc = any_to_s(obj);
@@ -2729,12 +2968,11 @@ f_missing(argc, argv, obj)
sourcefile = file;
sourceline = line;
PUSH_FRAME(); /* fake frame */
- *the_frame = *_frame.prev->prev;
+ *the_frame = *_frame->prev->prev;
NameError(format,
rb_id2name(id),
- desc?(char*)RSTRING(desc)->ptr:"",
- desc?rb_class2name(CLASS_OF(obj)):"");
+ desc?(char*)RSTRING(desc)->ptr:"");
POP_FRAME();
return Qnil; /* not reached */
@@ -2785,8 +3023,7 @@ stack_length()
static VALUE
rb_call(class, recv, mid, argc, argv, scope)
- struct RClass *class;
- VALUE recv;
+ VALUE class, recv;
ID mid;
int argc; /* OK */
VALUE *argv; /* OK */
@@ -2806,7 +3043,7 @@ rb_call(class, recv, mid, argc, argv, scope)
ent = cache + EXPR1(class, mid);
if (ent->mid == mid && ent->class == class) {
class = ent->origin;
- id = ent->mid0;
+ id = ent->mid0;
noex = ent->noex;
body = ent->method;
}
@@ -2833,19 +3070,19 @@ rb_call(class, recv, mid, argc, argv, scope)
/* for re-scoped/renamed method */
mid = id;
if (scope == 0) scope = 1;
- if (class->super == 0) {
+ if (RCLASS(class)->super == 0) {
/* origin is the Module, so need to scan superclass hierarchy. */
- struct RClass *cl = class;
+ struct RClass *cl = RCLASS(class);
- class = (struct RClass*)RBASIC(recv)->class;
+ class = RBASIC(recv)->class;
while (class) {
- if (class->m_tbl == cl->m_tbl)
+ if (RCLASS(class)->m_tbl == cl->m_tbl)
break;
- class = class->super;
+ class = RCLASS(class)->super;
}
}
else {
- class = class->super;
+ class = RCLASS(class)->super;
}
goto again;
}
@@ -2981,8 +3218,8 @@ rb_call(class, recv, mid, argc, argv, scope)
default:
{
- NODE *state;
- VALUE *local_vars;
+ int state;
+ VALUE *local_vars; /* OK */
PUSH_SCOPE();
@@ -3000,7 +3237,7 @@ rb_call(class, recv, mid, argc, argv, scope)
}
b2 = body = body->nd_body;
- PUSH_TAG();
+ PUSH_TAG(PROT_FUNC);
PUSH_VARS();
if ((state = EXEC_TAG()) == 0) {
@@ -3058,11 +3295,15 @@ rb_call(class, recv, mid, argc, argv, scope)
body = 0;
}
if (trace_func) {
- call_trace_func("call", b2->file, nd_line(b2),
+ call_trace_func("call", b2->nd_file, nd_line(b2),
recv, the_frame->last_func);
}
result = rb_eval(recv, body);
}
+ else if (state == TAG_RETURN) {
+ result = prot_tag->tag_retval;
+ state = 0;
+ }
POP_VARS();
POP_TAG();
POP_SCOPE();
@@ -3075,27 +3316,25 @@ rb_call(class, recv, mid, argc, argv, scope)
}
call_trace_func("return", file, line, 0, the_frame->last_func);
}
- if (state) {
- switch (state->nd_tag) {
- case TAG_NEXT:
- Raise(eLocalJumpError, "unexpected next");
- break;
- case TAG_BREAK:
- Raise(eLocalJumpError, "unexpected break");
- break;
- case TAG_REDO:
- Raise(eLocalJumpError, "unexpected redo");
- break;
- case TAG_RETURN:
- result = state->nd_tval;
- break;
- case TAG_RETRY:
- if (!iterator_p()) {
- Raise(eLocalJumpError, "retry outside of rescue clause");
- }
- default:
- JUMP_TAG(state);
+ switch (state) {
+ case 0:
+ break;
+
+ case TAG_NEXT:
+ Raise(eLocalJumpError, "unexpected next");
+ break;
+ case TAG_BREAK:
+ Raise(eLocalJumpError, "unexpected break");
+ break;
+ case TAG_REDO:
+ Raise(eLocalJumpError, "unexpected redo");
+ break;
+ case TAG_RETRY:
+ if (!iterator_p()) {
+ Raise(eLocalJumpError, "retry outside of rescue clause");
}
+ default:
+ JUMP_TAG(state);
}
}
}
@@ -3107,8 +3346,8 @@ rb_call(class, recv, mid, argc, argv, scope)
VALUE
rb_apply(recv, mid, args)
VALUE recv;
- struct RArray *args;
ID mid;
+ VALUE args;
{
int argc;
VALUE *argv;
@@ -3274,13 +3513,13 @@ rb_frame_last_func()
static NODE*
compile(src)
- struct RString *src;
+ VALUE src;
{
NODE *node;
Check_Type(src, T_STRING);
- node = compile_string(sourcefile, src->ptr, src->len);
+ node = compile_string(sourcefile, RSTRING(src)->ptr, RSTRING(src)->len);
if (nerrs == 0) return node;
return 0;
@@ -3288,23 +3527,21 @@ compile(src)
static VALUE
eval(self, src, scope)
- VALUE self;
- struct RString *src;
- struct RData *scope;
+ VALUE self, src, scope;
{
struct BLOCK *data;
volatile VALUE result = Qnil;
- NODE *state;
- volatile VALUE old_block;
- volatile VALUE old_scope;
- volatile VALUE old_d_vars;
+ struct SCOPE * volatile old_scope;
+ struct BLOCK * volatile old_block;
+ struct RVarmap * volatile old_d_vars;
struct FRAME frame;
char *file = sourcefile;
int line = sourceline;
volatile int iter = the_frame->iter;
+ int state;
if (!NIL_P(scope)) {
- if (TYPE(scope) != T_DATA || scope->dfree != blk_free) {
+ if (TYPE(scope) != T_DATA || RDATA(scope)->dfree != blk_free) {
TypeError("wrong argument type %s (expected Proc/Binding)",
rb_class2name(CLASS_OF(scope)));
}
@@ -3315,11 +3552,11 @@ eval(self, src, scope)
frame = data->frame;
frame.prev = the_frame;
the_frame = &(frame);
- old_scope = (VALUE)the_scope;
+ old_scope = the_scope;
the_scope = data->scope;
- old_block = (VALUE)the_block;
+ old_block = the_block;
the_block = data->prev;
- old_d_vars = (VALUE)the_dyna_vars;
+ old_d_vars = the_dyna_vars;
the_dyna_vars = data->d_vars;
self = data->self;
@@ -3331,17 +3568,18 @@ eval(self, src, scope)
}
}
PUSH_CLASS();
- the_class = (struct RClass*)((NODE*)the_frame->cbase)->nd_clss;
+ the_class = ((NODE*)the_frame->cbase)->nd_clss;
rb_in_eval++;
if (TYPE(the_class) == T_ICLASS) {
- the_class = (struct RClass*)RBASIC(the_class)->class;
+ the_class = RBASIC(the_class)->class;
}
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
+ eval_tree = 0;
compile(src);
if (nerrs > 0) {
- compile_error("eval()");
+ compile_error(0);
}
result = eval_node(self);
}
@@ -3350,22 +3588,21 @@ eval(self, src, scope)
rb_in_eval--;
if (!NIL_P(scope)) {
the_frame = the_frame->prev;
- the_scope = (struct SCOPE*)old_scope;
- the_block = (struct BLOCK*)old_block;
- the_dyna_vars = (struct RVarmap*)old_d_vars;
+ the_scope = old_scope;
+ the_block = old_block;
+ the_dyna_vars = old_d_vars;
}
else {
the_frame->iter = iter;
}
if (state) {
- VALUE err ;
+ VALUE err;
- switch (state->nd_tag) {
- case TAG_RAISE:
+ if (state == TAG_RAISE) {
sourcefile = file;
sourceline = line;
if (strcmp(sourcefile, "(eval)") == 0) {
- err = errinfo;
+ err = str_dup(errinfo);
if (sourceline > 1) {
err = RARRAY(errat)->ptr[0];
str_cat(err, ": ", 2);
@@ -3396,6 +3633,48 @@ f_eval(argc, argv, self)
return eval(self, src, scope);
}
+static VALUE
+eval_under(under, self, src)
+ VALUE under, self, src;
+{
+ VALUE val; /* OK */
+ int state;
+ VALUE cbase = the_frame->cbase;
+
+ PUSH_CLASS();
+ the_class = under;
+ PUSH_FRAME();
+ the_frame->last_func = _frame->last_func;
+ the_frame->last_class = _frame->last_class;
+ the_frame->argc = 1;
+ the_frame->argv = &src;
+ the_frame->cbase = (VALUE)node_newnode(NODE_CREF,under,0,cbase);
+ PUSH_TAG(PROT_NONE);
+ if ((state = EXEC_TAG()) == 0) {
+ val = eval(self, src, Qnil);
+ }
+ POP_TAG();
+ POP_FRAME();
+ POP_CLASS();
+ if (state) JUMP_TAG(state);
+
+ return val;
+}
+
+static VALUE
+obj_instance_eval(self, src)
+ VALUE self, src;
+{
+ return eval_under(CLASS_OF(self), self, src);
+}
+
+static VALUE
+mod_module_eval(mod, src)
+ VALUE mod, src;
+{
+ return eval_under(mod, mod, src);
+}
+
VALUE rb_load_path;
char *dln_find_file();
@@ -3438,23 +3717,22 @@ find_file(file)
VALUE
f_load(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
- NODE *state;
+ int state;
char *file;
volatile ID last_func;
Check_SafeStr(fname);
- if (fname->ptr[0] == '~') {
- fname = (struct RString*)file_s_expand_path(0, fname);
+ if (RSTRING(fname)->ptr[0] == '~') {
+ fname = file_s_expand_path(0, fname);
}
- file = find_file(fname->ptr);
- if (!file) LoadError("No such file to load -- %s", fname->ptr);
+ file = find_file(RSTRING(fname)->ptr);
+ if (!file) LoadError("No such file to load -- %s", RSTRING(fname)->ptr);
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
PUSH_CLASS();
- the_class = (struct RClass*)cObject;
+ the_class = cObject;
PUSH_SCOPE();
if (top_scope->local_tbl) {
int len = top_scope->local_tbl[0]+1;
@@ -3466,6 +3744,8 @@ f_load(obj, fname)
the_scope->local_tbl = tbl;
the_scope->local_vars = vars;
}
+ /* default visibility is private at loading toplevel */
+ FL_SET(the_scope, SCOPE_PRIVATE);
state = EXEC_TAG();
last_func = the_frame->last_func;
@@ -3546,27 +3826,26 @@ rb_provide(feature)
VALUE
f_require(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
- char *ext, *file, *feature, *buf;
- volatile VALUE load;
+ char *ext, *file, *feature, *buf; /* OK */
+ VALUE load;
Check_SafeStr(fname);
- if (rb_provided(fname->ptr))
+ if (rb_provided(RSTRING(fname)->ptr))
return FALSE;
- ext = strrchr(fname->ptr, '.');
+ ext = strrchr(RSTRING(fname)->ptr, '.');
if (ext) {
if (strcmp(".rb", ext) == 0) {
- feature = file = fname->ptr;
+ feature = file = RSTRING(fname)->ptr;
file = find_file(file);
if (file) goto rb_load;
}
else if (strcmp(".o", ext) == 0) {
- file = feature = fname->ptr;
+ file = feature = RSTRING(fname)->ptr;
if (strcmp(".o", DLEXT) != 0) {
- buf = ALLOCA_N(char, strlen(fname->ptr)+sizeof(DLEXT)+1);
+ buf = ALLOCA_N(char, strlen(file)+sizeof(DLEXT)+1);
strcpy(buf, feature);
ext = strrchr(buf, '.');
strcpy(ext, DLEXT);
@@ -3575,33 +3854,33 @@ f_require(obj, fname)
if (file) goto dyna_load;
}
else if (strcmp(DLEXT, ext) == 0) {
- feature = fname->ptr;
+ feature = RSTRING(fname)->ptr;
file = find_file(feature);
if (file) goto dyna_load;
}
}
- buf = ALLOCA_N(char, strlen(fname->ptr) + 5);
- sprintf(buf, "%s.rb", fname->ptr);
+ buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5);
+ sprintf(buf, "%s.rb", RSTRING(fname)->ptr);
file = find_file(buf);
if (file) {
- fname = (struct RString*)str_new2(file);
+ fname = str_new2(file);
feature = buf;
goto rb_load;
}
- sprintf(buf, "%s%s", fname->ptr, DLEXT);
+ sprintf(buf, "%s%s", RSTRING(fname)->ptr, DLEXT);
file = find_file(buf);
if (file) {
feature = buf;
goto dyna_load;
}
- LoadError("No such file to load -- %s", fname->ptr);
+ LoadError("No such file to load -- %s", RSTRING(fname)->ptr);
dyna_load:
#ifdef THREAD
if (thread_loading(feature)) return FALSE;
else {
- NODE *state;
- PUSH_TAG();
+ int state;
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
#endif
load = str_new2(file);
@@ -3621,8 +3900,8 @@ f_require(obj, fname)
#ifdef THREAD
if (thread_loading(feature)) return FALSE;
else {
- NODE *state;
- PUSH_TAG();
+ int state;
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
#endif
f_load(obj, fname);
@@ -3657,7 +3936,12 @@ mod_public(argc, argv, module)
VALUE *argv;
VALUE module;
{
- set_method_visibility(module, argc, argv, NOEX_PUBLIC);
+ if (argc == 0) {
+ FL_UNSET(the_scope, SCOPE_PRIVATE);
+ }
+ else {
+ set_method_visibility(module, argc, argv, NOEX_PUBLIC);
+ }
return module;
}
@@ -3667,7 +3951,12 @@ mod_private(argc, argv, module)
VALUE *argv;
VALUE module;
{
- set_method_visibility(module, argc, argv, NOEX_PRIVATE);
+ if (argc == 0) {
+ FL_SET(the_scope, SCOPE_PRIVATE);
+ }
+ else {
+ set_method_visibility(module, argc, argv, NOEX_PRIVATE);
+ }
return module;
}
@@ -3692,6 +3981,22 @@ mod_private_method(argc, argv, obj)
}
static VALUE
+top_public(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ return mod_public(argc, argv, cObject);
+}
+
+static VALUE
+top_private(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ return mod_private(argc, argv, cObject);
+}
+
+static VALUE
mod_modfunc(argc, argv, module)
int argc;
VALUE *argv;
@@ -3716,6 +4021,23 @@ mod_modfunc(argc, argv, module)
}
static VALUE
+mod_append_features(module, include)
+ VALUE module, include;
+{
+ switch (TYPE(include)) {
+ case T_CLASS:
+ case T_MODULE:
+ break;
+ default:
+ Check_Type(include, T_CLASS);
+ break;
+ }
+ rb_include_module(include, module);
+
+ return module;
+}
+
+static VALUE
mod_include(argc, argv, module)
int argc;
VALUE *argv;
@@ -3725,31 +4047,12 @@ mod_include(argc, argv, module)
for (i=0; i<argc; i++) {
Check_Type(argv[i], T_MODULE);
- rb_include_module(module, argv[i]);
+ rb_funcall(argv[i], rb_intern("append_features"), 1, module);
}
return module;
}
VALUE
-class_s_new(argc, argv, class)
- int argc;
- VALUE *argv;
- VALUE class;
-{
- VALUE obj = obj_alloc(class);
-
- if (FL_TEST(class, FL_SINGLETON)) {
- TypeError("can't create instance of virtual class");
- }
- obj = obj_alloc(class);
- PUSH_ITER(iterator_p()?ITER_PRE:ITER_NOT);
- rb_funcall2(obj, init, argc, argv);
- POP_ITER();
- return obj;
-}
-
-
-VALUE
class_new_instance(argc, argv, class)
int argc;
VALUE *argv;
@@ -3817,57 +4120,68 @@ errat_setter(val, id, var)
ID id;
VALUE *var;
{
- int i;
- static char *err = "value of $@ must be Array of String";
+ *var = check_errat(val);
+}
- if (!NIL_P(val)) {
- if (TYPE(val) != T_ARRAY) {
- TypeError(err);
- }
- for (i=0;i<RARRAY(val)->len;i++) {
- if (TYPE(RARRAY(val)->ptr[i]) != T_STRING) {
- TypeError(err);
- }
- }
- }
- *var = val;
+VALUE f_global_variables();
+static VALUE f_catch();
+static VALUE f_throw();
+
+struct end_proc_data {
+ void (*func)();
+ VALUE data;
+ struct end_proc_data *next;
+} *end_proc_data;
+
+void
+rb_set_end_proc(func, data)
+ void (*func)();
+ VALUE data;
+{
+ struct end_proc_data *link = ALLOC(struct end_proc_data);
+
+ link->next = end_proc_data;
+ link->func = func;
+ link->data = data;
+ rb_global_variable(&link->data);
+ end_proc_data = link;
}
-static VALUE
-f_catch(dmy, tag)
- VALUE dmy, tag;
+static void
+call_end_proc(data)
+ VALUE data;
{
- NODE *state;
- ID t;
- VALUE val;
+ proc_call(data, Qnil);
+}
- t = rb_to_id(tag);
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- val = rb_yield(tag);
- }
- POP_TAG();
- if (state) {
- if (state->nd_tag == TAG_THROW && state->nd_tlev == t) {
- return state->nd_tval;
- }
- JUMP_TAG(state);
- }
- return val;
+static void
+f_END()
+{
+ PUSH_FRAME();
+ rb_set_end_proc(call_end_proc, f_lambda());
+ POP_FRAME();
}
static VALUE
-f_throw(argc, argv)
- int argc;
- VALUE *argv;
+f_at_exit()
{
- VALUE tag, value;
- ID t;
+ VALUE proc;
- rb_scan_args(argc, argv, "11", &tag, &value);
- t = rb_to_id(tag);
- JUMP_TAG3(TAG_THROW, value, t);
- /* not reached */
+ proc = f_lambda();
+
+ rb_set_end_proc(call_end_proc, proc);
+ return proc;
+}
+
+static void
+exec_end_proc()
+{
+ struct end_proc_data *link = end_proc_data;
+
+ while (link) {
+ (*link->func)(link->data);
+ link = link->next;
+ }
}
void
@@ -3879,10 +4193,12 @@ Init_eval()
aref = rb_intern("[]");
aset = rb_intern("[]=");
+ match = rb_intern("=~");
- rb_global_variable(&top_scope);
- rb_global_variable(&eval_tree);
- rb_global_variable(&the_dyna_vars);
+ rb_global_variable((VALUE*)&top_scope);
+ rb_global_variable((VALUE*)&eval_tree0);
+ rb_global_variable((VALUE*)&eval_tree);
+ rb_global_variable((VALUE*)&the_dyna_vars);
rb_define_hooked_variable("$@", &errat, 0, errat_setter);
rb_define_hooked_variable("$!", &errinfo, 0, rb_str_setter);
@@ -3894,15 +4210,6 @@ Init_eval()
rb_define_method(mKernel, "respond_to?", obj_respond_to, -1);
- rb_define_global_function("break", f_break, 0);
- rb_define_alias(mKernel, "break!", "break");
- rb_define_global_function("next", f_next, 0);
- rb_define_alias(mKernel, "next!", "next");
- rb_define_alias(mKernel, "continue", "next");
- rb_define_global_function("redo", f_redo, 0);
- rb_define_alias(mKernel, "redo!", "redo");
- rb_define_global_function("retry", f_retry, 0);
- rb_define_alias(mKernel, "retry!", "retry");
rb_define_global_function("raise", f_raise, -1);
rb_define_alias(mKernel, "fail", "raise");
@@ -3911,21 +4218,37 @@ Init_eval()
rb_define_global_function("exit", f_exit, -1);
rb_define_global_function("abort", f_abort, 0);
+ rb_define_global_function("at_exit", f_at_exit, 0);
+
rb_define_global_function("catch", f_catch, 1);
rb_define_global_function("throw", f_throw, -1);
+ rb_define_global_function("global_variables", f_global_variables, 0);
rb_define_method(mKernel, "send", f_send, -1);
+ rb_define_method(mKernel, "instance_eval", obj_instance_eval, 1);
+ rb_define_private_method(cModule, "append_features", mod_append_features, 1);
+ rb_define_private_method(cModule, "extend_object", mod_extend_object, 1);
rb_define_private_method(cModule, "include", mod_include, -1);
rb_define_private_method(cModule, "public", mod_public, -1);
rb_define_private_method(cModule, "private", mod_private, -1);
rb_define_private_method(cModule, "module_function", mod_modfunc, -1);
rb_define_method(cModule, "method_defined?", mod_method_defined, 1);
- rb_define_method(cModule, "extend_object", mod_extend_object, 1);
rb_define_method(cModule, "public_class_method", mod_public_method, -1);
rb_define_method(cModule, "private_class_method", mod_private_method, -1);
+ rb_define_method(cModule, "module_eval", mod_module_eval, 1);
+
+ rb_define_method(cModule, "remove_method", mod_remove_method, -1);
+ rb_define_method(cModule, "undef_method", mod_undef_method, 1);
+ rb_define_method(cModule, "alias_method", mod_alias_method, 2);
+
+ rb_define_singleton_method(cModule, "nesting", mod_nesting, 0);
+ rb_define_singleton_method(cModule, "constants", mod_s_constants, 0);
+
+ rb_define_singleton_method(TopSelf, "include", top_include, -1);
+ rb_define_singleton_method(TopSelf, "public", top_public, -1);
+ rb_define_singleton_method(TopSelf, "private", top_private, -1);
- rb_define_method(CLASS_OF(TopSelf), "include", top_include, -1);
rb_define_method(mKernel, "extend", obj_extend, -1);
rb_define_global_function("trace_var", f_trace_var, -1);
@@ -4027,7 +4350,7 @@ static VALUE
proc_s_new(class)
VALUE class;
{
- VALUE proc;
+ volatile VALUE proc;
struct BLOCK *data;
if (!iterator_p() && !f_iterator_p()) {
@@ -4071,19 +4394,18 @@ f_lambda()
static VALUE
proc_call(proc, args)
- VALUE proc, args;
+ VALUE proc, args; /* OK */
{
struct BLOCK *data;
volatile VALUE result = Qnil;
- NODE *state;
- int tag_level;
+ int state;
volatile int orphan;
volatile int safe = safe_level;
if (TYPE(args) == T_ARRAY) {
switch (RARRAY(args)->len) {
case 0:
- args = 0;
+ args = Qnil;
break;
case 1:
args = RARRAY(args)->ptr[0];
@@ -4132,7 +4454,7 @@ proc_call(proc, args)
}
}
- PUSH_TAG();
+ PUSH_TAG(PROT_NONE);
state = EXEC_TAG();
if (state == 0) {
result = rb_yield(args);
@@ -4140,31 +4462,26 @@ proc_call(proc, args)
POP_TAG();
POP_ITER();
- tag_level = the_block->level;
+ if (the_block->tag->dst == state) {
+ state &= TAG_MASK;
+ }
POP_BLOCK();
safe_level = safe;
if (state) {
if (orphan) {/* orphan procedure */
- switch (state->nd_tag) {
- case TAG_BREAK: /* never happen */
- case IN_BLOCK|TAG_BREAK:
- if (state->nd_tlev == tag_level)
- Raise(eLocalJumpError, "break from proc-closure");
+ switch (state) {
+ case TAG_BREAK:
+ Raise(eLocalJumpError, "break from proc-closure");
break;
case TAG_RETRY:
Raise(eLocalJumpError, "retry from proc-closure");
break;
- case TAG_RETURN: /* never happen */
- case IN_BLOCK|TAG_RETURN:
- if (state->nd_tlev == tag_level)
- Raise(eLocalJumpError, "return from proc-closure");
+ case TAG_RETURN:
+ Raise(eLocalJumpError, "return from proc-closure");
break;
}
}
- else if (state->nd_tlev == tag_level) {
- state->nd_tag &= ~IN_BLOCK;
- }
JUMP_TAG(state);
}
return result;
@@ -4241,11 +4558,11 @@ struct thread {
struct FRAME *frame;
struct SCOPE *scope;
- struct RClass *class;
struct RVarmap *dyna_vars;
struct BLOCK *block;
struct iter *iter;
struct tag *tag;
+ VALUE class;
VALUE trace;
@@ -4358,13 +4675,13 @@ thread_free(th)
static thread_t
thread_check(data)
- struct RData *data;
+ VALUE data;
{
- if (TYPE(data) != T_DATA || data->dfree != thread_free) {
+ if (TYPE(data) != T_DATA || RDATA(data)->dfree != thread_free) {
TypeError("wrong argument type %s (expected Thread)",
rb_class2name(CLASS_OF(data)));
}
- return (thread_t)data->data;
+ return (thread_t)RDATA(data)->data;
}
VALUE lastline_get();
@@ -4472,7 +4789,7 @@ thread_restore_context(th, exit)
switch (ex) {
case 1:
- JUMP_TAG2(TAG_FATAL, INT2FIX(0));
+ JUMP_TAG(TAG_FATAL);
break;
case 2:
@@ -4540,7 +4857,7 @@ thread_deadlock()
void
thread_schedule()
{
- thread_t next;
+ thread_t next; /* OK */
thread_t th;
thread_t curr;
@@ -4564,8 +4881,6 @@ thread_schedule()
END_FOREACH_FROM(curr,th);
if (num_waiting_on_join) {
- curr_thread->file = sourcefile;
- curr_thread->line = sourceline;
FOREACH_THREAD_FROM(curr,th) {
if ((th->wait_for & WAIT_JOIN) && thread_dead(th->join)) {
th->join = 0;
@@ -4581,7 +4896,7 @@ thread_schedule()
if (num_waiting_on_fd > 0 || num_waiting_on_timer > 0) {
fd_set readfds;
struct timeval delay_tv, *delay_ptr;
- double delay, now;
+ double delay, now; /* OK */
int n, max;
@@ -4664,6 +4979,8 @@ thread_schedule()
}
if (!next) {
+ curr_thread->file = sourcefile;
+ curr_thread->line = sourceline;
FOREACH_THREAD_FROM(curr,th) {
fprintf(stderr, "%s:%d:deadlock 0x%x: %d:%d %s\n",
th->file, th->line, th->thread, th->status,
@@ -4969,6 +5286,8 @@ thread_stop()
return Qnil;
}
+struct timeval time_timeval();
+
void
thread_sleep(sec)
int sec;
@@ -5111,7 +5430,7 @@ thread_create(fn, arg)
void *arg;
{
thread_t th = thread_alloc();
- NODE *state;
+ int state;
#if defined(HAVE_SETITIMER) && !defined(__BOW__)
static init = 0;
@@ -5139,7 +5458,7 @@ thread_create(fn, arg)
return th->thread;
}
- PUSH_TAG();
+ PUSH_TAG(PROT_THREAD);
if ((state = EXEC_TAG()) == 0) {
thread_save_context(th);
if (setjmp(th->context) == 0) {
@@ -5148,47 +5467,34 @@ thread_create(fn, arg)
}
}
POP_TAG();
- if (state) {
- if (state->nd_tag == TAG_THROW) {
- char *mesg;
- char *tag = rb_id2name(state->nd_tlev);
-
- mesg = ALLOCA_N(char, strlen(tag) + 64);
-
- sprintf(mesg, "uncaught throw `%s' in thread 0x%x\n",
- tag, th->thread);
- curr_thread->errinfo = exc_new2(eThreadError, mesg);
- curr_thread->errat = make_backtrace();
- }
- else if (th->status != THREAD_TO_KILL && !NIL_P(errinfo)) {
- if (state->nd_tag == TAG_FATAL ||
- obj_is_kind_of(errinfo, eSystemExit)) {
- /* fatal error or global exit within this thread */
- /* need to stop whole script */
- main_thread->errat = errat;
- main_thread->errinfo = errinfo;
- thread_cleanup();
- }
- else if (thread_abort || curr_thread->abort) {
- f_abort();
- }
- else {
- curr_thread->errat = errat;
- curr_thread->errinfo = errinfo;
- }
+ if (state && th->status != THREAD_TO_KILL && !NIL_P(errinfo)) {
+ if (state == TAG_FATAL || obj_is_kind_of(errinfo, eSystemExit)) {
+ /* fatal error or global exit within this thread */
+ /* need to stop whole script */
+ main_thread->errat = errat;
+ main_thread->errinfo = errinfo;
+ thread_cleanup();
+ }
+ else if (thread_abort || curr_thread->abort || RTEST(debug)) {
+ f_abort();
+ }
+ else {
+ curr_thread->errat = errat;
+ curr_thread->errinfo = errinfo;
}
}
thread_remove();
return 0;
}
-static void
+static VALUE
thread_yield(arg, th)
int arg;
thread_t th;
{
scope_dup(the_block->scope);
rb_yield(th->thread);
+ return th->thread;
}
static VALUE
@@ -5400,3 +5706,83 @@ Init_Thread()
main_thread = thread_alloc();
}
#endif
+
+static VALUE
+f_catch(dmy, tag)
+ VALUE dmy, tag;
+{
+ int state;
+ ID t;
+ VALUE val; /* OK */
+
+ t = rb_to_id(tag);
+ PUSH_TAG(t);
+ if ((state = EXEC_TAG()) == 0) {
+ val = rb_yield(tag);
+ }
+ else if (state == TAG_THROW && prot_tag->tag == prot_tag->dst) {
+ val = prot_tag->tag_retval;
+ state = 0;
+ }
+ POP_TAG();
+ if (state) JUMP_TAG(state);
+
+ return val;
+}
+
+static VALUE
+f_throw(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE tag, value;
+ ID t;
+ struct tag *tt = prot_tag;
+
+ rb_scan_args(argc, argv, "11", &tag, &value);
+ t = rb_to_id(tag);
+
+ while (tt) {
+ if (tt->tag == t) {
+ tt->dst = t;
+ tt->tag_retval = value;
+ break;
+ }
+#ifdef THREAD
+ if (tt->tag == PROT_THREAD) {
+ Raise(eThreadError, "uncaught throw `%s' in thread 0x%x\n",
+ rb_id2name(t),
+ curr_thread);
+ }
+#endif
+ tt = tt->prev;
+ }
+
+ if (!tt) {
+ NameError("uncaught throw `%s'\n", rb_id2name(t));
+ }
+ JUMP_TAG(TAG_THROW);
+ /* not reached */
+}
+
+static void
+return_value(val)
+ VALUE val;
+{
+ struct tag *tt = prot_tag;
+
+ while (tt) {
+ if (tt->tag == PROT_FUNC) {
+ tt->tag_retval = val;
+ break;
+ }
+#ifdef THREAD
+ if (tt->tag == PROT_THREAD) {
+ Raise(eThreadError, "return from within thread 0x%x\n",
+ curr_thread);
+ }
+#endif
+ tt = tt->prev;
+ }
+}
+
diff --git a/ext/Setup b/ext/Setup
index a5dd797..c92ac53 100644
--- a/ext/Setup
+++ b/ext/Setup
@@ -6,7 +6,7 @@
#etc
#fcntl
#kconv
-#marshal
#md5
#socket
#tkutil
+#tcltklib
diff --git a/ext/curses/curses.c b/ext/curses/curses.c
index 6e8e496..3ae8db1 100644
--- a/ext/curses/curses.c
+++ b/ext/curses/curses.c
@@ -32,7 +32,8 @@ struct windata {
WINDOW *window;
};
-#define NUM2CHAR(x) (char)NUM2INT(x)
+#define NUM2CHAR(x) ((TYPE(x) == T_STRING)&&(RSTRING(x)->len>=1))?\
+ RSTRING(x)->ptr[0]:(char)NUM2INT(x)
#define CHAR2FIX(x) INT2FIX((int)x)
static void
@@ -46,13 +47,7 @@ no_window()
if (winp->window == 0) no_window();\
}
-static void
-curses_err()
-{
- Fail("curses error");
-}
-
-#define CHECK(c) if ((c)==ERR) {curses_err();}
+#define CHECK(c) c
static void
free_window(winp)
@@ -99,7 +94,7 @@ curses_init_screen()
static VALUE
curses_stdscr()
{
- if (!rb_stdscr) curses_init_screen();
+ if (rb_stdscr == 0) curses_init_screen();
return rb_stdscr;
}
@@ -107,7 +102,7 @@ curses_stdscr()
static VALUE
curses_close_screen()
{
- CHECK(endwin());
+ endwin();
return Qnil;
}
@@ -139,7 +134,7 @@ static VALUE
curses_refresh(obj)
VALUE obj;
{
- CHECK(refresh());
+ refresh();
return Qnil;
}
@@ -148,7 +143,7 @@ static VALUE
curses_doupdate(obj)
VALUE obj;
{
- CHECK(doupdate());
+ doupdate();
return Qnil;
}
@@ -157,7 +152,7 @@ static VALUE
curses_echo(obj)
VALUE obj;
{
- CHECK(echo());
+ echo();
return Qnil;
}
@@ -166,7 +161,7 @@ static VALUE
curses_noecho(obj)
VALUE obj;
{
- CHECK(noecho());
+ noecho();
return Qnil;
}
@@ -175,7 +170,7 @@ static VALUE
curses_raw(obj)
VALUE obj;
{
- CHECK(raw());
+ raw();
return Qnil;
}
@@ -184,7 +179,7 @@ static VALUE
curses_noraw(obj)
VALUE obj;
{
- CHECK(noraw());
+ noraw();
return Qnil;
}
@@ -193,7 +188,7 @@ static VALUE
curses_cbreak(obj)
VALUE obj;
{
- CHECK(cbreak());
+ cbreak();
return Qnil;
}
@@ -202,7 +197,7 @@ static VALUE
curses_nocbreak(obj)
VALUE obj;
{
- CHECK(nocbreak());
+ nocbreak();
return Qnil;
}
@@ -211,7 +206,7 @@ static VALUE
curses_nl(obj)
VALUE obj;
{
- CHECK(nl());
+ nl();
return Qnil;
}
@@ -220,7 +215,7 @@ static VALUE
curses_nonl(obj)
VALUE obj;
{
- CHECK(nonl());
+ nonl();
return Qnil;
}
@@ -251,7 +246,7 @@ curses_ungetch(obj, ch)
VALUE ch;
{
#ifdef HAVE_UNGETCH
- CHECK(ungetch(NUM2INT(ch)));
+ ungetch(NUM2INT(ch));
#else
rb_notimplement();
#endif
@@ -265,7 +260,7 @@ curses_setpos(obj, y, x)
VALUE y;
VALUE x;
{
- CHECK(move(NUM2INT(y), NUM2INT(x)));
+ move(NUM2INT(y), NUM2INT(x));
return Qnil;
}
@@ -301,7 +296,7 @@ curses_addch(obj, ch)
VALUE obj;
VALUE ch;
{
- CHECK(addch(NUM2CHAR(ch)));
+ addch(NUM2CHAR(ch));
return Qnil;
}
@@ -311,7 +306,7 @@ curses_insch(obj, ch)
VALUE obj;
VALUE ch;
{
- CHECK(insch(NUM2CHAR(ch)));
+ insch(NUM2CHAR(ch));
return Qnil;
}
@@ -339,7 +334,7 @@ curses_getstr(obj)
VALUE obj;
{
char rtn[1024]; /* This should be big enough.. I hope */
- CHECK(getstr(rtn));
+ getstr(rtn);
return str_taint(str_new2(rtn));
}
@@ -348,7 +343,7 @@ static VALUE
curses_delch(obj)
VALUE obj;
{
- CHECK(delch());
+ delch();
return Qnil;
}
@@ -357,7 +352,7 @@ static VALUE
curses_deleteln(obj)
VALUE obj;
{
- CHECK(deleteln());
+ deleteln();
return Qnil;
}
@@ -443,7 +438,7 @@ window_refresh(obj)
struct windata *winp;
GetWINDOW(obj, winp);
- CHECK(wrefresh(winp->window));
+ wrefresh(winp->window);
return Qnil;
}
@@ -474,7 +469,7 @@ window_move(obj, y, x)
struct windata *winp;
GetWINDOW(obj, winp);
- CHECK(mvwin(winp->window, NUM2INT(y), NUM2INT(x)));
+ mvwin(winp->window, NUM2INT(y), NUM2INT(x));
return Qnil;
}
@@ -489,7 +484,7 @@ window_setpos(obj, y, x)
struct windata *winp;
GetWINDOW(obj, winp);
- CHECK(wmove(winp->window, NUM2INT(y), NUM2INT(x)));
+ wmove(winp->window, NUM2INT(y), NUM2INT(x));
return Qnil;
}
@@ -639,7 +634,7 @@ window_addch(obj, ch)
struct windata *winp;
GetWINDOW(obj, winp);
- CHECK(waddch(winp->window, NUM2CHAR(ch)));
+ waddch(winp->window, NUM2CHAR(ch));
return Qnil;
}
@@ -653,7 +648,7 @@ window_insch(obj, ch)
struct windata *winp;
GetWINDOW(obj, winp);
- CHECK(winsch(winp->window, NUM2CHAR(ch)));
+ winsch(winp->window, NUM2CHAR(ch));
return Qnil;
}
@@ -667,7 +662,7 @@ window_addstr(obj, str)
struct windata *winp;
GetWINDOW(obj, winp);
- CHECK(waddstr(winp->window, RSTRING(str)->ptr));
+ waddstr(winp->window, RSTRING(str)->ptr);
return Qnil;
}
@@ -702,7 +697,7 @@ window_getstr(obj)
char rtn[1024]; /* This should be big enough.. I hope */
GetWINDOW(obj, winp);
- CHECK(wgetstr(winp->window, rtn));
+ wgetstr(winp->window, rtn);
return str_taint(str_new2(rtn));
}
@@ -714,7 +709,7 @@ window_delch(obj)
struct windata *winp;
GetWINDOW(obj, winp);
- CHECK(wdelch(winp->window));
+ wdelch(winp->window);
return Qnil;
}
@@ -726,7 +721,7 @@ window_deleteln(obj)
struct windata *winp;
GetWINDOW(obj, winp);
- CHECK(wdeleteln(winp->window));
+ wdeleteln(winp->window);
return Qnil;
}
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c
index ea0ac19..b416802 100644
--- a/ext/dbm/dbm.c
+++ b/ext/dbm/dbm.c
@@ -122,17 +122,15 @@ fdbm_fetch(obj, keystr)
}
static VALUE
-fdbm_indexes(obj, args)
- VALUE obj;
- struct RArray *args;
+fdbm_indexes(obj, ag)
+ VALUE obj, ag;
{
VALUE *p, *pend;
VALUE new;
int i = 0;
+ struct RArray *args = RARRAY(rb_Array(ag));
- args = (struct RArray*)rb_to_a(args);
new = ary_new2(args->len);
-
p = args->ptr; pend = p + args->len;
while (p < pend) {
ary_push(new, fdbm_fetch(obj, *p++));
diff --git a/ext/dbm/depend b/ext/dbm/depend
index 4013996..d7f1f41 100644
--- a/ext/dbm/depend
+++ b/ext/dbm/depend
@@ -1 +1 @@
-dbm.o: dbm.c ../../ruby.h ../../config.h ../../defines.h
+dbm.o: dbm.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h
diff --git a/ext/etc/depend b/ext/etc/depend
index 5c95ef1..fb3318a 100644
--- a/ext/etc/depend
+++ b/ext/etc/depend
@@ -1 +1 @@
-etc.o : etc.c ../../ruby.h ../../config.h ../../defines.h
+etc.o : etc.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index 78fe307..e1d318d 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -1,5 +1,7 @@
#! /usr/local/bin/ruby
+$".push 'mkmf.rb'
+
if ARGV[0] == 'static'
$force_static = TRUE
ARGV.shift
@@ -21,16 +23,17 @@ $topdir = "@top_srcdir@"
if $topdir !~ "^/"
# get absolute path
save = Dir.pwd
- Dir.chdir ".."
+ Dir.chdir $topdir
$topdir = Dir.pwd
Dir.chdir save
end
+$dots = if "@INSTALL@" =~ /^\// then "" else "#{$topdir}/ext/" end
if File.exist?("config.cache") then
f = open("config.cache", "r")
while f.gets
case $_
- when /^lib: ([\w_]+) (yes|no)/
+ when /^lib: (.+) (yes|no)/
$lib_cache[$1] = $2
when /^func: ([\w_]+) (yes|no)/
$func_cache[$1] = $2
@@ -215,6 +218,8 @@ SHELL = /bin/sh
srcdir = #{$srcdir}
VPATH = #{$srcdir}
+hdrdir = #{$topdir}
+
CC = @CC@
CFLAGS = %s -I#{$topdir} %s #$CFLAGS %s
@@ -233,20 +238,22 @@ libdir = @libdir@/$(RUBY_INSTALL_NAME)/@arch@
@SET_MAKE@
#### End of system configuration section. ####
+
"
mfile.printf "LOCAL_LIBS = %s\n", $local_libs if $local_libs
mfile.printf "LIBS = %s\n", $libs
mfile.printf "OBJS = "
if !$objs then
- $objs = Dir["#{$topdir}/ext/#{target}/*.c"]
- for f in $objs
- f.sub!(/\.c$/, ".o")
+ $objs = []
+ for f in Dir["#{$topdir}/ext/#{target}/*.{c,cc}"]
+ f = File.basename(f)
+ f.sub!(/\.(c|cc)$/, ".o")
+ $objs.push f
end
end
mfile.printf $objs.join(" ")
mfile.printf "\n"
- dots = if "@INSTALL@" =~ /^\// then "" else "#{$topdir}/ext/" end
mfile.printf "\
TARGET = %s.%s
@@ -262,28 +269,29 @@ clean:; @rm -f *.o *.so *.sl
realclean: clean
", target,
- if $static then "o" else "@DLEXT@" end, dots
+ if $static then "o" else "@DLEXT@" end, $dots
- if !$static
- mfile.printf "\
+ mfile.printf "\
install:
+"
+ if !$static
+ mfile.printf "
@test -d $(libdir) || mkdir $(libdir)
$(INSTALL) $(TARGET) $(libdir)/$(TARGET)
"
- else
- mfile.printf "\
-
-install:;
-"
end
+ for rb in Dir["lib/*.rb"]
+ mfile.printf "\t$(INSTALL) %s @libdir@/$(RUBY_INSTALL_NAME)\n", rb
+ end
+ mfile.printf "\n"
if !$static && "@DLEXT@" != "o"
mfile.printf "\
$(TARGET): $(OBJS)
$(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LOCAL_LIBS) $(LIBS)
"
- elsif not File.exist?(target + ".c")
+ elsif not File.exist?(target + ".c") and not File.exist?(target + ".cc")
if PLATFORM == "m68k-human"
mfile.printf "\
$(TARGET): $(OBJS)
@@ -316,9 +324,6 @@ $(TARGET): $(OBJS)
dfile.close
end
mfile.close
- if $static
- $extlist.push [$static,target]
- end
end
def extmake(target)
@@ -343,16 +348,19 @@ def extmake(target)
!File.exist?("./Makefile") ||
older("./Makefile", "#{$topdir}/ext/@setup@") ||
older("./Makefile", "../extmk.rb") ||
- older("./Makefile", "./extconf.rb")
+ older("./Makefile", "#{$topdir}/ext/#{target}/extconf.rb")
then
$defs = []
- if File.exist?("extconf.rb")
- load "extconf.rb"
+ if File.exist?("#{$topdir}/ext/#{target}/extconf.rb")
+ load "#{$topdir}/ext/#{target}/extconf.rb"
else
create_makefile(target);
end
end
if File.exist?("./Makefile")
+ if $static
+ $extlist.push [$static,target]
+ end
if $install
system "make install"
elsif $clean
@@ -373,19 +381,22 @@ end
# get static-link modules
$static_ext = {}
-if File.file? "#{$topdir}/ext/@setup@"
- f = open("#{$topdir}/ext/@setup@")
- while f.gets()
- $_.chop!
- sub!(/#.*$/, '')
- next if /^\s*$/
- if /^option +nodynamic/
- $nodynamic = TRUE
- next
+for setup in ["@setup@", "#{$topdir}/ext/@setup@"]
+ if File.file? setup
+ f = open(setup)
+ while f.gets()
+ $_.chop!
+ sub!(/#.*$/, '')
+ next if /^\s*$/
+ if /^option +nodynamic/
+ $nodynamic = TRUE
+ next
+ end
+ $static_ext[$_.split[0]] = TRUE
end
- $static_ext[$_.split[0]] = TRUE
+ f.close
+ break
end
- f.close
end
for d in Dir["#{$topdir}/ext/*"]
@@ -418,6 +429,7 @@ if $cache_mod
end
exit if $install or $clean
+$extinit += ""
if $extlist.size > 0
for s,t in $extlist
f = format("%s/%s.o", s, t)
diff --git a/ext/extmk.rb.nt b/ext/extmk.rb.nt
index 04b9e40..6792f27 100644
--- a/ext/extmk.rb.nt
+++ b/ext/extmk.rb.nt
@@ -18,7 +18,8 @@ $lib_cache = {}
$func_cache = {}
$hdr_cache = {}
-$dllopt = '-MD'
+#$dllopt = '-MD'
+$dllopt = ''
if File.exist?("config.cache") then
f = open("config.cache", "r")
@@ -48,11 +49,15 @@ def older(file1, file2)
return FALSE
end
-LINK = "cl -o conftest -I../.. -Zi -O -I. %s %s conftest.c %s > nul"
-CPP = "cl -E -I../.. -I../../missing -I. -Zi -O %s conftest.c > nul"
+#LINK = "cl -o conftest.exe -I../.. -Zi -O -I. %s conftest.c %s > nul"
+LINK = "cl -o conftest.exe -Zi -O %s conftest.c %s > nul"
+CPP = "cl -E -I../.. -I../../missing -I../../win32 -I. -Zi -O %s conftest.c > nul"
def try_link(libs)
- system(format(LINK, $CFLAGS, $LDFLAGS, libs))
+ #print(format("try #{LINK}", $CFLAGS, $LDFLAGS, libs))
+ #system(format(LINK, $CFLAGS, $LDFLAGS, libs))
+ print(format("try #{LINK}\n", $CFLAGS, libs))
+ system(format(LINK, $CFLAGS, libs))
end
def try_cpp
@@ -60,12 +65,13 @@ def try_cpp
end
def have_library(lib, func)
+ #print format("have_library(%s, %s)\n", lib, func)
if $lib_cache[lib]
if $lib_cache[lib] == "yes"
- if $libs
- $libs = "-l" + lib + " " + $libs
+ if $libs#
+ $libs = lib + ".lib " + $libs
else
- $libs = "-l" + lib
+ $libs = lib + ".lib "
end
return TRUE
else
@@ -75,6 +81,8 @@ def have_library(lib, func)
cfile = open("conftest.c", "w")
cfile.printf "\
+#include <windows.h>
+#include <winsock.h>
int main() { return 0; }
int t() { %s(); return 0; }
", func
@@ -86,7 +94,9 @@ int t() { %s(); return 0; }
else
libs = lib + ".lib"
end
+ #print "libs=#{libs}\n"
unless try_link(libs)
+ #print "fail : #{libs}\n"
$lib_cache[lib] = 'no'
$cache_mod = TRUE
return FALSE
@@ -113,7 +123,9 @@ def have_func(func)
cfile = open("conftest.c", "w")
cfile.printf "\
-char %s();
+#include <windows.h>
+#include <winsock.h>
+//char %s();
int main() { return 0; }
int t() { %s(); return 0; }
", func, func
@@ -123,6 +135,7 @@ int t() { %s(); return 0; }
libs = "" if libs == nil
begin
+ #print "libs=#{libs}\n"
unless try_link(libs)
$func_cache[func] = 'no'
$cache_mod = TRUE
@@ -186,7 +199,7 @@ def create_makefile(target)
if $libs and "obj" == "obj"
libs = $libs.split
for lib in libs
- lib.sub!(/(.*)/, '"lib\1.lib"')
+ lib.sub!(/(.*)/, '"\1.lib"') if /.lib$/ !~ lib
end
$defs.push(format("-DEXTLIB='%s'", libs.join(",")))
end
@@ -203,7 +216,7 @@ VPATH = .
CC = cl
-CFLAGS = %s -I../.. -I../../missing -I. -O -DNT %s #$CFLAGS %s
+CFLAGS = %s -I../.. -I../../missing -I../../win32 -I. -O -DNT %s #$CFLAGS %s
RUBYLIB = ../../ruby.lib
DLDFLAGS = /DLL
@@ -211,9 +224,9 @@ LDSHARED =
", if $static then "" else "-fpic" end, $dllopt, $defs.join(" ")
if $force_static
- print "static\n"
+ print "static\n"
else
- print "non static\n"
+ print "non static\n"
end
mfile.printf "\
@@ -245,7 +258,7 @@ DEFFILE = %s.def
all: $(TARGET)
-clean:; @rm -f *.obj *.lib *.exp *.pdb *.bak
+clean:; @rm -f *.obj *.lib *.exp vc*.pdb *.bak *.def
@rm -f Makefile extconf.h conftest.*
realclean: clean
@@ -274,8 +287,8 @@ $(TARGET): $(OBJS)
lib /OUT:$(TARGET) $(OBJS)
"
else
- mfile.printf "\
-$(DEFFILE):
+ mfile.printf "\
+$(DEFFILE):
echo $(DEFFILE)
$(TARGET): $(OBJS) $(DEFFILE)
@@ -293,11 +306,28 @@ $(TARGET): $(OBJS) $(DEFFILE)
end
mfile.close
if $static
- printf format("push %s,%s\n", $static, target); ##debug print##
+ #printf format("push %s,%s\n", $static, target); ##debug print##
$extlist.push [$static,target]
end
end
+#template of .def file.
+def create_def(basename)
+ defname = sprintf("%s.def", basename)
+ f = open(defname, "w")
+ f.printf "\
+LIBRARY %s.dll
+CODE LOADONCALL
+DATA LOADONCALL
+DESCRIPTION 'win32 %s.dll'
+EXPORTS
+
+ Init_%s
+", basename, basename, basename
+ f.close
+
+end
+
def extmake(target)
if $force_static or $static_ext[target]
$static = target
@@ -328,6 +358,11 @@ def extmake(target)
create_makefile(target);
end
end
+
+ if !File.exist?("#{target}.def")
+ create_def(target)
+ end
+
if File.exist?("./Makefile")
if $install
system "nmake install"
@@ -339,10 +374,12 @@ def extmake(target)
elsif $clean
system "nmake clean"
else
+ #print "!!!make!!!\n"
system "nmake all"
end
end
if $static
+ #$extlibs = " "
$extlibs += " " + $LDFLAGS if $LDFLAGS
$extlibs += " " + $local_libs if $local_libs
$extlibs += " " + $libs if $libs
@@ -360,7 +397,8 @@ if File.file? "./Setup"
$_.chop!
sub!(/#.*$/, '')
next if /^\s*$/
- print $_, "\n"
+ #print $_, "\n"
+
if /^option +nodynamic/
$nodynamic = TRUE
next
@@ -401,20 +439,19 @@ end
exit if $install or $clean
if $extlist.size > 0
- #for s,t in $extlist
- for s,t in $static_ext
+ for s,t in $extlist
+ #for s,t in $static_ext
#f = format("%s/%s.obj", s, t)
#f = format("%s/%s.obj", s, s)
- l = format("%s/%s.lib", s, s)
- #print format("%s/%s.obj\n", s, s) ##debug print##
+ l = format("%s/%s.lib", s, s)
if File.exist?(l)
$extinit += format("\
\tInit_%s();\n\
\trb_provide(\"%s.o\");\n\
", s, s)
$extobjs += "ext/"
- #$extobjs += f # *.obj
- $extobjs += l # *.lib
+ #$extobjs += f # *.obj
+ $extobjs += l # *.lib
$extobjs += " "
else
FALSE
@@ -441,7 +478,12 @@ if $extlist.size > 0
end
$extobjs = "ext/extinit.obj " + $extobjs
- $extlibs = ""
+ #$extlibs = ""
+ #print "EXTLIBS=#{$extlibs}\n"
+ $extlibs.gsub!("-L/usr/local/lib", "") if $extlibs
+ $extlibs.gsub!(" +", " ") if $extlibs
+ #print "EXTLIBS=#{$extlibs}\n"
+
system format('nmake ruby.exe EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs)
else
Dir.chdir ".."
@@ -450,31 +492,6 @@ else
`cp miniruby.exe ruby.exe`
end
end
-
-#template of .def file.
-#LIBRARY kconv.dll
-#CODE LOADONCALL
-#DATA LOADONCALL
-#DESCRIPTION 'win32 kconv.dll'
-#EXPORTS
-#
-# Init_kconv
-def makedef(basename)
- defname = sprintf("%s.def", basename)
- f = open(defname, "w")
- f.printf "\
-LIBRARY %s.dll
-CODE LOADONCALL
-DATA LOADONCALL
-DESCRIPTION 'win32 %s.dll'
-EXPORTS
-
- Init_%s
-", basename, basename
- f.close
-
-end
-
#Local variables:
# mode: ruby
#end:
diff --git a/ext/fcntl/depend b/ext/fcntl/depend
index 3c7ef84..a7915c7 100644
--- a/ext/fcntl/depend
+++ b/ext/fcntl/depend
@@ -1 +1 @@
-fcntl.o: fcntl.c ../../ruby.h ../../config.h ../../defines.h
+fcntl.o: fcntl.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h
diff --git a/ext/kconv/depend b/ext/kconv/depend
index e87b1fd..8f09d95 100644
--- a/ext/kconv/depend
+++ b/ext/kconv/depend
@@ -1 +1 @@
-kconv.o: kconv.c ../../ruby.h ../../config.h ../../defines.h
+kconv.o: kconv.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h
diff --git a/ext/kconv/kconv.c b/ext/kconv/kconv.c
index 3c59cb6..6778afc 100644
--- a/ext/kconv/kconv.c
+++ b/ext/kconv/kconv.c
@@ -88,6 +88,9 @@ static char *Patchlevel =
#define _JIS 1
#define _EUC 2
#define _SJIS 3
+#define _BINARY 4
+#define _NOCONV 4
+#define _UNKNOWN _AUTO
#if (defined(__TURBOC__) || defined(LSI_C)) && !defined(MSDOS)
#define MSDOS
@@ -596,7 +599,7 @@ do_kconv(i, o, siz, out_code, in_code)
outptr = o; /* output buffer */
outsiz = siz; /* output buffer size */
outlen = 0; /* current length of output string */
- x0201_f = FALSE; /* don't assume JISX0201 kana */
+ x0201_f = TRUE; /* don't assume JISX0201 kana */
rot_f = FALSE; /* rot14/43 mode */
input_f = FALSE; /* non fixed input code */
alpha_f = FALSE; /* convert JISX0208 alphbet to ASCII */
@@ -1774,7 +1777,7 @@ kconv_kconv(argc, argv)
int argc;
VALUE *argv;
{
- struct RString *src, *dst;
+ VALUE src, dst;
VALUE in, out;
int in_code, out_code;
@@ -1786,63 +1789,134 @@ kconv_kconv(argc, argv)
}
else {
out_code = NUM2INT(out);
+ if (out_code == _NOCONV) return (VALUE)src;
}
if (NIL_P(in)) {
in_code = _AUTO;
}
else {
in_code = NUM2INT(in);
+ if (in_code == _NOCONV) return (VALUE)src;
}
- dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
- dst->len = do_kconv(src->ptr, dst->ptr, dst->len, out_code, in_code);
+ dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
+ RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, out_code, in_code);
- return (VALUE)dst;
+ return dst;
}
static VALUE
kconv_tojis(obj, src)
- VALUE obj;
- struct RString *src;
+ VALUE obj, src;
{
- struct RString *dst;
+ VALUE dst;
Check_Type(src, T_STRING);
- dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
- dst->len = do_kconv(src->ptr, dst->ptr, dst->len, _JIS, _AUTO);
+ dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
+ RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _JIS, _AUTO);
- return (VALUE)dst;
+ return dst;
}
static VALUE
kconv_toeuc(obj, src)
- VALUE obj;
- struct RString* src;
+ VALUE obj, src;
{
- struct RString *dst;
+ VALUE dst;
Check_Type(src, T_STRING);
- dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
- dst->len = do_kconv(src->ptr, dst->ptr, dst->len, _EUC, _AUTO);
+ dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
+ RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _EUC, _AUTO);
return (VALUE)dst;
}
static VALUE
kconv_tosjis(obj, src)
- VALUE obj;
- struct RString* src;
+ VALUE obj, src;
{
- struct RString *dst;
+ VALUE dst;
Check_Type(src, T_STRING);
- dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
- dst->len = do_kconv(src->ptr, dst->ptr, dst->len, _SJIS, _AUTO);
+ dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */
+ RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _SJIS, _AUTO);
- return (VALUE)dst;
+ return dst;
+}
+
+/*
+ * Character code detection - Algorithm described in:
+ * Ken Lunde. `Understanding Japanese Information Processing'
+ * Sebastopol, CA: O'Reilly & Associates.
+ */
+
+static VALUE
+kconv_guess(obj, src)
+ VALUE obj, src;
+{
+ unsigned char *p = RSTRING(src)->ptr;
+ unsigned char *pend = p + RSTRING(src)->len;
+
+#define INCR {p++;if (p==pend) return INT2FIX(_UNKNOWN);}
+
+ while (p<pend) {
+ if (*p == '\033') {
+ return INT2FIX(_JIS);
+ }
+ if ('\000' < *p && *p < '\006'
+ || *p == 0x7f
+ || *p == 0xdf) {
+ return INT2FIX(_BINARY);
+ }
+ if (0x81 <= *p && *p <= 0x8d) {
+ return INT2FIX(_SJIS);
+ }
+ if (*p == 0x8e) {
+ INCR;
+ if ((0x40 <= *p && *p <= 0x7e) ||
+ (0x80 <= *p && *p <= 0xa0) ||
+ (0xe0 <= *p && *p <= 0xfc))
+ return INT2FIX(_SJIS);
+ }
+ if (0xa1 <= *p && *p <= 0xdf) {
+ INCR;
+ if (0xf0 <= *p && *p <= 0xfe)
+ return INT2FIX(_EUC);
+ if (0xe0 <= *p && *p <= 0xef) {
+ while (*p >= 0x40) {
+ if (*p >= 0x81) {
+ if (0x8d <= *p || (0x8f <= *p && *p <= 0x9f)) {
+ return INT2FIX(_SJIS);
+ }
+ else if (0xfd <= *p && *p <= 0xfe) {
+ return INT2FIX(_EUC);
+ }
+ }
+ }
+ }
+ if (*p <= 0x9f) {
+ return INT2FIX(_SJIS);
+ }
+ }
+ if (0xf0 <= *p && *p <= 0xfe) {
+ return INT2FIX(_EUC);
+ }
+ if (0xe0 <= *p && *p <= 0xef) {
+ INCR;
+ if ((0x40 <= *p && *p <= 0x7e) ||
+ (0x80 <= *p && *p <= 0xa0)) {
+ return INT2FIX(_SJIS);
+ }
+ if (0xfd <= *p && *p <= 0xfe) {
+ return INT2FIX(_EUC);
+ }
+ }
+ p++;
+ }
+ return INT2FIX(_UNKNOWN);
}
void
@@ -1854,11 +1928,15 @@ Init_kconv()
rb_define_module_function(mKconv, "tojis", kconv_tojis, 1);
rb_define_module_function(mKconv, "toeuc", kconv_toeuc, 1);
rb_define_module_function(mKconv, "tosjis", kconv_tosjis, 1);
+ rb_define_module_function(mKconv, "guess", kconv_guess, 1);
rb_define_const(mKconv, "AUTO", INT2FIX(_AUTO));
rb_define_const(mKconv, "JIS", INT2FIX(_JIS));
rb_define_const(mKconv, "EUC", INT2FIX(_EUC));
rb_define_const(mKconv, "SJIS", INT2FIX(_SJIS));
+ rb_define_const(mKconv, "BINARY", INT2FIX(_BINARY));
+ rb_define_const(mKconv, "NOCONV", INT2FIX(_NOCONV));
+ rb_define_const(mKconv, "UNKNOWN", INT2FIX(_UNKNOWN));
}
/**
diff --git a/ext/md5/depend b/ext/md5/depend
index be56da8..abb2a47 100644
--- a/ext/md5/depend
+++ b/ext/md5/depend
@@ -1,2 +1,2 @@
md5c.o: md5c.c md5.h
-md5init.o: md5init.c ../../ruby.h ../../config.h ../../defines.h md5.h
+md5init.o: md5init.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h md5.h
diff --git a/ext/socket/depend b/ext/socket/depend
index e6ede5a..3d54fa0 100644
--- a/ext/socket/depend
+++ b/ext/socket/depend
@@ -1 +1 @@
-socket.o : socket.c ../../ruby.h ../../config.h ../../defines.h ../../io.h ../../sig.h
+socket.o : socket.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h $(hdrdir)/io.h $(hdrdir)/sig.h
diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb
index bbde1a0..f719723 100644
--- a/ext/socket/extconf.rb
+++ b/ext/socket/extconf.rb
@@ -1,9 +1,18 @@
$LDFLAGS = "-L/usr/local/lib"
-have_library("wsock32", "cygwin32_socket") or have_library("socket", "socket")
-have_library("inet", "gethostbyname")
-have_library("nsl", "gethostbyname")
+case PLATFORM
+when /mswin32/
+ test_func = "WSACleanup"
+ have_library("wsock32", "WSACleanup")
+when /cygwin32/
+ test_func = "cygwin32_socket"
+else
+ test_func = "socket"
+ have_library("socket", "socket")
+ have_library("inet", "gethostbyname")
+ have_library("nsl", "gethostbyname")
+end
have_header("sys/un.h")
-if have_func("socket") or have_func("cygwin32_socket")
+if have_func(test_func)
have_func("hsterror")
unless have_func("gethostname")
have_func("uname")
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 9128e26..f5d191b 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -12,9 +12,11 @@
#include "io.h"
#include <stdio.h>
#include <sys/types.h>
+#ifndef NT
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
+#endif
#include <errno.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
@@ -36,8 +38,10 @@ extern VALUE cIO;
extern VALUE cInteger;
VALUE cBasicSocket;
+VALUE cIPsocket;
VALUE cTCPsocket;
VALUE cTCPserver;
+VALUE cUDPsocket;
#ifdef AF_UNIX
VALUE cUNIXsocket;
VALUE cUNIXserver;
@@ -85,8 +89,6 @@ sock_new(class, fd)
fp->f = rb_fdopen(fd, "r");
#ifdef NT
fp->finalize = sock_finalize;
-#else
- setbuf(fp->f, NULL);
#endif
fp->f2 = rb_fdopen(fd, "w");
fp->mode = FMODE_READWRITE;
@@ -254,24 +256,29 @@ bsock_send(argc, argv, sock)
return INT2FIX(n);
}
-static VALUE tcpaddr _((struct sockaddr_in*));
+static VALUE ipaddr _((struct sockaddr_in*));
#ifdef HAVE_SYS_UN_H
static VALUE unixaddr _((struct sockaddr_un*));
#endif
+enum sock_recv_type {
+ RECV_RECV, /* BasicSocket#recv(no from) */
+ RECV_TCP, /* TCPsocket#recvfrom */
+ RECV_UDP, /* UDPsocket#recvfrom */
+ RECV_UNIX, /* UNIXsocket#recvfrom */
+ RECV_SOCKET, /* Socket#recvfrom */
+};
+
static VALUE
s_recv(sock, argc, argv, from)
VALUE sock;
int argc;
VALUE *argv;
- int from; /* 0 - recv,
- 1 - TCPsocket#recvfrom,
- 2 - UNIXsocket#recvfrom,
- 3 - Socket#recvfrom */
+ enum sock_recv_type from;
{
OpenFile *fptr;
FILE f;
- struct RString *str;
+ VALUE str;
char buf[1024];
int fd, alen = sizeof buf;
VALUE len, flg;
@@ -282,7 +289,7 @@ s_recv(sock, argc, argv, from)
if (flg == Qnil) flags = 0;
else flags = NUM2INT(flg);
- str = (struct RString*)str_new(0, NUM2INT(len));
+ str = str_new(0, NUM2INT(len));
GetOpenFile(sock, fptr);
fd = fileno(fptr->f);
@@ -291,11 +298,11 @@ s_recv(sock, argc, argv, from)
#endif
TRAP_BEG;
retry:
- str->len = recvfrom(fd, str->ptr, str->len, flags,
- (struct sockaddr*)buf, &alen);
+ RSTRING(str)->len = recvfrom(fd, RSTRING(str)->ptr, RSTRING(str)->len, flags,
+ (struct sockaddr*)buf, &alen);
TRAP_END;
- if (str->len < 0) {
+ if (RSTRING(str)->len < 0) {
switch (errno) {
case EINTR:
case EWOULDBLOCK:
@@ -311,21 +318,28 @@ s_recv(sock, argc, argv, from)
}
str_taint(str);
switch (from) {
- case 0:
+ case RECV_RECV:
return (VALUE)str;
- case 1:
+ case RECV_TCP:
if (alen != sizeof(struct sockaddr_in)) {
TypeError("sockaddr size differs - should not happen");
}
- return assoc_new(str, tcpaddr((struct sockaddr_in *)buf));
+ return assoc_new(str, ipaddr((struct sockaddr_in *)buf));
+ case RECV_UDP:
+ {
+ VALUE addr = ipaddr((struct sockaddr_in *)buf);
+
+ return assoc_new(str, assoc_new(RARRAY(addr)->ptr[2],
+ RARRAY(addr)->ptr[1]));
+ }
#ifdef HAVE_SYS_UN_H
- case 2:
+ case RECV_UNIX:
if (alen != sizeof(struct sockaddr_un)) {
TypeError("sockaddr size differs - should not happen");
}
return assoc_new(str, unixaddr((struct sockaddr_un *)buf));
#endif
- case 3:
+ case RECV_SOCKET:
return assoc_new(str, str_new(buf, alen));
}
}
@@ -336,7 +350,7 @@ bsock_recv(argc, argv, sock)
VALUE *argv;
VALUE sock;
{
- return s_recv(sock, argc, argv, 0);
+ return s_recv(sock, argc, argv, RECV_RECV);
}
#if defined(THREAD) && defined(HAVE_FCNTL)
@@ -470,7 +484,7 @@ open_inet(class, h, serv, type)
Raise(eSocket, "no such proto %s", servent->s_proto);
}
- fd = socket(PF_INET, SOCK_STREAM, protoent->p_proto);
+ fd = socket(AF_INET, SOCK_STREAM, protoent->p_proto);
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
@@ -515,9 +529,7 @@ open_inet(class, h, serv, type)
if (type == INET_SERVER) listen(fd, 5);
/* create new instance */
- sock = sock_new(class, fd);
-
- return sock;
+ return sock_new(class, fd);
}
static VALUE
@@ -606,6 +618,15 @@ tcp_accept(sock)
(struct sockaddr*)&from, &fromlen);
}
+static VALUE
+tcp_recvfrom(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ return s_recv(sock, argc, argv, RECV_TCP);
+}
+
#ifdef HAVE_SYS_UN_H
static VALUE
open_unix(class, path, server)
@@ -619,7 +640,7 @@ open_unix(class, path, server)
OpenFile *fptr;
Check_SafeStr(path);
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd < 0) rb_sys_fail("socket(2)");
memset(&sockaddr, 0, sizeof(sockaddr));
@@ -700,7 +721,7 @@ mkipaddr(x)
}
static VALUE
-tcpaddr(sockaddr)
+ipaddr(sockaddr)
struct sockaddr_in *sockaddr;
{
VALUE family, port, addr1, addr2;
@@ -725,7 +746,7 @@ tcpaddr(sockaddr)
}
static VALUE
-tcp_addr(sock)
+ip_addr(sock)
VALUE sock;
{
OpenFile *fptr;
@@ -736,11 +757,11 @@ tcp_addr(sock)
if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
rb_sys_fail("getsockname(2)");
- return tcpaddr(&addr);
+ return ipaddr(&addr);
}
static VALUE
-tcp_peeraddr(sock)
+ip_peeraddr(sock)
VALUE sock;
{
OpenFile *fptr;
@@ -751,24 +772,14 @@ tcp_peeraddr(sock)
if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
rb_sys_fail("getpeername(2)");
- return tcpaddr(&addr);
+ return ipaddr(&addr);
}
static VALUE
-tcp_recvfrom(argc, argv, sock)
- int argc;
- VALUE *argv;
- VALUE sock;
-{
- return s_recv(sock, argc, argv, 1);
-}
-
-static VALUE
-tcp_s_getaddress(obj, host)
+ip_s_getaddress(obj, host)
VALUE obj, host;
{
struct sockaddr_in addr;
- struct hostent *h;
if (obj_is_kind_of(host, cInteger)) {
int i = NUM2INT(host);
@@ -782,6 +793,148 @@ tcp_s_getaddress(obj, host)
return mkipaddr(addr.sin_addr.s_addr);
}
+static VALUE
+udp_s_open(class)
+ VALUE class;
+{
+ return sock_new(class, socket(AF_INET, SOCK_DGRAM, 0));
+}
+
+static void
+udp_addrsetup(host, port, addr)
+ VALUE host, port;
+ struct sockaddr_in *addr;
+{
+ struct hostent *hostent;
+
+ memset(addr, 0, sizeof(struct sockaddr_in));
+ addr->sin_family = AF_INET;
+ if (NIL_P(host)) {
+ addr->sin_addr.s_addr = INADDR_ANY;
+ }
+ else if (obj_is_kind_of(host, cInteger)) {
+ int i = NUM2INT(host);
+ addr->sin_addr.s_addr = htonl(i);
+ }
+ else {
+ Check_Type(host, T_STRING);
+ setipaddr(RSTRING(host)->ptr, addr);
+ }
+ if (FIXNUM_P(port)) {
+ addr->sin_port = FIX2INT(port);
+ }
+ else {
+ struct servent *servent;
+
+ Check_Type(port, T_STRING);
+ servent = getservbyname(RSTRING(port)->ptr, "udp");
+ if (servent) {
+ addr->sin_port = servent->s_port;
+ }
+ else {
+ int port = strtoul(RSTRING(port)->ptr, 0, 0);
+
+ if (port == -1) {
+ Raise(eSocket, "no such servce %s", RSTRING(port)->ptr);
+ }
+ addr->sin_port = htons(port);
+ }
+ }
+}
+
+static VALUE
+udp_connect(sock, host, port)
+ VALUE sock, host, port;
+{
+ struct sockaddr_in addr;
+ OpenFile *fptr;
+
+ udp_addrsetup(host, port, &addr);
+ GetOpenFile(sock, fptr);
+ retry:
+ if (connect(fileno(fptr->f), (struct sockaddr*)&addr, sizeof(addr))<0) {
+ switch (errno) {
+ case EINTR:
+ case EWOULDBLOCK:
+#if EAGAIN != EWOULDBLOCK
+ case EAGAIN:
+#endif
+#ifdef THREAD
+ thread_schedule();
+#endif
+ goto retry;
+ }
+ rb_sys_fail("connect(2)");
+ }
+
+ return INT2FIX(0);
+}
+
+static VALUE
+udp_bind(sock, host, port)
+ VALUE sock, host, port;
+{
+ struct sockaddr_in addr;
+ OpenFile *fptr;
+
+ udp_addrsetup(host, port, &addr);
+ GetOpenFile(sock, fptr);
+ if (bind(fileno(fptr->f), (struct sockaddr*)&addr, sizeof(addr))<0) {
+ rb_sys_fail("bind(2)");
+ }
+ return INT2FIX(0);
+}
+
+static VALUE
+udp_send(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ VALUE mesg, flags, host, port;
+ struct sockaddr_in addr;
+ OpenFile *fptr;
+ FILE *f;
+ int n;
+
+ if (argc == 2) {
+ return bsock_send(argc, argv, sock);
+ }
+ rb_scan_args(argc, argv, "4", &mesg, &flags, &host, &port);
+ Check_Type(mesg, T_STRING);
+
+ udp_addrsetup(host, port, &addr);
+ GetOpenFile(sock, fptr);
+ f = fptr->f2?fptr->f2:fptr->f;
+ retry:
+ n = sendto(fileno(f), RSTRING(mesg)->ptr, RSTRING(mesg)->len,
+ NUM2INT(flags), (struct sockaddr*)&addr, sizeof(addr));
+ if (n < 0) {
+ switch (errno) {
+ case EINTR:
+ case EWOULDBLOCK:
+#if EAGAIN != EWOULDBLOCK
+ case EAGAIN:
+#endif
+#ifdef THREAD
+ thread_schedule();
+#endif
+ goto retry;
+ }
+ rb_sys_fail("sendto(2)");
+ }
+ return INT2FIX(n);
+}
+
+static VALUE
+udp_recvfrom(argc, argv, sock)
+ int argc;
+ VALUE *argv;
+ VALUE sock;
+{
+ return s_recv(sock, argc, argv, RECV_UDP);
+}
+
#ifdef HAVE_SYS_UN_H
static VALUE
unix_s_sock_open(sock, path)
@@ -820,7 +973,7 @@ unix_recvfrom(argc, argv, sock)
VALUE *argv;
VALUE sock;
{
- return s_recv(sock, argc, argv, 2);
+ return s_recv(sock, argc, argv, RECV_UNIX);
}
static VALUE
@@ -884,7 +1037,25 @@ setup_domain_and_type(domain, dv, type, tv)
if (TYPE(domain) == T_STRING) {
ptr = RSTRING(domain)->ptr;
- if (strcmp(ptr, "PF_INET") == 0)
+ if (strcmp(ptr, "AF_INET") == 0)
+ *dv = AF_INET;
+#ifdef AF_UNIX
+ else if (strcmp(ptr, "AF_UNIX") == 0)
+ *dv = AF_UNIX;
+#endif
+#ifdef AF_ISO
+ else if (strcmp(ptr, "AF_ISO") == 0)
+ *dv = AF_ISO;
+#endif
+#ifdef AF_NS
+ else if (strcmp(ptr, "AF_NS") == 0)
+ *dv = AF_NS;
+#endif
+#ifdef AF_IMPLINK
+ else if (strcmp(ptr, "AF_IMPLINK") == 0)
+ *dv = AF_IMPLINK;
+#endif
+ else if (strcmp(ptr, "PF_INET") == 0)
*dv = PF_INET;
#ifdef PF_UNIX
else if (strcmp(ptr, "PF_UNIX") == 0)
@@ -893,6 +1064,8 @@ setup_domain_and_type(domain, dv, type, tv)
#ifdef PF_IMPLINK
else if (strcmp(ptr, "PF_IMPLINK") == 0)
*dv = PF_IMPLINK;
+ else if (strcmp(ptr, "AF_IMPLINK") == 0)
+ *dv = AF_IMPLINK;
#endif
#ifdef PF_AX25
else if (strcmp(ptr, "PF_AX25") == 0)
@@ -978,8 +1151,7 @@ sock_s_socketpair(class, domain, type, protocol)
static VALUE
sock_connect(sock, addr)
- VALUE sock;
- struct RString *addr;
+ VALUE sock, addr;
{
OpenFile *fptr;
@@ -988,7 +1160,7 @@ sock_connect(sock, addr)
GetOpenFile(sock, fptr);
retry:
- if (connect(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0) {
+ if (connect(fileno(fptr->f), (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len) < 0) {
switch (errno) {
case EINTR:
case EWOULDBLOCK:
@@ -1008,8 +1180,7 @@ sock_connect(sock, addr)
static VALUE
sock_bind(sock, addr)
- VALUE sock;
- struct RString *addr;
+ VALUE sock, addr;
{
OpenFile *fptr;
@@ -1017,7 +1188,7 @@ sock_bind(sock, addr)
str_modify(addr);
GetOpenFile(sock, fptr);
- if (bind(fileno(fptr->f), (struct sockaddr*)addr->ptr, addr->len) < 0)
+ if (bind(fileno(fptr->f), (struct sockaddr*)RSTRING(addr)->ptr, RSTRING(addr)->len) < 0)
rb_sys_fail("bind(2)");
return INT2FIX(0);
@@ -1042,7 +1213,7 @@ sock_recvfrom(argc, argv, sock)
VALUE *argv;
VALUE sock;
{
- return s_recv(sock, argc, argv, 3);
+ return s_recv(sock, argc, argv, RECV_SOCKET);
}
static VALUE
@@ -1185,7 +1356,7 @@ sock_s_getservbyaname(argc, argv)
VALUE *argv;
{
VALUE service, protocol;
- char *name, *proto;
+ char *proto;
struct servent *sp;
int port;
@@ -1203,12 +1374,24 @@ sock_s_getservbyaname(argc, argv)
return INT2FIX(port);
}
+static VALUE mConst;
+
+static void
+sock_define_const(name, value)
+ char *name;
+ INT value;
+{
+ rb_define_const(cSocket, name, INT2FIX(value));
+ rb_define_const(mConst, name, INT2FIX(value));
+}
+
Init_socket()
{
eSocket = rb_define_class("SocketError", eException);
cBasicSocket = rb_define_class("BasicSocket", cIO);
rb_undef_method(CLASS_OF(cBasicSocket), "new");
+ rb_undef_method(CLASS_OF(cBasicSocket), "open");
rb_define_method(cBasicSocket, "shutdown", bsock_shutdown, -1);
rb_define_method(cBasicSocket, "setsockopt", bsock_setsockopt, 3);
rb_define_method(cBasicSocket, "getsockopt", bsock_getsockopt, 2);
@@ -1217,12 +1400,14 @@ Init_socket()
rb_define_method(cBasicSocket, "send", bsock_send, -1);
rb_define_method(cBasicSocket, "recv", bsock_recv, -1);
- cTCPsocket = rb_define_class("TCPsocket", cBasicSocket);
+ cIPsocket = rb_define_class("IPsocket", cBasicSocket);
+ rb_define_method(cIPsocket, "addr", ip_addr, 0);
+ rb_define_method(cIPsocket, "peeraddr", ip_peeraddr, 0);
+ rb_define_singleton_method(cIPsocket, "getaddress", ip_s_getaddress, 1);
+
+ cTCPsocket = rb_define_class("TCPsocket", cIPsocket);
rb_define_singleton_method(cTCPsocket, "open", tcp_s_open, 2);
rb_define_singleton_method(cTCPsocket, "new", tcp_s_open, 2);
- rb_define_method(cTCPsocket, "addr", tcp_addr, 0);
- rb_define_method(cTCPsocket, "peeraddr", tcp_peeraddr, 0);
- rb_define_singleton_method(cTCPsocket, "getaddress", tcp_s_getaddress, 1);
rb_define_method(cTCPsocket, "recvfrom", tcp_recvfrom, -1);
#ifdef SOCKS
@@ -1236,6 +1421,14 @@ Init_socket()
rb_define_singleton_method(cTCPserver, "new", tcp_svr_s_open, -1);
rb_define_method(cTCPserver, "accept", tcp_accept, 0);
+ cUDPsocket = rb_define_class("UDPsocket", cIPsocket);
+ rb_define_singleton_method(cUDPsocket, "open", udp_s_open, 0);
+ rb_define_singleton_method(cUDPsocket, "new", udp_s_open, 0);
+ rb_define_method(cUDPsocket, "connect", udp_connect, 2);
+ rb_define_method(cUDPsocket, "bind", udp_bind, 2);
+ rb_define_method(cUDPsocket, "send", udp_send, -1);
+ rb_define_method(cUDPsocket, "recvfrom", udp_recvfrom, -1);
+
#ifdef HAVE_SYS_UN_H
cUNIXsocket = rb_define_class("UNIXsocket", cBasicSocket);
rb_define_singleton_method(cUNIXsocket, "open", unix_s_sock_open, 1);
@@ -1271,137 +1464,138 @@ Init_socket()
rb_define_singleton_method(cSocket, "getservbyname", sock_s_getservbyaname, -1);
/* constants */
- rb_define_const(cSocket, "SOCK_STREAM", INT2FIX(SOCK_STREAM));
- rb_define_const(cSocket, "SOCK_DGRAM", INT2FIX(SOCK_DGRAM));
- rb_define_const(cSocket, "SOCK_RAW", INT2FIX(SOCK_RAW));
+ mConst = rb_define_module_under(cSocket, "Constants");
+ sock_define_const("SOCK_STREAM", SOCK_STREAM);
+ sock_define_const("SOCK_DGRAM", SOCK_DGRAM);
+ sock_define_const("SOCK_RAW", SOCK_RAW);
#ifdef SOCK_RDM
- rb_define_const(cSocket, "SOCK_RDM", INT2FIX(SOCK_RDM));
+ sock_define_const("SOCK_RDM", SOCK_RDM);
#endif
#ifdef SOCK_SEQPACKET
- rb_define_const(cSocket, "SOCK_SEQPACKET", INT2FIX(SOCK_SEQPACKET));
+ sock_define_const("SOCK_SEQPACKET", SOCK_SEQPACKET);
#endif
#ifdef SOCK_PACKET
- rb_define_const(cSocket, "SOCK_PACKET", INT2FIX(SOCK_PACKET));
+ sock_define_const("SOCK_PACKET", SOCK_PACKET);
#endif
- rb_define_const(cSocket, "AF_INET", INT2FIX(AF_INET));
- rb_define_const(cSocket, "PF_INET", INT2FIX(PF_INET));
+ sock_define_const("AF_INET", AF_INET);
+ sock_define_const("PF_INET", PF_INET);
#ifdef AF_UNIX
- rb_define_const(cSocket, "AF_UNIX", INT2FIX(AF_UNIX));
- rb_define_const(cSocket, "PF_UNIX", INT2FIX(PF_UNIX));
+ sock_define_const("AF_UNIX", AF_UNIX);
+ sock_define_const("PF_UNIX", PF_UNIX);
#endif
#ifdef AF_AX25
- rb_define_const(cSocket, "AF_AX25", INT2FIX(AF_AX25));
- rb_define_const(cSocket, "PF_AX25", INT2FIX(PF_AX25));
+ sock_define_const("AF_AX25", AF_AX25);
+ sock_define_const("PF_AX25", PF_AX25);
#endif
#ifdef AF_IPX
- rb_define_const(cSocket, "AF_IPX", INT2FIX(AF_IPX));
- rb_define_const(cSocket, "PF_IPX", INT2FIX(PF_IPX));
+ sock_define_const("AF_IPX", AF_IPX);
+ sock_define_const("PF_IPX", PF_IPX);
#endif
#ifdef AF_APPLETALK
- rb_define_const(cSocket, "AF_APPLETALK", INT2FIX(AF_APPLETALK));
- rb_define_const(cSocket, "PF_APPLETALK", INT2FIX(PF_APPLETALK));
+ sock_define_const("AF_APPLETALK", AF_APPLETALK);
+ sock_define_const("PF_APPLETALK", PF_APPLETALK);
#endif
- rb_define_const(cSocket, "MSG_OOB", INT2FIX(MSG_OOB));
- rb_define_const(cSocket, "MSG_PEEK", INT2FIX(MSG_PEEK));
- rb_define_const(cSocket, "MSG_DONTROUTE", INT2FIX(MSG_DONTROUTE));
+ sock_define_const("MSG_OOB", MSG_OOB);
+ sock_define_const("MSG_PEEK", MSG_PEEK);
+ sock_define_const("MSG_DONTROUTE", MSG_DONTROUTE);
- rb_define_const(cSocket, "SOL_SOCKET", INT2FIX(SOL_SOCKET));
+ sock_define_const("SOL_SOCKET", SOL_SOCKET);
#ifdef SOL_IP
- rb_define_const(cSocket, "SOL_IP", INT2FIX(SOL_IP));
+ sock_define_const("SOL_IP", SOL_IP);
#endif
#ifdef SOL_IPX
- rb_define_const(cSocket, "SOL_IPX", INT2FIX(SOL_IPX));
+ sock_define_const("SOL_IPX", SOL_IPX);
#endif
#ifdef SOL_AX25
- rb_define_const(cSocket, "SOL_AX25", INT2FIX(SOL_AX25));
+ sock_define_const("SOL_AX25", SOL_AX25);
#endif
#ifdef SOL_ATALK
- rb_define_const(cSocket, "SOL_ATALK", INT2FIX(SOL_ATALK));
+ sock_define_const("SOL_ATALK", SOL_ATALK);
#endif
#ifdef SOL_TCP
- rb_define_const(cSocket, "SOL_TCP", INT2FIX(SOL_TCP));
+ sock_define_const("SOL_TCP", SOL_TCP);
#endif
#ifdef SOL_UDP
- rb_define_const(cSocket, "SOL_UDP", INT2FIX(SOL_UDP));
+ sock_define_const("SOL_UDP", SOL_UDP);
#endif
#ifdef SO_DEBUG
- rb_define_const(cSocket, "SO_DEBUG", INT2FIX(SO_DEBUG));
+ sock_define_const("SO_DEBUG", SO_DEBUG);
#endif
- rb_define_const(cSocket, "SO_REUSEADDR", INT2FIX(SO_REUSEADDR));
+ sock_define_const("SO_REUSEADDR", SO_REUSEADDR);
#ifdef SO_TYPE
- rb_define_const(cSocket, "SO_TYPE", INT2FIX(SO_TYPE));
+ sock_define_const("SO_TYPE", SO_TYPE);
#endif
#ifdef SO_ERROR
- rb_define_const(cSocket, "SO_ERROR", INT2FIX(SO_ERROR));
+ sock_define_const("SO_ERROR", SO_ERROR);
#endif
#ifdef SO_DONTROUTE
- rb_define_const(cSocket, "SO_DONTROUTE", INT2FIX(SO_DONTROUTE));
+ sock_define_const("SO_DONTROUTE", SO_DONTROUTE);
#endif
#ifdef SO_BROADCAST
- rb_define_const(cSocket, "SO_BROADCAST", INT2FIX(SO_BROADCAST));
+ sock_define_const("SO_BROADCAST", SO_BROADCAST);
#endif
#ifdef SO_SNDBUF
- rb_define_const(cSocket, "SO_SNDBUF", INT2FIX(SO_SNDBUF));
+ sock_define_const("SO_SNDBUF", SO_SNDBUF);
#endif
#ifdef SO_RCVBUF
- rb_define_const(cSocket, "SO_RCVBUF", INT2FIX(SO_RCVBUF));
+ sock_define_const("SO_RCVBUF", SO_RCVBUF);
#endif
- rb_define_const(cSocket, "SO_KEEPALIVE", INT2FIX(SO_KEEPALIVE));
+ sock_define_const("SO_KEEPALIVE", SO_KEEPALIVE);
#ifdef SO_OOBINLINE
- rb_define_const(cSocket, "SO_OOBINLINE", INT2FIX(SO_OOBINLINE));
+ sock_define_const("SO_OOBINLINE", SO_OOBINLINE);
#endif
#ifdef SO_NO_CHECK
- rb_define_const(cSocket, "SO_NO_CHECK", INT2FIX(SO_NO_CHECK));
+ sock_define_const("SO_NO_CHECK", SO_NO_CHECK);
#endif
#ifdef SO_PRIORITY
- rb_define_const(cSocket, "SO_PRIORITY", INT2FIX(SO_PRIORITY));
+ sock_define_const("SO_PRIORITY", SO_PRIORITY);
#endif
- rb_define_const(cSocket, "SO_LINGER", INT2FIX(SO_LINGER));
+ sock_define_const("SO_LINGER", SO_LINGER);
#ifdef SOPRI_INTERACTIVE
- rb_define_const(cSocket, "SOPRI_INTERACTIVE", INT2FIX(SOPRI_INTERACTIVE));
+ sock_define_const("SOPRI_INTERACTIVE", SOPRI_INTERACTIVE);
#endif
#ifdef SOPRI_NORMAL
- rb_define_const(cSocket, "SOPRI_NORMAL", INT2FIX(SOPRI_NORMAL));
+ sock_define_const("SOPRI_NORMAL", SOPRI_NORMAL);
#endif
#ifdef SOPRI_BACKGROUND
- rb_define_const(cSocket, "SOPRI_BACKGROUND", INT2FIX(SOPRI_BACKGROUND));
+ sock_define_const("SOPRI_BACKGROUND", SOPRI_BACKGROUND);
#endif
#ifdef IP_MULTICAST_IF
- rb_define_const(cSocket, "IP_MULTICAST_IF", INT2FIX(IP_MULTICAST_IF));
+ sock_define_const("IP_MULTICAST_IF", IP_MULTICAST_IF);
#endif
#ifdef IP_MULTICAST_TTL
- rb_define_const(cSocket, "IP_MULTICAST_TTL", INT2FIX(IP_MULTICAST_TTL));
+ sock_define_const("IP_MULTICAST_TTL", IP_MULTICAST_TTL);
#endif
#ifdef IP_MULTICAST_LOOP
- rb_define_const(cSocket, "IP_MULTICAST_LOOP", INT2FIX(IP_MULTICAST_LOOP));
+ sock_define_const("IP_MULTICAST_LOOP", IP_MULTICAST_LOOP);
#endif
#ifdef IP_ADD_MEMBERSHIP
- rb_define_const(cSocket, "IP_ADD_MEMBERSHIP", INT2FIX(IP_ADD_MEMBERSHIP));
+ sock_define_const("IP_ADD_MEMBERSHIP", IP_ADD_MEMBERSHIP);
#endif
#ifdef IP_DEFAULT_MULTICAST_TTL
- rb_define_const(cSocket, "IP_DEFAULT_MULTICAST_TTL", INT2FIX(IP_DEFAULT_MULTICAST_TTL));
+ sock_define_const("IP_DEFAULT_MULTICAST_TTL", IP_DEFAULT_MULTICAST_TTL);
#endif
#ifdef IP_DEFAULT_MULTICAST_LOOP
- rb_define_const(cSocket, "IP_DEFAULT_MULTICAST_LOOP", INT2FIX(IP_DEFAULT_MULTICAST_LOOP));
+ sock_define_const("IP_DEFAULT_MULTICAST_LOOP", IP_DEFAULT_MULTICAST_LOOP);
#endif
#ifdef IP_MAX_MEMBERSHIPS
- rb_define_const(cSocket, "IP_MAX_MEMBERSHIPS", INT2FIX(IP_MAX_MEMBERSHIPS));
+ sock_define_const("IP_MAX_MEMBERSHIPS", IP_MAX_MEMBERSHIPS);
#endif
#ifdef IPX_TYPE
- rb_define_const(cSocket, "IPX_TYPE", INT2FIX(IPX_TYPE));
+ sock_define_const("IPX_TYPE", IPX_TYPE);
#endif
#ifdef TCP_NODELAY
- rb_define_const(cSocket, "TCP_NODELAY", INT2FIX(TCP_NODELAY));
+ sock_define_const("TCP_NODELAY", TCP_NODELAY);
#endif
#ifdef TCP_MAXSEG
- rb_define_const(cSocket, "TCP_MAXSEG", INT2FIX(TCP_MAXSEG));
+ sock_define_const("TCP_MAXSEG", TCP_MAXSEG);
#endif
}
diff --git a/ext/tkutil/depend b/ext/tkutil/depend
index ead83ed..e325a82 100644
--- a/ext/tkutil/depend
+++ b/ext/tkutil/depend
@@ -1 +1 @@
-tkutil.o: tkutil.c ../../ruby.h ../../config.h ../../defines.h
+tkutil.o: tkutil.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h
diff --git a/file.c b/file.c
index 0caa98a..b60ec65 100644
--- a/file.c
+++ b/file.c
@@ -42,15 +42,11 @@ struct timeval {
#include <pwd.h>
#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
+#ifndef HAVE_STRING_H
char *strrchr();
#endif
-#ifdef NT
#include <sys/stat.h>
-#endif
#ifndef NT
char *strdup();
@@ -101,6 +97,10 @@ file_s_open(argc, argv, class)
file = file_open(RSTRING(fname)->ptr, mode);
RBASIC(file)->class = class;
+ if (iterator_p()) {
+ rb_ensure(rb_yield, file, io_close, file);
+ }
+
return file;
}
@@ -136,7 +136,8 @@ file_reopen(argc, argv, file)
if (!fptr->f) {
fptr->f = rb_fopen(RSTRING(fname)->ptr, mode);
if (fptr->f2) {
- fclose(fptr->f2);
+ if (fileno(fptr->f2) < 3) /* need to keep stdio */
+ fclose(fptr->f2);
fptr->f2 = NULL;
}
return file;
@@ -155,13 +156,14 @@ file_reopen(argc, argv, file)
}
static int
-apply2files(func, args, arg)
+apply2files(func, vargs, arg)
int (*func)();
- struct RArray *args;
+ VALUE vargs;
void *arg;
{
int i;
VALUE path;
+ struct RArray *args = RARRAY(vargs);
for (i=0; i<args->len; i++) {
Check_SafeStr(args->ptr[i]);
@@ -269,7 +271,6 @@ file_isatty(obj)
#else
#include "missing/file.h"
#endif
-#include <sys/stat.h>
static VALUE
stat_new(st)
@@ -306,14 +307,13 @@ stat_new(st)
static VALUE
file_s_stat(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) == -1) {
- rb_sys_fail(fname->ptr);
+ if (stat(RSTRING(fname)->ptr, &st) == -1) {
+ rb_sys_fail(RSTRING(fname)->ptr);
}
return stat_new(&st);
}
@@ -334,15 +334,14 @@ file_stat(obj)
static VALUE
file_s_lstat(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#if !defined(MSDOS) && !defined(NT)
struct stat st;
Check_SafeStr(fname);
- if (lstat(fname->ptr, &st) == -1) {
- rb_sys_fail(fname->ptr);
+ if (lstat(RSTRING(fname)->ptr, &st) == -1) {
+ rb_sys_fail(RSTRING(fname)->ptr);
}
return stat_new(&st);
#else
@@ -424,19 +423,6 @@ eaccess(path, mode)
return 0;
}
-#if defined(DJGPP)
- {
- int stat_mode = 0;
- if (mode & X_OK)
- stat_mode |= S_IXOTH;
- if (mode & W_OK)
- stat_mode |= S_IWOTH;
- if (mode & R_OK)
- stat_mode |= S_IROTH;
- mode = stat_mode;
- }
-#endif
-
if (st.st_uid == euid) /* owner */
mode <<= 6;
else if (group_member (st.st_gid))
@@ -452,8 +438,7 @@ eaccess(path, mode)
static VALUE
test_d(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#ifndef S_ISDIR
# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
@@ -462,15 +447,14 @@ test_d(obj, fname)
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISDIR(st.st_mode)) return TRUE;
return FALSE;
}
static VALUE
test_p(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#ifdef S_IFIFO
# ifndef S_ISFIFO
@@ -480,7 +464,7 @@ test_p(obj, fname)
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISFIFO(st.st_mode)) return TRUE;
#endif
@@ -489,8 +473,7 @@ test_p(obj, fname)
static VALUE
test_l(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#ifndef S_ISLNK
# ifdef _S_ISLNK
@@ -510,7 +493,7 @@ test_l(obj, fname)
struct stat st;
Check_SafeStr(fname);
- if (lstat(fname->ptr, &st) < 0) return FALSE;
+ if (lstat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISLNK(st.st_mode)) return TRUE;
#endif
@@ -519,8 +502,7 @@ test_l(obj, fname)
static VALUE
test_S(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#ifndef S_ISSOCK
# ifdef _S_ISSOCK
@@ -540,7 +522,7 @@ test_S(obj, fname)
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISSOCK(st.st_mode)) return TRUE;
#endif
@@ -549,8 +531,7 @@ test_S(obj, fname)
static VALUE
test_b(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#ifndef S_ISBLK
# ifdef S_IFBLK
@@ -564,7 +545,7 @@ test_b(obj, fname)
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISBLK(st.st_mode)) return TRUE;
#endif
@@ -573,8 +554,7 @@ test_b(obj, fname)
static VALUE
test_c(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#ifndef S_ISCHR
# define S_ISCHR(m) ((m & S_IFMT) == S_IFCHR)
@@ -583,7 +563,7 @@ test_c(obj, fname)
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISBLK(st.st_mode)) return TRUE;
return FALSE;
@@ -591,73 +571,66 @@ test_c(obj, fname)
static VALUE
test_e(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
return TRUE;
}
static VALUE
test_r(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
Check_SafeStr(fname);
- if (eaccess(fname->ptr, R_OK) < 0) return FALSE;
+ if (eaccess(RSTRING(fname)->ptr, R_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_R(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
Check_SafeStr(fname);
- if (access(fname->ptr, R_OK) < 0) return FALSE;
+ if (access(RSTRING(fname)->ptr, R_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_w(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
Check_SafeStr(fname);
- if (eaccess(fname->ptr, W_OK) < 0) return FALSE;
+ if (eaccess(RSTRING(fname)->ptr, W_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_W(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
Check_SafeStr(fname);
- if (access(fname->ptr, W_OK) < 0) return FALSE;
+ if (access(RSTRING(fname)->ptr, W_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_x(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
Check_SafeStr(fname);
- if (eaccess(fname->ptr, X_OK) < 0) return FALSE;
+ if (eaccess(RSTRING(fname)->ptr, X_OK) < 0) return FALSE;
return TRUE;
}
static VALUE
test_X(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
Check_SafeStr(fname);
- if (access(fname->ptr, X_OK) < 0) return FALSE;
+ if (access(RSTRING(fname)->ptr, X_OK) < 0) return FALSE;
return TRUE;
}
@@ -667,79 +640,73 @@ test_X(obj, fname)
static VALUE
test_f(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (S_ISREG(st.st_mode)) return TRUE;
return FALSE;
}
static VALUE
test_z(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_size == 0) return TRUE;
return FALSE;
}
static VALUE
test_s(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_size == 0) return FALSE;
return int2inum(st.st_size);
}
static VALUE
test_owned(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_uid == geteuid()) return TRUE;
return FALSE;
}
static VALUE
test_rowned(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_uid == getuid()) return TRUE;
return FALSE;
}
static VALUE
test_grpowned(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#ifndef NT
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(RSTRING(fname)->ptr, &st) < 0) return FALSE;
if (st.st_gid == getegid()) return TRUE;
#endif
return FALSE;
@@ -761,12 +728,11 @@ check3rdbyte(file, mode)
static VALUE
test_suid(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#ifdef S_ISUID
Check_SafeStr(fname);
- return check3rdbyte(fname->ptr, S_ISUID);
+ return check3rdbyte(RSTRING(fname)->ptr, S_ISUID);
#else
return FALSE;
#endif
@@ -774,12 +740,11 @@ test_suid(obj, fname)
static VALUE
test_sgid(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
#ifndef NT
Check_SafeStr(fname);
- return check3rdbyte(fname->ptr, S_ISGID);
+ return check3rdbyte(RSTRING(fname)->ptr, S_ISGID);
#else
return FALSE;
#endif
@@ -787,12 +752,11 @@ test_sgid(obj, fname)
static VALUE
test_sticky(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
Check_Type(fname, T_STRING);
#ifdef S_ISVTX
- return check3rdbyte(fname->ptr, S_ISVTX);
+ return check3rdbyte(RSTRING(fname)->ptr, S_ISVTX);
#else
return FALSE;
#endif
@@ -800,26 +764,26 @@ test_sticky(obj, fname)
static VALUE
file_s_size(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+ if (stat(RSTRING(fname)->ptr, &st) < 0)
+ rb_sys_fail(RSTRING(fname)->ptr);
return int2inum(st.st_size);
}
static VALUE
file_s_ftype(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
char *t;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+ if (stat(RSTRING(fname)->ptr, &st) < 0)
+ rb_sys_fail(RSTRING(fname)->ptr);
if (S_ISREG(st.st_mode)) {
t = "file";
@@ -857,13 +821,13 @@ file_s_ftype(obj, fname)
static VALUE
file_s_atime(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+ if (stat(RSTRING(fname)->ptr, &st) < 0)
+ rb_sys_fail(RSTRING(fname)->ptr);
return time_new(st.st_atime, 0);
}
@@ -883,13 +847,13 @@ file_atime(obj)
static VALUE
file_s_mtime(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+ if (stat(RSTRING(fname)->ptr, &st) < 0)
+ rb_sys_fail(RSTRING(fname)->ptr);
return time_new(st.st_mtime, 0);
}
@@ -909,13 +873,13 @@ file_mtime(obj)
static VALUE
file_s_ctime(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
struct stat st;
Check_SafeStr(fname);
- if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+ if (stat(RSTRING(fname)->ptr, &st) < 0)
+ rb_sys_fail(RSTRING(fname)->ptr);
return time_new(st.st_ctime, 0);
}
@@ -1118,32 +1082,26 @@ file_s_utime(argc, argv)
static VALUE
file_s_link(obj, from, to)
- VALUE obj;
- struct RString *from, *to;
+ VALUE obj, from, to;
{
-#ifndef __human68k__
Check_SafeStr(from);
Check_SafeStr(to);
- if (link(from->ptr, to->ptr) < 0)
- rb_sys_fail(from->ptr);
+ if (link(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
+ rb_sys_fail(RSTRING(from)->ptr);
return INT2FIX(0);
-#else
- rb_notimplement();
-#endif
}
static VALUE
file_s_symlink(obj, from, to)
- VALUE obj;
- struct RString *from, *to;
+ VALUE obj, from, to;
{
#if !defined(MSDOS) && !defined(NT)
Check_SafeStr(from);
Check_SafeStr(to);
- if (symlink(from->ptr, to->ptr) < 0)
- rb_sys_fail(from->ptr);
+ if (symlink(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
+ rb_sys_fail(RSTRING(from)->ptr);
return TRUE;
#else
rb_notimplement();
@@ -1152,8 +1110,7 @@ file_s_symlink(obj, from, to)
static VALUE
file_s_readlink(obj, path)
- VALUE obj;
- struct RString *path;
+ VALUE obj, path;
{
#if !defined(MSDOS) && !defined(NT)
char buf[MAXPATHLEN];
@@ -1161,8 +1118,8 @@ file_s_readlink(obj, path)
Check_SafeStr(path);
- if ((cc = readlink(path->ptr, buf, MAXPATHLEN)) < 0)
- rb_sys_fail(path->ptr);
+ if ((cc = readlink(RSTRING(path)->ptr, buf, MAXPATHLEN)) < 0)
+ rb_sys_fail(RSTRING(path)->ptr);
return str_new(buf, cc);
#else
@@ -1180,8 +1137,7 @@ unlink_internal(path)
static VALUE
file_s_unlink(obj, args)
- VALUE obj;
- struct RArray *args;
+ VALUE obj, args;
{
int n;
@@ -1191,14 +1147,13 @@ file_s_unlink(obj, args)
static VALUE
file_s_rename(obj, from, to)
- VALUE obj;
- struct RString *from, *to;
+ VALUE obj, from, to;
{
Check_SafeStr(from);
Check_SafeStr(to);
- if (rename(from->ptr, to->ptr) == -1)
- rb_sys_fail(from->ptr);
+ if (rename(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
+ rb_sys_fail(RSTRING(from)->ptr);
return INT2FIX(0);
}
@@ -1225,14 +1180,13 @@ file_s_umask(argc, argv)
VALUE
file_s_expand_path(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
char *s, *p;
char buf[MAXPATHLEN];
Check_Type(fname, T_STRING);
- s = fname->ptr;
+ s = RSTRING(fname)->ptr;
p = buf;
if (s[0] == '~') {
@@ -1326,6 +1280,11 @@ rmext(p, e)
if (!e) return 0;
l2 = strlen(e);
+ if (l2 == 2 && e[1] == '*') {
+ e = strrchr(p, *e);
+ if (!e) return 0;
+ return e - p;
+ }
if (l1 < l2) return l1;
if (strcmp(p+l1-l2, e) == 0) {
@@ -1339,25 +1298,24 @@ file_s_basename(argc, argv)
int argc;
VALUE *argv;
{
- struct RString *fname;
- struct RString *ext;
+ VALUE fname, ext;
char *p;
int f;
rb_scan_args(argc, argv, "11", &fname, &ext);
Check_Type(fname, T_STRING);
if (!NIL_P(ext)) Check_Type(ext, T_STRING);
- p = strrchr(fname->ptr, '/');
+ p = strrchr(RSTRING(fname)->ptr, '/');
if (!p) {
if (!NIL_P(ext)) {
- f = rmext(fname->ptr, ext->ptr);
- if (f) return str_new(fname->ptr, f);
+ f = rmext(RSTRING(fname)->ptr, RSTRING(ext)->ptr);
+ if (f) return str_new(RSTRING(fname)->ptr, f);
}
return (VALUE)fname;
}
p++; /* skip last `/' */
if (!NIL_P(ext)) {
- f = rmext(p, ext->ptr);
+ f = rmext(p, RSTRING(ext)->ptr);
if (f) return str_new(p, f);
}
return str_taint(str_new2(p));
@@ -1365,19 +1323,18 @@ file_s_basename(argc, argv)
static VALUE
file_s_dirname(obj, fname)
- VALUE obj;
- struct RString *fname;
+ VALUE obj, fname;
{
UCHAR *p;
Check_Type(fname, T_STRING);
- p = strrchr(fname->ptr, '/');
+ p = strrchr(RSTRING(fname)->ptr, '/');
if (!p) {
return str_new2(".");
}
- if (p == fname->ptr)
+ if (p == RSTRING(fname)->ptr)
p++;
- return str_taint(str_new(fname->ptr, p - fname->ptr));
+ return str_taint(str_new(RSTRING(fname)->ptr, p - RSTRING(fname)->ptr));
}
static VALUE
@@ -1398,31 +1355,30 @@ file_s_join(obj, args)
static VALUE
file_s_truncate(obj, path, len)
- VALUE obj, len;
- struct RString *path;
+ VALUE obj, path, len;
{
Check_SafeStr(path);
#ifdef HAVE_TRUNCATE
- if (truncate(path->ptr, NUM2INT(len)) < 0)
- rb_sys_fail(path->ptr);
+ if (truncate(RSTRING(path)->ptr, NUM2INT(len)) < 0)
+ rb_sys_fail(RSTRING(path)->ptr);
#else
# ifdef HAVE_CHSIZE
{
int tmpfd;
# if defined(NT)
- if ((tmpfd = open(path->ptr, O_RDWR)) < 0) {
- rb_sys_fail(path->ptr);
+ if ((tmpfd = open(RSTRING(path)->ptr, O_RDWR)) < 0) {
+ rb_sys_fail(RSTRING(path)->ptr);
}
# else
- if ((tmpfd = open(path->ptr, 0)) < 0) {
- rb_sys_fail(path->ptr);
+ if ((tmpfd = open(RSTRING(path)->ptr, 0)) < 0) {
+ rb_sys_fail(RSTRING(path)->ptr);
}
# endif
if (chsize(tmpfd, NUM2INT(len)) < 0) {
close(tmpfd);
- rb_sys_fail(path->ptr);
+ rb_sys_fail(RSTRING(path)->ptr);
}
close(tmpfd);
}
@@ -1635,6 +1591,8 @@ extern VALUE mKernel;
void
Init_File()
{
+ VALUE mConst;
+
mFileTest = rb_define_module("FileTest");
rb_define_module_function(mFileTest, "directory?", test_d, 1);
@@ -1649,6 +1607,7 @@ Init_File()
rb_define_module_function(mFileTest, "file?", test_f, 1);
rb_define_module_function(mFileTest, "zero?", test_z, 1);
rb_define_module_function(mFileTest, "size?", test_s, 1);
+ rb_define_module_function(mFileTest, "size", test_s, 1);
rb_define_module_function(mFileTest, "owned?", test_owned, 1);
rb_define_module_function(mFileTest, "grpowned?", test_grpowned, 1);
@@ -1740,11 +1699,17 @@ Init_File()
# define LOCK_UN 8
# endif
+ mConst = rb_define_module_under(cFile, "Constants");
rb_define_const(cFile, "LOCK_SH", INT2FIX(LOCK_SH));
rb_define_const(cFile, "LOCK_EX", INT2FIX(LOCK_EX));
rb_define_const(cFile, "LOCK_UN", INT2FIX(LOCK_UN));
rb_define_const(cFile, "LOCK_NB", INT2FIX(LOCK_NB));
+ rb_define_const(mConst, "LOCK_SH", INT2FIX(LOCK_SH));
+ rb_define_const(mConst, "LOCK_EX", INT2FIX(LOCK_EX));
+ rb_define_const(mConst, "LOCK_UN", INT2FIX(LOCK_UN));
+ rb_define_const(mConst, "LOCK_NB", INT2FIX(LOCK_NB));
+
rb_define_method(cFile, "path", file_path, 0);
rb_define_global_function("test", f_test, -1);
diff --git a/gc.c b/gc.c
index 710f8d6..27065af 100644
--- a/gc.c
+++ b/gc.c
@@ -34,8 +34,6 @@
void *alloca();
#endif
-void gc();
-void gc_mark();
static void run_final();
#ifndef GC_MALLOC_LIMIT
@@ -57,11 +55,11 @@ xmalloc(size)
if (size == 0) size = 1;
malloc_memories += size;
if (malloc_memories > GC_MALLOC_LIMIT) {
- gc();
+ gc_gc();
}
mem = malloc(size);
if (!mem) {
- gc();
+ gc_gc();
mem = malloc(size);
if (!mem)
Fatal("failed to allocate memory");
@@ -92,7 +90,7 @@ xrealloc(ptr, size)
if (!ptr) return xmalloc(size);
mem = realloc(ptr, size);
if (!mem) {
- gc();
+ gc_gc();
mem = realloc(ptr, size);
if (!mem)
Fatal("failed to allocate memory(realloc)");
@@ -235,19 +233,21 @@ add_heap()
p++;
}
}
+#define RANY(o) ((RVALUE*)(o))
-struct RBasic *
+VALUE
rb_newobj()
{
- struct RBasic *obj;
+ VALUE obj;
+
if (freelist) {
retry:
- obj = (struct RBasic*)freelist;
+ obj = (VALUE)freelist;
freelist = freelist->as.free.next;
return obj;
}
if (dont_gc) add_heap();
- else gc();
+ else gc_gc();
goto retry;
}
@@ -259,8 +259,7 @@ data_object_alloc(class, datap, dmark, dfree)
void (*dfree)();
void (*dmark)();
{
- struct RData *data = (struct RData*)rb_newobj();
-
+ NEWOBJ(data, struct RData);
OBJSETUP(data, class, T_DATA);
data->data = datap;
data->dfree = dfree;
@@ -273,9 +272,10 @@ extern st_table *rb_class_tbl;
VALUE *gc_stack_start;
static int
-looks_pointerp(p)
- register RVALUE *p;
+looks_pointerp(ptr)
+ void *ptr;
{
+ register RVALUE *p = RANY(ptr);
register RVALUE *heap_org;
register long i;
@@ -365,9 +365,11 @@ gc_mark_maybe(obj)
}
void
-gc_mark(obj)
- register RVALUE *obj;
+gc_mark(ptr)
+ void *ptr;
{
+ register RVALUE *obj = RANY(ptr);
+
Top:
if (FIXNUM_P(obj)) return; /* fixnum not marked */
if (rb_special_const_p((VALUE)obj)) return; /* special const not marked */
@@ -403,16 +405,18 @@ gc_mark(obj)
case NODE_SUPER: /* 3 */
case NODE_FCALL:
case NODE_NEWLINE:
- obj = (RVALUE*)obj->as.node.u3.node;
+ obj = RANY(obj->as.node.u3.node);
goto Top;
case NODE_WHILE: /* 1,2 */
case NODE_UNTIL:
+ case NODE_MATCH2:
+ case NODE_MATCH3:
gc_mark(obj->as.node.u1.node);
/* fall through */
case NODE_METHOD: /* 2 */
case NODE_NOT:
- obj = (RVALUE*)obj->as.node.u2.node;
+ obj = RANY(obj->as.node.u2.node);
goto Top;
case NODE_HASH: /* 1 */
@@ -420,12 +424,13 @@ gc_mark(obj)
case NODE_STR:
case NODE_XSTR:
case NODE_DEFINED:
- obj = (RVALUE*)obj->as.node.u1.node;
+ case NODE_MATCH:
+ obj = RANY(obj->as.node.u1.node);
goto Top;
case NODE_SCOPE: /* 2,3 */
gc_mark(obj->as.node.u3.node);
- obj = (RVALUE*)obj->as.node.u2.node;
+ obj = RANY(obj->as.node.u2.node);
goto Top;
case NODE_ZARRAY: /* - */
@@ -443,6 +448,7 @@ gc_mark(obj)
case NODE_UNDEF:
case NODE_SELF:
case NODE_NIL:
+ case NODE_POSTEXE:
break;
default:
@@ -453,7 +459,7 @@ gc_mark(obj)
gc_mark(obj->as.node.u2.node);
}
if (looks_pointerp(obj->as.node.u3.node)) {
- obj = (RVALUE*)obj->as.node.u3.node;
+ obj = RANY(obj->as.node.u3.node);
goto Top;
}
}
@@ -491,7 +497,7 @@ gc_mark(obj)
case T_STRING:
if (obj->as.string.orig) {
- obj = (RVALUE*)obj->as.string.orig;
+ obj = RANY(obj->as.string.orig);
goto Top;
}
break;
@@ -512,14 +518,14 @@ gc_mark(obj)
case T_MATCH:
if (obj->as.match.str) {
- obj = (RVALUE*)obj->as.match.str;
+ obj = RANY(obj->as.match.str);
goto Top;
}
break;
case T_VARMAP:
gc_mark(obj->as.varmap.val);
- obj = (RVALUE*)obj->as.varmap.next;
+ obj = RANY(obj->as.varmap.next);
goto Top;
break;
@@ -604,20 +610,20 @@ gc_sweep()
void
gc_force_recycle(p)
- RVALUE *p;
+ VALUE p;
{
- p->as.free.flag = 0;
- p->as.free.next = freelist;
- freelist = p;
+ RANY(p)->as.free.flag = 0;
+ RANY(p)->as.free.next = freelist;
+ freelist = RANY(p);
}
static int need_call_final = 0;
static void
obj_free(obj)
- RVALUE *obj;
+ VALUE obj;
{
- switch (obj->as.basic.flags & T_MASK) {
+ switch (RANY(obj)->as.basic.flags & T_MASK) {
case T_NIL:
case T_FIXNUM:
case T_TRUE:
@@ -629,40 +635,44 @@ obj_free(obj)
if (need_call_final) {
run_final(obj);
}
- switch (obj->as.basic.flags & T_MASK) {
+ switch (RANY(obj)->as.basic.flags & T_MASK) {
case T_OBJECT:
- if (obj->as.object.iv_tbl) st_free_table(obj->as.object.iv_tbl);
+ if (RANY(obj)->as.object.iv_tbl) {
+ st_free_table(RANY(obj)->as.object.iv_tbl);
+ }
break;
case T_MODULE:
case T_CLASS:
rb_clear_cache();
- st_free_table(obj->as.class.m_tbl);
- if (obj->as.object.iv_tbl) st_free_table(obj->as.object.iv_tbl);
+ st_free_table(RANY(obj)->as.class.m_tbl);
+ if (RANY(obj)->as.object.iv_tbl) {
+ st_free_table(RANY(obj)->as.object.iv_tbl);
+ }
break;
case T_STRING:
- if (!obj->as.string.orig) free(obj->as.string.ptr);
+ if (!RANY(obj)->as.string.orig) free(RANY(obj)->as.string.ptr);
break;
case T_ARRAY:
- if (obj->as.array.ptr) free(obj->as.array.ptr);
+ if (RANY(obj)->as.array.ptr) free(RANY(obj)->as.array.ptr);
break;
case T_HASH:
- st_free_table(obj->as.hash.tbl);
+ st_free_table(RANY(obj)->as.hash.tbl);
break;
case T_REGEXP:
- reg_free(obj->as.regexp.ptr);
- free(obj->as.regexp.str);
+ reg_free(RANY(obj)->as.regexp.ptr);
+ free(RANY(obj)->as.regexp.str);
break;
case T_DATA:
- if (obj->as.data.dfree && DATA_PTR(obj))
- (*obj->as.data.dfree)(DATA_PTR(obj));
+ if (RANY(obj)->as.data.dfree && DATA_PTR(obj))
+ (*RANY(obj)->as.data.dfree)(DATA_PTR(obj));
break;
case T_MATCH:
- re_free_registers(obj->as.match.regs);
- free(obj->as.match.regs);
+ re_free_registers(RANY(obj)->as.match.regs);
+ free(RANY(obj)->as.match.regs);
break;
case T_FILE:
- io_fptr_finalize(obj->as.file.fptr);
- free(obj->as.file.fptr);
+ io_fptr_finalize(RANY(obj)->as.file.fptr);
+ free(RANY(obj)->as.file.fptr);
break;
case T_ICLASS:
/* iClass shares table with the module */
@@ -673,30 +683,30 @@ obj_free(obj)
break;
case T_BIGNUM:
- if (obj->as.bignum.digits) free(obj->as.bignum.digits);
+ if (RANY(obj)->as.bignum.digits) free(RANY(obj)->as.bignum.digits);
break;
case T_NODE:
- if (nd_type(obj) == NODE_SCOPE && obj->as.node.u1.tbl) {
- free(obj->as.node.u1.tbl);
+ if (nd_type(obj) == NODE_SCOPE && RANY(obj)->as.node.u1.tbl) {
+ free(RANY(obj)->as.node.u1.tbl);
}
return; /* no need to free iv_tbl */
case T_SCOPE:
- if (obj->as.scope.local_vars) {
- VALUE *vars = obj->as.scope.local_vars-1;
+ if (RANY(obj)->as.scope.local_vars) {
+ VALUE *vars = RANY(obj)->as.scope.local_vars-1;
if (vars[0] == 0)
- free(obj->as.scope.local_tbl);
- if (obj->as.scope.flag&SCOPE_MALLOC)
+ free(RANY(obj)->as.scope.local_tbl);
+ if (RANY(obj)->as.scope.flag&SCOPE_MALLOC)
free(vars);
}
break;
case T_STRUCT:
- free(obj->as.rstruct.ptr);
+ free(RANY(obj)->as.rstruct.ptr);
break;
default:
- Bug("gc_sweep(): unknown data type %d", obj->as.basic.flags & T_MASK);
+ Bug("gc_sweep(): unknown data type %d", RANY(obj)->as.basic.flags & T_MASK);
}
}
@@ -750,7 +760,7 @@ int rb_setjmp (rb_jmp_buf);
#endif /* __GNUC__ */
void
-gc()
+gc_gc()
{
struct gc_list *list;
struct FRAME *frame;
@@ -806,7 +816,7 @@ gc()
static VALUE
gc_method()
{
- gc();
+ gc_gc();
return Qnil;
}
@@ -851,7 +861,7 @@ os_live_obj()
case T_CLASS:
if (FL_TEST(p, FL_SINGLETON)) continue;
default:
- rb_yield(p);
+ rb_yield((VALUE)p);
n++;
}
}
@@ -883,8 +893,8 @@ os_obj_of(of)
case T_CLASS:
if (FL_TEST(p, FL_SINGLETON)) continue;
default:
- if (obj_is_kind_of(p, of)) {
- rb_yield(p);
+ if (obj_is_kind_of((VALUE)p, of)) {
+ rb_yield((VALUE)p);
n++;
}
}
@@ -957,10 +967,45 @@ run_final(obj)
if (!FL_TEST(obj, FL_FINALIZE)) return;
- obj |= FIXNUM_FLAG; /* make obj into id */
+ obj = INT2NUM((int)obj); /* make obj into id */
for (i=0; i<RARRAY(finalizers)->len; i++) {
- rb_eval_cmd(RARRAY(finalizers)->ptr[i], obj);
+ rb_eval_cmd(RARRAY(finalizers)->ptr[i], ary_new3(1,obj));
+ }
+}
+
+void
+gc_call_finalizer_at_exit()
+{
+ RVALUE *p, *pend;
+ int i;
+
+ for (i = 0; i < heaps_used; i++) {
+ p = heaps[i]; pend = p + HEAP_SLOTS;
+ while (p < pend) {
+ run_final(p);
+ if (BUILTIN_TYPE(p) == T_DATA &&
+ DATA_PTR(p) &&
+ RANY(p)->as.data.dfree)
+ (*RANY(p)->as.data.dfree)(DATA_PTR(p));
+ p++;
+ }
+ }
+}
+
+static VALUE
+id2ref(obj, id)
+ VALUE obj, id;
+{
+ INT ptr = NUM2INT(id);
+
+ if (FIXNUM_P(ptr)) return (VALUE)ptr;
+ if (!looks_pointerp(ptr)) {
+ IndexError("0x%x is not the id value", ptr);
+ }
+ if (RANY(ptr)->as.free.flag == 0) {
+ IndexError("0x%x is recycled object", ptr);
}
+ return (VALUE)ptr;
}
extern VALUE cModule;
@@ -978,11 +1023,12 @@ Init_GC()
mObSpace = rb_define_module("ObjectSpace");
rb_define_module_function(mObSpace, "each_object", os_each_obj, -1);
- rb_define_module_function(mObSpace, "garbage_collect", gc, 0);
+ rb_define_module_function(mObSpace, "garbage_collect", gc_method, 0);
rb_define_module_function(mObSpace, "add_finalizer", add_final, 1);
rb_define_module_function(mObSpace, "remove_finalizer", rm_final, 1);
rb_define_module_function(mObSpace, "finalizers", finals, 0);
rb_define_module_function(mObSpace, "call_finalizer", call_final, 1);
+ rb_define_module_function(mObSpace, "id2ref", id2ref, 1);
rb_global_variable(&finalizers);
finalizers = ary_new();
diff --git a/hash.c b/hash.c
index fe9dfba..49be7de 100644
--- a/hash.c
+++ b/hash.c
@@ -14,15 +14,44 @@
#include "st.h"
#include "sig.h"
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
+#include <sys/stat.h>
+
+#ifndef HAVE_STRING_H
char *strchr();
#endif
#define HASH_DELETED 0x1
#define HASH_REHASHED 0x2
+#define HASH_FREEZE FL_USER1
+
+static void
+hash_modify(hash)
+ VALUE hash;
+{
+ rb_secure(5);
+ if (FL_TEST(hash, HASH_FREEZE)) {
+ TypeError("can't modify frozen hash");
+ }
+}
+
+VALUE
+hash_freeze(hash)
+ VALUE hash;
+{
+ FL_SET(hash, HASH_FREEZE);
+ return hash;
+}
+
+static VALUE
+hash_frozen_p(hash)
+ VALUE hash;
+{
+ if (FL_TEST(hash, HASH_FREEZE))
+ return TRUE;
+ return FALSE;
+}
+
#ifndef NT
char *getenv();
#endif
@@ -90,7 +119,7 @@ static struct st_hash_type objhash = {
};
struct hash_foreach_arg {
- struct RHash *hash;
+ VALUE hash;
enum st_retval (*func)();
char *arg;
};
@@ -104,7 +133,7 @@ hash_foreach_iter(key, value, arg)
if (key == Qnil) return ST_CONTINUE;
status = (*arg->func)(key, value, arg->arg);
- if (arg->hash->status & HASH_REHASHED) return ST_STOP;
+ if (RHASH(arg->hash)->status & HASH_REHASHED) return ST_STOP;
return status;
}
@@ -112,7 +141,7 @@ static VALUE
hash_foreach_call(arg)
struct hash_foreach_arg *arg;
{
- st_foreach(arg->hash->tbl, hash_foreach_iter, arg);
+ st_foreach(RHASH(arg->hash)->tbl, hash_foreach_iter, arg);
return Qnil;
}
@@ -126,31 +155,31 @@ hash_delete_nil(key, value)
static void
hash_foreach_ensure(hash)
- struct RHash *hash;
+ VALUE hash;
{
- hash->iter_lev--;
+ RHASH(hash)->iter_lev--;
- if (hash->iter_lev == 0) {
- if (hash->status & HASH_DELETED) {
- st_foreach(hash->tbl, hash_delete_nil, 0);
+ if (RHASH(hash)->iter_lev == 0) {
+ if (RHASH(hash)->status & HASH_DELETED) {
+ st_foreach(RHASH(hash)->tbl, hash_delete_nil, 0);
}
- hash->status = 0;
+ RHASH(hash)->status = 0;
}
}
static int
hash_foreach(hash, func, farg)
- struct RHash *hash;
+ VALUE hash;
enum st_retval (*func)();
char *farg;
{
struct hash_foreach_arg arg;
- hash->iter_lev++;
+ RHASH(hash)->iter_lev++;
arg.hash = hash;
arg.func = func;
arg.arg = farg;
- return rb_ensure(hash_foreach_call, &arg, hash_foreach_ensure, hash);
+ return rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, (VALUE)hash);
}
static VALUE
@@ -177,7 +206,7 @@ hash_s_new(argc, argv, class)
return (VALUE)hash;
}
-VALUE
+static VALUE
hash_new2(class)
VALUE class;
{
@@ -196,7 +225,7 @@ hash_s_create(argc, argv, class)
VALUE *argv;
VALUE class;
{
- struct RHash *hash;
+ VALUE hash;
int i;
if (argc == 1 && TYPE(argv[0]) == T_HASH) {
@@ -216,18 +245,18 @@ hash_s_create(argc, argv, class)
if (argc % 2 != 0) {
ArgError("odd number args for Hash");
}
- hash = (struct RHash*)hash_new2(class);
+ hash = hash_new2(class);
for (i=0; i<argc; i+=2) {
- st_insert(hash->tbl, argv[i], argv[i+1]);
+ st_insert(RHASH(hash)->tbl, argv[i], argv[i+1]);
}
- return (VALUE)hash;
+ return hash;
}
static VALUE
hash_clone(hash)
- struct RHash *hash;
+ VALUE hash;
{
NEWOBJ(hash2, struct RHash);
CLONESETUP(hash2, hash);
@@ -235,7 +264,22 @@ hash_clone(hash)
hash2->iter_lev = 0;
hash2->status = 0;
hash2->tbl = 0; /* avoid GC crashing */
- hash2->tbl = (st_table*)st_copy(hash->tbl);
+ hash2->tbl = (st_table*)st_copy(RHASH(hash)->tbl);
+
+ return (VALUE)hash2;
+}
+
+static VALUE
+hash_dup(hash)
+ VALUE hash;
+{
+ NEWOBJ(hash2, struct RHash);
+ OBJSETUP(hash2, CLASS_OF(hash), T_HASH);
+
+ hash2->iter_lev = 0;
+ hash2->status = 0;
+ hash2->tbl = 0; /* avoid GC crashing */
+ hash2->tbl = (st_table*)st_copy(RHASH(hash)->tbl);
return (VALUE)hash2;
}
@@ -253,26 +297,26 @@ hash_rehash_i(key, value, tbl)
static VALUE
hash_rehash(hash)
- struct RHash *hash;
+ VALUE hash;
{
- st_table *tbl = st_init_table_with_size(&objhash, hash->tbl->num_entries);
+ st_table *tbl;
- st_foreach(hash->tbl, hash_rehash_i, tbl);
- st_free_table(hash->tbl);
- hash->tbl = tbl;
- if (hash->iter_lev > 0) hash->status |= HASH_REHASHED;
+ tbl = st_init_table_with_size(&objhash, RHASH(hash)->tbl->num_entries);
+ st_foreach(RHASH(hash)->tbl, hash_rehash_i, tbl);
+ st_free_table(RHASH(hash)->tbl);
+ RHASH(hash)->tbl = tbl;
+ if (RHASH(hash)->iter_lev > 0) RHASH(hash)->status |= HASH_REHASHED;
return (VALUE)hash;
}
VALUE
hash_aref(hash, key)
- struct RHash *hash;
- VALUE key;
+ VALUE hash, key;
{
VALUE val;
- if (!st_lookup(hash->tbl, key, &val)) {
+ if (!st_lookup(RHASH(hash)->tbl, key, &val)) {
return Qnil;
}
return val;
@@ -282,30 +326,30 @@ static VALUE
hash_indexes(argc, argv, hash)
int argc;
VALUE *argv;
- struct RHash *hash;
+ VALUE hash;
{
- struct RArray *indexes;
+ VALUE indexes;
int i;
- indexes = (struct RArray*)ary_new2(argc);
+ indexes = ary_new2(argc);
for (i=0; i<argc; i++) {
- indexes->ptr[i] = hash_aref(hash, argv[i]);
+ RARRAY(indexes)->ptr[i] = hash_aref(hash, argv[i]);
}
- indexes->len = i;
- return (VALUE)indexes;
+ RARRAY(indexes)->len = i;
+ return indexes;
}
static VALUE
hash_delete(hash, key)
- struct RHash *hash;
- VALUE key;
+ VALUE hash, key;
{
VALUE val;
- rb_secure(5);
- if (hash->iter_lev > 0 && st_delete_safe(hash->tbl, &key, &val, Qnil))
+ hash_modify(hash);
+ if (RHASH(hash)->iter_lev > 0
+ && st_delete_safe(RHASH(hash)->tbl, &key, &val, Qnil))
return val;
- else if (st_delete(hash->tbl, &key, &val))
+ else if (st_delete(RHASH(hash)->tbl, &key, &val))
return val;
if (iterator_p()) rb_yield(key);
return Qnil;
@@ -332,13 +376,13 @@ shift_i(key, value, var)
static VALUE
hash_shift(hash)
- struct RHash *hash;
+ VALUE hash;
{
struct shift_var var;
- rb_secure(5);
+ hash_modify(hash);
var.stop = 0;
- st_foreach(hash->tbl, shift_i, &var);
+ st_foreach(RHASH(hash)->tbl, shift_i, &var);
if (var.stop == 0) return Qnil;
return assoc_new(var.key, var.val);
@@ -356,9 +400,9 @@ delete_if_i(key, value)
static VALUE
hash_delete_if(hash)
- struct RHash *hash;
+ VALUE hash;
{
- rb_secure(5);
+ hash_modify(hash);
hash_foreach(hash, delete_if_i, 0);
return (VALUE)hash;
@@ -373,20 +417,19 @@ clear_i(key, value)
static VALUE
hash_clear(hash)
- struct RHash *hash;
+ VALUE hash;
{
- rb_secure(5);
- st_foreach(hash->tbl, clear_i);
+ hash_modify(hash);
+ st_foreach(RHASH(hash)->tbl, clear_i);
return (VALUE)hash;
}
VALUE
hash_aset(hash, key, val)
- struct RHash *hash;
- VALUE key, val;
+ VALUE hash, key, val;
{
- rb_secure(5);
+ hash_modify(hash);
if (NIL_P(val)) {
hash_delete(hash, key);
return Qnil;
@@ -394,22 +437,22 @@ hash_aset(hash, key, val)
if (TYPE(key) == T_STRING) {
key = str_dup_freezed(key);
}
- st_insert(hash->tbl, key, val);
+ st_insert(RHASH(hash)->tbl, key, val);
return val;
}
static VALUE
hash_length(hash)
- struct RHash *hash;
+ VALUE hash;
{
- return INT2FIX(hash->tbl->num_entries);
+ return INT2FIX(RHASH(hash)->tbl->num_entries);
}
-VALUE
+static VALUE
hash_empty_p(hash)
- struct RHash *hash;
+ VALUE hash;
{
- if (hash->tbl->num_entries == 0)
+ if (RHASH(hash)->tbl->num_entries == 0)
return TRUE;
return FALSE;
}
@@ -425,7 +468,7 @@ each_value_i(key, value)
static VALUE
hash_each_value(hash)
- struct RHash *hash;
+ VALUE hash;
{
hash_foreach(hash, each_value_i);
return (VALUE)hash;
@@ -442,7 +485,7 @@ each_key_i(key, value)
static VALUE
hash_each_key(hash)
- struct RHash *hash;
+ VALUE hash;
{
hash_foreach(hash, each_key_i);
return (VALUE)hash;
@@ -459,7 +502,7 @@ each_pair_i(key, value)
static VALUE
hash_each_pair(hash)
- struct RHash *hash;
+ VALUE hash;
{
hash_foreach(hash, each_pair_i);
return (VALUE)hash;
@@ -476,25 +519,24 @@ to_a_i(key, value, ary)
static VALUE
hash_to_a(hash)
- struct RHash *hash;
+ VALUE hash;
{
VALUE ary;
ary = ary_new();
- st_foreach(hash->tbl, to_a_i, ary);
+ st_foreach(RHASH(hash)->tbl, to_a_i, ary);
return ary;
}
static int
inspect_i(key, value, str)
- VALUE key, value;
- struct RString *str;
+ VALUE key, value, str;
{
VALUE str2;
if (key == Qnil) return ST_CONTINUE;
- if (str->len > 1) {
+ if (RSTRING(str)->len > 1) {
str_cat(str, ", ", 2);
}
str2 = rb_inspect(key);
@@ -508,12 +550,12 @@ inspect_i(key, value, str)
static VALUE
hash_inspect(hash)
- struct RHash *hash;
+ VALUE hash;
{
VALUE str;
str = str_new2("{");
- st_foreach(hash->tbl, inspect_i, str);
+ st_foreach(RHASH(hash)->tbl, inspect_i, str);
str_cat(str, "}", 1);
return str;
@@ -537,12 +579,12 @@ keys_i(key, value, ary)
static VALUE
hash_keys(hash)
- struct RHash *hash;
+ VALUE hash;
{
VALUE ary;
ary = ary_new();
- st_foreach(hash->tbl, keys_i, ary);
+ st_foreach(RHASH(hash)->tbl, keys_i, ary);
return ary;
}
@@ -558,22 +600,22 @@ values_i(key, value, ary)
static VALUE
hash_values(hash)
- struct RHash *hash;
+ VALUE hash;
{
VALUE ary;
ary = ary_new();
- st_foreach(hash->tbl, values_i, ary);
+ st_foreach(RHASH(hash)->tbl, values_i, ary);
return ary;
}
static VALUE
hash_has_key(hash, key)
- struct RHash *hash;
+ VALUE hash;
VALUE key;
{
- if (st_lookup(hash->tbl, key, 0)) {
+ if (st_lookup(RHASH(hash)->tbl, key, 0)) {
return TRUE;
}
return FALSE;
@@ -593,14 +635,14 @@ hash_search_value(key, value, data)
static VALUE
hash_has_value(hash, val)
- struct RHash *hash;
+ VALUE hash;
VALUE val;
{
VALUE data[2];
data[0] = FALSE;
data[1] = val;
- st_foreach(hash->tbl, hash_search_value, data);
+ st_foreach(RHASH(hash)->tbl, hash_search_value, data);
return data[0];
}
@@ -630,17 +672,17 @@ equal_i(key, val1, data)
static VALUE
hash_equal(hash1, hash2)
- struct RHash *hash1, *hash2;
+ VALUE hash1, hash2;
{
struct equal_data data;
if (TYPE(hash2) != T_HASH) return FALSE;
- if (hash1->tbl->num_entries != hash2->tbl->num_entries)
+ if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries)
return FALSE;
- data.tbl = hash2->tbl;
+ data.tbl = RHASH(hash2)->tbl;
data.result = TRUE;
- st_foreach(hash1->tbl, equal_i, &data);
+ st_foreach(RHASH(hash1)->tbl, equal_i, &data);
return data.result;
}
@@ -648,7 +690,7 @@ hash_equal(hash1, hash2)
static int
hash_invert_i(key, value, hash)
VALUE key, value;
- struct RHash *hash;
+ VALUE hash;
{
if (key == Qnil) return ST_CONTINUE;
hash_aset(hash, value, key);
@@ -657,15 +699,36 @@ hash_invert_i(key, value, hash)
static VALUE
hash_invert(hash)
- struct RHash *hash;
+ VALUE hash;
{
VALUE h = hash_new();
- st_foreach(hash->tbl, hash_invert_i, h);
+ st_foreach(RHASH(hash)->tbl, hash_invert_i, h);
return h;
}
-int env_path_tainted = 0;
+static int
+hash_update_i(key, value, hash)
+ VALUE key, value;
+ VALUE hash;
+{
+ if (key == Qnil) return ST_CONTINUE;
+ hash_aset(hash, key, value);
+ return ST_CONTINUE;
+}
+
+static VALUE
+hash_update(hash1, hash2)
+ VALUE hash1, hash2;
+{
+ Check_Type(hash2, T_HASH);
+
+ st_foreach(RHASH(hash2)->tbl, hash_update_i, hash1);
+ return hash1;
+}
+
+int env_path_tainted();
+static int path_tainted = -1;
#ifndef NT
extern char **environ;
@@ -673,17 +736,16 @@ extern char **environ;
static VALUE
env_delete(obj, name)
- VALUE obj;
- struct RString *name;
+ VALUE obj, name;
{
int i, len;
char *nam, *val = 0;
rb_secure(4);
Check_Type(name, T_STRING);
- nam = name->ptr;
+ nam = RSTRING(name)->ptr;
len = strlen(nam);
- if (strcmp(nam, "PATH") == 0) env_path_tainted = 0;
+ if (strcmp(nam, "PATH") == 0) path_tainted = 0;
for(i=0; environ[i]; i++) {
if (strncmp(environ[i], nam, len) == 0 && environ[i][len] == '=') {
val = environ[i]+len+1;
@@ -701,30 +763,97 @@ env_delete(obj, name)
}
static VALUE
+env_delete_method(obj, name)
+ VALUE obj, name;
+{
+ VALUE val = env_delete(obj, name);
+ if (iterator_p()) rb_yield(name);
+ return val;
+}
+
+static VALUE
f_getenv(obj, name)
- VALUE obj;
- struct RString *name;
+ VALUE obj, name;
{
char *env;
Check_Type(name, T_STRING);
- if (strlen(name->ptr) != name->len)
+ if (strlen(RSTRING(name)->ptr) != RSTRING(name)->len)
ArgError("Bad environment name");
- env = getenv(name->ptr);
+ env = getenv(RSTRING(name)->ptr);
if (env) {
- if (strcmp(name->ptr, "PATH") == 0 && !env_path_tainted)
+ if (strcmp(RSTRING(name)->ptr, "PATH") == 0 && !env_path_tainted())
return str_new2(env);
return str_taint(str_new2(env));
}
return Qnil;
}
+static int
+path_check_1(path)
+ char *path;
+{
+ struct stat st;
+ char *p = 0;
+ char *s;
+
+ for (;;) {
+ if (stat(path, &st) == 0 && (st.st_mode & 2)) {
+ return 0;
+ }
+ s = strrchr(path, '/');
+ if (p) *p = '/';
+ if (!s || s == path) return 1;
+ p = s;
+ *p = '\0';
+ }
+}
+
+static void
+path_check(path)
+ char *path;
+{
+ char *p = path;
+ char *pend = strchr(path, ':');
+
+ if (!path) {
+ path_tainted = 0;
+ }
+
+ p = path;
+ pend = strchr(path, ':');
+
+ for (;;) {
+ int safe;
+
+ if (pend) *pend = '\0';
+ safe = path_check_1(p);
+ if (!pend) break;
+ *pend = ':';
+ if (!safe) {
+ path_tainted = 1;
+ return;
+ }
+ p = pend + 1;
+ pend = strchr(p, ':');
+ }
+ path_tainted = 0;
+}
+
+int
+env_path_tainted()
+{
+ if (path_tainted < 0) {
+ path_check(getenv("PATH"));
+ }
+ return path_tainted;
+}
+
static VALUE
f_setenv(obj, name, value)
- VALUE obj;
- struct RString *name, *value;
+ VALUE obj, name, value;
{
if (rb_safe_level() >= 4) {
extern VALUE eSecurityError;
@@ -738,13 +867,23 @@ f_setenv(obj, name, value)
}
Check_SafeStr(value);
- if (strlen(name->ptr) != name->len)
+ if (strlen(RSTRING(name)->ptr) != RSTRING(name)->len)
ArgError("Bad environment name");
- if (strlen(value->ptr) != value->len)
+ if (strlen(RSTRING(value)->ptr) != RSTRING(value)->len)
ArgError("Bad environment value");
- setenv(name->ptr, value->ptr, 1);
- if (strcmp(name->ptr, "PATH") == 0) env_path_tainted = 0;
+ setenv(RSTRING(name)->ptr, RSTRING(value)->ptr, 1);
+ if (strcmp(RSTRING(name)->ptr, "PATH") == 0) {
+ char *p, pend;
+
+ if (str_tainted(value)) {
+ /* already tainted, no check */
+ path_tainted = 1;
+ return TRUE;
+ }
+
+ path_check(RSTRING(name)->ptr);
+ }
return TRUE;
}
@@ -941,15 +1080,19 @@ Init_Hash()
rb_define_singleton_method(cHash, "new", hash_s_new, -1);
rb_define_singleton_method(cHash, "[]", hash_s_create, -1);
- rb_define_method(cHash,"clone", hash_clone, 0);
- rb_define_method(cHash,"rehash", hash_rehash, 0);
+ rb_define_method(cHash,"clone", hash_clone, 0);
+ rb_define_method(cHash,"dup", hash_dup, 0);
+ rb_define_method(cHash,"rehash", hash_rehash, 0);
+
+ rb_define_method(cHash,"freeze", hash_freeze, 0);
+ rb_define_method(cHash,"frozen?",hash_frozen_p, 0);
- rb_define_method(cHash,"to_a", hash_to_a, 0);
- rb_define_method(cHash,"to_s", hash_to_s, 0);
- rb_define_method(cHash,"inspect", hash_inspect, 0);
+ rb_define_method(cHash,"to_a", hash_to_a, 0);
+ rb_define_method(cHash,"to_s", hash_to_s, 0);
+ rb_define_method(cHash,"inspect", hash_inspect, 0);
- rb_define_method(cHash,"==", hash_equal, 1);
- rb_define_method(cHash,"[]", hash_aref, 1);
+ rb_define_method(cHash,"==", hash_equal, 1);
+ rb_define_method(cHash,"[]", hash_aref, 1);
rb_define_method(cHash,"[]=", hash_aset, 2);
rb_define_method(cHash,"indexes", hash_indexes, -1);
rb_define_method(cHash,"length", hash_length, 0);
@@ -969,6 +1112,7 @@ Init_Hash()
rb_define_method(cHash,"delete_if", hash_delete_if, 0);
rb_define_method(cHash,"clear", hash_clear, 0);
rb_define_method(cHash,"invert", hash_invert, 0);
+ rb_define_method(cHash,"update", hash_update, 1);
rb_define_method(cHash,"include?", hash_has_key, 1);
rb_define_method(cHash,"has_key?", hash_has_key, 1);
@@ -985,7 +1129,7 @@ Init_Hash()
rb_define_singleton_method(envtbl,"each_pair", env_each, 0);
rb_define_singleton_method(envtbl,"each_key", env_each_key, 0);
rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
- rb_define_singleton_method(envtbl,"delete", env_delete, 1);
+ rb_define_singleton_method(envtbl,"delete", env_delete_method, 1);
rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
rb_define_singleton_method(envtbl,"rehash", env_none, 0);
diff --git a/inits.c b/inits.c
index ebfc0f9..123b32c 100644
--- a/inits.c
+++ b/inits.c
@@ -12,20 +12,51 @@
#include "ruby.h"
+void Init_Array _((void));
+void Init_Bignum _((void));
+void Init_Comparable _((void));
+void Init_Dir _((void));
+void Init_Enumerable _((void));
+void Init_Exception _((void));
+void Init_eval _((void));
+void Init_load _((void));
+void Init_Proc _((void));
+void Init_Thread _((void));
+void Init_File _((void));
+void Init_GC _((void));
+void Init_Hash _((void));
+void Init_IO _((void));
+void Init_Math _((void));
+void Init_marshal _((void));
+void Init_Numeric _((void));
+void Init_Object _((void));
+void Init_pack _((void));
+void Init_sym _((void));
+void Init_process _((void));
+void Init_Random _((void));
+void Init_Range _((void));
+void Init_Regexp _((void));
+void Init_signal _((void));
+void Init_String _((void));
+void Init_Struct _((void));
+void Init_Time _((void));
+void Init_var_tables _((void));
+void Init_version _((void));
+
void
rb_call_inits()
{
Init_sym();
Init_var_tables();
Init_Object();
+ Init_Exception();
#ifdef THREAD
Init_Thread();
#endif
- Init_eval();
Init_Comparable();
Init_Enumerable();
+ Init_eval();
Init_String();
- Init_Exception();
Init_Numeric();
Init_Bignum();
Init_Array();
@@ -44,5 +75,6 @@ rb_call_inits()
Init_Proc();
Init_Math();
Init_GC();
+ Init_marshal();
Init_version();
}
diff --git a/io.c b/io.c
index adf4b74..f84e15e 100644
--- a/io.c
+++ b/io.c
@@ -49,6 +49,10 @@ struct timeval {
# define NOFILE 64
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
VALUE rb_ad_string();
VALUE cIO;
@@ -130,16 +134,15 @@ closed()
/* writing functions */
VALUE
io_write(io, str)
- VALUE io;
- struct RString *str;
+ VALUE io, str;
{
OpenFile *fptr;
FILE *f;
int n;
if (TYPE(str) != T_STRING)
- str = (struct RString*)obj_as_string(str);
- if (str->len == 0) return INT2FIX(0);
+ str = obj_as_string(str);
+ if (RSTRING(str)->len == 0) return INT2FIX(0);
if (BUILTIN_TYPE(io) != T_FILE) {
return rb_funcall(io, id_write, 1, str);
@@ -164,7 +167,7 @@ io_write(io, str)
if (ferror(f))
rb_sys_fail(fptr->path);
#else
- n = fwrite(str->ptr, 1, str->len, f);
+ n = fwrite(RSTRING(str)->ptr, 1, RSTRING(str)->len, f);
if (n == 0 || ferror(f)) {
rb_sys_fail(fptr->path);
}
@@ -177,7 +180,7 @@ io_write(io, str)
}
static VALUE
-io_puts(io, str)
+io_addstr(io, str)
VALUE io, str;
{
io_write(io, str);
@@ -265,29 +268,53 @@ io_fileno(io)
}
/* reading functions */
+
+#ifndef S_ISREG
+# define S_ISREG(m) ((m & S_IFMT) == S_IFREG)
+#endif
+
+#define SMALLBUF 100
+
static VALUE
read_all(port)
VALUE port;
{
OpenFile *fptr;
VALUE str = Qnil;
- char buf[BUFSIZ];
+ char *buf;
+ struct stat st;
+ int siz = BUFSIZ;
+ int bytes = 0;
int n;
GetOpenFile(port, fptr);
io_readable(fptr);
if (fptr->f == NULL) closed();
+ if (fstat(fileno(fptr->f), &st) == 0 && S_ISREG(st.st_mode)) {
+ if (st.st_size == 0) return Qnil;
+ else {
+ int pos = ftell(fptr->f);
+ if (st.st_size > pos && pos >= 0) {
+ siz = st.st_size - pos + 1;
+ }
+ }
+ }
+ str = str_new(0, siz);
for (;;) {
READ_CHECK(fptr->f);
TRAP_BEG;
- n = fread(buf, 1, BUFSIZ, fptr->f);
+ n = fread(RSTRING(str)->ptr+bytes, 1, siz-bytes, fptr->f);
TRAP_END;
if (n == 0) break;
- if (n < 0) rb_sys_fail(0);
- if (NIL_P(str)) str = str_new(buf, n);
- else str_cat(str, buf, n);
- }
+ if (n < 0) rb_sys_fail(fptr->path);
+ bytes += n;
+ if (bytes < siz) break;
+ siz += BUFSIZ;
+ str_resize(str, siz);
+ }
+ if (bytes == 0) return Qnil;
+ if (bytes != siz) str_resize(str, bytes);
return str_taint(str);
}
@@ -298,26 +325,26 @@ io_read(argc, argv, io)
VALUE io;
{
OpenFile *fptr;
- int n, lgt;
- VALUE len, str;
+ int n, len;
+ VALUE length, str;
- if (rb_scan_args(argc, argv, "01", &len) == 0) {
+ if (rb_scan_args(argc, argv, "01", &length) == 0) {
return read_all(io);
}
- lgt = NUM2INT(len);
+ len = NUM2INT(length);
GetOpenFile(io, fptr);
io_readable(fptr);
if (fptr->f == NULL) closed();
- str = str_new(0, lgt);
+ str = str_new(0, len);
READ_CHECK(fptr->f);
TRAP_BEG;
- n = fread(RSTRING(str)->ptr, 1, RSTRING(str)->len, fptr->f);
+ n = fread(RSTRING(str)->ptr, 1, len, fptr->f);
TRAP_END;
- if (n == 0) {
- if (feof(fptr->f)) return Qnil;
+ if (n == 0) return Qnil;
+ if (n < 0) {
rb_sys_fail(fptr->path);
}
@@ -332,12 +359,12 @@ static VALUE lineno;
VALUE
io_gets_method(argc, argv, io)
int argc;
- VALUE argv;
+ VALUE *argv;
VALUE io;
{
OpenFile *fptr;
FILE *f;
- struct RString *str;
+ VALUE str = Qnil;
int c, newline;
char *rsptr;
int rslen, rspara = 0;
@@ -415,7 +442,7 @@ io_gets_method(argc, argv, io)
if (c == EOF) {
if (!append && cnt == 0) {
- str = RSTRING(Qnil);
+ str = Qnil;
goto return_gets;
}
}
@@ -423,12 +450,12 @@ io_gets_method(argc, argv, io)
if (append)
str_cat(str, buf, cnt);
else
- str = (struct RString*)str_new(buf, cnt);
+ str = str_new(buf, cnt);
if (c != EOF &&
(!rslen ||
- str->len < rslen ||
- memcmp(str->ptr+str->len-rslen, rsptr, rslen))) {
+ RSTRING(str)->len < rslen ||
+ memcmp(RSTRING(str)->ptr+RSTRING(str)->len-rslen, rsptr, rslen))) {
append = 1;
goto again;
}
@@ -448,13 +475,14 @@ io_gets_method(argc, argv, io)
}
}
- if (str) {
+ if (!NIL_P(str)) {
fptr->lineno++;
lineno = INT2FIX(fptr->lineno);
+ str_taint(str);
}
lastline_set(str);
- return str_taint(str);
+ return str;
}
VALUE
@@ -467,7 +495,7 @@ io_gets(io)
static VALUE
io_readline(argc, argv, io)
int argc;
- VALUE argv;
+ VALUE *argv;
VALUE io;
{
VALUE line = io_gets_method(argc, argv, io);
@@ -481,7 +509,7 @@ io_readline(argc, argv, io)
static VALUE
io_readlines(argc, argv, io)
int argc;
- VALUE argv;
+ VALUE *argv;
VALUE io;
{
VALUE line, ary;
@@ -496,7 +524,7 @@ io_readlines(argc, argv, io)
static VALUE
io_each_line(argc, argv, io)
int argc;
- VALUE argv;
+ VALUE *argv;
VALUE io;
{
VALUE str;
@@ -582,6 +610,7 @@ io_ungetc(io, c)
if (ungetc(FIX2INT(c), fptr->f) == EOF)
rb_sys_fail(fptr->path);
+ return Qnil;
}
static VALUE
@@ -777,7 +806,7 @@ rb_fopen(fname, mode)
f = fopen(fname, mode);
if (f == NULL) {
if (errno == EMFILE || errno == ENFILE) {
- gc();
+ gc_gc();
f = fopen(fname, mode);
}
if (f == NULL) {
@@ -945,16 +974,9 @@ pipe_open(pname, mode)
}
if (doexec) {
- VALUE serr = io_fileno(rb_stderr);
- int fd = FIX2INT(serr);
extern char *sourcefile;
extern int sourceline;
-
- if (fd != 2) {
- close(2);
- dup2(fd, 2);
- close(fd);
- }
+ int fd;
for (fd = 3; fd < NOFILE; fd++)
close(fd);
@@ -1043,13 +1065,13 @@ io_open(fname, mode)
}
static VALUE
-f_open(argc, argv, self)
+f_open(argc, argv)
int argc;
VALUE *argv;
- VALUE self;
{
char *mode;
VALUE pname, pmode;
+ VALUE port;
rb_scan_args(argc, argv, "11", &pname, &pmode);
Check_SafeStr(pname);
@@ -1062,13 +1084,35 @@ f_open(argc, argv, self)
ArgError("illegal access mode");
mode = RSTRING(pmode)->ptr;
}
- return io_open(RSTRING(pname)->ptr, mode);
+
+ port = io_open(RSTRING(pname)->ptr, mode);
+ if (iterator_p()) {
+ rb_ensure(rb_yield, port, io_close, port);
+ }
+
+ return port;
}
#ifndef NT
extern char *strdup();
#endif
+static char*
+io_mode_string(fptr)
+ OpenFile *fptr;
+{
+ switch (fptr->mode & FMODE_READWRITE) {
+ case FMODE_READABLE:
+ default:
+ return "r";
+ case FMODE_WRITABLE:
+ return "w";
+ case FMODE_READWRITE:
+ return "r+";
+ }
+ return "r";
+}
+
VALUE
io_reopen(io, nfile)
VALUE io, nfile;
@@ -1097,25 +1141,17 @@ io_reopen(io, nfile)
else fptr->path = 0;
fptr->finalize = orig->finalize;
- switch (fptr->mode & FMODE_READWRITE) {
- case FMODE_READABLE:
- default:
- mode = "r"; break;
- case FMODE_WRITABLE:
- mode = "w"; break;
- case FMODE_READWRITE:
- if (orig->f2) mode = "r";
- else mode = "r+";
- break;
- }
+ mode = io_mode_string(fptr);
fd = fileno(fptr->f);
- fclose(fptr->f);
+ if (fileno(fptr->f) < 3) /* need to keep stdio */
+ fclose(fptr->f);
dup2(fileno(orig->f), fd);
fptr->f = rb_fdopen(fd, mode);
if (fptr->f2) {
fd = fileno(fptr->f2);
- fclose(fptr->f2);
+ if (fileno(fptr->f2) < 3)
+ fclose(fptr->f2);
if (orig->f2) {
dup2(fileno(orig->f2), fd);
fptr->f = rb_fdopen(fd, "w");
@@ -1179,7 +1215,7 @@ io_clone(io)
fptr->f = rb_fdopen(fd, "w");
}
if (fptr->mode & FMODE_BINMODE) {
- io_binmode(obj);
+ io_binmode((VALUE)obj);
}
return (VALUE)obj;
@@ -1226,7 +1262,7 @@ io_print(argc, argv, out)
VALUE *argv;
VALUE out;
{
- int i;
+ int i, j;
VALUE line;
/* if no argument given, print `$_' */
@@ -1244,7 +1280,12 @@ io_print(argc, argv, out)
io_write(out, str_new2("nil"));
break;
case T_ARRAY:
- ary_print_on(argv[i], out);
+ for (j=0; j<RARRAY(argv[i])->len; j++) {
+ if (!NIL_P(OFS) && j>0) {
+ io_write(out, OFS);
+ }
+ io_write(out, RARRAY(argv[i])->ptr[j]);
+ }
break;
default:
io_write(out, argv[i]);
@@ -1268,6 +1309,53 @@ f_print(argc, argv)
}
static VALUE
+io_puts(argc, argv, out)
+ int argc;
+ VALUE *argv;
+ VALUE out;
+{
+ int i, j;
+ VALUE line;
+
+ /* if no argument given, print newline. */
+ if (argc == 0) {
+ io_write(out, str_new2("\n"));
+ return Qnil;
+ }
+ for (i=0; i<argc; i++) {
+ switch (TYPE(argv[i])) {
+ case T_NIL:
+ line = str_new2("nil");
+ break;
+ case T_ARRAY:
+ for (j=0; j<RARRAY(argv[i])->len; j++) {
+ io_puts(1, &RARRAY(argv[i])->ptr[j], out);
+ }
+ continue;
+ default:
+ line = argv[i];
+ break;
+ }
+ line = obj_as_string(line);
+ io_write(out, line);
+ if (RSTRING(line)->ptr[RSTRING(line)->len-1] != '\n') {
+ io_write(out, str_new2("\n"));
+ }
+ }
+
+ return Qnil;
+}
+
+static VALUE
+f_puts(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ io_puts(argc, argv, rb_defout);
+ return Qnil;
+}
+
+static VALUE
f_p(obj, val)
VALUE obj, val;
{
@@ -1279,6 +1367,13 @@ f_p(obj, val)
return Qnil;
}
+void
+rb_p(obj) /* for debug print within C code */
+ VALUE obj;
+{
+ f_p(Qnil, obj);
+}
+
static void
io_defset(val, id)
VALUE val;
@@ -1294,6 +1389,41 @@ io_defset(val, id)
rb_defout = val;
}
+static void
+io_errset(val, id)
+ VALUE val;
+ ID id;
+{
+ OpenFile *fptr;
+ int fd;
+
+ if (TYPE(val) != T_FILE) {
+ TypeError("$stderr must be IO Object");
+ }
+ GetOpenFile(val, fptr);
+ io_writable(fptr);
+ rb_stderr = val;
+
+ fd = fileno(fptr->f2?fptr->f2:fptr->f);
+ if (fd != 2) {
+ FILE *f;
+
+ fflush(stderr);
+ dup2(fd, 2);
+ f = rb_fdopen(2, io_mode_string(fptr));
+ if (fptr->f2) {
+ if (fileno(fptr->f2) < 3) /* need to keep stdio */
+ fclose(fptr->f2);
+ fptr->f2 = f;
+ }
+ else {
+ if (fileno(fptr->f) < 3)
+ fclose(fptr->f);
+ fptr->f = f;
+ }
+ }
+}
+
static VALUE
prep_stdio(f, mode)
FILE *f;
@@ -1336,11 +1466,11 @@ static int init_p = 0, next_p = 0;
static int
next_argv()
{
- extern VALUE Argv;
+ extern VALUE rb_argv;
char *fn;
if (init_p == 0) {
- if (RARRAY(Argv)->len > 0) {
+ if (RARRAY(rb_argv)->len > 0) {
next_p = 1;
}
else {
@@ -1354,8 +1484,8 @@ next_argv()
retry:
if (next_p == 1) {
next_p = 0;
- if (RARRAY(Argv)->len > 0) {
- filename = ary_shift(Argv);
+ if (RARRAY(rb_argv)->len > 0) {
+ filename = ary_shift(rb_argv);
fn = RSTRING(filename)->ptr;
if (RSTRING(filename)->len == 1 && fn[0] == '-') {
file = rb_stdin;
@@ -1371,7 +1501,7 @@ next_argv()
VALUE str;
FILE *fw;
- if (rb_defout != rb_stdout) {
+ if (TYPE(rb_defout) == T_FILE && rb_defout != rb_stdout) {
io_close(rb_defout);
}
fstat(fileno(fr), &st);
@@ -1539,13 +1669,12 @@ rb_str_setter(val, id, var)
static VALUE
f_backquote(obj, str)
- VALUE obj;
- struct RString *str;
+ VALUE obj, str;
{
VALUE port, result;
Check_SafeStr(str);
- port = pipe_open(str->ptr, "r");
+ port = pipe_open(RSTRING(str)->ptr, "r");
result = read_all(port);
io_close(port);
@@ -1719,8 +1848,7 @@ f_select(argc, argv, obj)
static VALUE
io_ctl(io, req, arg, io_p)
- VALUE io, req;
- struct RString *arg;
+ VALUE io, req, arg;
int io_p;
{
#if !defined(MSDOS) && !defined(__human68k__)
@@ -1757,12 +1885,14 @@ io_ctl(io, req, arg, io_p)
#endif
str_modify(arg);
- if (len < arg->len) {
- len = arg->len;
+ if (len <= RSTRING(arg)->len) {
+ len = RSTRING(arg)->len;
}
- str_resize(arg, len+1);
- arg->ptr[len] = 17; /* a little sanity check here */
- narg = (long)arg->ptr;
+ if (RSTRING(arg)->len < len) {
+ str_resize(arg, len+1);
+ }
+ RSTRING(arg)->ptr[len] = 17; /* a little sanity check here */
+ narg = (long)RSTRING(arg)->ptr;
}
fd = fileno(fptr->f);
#ifdef HAVE_FCNTL
@@ -1774,7 +1904,7 @@ io_ctl(io, req, arg, io_p)
retval = ioctl(fd, cmd, narg);
#endif
if (retval < 0) rb_sys_fail(fptr->path);
- if (TYPE(arg) == T_STRING && arg->ptr[len] != 17) {
+ if (TYPE(arg) == T_STRING && RSTRING(arg)->ptr[len] != 17) {
ArgError("return value overflowed string");
}
return INT2NUM(retval);
@@ -1957,14 +2087,14 @@ io_s_foreach(argc, argv, io)
VALUE *argv;
VALUE io;
{
- struct RString *fname;
+ VALUE fname;
struct foreach_arg arg;
rb_scan_args(argc, argv, "11", &fname, &arg.sep);
Check_SafeStr(fname);
arg.argc = argc - 1;
- arg.io = io_open(fname->ptr, "r");
+ arg.io = io_open(RSTRING(fname)->ptr, "r");
return rb_ensure(io_foreach_line, &arg, io_close, arg.io);
}
@@ -1988,14 +2118,14 @@ io_s_readlines(argc, argv, io)
VALUE *argv;
VALUE io;
{
- struct RString *fname;
+ VALUE fname;
struct foreach_arg arg;
rb_scan_args(argc, argv, "11", &fname, &arg.sep);
Check_SafeStr(fname);
arg.argc = argc - 1;
- arg.io = io_open(fname->ptr, "r");
+ arg.io = io_open(RSTRING(fname)->ptr, "r");
return rb_ensure(io_readline_line, &arg, io_close, arg.io);
}
@@ -2139,22 +2269,20 @@ opt_i_get()
static void
opt_i_set(val)
- struct RString *val;
+ VALUE val;
{
if (NIL_P(val)) {
inplace = 0;
return;
}
Check_Type(val, T_STRING);
- inplace = val->ptr;
+ inplace = RSTRING(val)->ptr;
}
-extern VALUE mEnumerable;
-
void
Init_IO()
{
- extern VALUE mKernel;
+ extern VALUE mEnumerable;
extern VALUE eException;
eEOFError = rb_define_class("EOFError", eException);
@@ -2166,6 +2294,7 @@ Init_IO()
rb_define_global_function("open", f_open, -1);
rb_define_global_function("printf", f_printf, -1);
rb_define_global_function("print", f_print, -1);
+ rb_define_global_function("puts", f_puts, -1);
rb_define_global_function("gets", f_gets_method, -1);
rb_define_global_function("readline", f_readline, -1);
rb_define_global_function("eof", f_eof, 0);
@@ -2209,6 +2338,7 @@ Init_IO()
rb_define_method(cIO, "reopen", io_reopen, 1);
rb_define_method(cIO, "print", io_print, -1);
+ rb_define_method(cIO, "puts", io_puts, -1);
rb_define_method(cIO, "printf", io_printf, -1);
rb_define_method(cIO, "each", io_each_line, -1);
@@ -2233,8 +2363,7 @@ Init_IO()
rb_define_method(cIO, "getc", io_getc, 0);
rb_define_method(cIO, "readchar", io_readchar, 0);
rb_define_method(cIO, "ungetc",io_ungetc, 1);
- rb_define_method(cIO, "puts", io_puts, 1);
- rb_define_method(cIO, "<<", io_puts, 1);
+ rb_define_method(cIO, "<<", io_addstr, 1);
rb_define_method(cIO, "flush", io_flush, 0);
rb_define_method(cIO, "eof", io_eof, 0);
rb_define_method(cIO, "eof?", io_eof, 0);
@@ -2254,7 +2383,7 @@ Init_IO()
rb_stdout = prep_stdio(stdout, FMODE_WRITABLE);
rb_define_readonly_variable("$stdout", &rb_stdout);
rb_stderr = prep_stdio(stderr, FMODE_WRITABLE);
- rb_define_readonly_variable("$stderr", &rb_stderr);
+ rb_define_hooked_variable("$stderr", &rb_stderr, 0, io_errset);
rb_defout = rb_stdout;
rb_define_hooked_variable("$>", &rb_defout, 0, io_defset);
diff --git a/io.h b/io.h
index cc87677..c671fca 100644
--- a/io.h
+++ b/io.h
@@ -48,6 +48,11 @@ typedef struct OpenFile {
#define GetWriteFile(fptr) (((fptr)->f2) ? (fptr)->f2 : (fptr)->f)
-FILE *rb_fopen();
+FILE *rb_fopen _((char *, char *));
+FILE *rb_fdopen _((int, char *));
+void io_writable _((OpenFile *));
+void io_readable _((OpenFile *));
+void io_fptr_finalize _((OpenFile *));
+void io_unbuffered _((OpenFile *));
#endif
diff --git a/lib/cgi-lib.rb b/lib/cgi-lib.rb
index afadbff..5234e04 100644
--- a/lib/cgi-lib.rb
+++ b/lib/cgi-lib.rb
@@ -9,29 +9,59 @@
# foo.keys <== array of fields
# foo.inputs <== hash of { <field> => <value> }
+# if running on Windows(IIS or PWS) then change cwd.
+if ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/ then
+ Dir.chdir ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, '')
+end
+
+require "shellwords.rb"
+
class CGI
+ include Shellwords
+
attr("inputs")
+
+ # original is CGI.pm
+ def read_from_cmdline
+ words = shellwords(if not ARGV.empty? then
+ ARGV.join(' ')
+ else
+ print "(offline mode: enter name=value pairs on standard input)\n"
+ readlines.join(' ').gsub(/\n/, '')
+ end.gsub(/\\=/, '%3D').gsub(/\\&/, '%26'))
+
+ if words.find{|x| x =~ /=/} then words.join('&') else words.join('+') end
+ end
+ # escape url encode
+ def escape(str)
+ str.gsub!(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) }
+ str
+ end
+
+ # unescape url encoded
+ def unescape(str)
+ str.gsub! /\+/, ' '
+ str.gsub!(/%([0-9a-fA-F]{2})/){ [$1.hex].pack("c") }
+ str
+ end
+ module_function :escape, :unescape
+
def initialize
- str = if ENV['REQUEST_METHOD'] == "GET"
- ENV['QUERY_STRING']
- elsif ENV['REQUEST_METHOD'] == "POST"
- $stdin.read ENV['CONTENT_LENGTH'].to_i
- else
- ""
- end
- arr = str.split(/&/)
+ # exception messages should be printed to stdout.
+ STDERR.reopen(STDOUT)
+
@inputs = {}
- arr.each do |x|
- x.gsub!(/\+/, ' ')
- key, val = x.split(/=/, 2)
- val = "" unless val
-
- key.gsub!(/%(..)/) { [$1.hex].pack("c") }
- val.gsub!(/%(..)/) { [$1.hex].pack("c") }
-
- @inputs[key] += "\0" if @inputs[key]
- @inputs[key] += val
+ case ENV['REQUEST_METHOD']
+ when "GET"
+ ENV['QUERY_STRING'] or ""
+ when "POST"
+ $stdin.read ENV['CONTENT_LENGTH'].to_i
+ else
+ read_from_cmdline
+ end.split(/&/).each do |x|
+ key, val = x.split(/=/,2).collect{|x|unescape(x)}
+ @inputs[key] += ("\0" if @inputs[key]) + (val or "")
end
end
@@ -53,4 +83,15 @@ class CGI
TRUE
end
+ def CGI.error
+ m = $!.dup
+ m.gsub!(/&/, '&amp;')
+ m.gsub!(/</, '&lt;')
+ m.gsub!(/>/, '&gt;')
+ msgs = ["<pre>ERROR: <strong>#{m}</strong>"]
+ msgs << $@
+ msgs << "</pre>"
+ CGI.message(msgs.join("\n"), "ERROR")
+ exit
+ end
end
diff --git a/lib/finalize.rb b/lib/finalize.rb
index e934753..9b2ffef 100644
--- a/lib/finalize.rb
+++ b/lib/finalize.rb
@@ -1,9 +1,9 @@
#
-# finalize.rb -
-# $Release Version: $
-# $Revision: 1.2 $
-# $Date: 1997/07/25 02:43:00 $
-# by Keiju ISHITSUKA(SHL Japan Inc.)
+# finalizer.rb -
+# $Release Version: 0.2$
+# $Revision: 1.3 $
+# $Date: 1998/01/09 08:09:49 $
+# by Keiju ISHITSUKA
#
# --
#
@@ -44,14 +44,14 @@
#
module Finalizer
- RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/finalize.rb,v 1.2 1997/07/25 02:43:00 keiju Exp keiju $-'
+ RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/finalize.rb,v 1.3 1998/01/09 08:09:49 keiju Exp keiju $-'
# @dependency: {id => [[dependant, method, *opt], ...], ...}
# 依存関係 R_method(obj, dependant) の追加
def add_dependency(obj, dependant, method = :finalize, *opt)
ObjectSpace.call_finalizer(obj)
- method = method.id unless method.kind_of?(Fixnum)
+ method = method.intern unless method.kind_of?(Integer)
assoc = [dependant, method].concat(opt)
if dep = @dependency[obj.id]
dep.push assoc
@@ -63,8 +63,8 @@ module Finalizer
# 依存関係 R_method(obj, dependant) の削除
def delete_dependency(id, dependant, method = :finalize)
- id = id.id unless id.kind_of?(Fixnum)
- method = method.id unless method.kind_of?(Fixnum)
+ id = id.id unless id.kind_of?(Integer)
+ method = method.intern unless method.kind_of?(Integer)
for assoc in @dependency[id]
assoc.delete_if do
|d, m, *o|
@@ -77,8 +77,8 @@ module Finalizer
# 依存関係 R_*(obj, dependant) の削除
def delete_all_dependency(id, dependant)
- id = id.id unless id.kind_of?(Fixnum)
- method = method.id unless method.kind_of?(Fixnum)
+ id = id.id unless id.kind_of?(Integer)
+ method = method.intern unless method.kind_of?(Integer)
for assoc in @dependency[id]
assoc.delete_if do
|d, m, *o|
@@ -90,8 +90,8 @@ module Finalizer
# 依存関係 R_method(*, dependant) の削除
def delete_by_dependant(dependant, method = :finalize)
- method = method.id unless method.kind_of?(Fixnum)
- for id in @dependency.keys
+ method = method.intern unless method.kind_of?(Integer)
+ for id in Dependency.keys
delete(id, dependant, method)
end
end
@@ -106,8 +106,8 @@ module Finalizer
# 依存関連 R_method(obj, dependtant) で結ばれるdependantをfinalizeす
# る.
def finalize_dependency(id, dependant, method = :finalize)
- id = id.id unless id.kind_of?(Fixnum)
- method = method.id unless method.kind_of?(Fixnum)
+ id = id.id unless id.kind_of?(Integer)
+ method = method.intern unless method.kind_of?(Integer)
for assocs in @dependency[id]
assocs.delete_if do
|d, m, *o|
@@ -121,8 +121,8 @@ module Finalizer
# 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする.
def finalize_all_dependency(id, dependant)
- id = id.id unless id.kind_of?(Fixnum)
- method = method.id unless method.kind_of?(Fixnum)
+ id = id.id unless id.kind_of?(Integer)
+ method = method.intern unless method.kind_of?(Integer)
for assoc in @dependency[id]
assoc.delete_if do
|d, m, *o|
@@ -134,7 +134,7 @@ module Finalizer
# 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする.
def finalize_by_dependant(dependant, method = :finalize)
- method = method.id unless method.kind_of?(Fixnum)
+ method = method.intern unless method.kind_of?(Integer)
for id in @dependency.keys
finalize(id, dependant, method)
end
diff --git a/lib/mailread.rb b/lib/mailread.rb
index d9feffb..a5d60c8 100644
--- a/lib/mailread.rb
+++ b/lib/mailread.rb
@@ -1,36 +1,35 @@
class Mail
- def Mail.new(f)
+
+ def initialize(f)
unless f.kind_of?(IO)
f = open(f, "r")
- me = super(f)
- f.close
- else
- me = super
+ opened = true
end
- return me
- end
- def initialize(f)
@header = {}
@body = []
- while f.gets()
- $_.chop!
- next if /^From / # skip From-line
- break if /^$/ # end of header
+ begin
+ while f.gets()
+ $_.chop!
+ next if /^From / # skip From-line
+ break if /^$/ # end of header
- if /^(\S+):\s*(.*)/
- @header[attr = $1.capitalize!] = $2
- elsif attr
- sub!(/^\s*/, '')
- @header[attr] += "\n" + $_
+ if /^(\S+):\s*(.*)/
+ @header[attr = $1.capitalize!] = $2
+ elsif attr
+ sub!(/^\s*/, '')
+ @header[attr] += "\n" + $_
+ end
end
- end
- return unless $_
+ return unless $_
- while f.gets()
- break if /^From /
- @body.push($_)
+ while f.gets()
+ break if /^From /
+ @body.push($_)
+ end
+ ensure
+ f.close if opened
end
end
diff --git a/lib/sync.rb b/lib/sync.rb
index 3e57ed0..b5a3fc3 100644
--- a/lib/sync.rb
+++ b/lib/sync.rb
@@ -1,13 +1,19 @@
#
# sync.rb - カウント付2-フェーズロッククラス
-# $Release Version: 0.1$
+# $Release Version: 0.2$
# $Revision$
# $Date$
# by Keiju ISHITSUKA
#
# --
+# Sync_m, Synchronizer_m
# Usage:
-# Sync_m, Synchronizer_m
+# obj.extend(Sync_m)
+# or
+# class Foo
+# Sync_m.include_to self
+# :
+# end
#
# Sync_m#sync_mode
# Sync_m#sync_locked?, locked?
@@ -19,8 +25,9 @@
#
# Sync, Synchronicer:
# include Sync_m
-#
+# Usage:
# sync = Sync.new
+#
# Sync#mode
# Sync#locked?
# Sync#shared?
@@ -36,15 +43,17 @@ unless defined? Thread
fail "Thread not available for this ruby interpreter"
end
-require "finalize.rb"
+require "finalize"
module Sync_m
RCS_ID='-$Header$-'
+ # lock mode
UN = :UN
SH = :SH
EX = :EX
+ # 例外定義
class Err < Exception
def Err.Fail(*opt)
fail self, sprintf(self::Message, *opt)
@@ -68,21 +77,53 @@ module Sync_m
end
end
- def Sync_m.extend_object(obj)
+ # include and extend initialize methods.
+ def Sync_m.extendable_module(obj)
if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj
raise TypeError, "Sync_m can't extend to this class(#{obj.type})"
else
begin
- eval "class << obj
- @sync_locked
- end"
- obj.extend(For_primitive_object)
+ obj.instance_eval "@sync_locked"
+ For_general_object
rescue TypeError
- obj.extend(For_general_object)
+ For_primitive_object
end
end
end
+ def Sync_m.includable_module(cl)
+ begin
+ dummy = cl.new
+ Sync_m.extendable_module(dummy)
+ rescue NameError
+ # newが定義されていない時は, DATAとみなす.
+ For_primitive_object
+ end
+ end
+
+ def Sync_m.extend_class(cl)
+ return super if cl.instance_of?(Module)
+
+ # モジュールの時は何もしない. クラスの場合, 適切なモジュールの決定
+ # とaliasを行う.
+ real = includable_module(cl)
+ cl.module_eval %q{
+ include real
+
+ alias locked? sync_locked?
+ alias shared? sync_shared?
+ alias exclusive? sync_exclusive?
+ alias lock sync_lock
+ alias unlock sync_unlock
+ alias try_lock sync_try_lock
+ alias synchronize sync_synchronize
+ }
+ end
+
+ def Sync_m.extend_object(obj)
+ obj.extend(Sync_m.extendable_module(obj))
+ end
+
def sync_extended
unless (defined? locked? and
defined? shared? and
@@ -94,7 +135,7 @@ module Sync_m
eval "class << self
alias locked? sync_locked?
alias shared? sync_shared?
- alias excluive? sync_exclusive?
+ alias exclusive? sync_exclusive?
alias lock sync_lock
alias unlock sync_unlock
alias try_lock sync_try_lock
@@ -103,6 +144,7 @@ module Sync_m
end
end
+ # accessing
def sync_locked?
sync_mode != UN
end
@@ -115,6 +157,7 @@ module Sync_m
sync_mode == EX
end
+ # locking methods.
def sync_try_lock(mode = EX)
return unlock if sync_mode == UN
@@ -238,7 +281,6 @@ module Sync_m
self.sync_ex_locker = Thread.current
self.sync_ex_count = 1
ret = TRUE
-
elsif sync_mode == EX && sync_ex_locker == Thread.current
self.sync_ex_count = sync_ex_count + 1
ret = TRUE
@@ -262,6 +304,7 @@ module Sync_m
end
end
+ # internal class
module For_primitive_object
include Sync_m
@@ -281,12 +324,18 @@ module Sync_m
Finalizer.add(obj, For_primitive_object, :sync_finalize)
end
- def sync_extended
+ def initialize
super
Sync_Locked[id] = LockState.new(UN, [], [], Hash.new, nil, 0 )
+ self
+ end
+
+ def sync_extended
+ super
+ initialize
end
- def sync_finalize
+ def For_primitive_object.sync_finalize(id)
wait = Sync_Locked.delete(id)
# waiting == [] ときだけ GCされるので, 待ち行列の解放は意味がない.
end
@@ -343,7 +392,7 @@ module Sync_m
obj.sync_extended
end
- def sync_extended
+ def initialize
super
@sync_mode = UN
@sync_waiting = []
@@ -351,6 +400,12 @@ module Sync_m
@sync_sh_locker = Hash.new
@sync_ex_locker = nil
@sync_ex_count = 0
+ self
+ end
+
+ def sync_extended
+ super
+ initialize
end
attr :sync_mode, TRUE
@@ -366,10 +421,11 @@ end
Synchronizer_m = Sync_m
class Sync
- include Sync_m::For_general_object
+ Sync_m.extend_class self
+ #include Sync_m
def initialize
- sync_extended
+ super
end
end
diff --git a/lib/tk.rb b/lib/tk.rb
index df68874..2cbbec0 100644
--- a/lib/tk.rb
+++ b/lib/tk.rb
@@ -1,12 +1,483 @@
#
-# tk.rb - Tk interface for ruby
+# tk.rb - Tk interface modue using tcltklib
# $Date$
-# by Yukihiro Matsumoto <matz@caelum.co.jp>
+# by Yukihiro Matsumoto <matz@netlab.co.jp>
-if defined? Thread and $tk_thread_safe
- require "tkthcore"
-else
- require "tkcore"
+# use Shigehiro's tcltklib
+require "tcltklib"
+require "tkutil"
+
+module TkComm
+ None = Object.new
+ def None.to_s
+ 'None'
+ end
+
+ Tk_CMDTBL = {}
+ Tk_WINDOWS = {}
+
+ def error_at
+ frames = caller(1)
+ frames.delete_if do |c|
+ c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+!
+ end
+ frames
+ end
+ private :error_at
+
+ def tk_tcl2ruby(val)
+ case val
+ when /^-?\d+$/
+ val.to_i
+ when /^\./
+ Tk_WINDOWS[val]
+ when /^rb_out (c\d+)/
+ Tk_CMDTBL[$1]
+ when / /
+ val.split.collect{|elt|
+ tk_tcl2ruby(elt)
+ }
+ when /^-?\d+\.\d*$/
+ val.to_f
+ else
+ val
+ end
+ end
+
+ def tk_split_list(str)
+ idx = str.index('{')
+ return tk_tcl2ruby(str) if not idx
+
+ list = tk_tcl2ruby(str[0,idx])
+ str = str[idx+1..-1]
+ i = -1
+ brace = 1
+ str.each_byte {|c|
+ i += 1
+ brace += 1 if c == ?{
+ brace -= 1 if c == ?}
+ break if brace == 0
+ }
+ if str[0, i] == ' '
+ list.push ' '
+ else
+ list.push tk_split_list(str[0, i])
+ end
+ list += tk_split_list(str[i+1..-1])
+ list
+ end
+ private :tk_tcl2ruby, :tk_split_list
+
+ def hash_kv(keys)
+ conf = []
+ if keys and keys != None
+ for k, v in keys
+ conf.push("-#{k}")
+ v = install_cmd(v) if v.kind_of? Proc
+ conf.push(v)
+ end
+ end
+ conf
+ end
+ private :hash_kv
+
+ def bool(val)
+ case val
+ when "1", 1, 'yes', 'true'
+ TRUE
+ else
+ FALSE
+ end
+ end
+ def number(val)
+ case val
+ when /^-?\d+$/
+ val.to_i
+ when /^-?\d+\.\d*$/
+ val.to_f
+ else
+ val
+ end
+ end
+ def string(val)
+ if val == "{}"
+ ''
+ elsif val[0] == ?{
+ val[1..-2]
+ else
+ val
+ end
+ end
+ def list(val)
+ tk_split_list(val)
+ end
+ def window(val)
+ Tk_WINDOWS[val]
+ end
+ def procedure(val)
+ if val =~ /^rb_out (c\d+)/
+ Tk_CMDTBL[$1]
+ else
+ nil
+ end
+ end
+ private :bool, :number, :string, :list, :window, :procedure
+
+ Tk_IDs = [0] # [0]-cmdid, [1]-winid
+ def _curr_cmd_id
+ id = format("c%.4d", Tk_IDs[0])
+ end
+ def _next_cmd_id
+ id = _curr_cmd_id
+ Tk_IDs[0] += 1
+ end
+ def install_cmd(cmd)
+ return '' if cmd == ''
+ id = _next_cmd_id
+ Tk_CMDTBL[id] = cmd
+ @cmdtbl = [] if not @cmdtbl
+ @cmdtbl.push id
+ return format("rb_out %s", id);
+ end
+ def uninstall_cmd(id)
+ Tk_CMDTBL[id] = nil
+ end
+ private :install_cmd, :uninstall_cmd
+
+ def install_win(ppath)
+ id = format("w%.4d", Tk_IDs[0])
+ Tk_IDs[0] += 1
+ if !ppath or ppath == "."
+ @path = format(".%s", id);
+ else
+ @path = format("%s.%s", ppath, id)
+ end
+ Tk_WINDOWS[@path] = self
+ end
+
+ def uninstall_win()
+ Tk_WINDOWS[@path] = nil
+ end
+
+ class Event
+ def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy)
+ @serial = seq
+ @num = b
+ @focus = (f == 1)
+ @height = h
+ @keycode = k
+ @state = s
+ @time = t
+ @width = w
+ @x = x
+ @y = y
+ @char = aa
+ @send_event = (ee == 1)
+ @keysym = kk
+ @keysym_num = nn
+ @type = tt
+ @widget = ww
+ @x_root = xx
+ @y_root = yy
+ end
+ attr :serial
+ attr :num
+ attr :focus
+ attr :height
+ attr :keycode
+ attr :state
+ attr :time
+ attr :width
+ attr :x
+ attr :y
+ attr :char
+ attr :send_event
+ attr :keysym
+ attr :keysym_num
+ attr :type
+ attr :widget
+ attr :x_root
+ attr :y_root
+ end
+
+ def install_bind(cmd, args=nil)
+ if args
+ id = install_cmd(proc{|arg|
+ TkUtil.eval_cmd cmd, *arg
+ })
+ id + " " + args
+ else
+ id = install_cmd(proc{|arg|
+ TkUtil.eval_cmd cmd, Event.new(*arg)
+ })
+ id + ' %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y'
+ end
+ end
+
+ def _bind(path, context, cmd, args=nil)
+ begin
+ id = install_bind(cmd, args)
+ tk_call 'bind', path, "<#{context}>", id
+ rescue
+ uninstall_cmd(id)
+ fail
+ end
+ end
+ private :install_bind, :_bind
+
+ def bind_all(context, cmd=Proc.new, args=nil)
+ _bind 'all', context, cmd, args
+ end
+
+ def pack(*args)
+ TkPack.configure *args
+ end
+
+ def after(ms, cmd=Proc.new)
+ myid = _curr_cmd_id
+ tk_call 'after', ms,
+ install_cmd(proc{
+ TkUtil.eval_cmd cmd
+ uninstall_cmd myid
+ })
+ end
+end
+
+module TkCore
+ include TkComm
+ extend TkComm
+
+ INTERP = TclTkIp.new
+ INTERP._eval("proc rb_out {args} { ruby [format \"TkCore.callback %%Q!%s!\" $args] }")
+
+ def TkCore.callback(arg)
+ arg = Array(tk_split_list(arg))
+ TkUtil.eval_cmd Tk_CMDTBL[arg.shift], *arg
+ end
+
+ def mainloop
+ TclTkLib.mainloop
+ end
+
+ def _get_eval_string(*args)
+ argstr = ""
+ args.each{|arg|
+ next if arg == None
+ if arg.kind_of?(Hash)
+ str = hash_kv(arg).join(" ")
+ elsif arg == nil
+ str = ""
+ elsif arg == false
+ str = "0"
+ elsif arg == true
+ str = "1"
+ elsif (arg.respond_to?(:to_eval))
+ str = arg.to_eval()
+ else
+ str = arg.to_s()
+ end
+ argstr += " " if argstr != ""
+ argstr += '"' + str.gsub(/[][$"]/, '\\\\\&') + '"'
+ }
+ return argstr
+ end
+
+ def tk_call(*args)
+ argstr = _get_eval_string(*args)
+
+ res = INTERP._eval(argstr)
+ if INTERP._return_value() != 0
+ fail RuntimeError, res, error_at
+ end
+ return res
+ end
+end
+
+module Tk
+ include TkCore
+ extend Tk
+
+ def root
+ TkRoot.new
+ end
+
+ def bell
+ tk_call 'bell'
+ end
+
+ def mainloop
+ TclTkLib.mainloop
+ end
+
+ module Scrollable
+ def xscrollcommand(cmd=Proc.new)
+ configure_cmd 'xscrollcommand', cmd
+ end
+ def yscrollcommand(cmd=Proc.new)
+ configure_cmd 'yscrollcommand', cmd
+ end
+ end
+
+ module Wm
+ def aspect(*args)
+ w = window(tk_call('wm', 'grid', path, *args))
+ w.split.collect{|s|s.to_i} if args.length == 0
+ end
+ def client(name=None)
+ tk_call 'wm', 'client', path, name
+ end
+ def colormapwindows(*args)
+ list(tk_call('wm', 'colormapwindows', path, *args))
+ end
+ def wm_command(value=None)
+ string(tk_call('wm', 'command', path, value))
+ end
+ def deiconify
+ tk_call 'wm', 'deiconify', path
+ end
+ def focusmodel(*args)
+ tk_call 'wm', 'focusmodel', path, *args
+ end
+ def frame
+ tk_call 'wm', 'frame', path
+ end
+ def geometry(*args)
+ list(tk_call('wm', 'geometry', path, *args))
+ end
+ def grid(*args)
+ w = tk_call('wm', 'grid', path, *args)
+ list(w) if args.size == 0
+ end
+ def group(*args)
+ tk_call 'wm', 'path', path, *args
+ end
+ def iconbitmap(*args)
+ tk_call 'wm', 'bitmap', path, *args
+ end
+ def iconify
+ tk_call 'wm', 'iconify'
+ end
+ def iconmask(*args)
+ tk_call 'wm', 'iconmask', path, *args
+ end
+ def iconname(*args)
+ tk_call 'wm', 'iconname', path, *args
+ end
+ def iconposition(*args)
+ w = tk_call('wm', 'iconposition', path, *args)
+ list(w) if args.size == 0
+ end
+ def iconwindow(*args)
+ tk_call 'wm', 'iconwindow', path, *args
+ end
+ def maxsize(*args)
+ w = tk_call('wm', 'maxsize', path, *args)
+ list(w) if not args.size == 0
+ end
+ def minsize(*args)
+ w = tk_call('wm', 'minsize', path, *args)
+ list(w) if args.size == 0
+ end
+ def overrideredirect(bool=None)
+ if bool == None
+ bool(tk_call('wm', 'overrideredirect', path))
+ else
+ tk_call 'wm', 'overrideredirect', path, bool
+ end
+ end
+ def positionfrom(*args)
+ tk_call 'wm', 'positionfrom', path, *args
+ end
+ def protocol(name, func=None)
+ func = install_cmd(func) if not func == None
+ tk_call 'wm', 'command', path, name, func
+ end
+ def resizable(*args)
+ w = tk_call('wm', 'resizable', path, *args)
+ if args.length == 0
+ list(w).collect{|e| bool(e)}
+ end
+ end
+ def sizefrom(*args)
+ list(tk_call('wm', 'sizefrom', path, *args))
+ end
+ def state
+ tk_call 'wm', 'state', path
+ end
+ def title(*args)
+ tk_call 'wm', 'title', path, *args
+ end
+ def transient(*args)
+ tk_call 'wm', 'transient', path, *args
+ end
+ def withdraw
+ tk_call 'wm', 'withdraw', path
+ end
+ end
+end
+
+class TkVariable
+ include Tk
+
+ Tk_VARIABLE_ID = ["v00000"]
+ def initialize(val="")
+ @id = Tk_VARIABLE_ID[0]
+ Tk_VARIABLE_ID[0] = Tk_VARIABLE_ID[0].succ
+ INTERP._eval(format('global %s; set %s %s', @id, @id, _get_eval_string(val)))
+ end
+
+ def id
+ @id
+ end
+
+ def value
+ INTERP._eval(format('global %s; set %s', @id, @id))
+ end
+
+ def value=(val)
+ INTERP._eval(format('global %s; set %s %s', @id, @id, _get_eval_string(val)))
+ end
+
+ def to_i
+ Integer(number(value))
+ end
+
+ def to_f
+ Float(number(value))
+ end
+
+ def to_s
+ String(string(value))
+ end
+
+ def inspect
+ format "<TkVariable: %s>", @id
+ end
+
+ def ==(other)
+ case other
+ when TkVariable
+ self.equal(self)
+ when String
+ self.to_s == other
+ when Integer
+ self.to_i == other
+ when Float
+ self.to_f == other
+ when Array
+ self.to_a == other
+ else
+ false
+ end
+ end
+
+ def to_a
+ list(value)
+ end
+
+ def to_eval
+ @id
+ end
end
module TkSelection
@@ -290,7 +761,7 @@ module TkPack
end
def propagate(master, bool=None)
- bool(tk_call('pack', 'propagate', mastaer.epath, bool))
+ bool(tk_call('pack', 'propagate', master.epath, bool))
end
module_function :configure, :forget, :propagate
end
@@ -324,6 +795,10 @@ class TkObject<TkKernel
return @path
end
+ def to_eval
+ @path
+ end
+
def tk_send(cmd, *rest)
tk_call path, cmd, *rest
end
@@ -372,60 +847,10 @@ class TkObject<TkKernel
end
end
-
-class TkVariable
- include Tk
- $tk_variable_id = "v00000"
- def initialize(val="")
- @id = $tk_variable_id
- $tk_variable_id = $tk_variable_id.succ
- tk_call(format('global %s; set %s', @id, @id), val)
- end
-
- def id
- @id
- end
-
- def value
- tk_call(format('global %s; set', @id), @id)
- end
-
- def value=(val)
- tk_call(format('global %s; set %s', @id, @id), val)
- end
-
- def to_i
- Integer(number(value))
- end
-
- def to_f
- Float(number(value))
- end
-
- def to_s
- String(string(value))
- end
-
- def inspect
- format "<TkVariable: %s>", @id
- end
-
- def to_a
- list(value)
- end
-end
-
class TkWindow<TkObject
- $tk_window_id = "w00000"
+
def initialize(parent=nil, keys=nil)
- id = $tk_window_id
- $tk_window_id = $tk_window_id.succ
- if !parent or parent == Tk.root
- @path = format(".%s", id);
- else
- @path = format("%s.%s", parent.path, id)
- end
- $tk_window_list[@path] = self
+ install_win(if parent then parent.path end)
create_self
if keys
tk_call @path, 'configure', *hash_kv(keys)
@@ -527,30 +952,32 @@ class TkWindow<TkObject
uninstall_cmd id
end
end
- $tk_window_list[path] = nil
- super
+ uninstall_win
end
end
class TkRoot<TkWindow
include Wm
+ ROOT = []
def TkRoot.new
- return $tk_root if $tk_root
- super
+ return ROOT[0] if ROOT[0]
+ new = super
+ ROOT[0] = new
+ end
+ def create_self
+ @path = '.'
end
def path
"."
end
- $tk_root = TkRoot.new
- $tk_window_list['.'] = $tk_root
end
class TkToplevel<TkWindow
include Wm
- def initialize(parent=nil, screen=nil, classname=nil)
+ def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
@screen = screen if screen
@classname = classname if classname
- super
+ super(parent, keys)
end
def create_self
@@ -661,7 +1088,7 @@ class TkScrollbar<TkWindow
ary1 = tk_send('get', path).split
ary2 = []
for i in ary1
- push number(i)
+ ary2.push number(i)
end
ary2
end
@@ -671,7 +1098,6 @@ class TkScrollbar<TkWindow
end
end
-# abstract class for Text and Listbox
class TkTextWin<TkWindow
def bbox(index)
tk_send 'bbox', index
@@ -682,9 +1108,6 @@ class TkTextWin<TkWindow
def get(*index)
tk_send 'get', *index
end
- def insert(index, *rest)
- tk_send 'insert', index, *rest
- end
def index(index)
tk_send 'index', index
end
@@ -793,8 +1216,10 @@ module TkComposite
private :initialize_composite
def delegate(option, *wins)
- @delegates = {} if not @delegates
- @delegates['DEFAULT'] = @frame
+ unless @delegates
+ @delegates = {}
+ @delegates['DEFAULT'] = @frame
+ end
if option.kind_of?(String)
@delegates[option] = wins
else
diff --git a/lib/tktext.rb b/lib/tktext.rb
index 2488f77..47e11f2 100644
--- a/lib/tktext.rb
+++ b/lib/tktext.rb
@@ -131,7 +131,7 @@ class TkTextMark<TkObject
@t = parent
@path = @id = $tk_text_mark
$tk_text_mark = $tk_text_mark.succ
- tk_call @t.path, 'set', @id, index
+ tk_call @t.path, 'mark', 'set', @id, index
@t._addtag id, self
end
def id
@@ -139,7 +139,7 @@ class TkTextMark<TkObject
end
def set(where)
- tk_call @t.path, 'mark', 'unset', @id, where
+ tk_call @t.path, 'mark', 'set', @id, where
end
def unset
diff --git a/math.c b/math.c
index 7b75a01..0e42703 100644
--- a/math.c
+++ b/math.c
@@ -14,16 +14,8 @@
#include <math.h>
VALUE mMath;
-VALUE float_new();
-VALUE f_float();
-
-#define Need_Float(x) \
-if (FIXNUM_P(x)) {\
- (x) = (struct RFloat*)float_new((double)FIX2INT(x));\
-} else {\
- (x) = (struct RFloat*)f_float(x, x);\
-}
+#define Need_Float(x) (x) = rb_Float(x)
#define Need_Float2(x,y) {\
Need_Float(x);\
Need_Float(y);\
@@ -31,79 +23,71 @@ if (FIXNUM_P(x)) {\
static VALUE
math_atan2(obj, x, y)
- VALUE obj;
- struct RFloat *x, *y;
+ VALUE obj, x, y;
{
Need_Float2(x, y);
- return float_new(atan2(x->value, y->value));
+ return float_new(atan2(RFLOAT(x)->value, RFLOAT(y)->value));
}
static VALUE
math_cos(obj, x)
- VALUE obj;
- struct RFloat *x;
+ VALUE obj, x;
{
Need_Float(x);
- return float_new(cos(x->value));
+ return float_new(cos(RFLOAT(x)->value));
}
static VALUE
math_sin(obj, x)
- VALUE obj;
- struct RFloat *x;
+ VALUE obj, x;
{
Need_Float(x);
- return float_new(sin(x->value));
+ return float_new(sin(RFLOAT(x)->value));
}
static VALUE
math_tan(obj, x)
- VALUE obj;
- struct RFloat *x;
+ VALUE obj, x;
{
Need_Float(x);
- return float_new(tan(x->value));
+ return float_new(tan(RFLOAT(x)->value));
}
static VALUE
math_exp(obj, x)
- VALUE obj;
- struct RFloat *x;
+ VALUE obj, x;
{
Need_Float(x);
- return float_new(exp(x->value));
+ return float_new(exp(RFLOAT(x)->value));
}
static VALUE
math_log(obj, x)
- VALUE obj;
- struct RFloat *x;
+ VALUE obj, x;
{
Need_Float(x);
- return float_new(log(x->value));
+ return float_new(log(RFLOAT(x)->value));
}
static VALUE
math_log10(obj, x)
- VALUE obj;
- struct RFloat *x;
+ VALUE obj, x;
{
Need_Float(x);
- return float_new(log10(x->value));
+ return float_new(log10(RFLOAT(x)->value));
}
static VALUE
math_sqrt(obj, x)
- VALUE obj;
- struct RFloat *x;
+ VALUE obj, x;
{
Need_Float(x);
- if (x->value < 0.0) ArgError("square root for negative number");
- return float_new(sqrt(x->value));
+ if (RFLOAT(x)->value < 0.0) ArgError("square root for negative number");
+ return float_new(sqrt(RFLOAT(x)->value));
}
void
diff --git a/missing/dir.h b/missing/dir.h
index 5c6281f..34be77b 100644
--- a/missing/dir.h
+++ b/missing/dir.h
@@ -183,66 +183,3 @@ void rewinddir(DIR *dirp);
void closedir(DIR *dirp);
#endif /* __DIR_INCLUDED */
-/* $RCSfile: dir.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:10 $
- *
- * (C) Copyright 1987, 1990 Diomidis Spinellis.
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Artistic License, as specified in the README file.
- *
- * $Log: dir.h,v $
- * Revision 4.0.1.1 91/06/07 11:22:10 lwall
- * patch4: new copyright notice
- *
- * Revision 4.0 91/03/20 01:34:20 lwall
- * 4.0 baseline.
- *
- * Revision 3.0.1.1 90/03/27 16:07:08 lwall
- * patch16: MSDOS support
- *
- * Revision 1.1 90/03/18 20:32:29 dds
- * Initial revision
- *
- *
- */
-
-/*
- * defines the type returned by the directory(3) functions
- */
-
-#ifndef __DIR_INCLUDED
-#define __DIR_INCLUDED
-
-/*Directory entry size */
-#ifdef DIRSIZ
-#undef DIRSIZ
-#endif
-#define DIRSIZ(rp) (sizeof(struct direct))
-
-/*
- * Structure of a directory entry
- */
-struct direct {
- ino_t d_ino; /* inode number (not used by MS-DOS) */
- int d_namlen; /* Name length */
- char d_name[256]; /* file name */
-};
-
-struct _dir_struc { /* Structure used by dir operations */
- char *start; /* Starting position */
- char *curr; /* Current position */
- long size; /* Size of string table */
- long nfiles; /* number if filenames in table */
- struct direct dirstr; /* Directory structure to return */
-};
-
-typedef struct _dir_struc DIR; /* Type returned by dir operations */
-
-DIR *cdecl opendir(char *filename);
-struct direct *readdir(DIR *dirp);
-long telldir(DIR *dirp);
-void seekdir(DIR *dirp,long loc);
-void rewinddir(DIR *dirp);
-void closedir(DIR *dirp);
-
-#endif /* __DIR_INCLUDED */
diff --git a/missing/nt.c b/missing/nt.c
index 1cd81fd..703556c 100644
--- a/missing/nt.c
+++ b/missing/nt.c
@@ -149,8 +149,8 @@ flock(int fd, int oper)
#undef LK_LEN
-#undef const
-FILE *fdopen(int, const char *);
+//#undef const
+//FILE *fdopen(int, const char *);
#if 0
void
@@ -185,7 +185,7 @@ NtInitialize(int *argc, char ***argv) {
tzset();
// Initialize Winsock
- // StartSockets();
+ StartSockets();
}
@@ -501,7 +501,6 @@ mypopen (char *cmd, char *mode)
return fp;
}
-
fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L);
if (!fRet)
Fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno));
@@ -1572,7 +1571,7 @@ valid_filename(char *s)
//
FILE *
-fdopen (int fd, const char *mode)
+myfdopen (int fd, const char *mode)
{
FILE *fp;
char sockbuf[80];
@@ -1580,6 +1579,8 @@ fdopen (int fd, const char *mode)
int retval;
extern int errno;
+ //fprintf(stderr, "myfdopen()\n");
+
retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
if (retval == SOCKET_ERROR) {
int iRet;
@@ -1951,8 +1952,10 @@ mysocket (int af, int type, int protocol)
if (!NtSocketsInitialized++) {
StartSockets();
}
- if ((s = socket (af, type, protocol)) == INVALID_SOCKET)
+ if ((s = socket (af, type, protocol)) == INVALID_SOCKET) {
errno = WSAGetLastError();
+ //fprintf(stderr, "socket fail (%d)", WSAGetLastError());
+ }
return s;
}
diff --git a/missing/nt.h b/missing/nt.h
index 5977a59..830b9ed 100644
--- a/missing/nt.h
+++ b/missing/nt.h
@@ -147,6 +147,29 @@ extern char *NtGetLib(void);
extern char *NtGetBin(void);
extern FILE *mypopen(char *, char *);
extern int flock(int fd, int oper);
+extern FILE * myfdopen(int, char*);
+extern SOCKET myaccept(SOCKET, struct sockaddr *, int *);
+extern int mybind(SOCKET, struct sockaddr *, int);
+extern int myconnect(SOCKET, struct sockaddr *, int);
+extern int mygetpeername(SOCKET, struct sockaddr *, int *);
+extern int mygetsockname(SOCKET, struct sockaddr *, int *);
+extern int mygetsockopt(SOCKET, int, int, char *, int *);
+extern int myioctlsocket(SOCKET, long, u_long *);
+extern int mylisten(SOCKET, int);
+extern int myrecv(SOCKET, char *, int, int);
+extern int myrecvfrom(SOCKET, char *, int, int, struct sockaddr *, int *);
+extern int mysend(SOCKET, char *, int, int);
+extern int mysendto(SOCKET, char *, int, int, struct sockaddr *, int);
+extern int mysetsockopt(SOCKET, int, int, char *, int);
+extern int myshutdown(SOCKET, int);
+extern SOCKET mysocket(int, int, int);
+extern struct hostent * mygethostbyaddr(char *, int, int);
+extern struct hostent * mygethostbyname(char *);
+extern int mygethostname(char *, int);
+extern struct protoent * mygetprotobyname(char *);
+extern struct protoent * mygetprotobynumber(int);
+extern struct servent * mygetservbyname(char *, char *);
+extern struct servent * mygetservbyport(int, char *);
//
// define this so we can do inplace editing
@@ -222,4 +245,118 @@ extern char *mystrerror(int);
#undef va_start
#undef va_end
+#ifdef fdopen
+#undef fdopen
+#endif
+#define fdopen myfdopen
+
+#ifdef accept
+#undef accept
+#endif
+#define accept myaccept
+
+#ifdef bind
+#undef bind
+#endif
+#define bind mybind
+
+#ifdef connect
+#undef connect
+#endif
+#define connect myconnect
+
+#ifdef getpeername
+#undef getpeername
+#endif
+#define getpeername mygetpeername
+
+#ifdef getsockname
+#undef getsockname
+#endif
+#define getsockname mygetsockname
+
+#ifdef getsockopt
+#undef getsockopt
+#endif
+#define getsockopt mygetsockopt
+
+#ifdef ioctlsocket
+#undef ioctlsocket
+#endif
+#define ioctlsocket myioctlsocket
+
+#ifdef listen
+#undef listen
+#endif
+#define listen mylisten
+
+#ifdef recv
+#undef recv
+#endif
+#define recv myrecv
+
+#ifdef recvfrom
+#undef recvfrom
+#endif
+#define recvfrom myrecvfrom
+
+#ifdef send
+#undef send
+#endif
+#define send mysend
+
+#ifdef sendto
+#undef sendto
+#endif
+#define sendto mysendto
+
+#ifdef setsockopt
+#undef setsockopt
+#endif
+#define setsockopt mysetsockopt
+
+#ifdef shutdown
+#undef shutdown
+#endif
+#define shutdown myshutdown
+
+#ifdef socket
+#undef socket
+#endif
+#define socket mysocket
+
+#ifdef gethostbyaddr
+#undef gethostbyaddr
+#endif
+#define gethostbyaddr mygethostbyaddr
+
+#ifdef gethostbyname
+#undef gethostbyname
+#endif
+#define gethostbyname mygethostbyname
+
+#ifdef gethostname
+#undef gethostname
+#endif
+#define gethostname mygethostname
+
+#ifdef getprotobyname
+#undef getprotobyname
+#endif
+#define getprotobyname mygetprotobyname
+
+#ifdef getprotobynumber
+#undef getprotobynumber
+#endif
+#define getprotobynumber mygetprotobynumber
+
+#ifdef getservbyname
+#undef getservbyname
+#endif
+#define getservbyname mygetservbyname
+
+#ifdef getservbyport
+#undef getservbyport
+#endif
+#define getservbyport mygetservbyport
#endif
diff --git a/missing/setenv.c b/missing/setenv.c
index b7b43a6..c9cb4b2 100644
--- a/missing/setenv.c
+++ b/missing/setenv.c
@@ -16,6 +16,10 @@ extern char **origenviron;
char *strdup();
#endif
+#ifdef USE_WIN32_RTL_ENV
+#include <stdlib.h>
+#endif
+
static int
envix(nam)
char *nam;
@@ -29,9 +33,11 @@ char *nam;
return i;
}
+#ifndef WIN32
void
-setenv(nam,val)
+setenv(nam,val, n)
char *nam, *val;
+int n;
{
register int i=envix(nam); /* where does it go? */
@@ -75,3 +81,69 @@ char *nam, *val;
(void)sprintf(environ[i] + strlen(nam),"=%s",val);
#endif /* MSDOS */
}
+#else /* if WIN32 */
+void
+setenv(nam,val, n)
+char *nam, *val;
+int n;
+{
+#ifdef USE_WIN32_RTL_ENV
+
+ register char *envstr;
+ STRLEN namlen = strlen(nam);
+ STRLEN vallen;
+ char *oldstr = environ[envix(nam)];
+
+ /* putenv() has totally broken semantics in both the Borland
+ * and Microsoft CRTLs. They either store the passed pointer in
+ * the environment without making a copy, or make a copy and don't
+ * free it. And on top of that, they dont free() old entries that
+ * are being replaced/deleted. This means the caller must
+ * free any old entries somehow, or we end up with a memory
+ * leak every time setenv() is called. One might think
+ * one could directly manipulate environ[], like the UNIX code
+ * above, but direct changes to environ are not allowed when
+ * calling putenv(), since the RTLs maintain an internal
+ * *copy* of environ[]. Bad, bad, *bad* stink.
+ * GSAR 97-06-07
+ */
+
+ if (!val) {
+ if (!oldstr)
+ return;
+ val = "";
+ vallen = 0;
+ }
+ else
+ vallen = strlen(val);
+ envstr = ALLOC_N(char, namelen + vallen + 3);
+ (void)sprintf(envstr,"%s=%s",nam,val);
+ (void)putenv(envstr);
+ if (oldstr)
+ free(oldstr);
+#ifdef _MSC_VER
+ free(envstr); /* MSVCRT leaks without this */
+#endif
+
+#else /* !USE_WIN32_RTL_ENV */
+
+ /* The sane way to deal with the environment.
+ * Has these advantages over putenv() & co.:
+ * * enables us to store a truly empty value in the
+ * environment (like in UNIX).
+ * * we don't have to deal with RTL globals, bugs and leaks.
+ * * Much faster.
+ * Why you may want to enable USE_WIN32_RTL_ENV:
+ * * environ[] and RTL functions will not reflect changes,
+ * which might be an issue if extensions want to access
+ * the env. via RTL. This cuts both ways, since RTL will
+ * not see changes made by extensions that call the Win32
+ * functions directly, either.
+ * GSAR 97-06-07
+ */
+ SetEnvironmentVariable(nam,val);
+
+#endif
+}
+
+#endif /* WIN32 */
diff --git a/node.h b/node.h
index db5824b..cdb354c 100644
--- a/node.h
+++ b/node.h
@@ -13,8 +13,6 @@
#ifndef NODE_H
#define NODE_H
-struct global_entry *rb_global_entry();
-
enum node_type {
NODE_METHOD,
NODE_FBODY,
@@ -29,6 +27,10 @@ enum node_type {
NODE_UNTIL,
NODE_ITER,
NODE_FOR,
+ NODE_BREAK,
+ NODE_NEXT,
+ NODE_REDO,
+ NODE_RETRY,
NODE_BEGIN,
NODE_RESCUE,
NODE_RESBODY,
@@ -64,6 +66,8 @@ enum node_type {
NODE_MATCH_REF,
NODE_LASTLINE,
NODE_MATCH,
+ NODE_MATCH2,
+ NODE_MATCH3,
NODE_LIT,
NODE_STR,
NODE_DSTR,
@@ -91,14 +95,17 @@ enum node_type {
NODE_ATTRSET,
NODE_SELF,
NODE_NIL,
+ NODE_TRUE,
+ NODE_FALSE,
NODE_DEFINED,
NODE_TAG,
NODE_NEWLINE,
+ NODE_POSTEXE,
};
typedef struct RNode {
UINT flags;
- char *file;
+ char *nd_file;
union {
struct RNode *node;
ID id;
@@ -185,7 +192,7 @@ typedef struct RNode {
#define nd_argc u2.argc
#define nd_cname u1.id
-#define nd_super u3.id
+#define nd_super u3.node
#define nd_modl u1.id
#define nd_clss u1.value
@@ -201,8 +208,6 @@ typedef struct RNode {
#define nd_tlev u3.cnt
#define nd_tval u2.value
-#define nd_file file
-
#define NEW_METHOD(n,x) node_newnode(NODE_METHOD,x,n,0)
#define NEW_FBODY(n,i,o) node_newnode(NODE_FBODY,n,i,o)
#define NEW_DEFN(i,a,d,p) node_newnode(NODE_DEFN,p,i,NEW_RFUNC(a,d))
@@ -220,6 +225,10 @@ typedef struct RNode {
#define NEW_UNTIL(c,b,n) node_newnode(NODE_UNTIL,c,b,n)
#define NEW_FOR(v,i,b) node_newnode(NODE_FOR,v,b,i)
#define NEW_ITER(v,i,b) node_newnode(NODE_ITER,v,b,i)
+#define NEW_BREAK() node_newnode(NODE_BREAK,0,0,0)
+#define NEW_NEXT() node_newnode(NODE_NEXT,0,0,0)
+#define NEW_REDO() node_newnode(NODE_REDO,0,0,0)
+#define NEW_RETRY() node_newnode(NODE_RETRY,0,0,0)
#define NEW_BEGIN(b) node_newnode(NODE_BEGIN,0,b,0)
#define NEW_RESCUE(b,res) node_newnode(NODE_RESCUE,b,res,0)
#define NEW_RESBODY(a,ex,n) node_newnode(NODE_RESBODY,n,ex,a)
@@ -248,6 +257,8 @@ typedef struct RNode {
#define NEW_NTH_REF(n) node_newnode(NODE_NTH_REF,0,n,local_cnt('~'))
#define NEW_BACK_REF(n) node_newnode(NODE_BACK_REF,0,n,local_cnt('~'))
#define NEW_MATCH(c) node_newnode(NODE_MATCH,c,0,0)
+#define NEW_MATCH2(n1,n2) node_newnode(NODE_MATCH2,n1,n2,0)
+#define NEW_MATCH3(r,n2) node_newnode(NODE_MATCH3,r,n2,0)
#define NEW_LIT(l) node_newnode(NODE_LIT,l,0,0)
#define NEW_STR(s) node_newnode(NODE_STR,s,0,0)
#define NEW_DSTR(s) node_newnode(NODE_DSTR,s,0,0)
@@ -275,8 +286,12 @@ typedef struct RNode {
#define NEW_ATTRSET(a) node_newnode(NODE_ATTRSET,a,0,0)
#define NEW_SELF() node_newnode(NODE_SELF,0,0,0)
#define NEW_NIL() node_newnode(NODE_NIL,0,0,0)
+#define NEW_TRUE() node_newnode(NODE_TRUE,0,0,0)
+#define NEW_FALSE() node_newnode(NODE_FALSE,0,0,0)
#define NEW_DEFINED(e) node_newnode(NODE_DEFINED,e,0,0)
#define NEW_NEWLINE(n) node_newnode(NODE_NEWLINE,0,0,n)
+#define NEW_PREEXE(b) NEW_SCOPE(b)
+#define NEW_POSTEXE() node_newnode(NODE_POSTEXE,0,0,0)
NODE *node_newnode();
VALUE rb_method_booundp();
@@ -284,7 +299,19 @@ VALUE rb_method_booundp();
#define NOEX_PUBLIC 0
#define NOEX_PRIVATE 1
-NODE *compile_string();
-NODE *compile_file();
+NODE *compile_string _((char *, char *, int));
+NODE *compile_file _((char *, VALUE, int));
+
+void rb_add_method _((VALUE, ID, NODE *, int));
+void rb_remove_method _((VALUE, ID));
+NODE *node_newnode();
+
+enum node_type nodetype _((NODE *));
+int nodeline _((NODE *));
+
+struct global_entry *rb_global_entry _((ID));
+VALUE rb_gvar_get _((struct global_entry *));
+VALUE rb_gvar_set _((struct global_entry *, VALUE));
+VALUE rb_gvar_defined _((struct global_entry *));
#endif
diff --git a/numeric.c b/numeric.c
index 242d13c..b0d5f7f 100644
--- a/numeric.c
+++ b/numeric.c
@@ -12,11 +12,6 @@
#include "ruby.h"
#include <math.h>
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else
-# include <strings.h>
-#endif
static ID coerce;
static ID to_i;
@@ -42,7 +37,7 @@ static VALUE
num_coerce(x, y)
VALUE x, y;
{
- return assoc_new(f_float(x,x),f_float(y,y));
+ return assoc_new(rb_Float(x),rb_Float(y));
}
VALUE
@@ -116,7 +111,7 @@ num_chr(num)
VALUE num;
{
char c;
- int i = NUM2INT(num);
+ INT i = NUM2INT(num);
if (i < 0 || 0xff < i)
Fail("%d out of char range", i);
@@ -147,11 +142,11 @@ float_new(d)
static VALUE
flo_to_s(flt)
- struct RFloat *flt;
+ VALUE flt;
{
char buf[32];
- sprintf(buf, "%g", flt->value);
+ sprintf(buf, "%g", RFLOAT(flt)->value);
if (strchr(buf, '.') == 0) {
int len = strlen(buf);
char *ind = strchr(buf, 'e');
@@ -172,27 +167,27 @@ static VALUE
flo_coerce(x, y)
VALUE x, y;
{
- return assoc_new(f_float(x, y), x);
+ return assoc_new(rb_Float(y), x);
}
static VALUE
flo_uminus(flt)
- struct RFloat *flt;
+ VALUE flt;
{
- return float_new(-flt->value);
+ return float_new(-RFLOAT(flt)->value);
}
static VALUE
flo_plus(x, y)
- struct RFloat *x, *y;
+ VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
- return float_new(x->value + (double)FIX2INT(y));
+ return float_new(RFLOAT(x)->value + (double)FIX2INT(y));
case T_BIGNUM:
- return float_new(x->value + big2dbl(y));
+ return float_new(RFLOAT(x)->value + big2dbl(y));
case T_FLOAT:
- return float_new(x->value + y->value);
+ return float_new(RFLOAT(x)->value + RFLOAT(y)->value);
case T_STRING:
return str_plus(obj_as_string(x), y);
default:
@@ -202,15 +197,15 @@ flo_plus(x, y)
static VALUE
flo_minus(x, y)
- struct RFloat *x, *y;
+ VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
- return float_new(x->value - (double)FIX2INT(y));
+ return float_new(RFLOAT(x)->value - (double)FIX2INT(y));
case T_BIGNUM:
- return float_new(x->value - big2dbl(y));
+ return float_new(RFLOAT(x)->value - big2dbl(y));
case T_FLOAT:
- return float_new(x->value - y->value);
+ return float_new(RFLOAT(x)->value - RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@@ -218,17 +213,17 @@ flo_minus(x, y)
static VALUE
flo_mul(x, y)
- struct RFloat *x, *y;
+ VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
- return float_new(x->value * (double)FIX2INT(y));
+ return float_new(RFLOAT(x)->value * (double)FIX2INT(y));
case T_BIGNUM:
- return float_new(x->value * big2dbl(y));
+ return float_new(RFLOAT(x)->value * big2dbl(y));
case T_FLOAT:
- return float_new(x->value * y->value);
+ return float_new(RFLOAT(x)->value * RFLOAT(y)->value);
case T_STRING:
- return str_times(y, INT2FIX((int)x->value));
+ return str_times(y, INT2FIX((int)RFLOAT(x)->value));
default:
return num_coerce_bin(x, y);
}
@@ -236,23 +231,23 @@ flo_mul(x, y)
static VALUE
flo_div(x, y)
- struct RFloat *x, *y;
+ VALUE x, y;
{
- int f_y;
+ INT f_y;
double d;
switch (TYPE(y)) {
case T_FIXNUM:
f_y = FIX2INT(y);
if (f_y == 0) num_zerodiv();
- return float_new(x->value / (double)f_y);
+ return float_new(RFLOAT(x)->value / (double)f_y);
case T_BIGNUM:
d = big2dbl(y);
if (d == 0.0) num_zerodiv();
- return float_new(x->value / d);
+ return float_new(RFLOAT(x)->value / d);
case T_FLOAT:
- if (y->value == 0.0) num_zerodiv();
- return float_new(x->value / y->value);
+ if (RFLOAT(y)->value == 0.0) num_zerodiv();
+ return float_new(RFLOAT(x)->value / RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@@ -260,7 +255,7 @@ flo_div(x, y)
static VALUE
flo_mod(x, y)
- struct RFloat *x, *y;
+ VALUE x, y;
{
double value;
@@ -272,16 +267,16 @@ flo_mod(x, y)
value = big2dbl(y);
break;
case T_FLOAT:
- value = y->value;
+ value = RFLOAT(y)->value;
break;
default:
return num_coerce_bin(x, y);
}
#ifdef HAVE_FMOD
- value = fmod(x->value, value);
+ value = fmod(RFLOAT(x)->value, value);
#else
{
- double value1 = x->value;
+ double value1 = RFLOAT(x)->value;
double value2;
modf(value1/value, &value2);
@@ -294,15 +289,15 @@ flo_mod(x, y)
VALUE
flo_pow(x, y)
- struct RFloat *x, *y;
+ VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
- return float_new(pow(x->value, (double)FIX2INT(y)));
+ return float_new(pow(RFLOAT(x)->value, (double)FIX2INT(y)));
case T_BIGNUM:
- return float_new(pow(x->value, big2dbl(y)));
+ return float_new(pow(RFLOAT(x)->value, big2dbl(y)));
case T_FLOAT:
- return float_new(pow(x->value, y->value));
+ return float_new(pow(RFLOAT(x)->value, RFLOAT(y)->value));
default:
return num_coerce_bin(x, y);
}
@@ -327,16 +322,16 @@ num_equal(x, y)
static VALUE
flo_eq(x, y)
- struct RFloat *x, *y;
+ VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
- if (x->value == FIX2INT(y)) return TRUE;
+ if (RFLOAT(x)->value == FIX2INT(y)) return TRUE;
return FALSE;
case T_BIGNUM:
- return (x->value == big2dbl(y))?TRUE:FALSE;
+ return (RFLOAT(x)->value == big2dbl(y))?TRUE:FALSE;
case T_FLOAT:
- return (x->value == y->value)?TRUE:FALSE;
+ return (RFLOAT(x)->value == RFLOAT(y)->value)?TRUE:FALSE;
default:
return num_equal(x, y);
}
@@ -344,13 +339,13 @@ flo_eq(x, y)
static VALUE
flo_hash(num)
- struct RFloat *num;
+ VALUE num;
{
double d;
char *c;
int i, hash;
- d = num->value;
+ d = RFLOAT(num)->value;
c = (char*)&d;
for (hash=0, i=0; i<sizeof(double);i++) {
hash += c[i] * 971;
@@ -361,11 +356,11 @@ flo_hash(num)
static VALUE
flo_cmp(x, y)
- struct RFloat *x, *y;
+ VALUE x, y;
{
double a, b;
- a = x->value;
+ a = RFLOAT(x)->value;
switch (TYPE(y)) {
case T_FIXNUM:
b = (double)FIX2INT(y);
@@ -376,7 +371,7 @@ flo_cmp(x, y)
break;
case T_FLOAT:
- b = y->value;
+ b = RFLOAT(y)->value;
break;
default:
@@ -389,19 +384,20 @@ flo_cmp(x, y)
static VALUE
flo_eql(x, y)
- struct RFloat *x, *y;
+ VALUE x, y;
{
if (TYPE(y) == T_FLOAT) {
- if (x->value == y->value) return TRUE;
+ if (RFLOAT(x)->value == RFLOAT(y)->value) return TRUE;
}
+ return FALSE;
}
static VALUE
flo_to_i(num)
- struct RFloat *num;
+ VALUE num;
{
- double f = num->value;
- int val;
+ double f = RFLOAT(num)->value;
+ INT val;
if (!FIXABLE(f)) {
return dbl2big(f);
@@ -419,9 +415,9 @@ flo_to_f(num)
static VALUE
flo_abs(flt)
- struct RFloat *flt;
+ VALUE flt;
{
- double val = fabs(flt->value);
+ double val = fabs(RFLOAT(flt)->value);
return float_new(val);
}
@@ -472,7 +468,7 @@ VALUE
num2fix(val)
VALUE val;
{
- int v;
+ INT v;
if (NIL_P(val)) return INT2FIX(0);
switch (TYPE(val)) {
@@ -515,12 +511,12 @@ fix2str(x, base)
VALUE x;
int base;
{
- char fmt[3], buf[12];
+ char fmt[4], buf[22];
- fmt[0] = '%'; fmt[2] = '\0';
- if (base == 10) fmt[1] = 'd';
- else if (base == 16) fmt[1] = 'x';
- else if (base == 8) fmt[1] = 'o';
+ fmt[0] = '%'; fmt[1] = 'l'; fmt[3] = '\0';
+ if (base == 10) fmt[2] = 'd';
+ else if (base == 16) fmt[2] = 'x';
+ else if (base == 8) fmt[2] = 'o';
else Fatal("fixnum cannot treat base %d", base);
sprintf(buf, fmt, FIX2INT(x));
@@ -536,13 +532,12 @@ fix_to_s(in)
static VALUE
fix_plus(x, y)
- VALUE x;
- struct RFloat *y;
+ VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
{
- int a, b, c;
+ INT a, b, c;
VALUE r;
a = FIX2INT(x);
@@ -556,7 +551,7 @@ fix_plus(x, y)
return r;
}
case T_FLOAT:
- return float_new((double)FIX2INT(x) + y->value);
+ return float_new((double)FIX2INT(x) + RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@@ -564,13 +559,12 @@ fix_plus(x, y)
static VALUE
fix_minus(x, y)
- VALUE x;
- struct RFloat *y;
+ VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
{
- int a, b, c;
+ INT a, b, c;
VALUE r;
a = FIX2INT(x);
@@ -584,7 +578,7 @@ fix_minus(x, y)
return r;
}
case T_FLOAT:
- return float_new((double)FIX2INT(x) - y->value);
+ return float_new((double)FIX2INT(x) - RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@@ -592,13 +586,12 @@ fix_minus(x, y)
static VALUE
fix_mul(x, y)
- VALUE x;
- struct RFloat *y;
+ VALUE x, y;
{
switch (TYPE(y)) {
case T_FIXNUM:
{
- int a, b, c;
+ INT a, b, c;
VALUE r;
a = FIX2INT(x);
@@ -614,7 +607,7 @@ fix_mul(x, y)
return r;
}
case T_FLOAT:
- return float_new((double)FIX2INT(x) * y->value);
+ return float_new((double)FIX2INT(x) * RFLOAT(y)->value);
default:
return num_coerce_bin(x, y);
}
@@ -622,10 +615,9 @@ fix_mul(x, y)
static VALUE
fix_div(x, y)
- VALUE x;
- struct RFloat *y;
+ VALUE x, y;
{
- int i;
+ INT i;
if (TYPE(y) == T_FIXNUM) {
i = FIX2INT(y);
@@ -640,7 +632,7 @@ static VALUE
fix_mod(x, y)
VALUE x, y;
{
- int i;
+ INT i;
if (TYPE(y) == T_FIXNUM) {
i = FIX2INT(y);
@@ -656,7 +648,7 @@ fix_pow(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
- int a, b;
+ INT a, b;
b = FIX2INT(y);
if (b == 0) return INT2FIX(1);
@@ -689,7 +681,7 @@ fix_cmp(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
- int a = FIX2INT(x), b = FIX2INT(y);
+ INT a = FIX2INT(x), b = FIX2INT(y);
if (a == b) return INT2FIX(0);
if (a > b) return INT2FIX(1);
@@ -705,7 +697,7 @@ fix_gt(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
- int a = FIX2INT(x), b = FIX2INT(y);
+ INT a = FIX2INT(x), b = FIX2INT(y);
if (a > b) return TRUE;
return FALSE;
@@ -720,7 +712,7 @@ fix_ge(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
- int a = FIX2INT(x), b = FIX2INT(y);
+ INT a = FIX2INT(x), b = FIX2INT(y);
if (a >= b) return TRUE;
return FALSE;
@@ -735,7 +727,7 @@ fix_lt(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
- int a = FIX2INT(x), b = FIX2INT(y);
+ INT a = FIX2INT(x), b = FIX2INT(y);
if (a < b) return TRUE;
return FALSE;
@@ -750,7 +742,7 @@ fix_le(x, y)
VALUE x, y;
{
if (FIXNUM_P(y)) {
- int a = FIX2INT(x), b = FIX2INT(y);
+ INT a = FIX2INT(x), b = FIX2INT(y);
if (a <= b) return TRUE;
return FALSE;
@@ -876,14 +868,14 @@ static VALUE
fix_type(fix)
VALUE fix;
{
- return str_new2("Fixnum");
+ return cFixnum;
}
static VALUE
fix_abs(fix)
VALUE fix;
{
- int i = FIX2INT(fix);
+ INT i = FIX2INT(fix);
if (i < 0) i = -i;
@@ -903,7 +895,7 @@ static VALUE
fix_succ(fix)
VALUE fix;
{
- int i = FIX2INT(fix) + 1;
+ INT i = FIX2INT(fix) + 1;
return int2inum(i);
}
@@ -912,7 +904,7 @@ static VALUE
fix_size(fix)
VALUE fix;
{
- return INT2FIX(sizeof(VALUE));
+ return INT2FIX(sizeof(INT));
}
VALUE
@@ -951,7 +943,7 @@ num_step(from, to, step)
ID cmp;
if (step == INT2FIX(0)) {
- IndexError("step cannot be 0");
+ ArgError("step cannot be 0");
}
if (RTEST(rb_funcall(step, '>', 1, INT2FIX(0)))) {
@@ -986,7 +978,7 @@ VALUE
fix_upto(from, to)
VALUE from, to;
{
- int i, end;
+ INT i, end;
if (!FIXNUM_P(to)) return num_upto(from, to);
end = FIX2INT(to);
@@ -1001,7 +993,7 @@ static VALUE
fix_downto(from, to)
VALUE from, to;
{
- int i, end;
+ INT i, end;
if (!FIXNUM_P(to)) return num_downto(from, to);
end = FIX2INT(to);
@@ -1016,7 +1008,7 @@ static VALUE
fix_step(from, to, step)
VALUE from, to, step;
{
- int i, end, diff;
+ INT i, end, diff;
if (!FIXNUM_P(to) || !FIXNUM_P(step))
return num_step(from, to, step);
@@ -1044,7 +1036,7 @@ static VALUE
fix_dotimes(num)
VALUE num;
{
- int i, end;
+ INT i, end;
end = FIX2INT(num);
for (i=0; i<end; i++) {
diff --git a/object.c b/object.c
index 6430440..2e614b3 100644
--- a/object.c
+++ b/object.c
@@ -18,7 +18,7 @@ VALUE mKernel;
VALUE cObject;
VALUE cModule;
VALUE cClass;
-VALUE cFixnum;
+extern VALUE cFixnum;
VALUE cData;
static VALUE cNilClass;
@@ -72,14 +72,19 @@ static VALUE
obj_id(obj)
VALUE obj;
{
- return obj | FIXNUM_FLAG;
+ return INT2NUM((int)obj);
}
static VALUE
obj_type(obj)
- struct RBasic *obj;
+ VALUE obj;
{
- return rb_class_path(CLASS_OF(obj));
+ VALUE cl = CLASS_OF(obj);
+
+ if (FL_TEST(cl, FL_SINGLETON)) {
+ cl = RCLASS(cl)->super;
+ }
+ return cl;
}
static VALUE
@@ -91,13 +96,13 @@ obj_clone(obj)
if (TYPE(obj) != T_OBJECT) {
TypeError("can't clone %s", rb_class2name(CLASS_OF(obj)));
}
-
clone = obj_alloc(RBASIC(obj)->class);
+ CLONESETUP(clone,obj);
if (ROBJECT(obj)->iv_tbl) {
ROBJECT(clone)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl);
- }
RBASIC(clone)->class = singleton_class_clone(RBASIC(obj)->class);
RBASIC(clone)->flags = RBASIC(obj)->flags;
+ }
return clone;
}
@@ -130,15 +135,15 @@ static int
inspect_i(id, value, str)
ID id;
VALUE value;
- struct RString *str;
+ VALUE str;
{
VALUE str2;
char *ivname;
/* need not to show internal data */
if (CLASS_OF(value) == 0) return ST_CONTINUE;
- if (str->ptr[0] == '-') {
- str->ptr[0] = '#';
+ if (RSTRING(str)->ptr[0] == '-') {
+ RSTRING(str)->ptr[0] = '#';
str_cat(str, ": ", 2);
}
else {
@@ -160,17 +165,18 @@ inspect_i(id, value, str)
static VALUE
obj_inspect(obj)
- struct RObject *obj;
+ VALUE obj;
{
if (TYPE(obj) == T_OBJECT
- && obj->iv_tbl && obj->iv_tbl->num_entries > 0) {
+ && ROBJECT(obj)->iv_tbl
+ && ROBJECT(obj)->iv_tbl->num_entries > 0) {
VALUE str;
char *b;
str = str_new2("-<");
b = rb_class2name(CLASS_OF(obj));
str_cat(str, b, strlen(b));
- st_foreach(obj->iv_tbl, inspect_i, str);
+ st_foreach(ROBJECT(obj)->iv_tbl, inspect_i, str);
str_cat(str, ">", 1);
return str;
@@ -182,7 +188,7 @@ VALUE
obj_is_instance_of(obj, c)
VALUE obj, c;
{
- struct RClass *class = (struct RClass*)CLASS_OF(obj);
+ VALUE cl;
switch (TYPE(c)) {
case T_MODULE:
@@ -205,10 +211,11 @@ obj_is_instance_of(obj, c)
TypeError("class or module required");
}
- while (FL_TEST(class, FL_SINGLETON)) {
- class = class->super;
+ cl = CLASS_OF(obj);
+ while (FL_TEST(cl, FL_SINGLETON)) {
+ cl = RCLASS(cl)->super;
}
- if (c == (VALUE)class) return TRUE;
+ if (c == cl) return TRUE;
return FALSE;
}
@@ -216,7 +223,7 @@ VALUE
obj_is_kind_of(obj, c)
VALUE obj, c;
{
- struct RClass *class = (struct RClass*)CLASS_OF(obj);
+ VALUE cl = CLASS_OF(obj);
switch (TYPE(c)) {
case T_MODULE:
@@ -239,33 +246,33 @@ obj_is_kind_of(obj, c)
TypeError("class or module required");
}
- while (class) {
- if ((VALUE)class == c || RCLASS(class)->m_tbl == RCLASS(c)->m_tbl)
+ while (cl) {
+ if (cl == c || RCLASS(cl)->m_tbl == RCLASS(c)->m_tbl)
return TRUE;
- class = class->super;
+ cl = RCLASS(cl)->super;
}
return FALSE;
}
static VALUE
-obj_initialize(obj)
+obj_dummy(obj)
VALUE obj;
{
return Qnil;
}
static VALUE
-obj_s_added(obj, id)
- VALUE obj, id;
+nil_to_s(obj)
+ VALUE obj;
{
- return Qnil;
+ return str_new2("");
}
static VALUE
-nil_to_s(obj)
+nil_to_a(obj)
VALUE obj;
{
- return str_new2("");
+ return ary_new2(0);
}
static VALUE
@@ -279,7 +286,7 @@ static VALUE
nil_type(obj)
VALUE obj;
{
- return str_new2("nil");
+ return cNilClass;
}
static VALUE
@@ -311,28 +318,28 @@ static VALUE
true_to_s(obj)
VALUE obj;
{
- return str_new2("TRUE");
+ return str_new2("true");
}
static VALUE
true_type(obj)
VALUE obj;
{
- return str_new2("TRUE");
+ return cTrueClass;
}
static VALUE
false_to_s(obj)
VALUE obj;
{
- return str_new2("FALSE");
+ return str_new2("false");
}
static VALUE
false_type(obj)
VALUE obj;
{
- return str_new2("FALSE");
+ return cFalseClass;
}
static VALUE
@@ -362,15 +369,15 @@ obj_alloc(class)
static VALUE
mod_clone(module)
- struct RClass *module;
+ VALUE module;
{
NEWOBJ(clone, struct RClass);
OBJSETUP(clone, CLASS_OF(module), TYPE(module));
- clone->super = module->super;
+ clone->super = RCLASS(module)->super;
clone->iv_tbl = 0;
clone->m_tbl = 0; /* avoid GC crashing */
- clone->m_tbl = st_copy(module->m_tbl);
+ clone->m_tbl = st_copy(RCLASS(module)->m_tbl);
return (VALUE)clone;
}
@@ -389,15 +396,89 @@ mod_eqq(mod, arg)
return obj_is_kind_of(arg, mod);
}
+static VALUE
+mod_le(mod, arg)
+ VALUE mod, arg;
+{
+ switch (TYPE(arg)) {
+ case T_MODULE:
+ case T_CLASS:
+ break;
+ default:
+ TypeError("compared with non class/module");
+ }
+
+ while (mod) {
+ if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl)
+ return TRUE;
+ mod = RCLASS(mod)->super;
+ }
+
+ return FALSE;
+}
+
+static VALUE
+mod_lt(mod, arg)
+ VALUE mod, arg;
+{
+ if (mod == arg) return FALSE;
+ return mod_le(mod, arg);
+}
+
+static VALUE
+mod_ge(mod, arg)
+ VALUE mod, arg;
+{
+ switch (TYPE(arg)) {
+ case T_MODULE:
+ case T_CLASS:
+ break;
+ default:
+ TypeError("compared with non class/module");
+ }
+
+ return mod_lt(arg, mod);
+}
+
+static VALUE
+mod_gt(mod, arg)
+ VALUE mod, arg;
+{
+ if (mod == arg) return FALSE;
+ return mod_ge(mod, arg);
+}
+
+static VALUE
+mod_cmp(mod, arg)
+ VALUE mod, arg;
+{
+ if (mod == arg) return INT2FIX(0);
+
+ switch (TYPE(arg)) {
+ case T_MODULE:
+ case T_CLASS:
+ break;
+ default:
+ TypeError("<=> requires Class or Module (%s given)",
+ rb_class2name(CLASS_OF(arg)));
+ break;
+ }
+
+ if (mod_le(mod, arg)) {
+ return INT2FIX(-1);
+ }
+ return INT2FIX(1);
+}
+
VALUE module_new();
VALUE class_new_instance();
static VALUE
-class_s_new(argc, argv, class)
+class_s_new(argc, argv)
int argc;
VALUE *argv;
{
- VALUE super, cls;
+ VALUE super, klass;
rb_scan_args(argc, argv, "01", &super);
if (NIL_P(super)) super = cObject;
@@ -405,26 +486,33 @@ class_s_new(argc, argv, class)
if (FL_TEST(super, FL_SINGLETON)) {
TypeError("can't make subclass of virtual class");
}
- cls = class_new(super);
+ klass = class_new(super);
/* make metaclass */
- RBASIC(cls)->class = singleton_class_new(RBASIC(super)->class);
+ RBASIC(klass)->class = singleton_class_new(RBASIC(super)->class);
+ singleton_class_attached(RBASIC(klass)->class, klass);
- return cls;
+ return klass;
}
+VALUE mod_name();
+VALUE mod_included_modules();
+VALUE mod_ancestors();
+VALUE class_instance_methods();
+VALUE class_private_instance_methods();
+
static VALUE
-class_superclass(class)
- struct RClass *class;
+class_superclass(cl)
+ VALUE cl;
{
- struct RClass *super = class->super;
+ VALUE super = RCLASS(cl)->super;
while (TYPE(super) == T_ICLASS) {
- super = super->super;
+ super = RCLASS(super)->super;
}
if (!super) {
return Qnil;
}
- return (VALUE)super;
+ return super;
}
ID
@@ -447,11 +535,102 @@ mod_attr(argc, argv, class)
VALUE name, pub;
rb_scan_args(argc, argv, "11", &name, &pub);
- rb_define_attr(class, rb_to_id(name), RTEST(pub));
+ rb_define_attr(class, rb_to_id(name), 1, RTEST(pub));
+ return Qnil;
+}
+
+static VALUE
+mod_attr_reader(argc, argv, class)
+ int argc;
+ VALUE *argv;
+ VALUE class;
+{
+ int i;
+
+ for (i=0; i<argc; i++) {
+ rb_define_attr(class, rb_to_id(argv[i]), 1, 0);
+ }
+ return Qnil;
+}
+
+static VALUE
+mod_attr_writer(argc, argv, class)
+ int argc;
+ VALUE *argv;
+ VALUE class;
+{
+ int i;
+
+ for (i=0; i<argc; i++) {
+ rb_define_attr(class, rb_to_id(argv[i]), 0, 1);
+ }
return Qnil;
}
static VALUE
+mod_attr_accessor(argc, argv, class)
+ int argc;
+ VALUE *argv;
+ VALUE class;
+{
+ int i;
+
+ for (i=0; i<argc; i++) {
+ rb_define_attr(class, rb_to_id(argv[i]), 1, 1);
+ }
+ return Qnil;
+}
+
+VALUE mod_constants();
+
+static VALUE
+mod_const_get(mod, name)
+ VALUE mod, name;
+{
+ return rb_const_get_at(mod, rb_to_id(name));
+}
+
+static VALUE
+mod_const_set(mod, name, value)
+ VALUE mod, name, value;
+{
+ rb_const_set(mod, rb_to_id(name), value);
+ return value;
+}
+
+static VALUE
+mod_const_defined(mod, name)
+ VALUE mod, name;
+{
+ return rb_const_defined_at(mod, rb_to_id(name));
+}
+
+static VALUE
+obj_methods(obj)
+ VALUE obj;
+{
+ VALUE argv[1];
+
+ argv[0] = TRUE;
+ return class_instance_methods(1, argv, CLASS_OF(obj));
+}
+
+VALUE obj_singleton_methods();
+
+static VALUE
+obj_private_methods(obj)
+ VALUE obj;
+{
+ VALUE argv[1];
+
+ argv[0] = TRUE;
+ return class_private_instance_methods(1, argv, CLASS_OF(obj));
+}
+
+VALUE obj_instance_variables();
+VALUE obj_remove_instance_variable();
+
+static VALUE
f_integer(obj, arg)
VALUE obj, arg;
{
@@ -478,6 +657,13 @@ f_integer(obj, arg)
return INT2NUM(i);
}
+VALUE
+rb_Integer(val)
+ VALUE val;
+{
+ return f_integer(Qnil, val);
+}
+
static VALUE
to_flo(val)
VALUE val;
@@ -494,12 +680,14 @@ fail_to_flo(val)
double big2dbl();
-VALUE
+static VALUE
f_float(obj, arg)
VALUE obj, arg;
{
-
switch (TYPE(arg)) {
+ case T_FIXNUM:
+ return float_new((double)FIX2INT(arg));
+
case T_FLOAT:
return arg;
@@ -511,6 +699,21 @@ f_float(obj, arg)
}
}
+VALUE
+rb_Float(val)
+ VALUE val;
+{
+ return f_float(Qnil, val);
+}
+
+double
+num2dbl(val)
+ VALUE val;
+{
+ VALUE v = rb_Float(val);
+ return RFLOAT(v)->value;
+}
+
static VALUE
f_string(obj, arg)
VALUE obj, arg;
@@ -518,11 +721,37 @@ f_string(obj, arg)
return rb_funcall(arg, rb_intern("to_s"), 0);
}
+VALUE
+rb_String(val)
+ VALUE val;
+{
+ return f_string(Qnil, val);
+}
+
static VALUE
f_array(obj, arg)
VALUE obj, arg;
{
- return rb_funcall(arg, rb_intern("to_a"), 0);
+ if (TYPE(arg) == T_ARRAY) return arg;
+ arg = rb_funcall(arg, rb_intern("to_a"), 0);
+ if (TYPE(arg) != T_ARRAY) {
+ TypeError("`to_a' did not return Array");
+ }
+ return arg;
+}
+
+VALUE
+rb_Array(val)
+ VALUE val;
+{
+ return f_array(Qnil, val);
+}
+
+VALUE
+rb_to_a(val) /* backward compatibility */
+ VALUE val;
+{
+ return f_array(Qnil, val);
}
static VALUE
@@ -531,7 +760,7 @@ boot_defclass(name, super)
VALUE super;
{
extern st_table *rb_class_tbl;
- struct RClass *obj = (struct RClass*)class_new(super);
+ VALUE obj = class_new(super);
ID id = rb_intern(name);
rb_name_class(obj, id);
@@ -551,30 +780,6 @@ rb_class_of(obj)
return RBASIC(obj)->class;
}
-int
-rb_type(obj)
- VALUE obj;
-{
- if (FIXNUM_P(obj)) return T_FIXNUM;
- if (obj == Qnil) return T_NIL;
- if (obj == FALSE) return T_FALSE;
- if (obj == TRUE) return T_TRUE;
-
- return BUILTIN_TYPE(obj);
-}
-
-int
-rb_special_const_p(obj)
- VALUE obj;
-{
- if (FIXNUM_P(obj)) return TRUE;
- if (obj == Qnil) return TRUE;
- if (obj == FALSE) return TRUE;
- if (obj == TRUE) return TRUE;
-
- return FALSE;
-}
-
VALUE TopSelf;
void
@@ -587,11 +792,15 @@ Init_Object()
cClass = boot_defclass("Class", cModule);
metaclass = RBASIC(cObject)->class = singleton_class_new(cClass);
+ singleton_class_attached(metaclass, cObject);
metaclass = RBASIC(cModule)->class = singleton_class_new(metaclass);
+ singleton_class_attached(metaclass, cModule);
metaclass = RBASIC(cClass)->class = singleton_class_new(metaclass);
+ singleton_class_attached(metaclass, cClass);
mKernel = rb_define_module("Kernel");
rb_include_module(cObject, mKernel);
+ rb_define_private_method(cClass, "inherited", obj_dummy, 1);
/*
* Ruby's Class Hierarchy Chart
@@ -621,6 +830,7 @@ Init_Object()
rb_define_method(mKernel, "==", obj_equal, 1);
rb_define_alias(mKernel, "equal?", "==");
rb_define_alias(mKernel, "===", "==");
+ rb_define_method(mKernel, "=~", rb_false, 1);
rb_define_method(mKernel, "eql?", obj_equal, 1);
@@ -634,6 +844,11 @@ Init_Object()
rb_define_method(mKernel, "to_a", any_to_a, 0);
rb_define_method(mKernel, "to_s", any_to_s, 0);
rb_define_method(mKernel, "inspect", obj_inspect, 0);
+ rb_define_method(mKernel, "methods", obj_methods, 0);
+ rb_define_method(mKernel, "singleton_methods", obj_singleton_methods, 0);
+ rb_define_method(mKernel, "private_methods", obj_private_methods, 0);
+ rb_define_method(mKernel, "instance_variables", obj_instance_variables, 0);
+ rb_define_method(mKernel, "remove_instance_variable", obj_remove_instance_variable, 0);
rb_define_method(mKernel, "instance_of?", obj_is_instance_of, 1);
rb_define_method(mKernel, "kind_of?", obj_is_kind_of, 1);
@@ -651,27 +866,53 @@ Init_Object()
cNilClass = rb_define_class("NilClass", cObject);
rb_define_method(cNilClass, "type", nil_type, 0);
rb_define_method(cNilClass, "to_s", nil_to_s, 0);
+ rb_define_method(cNilClass, "to_a", nil_to_a, 0);
rb_define_method(cNilClass, "inspect", nil_inspect, 0);
- rb_define_method(cNilClass, "=~", rb_equal, 1);
rb_define_method(cNilClass, "nil?", rb_true, 0);
rb_undef_method(CLASS_OF(cNilClass), "new");
+ rb_define_global_const("NIL", Qnil);
/* default addition */
rb_define_method(cNilClass, "+", nil_plus, 1);
- rb_define_global_function("initialize", obj_initialize, -1);
- rb_define_global_function("singleton_method_added", obj_s_added, 1);
+ rb_define_global_function("initialize", obj_dummy, -1);
+ rb_define_global_function("singleton_method_added", obj_dummy, 1);
rb_define_method(cModule, "===", mod_eqq, 1);
+ rb_define_method(cModule, "<=>", mod_cmp, 1);
+ rb_define_method(cModule, "<", mod_lt, 1);
+ rb_define_method(cModule, "<=", mod_le, 1);
+ rb_define_method(cModule, ">", mod_gt, 1);
+ rb_define_method(cModule, ">=", mod_ge, 1);
+ rb_define_method(cModule, "clone", mod_clone, 0);
rb_define_method(cModule, "to_s", mod_to_s, 0);
+ rb_define_method(cModule, "included_modules", mod_included_modules, 0);
+ rb_define_method(cModule, "name", mod_name, 0);
+ rb_define_method(cModule, "ancestors", mod_ancestors, 0);
rb_define_private_method(cModule, "attr", mod_attr, -1);
+ rb_define_private_method(cModule, "attr_reader", mod_attr_reader, -1);
+ rb_define_private_method(cModule, "attr_writer", mod_attr_writer, -1);
+ rb_define_private_method(cModule, "attr_accessor", mod_attr_accessor, -1);
+
rb_define_singleton_method(cModule, "new", module_new, 0);
+ rb_define_method(cModule, "instance_methods", class_instance_methods, -1);
+ rb_define_method(cModule, "private_instance_methods", class_private_instance_methods, -1);
+
+ rb_define_method(cModule, "constants", mod_constants, 0);
+ rb_define_method(cModule, "const_get", mod_const_get, 1);
+ rb_define_method(cModule, "const_set", mod_const_set, 2);
+ rb_define_method(cModule, "const_defined?", mod_const_defined, 1);
+ rb_define_private_method(cModule, "method_added", obj_dummy, 1);
rb_define_method(cClass, "new", class_new_instance, -1);
rb_define_method(cClass, "superclass", class_superclass, 0);
+ rb_define_singleton_method(cClass, "new", class_s_new, -1);
rb_undef_method(cClass, "extend_object");
+ rb_undef_method(cClass, "append_features");
+
+ rb_define_singleton_method(cClass, "new", class_s_new, -1);
cData = rb_define_class("Data", cObject);
diff --git a/pack.c b/pack.c
index 35052e3..20d12d4 100644
--- a/pack.c
+++ b/pack.c
@@ -85,8 +85,7 @@ static void encodes();
static VALUE
pack_pack(ary, fmt)
- struct RArray *ary;
- struct RString *fmt;
+ VALUE ary, fmt;
{
static char *nul10 = "\0\0\0\0\0\0\0\0\0\0";
static char *spc10 = " ";
@@ -99,14 +98,14 @@ pack_pack(ary, fmt)
Check_Type(fmt, T_STRING);
- p = fmt->ptr;
- pend = fmt->ptr + fmt->len;
+ p = RSTRING(fmt)->ptr;
+ pend = RSTRING(fmt)->ptr + RSTRING(fmt)->len;
res = str_new(0, 0);
- items = ary->len;
+ items = RARRAY(ary)->len;
idx = 0;
-#define NEXTFROM (items-- > 0 ? ary->ptr[idx++] : (ArgError(toofew),0))
+#define NEXTFROM (items-- > 0 ? RARRAY(ary)->ptr[idx++] : (ArgError(toofew),0))
while (p < pend) {
type = *p++; /* get data type */
@@ -285,7 +284,7 @@ pack_pack(ary, fmt)
else {
s = NUM2INT(from);
}
- str_cat(res, &s, sizeof(short));
+ str_cat(res, (UCHAR*)&s, sizeof(short));
}
break;
@@ -299,7 +298,7 @@ pack_pack(ary, fmt)
else {
i = NUM2INT(from);
}
- str_cat(res, &i, sizeof(int));
+ str_cat(res, (UCHAR*)&i, sizeof(int));
}
break;
@@ -313,7 +312,7 @@ pack_pack(ary, fmt)
else {
l = NUM2INT(from);
}
- str_cat(res, &l, sizeof(long));
+ str_cat(res, (UCHAR*)&l, sizeof(long));
}
break;
@@ -327,7 +326,7 @@ pack_pack(ary, fmt)
s = NUM2INT(from);
}
s = htons(s);
- str_cat(res, &s, sizeof(short));
+ str_cat(res, (UCHAR*)&s, sizeof(short));
}
break;
@@ -341,7 +340,7 @@ pack_pack(ary, fmt)
l = NUM2INT(from);
}
l = htonl(l);
- str_cat(res, &l, sizeof(long));
+ str_cat(res, (UCHAR*)&l, sizeof(long));
}
break;
@@ -355,7 +354,7 @@ pack_pack(ary, fmt)
s = NUM2INT(from);
}
s = htovs(s);
- str_cat(res, &s, sizeof(short));
+ str_cat(res, (UCHAR*)&s, sizeof(short));
}
break;
@@ -369,7 +368,7 @@ pack_pack(ary, fmt)
l = NUM2INT(from);
}
l = htovl(l);
- str_cat(res, &l, sizeof(long));
+ str_cat(res, (UCHAR*)&l, sizeof(long));
}
break;
@@ -389,7 +388,7 @@ pack_pack(ary, fmt)
f = (float)NUM2INT(from);
break;
}
- str_cat(res, &f, sizeof(float));
+ str_cat(res, (UCHAR*)&f, sizeof(float));
}
break;
@@ -409,7 +408,7 @@ pack_pack(ary, fmt)
d = (double)NUM2INT(from);
break;
}
- str_cat(res, &d, sizeof(double));
+ str_cat(res, (UCHAR*)&d, sizeof(double));
}
break;
@@ -442,6 +441,7 @@ pack_pack(ary, fmt)
break;
case 'u':
+ case 'm':
from = obj_as_string(NEXTFROM);
ptr = RSTRING(from)->ptr;
plen = RSTRING(from)->len;
@@ -457,7 +457,7 @@ pack_pack(ary, fmt)
todo = len;
else
todo = plen;
- encodes(res, ptr, todo);
+ encodes(res, ptr, todo, type);
plen -= todo;
ptr += todo;
}
@@ -471,39 +471,55 @@ pack_pack(ary, fmt)
return res;
}
+static char uu_table[] =
+"`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
+static char b64_table[] =
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
static void
-encodes(str, s, len)
- struct RString *str;
+encodes(str, s, len, type)
+ VALUE str;
UCHAR *s;
int len;
+ int type;
{
char hunk[4];
UCHAR *p, *pend;
+ char *trans = type == 'u' ? uu_table : b64_table;
+ int padding;
- *hunk = len + ' ';
- str_cat(str, hunk, 1);
+ if (type == 'u') {
+ *hunk = len + ' ';
+ str_cat(str, hunk, 1);
+ padding = '`';
+ }
+ else {
+ padding = '=';
+ }
while (len > 0) {
- hunk[0] = ' ' + (077 & (*s >> 2));
- hunk[1] = ' ' + (077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017)));
- hunk[2] = ' ' + (077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)));
- hunk[3] = ' ' + (077 & (s[2] & 077));
+ hunk[0] = trans[077 & (*s >> 2)];
+ hunk[1] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
+ hunk[2] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
+ hunk[3] = trans[077 & s[2]];
str_cat(str, hunk, 4);
s += 3;
len -= 3;
}
- p = str->ptr;
- pend = str->ptr + str->len;
- while (p < pend) {
- if (*p == ' ')
- *p = '`';
- p++;
+ p = RSTRING(str)->ptr;
+ pend = RSTRING(str)->ptr + RSTRING(str)->len;
+ if (len == -1) {
+ pend[-1] = padding;
+ }
+ else if (len == -2) {
+ pend[-2] = padding;
+ pend[-1] = padding;
}
str_cat(str, "\n", 1);
}
static VALUE
pack_unpack(str, fmt)
- struct RString *str, *fmt;
+ VALUE str, fmt;
{
static char *hexdigits = "0123456789abcdef0123456789ABCDEFx";
UCHAR *s, *send;
@@ -514,10 +530,10 @@ pack_unpack(str, fmt)
Check_Type(fmt, T_STRING);
- s = str->ptr;
- send = s + str->len;
- p = fmt->ptr;
- pend = p + fmt->len;
+ s = RSTRING(str)->ptr;
+ send = s + RSTRING(str)->len;
+ p = RSTRING(fmt)->ptr;
+ pend = p + RSTRING(fmt)->len;
ary = ary_new();
while (p < pend) {
@@ -851,12 +867,55 @@ pack_unpack(str, fmt)
}
break;
+ case 'm':
+ {
+ VALUE str = str_new(0, (send - s)*3/4);
+ UCHAR *ptr = RSTRING(str)->ptr;
+ int total = 0;
+ int a,b,c,d;
+ static int first = 1;
+ static int b64_xtable[256];
+
+ if (first) {
+ int i;
+ first = 0;
+
+ for (i = 0; i < 256; i++) {
+ b64_xtable[i] = -1;
+ }
+ for (i = 0; i < 64; i++) {
+ b64_xtable[b64_table[i]] = i;
+ }
+ }
+ for (;;) {
+ while (s[0] == '\r' || s[0] == '\n') { s++; }
+ if ((a = b64_xtable[s[0]]) == -1) break;
+ if ((b = b64_xtable[s[1]]) == -1) break;
+ if ((c = b64_xtable[s[2]]) == -1) break;
+ if ((d = b64_xtable[s[3]]) == -1) break;
+ *ptr++ = a << 2 | b >> 4;
+ *ptr++ = b << 4 | c >> 2;
+ *ptr++ = c << 6 | d;
+ s += 4;
+ }
+ if (a != -1 && b != -1 && s[2] == '=') {
+ *ptr++ = a << 2 | b >> 4;
+ }
+ if (a != -1 && b != -1 && c != -1 && s[3] == '=') {
+ *ptr++ = a << 2 | b >> 4;
+ *ptr++ = b << 4 | c >> 2;
+ }
+ RSTRING(str)->len = ptr - RSTRING(str)->ptr;
+ ary_push(ary, str);
+ }
+ break;
+
case '@':
- s = str->ptr + len;
+ s = RSTRING(str)->ptr + len;
break;
case 'X':
- if (len > s - str->ptr)
+ if (len > s - RSTRING(str)->ptr)
ArgError("X outside of string");
s -= len;
break;
diff --git a/parse.y b/parse.y
index 02ff720..4bf13cf 100644
--- a/parse.y
+++ b/parse.y
@@ -44,6 +44,7 @@ struct op_tbl {
char *name;
};
+NODE *eval_tree0 = 0;
NODE *eval_tree = 0;
char *sourcefile; /* current source file */
@@ -58,6 +59,7 @@ static enum lex_state {
EXPR_END, /* newline significant, +/- is a operator. */
EXPR_ARG, /* newline significant, +/- may be a sign. */
EXPR_FNAME, /* ignore newline, +/- is a operator. */
+ EXPR_CLASS, /* immediate after `class' no here document. */
} lex_state;
static int class_nest = 0;
@@ -74,6 +76,7 @@ static void fixpos();
static NODE *block_append();
static NODE *list_append();
static NODE *list_concat();
+static NODE *arg_add();
static NODE *call_op();
static int in_defined = 0;
@@ -83,6 +86,7 @@ static NODE *aryset();
static NODE *attrset();
static void backref_error();
+static NODE *match_gen();
static void local_push();
static void local_pop();
static int local_cnt();
@@ -112,40 +116,48 @@ static void top_local_setup();
struct RVarmap *vars;
}
-%token CLASS
- MODULE
- DEF
- UNDEF
- BEGIN
- RESCUE
- ENSURE
- END
- IF
- UNLESS
- THEN
- ELSIF
- ELSE
- CASE
- WHEN
- WHILE
- UNTIL
- FOR
- IN
- DO
- RETURN
- YIELD
- SUPER
- SELF
- NIL
- AND
- OR
- NOT
- IF_MOD
- UNLESS_MOD
- WHILE_MOD
- UNTIL_MOD
- ALIAS
- DEFINED
+%token kCLASS
+ kMODULE
+ kDEF
+ kUNDEF
+ kBEGIN
+ kRESCUE
+ kENSURE
+ kEND
+ kIF
+ kUNLESS
+ kTHEN
+ kELSIF
+ kELSE
+ kCASE
+ kWHEN
+ kWHILE
+ kUNTIL
+ kFOR
+ kBREAK
+ kNEXT
+ kREDO
+ kRETRY
+ kIN
+ kDO
+ kRETURN
+ kYIELD
+ kSUPER
+ kSELF
+ kNIL
+ kTRUE
+ kFALSE
+ kAND
+ kOR
+ kNOT
+ kIF_MOD
+ kUNLESS_MOD
+ kWHILE_MOD
+ kUNTIL_MOD
+ kALIAS
+ kDEFINED
+ klBEGIN
+ klEND
%token <id> IDENTIFIER FID GVAR IVAR CONSTANT
%token <val> INTEGER FLOAT STRING XSTRING REGEXP
@@ -153,18 +165,18 @@ static void top_local_setup();
%type <node> singleton
%type <val> literal numeric
-%type <node> compexpr exprs expr arg primary command_call method_call
+%type <node> compstmt stmts stmt expr arg primary command_call method_call
%type <node> if_tail opt_else case_body cases rescue ensure iterator
-%type <node> call_args call_args0 ret_args args mrhs opt_args var_ref
+%type <node> call_args call_args0 ret_args args mrhs opt_list var_ref
%type <node> superclass f_arglist f_args f_optarg f_opt
%type <node> array assoc_list assocs assoc undef_list
%type <node> iter_var opt_iter_var iter_block iter_do_block
%type <node> mlhs mlhs_head mlhs_tail lhs backref
-%type <id> variable symbol operation
+%type <id> variable symbol operation assoc_kw
%type <id> cname fname op rest_arg
%type <num> f_arg
-%token UPLUS /* unary+ */
-%token UMINUS /* unary- */
+%token oUPLUS /* unary+ */
+%token MINUS /* unary- */
%token POW /* ** */
%token CMP /* <=> */
%token EQ /* == */
@@ -180,6 +192,7 @@ static void top_local_setup();
%token COLON2 /* :: */
%token <id> OP_ASGN /* +=, -= etc. */
%token ASSOC /* => */
+%token KW_ASSOC /* -> */
%token LPAREN /* ( */
%token LBRACK /* [ */
%token LBRACE /* { */
@@ -190,10 +203,10 @@ static void top_local_setup();
* precedence table
*/
-%left IF_MOD UNLESS_MOD WHILE_MOD UNTIL_MOD
-%left OR AND
-%right NOT
-%nonassoc DEFINED
+%left kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
+%left kOR kAND
+%right kNOT
+%nonassoc kDEFINED
%right '=' OP_ASGN
%nonassoc DOT2 DOT3
%left OROP
@@ -218,7 +231,7 @@ program : {
if ((VALUE)the_class == cObject) class_nest = 0;
else class_nest = 1;
}
- compexpr
+ compstmt
{
eval_tree = block_append(eval_tree, $2);
top_local_setup();
@@ -226,67 +239,44 @@ program : {
class_nest = 0;
}
-compexpr : exprs opt_terms
+compstmt : stmts opt_terms
-exprs : /* none */
+stmts : /* none */
{
$$ = 0;
}
- | expr
+ | stmt
{
$$ = newline_node($1);
}
- | exprs terms expr
+ | stmts terms stmt
{
$$ = block_append($1, newline_node($3));
}
- | error expr
+ | error stmt
{
$$ = $2;
}
-expr : mlhs '=' mrhs
- {
- value_expr($3);
- $1->nd_value = $3;
- $$ = $1;
- }
- | assocs
- {
- $$ = NEW_HASH($1);
- }
- | RETURN ret_args
- {
- value_expr($2);
- if (!cur_mid && !in_single)
- yyerror("return appeared outside of method");
- $$ = NEW_RET($2);
- }
- | YIELD ret_args
- {
- value_expr($2);
- $$ = NEW_YIELD($2);
- }
- | command_call
- | iterator iter_do_block
+stmt : iterator iter_do_block
{
$2->nd_iter = $1;
$$ = $2;
fixpos($$, $2);
}
- | ALIAS fname {lex_state = EXPR_FNAME;} fname
+ | kALIAS fname {lex_state = EXPR_FNAME;} fname
{
if (cur_mid || in_single)
yyerror("alias within method");
$$ = NEW_ALIAS($2, $4);
}
- | ALIAS GVAR GVAR
+ | kALIAS GVAR GVAR
{
if (cur_mid || in_single)
yyerror("alias within method");
$$ = NEW_VALIAS($2, $3);
}
- | ALIAS GVAR BACK_REF
+ | kALIAS GVAR BACK_REF
{
char buf[3];
@@ -295,28 +285,28 @@ expr : mlhs '=' mrhs
sprintf(buf, "$%c", $3->nd_nth);
$$ = NEW_VALIAS($2, rb_intern(buf));
}
- | ALIAS GVAR NTH_REF
+ | kALIAS GVAR NTH_REF
{
yyerror("can't make alias for the number variables");
$$ = 0;
}
- | UNDEF undef_list
+ | kUNDEF undef_list
{
if (cur_mid || in_single)
yyerror("undef within method");
$$ = $2;
}
- | expr IF_MOD expr
+ | stmt kIF_MOD expr
{
value_expr($3);
- $$ = NEW_IF(cond($3), $1, 0);
+ $$ = node_newnode(NODE_AND, cond($3), $1);
}
- | expr UNLESS_MOD expr
+ | stmt kUNLESS_MOD expr
{
value_expr($3);
- $$ = NEW_UNLESS(cond($3), $1, 0);
+ $$ = node_newnode(NODE_OR, cond($3), $1);
}
- | expr WHILE_MOD expr
+ | stmt kWHILE_MOD expr
{
value_expr($3);
if (nd_type($1) == NODE_BEGIN) {
@@ -326,7 +316,7 @@ expr : mlhs '=' mrhs
$$ = NEW_WHILE(cond($3), $1, 1);
}
}
- | expr UNTIL_MOD expr
+ | expr kUNTIL_MOD expr
{
value_expr($3);
if (nd_type($1) == NODE_BEGIN) {
@@ -336,15 +326,58 @@ expr : mlhs '=' mrhs
$$ = NEW_UNTIL(cond($3), $1, 1);
}
}
- | expr AND expr
+ | klBEGIN
+ {
+ if (cur_mid || in_single) {
+ yyerror("BEGIN in method");
+ }
+
+ local_push();
+ }
+ '{' compstmt '}'
+ {
+ eval_tree0 = block_append(eval_tree0,NEW_PREEXE($4));
+ local_pop();
+ $$ = 0;
+ }
+ | klEND '{' compstmt '}'
+ {
+ if (cur_mid || in_single) {
+ yyerror("END in method; use at_exit");
+ }
+
+ $$ = NEW_ITER(0, NEW_POSTEXE(), $3);
+ }
+ | expr
+
+expr : mlhs '=' mrhs
+ {
+ value_expr($3);
+ $1->nd_value = $3;
+ $$ = $1;
+ }
+ | kRETURN ret_args
+ {
+ value_expr($2);
+ if (!cur_mid && !in_single)
+ yyerror("return appeared outside of method");
+ $$ = NEW_RET($2);
+ }
+ | kYIELD ret_args
+ {
+ value_expr($2);
+ $$ = NEW_YIELD($2);
+ }
+ | command_call
+ | expr kAND expr
{
$$ = logop(NODE_AND, $1, $3);
}
- | expr OR expr
+ | expr kOR expr
{
$$ = logop(NODE_OR, $1, $3);
}
- | NOT expr
+ | kNOT expr
{
value_expr($2);
$$ = NEW_NOT(cond($2));
@@ -367,7 +400,13 @@ command_call : operation call_args0
$$ = NEW_CALL($1, $3, $4);
fixpos($$, $1);
}
- | SUPER call_args0
+ | primary COLON2 operation call_args0
+ {
+ value_expr($1);
+ $$ = NEW_CALL($1, $3, $4);
+ fixpos($$, $1);
+ }
+ | kSUPER call_args0
{
if (!cur_mid && !in_single && !in_defined)
yyerror("super called outside of method");
@@ -411,7 +450,7 @@ lhs : variable
{
$$ = assignable($1, 0);
}
- | primary '[' opt_args opt_nl ']'
+ | primary '[' call_args ']'
{
$$ = aryset($1, $3, 0);
}
@@ -487,21 +526,16 @@ arg : variable '=' arg
$$ = assignable($1, $3);
fixpos($$, $3);
}
- | primary '[' opt_args opt_nl ']' '=' arg
+ | primary '[' call_args ']' '=' arg
{
- $$ = aryset($1, $3, $7);
- fixpos($$, $7);
+ $$ = aryset($1, $3, $6);
+ fixpos($$, $1);
}
| primary '.' IDENTIFIER '=' arg
{
$$ = attrset($1, $3, $5);
fixpos($$, $5);
}
- | primary '.' CONSTANT '=' arg
- {
- $$ = attrset($1, $3, $5);
- fixpos($$, $5);
- }
| backref '=' arg
{
value_expr($3);
@@ -516,19 +550,24 @@ arg : variable '=' arg
$$ = assignable($1, call_op(gettable($1), $2, 1, $3));
fixpos($$, $3);
}
- | primary '[' opt_args opt_nl ']' OP_ASGN arg
+ | primary '[' call_args ']' OP_ASGN arg
{
- NODE *args = NEW_LIST($7);
+ NODE *args = NEW_LIST($6);
list_append($3, NEW_NIL());
list_concat(args, $3);
- $$ = NEW_OP_ASGN1($1, $6, args);
- fixpos($$, $7);
+ $$ = NEW_OP_ASGN1($1, $5, args);
+ fixpos($$, $1);
}
| primary '.' IDENTIFIER OP_ASGN arg
{
$$ = NEW_OP_ASGN2($1, $3, $4, $5);
- fixpos($$, $5);
+ fixpos($$, $1);
+ }
+ | primary '.' CONSTANT OP_ASGN arg
+ {
+ $$ = NEW_OP_ASGN2($1, $3, $4, $5);
+ fixpos($$, $1);
}
| backref OP_ASGN arg
{
@@ -621,13 +660,11 @@ arg : variable '=' arg
}
| arg MATCH arg
{
- local_cnt('~');
- $$ = NEW_CALL($1, MATCH, NEW_LIST($3));
+ $$ = match_gen($1, $3);
}
| arg NMATCH arg
{
- local_cnt('~');
- $$ = NEW_NOT(NEW_CALL($1, MATCH, NEW_LIST($3)));
+ $$ = NEW_NOT(match_gen($1, $3));
}
| '!' arg
{
@@ -654,7 +691,7 @@ arg : variable '=' arg
{
$$ = logop(NODE_OR, $1, $3);
}
- | DEFINED opt_nl {in_defined = 1;} arg
+ | kDEFINED opt_nl {in_defined = 1;} arg
{
in_defined = 0;
$$ = NEW_DEFINED($4);
@@ -670,16 +707,25 @@ call_args : /* none */
}
| call_args0 opt_nl
-call_args0 : args
- | command_call
+call_args0 : command_call
{
value_expr($1);
$$ = NEW_LIST($1);
}
+ | args
+ | args ',' STAR arg
+ {
+ $$ = arg_add($1, $4);
+ }
| assocs
{
$$ = NEW_LIST(NEW_HASH($1));
}
+ | assocs ',' STAR arg
+ {
+ $$ = NEW_LIST(NEW_HASH($1));
+ $$ = arg_add($$, $4);
+ }
| args ',' assocs
{
$$ = list_append($1, NEW_HASH($3));
@@ -687,11 +733,7 @@ call_args0 : args
| args ',' assocs ',' STAR arg
{
$$ = list_append($1, NEW_HASH($3));
- $$ = call_op($$, '+', 1, $6);
- }
- | args ',' STAR arg
- {
- $$ = call_op($1, '+', 1, $4);
+ $$ = arg_add($$, $6);
}
| STAR arg
{
@@ -699,7 +741,7 @@ call_args0 : args
$$ = $2;
}
-opt_args : /* none */
+opt_list : /* none */
{
$$ = 0;
}
@@ -718,7 +760,9 @@ args : arg
mrhs : args
{
- if ($1 && $1->nd_next == 0) {
+ if ($1 &&
+ nd_type($1) == NODE_ARRAY &&
+ $1->nd_next == 0) {
$$ = $1->nd_head;
}
else {
@@ -727,7 +771,7 @@ mrhs : args
}
| args ',' STAR arg
{
- $$ = call_op($1, '+', 1, $4);
+ $$ = arg_add($1, $4);
}
| STAR arg
{
@@ -774,19 +818,7 @@ primary : literal
| DREGEXP
| var_ref
| backref
- | SUPER '(' call_args ')'
- {
- if (!cur_mid && !in_single && !in_defined)
- yyerror("super called outside of method");
- $$ = NEW_SUPER($3);
- }
- | SUPER
- {
- if (!cur_mid && !in_single && !in_defined)
- yyerror("super called outside of method");
- $$ = NEW_ZSUPER();
- }
- | primary '[' opt_args opt_nl ']'
+ | primary '[' call_args ']'
{
value_expr($1);
$$ = NEW_CALL($1, AREF, $3);
@@ -803,39 +835,39 @@ primary : literal
{
$$ = NEW_HASH($2);
}
- | RETURN '(' ret_args ')'
+ | kRETURN '(' ret_args ')'
{
if (!cur_mid && !in_single)
yyerror("return appeared outside of method");
value_expr($3);
$$ = NEW_RET($3);
}
- | RETURN '(' ')'
+ | kRETURN '(' ')'
{
if (!cur_mid && !in_single)
yyerror("return appeared outside of method");
$$ = NEW_RET(0);
}
- | RETURN
+ | kRETURN
{
if (!cur_mid && !in_single)
yyerror("return appeared outside of method");
$$ = NEW_RET(0);
}
- | YIELD '(' ret_args ')'
+ | kYIELD '(' ret_args ')'
{
value_expr($3);
$$ = NEW_YIELD($3);
}
- | YIELD '(' ')'
+ | kYIELD '(' ')'
{
$$ = NEW_YIELD(0);
}
- | YIELD
+ | kYIELD
{
$$ = NEW_YIELD(0);
}
- | DEFINED opt_nl '(' {in_defined = 1;} expr ')'
+ | kDEFINED opt_nl '(' {in_defined = 1;} expr ')'
{
in_defined = 0;
$$ = NEW_DEFINED($5);
@@ -856,55 +888,61 @@ primary : literal
$$ = $2;
fixpos($$, $1);
}
- | IF expr then
- compexpr
+ | kIF expr then
+ compstmt
if_tail
- END
+ kEND
{
value_expr($2);
$$ = NEW_IF(cond($2), $4, $5);
fixpos($$, $2);
}
- | UNLESS expr then
- compexpr
+ | kUNLESS expr then
+ compstmt
opt_else
- END
+ kEND
{
value_expr($2);
$$ = NEW_UNLESS(cond($2), $4, $5);
fixpos($$, $2);
}
- | WHILE expr term compexpr END
+ | kWHILE expr do
+ compstmt
+ kEND
{
value_expr($2);
$$ = NEW_WHILE(cond($2), $4, 1);
fixpos($$, $2);
}
- | UNTIL expr term compexpr END
+ | kUNTIL expr do
+ compstmt
+ kEND
{
value_expr($2);
$$ = NEW_UNTIL(cond($2), $4, 1);
fixpos($$, $2);
}
- | CASE compexpr
+ | kCASE compstmt
case_body
- END
+ kEND
{
value_expr($2);
$$ = NEW_CASE($2, $3);
fixpos($$, $2);
}
- | FOR iter_var IN expr term compexpr END
+ | kFOR iter_var kIN expr do
+ compstmt
+ kEND
{
value_expr($2);
$$ = NEW_FOR($2, $4, $6);
fixpos($$, $2);
}
- | BEGIN
- compexpr
+ | kBEGIN
+ compstmt
rescue
ensure
- END
+ kEND
{
if (!$3 && !$4)
$$ = NEW_BEGIN($2);
@@ -915,11 +953,11 @@ primary : literal
}
fixpos($$, $2);
}
- | LPAREN compexpr ')'
+ | LPAREN compstmt ')'
{
$$ = $2;
}
- | CLASS cname superclass
+ | kCLASS cname superclass
{
if (cur_mid || in_single)
yyerror("class definition in method body");
@@ -928,8 +966,8 @@ primary : literal
cref_push();
local_push();
}
- compexpr
- END
+ compstmt
+ kEND
{
$$ = NEW_CLASS($2, $5, $3);
fixpos($$, $3);
@@ -937,7 +975,7 @@ primary : literal
cref_pop();
class_nest--;
}
- | CLASS LSHFT expr term
+ | kCLASS LSHFT expr term
{
if (cur_mid || in_single)
yyerror("class definition in method body");
@@ -946,8 +984,8 @@ primary : literal
cref_push();
local_push();
}
- compexpr
- END
+ compstmt
+ kEND
{
$$ = NEW_SCLASS($3, $6);
fixpos($$, $3);
@@ -955,7 +993,7 @@ primary : literal
cref_pop();
class_nest--;
}
- | MODULE cname
+ | kMODULE cname
{
if (cur_mid || in_single)
yyerror("module definition in method body");
@@ -963,8 +1001,8 @@ primary : literal
cref_push();
local_push();
}
- compexpr
- END
+ compstmt
+ kEND
{
$$ = NEW_MODULE($2, $4);
fixpos($$, $4);
@@ -972,7 +1010,7 @@ primary : literal
cref_pop();
class_nest--;
}
- | DEF fname
+ | kDEF fname
{
if (cur_mid || in_single)
yyerror("nested method definition");
@@ -980,15 +1018,16 @@ primary : literal
local_push();
}
f_arglist
- compexpr
- END
+ compstmt
+ kEND
{
+ /* NOEX_PRIVATE for toplevel */
$$ = NEW_DEFN($2, $4, $5, class_nest?0:1);
fixpos($$, $4);
local_pop();
cur_mid = 0;
}
- | DEF singleton '.' {lex_state = EXPR_FNAME;} fname
+ | kDEF singleton '.' {lex_state = EXPR_FNAME;} fname
{
value_expr($2);
in_single++;
@@ -996,22 +1035,42 @@ primary : literal
lex_state = EXPR_END; /* force for args */
}
f_arglist
- compexpr
- END
+ compstmt
+ kEND
{
$$ = NEW_DEFS($2, $5, $7, $8);
fixpos($$, $2);
local_pop();
in_single--;
}
+ | kBREAK
+ {
+ $$ = NEW_BREAK();
+ }
+ | kNEXT
+ {
+ $$ = NEW_NEXT();
+ }
+ | kREDO
+ {
+ $$ = NEW_REDO();
+ }
+ | kRETRY
+ {
+ $$ = NEW_RETRY();
+ }
then : term
- | THEN
- | term THEN
+ | kTHEN
+ | term kTHEN
+
+do : term
+ | kDO
+ | term kDO
if_tail : opt_else
- | ELSIF expr then
- compexpr
+ | kELSIF expr then
+ compstmt
if_tail
{
value_expr($2);
@@ -1023,7 +1082,7 @@ opt_else : /* none */
{
$$ = 0;
}
- | ELSE compexpr
+ | kELSE compstmt
{
$$ = $2;
}
@@ -1048,13 +1107,13 @@ opt_iter_var : /* node */
$$ = $2;
}
-iter_do_block : DO
+iter_do_block : kDO
{
$<vars>$ = dyna_push();
}
opt_iter_var
- compexpr
- END
+ compstmt
+ kEND
{
$$ = NEW_ITER($3, 0, $4);
fixpos($$, $3?$3:$4);
@@ -1066,7 +1125,7 @@ iter_block : '{'
$<vars>$ = dyna_push();
}
opt_iter_var
- compexpr '}'
+ compstmt '}'
{
$$ = NEW_ITER($3, 0, $4);
fixpos($$, $3?$3:$4);
@@ -1110,9 +1169,22 @@ method_call : operation '(' call_args ')'
$$ = NEW_CALL($1, $3, $5);
fixpos($$, $1);
}
+ | kSUPER '(' call_args ')'
+ {
+ if (!cur_mid && !in_single && !in_defined)
+ yyerror("super called outside of method");
+ $$ = NEW_SUPER($3);
+ }
+ | kSUPER
+ {
+ if (!cur_mid && !in_single && !in_defined)
+ yyerror("super called outside of method");
+ $$ = NEW_ZSUPER();
+ }
-case_body : WHEN args then
- compexpr
+
+case_body : kWHEN args then
+ compstmt
cases
{
$$ = NEW_WHEN($2, $4, $5);
@@ -1121,7 +1193,8 @@ case_body : WHEN args then
cases : opt_else
| case_body
-rescue : RESCUE opt_args term compexpr
+rescue : kRESCUE opt_list do
+ compstmt
rescue
{
$$ = NEW_RESBODY($2, $4, $5);
@@ -1136,15 +1209,15 @@ ensure : /* none */
{
$$ = 0;
}
- | ENSURE compexpr
+ | kENSURE compstmt
{
$$ = $2;
}
literal : numeric
- | SYMBEG {lex_state = EXPR_FNAME;} symbol
+ | SYMBEG symbol
{
- $$ = INT2FIX($3);
+ $$ = INT2FIX($2);
}
| REGEXP
@@ -1159,14 +1232,10 @@ variable : IDENTIFIER
| IVAR
| GVAR
| CONSTANT
- | NIL
- {
- $$ = NIL;
- }
- | SELF
- {
- $$ = SELF;
- }
+ | kNIL {$$ = kNIL;}
+ | kSELF {$$ = kSELF;}
+ | kTRUE {$$ = kTRUE;}
+ | kFALSE {$$ = kFALSE;}
var_ref : variable
{
@@ -1329,6 +1398,13 @@ assoc : arg ASSOC arg
{
$$ = list_append(NEW_LIST($1), $3);
}
+ | assoc_kw KW_ASSOC arg
+ {
+ $$ = list_append(NEW_LIST(NEW_STR(str_new2(rb_id2name($1)))), $3);
+ }
+
+assoc_kw : IDENTIFIER
+ | CONSTANT
operation : IDENTIFIER
| CONSTANT
@@ -1371,6 +1447,7 @@ static NODE *str_extend();
#define LEAVE_BS 1
static VALUE lex_input; /* non-nil if File */
+static VALUE lex_lastline; /* gc protect */
static char *lex_pbeg;
static char *lex_p;
static char *lex_pend;
@@ -1430,7 +1507,6 @@ yycompile(f)
newline_seen = 0;
sourcefile = strdup(f);
- eval_tree = 0;
rb_in_compile = 1;
n = yyparse();
rb_in_compile = 0;
@@ -1478,8 +1554,15 @@ nextc()
if (NIL_P(v)) return -1;
lex_pbeg = lex_p = RSTRING(v)->ptr;
lex_pend = lex_p + RSTRING(v)->len;
+ if (RSTRING(v)->len == 8 &&
+ strncmp(lex_pbeg, "__END__", 7) == 0) {
+ lex_lastline = 0;
+ return -1;
+ }
+ lex_lastline = v;
}
else {
+ lex_lastline = 0;
return -1;
}
}
@@ -1509,7 +1592,7 @@ newtok()
toksiz = 60;
tokenbuf = ALLOC_N(char, 60);
}
- if (toksiz > 1024) {
+ if (toksiz > 4096) {
toksiz = 60;
REALLOC_N(tokenbuf, char, 60);
}
@@ -1666,13 +1749,13 @@ parse_regx(term)
case '#':
list = str_extend(list, term);
if (list == (NODE*)-1) return 0;
- continue;
+ continue;
case '\\':
switch (c = nextc()) {
case -1:
sourceline = re_start;
- Error("unterminated regexp meets end of file");
+ Error("unterminated regexp meets end of file"); /* */
return 0;
case '\n':
@@ -1778,6 +1861,8 @@ parse_regx(term)
return 0;
}
+static int parse_qstring();
+
static int
parse_string(func,term)
int func, term;
@@ -1786,11 +1871,13 @@ parse_string(func,term)
NODE *list = 0;
int strstart;
+ if (func == '\'') {
+ return parse_qstring(term);
+ }
strstart = sourceline;
newtok();
while ((c = nextc()) != term) {
- str_retry:
if (c == -1) {
unterm_str:
sourceline = strstart;
@@ -1901,45 +1988,115 @@ parse_qstring(term)
return STRING;
}
-#define LAST(v) ((v)-1 + sizeof(v)/sizeof(v[0]))
+char *strdup();
+
+static int
+here_document(term)
+ char term;
+{
+ int c;
+ char *eos;
+ int len;
+ VALUE str, line;
+ char *save_beg, *save_end, *save_lexp;
+ NODE *list = 0;
-static struct kwtable {
- char *name;
- int id;
- enum lex_state state;
-} kwtable [] = {
- "__END__", 0, EXPR_BEG,
- "alias", ALIAS, EXPR_FNAME,
- "and", AND, EXPR_BEG,
- "begin", BEGIN, EXPR_BEG,
- "case", CASE, EXPR_BEG,
- "class", CLASS, EXPR_BEG,
- "def", DEF, EXPR_FNAME,
- "defined?", DEFINED, EXPR_END,
- "do", DO, EXPR_BEG,
- "else", ELSE, EXPR_BEG,
- "elsif", ELSIF, EXPR_BEG,
- "end", END, EXPR_END,
- "ensure", ENSURE, EXPR_BEG,
- "for", FOR, EXPR_BEG,
- "if", IF, EXPR_BEG,
- "in", IN, EXPR_BEG,
- "module", MODULE, EXPR_BEG,
- "nil", NIL, EXPR_END,
- "not", NOT, EXPR_BEG,
- "or", OR, EXPR_BEG,
- "rescue", RESCUE, EXPR_MID,
- "return", RETURN, EXPR_MID,
- "self", SELF, EXPR_END,
- "super", SUPER, EXPR_END,
- "then", THEN, EXPR_BEG,
- "undef", UNDEF, EXPR_FNAME,
- "unless", UNLESS, EXPR_BEG,
- "until", UNTIL, EXPR_BEG,
- "when", WHEN, EXPR_BEG,
- "while", WHILE, EXPR_BEG,
- "yield", YIELD, EXPR_END,
-};
+ newtok();
+ switch (term) {
+ case '\'':
+ case '"':
+ case '`':
+ while ((c = nextc()) != term) {
+ tokadd(c);
+ }
+ break;
+
+ default:
+ c = term;
+ term = '"';
+ if (!is_identchar(c)) {
+ yyerror("illegal here document");
+ return 0;
+ }
+ while (is_identchar(c)) {
+ tokadd(c);
+ c = nextc();
+ }
+ pushback(c);
+ break;
+ }
+ tokfix();
+ save_lexp = lex_p;
+ save_beg = lex_pbeg;
+ save_end = lex_pend;
+ eos = strdup(tok());
+ len = strlen(eos);
+
+ str = str_new(0,0);
+ for (;;) {
+ line = io_gets(lex_input);
+ if (NIL_P(line)) {
+ error:
+ Error("unterminated string meets end of file");
+ free(eos);
+ return 0;
+ }
+ if (strncmp(eos, RSTRING(line)->ptr, len) == 0 &&
+ (RSTRING(line)->ptr[len] == '\n' ||
+ RSTRING(line)->ptr[len] == '\r')) {
+ break;
+ }
+
+ lex_pbeg = lex_p = RSTRING(line)->ptr;
+ lex_pend = lex_p + RSTRING(line)->len;
+ sourceline++;
+ switch (parse_string(term, '\n')) {
+ case STRING:
+ case XSTRING:
+ str_cat(yylval.val, "\n", 1);
+ if (!list) {
+ str_cat(str, RSTRING(yylval.val)->ptr, RSTRING(yylval.val)->len);
+ }
+ else {
+ list_append(list, NEW_STR(yylval.val));
+ }
+ break;
+ case DSTRING:
+ case DXSTRING:
+ list_append(yylval.node, NEW_STR(str_new2("\n")));
+ nd_set_type(yylval.node, NODE_STR);
+ if (!list) list = NEW_DSTR(str);
+ yylval.node = NEW_LIST(yylval.node);
+ yylval.node->nd_next = yylval.node->nd_head->nd_next;
+ list_concat(list, yylval.node);
+ break;
+
+ case 0:
+ goto error;
+ }
+ }
+ free(eos);
+ lex_p = save_lexp;
+ lex_pbeg = save_beg;
+ lex_pend = save_end;
+
+ if (list) {
+ yylval.node = list;
+ }
+ switch (term) {
+ case '\'':
+ case '"':
+ if (list) return DSTRING;
+ yylval.val = str;
+ return STRING;
+ case '`':
+ if (list) return DXSTRING;
+ return XSTRING;
+ }
+ return 0;
+}
+
+#include "lex.c"
static void
arg_ambiguous()
@@ -1956,7 +2113,7 @@ yylex()
{
register int c;
int space_seen = 0;
- struct kwtable *low = kwtable, *mid, *high = LAST(kwtable);
+ struct kwtable *kw;
if (newline_seen) {
sourceline+=newline_seen;
@@ -1981,39 +2138,20 @@ retry:
while ((c = nextc()) != '\n') {
if (c == -1)
return 0;
- if (c == '\\') { /* skip a char */
+ if (c == '\\') { /* skip a char */
c = nextc();
if (c == '\n') sourceline++;
}
if (ismbchar(c)) {
c = nextc();
- if (c == '\n')
+ if (c == '\n') {
+ sourceline++;
break;
+ }
}
}
/* fall through */
case '\n':
- /* skip embedded rd document */
- if ((c = nextc()) == '=' &&
- strncmp(lex_p, "begin", 5) == 0 &&
- (lex_p[5] == '\n' || lex_p[5] == '\r')) {
- for (;;) {
- if (c == -1) return 0;
- c = nextc();
- if (c != '\n') continue;
- c = nextc();
- if (c != '=') continue;
- if (strncmp(lex_p, "end", 3) == 0 &&
- (lex_p[3] == '\n' || lex_p[3] == '\r')) {
- lex_p += 3; /* sizeof "end" */
- break;
- }
- }
- }
- else {
- pushback(c);
- }
-
if (lex_state == EXPR_BEG || lex_state == EXPR_FNAME) {
sourceline++;
goto retry;
@@ -2064,18 +2202,21 @@ retry:
if (lex_p == lex_pbeg + 1) {
/* skip embedded rd document */
if (strncmp(lex_p, "begin", 5) == 0 && isspace(lex_p[5])) {
- lex_p = lex_pend;
for (;;) {
- if (c == -1) return 0;
- c = nextc();
- if (c != '\n') continue;
+ sourceline++;
+ lex_p = lex_pend;
c = nextc();
+ if (c == -1) {
+ Error("embedded document meets end of file");
+ return 0;
+ }
if (c != '=') continue;
if (strncmp(lex_p, "end", 3) == 0 && isspace(lex_p[3])) {
- lex_p = lex_pend;
break;
}
}
+ sourceline++;
+ lex_p = lex_pend;
goto retry;
}
}
@@ -2098,8 +2239,22 @@ retry:
return '=';
case '<':
+ c = nextc();
+ if (c == '<' &&
+ lex_state != EXPR_END
+ && lex_state != EXPR_CLASS &&
+ (lex_state != EXPR_ARG || space_seen)) {
+ int c2 = nextc();
+ if (!isspace(c2) && (strchr("\"'`", c2) || is_identchar(c2))) {
+ if (!lex_input) {
+ ArgError("here document not available");
+ }
+ return here_document(c2);
+ }
+ pushback(c2);
+ }
lex_state = EXPR_BEG;
- if ((c = nextc()) == '=') {
+ if (c == '=') {
if ((c = nextc()) == '>') {
return CMP;
}
@@ -2223,6 +2378,10 @@ retry: