summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cvsignore27
-rw-r--r--ChangeLog611
-rw-r--r--README23
-rw-r--r--README.jp16
-rw-r--r--array.c2
-rw-r--r--bignum.c12
-rw-r--r--configure.in32
-rw-r--r--cygwin/GNUmakefile.in2
-rw-r--r--dir.c62
-rw-r--r--djgpp/config.status77
-rw-r--r--dln.c6
-rw-r--r--error.c7
-rw-r--r--eval.c454
-rw-r--r--ext/.cvsignore1
-rw-r--r--ext/curses/.cvsignore1
-rw-r--r--ext/curses/extconf.rb4
-rw-r--r--ext/dbm/.cvsignore1
-rw-r--r--ext/etc/.cvsignore1
-rw-r--r--ext/extmk.rb.in5
-rw-r--r--ext/fcntl/.cvsignore1
-rw-r--r--ext/gdbm/.cvsignore1
-rw-r--r--ext/md5/.cvsignore1
-rw-r--r--ext/nkf/.cvsignore1
-rw-r--r--ext/pty/.cvsignore1
-rw-r--r--ext/pty/extconf.rb16
-rw-r--r--ext/readline/.cvsignore1
-rw-r--r--ext/sdbm/.cvsignore1
-rw-r--r--ext/sdbm/_sdbm.c4
-rw-r--r--ext/socket/.cvsignore1
-rw-r--r--ext/tcltklib/.cvsignore1
-rw-r--r--ext/tk/.cvsignore1
-rw-r--r--file.c25
-rw-r--r--gc.c80
-rw-r--r--hash.c9
-rw-r--r--intern.h4
-rw-r--r--io.c15
-rw-r--r--lib/Env.rb14
-rw-r--r--lib/cgi.rb232
-rw-r--r--lib/cgi/session.rb15
-rw-r--r--lib/date.rb38
-rw-r--r--lib/debug.rb210
-rw-r--r--lib/delegate.rb2
-rw-r--r--lib/importenv.rb6
-rw-r--r--lib/irb/ruby-lex.rb2
-rw-r--r--lib/mkmf.rb24
-rw-r--r--lib/monitor.rb53
-rw-r--r--lib/net/http.rb1118
-rw-r--r--lib/net/imap.rb6
-rw-r--r--lib/net/pop.rb13
-rw-r--r--lib/net/protocol.rb309
-rw-r--r--lib/net/smtp.rb29
-rw-r--r--lib/net/telnet.rb217
-rw-r--r--lib/observer.rb2
-rw-r--r--lib/parsedate.rb11
-rw-r--r--lib/ping.rb2
-rw-r--r--lib/thread.rb2
-rw-r--r--math.c5
-rw-r--r--misc/ruby-mode.el2
-rw-r--r--missing/flock.c103
-rw-r--r--missing/strftime.c6
-rw-r--r--missing/vsnprintf.c6
-rw-r--r--mkconfig.rb17
-rw-r--r--node.h2
-rw-r--r--object.c16
-rw-r--r--pack.c8
-rw-r--r--parse.y345
-rw-r--r--prec.c2
-rw-r--r--re.c14
-rw-r--r--regex.c3
-rw-r--r--ruby.c29
-rw-r--r--ruby.h33
-rw-r--r--signal.c16
-rw-r--r--sprintf.c2
-rw-r--r--string.c29
-rw-r--r--util.c36
-rw-r--r--version.h8
-rw-r--r--win32/config.h.in1
-rw-r--r--win32/config.status.in2
-rw-r--r--win32/win32.c65
-rw-r--r--win32/win32.h2
80 files changed, 2733 insertions, 1831 deletions
diff --git a/.cvsignore b/.cvsignore
index 8fcaffddb2..35fff17b58 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,19 +1,20 @@
-parse.c
-newver.rb
-ruby
-miniruby
+*.bak
+*.orig
+*.rej
+*.sav
+*~
+.cvsignore
+Makefile
README.fat-patch
-configure
+archive
config.cache
config.h
config.log
config.status
-Makefile
+configure
+miniruby
+newver.rb
+parse.c
ppack
-archive
-extmk.rb
-*.orig
-*.rej
-*.bak
-*.sav
-*~
+rbconfig.rb
+ruby
diff --git a/ChangeLog b/ChangeLog
index c6cd432b49..a540fc71a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,580 @@
+Tue Mar 20 23:09:33 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * win32/win32.c (win32_stat): UNC support.
+
+ * dir.c (extract_path): fix "./*" problem.
+
+Mon Mar 19 16:52:23 2001 K.Kosako <kosako@sofnec.co.jp>
+
+ * eval.c (ev_const_defined): need not to check if cbase->nd_class
+ is rb_cObject.
+
+ * eval.c (ev_const_get): ditto.
+
+Mon Mar 19 16:27:32 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (THREAD_ALLOC): flags should be initialized.
+
+ * signal.c (rb_f_kill): should use FIX2INT, not FIX2UINT.
+
+Sun Mar 18 08:58:18 2001 Wakou Aoyama <wakou@fsinet.or.jp>
+
+ * lib/net/cgi.rb: // === '' --> //.match('')
+
+ * lib/net/cgi.rb: cgi#header(): improvement for mod_ruby.
+
+ * lib/net/cgi.rb: cgi#rfc1123date(): improvement.
+ thanks to TADA Tadashi <sho@spc.gr.jp>.
+
+ * lib/net/cgi.rb: cgi#rfc1123date(): document bug fix.
+ thanks to Kazuhiro NISHIYAMA <zn@mbf.nifty.com>.
+
+ * lib/net/cgi.rb: cgi#header(): bug fix.
+ thanks to IWATSUKI Hiroyuki <don@na.rim.or.jp>.
+
+Fri Mar 16 17:21:25 2001 Akinori MUSHA <knu@iDaemons.org>
+
+ * configure.in: Set SOLIBS properly for all ELF and
+ FreeBSD/NetBSD/OpenBSD a.out platforms so that the shlib
+ dependencies are recorded in the libruby shlib.
+
+Wed Mar 14 16:41:45 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_thread_schedule): raise FATAL just once to
+ THREAD_TO_KILL.
+
+Wed Mar 14 10:41:34 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_yield_0): 0 (= Qfalse) is a valid value, so that
+ default self should be checked by klass == 0.
+
+ * bignum.c (rb_cstr2inum): should disallow '++1', '+-1', etc.
+
+Tue Mar 13 17:51:09 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (ev_const_defined): add new parameter self for special
+ const fallback.
+
+ * eval.c (ev_const_get): ditto.
+
+Tue Mar 13 16:39:45 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * dir.c (rb_glob_helper): fix drive letter handling on DOSISH.
+
+Tue Mar 13 15:01:12 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/http.rb: add HTTPRequest#basic_auth.
+
+ * lib/net/smtp.rb: raise if only account or password is given.
+
+ * lib/net/protocol.rb: WriteAdapter#<< returns self.
+
+Tue Mar 13 14:41:16 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * io.c (argf_seek): wrong calling sequence of rb_io_seek().
+
+Mon Mar 12 18:59:38 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * lib/mkmf.rb (create_makefile): save/restore $libs and $LIBPATH.
+
+Sun Mar 11 00:55:31 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * lib/mkmf.rb (install_rb): fix handling of destination path.
+
+Sat Mar 10 02:34:18 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * math.c (math_log, math_log10): use nan() instead of 0.0/0.0 on Cygwin.
+
+Thu Mar 8 17:43:59 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/protocol.rb: one write(2) per one line.
+
+Wed Mar 7 14:26:11 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * math.c (math_log, math_log10): should return NaN if x < 0.0
+ on Cygwin.
+
+Thu Mar 7 10:31:26 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
+
+ * parse.y (stmt): while/until modifier must work for empty body.
+
+Tue Mar 6 22:53:58 2001 Kazuhiro Yoshida <moriq.kazuhiro@nifty.ne.jp>
+
+ * ruby.c (ruby_set_argv): clear ARGV contents before adding args.
+
+Tue Mar 6 10:50:29 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * parse.y (primary): rescue and ensure clauses should be allowed
+ to appear in singleton method body.
+
+Mon Mar 5 17:25:13 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (proc_eq): compare Procs using blocktag equality.
+
+ * eval.c (proc_to_s): stringify according to block tag address.
+
+Mon Mar 5 17:19:56 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * win32/win32.c (gettimeofday): use GetLocalTime() instead of ftime()
+ for high-resolution timing.
+
+Sun Mar 4 20:45:20 2001 Akinori MUSHA <knu@iDaemons.org>
+
+ * ext/extmk.rb.in, lib/mkmf.rb: add C++ rules in addition to C
+ rules.
+
+Sun Mar 4 17:01:09 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * string.c (trnext): support backslash escape in String#tr.
+
+Wed Feb 28 11:02:41 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * string.c (rb_str_delete_bang): delete! should take at least 1
+ argument.
+
+Tue Feb 27 16:38:15 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (ev_const_get): retrieve Object's caonstat if no current
+ class is available (e.g. defining singleton class for Fixnums).
+
+ * eval.c (ev_const_defined): check Object's constant if no current
+ class is available (e.g. defining singleton class for Fixnums).
+
+ * eval.c (proc_call): ignore block to `call' always, despite of
+ being orphan or not.
+
+Wed Feb 27 10:16:32 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
+
+ * eval.c (rb_yield_0): should check based on rb_block_given_p()
+ and rb_f_block_given_p().
+
+Mon Feb 26 16:20:27 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * ruby.c (proc_options): call ruby_show_version() just once.
+
+Mon Feb 26 00:04:52 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (proc_call): should not modify ruby_block->frame.iter
+ based on ruby_frame->iter altered by PUSH_ITER().
+
+Mon Feb 26 05:27:52 2001 Wakou Aoyama <wakou@fsinet.or.jp>
+
+ * lib/net/telnet.rb: #telnetmode(), #binmode(): bug fix.
+ thanks to nobu.nakada@nifty.ne.jp.
+
+Mon Feb 26 04:55:50 2001 Wakou Aoyama <wakou@fsinet.or.jp>
+
+ * lib/cgi.rb: CGI#form(): bug fix.
+ thanks to MoonWolf <moonwolf@moonwolf.com>.
+
+ * lib/cgi.rb: CGI#rfc1123_date(): improvement.
+ thanks to Tomoyasu Akita <genzo-@dm4lab.to>.
+
+ * lib/cgi.rb: CGI#header(): improvement for mod_ruby.
+ thanks to Shugo Maeda <shugo@ruby-lang.org>.
+
+Sun Feb 25 02:45:30 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * file.c (rb_file_s_rename): avoid Cygwin's bug.
+
+Sat Feb 24 23:32:55 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_thread_fd_close): should save current context before
+ raising exception.
+
+Sat Feb 24 22:14:00 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * win32/win32.c (myrename): fix error handling.
+
+Sat Feb 24 15:43:31 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/protocol.rb: use net 1.2 for also ruby 1.6 branch.
+
+ * lib/net/smtp.rb: ditto.
+
+ * lib/net/pop.rb: ditto.
+
+ * lib/net/http.rb: ditto.
+
+Fri Feb 23 16:36:09 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/http.rb: always close connection if body is not exist.
+
+Fri Feb 23 13:27:05 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/http.rb: keep-alive detection was incomplete.
+
+Fri Feb 23 08:24:53 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/protocol.rb: clear read buffer after reopen.
+
+ * lib/net/http.rb: update RD document.
+
+Tue Feb 20 16:37:58 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * bignum.c (rb_big2long): should not raise RangeError for Bignum
+ LONG_MIN value.
+
+Mon Feb 19 17:46:37 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * string.c (rb_str_substr): "a"[1,2] should return ""; need
+ rubicon upgrade.
+
+Mon Feb 19 01:55:43 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (secure_visibility): visibility check for untainted modules.
+
+Mon Feb 19 00:29:29 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
+
+ * signal.c (sigpipe): sighandler which does nothing.
+
+ * signal.c (trap): set sigpipe function for SIGPIPE.
+
+ * signal.c (Init_signal): default SIGPIPE handler should be
+ sigpipe function.
+
+Sun Feb 18 15:42:38 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * ext/curses/extconf.rb: add dir_config.
+
+ * missing/flock.c: use fcntl(2) instead of lockf(2).
+
+Sun Feb 18 13:02:03 2001 Yasushi Shoji <yashi@yashi.com>
+
+ * array.c (rb_ary_subseq): wrong boundary check.
+
+Fri Feb 16 01:44:56 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * io.c (set_outfile): f should be the FILE* from the assigning value.
+
+Thu Feb 15 11:33:49 2001 Shugo Maeda <shugo@ruby-lang.org>
+
+ * lib/cgi/session.rb (close): fixed reversed condition.
+
+Wed Feb 14 17:28:24 2001 Shugo Maeda <shugo@ruby-lang.org>
+
+ * lib/net/imap.rb: supports unknown resp_text_code.
+
+Wed Feb 14 00:44:17 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * dir.c (dir_s_glob): call rb_yield directly (via push_pattern) if
+ block is given to the method.
+
+ * dir.c (push_pattern): do not call rb_ary_push; yield directly.
+
+Tue Feb 13 23:05:38 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * dir.c (lstat): should use rb_sys_stat if lstat(2) is not
+ available.
+
+Tue Feb 13 17:00:18 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/http.rb: supports HTTP 1.0 server.
+
+Tue Feb 13 01:13:43 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * parse.y (primary): preserve and clear in_single and in_def using
+ stack to prevent nested method errors in singleton class bodies.
+
+Sun Feb 11 16:00:30 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * eval.c (stack_length): use __builtin_frame_address() only if
+ GCC and i386 CPU.
+
+ * gc.c (rb_gc, Init_stack): ditto.
+
+ * configure.in: add ac_cv_func_getpgrp_void=yes on DJGPP.
+
+Sat Feb 10 23:43:49 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
+
+ * hash.c (rb_any_hash): dumped core on machines sizeof(int) != sizeof(long).
+
+Sat Feb 10 23:07:15 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * regex.c (PREV_IS_A_LETTER): should not treat c>0x7f as a word
+ character if -Kn.
+
+Sat Feb 10 00:06:28 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
+
+ * win32/win32.c (win32_stat): replace stat for enable when pathname
+ ends with '/' or '\' for mswin32 on Win9X / Win2k.
+
+ * win32/win32.h: ditto.
+
+ * ruby.h: ditto.
+
+ * dir.c (rb_glob_helper): ditto.
+
+ * file.c (rb_stat, rb_file_s_stat, eaccess, check3rdbyte): ditto.
+
+Fri Feb 9 22:54:57 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * ruby.c (ruby_init_loadpath): convert '\\' to '/'
+ before finding executable file path.
+
+Fri Feb 9 17:41:53 2001 Triet H. Lai <thlai@mail.usyd.edu.au>
+
+ * dir.c (rb_glob_helper): do not follow symbolic links.
+
+Fri Feb 8 23:53:08 2001 Usaku Nakamura <usa@osb.att.ne.jp>
+
+ * win32/config.h.in (inline): add inline definition.
+
+Thu Feb 8 21:27:24 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * lib/mkmf.rb (install_rb): fix handling of relative path.
+
+ * lib/mkmf.rb (create_makefile): add srcdir.
+
+Wed Feb 7 16:05:22 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
+
+ * parse.y (parse_quotedwords): %w should allow parenthesis escape.
+
+Wed Feb 7 00:57:42 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * parse.y (parse_qstring): %q should allow terminator escape.
+
+Wed Feb 7 00:57:42 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * re.c (rb_reg_equal): all option flags should be same to be equal.
+
+Tue Feb 6 21:01:29 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/protocol.rb: ignore EOFError on only specified case.
+
+ * lib/net/http.rb: take HTTP 1.0 server into account.
+
+Mon Feb 5 00:39:06 2001 KANEKO Naoshi <wbs01621@mail.wbs.ne.jp>
+
+ * dir.c: use ISXXX() instead of isxxx().
+
+ * dln.c (aix_loaderror): ditto.
+
+ * file.c (rb_file_s_expand_path): ditto.
+
+ * string.c (rb_str_upcase_bang): ditto.
+
+ * win32/win32.c (do_spawn): ditto.
+
+ * win32/win32.c (NtMakeCmdVector): ditto.
+
+ * win32/win32.c (opendir): ditto.
+
+Fri Feb 3 00:48:50 2001 Usaku Nakamura <usa@osb.att.ne.jp>
+
+ * win32/win32.c (isInternalCmd): ignore case for shell's internal
+ command. (marge from HEAD)
+
+Fri Feb 2 16:14:51 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (POP_VARS): propagate DVAR_DONT_RECYCLE, if
+ SCOPE_DONT_RECYCLE of ruby_scope is set.
+
+Wed Jan 31 22:27:29 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * configure.in: gcc-2.95.2-7(cygwin) support.
+ add -mwin32 if available.
+
+ * cygwin/GNUmakefile: ditto.
+
+Mon Jan 29 17:36:19 2001 TOYOFUKU Chikanobu <toyofuku@juice.or.jp>
+
+ * eval.c (rb_eval): nd_iter evaluation should be wrapped by
+ BEGIN_CALLARGS and END_CALLARGS.
+
+Mon Jan 29 01:40:27 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * string.c (str_independent): should not clear str->orig here.
+ it's too early.
+
+Wed Jan 24 01:45:49 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (POP_BLOCK_TAG): call rb_gc_force_recycle() if block has
+ not been objectified.
+
+ * eval.c (rb_callcc): should nail down block->tag history to avoid
+ rb_gc_force_recycle().
+
+Tue Jan 23 18:51:57 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * gc.c (rb_gc_call_finalizer_at_exit): should finalize objects in
+ deferred_final_list too.
+
+Tue Jan 23 16:10:12 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * gc.c (os_live_obj): do not list terminated object.
+
+ * gc.c (os_obj_of): ditto.
+
+ * gc.c (rb_gc_mark): support new T_BLKTAG tag.
+
+ * gc.c (obj_free): ditto.
+
+ * eval.c (new_blktag): creation of new block tag, which holds
+ destination of global jump and orphan status.
+
+ * eval.c (block_pass): break from orphan Proc object will raise a
+ LocalJumpError exception.
+
+Mon Jan 22 16:33:16 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * mkconfig.rb: autoconf 2.49 support.
+
+Sat Jan 20 03:54:00 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * parse.y (yylex): fixed serious syntax misbehavior. do's
+ preceding was too high. a block in `foo bar do .. end' should
+ be passed to `foo', not `bar'.
+
+ * parse.y (block_call): syntax restructure.
+
+Fri Jan 19 04:04:31 2001 Akinori MUSHA <knu@iDaemons.org>
+
+ * lib/irb/ruby-lex.rb: Merge from HEAD: rev.1.4
+
+Wed Jan 17 13:28:26 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * configure.in: remove DEFS definition.
+
+ * mkconfig.rb: ditto.
+
+ * win32/config.status.in: ditto.
+
+Tue Jan 16 16:59:14 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/protocol.rb: ignore EOFError for read
+
+Sun Jan 14 21:49:28 2001 Koji Arai <JCA02266@nifty.ne.jp>
+
+ * sprintf.c (rb_f_sprintf): simple typo. binary base should be 2,
+ not '2'.
+
+Sun Jan 14 02:49:57 2001 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
+
+ * lib/net/protocol.rb (adding): too few "yield" in case of arg is
+ not String/File.
+
+Sat Jan 13 19:18:18 2001 WATANABE Hirofumi <eban@ruby-lang.org>
+
+ * re.c (rb_reg_desc): separate RE_OPTION_MULTILINE
+
+ * re.c (rb_reg_options): add RE_OPTION_{POSIXLINE,RE_OPTION_MULTILINE,
+ RE_OPTION_EXTENDED}
+
+Thu Jan 11 06:45:55 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * object.c (rb_mod_dup): should propagate FL_SINGLETON.
+
+ * object.c (inspect_obj): handles the case of no instance variable.
+
+Wed Jan 10 01:50:45 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * string.c (rb_str_reverse_bang): forgot to call rb_str_modify().
+
+Tue Jan 9 17:41:40 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * object.c (rb_obj_taint): check frozen status before modifying
+ taint status.
+
+ * object.c (rb_obj_untaint): ditto.
+
+Mon Jan 8 21:35:10 2001 Guy Decoux <decoux@moulon.inra.fr>
+
+ * file.c (path_check_1): should restore modified path.
+
+Mon Jan 8 21:24:37 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * bignum.c (bigdivrem): t2 might be too big for signed long; do
+ not use rb_int2big(), but rb_uint2big().
+
+Mon Jan 8 03:09:58 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * error.c (rb_load_fail): new func to report LoadError.
+
+ * ruby.c (load_file): use rb_load_fail.
+
+Sat Jan 6 00:55:59 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * pack.c (pack_pack): template "m2" or "u2" caused inifinite loop.
+
+Fri Jan 5 01:02:17 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (ruby_finalize): should enclosed by PUSH_TAG/POP_TAG.
+
+Sun Dec 31 01:39:16 2000 Guy Decoux <decoux@moulon.inra.fr>
+
+ * eval.c (rb_mod_define_method): wrong comparison for blocks.
+
+Sat Dec 30 19:28:50 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * gc.c (id2ref): should handle Symbol too.
+
+ * gc.c (id2ref): should print original ptr value
+
+Sat Dec 30 03:14:22 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_iterate): NODE_CFUNC does not protect its data
+ (nd_tval), so create new node NODE_IFUNC for iteration C
+ function.
+
+ * eval.c (rb_yield_0): use NODE_IFUNC.
+
+ * gc.c (rb_gc_mark): support NODE_IFUNC.
+
+Fri Dec 29 11:41:55 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * gc.c (mem_error): prohibit recursive mem_error().
+ (ruby-bugs-ja:PR#36)
+
+Fri Dec 29 11:05:41 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_thread_fd_writable): should not switch context if
+ rb_thread_critical is set.
+
+ * eval.c (rb_thread_wait_fd): ditto.
+
+ * eval.c (rb_thread_wait_for): ditto.
+
+ * eval.c (rb_thread_select): ditto.
+
+ * eval.c (rb_thread_join): join during critical section causes
+ deadlock.
+
+Tue Dec 26 18:46:41 2000 NAKAMURA Hiroshi <nakahiro@sarion.co.jp>
+
+ * lib/debug.rb: Avoid thread deadlock in debugging stopped thread.
+
+ * lib/debug.rb: Uncleared 'finish' state.
+
+Tue Dec 26 16:53:55 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * eval.c (rb_yield_0): remove dvar node by rb_gc_force_recycle()
+ more eagerly.
+
+ * eval.c (rb_f_binding): recycling should be stopped for outer
+ scope too.
+
+ * eval.c (proc_new): ditto.
+
+Tue Dec 26 15:45:35 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * string.c (rb_str_inspect): should treat multibyte chracters
+ properly.
+
+Mon Dec 25 17:49:08 2000 K.Kosako <kosako@sofnec.co.jp>
+
+ * string.c (rb_str_replace_m): unexpected string share happens if
+ replace is done for associated (STR_NO_ORIG) string.
+
+Tue Dec 26 15:01:53 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * io.c (rb_f_p): should not call rb_io_flush() if rb_defout is not
+ a IO (T_FILE).
+
+Mon Dec 25 15:52:39 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * stable version 1.6.2 released.
+
Mon Dec 25 05:11:04 2000 Wakou Aoyama <wakou@fsinet.or.jp>
* lib/cgi.rb: version 2.1.2 (some bug fixes).
@@ -21,10 +598,6 @@ Mon Dec 25 00:04:54 2000 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* eval.c (rb_thread_schedule): initial value of `max' changed to -1.
-Fri Dec 22 17:59:30 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
-
- * stable version 1.6.2 released.
-
Mon Dec 25 00:16:14 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
* string.c (rb_str_replace_m): copy-on-write replace.
@@ -85,7 +658,7 @@ Tue Dec 19 13:44:50 2000 K.Kosako <kosako@sofnec.co.jp>
Tue Dec 19 00:57:10 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
- * time.c (time_minus): usec might overflow (ruby-bugs-ja:#PR#35).
+ * time.c (time_minus): usec might overflow. (ruby-bugs-ja:PR#35)
* eval.c (rb_obj_extend): Object#extend should take at least one
argument.
@@ -837,7 +1410,7 @@ Sat Sep 23 03:06:25 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
Fri Sep 22 15:46:21 2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
- * lib/net/http.rb: too early parameter expantion in string.
+ * lib/net/http.rb: too early parameter expansion in string.
Fri Sep 22 13:58:51 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
@@ -894,7 +1467,7 @@ Wed Sep 20 23:21:38 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
Wed Sep 20 14:01:45 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
- * eval.c (rb_provided): detect infnite load loop.
+ * eval.c (rb_provided): detect infinite load loop.
* eval.c (rb_provided): too weak filename comparison.
@@ -959,7 +1532,7 @@ Thu Sep 14 02:46:54 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
Wed Sep 13 17:01:03 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
- * bignum.c (rb_big_eq): imcomplete value compare of bignums.
+ * bignum.c (rb_big_eq): incomplete value comparison of bignums.
Wed Sep 13 06:39:54 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
@@ -1084,7 +1657,7 @@ Fri Sep 1 10:36:29 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
* parse.y (aref_args,opt_call_args): add block_call to allow a
method without parentheses and with block as a last argument.
- * hash.c (rb_hash_sort): should not retrun nil.
+ * hash.c (rb_hash_sort): should not return nil.
* re.c (match_aref): should use rb_reg_nth_match().
@@ -1252,7 +1825,7 @@ Fri Aug 11 15:43:46 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
Thu Aug 10 08:05:03 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
- * eval.c (rb_callcc): returned current thread instaed of
+ * eval.c (rb_callcc): returned current thread instead of
continuation wrongly.
Thu Aug 10 05:40:28 2000 WATANABE Hirofumi <eban@os.rim.or.jp>
@@ -1425,7 +1998,7 @@ Tue Jul 18 14:58:30 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
Mon Jul 17 04:29:50 2000 Minero Aoki <aamine@dp.u-netsurf.ne.jp>
- * lib/mkmf.rb: converts extention of $objs into $OBJEXT.
+ * lib/mkmf.rb: converts extension of $objs into $OBJEXT.
Sun Jul 16 03:02:34 2000 Dave Thomas <dave@thomases.com>
@@ -1522,7 +2095,7 @@ Mon Jul 10 09:07:54 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
Sat Jul 8 23:08:40 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
* eval.c (rb_thread_start_0): should copy previous scopes to
- prevent rb_gc_force_recylce().
+ prevent rb_gc_force_recycle().
Fri Jul 7 23:36:36 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp>
@@ -1597,7 +2170,7 @@ Wed Jul 5 09:47:14 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
* time.c (time_arg): Time::local, Time::gm now take 7th optional
argument for usec.
- * numeric.c (num_ceil, etc): default ceil, floor, round, trancate
+ * numeric.c (num_ceil, etc): default ceil, floor, round, truncate
implementation for Numeric, using `to_f'.
* io.c (rb_io_reopen): clear fptr->path after free() to prevent
@@ -1688,7 +2261,7 @@ Mon Jul 3 13:15:02 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
* bignum.c (rb_big_divmod): ditto.
- * numeric.c (fixdivmod): does not depend C's undifined %
+ * numeric.c (fixdivmod): does not depend C's undefined %
behavior. adopt to fmod(3m) behavior.
* numeric.c (flo_mod): modulo now reserves fmod(3m) behavior.
@@ -1731,7 +2304,7 @@ Sat Jul 1 15:22:35 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
Sat Jul 1 15:22:35 2000 Yukihiro Matsumoto <matz@netlab.co.jp>
* eval.c (rb_eval): the value from RTEST() is not valid Ruby
- objct. result should be either true or false.
+ object. result should be either true or false.
Sat Jul 1 09:30:06 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp>
@@ -3924,7 +4497,7 @@ Thu Oct 21 16:14:19 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* ruby.c (proc_options): use RUBYOPT environment variable to
retrieve the default options.
- * dir.c (fnmatch): use eban's fnmatch; do not depend on systems's
+ * dir.c (fnmatch): use eban's fnmatch; do not depend on system's
fnmatch (which may have portability problem) anymore.
Wed Oct 20 15:14:24 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
@@ -6519,7 +7092,7 @@ Sun Nov 1 01:18:52 1998 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
Sat Oct 31 23:18:34 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* string.c (rb_str_split_method): negative LIMIT means number of
- splitted fields are unlimited, as in perl.
+ split fields are unlimited, as in perl.
* string.c (rb_str_split_method): if LIMIT is unspecified,
trailing null fields are stripped.
@@ -8775,7 +9348,7 @@ Wed Nov 12 13:44:47 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
Mon Nov 10 11:24:51 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
- * regex.c (re_compile_pattern): non-resitering parens (?:..).
+ * regex.c (re_compile_pattern): non-registering parens (?:..).
* regex.c (re_compile_pattern): new meta character \< (wordbeg)
and \> (wordend).
@@ -9031,7 +9604,7 @@ Tue Sep 16 17:54:25 1997 Yukihiro Matsumoto <matz@netlab.co.jp>
* 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.
+ variable, if ruby is running under setuid.
* process.c (init_ids): check suid check for setuid/seteuid etc.
diff --git a/README b/README
index 5794f5daf6..83a88e1359 100644
--- a/README
+++ b/README
@@ -26,10 +26,10 @@ The Ruby distribution can be found on:
You can get it by anonymous CVS. How to check out is:
- $ cvs -d :pserver:anonymous@cvs.netlab.co.jp:/home/cvs login
- (Logging in to anonymous@cvs.netlab.co.jp)
+ $ cvs -d :pserver:anonymous@cvs.ruby-lang.org:/home/cvs login
+ (Logging in to anonymous@cvs.ruby-lang.org)
CVS password: guest
- $ cvs -d :pserver:anonymous@cvs.netlab.co.jp:/home/cvs checkout ruby
+ $ cvs -d :pserver:anonymous@cvs.ruby-lang.org:/home/cvs checkout ruby
* Mailing list
@@ -40,17 +40,20 @@ To subscribe this list, please send the following phrase
e.g.
subscribe Joseph Smith
-in the mail body (not subject) to the address <ruby-talk-ctl@netlab.co.jp>.
+in the mail body (not subject) to the address <ruby-talk-ctl@ruby-lang.org>.
* How to compile and install
This is what you need to do to compile and install Ruby:
- 1. Run ./configure, which will generate config.h and Makefile.
+ 1. If ./configure does not exist or is older than configure.in,
+ run autoconf to (re)generate configure.
- 2. Edit defines.h if you need. Probably this step will not need.
+ 2. Run ./configure, which will generate config.h and Makefile.
- 3. Remove comment mark(#) before the module names from ext/Setup (or
+ 3. Edit defines.h if you need. Probably this step will not need.
+
+ 4. Remove comment mark(#) before the module names from ext/Setup (or
add module names if not present), if you want to link modules
statically.
@@ -59,13 +62,13 @@ This is what you need to do to compile and install Ruby:
remove comment mark from the line "#option nodynamic" in
ext/Setup.
- 4. Run make.
+ 5. Run make.
- 5. Optionally, run 'make test' to check whether the compiled Ruby
+ 6. Optionally, run 'make test' to check whether the compiled Ruby
interpreter works well. If you see the message "test succeeded",
your ruby works as it should (hopefully).
- 6. Run 'make install'
+ 7. Run 'make install'
You may have to be a super user to install ruby.
diff --git a/README.jp b/README.jp
index fccedb2f99..566fbcdac4 100644
--- a/README.jp
+++ b/README.jp
@@ -78,13 +78,17 @@ Ruby³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë¤Ä¤¤¤ÆÏ䷹礦ruby-ext¥á¡¼¥ê¥ó¥°¥ê¥¹¥È¤È
°Ê²¼¤Î¼ê½ç¤Ç¹Ô¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
- 1. configure¤ò¼Â¹Ô¤·¤ÆMakefile¤Ê¤É¤òÀ¸À®¤¹¤ë
+ 1. ¤â¤·configure¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤é¤Ê¤¤¡¢¤â¤·¤¯¤Ï
+ configure.in¤è¤ê¸Å¤¤¤è¤¦¤Ê¤é¡¢autoconf¤ò¼Â¹Ô¤·¤Æ
+ ¿·¤·¤¯configure¤òÀ¸À®¤¹¤ë
- 2. (ɬÍפʤé¤Ð)defines.h¤òÊÔ½¸¤¹¤ë
+ 2. configure¤ò¼Â¹Ô¤·¤ÆMakefile¤Ê¤É¤òÀ¸À®¤¹¤ë
+
+ 3. (ɬÍפʤé¤Ð)defines.h¤òÊÔ½¸¤¹¤ë
¿ʬ¡¤É¬Í×̵¤¤¤È»×¤¤¤Þ¤¹¡¥
- 3. (ɬÍפʤé¤Ð)ext/Setup¤ËÀÅŪ¤Ë¥ê¥ó¥¯¤¹¤ë³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ò
+ 4. (ɬÍפʤé¤Ð)ext/Setup¤ËÀÅŪ¤Ë¥ê¥ó¥¯¤¹¤ë³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ò
»ØÄꤹ¤ë
ext/Setup¤Ëµ­½Ò¤·¤¿¥â¥¸¥å¡¼¥ë¤ÏÀÅŪ¤Ë¥ê¥ó¥¯¤µ¤ì¤Þ¤¹¡¥
@@ -95,14 +99,14 @@ Ruby³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë¤Ä¤¤¤ÆÏ䷹礦ruby-ext¥á¡¼¥ê¥ó¥°¥ê¥¹¥È¤È
³ÈÄ¥¥â¥¸¥å¡¼¥ë¤òÍøÍѤ¹¤ë¤¿¤á¤Ë¤Ï¡¤¤¢¤é¤«¤¸¤áÀÅŪ¤Ë¥ê¥ó
¥¯¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥
- 4. make¤ò¼Â¹Ô¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ë
+ 5. make¤ò¼Â¹Ô¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ë
- 5. make test¤Ç¥Æ¥¹¥È¤ò¹Ô¤¦¡¥
+ 6. make test¤Ç¥Æ¥¹¥È¤ò¹Ô¤¦¡¥
¡Ötest succeeded¡×¤Èɽ¼¨¤µ¤ì¤ì¤ÐÀ®¸ù¤Ç¤¹¡¥¤¿¤À¤·¥Æ¥¹¥È
¤ËÀ®¸ù¤·¤Æ¤â´°àú¤À¤ÈÊݾڤµ¤ì¤Æ¤¤¤ëÌõ¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡¥
- 6. make install
+ 7. make install
root¤Çºî¶È¤¹¤ëɬÍפ¬¤¢¤ë¤«¤â¤·¤ì¤Þ¤»¤ó¡¥
diff --git a/array.c b/array.c
index 638b392753..3349a81f8f 100644
--- a/array.c
+++ b/array.c
@@ -1171,7 +1171,7 @@ rb_ary_replace_m(ary, ary2)
return ary;
}
-static VALUE
+VALUE
rb_ary_clear(ary)
VALUE ary;
{
diff --git a/bignum.c b/bignum.c
index daf131b042..521393545b 100644
--- a/bignum.c
+++ b/bignum.c
@@ -209,6 +209,10 @@ rb_cstr2inum(str, base)
str++;
sign = 0;
}
+ if (str[0] == '+' || str[0] == '-') {
+ if (badcheck) goto bad;
+ return INT2FIX(0);
+ }
if (base == 0) {
if (str[0] == '0') {
if (str[1] == 'x' || str[1] == 'X') {
@@ -467,7 +471,7 @@ rb_big2long(x)
{
unsigned long num = big2ulong(x, "int");
- if ((long)num < 0) {
+ if ((long)num < 0 && (long)num != LONG_MIN) {
rb_raise(rb_eRangeError, "bignum too big to convert into `int'");
}
if (!RBIGNUM(x)->sign) return -(long)num;
@@ -831,8 +835,10 @@ bigdivrem(x, y, divp, modp)
t2 %= dd;
}
RBIGNUM(z)->sign = RBIGNUM(x)->sign==RBIGNUM(y)->sign;
- if (!RBIGNUM(x)->sign) t2 = -(long)t2;
- if (modp) *modp = rb_int2big((long)t2);
+ if (modp) {
+ *modp = rb_uint2big((unsigned long)t2);
+ RBIGNUM(*modp)->sign = RBIGNUM(x)->sign;
+ }
if (divp) *divp = z;
return;
}
diff --git a/configure.in b/configure.in
index b24f492665..0d152aaeb6 100644
--- a/configure.in
+++ b/configure.in
@@ -90,14 +90,20 @@ AC_CHECK_TOOL(AR, ar)
AC_CHECK_PROGS(AR, ar aal, ar)
case "$target_os" in
- cygwin*|mingw*)
- AC_CHECK_TOOL(NM, nm)
- AC_CHECK_TOOL(DLLWRAP, dllwrap)
- AC_CHECK_TOOL(AS, as)
- AC_CHECK_TOOL(DLLTOOL, dlltool)
- AC_CHECK_TOOL(WINDRES, windres)
- ;;
+cygwin*|mingw*)
+ AC_CHECK_TOOL(NM, nm)
+ AC_CHECK_TOOL(DLLWRAP, dllwrap)
+ AC_CHECK_TOOL(AS, as)
+ AC_CHECK_TOOL(DLLTOOL, dlltool)
+ AC_CHECK_TOOL(WINDRES, windres)
+ echo 'main(){}' > conftest.c
+ if $CC -mwin32 -c conftest.c 2> /dev/null; then
+ MWIN32=-mwin32
+ CFLAGS="$CFLAGS $MWIN32"
+ fi
+ ;;
esac
+AC_SUBST(MWIN32)
AC_PROG_LN_S
AC_PROG_MAKE_SET
@@ -184,6 +190,8 @@ mingw*) LIBS="-lwsock32 -lmsvcrt $LIBS"
ac_cv_func_times=yes;;
os2_emx*) LIBS="-lm $LIBS"
ac_cv_lib_dir_opendir=no;;
+msdosdjgpp*) LIBS="-lm $LIBS"
+ ac_cv_func_getpgrp_void=yes;;
freebsd*) LIBS="-lm $LIBS"
AC_CACHE_CHECK([whether -lxpg4 has to be linked],
rb_cv_lib_xpg4_needed,
@@ -313,6 +321,7 @@ main()
], rb_cv_func_strtod=yes, rb_cv_func_strtod=no, rb_cv_func_strtod=no)])
test $rb_cv_func_strtod = no && LIBOBJS="$LIBOBJS strtod.o"
+AC_C_INLINE
AC_C_BIGENDIAN
AC_C_CONST
AC_C_CHAR_UNSIGNED
@@ -757,6 +766,9 @@ if test "$enable_shared" = 'yes'; then
LIBRUBYARG='-L. -l$(RUBY_INSTALL_NAME)'
CFLAGS="$CFLAGS $CCDLFLAGS"
ENABLE_SHARED=yes
+ if test "$rb_cv_binary_elf" = yes; then
+ SOLIBS='$(LIBS)'
+ fi
case "$target_os" in
sunos4*)
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so'
@@ -766,6 +778,7 @@ if test "$enable_shared" = 'yes'; then
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so'
;;
freebsd*)
+ SOLIBS='$(LIBS)'
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR)$(MINOR)'
if test "$rb_cv_binary_elf" != "yes" ; then
LIBRUBY_SO="$LIBRUBY_SO.\$(TEENY)"
@@ -773,6 +786,7 @@ if test "$enable_shared" = 'yes'; then
fi
;;
netbsd*)
+ SOLIBS='$(LIBS)'
LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR)'
if test "$rb_cv_binary_elf" = yes; then # ELF platforms
LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR) lib$(RUBY_INSTALL_NAME).so'
@@ -780,6 +794,9 @@ if test "$enable_shared" = 'yes'; then
LIBRUBY_ALIASES= # a.out platforms
fi
;;
+ openbsd*)
+ SOLIBS='$(LIBS)'
+ ;;
solaris*)
XLDFLAGS='-R${prefix}/lib'
;;
@@ -963,5 +980,6 @@ fi
echo "creating config.h"
tr -d '\015' < confdefs.h > config.h
+: > confdefs.h
AC_OUTPUT($FIRSTMAKEFILE Makefile ext/extmk.rb)
diff --git a/cygwin/GNUmakefile.in b/cygwin/GNUmakefile.in
index 76ce832a31..0e89d15dec 100644
--- a/cygwin/GNUmakefile.in
+++ b/cygwin/GNUmakefile.in
@@ -21,7 +21,7 @@ $(LIBRUBY_SO): $(RUBYDEF) $(LIBRUBY_SO).res.@OBJEXT@
$(LIBRUBY): $(LIBRUBY_SO)
%.res.@OBJEXT@: %.rc
- @WINDRES@ --include-dir . --include-dir $(<D) --include-dir $(srcdir)/win32 $< $@
+ @WINDRES@ --preprocessor '$(CC) -E -xc-header -DRC_INVOKE @MWIN32@' --include-dir . --include-dir $(<D) --include-dir $(srcdir)/win32 $< $@
$(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(LIBRUBY_SO).rc: rbconfig.rb
@@MINIRUBY@ $(srcdir)/win32/resource.rb \
diff --git a/dir.c b/dir.c
index 37cf332cb5..fb5d30d6ee 100644
--- a/dir.c
+++ b/dir.c
@@ -61,6 +61,10 @@ char *strchr _((char*,char));
#include <ctype.h>
+#ifndef HAVE_LSTAT
+#define lstat rb_sys_stat
+#endif
+
#define FNM_NOESCAPE 0x01
#define FNM_PATHNAME 0x02
#define FNM_PERIOD 0x04
@@ -69,7 +73,7 @@ char *strchr _((char*,char));
#define FNM_NOMATCH 1
#define FNM_ERROR 2
-#define downcase(c) (nocase && isupper(c) ? tolower(c) : (c))
+#define downcase(c) (nocase && ISUPPER(c) ? tolower(c) : (c))
#if defined DOSISH
#define isdirsep(c) ((c) == '/' || (c) == '\\')
@@ -531,7 +535,11 @@ extract_path(p, pend)
len = pend - p;
alloc = ALLOC_N(char, len+1);
memcpy(alloc, p, len);
- if (len > 1 && pend[-1] == '/') {
+ if (len > 1 && pend[-1] == '/'
+#if defined DOSISH
+ && pend[-2] != ':'
+#endif
+ ) {
alloc[len-1] = 0;
}
else {
@@ -568,7 +576,7 @@ rb_glob_helper(path, flag, func, arg)
char *p, *m;
if (!has_magic(path, 0)) {
- if (stat(path, &st) == 0) {
+ if (rb_sys_stat(path, &st) == 0) {
(*func)(path, arg);
}
return;
@@ -601,12 +609,27 @@ rb_glob_helper(path, flag, func, arg)
rb_glob_helper(buf, flag, func, arg);
free(buf);
}
- dirp = opendir(dir);
- if (dirp == NULL) {
- free(base);
- break;
+ if (lstat(dir, &st) < 0) {
+ free(base);
+ break;
+ }
+ if (S_ISDIR(st.st_mode)) {
+ dirp = opendir(dir);
+ if (dirp == NULL) {
+ free(base);
+ break;
+ }
}
+ else {
+ free(base);
+ break;
+ }
+
+#if defined DOSISH
+#define BASE (*base && !((isdirsep(*base) && !base[1]) || (base[1] == ':' && isdirsep(base[2]) && !base[3])))
+#else
#define BASE (*base && !(*base == '/' && !base[1]))
+#endif
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
if (recursive) {
@@ -636,7 +659,7 @@ rb_glob_helper(path, flag, func, arg)
free(base);
free(magic);
while (link) {
- stat(link->path, &st); /* should success */
+ lstat(link->path, &st); /* should success */
if (S_ISDIR(st.st_mode)) {
int len = strlen(link->path);
int mlen = strlen(m);
@@ -679,7 +702,14 @@ push_pattern(path, ary)
char *path;
VALUE ary;
{
- rb_ary_push(ary, rb_tainted_str_new2(path));
+ VALUE str = rb_tainted_str_new2(path);
+
+ if (ary) {
+ rb_ary_push(ary, str);
+ }
+ else {
+ rb_yield(str);
+ }
}
static void
@@ -753,10 +783,12 @@ dir_s_glob(dir, str)
char buffer[MAXPATHLEN], *buf = buffer;
char *t;
int nest;
- VALUE ary;
+ VALUE ary = 0;
Check_SafeStr(str);
- ary = rb_ary_new();
+ if (!rb_block_given_p()) {
+ ary = rb_ary_new();
+ }
if (RSTRING(str)->len >= MAXPATHLEN)
buf = xmalloc(RSTRING(str)->len + 1);
@@ -783,14 +815,6 @@ dir_s_glob(dir, str)
}
if (buf != buffer)
free(buf);
- if (rb_block_given_p()) {
- long len = RARRAY(ary)->len;
- VALUE *ptr = RARRAY(ary)->ptr;
-
- while (len--) {
- rb_yield(*ptr++);
- }
- }
return ary;
}
diff --git a/djgpp/config.status b/djgpp/config.status
deleted file mode 100644
index 7a10754d1d..0000000000
--- a/djgpp/config.status
+++ /dev/null
@@ -1,77 +0,0 @@
-/^SHELL/s,/bin/sh,$(COMPSEC),
-s%@srcdir@%.%g
-s%@top_srcdir@%..%
-s%@CFLAGS@%-O2%g
-s%@CPPFLAGS@%%g
-s%@CXXFLAGS@%%g
-s%@LDFLAGS@%%g
-s%@LIBS@%-lm %g
-s%@exec_prefix@%${prefix}%g
-s%@prefix@%/usr/local%g
-s%@program_transform_name@%s,x,x,%g
-s%@bindir@%${exec_prefix}/bin%g
-s%@sbindir@%${exec_prefix}/sbin%g
-s%@libexecdir@%${exec_prefix}/libexec%g
-s%@datadir@%${prefix}/share%g
-s%@sysconfdir@%${prefix}/etc%g
-s%@sharedstatedir@%${prefix}/com%g
-s%@localstatedir@%${prefix}/var%g
-s%@libdir@%${exec_prefix}/lib%g
-s%@includedir@%${prefix}/include%g
-s%@oldincludedir@%/usr/include%g
-s%@infodir@%${prefix}/info%g
-s%@mandir@%${prefix}/man%g
-s%@host@%i386-pc-msdosdjgpp%g
-s%@host_alias@%i386-msdosdjgpp%g
-s%@host_cpu@%i386%g
-s%@host_vendor@%pc%g
-s%@host_os@%msdosdjgpp%g
-s%@CC@%gcc%g
-s%@CPP@%gcc -E%g
-s%@YACC@%bison -y%g
-s%@RANLIB@%ranlib%g
-s%@AR@%ar%g
-s%@INSTALL_PROGRAM@%${INSTALL}%g
-s%@INSTALL_DATA@%${INSTALL} -m 644%g
-s%@SET_MAKE@%%g
-s%@LIBOBJS@% crypt.o flock.o vsnprintf.o%g
-s%@ALLOCA@%%g
-s%@DEFAULT_KCODE@%%g
-s%@EXEEXT@%.exe%g
-s%@OBJEXT@%o%g
-s%@XLDFLAGS@%%g
-s%@DLDFLAGS@%%g
-s%@STATIC@%%g
-s%@CCDLFLAGS@%%g
-s%@LDSHARED@%ld%g
-s%@DLEXT@%o%g
-s%@STRIP@%strip%g
-s%@EXTSTATIC@%%g
-s%@binsuffix@%.exe%g
-s%@setup@%Setup.dj%g
-s%@LIBRUBY@%libruby.a%g
-s%@LIBRUBY_A@%libruby.a%g
-s%@LIBRUBYARG@%libruby.a%g
-s%@LIBRUBY_SO@%%g
-s%@SOLIBS@%%g
-s%@arch@%i386-msdosdjgpp%g
-;s%/bin/rm%rm%
-s%@DLDLIBS@%-lc%g
-s%@PREP@%%
-s%@RUBY_INSTALL_NAME@%ruby%g
-s%@RUBY_SO_NAME@%%g
-s%@arch@%i386-msdosdjgpp%g
-s%@sitedir@%${prefix}/lib/ruby/site_ruby%g
-s%@MINIRUBY@%./miniruby%
-s%@archlib@%/usr/local/lib/ruby/i386-msdosdjgpp%
-;s%|| true%%
-;/\/dev\/null/ {
-;s,/dev/null 2>&1, nul,
-;s,2> /dev/null,,
-;}
-;/^config.status/ {
-; N;N;N;N;N;d
-;}
-;s%y\.tab\.c%y_tab.c%
-/^,THIS_IS_DUMMY_PATTERN_/i\
-ac_given_srcdir=.
diff --git a/dln.c b/dln.c
index c843bee57b..a98a44c517 100644
--- a/dln.c
+++ b/dln.c
@@ -1166,7 +1166,7 @@ dln_strerror()
}
-#if defined(_AIX)
+#if defined(_AIX) && ! defined(_IA64)
static void
aix_loaderror(const char *pathname)
{
@@ -1204,7 +1204,7 @@ aix_loaderror(const char *pathname)
if (nerr == load_errtab[i].errno && load_errtab[i].errstr)
ERRBUF_APPEND(load_errtab[i].errstr);
}
- while (isdigit(*message[i])) message[i]++;
+ while (ISDIGIT(*message[i])) message[i]++;
ERRBUF_APPEND(message[i]);
ERRBUF_APPEND("\n");
}
@@ -1310,7 +1310,7 @@ dln_load(file)
}
#endif /* hpux */
-#if defined(_AIX)
+#if defined(_AIX) && ! defined(_IA64)
#define DLN_DEFINED
{
void (*init_fct)();
diff --git a/error.c b/error.c
index 4527128030..6a008cdac5 100644
--- a/error.c
+++ b/error.c
@@ -695,6 +695,13 @@ rb_sys_fail(mesg)
}
void
+rb_load_fail(path)
+ char *path;
+{
+ rb_loaderror("%s -- %s", strerror(errno), path);
+}
+
+void
rb_error_frozen(what)
char *what;
{
diff --git a/eval.c b/eval.c
index ae2ce62da9..9da8d6130a 100644
--- a/eval.c
+++ b/eval.c
@@ -6,7 +6,7 @@
$Date$
created at: Thu Jun 10 14:22:17 JST 1993
- Copyright (C) 1993-2000 Yukihiro Matsumoto
+ Copyright (C) 1993-2001 Yukihiro Matsumoto
Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
Copyright (C) 2000 Information-technology Promotion Agency, Japan
@@ -22,6 +22,25 @@
#include "st.h"
#include "dln.h"
+/* Make alloca work the best possible way. */
+#ifdef __GNUC__
+# ifndef atarist
+# ifndef alloca
+# define alloca __builtin_alloca
+# endif
+# endif /* atarist */
+#else
+# if defined(HAVE_ALLOCA_H)
+# include <alloca.h>
+# elif !defined(alloca)
+char *alloca();
+# endif
+#endif /* __GNUC__ */
+
+#ifdef _AIX
+#pragma alloca
+#endif
+
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
@@ -527,14 +546,20 @@ static struct SCOPE *top_scope;
ruby_sourceline = _frame.line; \
ruby_frame = _frame.prev; }
+struct BLOCKTAG {
+ struct RBasic super;
+ long dst;
+ long flags;
+};
+
struct BLOCK {
NODE *var;
NODE *body;
VALUE self;
struct FRAME frame;
struct SCOPE *scope;
+ struct BLOCKTAG *tag;
VALUE klass;
- struct tag *tag;
int iter;
int vmode;
int flags;
@@ -545,12 +570,23 @@ struct BLOCK {
#define BLOCK_D_SCOPE 1
#define BLOCK_DYNAMIC 2
+#define BLOCK_ORPHAN 4
static struct BLOCK *ruby_block;
+static struct BLOCKTAG*
+new_blktag()
+{
+ NEWOBJ(blktag, struct BLOCKTAG);
+ OBJSETUP(blktag, 0, T_BLKTAG);
+ blktag->dst = 0;
+ blktag->flags = 0;
+ return blktag;
+}
+
#define PUSH_BLOCK(v,b) { \
struct BLOCK _block; \
- _block.tag = prot_tag; \
+ _block.tag = new_blktag(); \
_block.var = v; \
_block.body = b; \
_block.self = self; \
@@ -566,19 +602,18 @@ static struct BLOCK *ruby_block;
_block.dyna_vars = ruby_dyna_vars; \
ruby_block = &_block;
+#define POP_BLOCK_TAG(tag) do { \
+ if ((tag)->flags & BLOCK_DYNAMIC) \
+ (tag)->flags |= BLOCK_ORPHAN; \
+ else \
+ rb_gc_force_recycle((VALUE)tag); \
+} while (0)
+
#define POP_BLOCK() \
+ POP_BLOCK_TAG(_block.tag); \
ruby_block = _block.prev; \
}
-#define PUSH_BLOCK2(b) { \
- struct BLOCK * volatile _old; \
- _old = ruby_block; \
- ruby_block = b;
-
-#define POP_BLOCK2() \
- ruby_block = _old; \
-}
-
struct RVarmap *ruby_dyna_vars;
#define PUSH_VARS() { \
struct RVarmap * volatile _old; \
@@ -586,6 +621,8 @@ struct RVarmap *ruby_dyna_vars;
ruby_dyna_vars = 0;
#define POP_VARS() \
+ if (_old && (ruby_scope->flag & SCOPE_DONT_RECYCLE)) \
+ FL_SET(_old, DVAR_DONT_RECYCLE); \
ruby_dyna_vars = _old; \
}
@@ -739,7 +776,6 @@ static struct tag *prot_tag;
_tag.frame = ruby_frame; \
_tag.iter = ruby_iter; \
_tag.prev = prot_tag; \
- _tag.retval = Qnil; \
_tag.scope = ruby_scope; \
_tag.tag = ptag; \
_tag.dst = 0; \
@@ -1051,7 +1087,7 @@ static int
error_handle(ex)
int ex;
{
- switch (ex & 0xf) {
+ switch (ex & TAG_MASK) {
case 0:
ex = 0;
break;
@@ -1122,9 +1158,13 @@ void rb_exec_end_proc _((void));
void
ruby_finalize()
{
- rb_trap_exit();
- rb_exec_end_proc();
- rb_gc_call_finalizer_at_exit();
+ PUSH_TAG(PROT_NONE);
+ if (EXEC_TAG() == 0) {
+ rb_trap_exit();
+ rb_exec_end_proc();
+ rb_gc_call_finalizer_at_exit();
+ }
+ POP_TAG();
}
void
@@ -1255,6 +1295,34 @@ rb_eval_string_wrap(str, state)
return val;
}
+static void
+jump_tag_but_local_jump(state)
+ int state;
+{
+ switch (state) {
+ case 0:
+ break;
+ case TAG_RETURN:
+ rb_raise(rb_eLocalJumpError, "unexpected return");
+ break;
+ case TAG_NEXT:
+ rb_raise(rb_eLocalJumpError, "unexpected next");
+ break;
+ case TAG_BREAK:
+ rb_raise(rb_eLocalJumpError, "unexpected break");
+ break;
+ case TAG_REDO:
+ rb_raise(rb_eLocalJumpError, "unexpected redo");
+ break;
+ case TAG_RETRY:
+ rb_raise(rb_eLocalJumpError, "retry outside of rescue clause");
+ break;
+ default:
+ JUMP_TAG(state);
+ break;
+ }
+}
+
VALUE
rb_eval_cmd(cmd, arg)
VALUE cmd, arg;
@@ -1290,28 +1358,7 @@ rb_eval_cmd(cmd, arg)
POP_TAG();
POP_CLASS();
- switch (state) {
- case 0:
- break;
- case TAG_RETURN:
- rb_raise(rb_eLocalJumpError, "unexpected return");
- break;
- case TAG_NEXT:
- rb_raise(rb_eLocalJumpError, "unexpected next");
- break;
- case TAG_BREAK:
- rb_raise(rb_eLocalJumpError, "unexpected break");
- break;
- case TAG_REDO:
- rb_raise(rb_eLocalJumpError, "unexpected redo");
- break;
- case TAG_RETRY:
- rb_raise(rb_eLocalJumpError, "retry outside of rescue clause");
- break;
- default:
- JUMP_TAG(state);
- break;
- }
+ jump_tag_but_local_jump(state);
return val;
}
@@ -1373,17 +1420,18 @@ superclass(self, node)
#define ruby_cbase (RNODE(ruby_frame->cbase)->nd_clss)
static VALUE
-ev_const_defined(cref, id)
+ev_const_defined(cref, id, self)
NODE *cref;
ID id;
+ VALUE self;
{
NODE *cbase = cref;
- while (cbase && cbase->nd_clss != rb_cObject) {
+ while (cbase) {
struct RClass *klass = RCLASS(cbase->nd_clss);
- if (klass->iv_tbl &&
- st_lookup(klass->iv_tbl, id, 0)) {
+ if (NIL_P(klass)) return rb_const_defined(CLASS_OF(self), id);
+ if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, 0)) {
return Qtrue;
}
cbase = cbase->nd_next;
@@ -1392,16 +1440,18 @@ ev_const_defined(cref, id)
}
static VALUE
-ev_const_get(cref, id)
+ev_const_get(cref, id, self)
NODE *cref;
ID id;
+ VALUE self;
{
NODE *cbase = cref;
VALUE result;
- while (cbase && cbase->nd_clss != rb_cObject) {
+ while (cbase) {
struct RClass *klass = RCLASS(cbase->nd_clss);
+ if (NIL_P(klass)) return rb_const_get(CLASS_OF(self), id);
if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, &result)) {
return result;
}
@@ -1411,27 +1461,6 @@ ev_const_get(cref, id)
}
static VALUE
-ev_const_set(cref, id, val)
- NODE *cref;
- ID id;
- VALUE val;
-{
- NODE *cbase = cref;
-
- while (cbase && cbase->nd_clss != rb_cObject) {
- struct RClass *klass = RCLASS(cbase->nd_clss);
-
- if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, 0)) {
- st_insert(klass->iv_tbl, id, val);
- return val;
- }
- cbase = cbase->nd_next;
- }
- rb_const_assign(cbase->nd_clss, id, val);
- return val;
-}
-
-static VALUE
rb_mod_nesting()
{
NODE *cbase = RNODE(ruby_frame->cbase);
@@ -1776,7 +1805,7 @@ is_defined(self, node, buf)
break;
case NODE_CONST:
- if (ev_const_defined(RNODE(ruby_frame->cbase), node->nd_vid)) {
+ if (ev_const_defined(RNODE(ruby_frame->cbase), node->nd_vid, self)) {
return "constant";
}
break;
@@ -2207,15 +2236,14 @@ rb_eval(self, n)
case NODE_FOR:
{
iter_retry:
- PUSH_BLOCK(node->nd_var, node->nd_body);
PUSH_TAG(PROT_FUNC);
+ PUSH_BLOCK(node->nd_var, node->nd_body);
state = EXEC_TAG();
if (state == 0) {
+ PUSH_ITER(ITER_PRE);
if (nd_type(node) == NODE_ITER) {
- PUSH_ITER(ITER_PRE);
result = rb_eval(self, node->nd_iter);
- POP_ITER();
}
else {
VALUE recv;
@@ -2223,13 +2251,14 @@ rb_eval(self, n)
int line = ruby_sourceline;
_block.flags &= ~BLOCK_D_SCOPE;
+ BEGIN_CALLARGS;
recv = rb_eval(self, node->nd_iter);
- PUSH_ITER(ITER_PRE);
+ END_CALLARGS;
ruby_sourcefile = file;
ruby_sourceline = line;
result = rb_call(CLASS_OF(recv),recv,each,0,0,0);
- POP_ITER();
}
+ POP_ITER();
}
else if (_block.tag->dst == state) {
state &= TAG_MASK;
@@ -2237,8 +2266,8 @@ rb_eval(self, n)
result = prot_tag->retval;
}
}
- POP_TAG();
POP_BLOCK();
+ POP_TAG();
switch (state) {
case 0:
break;
@@ -2688,7 +2717,7 @@ rb_eval(self, n)
break;
case NODE_CONST:
- result = ev_const_get(RNODE(ruby_frame->cbase), node->nd_vid);
+ result = ev_const_get(RNODE(ruby_frame->cbase), node->nd_vid, self);
break;
case NODE_CVAR: /* normal method */
@@ -3467,7 +3496,7 @@ rb_yield_0(val, self, klass, acheck)
int state;
static unsigned serial = 1;
- if (!ruby_frame->iter || !ruby_block) {
+ if (!(rb_block_given_p() || rb_f_block_given_p()) || !ruby_block) {
rb_raise(rb_eLocalJumpError, "yield called out of block");
}
@@ -3489,7 +3518,7 @@ rb_yield_0(val, self, klass, acheck)
ruby_dyna_vars = block->dyna_vars;
}
ruby_class = klass?klass:block->klass;
- if (!self) self = block->self;
+ if (!klass) self = block->self;
node = block->body;
if (block->var) {
@@ -3526,7 +3555,7 @@ rb_yield_0(val, self, klass, acheck)
if (!node) {
result = Qnil;
}
- else if (nd_type(node) == NODE_CFUNC) {
+ else if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) {
if (val == Qundef) val = rb_ary_new2(0);
result = (*node->nd_cfnc)(val, node->nd_tval, self);
}
@@ -3548,7 +3577,7 @@ rb_yield_0(val, self, klass, acheck)
case TAG_RETURN:
state |= (serial++ << 8);
state |= 0x10;
- block->tag->dst = state;
+ block->tag->dst = state;
break;
default:
break;
@@ -3558,26 +3587,56 @@ rb_yield_0(val, self, klass, acheck)
pop_state:
POP_ITER();
POP_CLASS();
- if ((block->flags & BLOCK_D_SCOPE) &&
+#if 0
+ if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&
+ (!(ruby_scope->flags & SCOPE_DONT_RECYCLE) ||
+ !(block->tag->flags & BLOCK_DYNAMIC) ||
+ !FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE))) {
+ struct RVarmap *vars, *tmp;
+
+ if (ruby_dyna_vars->id == 0) {
+ vars = ruby_dyna_vars->next;
+ rb_gc_force_recycle((VALUE)ruby_dyna_vars);
+ while (vars && vars->id != 0) {
+ tmp = vars->next;
+ rb_gc_force_recycle((VALUE)vars);
+ vars = tmp;
+ }
+ }
+ }
+#else
+ if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&
!FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {
struct RVarmap *vars = ruby_dyna_vars;
- while (vars && vars->id != 0) {
- struct RVarmap *tmp = vars->next;
- rb_gc_force_recycle((VALUE)vars);
- vars = tmp;
- }
- if (ruby_dyna_vars && ruby_dyna_vars->id == 0) {
+ if (ruby_dyna_vars->id == 0) {
+ vars = ruby_dyna_vars->next;
rb_gc_force_recycle((VALUE)ruby_dyna_vars);
+ while (vars && vars->id != 0) {
+ struct RVarmap *tmp = vars->next;
+ rb_gc_force_recycle((VALUE)vars);
+ vars = tmp;
+ }
}
}
+#endif
POP_VARS();
ruby_block = block;
ruby_frame = ruby_frame->prev;
if (ruby_scope->flag & SCOPE_DONT_RECYCLE)
scope_dup(old_scope);
ruby_scope = old_scope;
- if (state) JUMP_TAG(state);
+ if (state) {
+ if (!block->tag) {
+ switch (state & TAG_MASK) {
+ case TAG_BREAK:
+ case TAG_RETURN:
+ jump_tag_but_local_jump(state & TAG_MASK);
+ break;
+ }
+ }
+ JUMP_TAG(state);
+ }
return result;
}
@@ -3744,7 +3803,7 @@ rb_iterate(it_proc, data1, bl_proc, data2)
{
int state;
volatile VALUE retval = Qnil;
- NODE *node = NEW_CFUNC(bl_proc, data2);
+ NODE *node = NEW_IFUNC(bl_proc, data2);
VALUE self = ruby_top_self;
iter_retry:
@@ -4072,7 +4131,7 @@ stack_length(p)
alloca(0);
# define STACK_END (&stack_end)
#else
-# if defined(__GNUC__) && !defined(__alpha__) && !defined(__APPLE__)
+# if defined(__GNUC__) && defined(__i386__)
VALUE *stack_end = __builtin_frame_address(0);
# else
VALUE *stack_end = alloca(1);
@@ -4081,7 +4140,7 @@ stack_length(p)
#endif
if (p) *p = STACK_END;
-#ifdef sparc
+#ifdef __sparc__
return rb_gc_stack_start - STACK_END + 0x80;
#else
return (STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END
@@ -4379,21 +4438,14 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper)
case 0:
break;
- case TAG_NEXT:
- rb_raise(rb_eLocalJumpError, "unexpected next");
- break;
- case TAG_BREAK:
- rb_raise(rb_eLocalJumpError, "unexpected break");
- break;
- case TAG_REDO:
- rb_raise(rb_eLocalJumpError, "unexpected redo");
- break;
case TAG_RETRY:
- if (!rb_block_given_p()) {
- rb_raise(rb_eLocalJumpError, "retry outside of rescue clause");
+ if (rb_block_given_p()) {
+ break;
}
+ /* fall through */
default:
- JUMP_TAG(state);
+ jump_tag_but_local_jump(state);
+ break;
}
}
}
@@ -4416,6 +4468,9 @@ rb_call(klass, recv, mid, argc, argv, scope)
ID id = mid;
struct cache_entry *ent;
+ if (!klass) {
+ rb_raise(rb_eNotImpError, "method call on terminated object");
+ }
/* is it in the method cache? */
ent = cache + EXPR1(klass, mid);
if (ent->mid == mid && ent->klass == klass) {
@@ -4701,7 +4756,6 @@ eval(self, src, scope, file, line)
}
Data_Get_Struct(scope, struct BLOCK, data);
-
/* PUSH BLOCK from data */
frame = data->frame;
frame.tmp = ruby_frame; /* gc protection */
@@ -4747,14 +4801,33 @@ eval(self, src, scope, file, line)
POP_CLASS();
ruby_in_eval--;
if (!NIL_P(scope)) {
+ int dont_recycle = ruby_scope->flag & SCOPE_DONT_RECYCLE;
+
ruby_frame = frame.tmp;
- if (ruby_scope->flag & SCOPE_DONT_RECYCLE)
- scope_dup(old_scope);
ruby_scope = old_scope;
ruby_block = old_block;
ruby_dyna_vars = old_dyna_vars;
data->vmode = scope_vmode; /* write back visibility mode */
scope_vmode = old_vmode;
+ if (dont_recycle) {
+ struct tag *tag;
+ struct RVarmap *vars;
+
+ scope_dup(ruby_scope);
+ for (tag=prot_tag; tag; tag=tag->prev) {
+ scope_dup(tag->scope);
+ }
+ if (ruby_block) {
+ struct BLOCK *block = ruby_block;
+ while (block) {
+ block->tag->flags |= BLOCK_DYNAMIC;
+ block = block->prev;
+ }
+ }
+ for (vars = ruby_dyna_vars; vars; vars = vars->next) {
+ FL_SET(vars, DVAR_DONT_RECYCLE);
+ }
+ }
}
else {
ruby_frame->iter = iter;
@@ -5093,7 +5166,7 @@ rb_load(fname, wrap)
rb_exc_raise(ruby_errinfo);
}
TMP_PROTECT_END;
- if (state) JUMP_TAG(state);
+ if (state) jump_tag_but_local_jump(state);
if (!NIL_P(ruby_errinfo)) /* exception during load */
rb_exc_raise(ruby_errinfo);
}
@@ -5167,7 +5240,7 @@ rb_feature_p(feature, wait)
while (st_lookup(loading_tbl, f, &th)) {
if (th == curr_thread) {
- rb_raise(rb_eLoadError, "infinite load loop -- %s", f);
+ return Qtrue;
}
CHECK_INTS;
rb_thread_schedule();
@@ -5333,6 +5406,15 @@ rb_require(fname)
}
static void
+secure_visibility(self)
+ VALUE self;
+{
+ if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
+ rb_raise(rb_eSecurityError, "Insecure: can't change method visibility");
+ }
+}
+
+static void
set_method_visibility(self, argc, argv, ex)
VALUE self;
int argc;
@@ -5341,6 +5423,7 @@ set_method_visibility(self, argc, argv, ex)
{
int i;
+ secure_visibility(self);
for (i=0; i<argc; i++) {
rb_export_method(self, rb_to_id(argv[i]), ex);
}
@@ -5352,6 +5435,7 @@ rb_mod_public(argc, argv, module)
VALUE *argv;
VALUE module;
{
+ secure_visibility(module);
if (argc == 0) {
SCOPE_SET(SCOPE_PUBLIC);
}
@@ -5367,6 +5451,7 @@ rb_mod_protected(argc, argv, module)
VALUE *argv;
VALUE module;
{
+ secure_visibility(module);
if (argc == 0) {
SCOPE_SET(SCOPE_PROTECTED);
}
@@ -5382,6 +5467,7 @@ rb_mod_private(argc, argv, module)
VALUE *argv;
VALUE module;
{
+ secure_visibility(module);
if (argc == 0) {
SCOPE_SET(SCOPE_PRIVATE);
}
@@ -5441,6 +5527,7 @@ rb_mod_modfunc(argc, argv, module)
rb_raise(rb_eTypeError, "module_function must be called for modules");
}
+ secure_visibility(module);
if (argc == 0) {
SCOPE_SET(SCOPE_MODFUNC);
return module;
@@ -5883,6 +5970,7 @@ blk_mark(data)
rb_gc_mark(data->self);
rb_gc_mark(data->dyna_vars);
rb_gc_mark(data->klass);
+ rb_gc_mark(data->tag);
data = data->prev;
}
}
@@ -5925,6 +6013,7 @@ blk_copy_prev(block)
MEMCPY(tmp->frame.argv, block->prev->frame.argv, VALUE, tmp->frame.argc);
}
scope_dup(tmp->scope);
+ tmp->tag->flags |= BLOCK_DYNAMIC;
block->prev = tmp;
block = tmp;
}
@@ -5980,7 +6069,7 @@ static VALUE
rb_f_binding(self)
VALUE self;
{
- struct BLOCK *data;
+ struct BLOCK *data, *p;
struct RVarmap *vars;
VALUE bind;
@@ -6002,10 +6091,14 @@ rb_f_binding(self)
else {
data->prev = 0;
}
+ data->flags |= BLOCK_DYNAMIC;
+ data->tag->flags |= BLOCK_DYNAMIC;
- for (vars = data->dyna_vars; vars; vars = vars->next) {
- if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
- FL_SET(vars, DVAR_DONT_RECYCLE);
+ for (p = data; p; p = p->prev) {
+ for (vars = p->dyna_vars; vars; vars = vars->next) {
+ if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
+ FL_SET(vars, DVAR_DONT_RECYCLE);
+ }
}
scope_dup(data->scope);
POP_BLOCK();
@@ -6063,11 +6156,11 @@ proc_new(klass)
VALUE klass;
{
volatile VALUE proc;
- struct BLOCK *data;
+ struct BLOCK *data, *p;
struct RVarmap *vars;
if (!rb_block_given_p() && !rb_f_block_given_p()) {
- rb_raise(rb_eArgError, "tried to create Procedure-Object without a block");
+ rb_raise(rb_eArgError, "tried to create Proc object without a block");
}
proc = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data);
@@ -6075,7 +6168,6 @@ proc_new(klass)
data->orig_thread = rb_thread_current();
data->iter = data->prev?Qtrue:Qfalse;
- data->tag = 0; /* should not point into stack */
frame_dup(&data->frame);
if (data->iter) {
blk_copy_prev(data);
@@ -6084,10 +6176,13 @@ proc_new(klass)
data->prev = 0;
}
data->flags |= BLOCK_DYNAMIC;
+ data->tag->flags |= BLOCK_DYNAMIC;
- for (vars = data->dyna_vars; vars; vars = vars->next) {
- if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
- FL_SET(vars, DVAR_DONT_RECYCLE);
+ for (p = data; p; p = p->prev) {
+ for (vars = p->dyna_vars; vars; vars = vars->next) {
+ if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
+ FL_SET(vars, DVAR_DONT_RECYCLE);
+ }
}
scope_dup(data->scope);
proc_save_safe_level(proc);
@@ -6165,6 +6260,8 @@ proc_call(proc, args)
old_block = ruby_block;
_block = *data;
ruby_block = &_block;
+ ruby_block->frame.iter = ITER_NOT;
+
PUSH_ITER(ITER_CUR);
ruby_frame->iter = ITER_CUR;
@@ -6172,17 +6269,7 @@ proc_call(proc, args)
args = callargs(args);
}
- if (orphan) {/* orphan procedure */
- if (rb_block_given_p()) {
- ruby_block->frame.iter = ITER_CUR;
- }
- else {
- ruby_block->frame.iter = ITER_NOT;
- }
- }
-
PUSH_TAG(PROT_NONE);
- _block.tag = prot_tag;
state = EXEC_TAG();
if (state == 0) {
proc_set_safe_level(proc);
@@ -6243,6 +6330,37 @@ proc_arity(proc)
}
static VALUE
+proc_eq(self, other)
+ VALUE self, other;
+{
+ struct BLOCK *data, *data2;
+
+ if (TYPE(other) != T_DATA) return Qfalse;
+ if (RDATA(other)->dmark != (RUBY_DATA_FUNC)blk_mark) Qfalse;
+ Data_Get_Struct(self, struct BLOCK, data);
+ Data_Get_Struct(other, struct BLOCK, data2);
+ if (data->tag == data2->tag) return Qtrue;
+ return Qfalse;
+}
+
+static VALUE
+proc_to_s(self, other)
+ VALUE self, other;
+{
+ struct BLOCK *data;
+ char *cname = rb_class2name(CLASS_OF(self));
+ VALUE str;
+
+ Data_Get_Struct(self, struct BLOCK, data);
+ str = rb_str_new(0, strlen(cname)+6+16+1); /* 6:tags 16:addr 1:eos */
+ sprintf(RSTRING(str)->ptr, "#<%s:0x%lx>", cname, data->tag);
+ RSTRING(str)->len = strlen(RSTRING(str)->ptr);
+ if (OBJ_TAINTED(self)) OBJ_TAINT(str);
+
+ return str;
+}
+
+static VALUE
block_pass(self, node)
VALUE self;
NODE *node;
@@ -6278,7 +6396,6 @@ block_pass(self, node)
ruby_frame->iter = ITER_PRE;
PUSH_TAG(PROT_NONE);
- _block.tag = prot_tag;
state = EXEC_TAG();
if (state == 0) {
proc_set_safe_level(block);
@@ -6300,25 +6417,33 @@ block_pass(self, node)
}
ptr = ptr->prev;
}
+ if (!ptr) {
+ state &= TAG_MASK;
+ }
}
}
ruby_block = old_block;
ruby_safe_level = safe;
- if (state) {
- switch (state) {/* escape from orphan procedure */
- case TAG_BREAK:
+ switch (state) {/* escape from orphan procedure */
+ case 0:
+ break;
+ case TAG_BREAK:
+ if (orphan) {
rb_raise(rb_eLocalJumpError, "break from proc-closure");
- break;
- case TAG_RETRY:
- rb_raise(rb_eLocalJumpError, "retry from proc-closure");
- break;
- case TAG_RETURN:
+ }
+ break;
+ case TAG_RETRY:
+ rb_raise(rb_eLocalJumpError, "retry from proc-closure");
+ break;
+ case TAG_RETURN:
+ if (orphan) {
rb_raise(rb_eLocalJumpError, "return from proc-closure");
- break;
}
+ default:
JUMP_TAG(state);
}
+
return result;
}
@@ -6611,7 +6736,7 @@ rb_mod_define_method(argc, argv, mod)
VALUE mod;
{
ID id;
- VALUE name, body;
+ VALUE body;
if (argc == 1) {
id = rb_to_id(argv[0]);
@@ -6630,7 +6755,7 @@ rb_mod_define_method(argc, argv, mod)
if (RDATA(body)->dmark == (RUBY_DATA_FUNC)bm_mark) {
rb_add_method(mod, id, NEW_DMETHOD(method_unbind(body)), NOEX_PUBLIC);
}
- else if (RDATA(body)->dmark != (RUBY_DATA_FUNC)blk_mark) {
+ else if (RDATA(body)->dmark == (RUBY_DATA_FUNC)blk_mark) {
rb_add_method(mod, id, NEW_BMETHOD(body), NOEX_PUBLIC);
}
else {
@@ -6652,6 +6777,8 @@ Init_Proc()
rb_define_method(rb_cProc, "call", proc_call, -2);
rb_define_method(rb_cProc, "arity", proc_arity, 0);
rb_define_method(rb_cProc, "[]", proc_call, -2);
+ rb_define_method(rb_cProc, "==", proc_eq, 1);
+ rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
rb_define_global_function("proc", rb_f_lambda, 0);
rb_define_global_function("lambda", rb_f_lambda, 0);
rb_define_global_function("binding", rb_f_binding, 0);
@@ -6758,7 +6885,9 @@ struct thread {
VALUE thread;
};
-#define THREAD_RAISED 0x200
+#define THREAD_RAISED 0x200 /* temporary flag */
+#define THREAD_TERMINATING 0x400 /* persistent flag */
+#define THREAD_FLAGS_MASK 0x400 /* mask for persistent flags */
#define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
#define END_FOREACH_FROM(f,x) } while (x != f)
@@ -6868,6 +6997,8 @@ rb_thread_check(data)
return (rb_thread_t)RDATA(data)->data;
}
+static VALUE rb_thread_raise _((int, VALUE*, rb_thread_t));
+
static int th_raise_argc;
static VALUE th_raise_argv[2];
static char *th_raise_file;
@@ -6908,7 +7039,8 @@ rb_thread_save_context(th)
th->wrapper = ruby_wrapper;
th->dyna_vars = ruby_dyna_vars;
th->block = ruby_block;
- th->flags = scope_vmode | (rb_trap_immediate<<8);
+ th->flags &= THREAD_FLAGS_MASK;
+ th->flags |= (rb_trap_immediate<<8) | scope_vmode;
th->iter = ruby_iter;
th->tag = prot_tag;
th->tracing = tracing;
@@ -7055,13 +7187,8 @@ rb_thread_fd_close(fd)
FOREACH_THREAD(th) {
if ((th->wait_for & WAIT_FD) && fd == th->fd) {
- th_raise_argc = 1;
- th_raise_argv[0] = rb_exc_new2(rb_eIOError, "stream closed");
- th_raise_file = ruby_sourcefile;
- th_raise_line = ruby_sourceline;
- curr_thread = th;
- rb_thread_ready(th);
- rb_thread_restore_context(curr_thread, RESTORE_RAISE);
+ VALUE exc = rb_exc_new2(rb_eIOError, "stream closed");
+ rb_thread_raise(1, &exc, th);
}
}
END_FOREACH(th);
@@ -7339,8 +7466,11 @@ rb_thread_schedule()
curr_thread = next;
if (next->status == THREAD_TO_KILL) {
- /* execute ensure-clause if any */
- rb_thread_restore_context(next, RESTORE_FATAL);
+ if (!(next->flags & THREAD_TERMINATING)) {
+ next->flags |= THREAD_TERMINATING;
+ /* terminate; execute ensure-clause if any */
+ rb_thread_restore_context(next, RESTORE_FATAL);
+ }
}
rb_thread_restore_context(next, RESTORE_NORMAL);
}
@@ -7349,6 +7479,7 @@ void
rb_thread_wait_fd(fd)
int fd;
{
+ if (rb_thread_critical) return;
if (curr_thread == curr_thread->next) return;
if (curr_thread->status == THREAD_TO_KILL) return;
@@ -7362,6 +7493,7 @@ int
rb_thread_fd_writable(fd)
int fd;
{
+ if (rb_thread_critical) return Qtrue;
if (curr_thread == curr_thread->next) return Qtrue;
if (curr_thread->status == THREAD_TO_KILL) return Qtrue;
@@ -7382,7 +7514,8 @@ rb_thread_wait_for(time)
{
double date;
- if (curr_thread == curr_thread->next ||
+ if (rb_thread_critical ||
+ curr_thread == curr_thread->next ||
curr_thread->status == THREAD_TO_KILL) {
int n;
#ifndef linux
@@ -7447,7 +7580,8 @@ rb_thread_select(max, read, write, except, timeout)
(double)timeout->tv_sec+(double)timeout->tv_usec*1e-6;
}
- if (curr_thread == curr_thread->next ||
+ if (rb_thread_critical ||
+ curr_thread == curr_thread->next ||
curr_thread->status == THREAD_TO_KILL) {
#ifndef linux
struct timeval tv, *tvp = timeout;
@@ -7513,6 +7647,7 @@ rb_thread_join(thread)
rb_thread_t th = rb_thread_check(thread);
enum thread_status last_status = THREAD_RUNNABLE;
+ if (rb_thread_critical) rb_thread_deadlock();
if (!rb_thread_dead(th)) {
if (th == curr_thread)
rb_raise(rb_eThreadError, "thread tried to join itself");
@@ -7612,8 +7747,8 @@ rb_thread_kill(thread)
rb_thread_ready(th);
th->gid = 0;
th->status = THREAD_TO_KILL;
- rb_thread_schedule();
- return Qnil; /* not reached */
+ if (!rb_thread_critical) rb_thread_schedule();
+ return thread;
}
static VALUE
@@ -7780,6 +7915,7 @@ rb_thread_abort_exc_set(thread, val)
\
th->status = THREAD_RUNNABLE;\
th->result = 0;\
+ th->flags = 0;\
\
th->stk_ptr = 0;\
th->stk_len = 0;\
@@ -7846,8 +7982,6 @@ catch_timer(sig)
int rb_thread_tick = THREAD_TICK;
#endif
-static VALUE rb_thread_raise _((int, VALUE*, rb_thread_t));
-
#define SCOPE_SHARED FL_USER1
#if defined(HAVE_SETITIMER)
@@ -8018,8 +8152,6 @@ static VALUE
rb_thread_start(klass, args)
VALUE klass, args;
{
- rb_thread_t th;
-
if (!rb_block_given_p()) {
rb_raise(rb_eThreadError, "must be called with a block");
}
@@ -8366,6 +8498,14 @@ rb_callcc(self)
for (tag=prot_tag; tag; tag=tag->prev) {
scope_dup(tag->scope);
}
+ if (ruby_block) {
+ struct BLOCK *block = ruby_block;
+
+ while (block) {
+ block->tag->flags |= BLOCK_DYNAMIC;
+ block = block->prev;
+ }
+ }
th->thread = curr_thread->thread;
for (vars = th->dyna_vars; vars; vars = vars->next) {
diff --git a/ext/.cvsignore b/ext/.cvsignore
new file mode 100644
index 0000000000..d8b8a61d92
--- /dev/null
+++ b/ext/.cvsignore
@@ -0,0 +1 @@
+extmk.rb
diff --git a/ext/curses/.cvsignore b/ext/curses/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/curses/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/curses/extconf.rb b/ext/curses/extconf.rb
index 5c6881164a..c16ab00f28 100644
--- a/ext/curses/extconf.rb
+++ b/ext/curses/extconf.rb
@@ -1,5 +1,9 @@
require 'mkmf'
+dir_config('curses')
+dir_config('ncurses')
+dir_config('termcap')
+
make=false
have_library("mytinfo", "tgetent") if /bow/ =~ RUBY_PLATFORM
if have_header("ncurses.h") and have_library("ncurses", "initscr")
diff --git a/ext/dbm/.cvsignore b/ext/dbm/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/dbm/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/etc/.cvsignore b/ext/etc/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/etc/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index 92d11d0f6e..747f685e83 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -370,7 +370,7 @@ def create_makefile(target)
if $configure_args['--enable-shared'] or "@LIBRUBY@" != "@LIBRUBY_A@"
$libs = "@LIBRUBYARG@ " + $libs
- $LIBPATH |= [$topdir]
+ $LIBPATH.unshift $topdir
end
defflag = ''
@@ -505,6 +505,9 @@ EOS
mfile.print "
.c.@OBJEXT@:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(subst /,\\\\,$<)
+
+.cc.@OBJEXT@ .cpp.@OBJEXT@ .cxx.@OBJEXT@ .C.@OBJEXT@:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(subst /,\\\\,$<)
"
end
diff --git a/ext/fcntl/.cvsignore b/ext/fcntl/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/fcntl/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/gdbm/.cvsignore b/ext/gdbm/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/gdbm/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/md5/.cvsignore b/ext/md5/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/md5/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/nkf/.cvsignore b/ext/nkf/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/nkf/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/pty/.cvsignore b/ext/pty/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/pty/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/pty/extconf.rb b/ext/pty/extconf.rb
index 4df2011eb5..ba2b44c70b 100644
--- a/ext/pty/extconf.rb
+++ b/ext/pty/extconf.rb
@@ -1,10 +1,12 @@
require 'mkmf'
-have_header("sys/stropts.h")
-have_func("setresuid")
-$CFLAGS << "-DHAVE_DEV_PTMX" if /cygwin/ === RUBY_PLATFORM
-if have_func("openpty") or
- have_func("_getpty") or
- have_func("ioctl")
- create_makefile('pty')
+if /mswin32|mingw/ !~ RUBY_PLATFORM
+ have_header("sys/stropts.h")
+ have_func("setresuid")
+ $CFLAGS << "-DHAVE_DEV_PTMX" if /cygwin/ === RUBY_PLATFORM
+ if have_func("openpty") or
+ have_func("_getpty") or
+ have_func("ioctl")
+ create_makefile('pty')
+ end
end
diff --git a/ext/readline/.cvsignore b/ext/readline/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/readline/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/sdbm/.cvsignore b/ext/sdbm/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/sdbm/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/sdbm/_sdbm.c b/ext/sdbm/_sdbm.c
index 7a31472930..92c96f26d0 100644
--- a/ext/sdbm/_sdbm.c
+++ b/ext/sdbm/_sdbm.c
@@ -103,11 +103,9 @@ static int duppair proto((char *, datum));
/*
* externals
*/
-#ifndef sun
-#ifndef MSDOS
+#if !defined(sun) && !defined(MSDOS) && !defined(_WIN32)
extern int errno;
#endif
-#endif
/*
* forward
diff --git a/ext/socket/.cvsignore b/ext/socket/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/socket/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/tcltklib/.cvsignore b/ext/tcltklib/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/tcltklib/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/ext/tk/.cvsignore b/ext/tk/.cvsignore
new file mode 100644
index 0000000000..f3c7a7c5da
--- /dev/null
+++ b/ext/tk/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/file.c b/file.c
index 98098f9047..45b6790880 100644
--- a/file.c
+++ b/file.c
@@ -67,7 +67,7 @@ char *strrchr _((const char*,const char));
#include <sys/stat.h>
#ifndef HAVE_LSTAT
-#define lstat stat
+#define lstat rb_sys_stat
#endif
VALUE rb_cFile;
@@ -314,7 +314,7 @@ rb_stat(file, st)
#if defined DJGPP
if (RSTRING(file)->len == 0) return -1;
#endif
- return stat(RSTRING(file)->ptr, st);
+ return rb_sys_stat(RSTRING(file)->ptr, st);
}
static VALUE
@@ -324,7 +324,7 @@ rb_file_s_stat(obj, fname)
struct stat st;
Check_SafeStr(fname);
- if (stat(RSTRING(fname)->ptr, &st) == -1) {
+ if (rb_sys_stat(RSTRING(fname)->ptr, &st) == -1) {
rb_sys_fail(RSTRING(fname)->ptr);
}
return stat_new(&st);
@@ -420,7 +420,7 @@ eaccess(path, mode)
struct stat st;
static int euid = -1;
- if (stat(path, &st) < 0) return (-1);
+ if (rb_sys_stat(path, &st) < 0) return (-1);
if (euid == -1)
euid = geteuid ();
@@ -722,7 +722,7 @@ check3rdbyte(file, mode)
{
struct stat st;
- if (stat(file, &st) < 0) return Qfalse;
+ if (rb_sys_stat(file, &st) < 0) return Qfalse;
if (st.st_mode & mode) return Qtrue;
return Qfalse;
}
@@ -1170,8 +1170,13 @@ rb_file_s_rename(obj, from, to)
Check_SafeStr(from);
Check_SafeStr(to);
- if (rename(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
+ if (rename(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0) {
+#if defined __CYGWIN__
+ extern unsigned long __attribute__((stdcall)) GetLastError();
+ errno = GetLastError(); /* This is a Cygwin bug */
+#endif
rb_sys_fail(RSTRING(from)->ptr);
+ }
return INT2FIX(0);
}
@@ -1253,7 +1258,7 @@ rb_file_s_expand_path(argc, argv)
}
#if defined DOSISH
/* skip drive letter */
- else if (isalpha(s[0]) && s[1] == ':' && isdirsep(s[2])) {
+ else if (ISALPHA(s[0]) && s[1] == ':' && isdirsep(s[2])) {
while (*s && !isdirsep(*s)) {
*p++ = *s++;
}
@@ -2029,6 +2034,7 @@ path_check_1(path)
}
for (;;) {
if (stat(path, &st) == 0 && (st.st_mode & 002)) {
+ if (p) *p = '/';
return 0;
}
s = strrchr(path, '/');
@@ -2056,7 +2062,10 @@ rb_path_check(path)
if (pend) *pend = '\0';
safe = path_check_1(p);
- if (!safe) return 0;
+ if (!safe) {
+ if (pend) *pend = sep;
+ return 0;
+ }
if (!pend) break;
*pend = sep;
p = pend + 1;
diff --git a/gc.c b/gc.c
index a3578aef2f..e470ea9407 100644
--- a/gc.c
+++ b/gc.c
@@ -31,6 +31,25 @@ void rb_io_fptr_finalize _((struct OpenFile*));
#endif
#endif
+/* Make alloca work the best possible way. */
+#ifdef __GNUC__
+# ifndef atarist
+# ifndef alloca
+# define alloca __builtin_alloca
+# endif
+# endif /* atarist */
+#else
+# if defined(HAVE_ALLOCA_H)
+# include <alloca.h>
+# elif !defined(alloca)
+char *alloca();
+# endif
+#endif /* __GNUC__ */
+
+#ifdef _AIX
+#pragma alloca
+#endif
+
#ifdef C_ALLOCA
#ifndef alloca
void *alloca();
@@ -53,10 +72,17 @@ static void
mem_error(mesg)
char *mesg;
{
+ static int recurse = 0;
+
if (rb_safe_level() >= 4) {
rb_raise(rb_eNoMemError, mesg);
}
- rb_fatal(mesg);
+ if (recurse == 0) {
+ recurse++;
+ rb_fatal(mesg);
+ }
+ fprintf(stderr, "[FATAL] failed to allocate memory\n");
+ exit(1);
}
void *
@@ -308,10 +334,7 @@ rb_data_object_alloc(klass, datap, dmark, dfree)
extern st_table *rb_class_tbl;
VALUE *rb_gc_stack_start = 0;
-#if defined(__GNUC__) && __GNUC__ >= 2
-__inline__
-#endif
-static int
+static inline int
is_pointer_to_heap(ptr)
void *ptr;
{
@@ -606,6 +629,7 @@ rb_gc_mark(ptr)
case T_REGEXP:
case T_FLOAT:
case T_BIGNUM:
+ case T_BLKTAG:
break;
case T_MATCH:
@@ -712,7 +736,7 @@ gc_sweep()
during_gc = 0;
/* clear finalization list */
- if (need_call_final && final_list) {
+ if (final_list) {
RVALUE *tmp;
if (rb_prohibit_interrupt || ruby_in_compile) {
@@ -822,6 +846,7 @@ obj_free(obj)
case T_FLOAT:
case T_VARMAP:
+ case T_BLKTAG:
break;
case T_BIGNUM:
@@ -924,7 +949,7 @@ rb_gc()
alloca(0);
# define STACK_END (&stack_end)
#else
-# if defined(__GNUC__) && !defined(__alpha__) && !defined(__APPLE__)
+# if defined(__GNUC__) && defined(__i386__)
VALUE *stack_end = __builtin_frame_address(0);
# else
VALUE *stack_end = alloca(1);
@@ -1004,7 +1029,7 @@ Init_stack(addr)
#if defined(__human68k__)
extern void *_SEND;
rb_gc_stack_start = _SEND;
-#elif defined(__GNUC__) && !defined(__alpha__) && !defined(__APPLE__)
+#elif defined(__GNUC__) && defined(__i386__)
rb_gc_stack_start = __builtin_frame_address(2);
#else
VALUE start;
@@ -1044,6 +1069,7 @@ os_live_obj()
case T_CLASS:
if (FL_TEST(p, FL_SINGLETON)) continue;
default:
+ if (!p->as.basic.klass) continue;
rb_yield((VALUE)p);
n++;
}
@@ -1076,6 +1102,7 @@ os_obj_of(of)
case T_CLASS:
if (FL_TEST(p, FL_SINGLETON)) continue;
default:
+ if (!p->as.basic.klass) continue;
if (rb_obj_is_kind_of((VALUE)p, of)) {
rb_yield((VALUE)p);
n++;
@@ -1207,8 +1234,7 @@ run_final(obj)
args[0] = RARRAY(finalizers)->ptr[i];
rb_protect(run_single_final, (VALUE)args, &status);
}
- if (finalizer_table && st_lookup(finalizer_table, obj, &table)) {
- st_delete(finalizer_table, &obj, 0);
+ if (finalizer_table && st_delete(finalizer_table, &obj, &table)) {
for (i=0; i<RARRAY(table)->len; i++) {
args[0] = RARRAY(table)->ptr[i];
rb_protect(run_single_final, (VALUE)args, &status);
@@ -1223,14 +1249,25 @@ rb_gc_call_finalizer_at_exit()
int i;
/* run finalizers */
- for (i = 0; i < heaps_used; i++) {
- p = heaps[i]; pend = p + HEAP_SLOTS;
- while (p < pend) {
- if (FL_TEST(p, FL_FINALIZE)) {
- p->as.free.flag = 0;
- run_final((VALUE)p);
+ if (need_call_final) {
+ if (deferred_final_list) {
+ p = deferred_final_list;
+ while (p) {
+ RVALUE *tmp = p;
+ p = p->as.free.next;
+ run_final((VALUE)tmp);
+ }
+ }
+ for (i = 0; i < heaps_used; i++) {
+ p = heaps[i]; pend = p + HEAP_SLOTS;
+ while (p < pend) {
+ if (FL_TEST(p, FL_FINALIZE)) {
+ FL_UNSET(p, FL_FINALIZE);
+ p->as.basic.klass = 0;
+ run_final((VALUE)p);
+ }
+ p++;
}
- p++;
}
}
/* run data object's finaliers */
@@ -1255,21 +1292,22 @@ static VALUE
id2ref(obj, id)
VALUE obj, id;
{
- unsigned long ptr;
+ unsigned long ptr, p0;
rb_secure(4);
- ptr = NUM2UINT(id);
+ p0 = ptr = NUM2UINT(id);
if (FIXNUM_P(ptr)) return (VALUE)ptr;
+ if (SYMBOL_P(ptr)) return (VALUE)ptr;
if (ptr == Qtrue) return Qtrue;
if (ptr == Qfalse) return Qfalse;
if (ptr == Qnil) return Qnil;
ptr = id ^ FIXNUM_FLAG; /* unset FIXNUM_FLAG */
if (!is_pointer_to_heap(ptr)) {
- rb_raise(rb_eRangeError, "0x%x is not id value", ptr);
+ rb_raise(rb_eRangeError, "0x%x is not id value", p0);
}
if (BUILTIN_TYPE(ptr) == 0) {
- rb_raise(rb_eRangeError, "0x%x is recycled object", ptr);
+ rb_raise(rb_eRangeError, "0x%x is recycled object", p0);
}
return (VALUE)ptr;
}
diff --git a/hash.c b/hash.c
index 2a5803c96e..eb6e73908c 100644
--- a/hash.c
+++ b/hash.c
@@ -79,16 +79,16 @@ static int
rb_any_hash(a)
VALUE a;
{
- unsigned int hval;
+ VALUE hval;
switch (TYPE(a)) {
case T_FIXNUM:
case T_SYMBOL:
- hval = a;
+ return (int)a;
break;
case T_STRING:
- hval = rb_str_hash(a);
+ return rb_str_hash(a);
break;
default:
@@ -98,9 +98,8 @@ rb_any_hash(a)
hval = rb_funcall(hval, '%', 1, INT2FIX(65439));
}
ENABLE_INTS;
- hval = FIX2LONG(hval);
+ return (int)FIX2LONG(hval);
}
- return hval;
}
static struct st_hash_type objhash = {
diff --git a/intern.h b/intern.h
index 7d8b0de130..9b490bd996 100644
--- a/intern.h
+++ b/intern.h
@@ -41,6 +41,7 @@ VALUE rb_ary_sort _((VALUE));
VALUE rb_ary_sort_bang _((VALUE));
VALUE rb_ary_delete _((VALUE, VALUE));
VALUE rb_ary_delete_at _((VALUE, long));
+VALUE rb_ary_clear _((VALUE));
VALUE rb_ary_plus _((VALUE, VALUE));
VALUE rb_ary_concat _((VALUE, VALUE));
VALUE rb_ary_assoc _((VALUE, VALUE));
@@ -107,7 +108,8 @@ VALUE rb_exc_new3 _((VALUE, VALUE));
void rb_loaderror __((const char*, ...)) NORETURN;
void rb_compile_error __((const char*, ...));
void rb_compile_error_append __((const char*, ...));
-void rb_error_frozen _((char*));
+void rb_load_fail _((char*)) NORETURN;
+void rb_error_frozen _((char*)) NORETURN;
/* eval.c */
void rb_exc_raise _((VALUE)) NORETURN;
void rb_exc_fatal _((VALUE)) NORETURN;
diff --git a/io.c b/io.c
index a422cc0869..0375b87cc4 100644
--- a/io.c
+++ b/io.c
@@ -2156,7 +2156,9 @@ rb_f_p(argc, argv)
for (i=0; i<argc; i++) {
rb_p(argv[i]);
}
+ if (TYPE(rb_defout) == T_FILE) {
rb_io_flush(rb_defout);
+ }
return Qnil;
}
@@ -2238,8 +2240,6 @@ set_outfile(val, var, orig, stdf)
GetOpenFile(val, fptr);
rb_io_check_writable(fptr);
-
- GetOpenFile(*var, fptr);
f = GetWriteFile(fptr);
dup2(fileno(f), fileno(stdf));
@@ -2281,7 +2281,7 @@ prep_stdio(f, mode, klass)
return (VALUE)io;
}
-static VALUE
+static void
prep_path(io, path)
VALUE io;
char *path;
@@ -3095,8 +3095,9 @@ argf_tell()
}
static VALUE
-argf_seek(self, offset, ptrname)
- VALUE self, offset, ptrname;
+argf_seek(argc, argv)
+ int argc;
+ VALUE *argv;
{
if (!next_argv()) {
rb_raise(rb_eArgError, "no stream to seek");
@@ -3105,7 +3106,7 @@ argf_seek(self, offset, ptrname)
if (TYPE(current_file) != T_FILE) {
return argf_forward();
}
- return rb_io_seek(current_file, offset, ptrname);
+ return rb_io_seek(argc, argv, current_file);
}
static VALUE
@@ -3474,7 +3475,7 @@ Init_IO()
rb_define_singleton_method(argf, "getc", argf_getc, 0);
rb_define_singleton_method(argf, "readchar", argf_readchar, 0);
rb_define_singleton_method(argf, "tell", argf_tell, 0);
- rb_define_singleton_method(argf, "seek", argf_seek, 2);
+ rb_define_singleton_method(argf, "seek", argf_seek, -1);
rb_define_singleton_method(argf, "rewind", argf_rewind, 0);
rb_define_singleton_method(argf, "pos", argf_tell, 0);
rb_define_singleton_method(argf, "pos=", argf_set_pos, 1);
diff --git a/lib/Env.rb b/lib/Env.rb
index 7101b84c91..452a28659e 100644
--- a/lib/Env.rb
+++ b/lib/Env.rb
@@ -6,19 +6,7 @@
# $USER = "matz"
# p ENV["USER"]
-for k,v in ENV
- next unless /^[a-zA-Z][_a-zA-Z0-9]*/ =~ k
- eval <<EOS
- $#{k} = %q!#{v}!
- trace_var "$#{k}", proc{|v|
- ENV[%q!#{k}!] = v;
- $#{k} = %q!#{v}!
- if v == nil
- untrace_var "$#{k}"
- end
- }
-EOS
-end
+require 'importenv'
if __FILE__ == $0
p $TERM
diff --git a/lib/cgi.rb b/lib/cgi.rb
index 7d27cecd67..fcf8c006e5 100644
--- a/lib/cgi.rb
+++ b/lib/cgi.rb
@@ -4,7 +4,7 @@
cgi.rb - cgi support library
-Version 2.1.2
+Version 2.1.4
Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
@@ -185,12 +185,13 @@ class CGI
CR = "\015"
LF = "\012"
EOL = CR + LF
- VERSION = "2.1.2"
- RELEASE_DATE = "2000-12-25"
- VERSION_CODE = 212
- RELEASE_CODE = 20001225
+ VERSION = '2.1.3'
+ RELEASE_DATE = '2001-03-18'
+ VERSION_CODE = 214
+ RELEASE_CODE = 20010318
+ REVISION = '$Id$'
- NEEDS_BINMODE = true if /WIN/ni === RUBY_PLATFORM
+ NEEDS_BINMODE = true if /WIN/ni.match(RUBY_PLATFORM)
PATH_SEPARATOR = {'UNIX'=>'/', 'WINDOWS'=>'\\', 'MACINTOSH'=>':'}
HTTP_STATUS = {
@@ -350,11 +351,11 @@ class CGI
=begin
=== MAKE RFC1123 DATE STRING
CGI::rfc1123_date(Time.now)
- # Sat, 1 Jan 2000 00:00:00 GMT
+ # Sat, 01 Jan 2000 00:00:00 GMT
=end
def CGI::rfc1123_date(time)
t = time.clone.gmtime
- return format("%s, %d %s %d %.2d:%.2d:%.2d GMT",
+ return format("%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT",
RFC822_DAYS[t.wday], t.day, RFC822_MONTHS[t.month-1], t.year,
t.hour, t.min, t.sec)
end
@@ -423,7 +424,8 @@ status:
options["type"].concat( options.delete("charset") )
end
- if options.delete("nph") or (/IIS/n === env_table['SERVER_SOFTWARE'])
+ options.delete("nph") if defined?(MOD_RUBY)
+ if options.delete("nph") or /IIS/n.match(env_table['SERVER_SOFTWARE'])
buf.concat( (env_table["SERVER_PROTOCOL"] or "HTTP/1.0") + " " )
buf.concat( (HTTP_STATUS[options["status"]] or
options["status"] or
@@ -446,7 +448,9 @@ status:
end
if options.has_key?("status")
- buf.concat("Status: " + options.delete("status") + EOL)
+ status = (HTTP_STATUS[options["status"]] or options["status"])
+ buf.concat("Status: " + status + EOL)
+ options.delete("status")
end
if options.has_key?("server")
@@ -496,8 +500,21 @@ status:
}
if defined?(MOD_RUBY)
- buf.scan(/([^:]+): (.+)#{EOL}/n){
- Apache::request[$1] = $2
+ table = Apache::request.headers_out
+ buf.scan(/([^:]+): (.+)#{EOL}/n){ |name, value|
+ $stderr.printf("name:%s value:%s\n", name, value) if $DEBUG
+ case name
+ when 'Set-Cookie'
+ table.add($1, $2)
+ when /^status$/ni
+ Apache::request.status_line = value
+ when /^content-type$/ni
+ Apache::request.content_type = value
+ when /^content-encoding$/ni
+ Apache::request.content_encoding = value
+ else
+ Apache::request.headers_out[name] = value
+ end
}
Apache::request.send_http_header
''
@@ -793,9 +810,9 @@ convert string charset, and set language to "ja".
body = Tempfile.new("CGI")
body.binmode
- until head and (/#{boundary}(?:#{EOL}|--)/n === buf)
+ until head and /#{boundary}(?:#{EOL}|--)/n.match(buf)
- if (not head) and (/#{EOL}#{EOL}/n === buf)
+ if (not head) and /#{EOL}#{EOL}/n.match(buf)
buf = buf.sub(/\A((?:.|\n)*?#{EOL})#{EOL}/n) do
head = $1.dup
""
@@ -834,14 +851,14 @@ convert string charset, and set language to "ja".
end
END
- /Content-Disposition:.* filename="?([^\";]*)"?/ni === head
+ /Content-Disposition:.* filename="?([^\";]*)"?/ni.match(head)
eval <<-END
def body.original_filename
#{
filename = ($1 or "").dup
- if (/Mac/ni === env_table['HTTP_USER_AGENT']) and
- (/Mozilla/ni === env_table['HTTP_USER_AGENT']) and
- (not /MSIE/ni === env_table['HTTP_USER_AGENT'])
+ if /Mac/ni.match(env_table['HTTP_USER_AGENT']) and
+ /Mozilla/ni.match(env_table['HTTP_USER_AGENT']) and
+ (not /MSIE/ni.match(env_table['HTTP_USER_AGENT']))
CGI::unescape(filename)
else
filename
@@ -850,14 +867,14 @@ convert string charset, and set language to "ja".
end
END
- /Content-Type: (.*)/ni === head
+ /Content-Type: (.*)/ni.match(head)
eval <<-END
def body.content_type
#{($1 or "").dump.untaint}.taint
end
END
- /Content-Disposition:.* name="?([^\";]*)"?/ni === head
+ /Content-Disposition:.* name="?([^\";]*)"?/ni.match(head)
name = $1.dup
if params.has_key?(name)
@@ -889,7 +906,7 @@ convert string charset, and set language to "ja".
words = Shellwords.shellwords(string)
- if words.find{|x| /=/n === x }
+ if words.find{|x| /=/n.match(x) }
words.join('&')
else
words.join('+')
@@ -899,8 +916,7 @@ convert string charset, and set language to "ja".
def initialize_query()
if ("POST" == env_table['REQUEST_METHOD']) and
- (%r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n ===
- env_table['CONTENT_TYPE'])
+ %r|\Amultipart/form-data.*boundary=\"?([^\";,]+)\"?|n.match(env_table['CONTENT_TYPE'])
boundary = $1.dup
@params = read_multipart(boundary, Integer(env_table['CONTENT_LENGTH']))
else
@@ -975,8 +991,8 @@ convert string charset, and set language to "ja".
cgi = CGI.new("html3") # add HTML generation methods
cgi.element
cgi.element{ "string" }
- cgi.element({ "ATTRILUTE1" => "value1", "ATTRIBUTE2" => "value2" })
- cgi.element({ "ATTRILUTE1" => "value1", "ATTRIBUTE2" => "value2" }){ "string" }
+ cgi.element({ "ATTRIBUTE1" => "value1", "ATTRIBUTE2" => "value2" })
+ cgi.element({ "ATTRIBUTE1" => "value1", "ATTRIBUTE2" => "value2" }){ "string" }
# add HTML generation methods
CGI.new("html3") # html3.2
@@ -1235,8 +1251,10 @@ convert string charset, and set language to "ja".
form("get", "url"){ "string" }
# <FORM METHOD="get" ACTION="url" ENCTYPE="application/x-www-form-urlencoded">string</FORM>
- form({"METHOD" => "post", ENCTYPE => "enctype"}){ "string" }
+ form({"METHOD" => "post", "ENCTYPE" => "enctype"}){ "string" }
# <FORM METHOD="post" ENCTYPE="enctype">string</FORM>
+
+The hash keys are case sensitive. Ask the samples.
=end
def form(method = "post", action = nil, enctype = "application/x-www-form-urlencoded")
attributes = if method.kind_of?(String)
@@ -1244,7 +1262,7 @@ convert string charset, and set language to "ja".
"ENCTYPE" => enctype }
else
unless method.has_key?("METHOD")
- method["METHOD"] = method
+ method["METHOD"] = "post"
end
unless method.has_key?("ENCTYPE")
method["ENCTYPE"] = enctype
@@ -1935,161 +1953,7 @@ end
== HISTORY
-* Mon Dec 25 05:02:27 JST 2000 - wakou
- * version 2.1.2
- * bug fix: CGI::escapeElement(): didn't accept empty element.
- * bug fix: CGI::unescapeElement(): ditto.
- * bug fix: CGI::unescapeHTML(): support for "&copy;, &hearts;, ..."
- thanks to YANAGAWA Kazuhisa <kjana@os.xaxon.ne.jp>
- * bug fix: CGI::unescapeHTML(): support for "&#09;"
- thanks to OHSHIMA Ryunosuke <ryu@jaist.ac.jp>
- * Regexp::last_match[0] --> $&
- * Regexp::last_match[1] --> $1
- * Regexp::last_match[2] --> $2
- * add: CGI#param(): test implement. undocumented.
-
-* Mon Dec 11 00:16:51 JST 2000 - wakou
- * version 2.1.1
- * support -T1 on ruby 1.6.2
- * body.original_filename: eval(str.dump.untaint).taint
- * body.content_type: eval(str.dump.untaint).taint
- * $& --> Regexp::last_match[0]
- * $1 --> Regexp::last_match[1]
- * $2 --> Regexp::last_match[2]
-
-* Thu Oct 12 01:16:59 JST 2000 - wakou
- * version 2.1.0
- * bug fix: CGI::html(): PRETTY option didn't work.
- thanks to akira yamada <akira@ruby-lang.org>
-
-* Wed Sep 13 06:09:26 JST 2000 - wakou
- * version 2.0.1
- * bug fix: CGI::header(): output status header.
- thanks to Yasuhiro Fukuma <yasuf@bsdclub.org>
-
-* Tue Sep 12 06:56:51 JST 2000 - wakou
- * version 2.0.0
- * require ruby1.5.4 or later. (ruby1.4 doesn't have block_given? method.)
- * improvement: CGI::escape(), CGI::unescape().
- thanks to WATANABE Hirofumi <eban@os.rim.or.jp>
- * bug fix: CGI::escapeElement().
- * improvement: CGI::unescapeHTML().
- thanks to Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
-
-* 2000/08/09 04:32:22 - matz
- * improvement: CGI::pretty()
-
-* 2000/06/23 07:01:34 - matz
- * change: iterator? --> block_given?
-
-* Sun Jun 18 23:31:44 JST 2000 - wakou
- * version 1.7.0
- * change: version syntax. old: x.yz, now: x.y.z
-
-* 2000/06/13 15:49:27 - wakou
- * version 1.61
- * read_multipart(): if no content body then raise EOFError.
-
-* 2000/06/03 18:16:17 - wakou
- * version 1.60
- * improve: CGI::pretty()
-
-* 2000/05/30 19:04:08 - wakou
- * version 1.50
- * CGI#out(): if "HEAD" == REQUEST_METHOD then output only HTTP header.
-
-* 2000/05/24 06:58:51 - wakou
- * version 1.40
- * typo: CGI::Cookie::new()
- * bug fix: CGI::escape(): bad: " " --> "%2B"; true: " " --> "+";
- thanks to Ryunosuke Ohshima <ryu@jaist.ac.jp>
-
-* 2000/05/08 21:51:30 - wakou
- * version 1.31
- * improvement of time forming new CGI object accompanied with HTML generation methods.
-
-* 2000/05/07 21:51:14 - wakou
- * version 1.30
- * require English.rb
- * improvement of load time.
-
-* 2000/05/02 21:44:12 - wakou
- * version 1.21
- * support for ruby 1.5.3 (2000-05-01) (Array#filter --> Array#collect!)
-
-* 2000/04/03 18:31:42 - wakou
- * version 1.20
- * bug fix: CGI#image_button() can't get Hash option.
- thanks to Takashi Ikeda <ikeda@auc.co.jp>
- * CGI::unescapeHTML(): simple support for "&#12345;"
- * CGI::Cookie::new(): simple support for IE
- * CGI::escape(): ' ' replaced by '+'
-
-* 1999/12/06 20:16:34 - wakou
- * version 1.10
- * can make many CGI objects.
- * if use mod_ruby, then require ruby1.4.3 or later.
-
-* 1999/11/29 21:35:58 - wakou
- * version 1.01
- * support for ruby 1.5.0 (1999-11-20)
-
-* 1999/09/13 23:00:58 - wakou
- * version 1.00
- * COUTION! name change. CGI.rb --> cgi.rb
- * CGI#auth_type, CGI#content_length, CGI#content_type, ...
- if not ENV included it, then return nil.
- * CGI#content_length and CGI#server_port return Integer.
- * if not CGI#params.include?('name'), then CGI#params['name'] return [].
- * if not CGI#cookies.include?('name'), then CGI#cookies['name'] return [].
-
-* 1999/08/05 18:04:59 - wakou
- * version 0.41
- * typo. thanks to MJ Ray <markj@altern.org>
- HTTP_STATUS["NOT_INPLEMENTED"] --> HTTP_STATUS["NOT_IMPLEMENTED"]
-
-* 1999/07/20 20:44:31 - wakou
- * version 0.40
- * COUTION! incompatible change.
- sorry, but probably this change is last big incompatible change.
- * CGI::print --> CGI#out
- cgi = CGI.new
- cgi.out{"string"} # old: CGI::print{"string"}
- * CGI::cookie --> CGI::Cookie::new
- cookie1 = CGI::Cookie::new # old: CGI::cookie
- * CGI::header --> CGI#header
-
-* 1999/06/29 06:50:21 - wakou
- * version 0.30
- * COUTION! incompatible change.
- query = CGI.new
- cookies = query.cookies # old: query.cookie
- values = query.cookies[name] # old: query.cookie[name]
-
-* 1999/06/21 21:05:57 - wakou
- * version 0.24
- * CGI::Cookie::parse() return { name => CGI::Cookie object } pairs.
-
-* 1999/06/20 23:29:12 - wakou
- * version 0.23
- * modified a bit to clear module separation.
-
-* Mon Jun 14 17:49:32 JST 1999 - matz
- * version 0.22
- * Cookies are now CGI::Cookie objects.
- * Cookie modeled after CGI::Cookie.pm.
-
-* Fri Jun 11 11:19:11 JST 1999 - matz
- * version 0.21
- * modified a bit to clear module separation.
-
-* 1999/06/03 06:48:15 - wakou
- * version 0.20
- * support for multipart form.
-
-* 1999/05/24 07:05:41 - wakou
- * version 0.10
- * first release.
-
-$Date$
+delete. see cvs log.
+
+
=end
diff --git a/lib/cgi/session.rb b/lib/cgi/session.rb
index 48f3496939..1120fb50f0 100644
--- a/lib/cgi/session.rb
+++ b/lib/cgi/session.rb
@@ -1,3 +1,4 @@
+# Copyright (C) 2001 Yukihiro "Matz" Matsumoto
# Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
# Copyright (C) 2000 Information-technology Promotion Agency, Japan
@@ -15,23 +16,22 @@ class CGI
}
end
- def create_new_id
+ def Session::create_new_id
require 'md5'
md5 = MD5::new
md5.update(String(Time::now))
md5.update(String(rand(0)))
md5.update(String($$))
md5.update('foobar')
- @session_id = md5.hexdigest[0,16]
+ md5.hexdigest[0,16]
end
- private :create_new_id
def initialize(request, option={})
session_key = option['session_key'] || '_session_id'
id, = option['session_id']
unless id
if option['new_session']
- id = create_new_id
+ id = Session::create_new_id
end
end
unless id
@@ -43,7 +43,7 @@ class CGI
if option.key?('new_session') and not option['new_session']
raise ArgumentError, "session_key `%s' should be supplied"%session_key
end
- id = create_new_id
+ id = Session::create_new_id
end
end
@session_id = id
@@ -54,7 +54,9 @@ class CGI
@output_cookies = [
Cookie::new("name" => session_key,
"value" => id,
- "path" => if ENV["SCRIPT_NAME"] then
+ "path" => if option['session_path'] then
+ option['session_path']
+ elsif ENV["SCRIPT_NAME"] then
File::dirname(ENV["SCRIPT_NAME"])
else
""
@@ -132,6 +134,7 @@ class CGI
end
def close
+ return if @f.closed?
update
@f.close
end
diff --git a/lib/date.rb b/lib/date.rb
index 58179a7153..3422121298 100644
--- a/lib/date.rb
+++ b/lib/date.rb
@@ -1,5 +1,5 @@
-# date.rb: Written by Tadayoshi Funaba 1998-2000
-# $Id: date.rb,v 1.22 2000-07-16 10:23:40+09 tadf Exp $
+# date2.rb: Written by Tadayoshi Funaba 1998-2001
+# $Id: date2.rb,v 1.23 2001-01-18 12:09:47+09 tadf Exp $
class Date
@@ -128,16 +128,15 @@ class Date
end
if d < 0
ny, nm = clfloor(y * 12 + m, 12)
- nm, = clfloor(m + 1, 1)
- la = nil
- 31.downto 1 do |z|
- break if la = exist3?(y, m, z, sg)
- end
- ns = ns?(la, sg)
- d = jd_to_civil(civil_to_jd(ny, nm, 1, ns) + d, ns)[-1]
+ nm, = clfloor(nm + 1, 1)
+ jd = civil_to_jd(ny, nm, d + 1, sg)
+ ns = ns?(jd, sg)
+ return unless [y, m] == jd_to_civil(jd, sg)[0..1]
+ return unless [ny, nm, 1] == jd_to_civil(jd - d, ns)
+ else
+ jd = civil_to_jd(y, m, d, sg)
+ return unless [y, m, d] == jd_to_civil(jd, sg)
end
- jd = civil_to_jd(y, m, d, sg)
- return unless [y, m, d] == jd_to_civil(jd, sg)
jd
end
@@ -154,16 +153,15 @@ class Date
def exist2? (y, d, sg=ITALY)
if d < 0
- ny = y + 1
- la = nil
- 366.downto 1 do |z|
- break if la = exist2?(y, z, sg)
- end
- ns = ns?(la, sg)
- d = jd_to_ordinal(ordinal_to_jd(ny, 1, ns) + d, ns)[-1]
+ ny, = clfloor(y + 1, 1)
+ jd = ordinal_to_jd(ny, d + 1, sg)
+ ns = ns?(jd, sg)
+ return unless [y] == jd_to_ordinal(jd, sg)[0..0]
+ return unless [ny, 1] == jd_to_ordinal(jd - d, ns)
+ else
+ jd = ordinal_to_jd(y, d, sg)
+ return unless [y, d] == jd_to_ordinal(jd, sg)
end
- jd = ordinal_to_jd(y, d, sg)
- return unless [y, d] == jd_to_ordinal(jd, sg)
jd
end
diff --git a/lib/debug.rb b/lib/debug.rb
index b6968cc338..220b68d2c9 100644
--- a/lib/debug.rb
+++ b/lib/debug.rb
@@ -91,22 +91,70 @@ class DEBUGGER__
@finish_pos = 0
@trace = false
@catch = "StandardError"
+ @suspend_next = false
end
def stop_next(n=1)
@stop_next = n
end
+ def set_suspend
+ @suspend_next = true
+ end
+
+ def clear_suspend
+ @suspend_next = false
+ end
+
+ def suspend_all
+ DEBUGGER__.suspend
+ end
+
+ def resume_all
+ DEBUGGER__.resume
+ end
+
+ def check_suspend
+ while (Thread.critical = true; @suspend_next)
+ DEBUGGER__.waiting.push Thread.current
+ @suspend_next = false
+ Thread.stop
+ end
+ Thread.critical = false
+ end
+
+ def trace?
+ @trace
+ end
+
+ def set_trace(arg)
+ @trace = arg
+ end
+
def stdout
DEBUGGER__.stdout
end
+
def break_points
DEBUGGER__.break_points
end
+
def display
DEBUGGER__.display
end
+ def context(th)
+ DEBUGGER__.context(th)
+ end
+
+ def set_trace_all(arg)
+ DEBUGGER__.set_trace(arg)
+ end
+
+ def set_last_thread(th)
+ DEBUGGER__.set_last_thread(th)
+ end
+
def debug_eval(str, binding)
begin
val = eval(str, binding)
@@ -205,7 +253,7 @@ class DEBUGGER__
def debug_command(file, line, id, binding)
MUTEX.lock
- DEBUGGER__.set_last_thread(Thread.current)
+ set_last_thread(Thread.current)
frame_pos = 0
binding_file = file
binding_line = line
@@ -218,7 +266,8 @@ class DEBUGGER__
end
@frames[0] = [binding, file, line, id]
display_expressions(binding)
- while input = readline("(rdb:%d) "%thnum(), true)
+ prompt = true
+ while prompt and input = readline("(rdb:%d) "%thnum(), true)
catch(:debug_error) do
if input == ""
input = DEBUG_LAST_CMD[0]
@@ -228,18 +277,24 @@ class DEBUGGER__
end
case input
- when /^\s*tr(?:ace)?(?:\s+(on|off))?$/
- if defined?( $1 )
+ when /^\s*tr(?:ace)?(?:\s+(on|off))?(?:\s+(all))?$/
+ if defined?( $2 )
if $1 == 'on'
- @trace = true
+ set_trace_all true
else
- @trace = false
+ set_trace_all false
+ end
+ elsif defined?( $1 )
+ if $1 == 'on'
+ set_trace true
+ else
+ set_trace false
end
end
- if @trace
- stdout.print "Trace on\n"
+ if trace?
+ stdout.print "Trace on.\n"
else
- stdout.print "Trace off\n"
+ stdout.print "Trace off.\n"
end
when /^\s*b(?:reak)?\s+((?:.*?+:)?.+)$/
@@ -336,8 +391,7 @@ class DEBUGGER__
end
when /^\s*c(?:ont)?$/
- MUTEX.unlock
- return
+ prompt = false
when /^\s*s(?:tep)?(?:\s+(\d+))?$/
if $1
@@ -346,7 +400,7 @@ class DEBUGGER__
lev = 1
end
@stop_next = lev
- return
+ prompt = false
when /^\s*n(?:ext)?(?:\s+(\d+))?$/
if $1
@@ -356,7 +410,7 @@ class DEBUGGER__
end
@stop_next = lev
@no_step = @frames.size - frame_pos
- return
+ prompt = false
when /^\s*w(?:here)?$/, /^\s*f(?:rame)?$/
display_frames(frame_pos)
@@ -417,8 +471,7 @@ class DEBUGGER__
else
@finish_pos = @frames.size - frame_pos
frame_pos = 0
- MUTEX.unlock
- return
+ prompt = false
end
when /^\s*cat(?:ch)?(?:\s+(.+))?$/
@@ -440,8 +493,10 @@ class DEBUGGER__
end
when /^\s*q(?:uit)?$/
- input = readline("really quit? (y/n) ", false)
- exit if input == "y"
+ input = readline("Really quit? (y/n) ", false)
+ if input == "y"
+ exit! # exit -> exit!: No graceful way to stop threads...
+ end
when /^\s*v(?:ar)?\s+/
debug_variable_info($', binding)
@@ -451,8 +506,7 @@ class DEBUGGER__
when /^\s*th(?:read)?\s+/
if DEBUGGER__.debug_thread_info($', binding) == :cont
- MUTEX.unlock
- return
+ prompt = false
end
when /^\s*p\s+/
@@ -467,6 +521,8 @@ class DEBUGGER__
end
end
end
+ MUTEX.unlock
+ resume_all
end
def debug_print_help
@@ -492,7 +548,8 @@ Commands
up[ nn] move to higher frame
down[ nn] move to lower frame
fin[ish] return to outer frame
- tr[ace][ (on|off)] set trace mode
+ tr[ace] (on|off) set trace mode of current thread
+ tr[ace] (on|off) all set trace mode of all threads
q[uit] exit from debugger
v[ar] g[lobal] show global variables
v[ar] l[ocal] show local variables
@@ -501,11 +558,10 @@ Commands
m[ethod] i[nstance] <obj> show methods of object
m[ethod] <class|module> show instance methods of class or module
th[read] l[ist] list all threads
- th[read] c[ur[rent]] show current threads
- th[read] <nnn> stop thread nnn
- th[read] stop <nnn> alias for th[read] <nnn>
- th[read] c[ur[rent]] <nnn> alias for th[read] <nnn>
- th[read] resume <nnn> run thread nnn
+ th[read] c[ur[rent]] show current thread
+ th[read] [sw[itch]] <nnn> switch thread context to nnn
+ th[read] stop <nnn> stop thread nnn
+ th[read] resume <nnn> resume thread nnn
p expression evaluate expression and print its value
h[elp] print this help
<everything else> evaluate
@@ -587,7 +643,7 @@ EOHELP
end
def check_break_points(file, pos, binding, id)
- MUTEX.lock # Stop all threads before 'line' and 'call'.
+ return false if break_points.empty?
file = File.basename(file)
n = 1
for b in break_points
@@ -604,7 +660,6 @@ EOHELP
end
n += 1
end
- MUTEX.unlock
return false
end
@@ -616,7 +671,6 @@ EOHELP
end
if @catch and ($!.type.ancestors.find { |e| e.to_s == @catch })
- MUTEX.lock
fs = @frames.size
tb = caller(0)[-fs..-1]
if tb
@@ -624,12 +678,14 @@ EOHELP
stdout.printf "\tfrom %s\n", i
end
end
+ suspend_all
debug_command(file, line, id, binding)
end
end
def trace_func(event, file, line, id, binding, klass)
- Tracer.trace_func(event, file, line, id, binding) if @trace
+ Tracer.trace_func(event, file, line, id, binding, klass) if trace?
+ context(Thread.current).check_suspend
@file = file
@line = line
case event
@@ -647,6 +703,7 @@ EOHELP
@stop_next = 1
else
@no_step = nil
+ suspend_all
debug_command(file, line, id, binding)
@last = [file, line]
end
@@ -656,6 +713,7 @@ EOHELP
@frames.unshift [binding, file, line, id]
if check_break_points(file, id.id2name, binding, id) or
check_break_points(klass.to_s, id.id2name, binding, id)
+ suspend_all
debug_command(file, line, id, binding)
end
@@ -668,6 +726,7 @@ EOHELP
when 'return', 'end'
if @frames.size == @finish_pos
@stop_next = 1
+ @finish_pos = 0
end
@frames.shift
@@ -682,19 +741,20 @@ EOHELP
end
end
- trap("INT") { DEBUGGER__.interrupt }
-# $DEBUG = true
+ trap("INT") { DEBUGGER__.interrupt }
@last_thread = Thread::main
@max_thread = 1
@thread_list = {Thread::main => 1}
@break_points = []
@display = []
+ @waiting = []
@stdout = STDOUT
class <<DEBUGGER__
def stdout
@stdout
end
+
def stdout=(s)
@stdout = s
end
@@ -707,10 +767,51 @@ EOHELP
@break_points
end
+ def waiting
+ @waiting
+ end
+
+ def set_trace( arg )
+ Thread.critical = true
+ make_thread_list
+ for th in @thread_list
+ context(th[0]).set_trace arg
+ end
+ Thread.critical = false
+ end
+
def set_last_thread(th)
@last_thread = th
end
+ def suspend
+ Thread.critical = true
+ make_thread_list
+ for th in @thread_list
+ next if th[0] == Thread.current
+ context(th[0]).set_suspend
+ end
+ Thread.critical = false
+ # Schedule other threads to suspend as soon as possible.
+ Thread.pass
+ end
+
+ def resume
+ Thread.critical = true
+ make_thread_list
+ for th in @thread_list
+ next if th[0] == Thread.current
+ context(th[0]).clear_suspend
+ end
+ waiting.each do |th|
+ th.run
+ end
+ waiting.clear
+ Thread.critical = false
+ # Schedule other threads to restart as soon as possible.
+ Thread.pass
+ end
+
def context(thread=Thread.current)
c = thread[:__debugger_data__]
unless c
@@ -726,7 +827,7 @@ EOHELP
def get_thread(num)
th = @thread_list.index(num)
unless th
- @stdout.print "no thread no.", num, "\n"
+ @stdout.print "No thread ##{num}\n"
throw :debug_error
end
th
@@ -773,31 +874,52 @@ EOHELP
make_thread_list
thread_list_all
- when /^c(?:ur(?:rent)?)?\s+(\d+)/, /^stop\s+(\d+)/, /^(\d+)/
+ when /^c(?:ur(?:rent)?)?$/
+ make_thread_list
+ thread_list(@thread_list[Thread.current])
+
+ when /^(?:sw(?:itch)?\s+)?(\d+)/
make_thread_list
th = get_thread($1.to_i)
- thread_list(@thread_list[th])
- context(th).stop_next
- th.run
- return :cont
+ if th == Thread.current
+ @stdout.print "It's the current thread.\n"
+ else
+ thread_list(@thread_list[th])
+ context(th).stop_next
+ th.run
+ return :cont
+ end
- when /^c(?:ur(?:rent)?)?$/
+ when /^stop\s+(\d+)/
make_thread_list
- thread_list(@thread_list[Thread.current])
+ th = get_thread($1.to_i)
+ if th == Thread.current
+ @stdout.print "It's the current thread.\n"
+ elsif th.stop?
+ @stdout.print "Already stopped.\n"
+ else
+ thread_list(@thread_list[th])
+ context(th).suspend
+ end
when /^resume\s+(\d+)/
make_thread_list
th = get_thread($1.to_i)
- thread_list(@thread_list[th])
- th.run
- return :cont
+ if th == Thread.current
+ @stdout.print "It's the current thread.\n"
+ elsif !th.stop?
+ @stdout.print "Already running."
+ else
+ thread_list(@thread_list[th])
+ th.run
+ end
end
end
end
stdout.printf "Debug.rb\n"
stdout.printf "Emacs support available.\n\n"
- set_trace_func proc{|event, file, line, id, binding,klass,*rest|
- DEBUGGER__.context.trace_func event, file, line, id, binding,klass
+ set_trace_func proc { |event, file, line, id, binding, klass, *rest|
+ DEBUGGER__.context.trace_func event, file, line, id, binding, klass
}
end
diff --git a/lib/delegate.rb b/lib/delegate.rb
index 480e1ef6b8..a72ea943ba 100644
--- a/lib/delegate.rb
+++ b/lib/delegate.rb
@@ -8,7 +8,7 @@
# Usage:
# foo = Object.new
# foo2 = SimpleDelegator.new(foo)
-# foo.hash == foo2.hash # => true
+# foo.hash == foo2.hash # => false
#
# Foo = DelegateClass(Array)
#
diff --git a/lib/importenv.rb b/lib/importenv.rb
index fcf306a9ab..586f37661b 100644
--- a/lib/importenv.rb
+++ b/lib/importenv.rb
@@ -10,10 +10,10 @@
for k,v in ENV
next unless /^[a-zA-Z][_a-zA-Z0-9]*/ =~ k
eval <<EOS
- $#{k} = %q!#{v}!
+ $#{k} = v
trace_var "$#{k}", proc{|v|
- ENV[%q!#{k}!] = v;
- $#{k} = %q!#{v}!
+ ENV[%q!#{k}!] = v
+ $#{k} = v
if v == nil
untrace_var "$#{k}"
end
diff --git a/lib/irb/ruby-lex.rb b/lib/irb/ruby-lex.rb
index 4c7a3b1002..534870e329 100644
--- a/lib/irb/ruby-lex.rb
+++ b/lib/irb/ruby-lex.rb
@@ -608,7 +608,7 @@ class RubyLex
identify_quotation
elsif peek(0) == '='
getc
- Token(OP_ASGIN, "%")
+ Token(TkOPASGN, :%)
elsif @lex_state == EXPR_ARG and @space_seen and peek(0) !~ /\s/
identify_quotation
else
diff --git a/lib/mkmf.rb b/lib/mkmf.rb
index 317200ba79..eb3cb74e16 100644
--- a/lib/mkmf.rb
+++ b/lib/mkmf.rb
@@ -43,7 +43,7 @@ else
$null = open('test.log', 'w')
end
-LINK = "#{CONFIG['CC']} -o conftest -I#{$hdrdir} #{CFLAGS} -I#{CONFIG['includedir']} %s #{CONFIG['LDFLAGS']} %s conftest.c %s %s #{CONFIG['LIBS']}"
+LINK = "#{CONFIG['CC']} -o conftest -I#{$hdrdir} #{CFLAGS} -I#{CONFIG['includedir']} %s %s #{CONFIG['LDFLAGS']} %s conftest.c %s %s #{CONFIG['LIBS']}"
CPP = "#{CONFIG['CPP']} -E %s -I#{$hdrdir} #{CFLAGS} -I#{CONFIG['includedir']} %s %s conftest.c"
def rm_f(*files)
@@ -155,7 +155,9 @@ def install_rb(mfile, dest, srcdir = nil)
mfile.printf "\t@$(RUBY) -r ftools -e 'File::makedirs(*ARGV)' %s/%s\n", dest, f
end
for f in path
- mfile.printf "\t@$(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0644, true)' lib/%s %s/%s\n", f, dest, f
+ d = '/' + File::dirname(f)
+ d = '' if d == '/.'
+ mfile.printf "\t@$(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0644, true)' %s/%s %s%s\n", libdir, f, dest, d
end
end
@@ -352,6 +354,8 @@ def dir_config(target, idefault=nil, ldefault=nil)
end
def create_makefile(target, srcdir = File.dirname($0))
+ save_libs = $libs.dup
+ save_libpath = $LIBPATH.dup
print "creating Makefile\n"
rm_f "conftest*"
STDOUT.flush
@@ -370,10 +374,9 @@ def create_makefile(target, srcdir = File.dirname($0))
end
$DLDFLAGS = CONFIG["DLDFLAGS"]
- if $configure_args['--enable-shared'] or CONFIG['LIBRUBY'] != CONFIG['LIBRUBY_A']
- $libs = CONFIG["LIBRUBYARG"] + " " + $libs
- $LIBPATH |= ["$(topdir)", CONFIG["libdir"]]
- end
+ $libs = CONFIG["LIBRUBYARG"] + " " + $libs
+ $configure_args['--enable-shared'] or $LIBPATH |= [$topdir]
+ $LIBPATH |= [CONFIG["libdir"]]
defflag = ''
if RUBY_PLATFORM =~ /cygwin|mingw/
@@ -474,7 +477,7 @@ $(archdir)/$(DLLIB): $(DLLIB)
@$(RUBY) -r ftools -e 'File::makedirs(*ARGV)' $(libdir) $(archdir)
@$(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0555, true)' $(DLLIB) $(archdir)/$(DLLIB)
EOMF
- install_rb(mfile, "$(libdir)")
+ install_rb(mfile, "$(libdir)", srcdir)
mfile.printf "\n"
mfile.printf <<EOMF
@@ -482,7 +485,7 @@ $(sitearchdir)/$(DLLIB): $(DLLIB)
@$(RUBY) -r ftools -e 'File::makedirs(*ARGV)' $(libdir) $(sitearchdir)
@$(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0555, true)' $(DLLIB) $(sitearchdir)/$(DLLIB)
EOMF
- install_rb(mfile, "$(sitelibdir)")
+ install_rb(mfile, "$(sitelibdir)", srcdir)
mfile.printf "\n"
if /mswin32/ !~ RUBY_PLATFORM
@@ -504,6 +507,9 @@ EOMF
.c.#{$OBJEXT}:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $(subst /,\\\\,$<)
+
+.cc.#{$OBJEXT} .cpp.#{$OBJEXT} .cxx.#{$OBJEXT} .C.#{$OBJEXT}:
+ $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $(subst /,\\\\,$<)
"
end
@@ -536,6 +542,8 @@ EOMF
dfile.close
end
mfile.close
+ $libs = save_libs
+ $LIBPATH = save_libpath
end
$OBJEXT = CONFIG["OBJEXT"]
diff --git a/lib/monitor.rb b/lib/monitor.rb
index 75d9c35821..7cca6e871e 100644
--- a/lib/monitor.rb
+++ b/lib/monitor.rb
@@ -1,27 +1,44 @@
=begin
-monitor.rb
-Author: Shugo Maeda <shugo@netlab.co.jp>
-Version: 1.2.1
+= monitor.rb
-USAGE:
+Copyright (C) 2001 Shugo Maeda <shugo@ruby-lang.org>
- foo = Foo.new
- foo.extend(MonitorMixin)
- cond = foo.new_cond
+This library is distributed under the terms of the Ruby license.
+You can freely distribute/modify this library.
- thread1:
- foo.synchronize {
- ...
- cond.wait_until { foo.done? }
- ...
- }
+== example
- thread2:
- foo.synchronize {
- foo.do_something
- cond.signal
- }
+This is a simple example.
+
+ require 'monitor.rb'
+
+ buf = []
+ buf.extend(MonitorMixin)
+ empty_cond = buf.new_cond
+
+ # consumer
+ Thread.start do
+ loop do
+ buf.synchronize do
+ empty_cond.wait_while { buf.empty? }
+ print buf.shift
+ end
+ end
+ end
+
+ # producer
+ while line = ARGF.gets
+ buf.synchronize do
+ buf.push(line)
+ empty_cond.signal
+ end
+ end
+
+The consumer thread waits for the producer thread to push a line
+to buf while buf.empty?, and the producer thread (main thread)
+reads a line from ARGF and push it to buf, then call
+empty_cond.signal.
=end
diff --git a/lib/net/http.rb b/lib/net/http.rb
index 3900ed6c68..26e5285525 100644
--- a/lib/net/http.rb
+++ b/lib/net/http.rb
@@ -1,8 +1,9 @@
=begin
-= net/http.rb version 1.1.32
+= net/http.rb version 1.1.34
+
+written by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
-maintained by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
This file is derived from "http-access.rb".
This program is free software.
@@ -14,9 +15,34 @@ You can get it from RAA
(Ruby Application Archive: http://www.ruby-lang.org/en/raa.html).
-= class HTTP
+== http.rb version 1.2 features
+
+You can use 1.2 features by calling HTTP.version_1_2. And
+calling Net::HTTP.version_1_1 allows to use 1.1 features.
+
+ # example
+ HTTP.start {|http1| ...(http1 has 1.1 features)... }
+
+ HTTP.version_1_2
+ HTTP.start {|http2| ...(http2 has 1.2 features)... }
+
+ HTTP.version_1_1
+ HTTP.start {|http3| ...(http3 has 1.1 features)... }
+
+Changes are:
-== Class Methods
+ * HTTP#get, head, post does not raise ProtocolError
+ * HTTP#get, head, post returns only one object, a HTTPResponse object
+ * HTTPResponseReceiver is joined into HTTPResponse
+ * request object: HTTP::Get, Head, Post; and HTTP#request(req)
+
+WARNING: These features are not definite yet.
+They will change without notice!
+
+
+== class HTTP
+
+=== Class Methods
: new( address = 'localhost', port = 80, proxy_addr = nil, proxy_port = nil )
creates a new Net::HTTP object.
@@ -49,7 +75,7 @@ You can get it from RAA
HTTP default port (80).
-== Methods
+=== Methods
: start
: start {|http| .... }
@@ -72,7 +98,7 @@ You can get it from RAA
get data from "path" on connecting host.
"header" must be a Hash like { 'Accept' => '*/*', ... }.
Data is written to "dest" by using "<<" method.
- This method returns Net::HTTPResponse object, and "dest".
+ This method returns HTTPResponse object, and "dest".
# example
response, body = http.get( '/index.html' )
@@ -95,7 +121,7 @@ You can get it from RAA
: head( path, header = nil )
gets only header from "path" on connecting host.
"header" is a Hash like { 'Accept' => '*/*', ... }.
- This method returns a Net::HTTPResponse object.
+ This method returns a HTTPResponse object.
You can http header from this object like:
response['content-length'] #-> '2554'
@@ -109,7 +135,7 @@ You can get it from RAA
If the body exists, also gets entity body.
Data is written to "dest" by using "<<" method.
"header" must be a Hash like { 'Accept' => '*/*', ... }.
- This method returns Net::HTTPResponse object and "dest".
+ This method returns HTTPResponse object and "dest".
If called with block, gives a part of entity body string.
@@ -181,21 +207,21 @@ You can get it from RAA
response.body
-= class HTTPResponse
+== class HTTPResponse
HTTP response object.
All "key" is case-insensitive.
-== Methods
+=== Methods
: body
- the entity body. ("dest" argument for HTTP#get, post, put)
+ the entity body (String).
: self[ key ]
returns header field for "key".
for HTTP, value is a string like 'text/plain'(for Content-Type),
- '2045'(for Content-Length), 'bytes 0-1024/10024'(for Content-Range).
- Multiple header had be joined by HTTP1.1 scheme.
+ '2045'(for Content-Length), 'bytes 0-1023/10024'(for Content-Range).
+ If there's some fields which has same name, they are joined with ','.
: self[ key ] = val
set field value for "key".
@@ -204,88 +230,92 @@ All "key" is case-insensitive.
true if key exists
: each {|name,value| .... }
- iterates for each field name and value pair
+ iterates for each field name and value pair.
: code
- HTTP result code string. For example, '302'
+ HTTP result code string. For example, '302'.
: message
- HTTP result message. For example, 'Not Found'
+ HTTP result message. For example, 'Not Found'.
-= class HTTPResponseReceiver
+== class HTTPResponseReceiver
-== Methods
+=== Methods
: header
: response
- Net::HTTPResponse object
+ HTTPResponse object
-: body( dest = '' )
-: entity( dest = '' )
- entity body. A body is written to "dest" using "<<" method.
+: read_body( dest = '' )
+ reads entity body into DEST by calling "<<" method and
+ returns DEST.
-: body {|str| ... }
- gets entity body with block.
- If this method is called twice, block is not executed and
- returns first "dest".
+: read_body {|string| ... }
+ reads entity body little by little and gives it to block
+ until entity ends.
+: body
+: entity
+ entity body. If #read_body is called already, returns its
+ argument DEST. Else returns entity body as String.
-= http.rb version 1.2 features
+ Calling this method any times causes returning same
+ object (does not read entity again).
-You can use 1.2 features by calling HTTP.version_1_2. And
-calling Net::HTTP.version_1_1 allows to use 1.1 features.
+=end
- # example
- HTTP.start {|http1| ...(http1 has 1.1 features)... }
+require 'net/protocol'
- HTTP.version_1_2
- HTTP.start {|http2| ...(http2 has 1.2 features)... }
- HTTP.version_1_1
- HTTP.start {|http3| ...(http3 has 1.1 features)... }
+module Net
-== Method (only diff to 1.1)
+ class HTTPBadResponse < StandardError; end
+ class HTTPHeaderSyntaxError < StandardError; end
-: get( path, u_header = nil )
-: get( path, u_header = nil ) {|str| .... }
- gets document from "path".
- returns HTTPResponse object.
-: head( path, u_header = nil )
- gets only document header from "path".
- returns HTTPResponse object.
+ class HTTP < Protocol
-: post( path, data, u_header = nil )
-: post( path, data, u_header = nil ) {|str| .... }
- posts "data" to "path" entity and gets document.
- returns HTTPResponse object.
+ HTTPVersion = '1.1'
-=end
+ #
+ # connection
+ #
-require 'net/protocol'
+ protocol_param :port, '80'
-module Net
+ def initialize( addr = nil, port = nil )
+ super
- class HTTPBadResponse < StandardError; end
+ @proxy_address = nil
+ @proxy_port = nil
+ @curr_http_version = HTTPVersion
+ @seems_1_0_server = false
+ end
- class HTTP < Protocol
- protocol_param :port, '80'
- protocol_param :command_type, '::Net::NetPrivate::HTTPCommand'
+ private
+ def conn_command( sock )
+ end
+
+ def do_finish
+ end
+
+
+ #
+ # proxy
+ #
+
+ public
- ###
- ### proxy
- ###
class << self
def Proxy( p_addr, p_port = nil )
- ::Net::NetPrivate::HTTPProxy.create_proxy_class(
- p_addr, p_port || self.port )
+ ProxyMod.create_proxy_class( p_addr, p_port || self.port )
end
alias orig_new new
@@ -293,7 +323,7 @@ module Net
def new( address = nil, port = nil, p_addr = nil, p_port = nil )
c = p_addr ? self::Proxy(p_addr, p_port) : self
i = c.orig_new( address, port )
- setimplv i
+ setvar i
i
end
@@ -332,385 +362,230 @@ module Net
end
- ###
- ### 1.2 implementation
- ###
+ module ProxyMod
- @@newimpl = false
+ class << self
- #class << self
+ def create_proxy_class( p_addr, p_port )
+ mod = self
+ klass = Class.new( HTTP )
+ klass.module_eval {
+ include mod
+ @proxy_address = p_addr
+ @proxy_port = p_port
+ }
+ def klass.proxy_class?
+ true
+ end
- def self.version_1_2
- @@newimpl = true
- end
+ def klass.proxy_address
+ @proxy_address
+ end
- def self.version_1_1
- @@newimpl = false
- end
+ def klass.proxy_port
+ @proxy_port
+ end
- #private
+ klass
+ end
- def self.setimplv( obj )
- f = @@newimpl
- obj.instance_eval { @newimpl = f }
end
- #end
-
-
- ###
- ### http operations
- ###
-
- def get( path, u_header = nil, dest = nil, &block )
- resp = get2( path, u_header ) {|f| f.body( dest, &block ) }
- if @newimpl then
- resp
- else
- resp.value
- return resp, resp.body
+ def initialize( addr, port )
+ super
+ @proxy_address = type.proxy_address
+ @proxy_port = type.proxy_port
end
- end
-
- def get2( path, u_header = nil, &block )
- common_oper( u_header, true, block ) {|uh|
- @command.get edit_path(path), uh
- }
- end
+
+ attr_reader :proxy_address, :proxy_port
+ alias proxyaddr proxy_address
+ alias proxyport proxy_port
- def head( path, u_header = nil )
- resp = head2( path, u_header )
- unless @newimpl then
- resp.value
+ def proxy?
+ true
end
- resp
- end
-
- def head2( path, u_header = nil, &block )
- common_oper( u_header, false, block ) {|uh|
- @command.head edit_path(path), uh
- }
- end
-
-
- def post( path, data, u_header = nil, dest = nil, &block )
- resp = post2( path, data, u_header ) {|f| f.body( dest, &block ) }
- if @newimpl then
- resp
- else
- resp.value
- return resp, resp.body
+
+ private
+
+ def conn_socket( addr, port )
+ super @proxy_address, @proxy_port
end
- end
-
- def post2( path, data, u_header = nil, &block )
- common_oper( u_header, true, block ) {|uh|
- @command.post edit_path(path), uh, data
- }
- end
-
- # not tested because I could not setup apache (__;;;
- def put( path, src, u_header = nil )
- resp = put2( path, src, u_header ) {|f| f.body }
- if @newimpl then
- resp
- else
- resp.value
- return resp, resp.body
+ def edit_path( path )
+ 'http://' + addr_port + path
end
- end
+
+ end # module ProxyMod
- def put2( path, src, u_header = nil, &block )
- common_oper( u_header, true, block ) {|uh|
- @command.put path, uh, src
- }
- end
-
-
- private
-
-
- def common_oper( u_header, body_exist, block )
- header = procheader( u_header )
- recv = err = nil
-
- connecting( header ) {
- recv = HTTPResponseReceiver.new( @command, body_exist )
- yield header
- begin
- block.call recv if block
- rescue Exception => err
- ;
- end
- recv.terminate
-
- recv.response
- }
- raise err if err
- recv.response
- end
+ #
+ # for backward compatibility
+ #
- def connecting( header )
- if not @socket then
- header['Connection'] = 'close'
- start
- elsif @socket.closed? then
- @socket.reopen
- end
+ @@newimpl = false
- resp = yield
+ class << self
- unless keep_alive? header, resp then
- @socket.close
+ def version_1_2
+ @@newimpl = true
end
- end
- def keep_alive?( header, resp )
- if resp.key? 'connection' then
- if /keep-alive/i === resp['connection'] then
- return true
- end
- elsif resp.key? 'proxy-connection' then
- if /keep-alive/i === resp['proxy-connection'] then
- return true
- end
- elsif header.key? 'Connection' then
- if /keep-alive/i === header['Connection'] then
- return true
- end
- else
- if @command.http_version == '1.1' then
- return true
- end
+ def version_1_1
+ @@newimpl = false
end
- false
- end
-
- def procheader( h )
- ret = {}
- ret[ 'Host' ] = address +
- ((port == HTTP.port) ? '' : ":#{port}")
- ret[ 'Connection' ] = 'Keep-Alive'
- ret[ 'Accept' ] = '*/*'
+ private
- return ret unless h
- tmp = {}
- h.each do |k,v|
- key = k.split('-').collect {|i| i.capitalize }.join('-')
- if tmp[key] then
- $stderr.puts "'#{key}' http header appered twice" if $VERBOSE
- end
- tmp[key] = v
+ def setvar( obj )
+ f = @@newimpl
+ obj.instance_eval { @newimpl = f }
end
- ret.update tmp
- ret
end
- def do_finish
- end
+ #
+ # http operations
+ #
- end
-
- HTTPSession = HTTP
-
-
- module NetPrivate
-
- module HTTPProxy
-
- class << self
-
- def create_proxy_class( p_addr, p_port )
- klass = Class.new( HTTP )
- klass.module_eval {
- include HTTPProxy
- @proxy_address = p_addr
- @proxy_port = p_port
- }
- def klass.proxy_class?
- true
- end
+ public
- def klass.proxy_address
- @proxy_address
+ def self.def_http_method( nm, hasdest, hasdata )
+ name = nm.id2name.downcase
+ cname = nm.id2name
+ lineno = __LINE__ + 2
+ src = <<" ----"
+
+ def #{name}( path, #{hasdata ? 'data,' : ''}
+ u_header = nil #{hasdest ? ',dest = nil, &block' : ''} )
+ resp = nil
+ request(
+ #{cname}.new( path, u_header ) #{hasdata ? ',data' : ''}
+ ) do |resp|
+ resp.read_body( #{hasdest ? 'dest, &block' : ''} )
+ end
+ if @newimpl then
+ resp
+ else
+ resp.value
+ #{hasdest ? 'return resp, resp.body' : 'resp'}
+ end
end
- def klass.proxy_port
- @proxy_port
+ def #{name}2( path, #{hasdata ? 'data,' : ''}
+ u_header = nil, &block )
+ request( #{cname}.new(path, u_header),
+ #{hasdata ? 'data,' : ''} &block )
end
-
- klass
- end
-
- end
-
-
- def initialize( addr, port )
- super
- @proxy_address = type.proxy_address
- @proxy_port = type.proxy_port
+ ----
+ module_eval src, __FILE__, lineno
end
- attr_reader :proxy_address, :proxy_port
+ def_http_method :Get, true, false
+ def_http_method :Head, false, false
+ def_http_method :Post, true, true
+ def_http_method :Put, false, true
- alias proxyaddr proxy_address
- alias proxyport proxy_port
-
- def proxy?
- true
- end
-
- def connect( addr = nil, port = nil )
- super @proxy_address, @proxy_port
- end
-
- def edit_path( path )
- 'http://' + address + (port == type.port ? '' : ":#{port}") + path
+ def request( req, *args )
+ common_oper( req ) {
+ req.__send__( :exec,
+ @socket, @curr_http_version, edit_path(req.path), *args )
+ yield req.response if block_given?
+ }
+ req.response
end
-
- end
-
- end # net private
+ private
- class HTTPResponseReceiver
-
- def initialize( command, body_exist )
- @command = command
- @body_exist = body_exist
- @header = @body = nil
- end
-
- def inspect
- "#<#{type}>"
- end
- def read_header
- unless @header then
- stream_check
- @header = @command.get_response
+ def common_oper( req )
+ req['connection'] ||= 'keep-alive'
+ if not @socket then
+ start
+ req['connection'] = 'close'
+ elsif @socket.closed? then
+ re_connect
end
- @header
- end
-
- alias header read_header
- alias response read_header
-
- def read_body( dest = nil, &block )
- unless @body then
- read_header
-
- to = procdest( dest, block )
- stream_check
-
- if @body_exist and @header.code_type.body_exist? then
- @command.get_body @header, to
- @header.body = @body = to
- else
- @command.no_body
- @header.body = nil
- @body = 1
- end
+ if not req.body_exist? or @seems_1_0_server then
+ req['connection'] = 'close'
end
- @body == 1 ? nil : @body
- end
-
- alias body read_body
- alias entity read_body
+ req['host'] = addr_port
- def terminate
- read_header
- read_body
- @command = nil
- end
+ yield req
+ req.response.__send__ :terminate
+ @curr_http_version = req.response.http_version
-
- private
-
- def stream_check
- unless @command then
- raise IOError, 'receiver was used out of block'
- end
- end
-
- def procdest( dest, block )
- if dest and block then
- raise ArgumentError,
- 'both of arg and block are given for HTTP method'
- end
- if block then
- NetPrivate::ReadAdapter.new block
+ if not req.response.body then
+ @socket.close
+ elsif keep_alive? req, req.response then
+ D 'Conn keep-alive'
+ if @socket.closed? then # (only) read stream had been closed
+ D 'Conn (but seems 1.0 server)'
+ @seems_1_0_server = true
+ @socket.close
+ end
else
- dest or ''
+ D 'Conn close'
+ @socket.close
end
- end
-
- end
-
- HTTPReadAdapter = HTTPResponseReceiver
-
- class HTTPResponse < Response
-
- def initialize( code_type, code, msg )
- super
- @data = {}
- @body = nil
+ req.response
end
- attr_accessor :body
+ def keep_alive?( req, res )
+ /close/i === req['connection'].to_s and return false
+ @seems_1_0_server and return false
- def inspect
- "#<#{type.name} #{code}>"
- end
+ /keep-alive/i === res['connection'].to_s and return true
+ /close/i === res['connection'].to_s and return false
+ /keep-alive/i === res['proxy-connection'].to_s and return true
+ /close/i === res['proxy-connection'].to_s and return false
- def []( key )
- @data[ key.downcase ]
+ @curr_http_version == '1.1' and return true
+ false
end
- def []=( key, val )
- @data[ key.downcase ] = val
- end
- def each( &block )
- @data.each( &block )
- end
+ #
+ # utils
+ #
- def each_key( &block )
- @data.each_key( &block )
- end
+ public
- def each_value( &block )
- @data.each_value( &block )
+ def self.get( addr, path, port = nil )
+ req = Get.new( path )
+ resp = nil
+ new( addr, port || HTTP.port ).start {|http|
+ resp = http.request( req )
+ }
+ resp.body
end
- def delete( key )
- @data.delete key.downcase
+ def self.get_print( addr, path, port = nil )
+ print get( addr, path, port )
end
- def key?( key )
- @data.key? key.downcase
- end
- def to_hash
- @data.dup
+ private
+
+ def addr_port
+ address + (port == HTTP.port ? '' : ":#{port}")
end
- def value
- unless SuccessCode === self then
- error! self
+ def D( msg )
+ if @dout then
+ @dout << msg
+ @dout << "\n"
end
end
end
+ HTTPSession = HTTP
+
+
class Code
@@ -776,101 +651,246 @@ module Net
HTTPVersionNotSupported = HTTPServerErrorCode.http_mkchild
- module NetPrivate
+ ###
+ ### header
+ ###
- class HTTPCommand < Command
+ net_private {
- HTTPVersion = '1.1'
+ module HTTPHeader
- def initialize( sock )
- @http_version = HTTPVersion
- super sock
+ def size
+ @header.size
end
- attr_reader :http_version
+ alias length size
- def inspect
- "#<Net::HTTPCommand>"
+ def []( key )
+ @header[ key.downcase ]
end
+ def []=( key, val )
+ @header[ key.downcase ] = val
+ end
- ###
- ### request
- ###
+ def each( &block )
+ @header.each( &block )
+ end
- public
+ def each_key( &block )
+ @header.each_key( &block )
+ end
- def get( path, u_header )
- return unless begin_critical
- request sprintf('GET %s HTTP/%s', path, HTTPVersion), u_header
+ def each_value( &block )
+ @header.each_value( &block )
end
-
- def head( path, u_header )
- return unless begin_critical
- request sprintf('HEAD %s HTTP/%s', path, HTTPVersion), u_header
+
+ def delete( key )
+ @header.delete key.downcase
+ end
+
+ def key?( key )
+ @header.key? key.downcase
+ end
+
+ def to_hash
+ @header.dup
end
- def post( path, u_header, data )
- return unless begin_critical
- u_header[ 'Content-Length' ] = data.size.to_s
- request sprintf('POST %s HTTP/%s', path, HTTPVersion), u_header
- @socket.write data
+ def canonical_each
+ @header.each do |k,v|
+ yield canonical(k), v
+ end
end
- def put( path, u_header, src )
- return unless begin_critical
- request sprintf('PUT %s HTTP/%s', path, HTTPVersion), u_header
- @socket.write_bin src
+ def canonical( k )
+ k.split('-').collect {|i| i.capitalize }.join('-')
end
- # def delete
+ def range
+ s = @header['range']
+ s or return nil
- # def trace
+ arr = []
+ s.split(',').each do |spec|
+ m = /bytes\s*=\s*(\d+)?\s*-\s*(\d+)?/i.match( spec )
+ m or raise HTTPHeaderSyntaxError, "wrong Range: #{spec}"
- # def options
+ d1 = m[1].to_i
+ d2 = m[2].to_i
+ if m[1] and m[2] then arr.push (d1 .. d2)
+ elsif m[1] then arr.push (d1 .. -1)
+ elsif m[2] then arr.push (-d2 .. -1)
+ else
+ raise HTTPHeaderSyntaxError, 'range is not specified'
+ end
+ end
- def quit
+ return *arr
end
+ def range=( r, fin = nil )
+ if fin then
+ r = r ... r+fin
+ end
- private
+ case r
+ when Numeric
+ s = r > 0 ? "0-#{r - 1}" : "-#{-r}"
+ when Range
+ first = r.first
+ last = r.last
+ if r.exclude_end? then
+ last -= 1
+ end
- def request( req, u_header )
- @socket.writeline req
- u_header.each do |n,v|
- @socket.writeline n + ': ' + v
+ if last == -1 then
+ s = first > 0 ? "#{first}-" : "-#{-first}"
+ else
+ first >= 0 or raise HTTPHeaderSyntaxError, 'range.first is negative'
+ last > 0 or raise HTTPHeaderSyntaxError, 'range.last is negative'
+ first < last or raise HTTPHeaderSyntaxError, 'must be .first < .last'
+ s = "#{first}-#{last}"
+ end
+ else
+ raise TypeError, 'Range/Integer is required'
end
- @socket.writeline ''
+
+ @header['range'] = "bytes=#{s}"
+ r
end
+ alias set_range range=
- ###
- ### response line & header
- ###
+ def content_length
+ s = @header['content-length']
+ s or return nil
- public
+ m = /\d+/.match(s)
+ m or raise HTTPHeaderSyntaxError, 'wrong Content-Length format'
+ m[0].to_i
+ end
- def get_response
- resp = get_resp0
- resp = get_resp0 while ContinueCode === resp
- resp
+ def chunked?
+ s = @header['transfer-encoding']
+ (s and /(?:\A|[^\-\w])chunked(?:[^\-\w]|\z)/i === s) ? true : false
+ end
+
+ def content_range
+ s = @header['content-range']
+ s or return nil
+
+ m = %r<bytes\s+(\d+)-(\d+)/(?:\d+|\*)>i.match( s )
+ m or raise HTTPHeaderSyntaxError, 'wrong Content-Range format'
+
+ m[1].to_i .. m[2].to_i + 1
+ end
+
+ def range_length
+ r = content_range
+ r and r.length
+ end
+
+ def basic_auth( acc, pass )
+ @header['authorization'] =
+ 'Basic ' + ["#{acc}:#{pass}"].pack('m').gsub(/\s+/, '')
+ end
+
+ end
+
+ }
+
+
+ ###
+ ### request
+ ###
+
+ net_private {
+
+ class HTTPRequest
+
+ include ::Net::NetPrivate::HTTPHeader
+
+ def initialize( path, uhead = nil )
+ @path = path
+ @header = tmp = {}
+ return unless uhead
+ uhead.each do |k,v|
+ key = k.downcase
+ if tmp.key? key then
+ $stderr.puts "WARNING: duplicated HTTP header: #{k}" if $VERBOSE
+ end
+ tmp[ key ] = v.strip
+ end
+ tmp['accept'] ||= '*/*'
+
+ @socket = nil
+ @response = nil
+ end
+
+ attr_reader :path
+ attr_reader :response
+
+ def inspect
+ "\#<#{type}>"
+ end
+
+ def body_exist?
+ type::HAS_BODY
end
private
- def get_resp0
- resp = get_reply
+ #
+ # write
+ #
+
+ def exec( sock, ver, path )
+ ready( sock ) {
+ request ver, path
+ }
+ @response
+ end
+
+ def ready( sock )
+ @response = nil
+ @socket = sock
+ yield
+ @response = get_response
+ @socket = nil
+ end
+
+ def request( ver, path )
+ @socket.writeline sprintf('%s %s HTTP/%s', type::METHOD, path, ver)
+ canonical_each do |k,v|
+ @socket.writeline k + ': ' + v
+ end
+ @socket.writeline ''
+ end
+
+ #
+ # read
+ #
+
+ def get_response
+ begin
+ resp = read_response
+ end while ContinueCode === resp
+ resp
+ end
+
+ def read_response
+ resp = get_resline
while true do
- line = @socket.readline
+ line = @socket.readuntil( "\n", true ) # ignore EOF
+ line.sub!( /\s+\z/, '' ) # don't use chop!
break if line.empty?
m = /\A([^:]+):\s*/.match( line )
- unless m then
- raise HTTPBadResponse, 'wrong header line format'
- end
+ m or raise HTTPBadResponse, 'wrong header line format'
nm = m[1]
line = m.post_match
if resp.key? nm then
@@ -883,23 +903,117 @@ module Net
resp
end
- def get_reply
+ def get_resline
str = @socket.readline
- m = /\AHTTP\/(\d+\.\d+)?\s+(\d\d\d)\s*(.*)\z/i.match( str )
- unless m then
- raise HTTPBadResponse, "wrong status line: #{str}"
- end
- @http_version = m[1]
+ m = /\AHTTP(?:\/(\d+\.\d+))?\s+(\d\d\d)\s*(.*)\z/i.match( str )
+ m or raise HTTPBadResponse, "wrong status line: #{str}"
+ httpver = m[1]
status = m[2]
discrip = m[3]
- code = HTTPCODE_TO_OBJ[status] ||
- HTTPCODE_CLASS_TO_OBJ[status[0,1]] ||
- UnknownCode
- HTTPResponse.new( code, status, discrip )
+ ::Net::NetPrivate::HTTPResponse.new(
+ status, discrip, @socket, type::HAS_BODY, httpver )
+ end
+
+ end
+
+
+ class HTTPRequestWithBody < HTTPRequest
+
+ private
+
+ def exec( sock, ver, path, str = nil )
+ check_arg str, block_given?
+
+ if block_given? then
+ ac = Accumulator.new
+ yield ac # must be yield, DO NOT USE block.call
+ data = ac.terminate
+ else
+ data = str
+ end
+ @header['content-length'] = data.size.to_s
+ @header.delete 'transfer-encoding'
+
+ ready( sock ) {
+ request ver, path
+ @socket.write data
+ }
+ @response
+ end
+
+ def check_arg( data, blkp )
+ if data and blkp then
+ raise ArgumentError, 'both of data and block given'
+ end
+ unless data or blkp then
+ raise ArgumentError, 'str or block required'
+ end
+ end
+
+ end
+
+
+ class Accumulator
+
+ def initialize
+ @buf = ''
+ end
+
+ def write( s )
+ @buf.concat s
+ end
+
+ alias << write
+
+ def terminate
+ ret = @buf
+ @buf = nil
+ ret
+ end
+
+ end
+
+ }
+
+
+ class HTTP
+
+ class Get < ::Net::NetPrivate::HTTPRequest
+ HAS_BODY = true
+ METHOD = 'GET'
+ end
+
+ class Head < ::Net::NetPrivate::HTTPRequest
+ HAS_BODY = false
+ METHOD = 'HEAD'
+ end
+
+ class Post < ::Net::NetPrivate::HTTPRequestWithBody
+ HAS_BODY = true
+ METHOD = 'POST'
+ end
+
+ class Put < ::Net::NetPrivate::HTTPRequestWithBody
+ HAS_BODY = true
+ METHOD = 'PUT'
end
- HTTPCODE_CLASS_TO_OBJ = {
+ end
+
+
+
+ ###
+ ### response
+ ###
+
+ net_private {
+
+ class HTTPResponse < Response
+
+ include ::Net::NetPrivate::HTTPHeader
+
+ CODE_CLASS_TO_OBJ = {
'1' => HTTPInformationCode,
'2' => HTTPSuccessCode,
'3' => HTTPRedirectionCode,
@@ -907,7 +1021,7 @@ module Net
'5' => HTTPServerErrorCode
}
- HTTPCODE_TO_OBJ = {
+ CODE_TO_OBJ = {
'100' => ContinueCode,
'101' => HTTPSwitchProtocol,
@@ -951,22 +1065,87 @@ module Net
'505' => HTTPVersionNotSupported
}
+ def initialize( stat, msg, sock, be, hv )
+ code = CODE_TO_OBJ[stat] ||
+ CODE_CLASS_TO_OBJ[stat[0,1]] ||
+ UnknownCode
+ super code, stat, msg
+ @socket = sock
+ @body_exist = be
+ @http_version = hv
- ###
- ### body
- ###
+ @header = {}
+ @body = nil
+ @read = false
+ end
- public
+ attr_reader :http_version
+
+ def inspect
+ "#<#{type} #{code}>"
+ end
+
+ def value
+ SuccessCode === self or error! self
+ end
- def get_body( resp, dest )
- if chunked? resp then
+
+ #
+ # header (for backward compatibility)
+ #
+
+ def read_header
+ self
+ end
+
+ alias header read_header
+ alias response read_header
+
+ #
+ # body
+ #
+
+ def read_body( dest = nil, &block )
+ if @read and (dest or block) then
+ raise IOError, "#{type}\#read_body called twice with argument"
+ end
+
+ unless @read then
+ to = procdest( dest, block )
+ stream_check
+
+ if @body_exist and code_type.body_exist? then
+ read_body_0 to
+ @body = to
+ else
+ @body = nil
+ end
+ @read = true
+ end
+
+ @body
+ end
+
+ alias body read_body
+ alias entity read_body
+
+
+ private
+
+
+ def terminate
+ read_body
+ end
+
+ def read_body_0( dest )
+ if chunked? then
read_chunked dest
else
- clen = content_length( resp )
+ clen = content_length
if clen then
- @socket.read clen, dest
+ @socket.read clen, dest, true # ignore EOF
else
- clen = range_length( resp )
+ clen = range_length
if clen then
@socket.read clen, dest
else
@@ -974,16 +1153,8 @@ module Net
end
end
end
- end_critical
- end
-
- def no_body
- end_critical
end
-
- private
-
def read_chunked( dest )
len = nil
total = 0
@@ -991,9 +1162,7 @@ module Net
while true do
line = @socket.readline
m = /[0-9a-fA-F]+/.match( line )
- unless m then
- raise HTTPBadResponse, "wrong chunk size line: #{line}"
- end
+ m or raise HTTPBadResponse, "wrong chunk size line: #{line}"
len = m[0].hex
break if len == 0
@socket.read( len, dest ); total += len
@@ -1004,44 +1173,27 @@ module Net
end
end
- def content_length( resp )
- if resp.key? 'content-length' then
- m = /\d+/.match( resp['content-length'] )
- unless m then
- raise HTTPBadResponse, 'wrong Content-Length format'
- end
- m[0].to_i
- else
- nil
- end
+ def stream_check
+ @socket.closed? and raise IOError, 'try to read body out of block'
end
- def chunked?( resp )
- tmp = resp['transfer-encoding']
- tmp and /(?:\A|\s+)chunked(?:\s+|\z)/i === tmp
- end
-
- def range_length( resp )
- if resp.key? 'content-range' then
- m = %r<bytes\s+(\d+)-(\d+)/\d+>.match( resp['content-range'] )
- unless m then
- raise HTTPBadResponse, 'wrong Content-Range format'
- end
- l = m[2].to_i
- u = m[1].to_i
- if l > u then
- nil
- else
- u - l
- end
+ def procdest( dest, block )
+ if dest and block then
+ raise ArgumentError, 'both of arg and block are given for HTTP method'
+ end
+ if block then
+ ::Net::NetPrivate::ReadAdapter.new block
else
- nil
+ dest || ''
end
end
end
+ }
+
- end # module Net::NetPrivate
+ HTTPResponse = NetPrivate::HTTPResponse
+ HTTPResponseReceiver = NetPrivate::HTTPResponse
end # module Net
diff --git a/lib/net/imap.rb b/lib/net/imap.rb
index 34d324ed12..23b22c0282 100644
--- a/lib/net/imap.rb
+++ b/lib/net/imap.rb
@@ -1475,6 +1475,12 @@ module Net
when /\A(?:UIDVALIDITY|UIDNEXT|UNSEEN)\z/n
match(T_SPACE)
result = ResponseCode.new(name, number)
+ else
+ match(T_SPACE)
+ @lex_state = EXPR_CTEXT
+ token = match(T_TEXT)
+ @lex_state = EXPR_BEG
+ result = ResponseCode.new(name, token.value)
end
match(T_RBRA)
@lex_state = EXPR_RTEXT
diff --git a/lib/net/pop.rb b/lib/net/pop.rb
index 4f6eb930a4..8f3f978e8c 100644
--- a/lib/net/pop.rb
+++ b/lib/net/pop.rb
@@ -1,6 +1,6 @@
=begin
-= net/pop.rb version 1.1.32
+= net/pop.rb version 1.1.34
written by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
@@ -184,6 +184,7 @@ module Net
protocol_param :port, '110'
protocol_param :command_type, '::Net::NetPrivate::POP3Command'
+ protocol_param :apop_command_type, '::Net::NetPrivate::APOPCommand'
protocol_param :mail_type, '::Net::POPMail'
@@ -206,9 +207,10 @@ module Net
end
- def initialize( addr = nil, port = nil )
- super
+ def initialize( addr = nil, port = nil, apop = false )
+ super addr, port
@mails = nil
+ @apop = false
end
attr :mails
@@ -238,6 +240,11 @@ module Net
private
+ def conn_command( sock )
+ @command =
+ (@apop ? type.apop_command_type : type.command_type).new(sock)
+ end
+
def do_start( acnt, pwd )
@command.auth( acnt, pwd )
diff --git a/lib/net/protocol.rb b/lib/net/protocol.rb
index 161024cfe2..343721add3 100644
--- a/lib/net/protocol.rb
+++ b/lib/net/protocol.rb
@@ -1,6 +1,6 @@
=begin
-= net/protocol.rb version 1.1.32
+= net/protocol.rb version 1.1.34
written by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
@@ -59,13 +59,22 @@ Object
=end
require 'socket'
+require 'timeout'
module Net
+ module NetPrivate
+ end
+
+ def self.net_private( &block )
+ ::Net::NetPrivate.module_eval( &block )
+ end
+
+
class Protocol
- Version = '1.1.32'
+ Version = '1.1.34'
class << self
@@ -116,8 +125,12 @@ module Net
@command = nil
@socket = nil
- @active = false
- @pipe = nil
+ @active = false
+
+ @open_timeout = nil
+ @read_timeout = nil
+
+ @dout = nil
end
attr_reader :address
@@ -126,10 +139,26 @@ module Net
attr_reader :command
attr_reader :socket
+ attr_accessor :open_timeout
+ attr_accessor :read_timeout
+
+ def active?
+ @active
+ end
+
+ def set_debug_output( arg ) # un-documented
+ @dout = arg
+ end
+
+ alias set_pipe set_debug_output
+
def inspect
"#<#{type} #{address}:#{port} open=#{active?}>"
end
+ #
+ # open session
+ #
def start( *args )
return false if active?
@@ -146,45 +175,59 @@ module Net
end
end
+ private
+
def _start( args )
connect
do_start( *args )
@active = true
end
- private :_start
-
- def finish
- return false unless active?
- do_finish unless @command.critical?
- disconnect
- @active = false
- true
+ def connect
+ conn_socket @address, @port
+ conn_command @socket
+ on_connect
end
- def active?
- @active
+ def re_connect
+ @socket.reopen @open_timeout
+ on_connect
end
- def set_pipe( arg ) # un-documented
- @pipe = arg
+ def conn_socket( addr, port )
+ @socket = type.socket_type.open(
+ addr, port, @open_timeout, @read_timeout, @dout )
end
+ def conn_command( sock )
+ @command = type.command_type.new( sock )
+ end
- private
-
+ def on_connect
+ end
def do_start
end
- def do_finish
- @command.quit
+ #
+ # close session
+ #
+
+ public
+
+ def finish
+ return false unless active?
+
+ do_finish if @command and not @command.critical?
+ disconnect
+ @active = false
+ true
end
+ private
- def connect( addr = @address, port = @port )
- @socket = type.socket_type.open( addr, port, @pipe )
- @command = type.command_type.new( @socket )
+ def do_finish
+ @command.quit
end
def disconnect
@@ -192,7 +235,11 @@ module Net
if @socket and not @socket.closed? then
@socket.close
end
- @socket = nil
+ @socket = nil
+ on_disconnect
+ end
+
+ def on_disconnect
end
end
@@ -200,6 +247,7 @@ module Net
Session = Protocol
+ net_private {
class Response
@@ -223,6 +271,8 @@ module Net
end
+ }
+
class ProtocolError < StandardError; end
class ProtoSyntaxError < ProtocolError; end
@@ -294,8 +344,7 @@ module Net
- module NetPrivate
-
+ net_private {
class WriteAdapter
@@ -311,7 +360,11 @@ module Net
def write( str )
@sock.__send__ @mid, str
end
- alias << write
+
+ def <<( str )
+ @sock.__send__ @mid, str
+ self
+ end
end
@@ -407,6 +460,7 @@ module Net
@critical = false
end
+
private
def critical
@@ -431,22 +485,30 @@ module Net
class Socket
- def initialize( addr, port, pipe = nil )
+ def initialize( addr, port, otime = nil, rtime = nil, dout = nil )
@addr = addr
@port = port
- @pipe = pipe
- @prepipe = nil
- @closed = true
- @ipaddr = ''
+ @read_timeout = rtime
+
+ @debugout = dout
+
+ @socket = nil
@sending = ''
@buffer = ''
- @socket = TCPsocket.new( addr, port )
- @closed = false
- @ipaddr = @socket.addr[3]
+ connect otime
+ D 'opened'
end
+ def connect( otime )
+ D "opening connection to #{@addr}..."
+ timeout( otime ) {
+ @socket = TCPsocket.new( @addr, @port )
+ }
+ end
+ private :connect
+
attr :pipe, true
class << self
@@ -454,27 +516,31 @@ module Net
end
def inspect
- "#<#{type} open=#{!@closed}>"
+ "#<#{type} #{closed? ? 'closed' : 'opened'}>"
end
- def reopen
- unless closed? then
- close
- @buffer = ''
- end
- @socket = TCPsocket.new( @addr, @port )
- @closed = false
+ def reopen( otime = nil )
+ D 'reopening...'
+ close
+ connect otime
+ D 'reopened'
end
attr :socket, true
def close
- @socket.close
- @closed = true
+ if @socket then
+ @socket.close
+ D 'closed'
+ else
+ D 'close call for already closed socket'
+ end
+ @socket = nil
+ @buffer = ''
end
def closed?
- @closed
+ not @socket
end
def address
@@ -486,7 +552,8 @@ module Net
attr_reader :port
def ip_address
- @ipaddr.dup
+ @socket or return ''
+ @socket.addr[3]
end
alias ipaddr ip_address
@@ -494,57 +561,64 @@ module Net
attr_reader :sending
- ###
- ### read
- ###
+ #
+ # read
+ #
+
+ public
CRLF = "\r\n"
- def read( len, dest = '' )
- @pipe << "reading #{len} bytes...\n" if @pipe; pipeoff
+ def read( len, dest = '', ignerr = false )
+ D_off "reading #{len} bytes..."
rsize = 0
- while rsize + @buffer.size < len do
- rsize += writeinto( dest, @buffer.size )
- fill_rbuf
+ begin
+ while rsize + @buffer.size < len do
+ rsize += rbuf_moveto( dest, @buffer.size )
+ rbuf_fill
+ end
+ rbuf_moveto dest, len - rsize
+ rescue EOFError
+ raise unless igneof
end
- writeinto( dest, len - rsize )
- @pipe << "read #{len} bytes\n" if pipeon
+ D_on "read #{len} bytes"
dest
end
-
def read_all( dest = '' )
- @pipe << "reading all...\n" if @pipe; pipeoff
+ D_off 'reading all...'
rsize = 0
begin
while true do
- rsize += writeinto( dest, @buffer.size )
- fill_rbuf
+ rsize += rbuf_moveto( dest, @buffer.size )
+ rbuf_fill
end
rescue EOFError
;
end
- @pipe << "read #{rsize} bytes\n" if pipeon
+ D_on "read #{rsize} bytes"
dest
end
-
- def readuntil( target )
- while true do
- idx = @buffer.index( target )
- break if idx
- fill_rbuf
- end
-
+ def readuntil( target, igneof = false )
dest = ''
- writeinto( dest, idx + target.size )
+ begin
+ while true do
+ idx = @buffer.index( target )
+ break if idx
+ rbuf_fill
+ end
+ rbuf_moveto dest, idx + target.size
+ rescue EOFError
+ raise unless igneof
+ rbuf_moveto dest, @buffer.size
+ end
dest
end
-
def readline
ret = readuntil( "\n" )
@@ -552,9 +626,8 @@ module Net
ret
end
-
def read_pendstr( dest )
- @pipe << "reading text...\n" if @pipe; pipeoff
+ D_off 'reading text...'
rsize = 0
while (str = readuntil("\r\n")) != ".\r\n" do
@@ -563,14 +636,13 @@ module Net
dest << str
end
- @pipe << "read #{rsize} bytes\n" if pipeon
+ D_on "read #{rsize} bytes"
dest
end
-
# private use only (can not handle 'break')
def read_pendlist
- @pipe << "reading list...\n" if @pipe; pipeoff
+ D_off 'reading list...'
str = nil
i = 0
@@ -580,55 +652,59 @@ module Net
yield str
end
- @pipe << "read #{i} items\n" if pipeon
+ D_on "read #{i} items"
end
private
- READ_BLOCK = 1024 * 8
+ READ_SIZE = 1024 * 4
- def fill_rbuf
- @buffer << @socket.sysread( READ_BLOCK )
+ def rbuf_fill
+ unless IO.select [@socket], nil, nil, @read_timeout then
+ on_read_timeout
+ end
+ @buffer << @socket.sysread( READ_SIZE )
end
- def writeinto( dest, len )
+ def on_read_timeout
+ raise TimeoutError, "socket read timeout (#{@read_timeout} sec)"
+ end
+
+ def rbuf_moveto( dest, len )
bsi = @buffer.size
- dest << @buffer[ 0, len ]
+ s = @buffer[ 0, len ]
+ dest << s
@buffer = @buffer[ len, bsi - len ]
- @pipe << %{read "#{Net.quote dest}"\n} if @pipe
+ @debugout << %<read "#{Net.quote s}"\n> if @debugout
len
end
- ###
- ### write
- ###
+ #
+ # write interfece
+ #
public
-
def write( str )
writing {
do_write str
}
end
-
def writeline( str )
writing {
- do_write str
- do_write "\r\n"
+ do_write str + "\r\n"
}
end
-
def write_bin( src, block )
writing {
if block then
- block.call WriteAdapter.new( self, :do_write )
+ block.call ::Net::NetPrivate::WriteAdapter.new( self, :do_write )
else
src.each do |bin|
do_write bin
@@ -637,19 +713,18 @@ module Net
}
end
-
def write_pendstr( src, block )
- @pipe << "writing text from #{src.type}\n" if @pipe; pipeoff
+ D_off "writing text from #{src.type}"
wsize = use_each_crlf_line {
if block then
- block.call WriteAdapter.new( self, :wpend_in )
+ block.call ::Net::NetPrivate::WriteAdapter.new( self, :wpend_in )
else
wpend_in src
end
}
- @pipe << "wrote #{wsize} bytes text\n" if pipeon
+ D_on "wrote #{wsize} bytes text"
wsize
end
@@ -696,17 +771,17 @@ module Net
beg = 0
buf = @wbuf
while buf.index( /\n|\r\n|\r/, beg ) do
- m = $~
+ m = Regexp.last_match
if m.begin(0) == buf.size - 1 and buf[-1] == ?\r then
# "...\r" : can follow "\n..."
break
end
- str = buf[ beg, m.begin(0) - beg ]
+ str = buf[ beg ... m.begin(0) ]
str.concat "\r\n"
yield str
beg = m.end(0)
end
- @wbuf = buf[ beg, buf.size - beg ]
+ @wbuf = buf[ beg ... buf.size ]
end
end
@@ -736,6 +811,7 @@ module Net
yield
end
end
+ yield unless @wbuf.empty?
end
end
@@ -746,17 +822,17 @@ module Net
yield
- if @pipe then
- @pipe << 'write "'
- @pipe << @sending
- @pipe << "\"\n"
+ if @debugout then
+ @debugout << 'write "'
+ @debugout << @sending
+ @debugout << "\"\n"
end
@socket.flush
@writtensize
end
def do_write( arg )
- if @pipe or @sending.size < 128 then
+ if @debugout or @sending.size < 128 then
@sending << Net.quote( arg )
else
@sending << '...' unless @sending[-1] == ?.
@@ -768,22 +844,25 @@ module Net
end
- def pipeoff
- @prepipe = @pipe
- @pipe = nil
- @prepipe
+ def D_off( msg )
+ D msg
+ @savedo, @debugout = @debugout, nil
end
- def pipeon
- @pipe = @prepipe
- @prepipe = nil
- @pipe
+ def D_on( msg )
+ @debugout = @savedo
+ D msg
end
- end
+ def D( msg )
+ @debugout or return
+ @debugout << msg
+ @debugout << "\n"
+ end
+ end
- end # module Net::NetPrivate
+ }
def Net.quote( str )
diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb
index 9679984e2c..befc1adf03 100644
--- a/lib/net/smtp.rb
+++ b/lib/net/smtp.rb
@@ -1,6 +1,6 @@
=begin
-= net/smtp.rb version 1.1.32
+= net/smtp.rb version 1.1.34
written by Minero Aoki <aamine@dp.u-netsurf.ne.jp>
@@ -30,10 +30,8 @@ Net::Protocol
=== Methods
-: start( helo_domain = Socket.gethostname, \
- account = nil, password = nil, authtype = nil )
-: start( helo_domain = Socket.gethostname, \
- account = nil, password = nil, authtype = nil ) {|smtp| .... }
+: start( helo_domain = Socket.gethostname, account = nil, password = nil, authtype = nil )
+: start( helo_domain = Socket.gethostname, account = nil, password = nil, authtype = nil ) {|smtp| .... }
opens TCP connection and starts SMTP session.
If protocol had been started, do nothing and return false.
@@ -53,10 +51,10 @@ Net::Protocol
to_addrs must be a String(s) or an Array of String.
Exceptions which SMTP raises are:
- * Net::ProtoSyntaxError: syntax error (errno.500)
- * Net::ProtoFatalError: fatal error (errno.550)
- * Net::ProtoUnknownError: unknown error
- * Net::ProtoServerBusy: temporary error (errno.420/450)
+ * Net::ProtoSyntaxError: syntax error (errno.500)
+ * Net::ProtoFatalError: fatal error (errno.550)
+ * Net::ProtoUnknownError: unknown error
+ * Net::ProtoServerBusy: temporary error (errno.420/450)
# usage example
@@ -153,12 +151,15 @@ module Net
end
end
- if user and secret then
+ if user or secret then
+ (user and secret) or
+ raise ArgumentError, 'both of account and password are required'
+
mid = 'auth_' + (authtype || 'cram_md5').to_s
- unless @command.respond_to? mid then
- raise ArgumentError, "wrong auth type #{authtype.to_s}"
- end
- @command.send mid, user, secret
+ @command.respond_to? mid or
+ raise ArgumentError, "wrong auth type #{authtype.to_s}"
+
+ @command.__send__ mid, user, secret
end
end
diff --git a/lib/net/telnet.rb b/lib/net/telnet.rb
index 87790c0300..380e834bea 100644
--- a/lib/net/telnet.rb
+++ b/lib/net/telnet.rb
@@ -4,7 +4,7 @@
net/telnet.rb - simple telnet client library
-Version 1.6.2
+Version 1.6.3
Wakou Aoyama <wakou@fsinet.or.jp>
@@ -239,10 +239,11 @@ module Net
CR = "\015"
LF = "\012"
EOL = CR + LF
- VERSION = "1.6.2"
- RELEASE_DATE = "2000-12-25"
- VERSION_CODE = 162
- RELEASE_CODE = 20001225
+ VERSION = '1.6.3'
+ RELEASE_DATE = '2001-02-26'
+ VERSION_CODE = 163
+ RELEASE_CODE = 20010226
+ REVISION = '$Id$'
def initialize(options)
@options = options
@@ -346,14 +347,13 @@ module Net
attr :sock
def telnetmode(mode = nil)
- if mode
- if (true == mode or false == mode)
- @options["Telnetmode"] = mode
- else
- raise ArgumentError, "required true or false"
- end
- else
+ case mode
+ when nil
@options["Telnetmode"]
+ when true, false
+ @options["Telnetmode"] = mode
+ else
+ raise ArgumentError, "required true or false"
end
end
@@ -366,14 +366,13 @@ module Net
end
def binmode(mode = nil)
- if mode
- if (true == mode or false == mode)
- @options["Binmode"] = mode
- else
- raise ArgumentError, "required true or false"
- end
- else
+ case mode
+ when nil
@options["Binmode"]
+ when true, false
+ @options["Binmode"] = mode
+ else
+ raise ArgumentError, "required true or false"
end
end
@@ -599,181 +598,7 @@ end
== HISTORY
-* Mon Dec 25 01:37:43 JST 2000 - wakou
- * version 1.6.2
- * Regexp::last_match[1] --> $1
-
-* Mon Dec 11 00:16:51 JST 2000 - wakou
- * version 1.6.1
- * $1 --> Regexp::last_match[1]
-
-* 2000/09/12 05:37:35 - matz
- * change: iterator? --> block_given?
-
-* Tue Sep 12 06:52:48 JST 2000 - wakou
- * version 1.6.0
- * correct: document.
- thanks to Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
- * add: Telnet#puts().
-
-* Sun Jun 18 23:31:44 JST 2000 - wakou
- * version 1.5.0
- * change: version syntax. old: x.yz, now: x.y.z
-
-* 2000/05/24 06:57:38 - wakou
- * version 1.40
- * improve: binmode(), telnetmode() interface.
- thanks to Dave Thomas <Dave@thomases.com>
-
-* 2000/05/09 22:02:56 - wakou
- * version 1.32
- * require English.rb
-
-* 2000/05/02 21:48:39 - wakou
- * version 1.31
- * Proxy option: can receive IO object.
-
-* 2000/04/03 18:27:02 - wakou
- * version 1.30
- * telnet.rb --> net/telnet.rb
-
-* 2000/01/24 17:02:57 - wakou
- * version 1.20
- * respond to "IAC WILL x" with "IAC DONT x"
- * respond to "IAC WONT x" with "IAC DONT x"
- * better dumplog format.
- thanks to WATANABE Hirofumi <Hirofumi.Watanabe@jp.sony.com>
-
-* 2000/01/18 17:47:31 - wakou
- * version 1.10
- * bug fix: write method
- * respond to "IAC WILL BINARY" with "IAC DO BINARY"
-
-* 1999/10/04 22:51:26 - wakou
- * version 1.00
- * bug fix: waitfor(preprocess) method.
- thanks to Shin-ichiro Hara <sinara@blade.nagaokaut.ac.jp>
- * add simple support for AO, DM, IP, NOP, SB, SE
- * COUTION! TimeOut --> TimeoutError
-
-* 1999/09/21 21:24:07 - wakou
- * version 0.50
- * add write method
-
-* 1999/09/17 17:41:41 - wakou
- * version 0.40
- * bug fix: preprocess method
-
-* 1999/09/14 23:09:05 - wakou
- * version 0.30
- * change prompt check order.
- not IO::select([@sock], nil, nil, waittime) and prompt === line
- --> prompt === line and not IO::select([@sock], nil, nil, waittime)
-
-* 1999/09/13 22:28:33 - wakou
- * version 0.24
- * Telnet#login: if ommit password, then not require password prompt.
-
-* 1999/08/10 05:20:21 - wakou
- * version 0.232
- * STATUS OUTPUT sample code typo.
- thanks to Tadayoshi Funaba <tadf@kt.rim.or.jp>
- host = Telnet.new({"Hosh" => "localhost"){|c| print c }
- --> host = Telnet.new({"Host" => "localhost"){|c| print c }
-
-* 1999/07/16 13:39:42 - wakou
- * version 0.231
- * TRUE --> true, FALSE --> false
-
-* 1999/07/15 22:32:09 - wakou
- * version 0.23
- * waitfor: if end of file reached, then return nil.
-
-* 1999/06/29 09:08:51 - wakou
- * version 0.22
- * new, waitfor, cmd: {"Timeout" => false} # ignore timeout
-
-* 1999/06/28 18:18:55 - wakou
- * version 0.21
- * waitfor: not rescue (EOFError)
-
-* 1999/06/04 06:24:58 - wakou
- * version 0.20
- * waitfor: support for divided telnet command
-
-* 1999/05/22 - wakou
- * version 0.181
- * bug fix: print method
-
-* 1999/05/14 - wakou
- * version 0.18
- * respond to "IAC WON'T SGA" with "IAC DON'T SGA"
- * DON'T SGA : end of line --> CR + LF
- * bug fix: preprocess method
-
-* 1999/04/30 - wakou
- * version 0.17
- * bug fix: $! + "\n" --> $!.to_s + "\n"
-
-* 1999/04/11 - wakou
- * version 0.163
- * STDOUT.write(message) --> yield(message) if iterator?
-
-* 1999/03/17 - wakou
- * version 0.162
- * add "Proxy" option
- * required timeout.rb
-
-* 1999/02/03 - wakou
- * version 0.161
- * select --> IO::select
-
-* 1998/10/09 - wakou
- * version 0.16
- * preprocess method change for the better
- * add binmode method.
- * change default Binmode. TRUE --> FALSE
-
-* 1998/10/04 - wakou
- * version 0.15
- * add telnetmode method.
-
-* 1998/09/22 - wakou
- * version 0.141
- * change default prompt. /[$%#>] $/ --> /[$%#>] \Z/
-
-* 1998/09/01 - wakou
- * version 0.14
- * IAC WILL SGA send EOL --> CR+NULL
- * IAC WILL SGA IAC DO BIN send EOL --> CR
- * NONE send EOL --> LF
- * add Dump_log option.
-
-* 1998/08/25 - wakou
- * version 0.13
- * add print method.
-
-* 1998/08/05 - wakou
- * version 0.122
- * support for HP-UX 10.20.
- thanks to WATANABE Tetsuya <tetsu@jpn.hp.com>
- * socket.<< --> socket.write
-
-* 1998/07/15 - wakou
- * version 0.121
- * string.+= --> string.concat
-
-* 1998/06/01 - wakou
- * version 0.12
- * add timeout, waittime.
-
-* 1998/04/21 - wakou
- * version 0.11
- * add realtime output.
-
-* 1998/04/13 - wakou
- * version 0.10
- * first release.
-
-$Date$
+delete. see cvs log.
+
+
=end
diff --git a/lib/observer.rb b/lib/observer.rb
index 08e75f5125..e1b249e885 100644
--- a/lib/observer.rb
+++ b/lib/observer.rb
@@ -5,7 +5,7 @@
module Observable
def add_observer(observer)
@observer_peers = [] unless defined? @observer_peers
- unless defined? observer.update
+ unless observer.respond_to? :update
raise NameError, "observer needs to respond to `update'"
end
@observer_peers.push observer
diff --git a/lib/parsedate.rb b/lib/parsedate.rb
index eee114acb2..7fc75cf0c2 100644
--- a/lib/parsedate.rb
+++ b/lib/parsedate.rb
@@ -1,5 +1,5 @@
-# parsedate.rb: Written by Tadayoshi Funaba 2000
-# $Id: parsedate.rb,v 1.2 2000-04-01 12:16:56+09 tadf Exp $
+# parsedate3.rb: Written by Tadayoshi Funaba 2000, 2001
+# $Id: parsedate3.rb,v 1.3 2001-01-18 12:09:47+09 tadf Exp $
module ParseDate
@@ -46,7 +46,12 @@ module ParseDate
hour = $1.to_i
min = $2.to_i
sec = $3.to_i if $3
- hour += 12 if $4 and $4.downcase == 'p'
+ if $4
+ hour %= 12
+ if $4.downcase == 'p'
+ hour += 12
+ end
+ end
zone = $5
end
diff --git a/lib/ping.rb b/lib/ping.rb
index 48657818cc..d698dd0c52 100644
--- a/lib/ping.rb
+++ b/lib/ping.rb
@@ -47,6 +47,8 @@ module Ping
s = TCPsocket.new(host, service)
s.close
end
+ rescue Errno::ECONNREFUSED
+ return true
rescue
return false
end
diff --git a/lib/thread.rb b/lib/thread.rb
index d4b6ad6ec1..559cd95a8a 100644
--- a/lib/thread.rb
+++ b/lib/thread.rb
@@ -185,7 +185,7 @@ class Queue
end
end
def shift(non_block=false)
- pop(non_block=false)
+ pop(non_block)
end
alias deq shift
diff --git a/math.c b/math.c
index ac87b9c8dc..2cac83e938 100644
--- a/math.c
+++ b/math.c
@@ -64,6 +64,11 @@ math_exp(obj, x)
return rb_float_new(exp(RFLOAT(x)->value));
}
+#if defined __CYGWIN__
+#define log(x) ((x) < 0.0 ? nan() : log(x))
+#define log10(x) ((x) < 0.0 ? nan() : log10(x))
+#endif
+
static VALUE
math_log(obj, x)
VALUE obj, x;
diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el
index c0754efad4..7dd4708176 100644
--- a/misc/ruby-mode.el
+++ b/misc/ruby-mode.el
@@ -749,7 +749,7 @@ An end of a defun is found by moving forward from the beginning of one."
'("^\\s *def\\s +\\([^( ]+\\)"
1 font-lock-function-name-face)
;; symbols
- '("\\(^\\|[^:]\\)\\(:\\(\\w\\|_\\)+\\??\\)\\b"
+ '("\\(^\\|[^:]\\)\\(:\\([-+/%&|^~`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|\\[\\]\\|\\(\\w\\|_\\)+\\([!?=]\\|\\b\\)\\)\\)"
2 font-lock-reference-face))
"*Additional expressions to highlight in ruby mode."))
diff --git a/missing/flock.c b/missing/flock.c
index 78576d438c..e293ca0d72 100644
--- a/missing/flock.c
+++ b/missing/flock.c
@@ -1,6 +1,55 @@
#include "config.h"
-#if defined(HAVE_LOCKF)
+#if defined HAVE_FCNTL && defined HAVE_FCNTL_H
+
+/* These are the flock() constants. Since this sytems doesn't have
+ flock(), the values of the constants are probably not available.
+*/
+# ifndef LOCK_SH
+# define LOCK_SH 1
+# endif
+# ifndef LOCK_EX
+# define LOCK_EX 2
+# endif
+# ifndef LOCK_NB
+# define LOCK_NB 4
+# endif
+# ifndef LOCK_UN
+# define LOCK_UN 8
+# endif
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+
+int
+flock(fd, operation)
+ int fd;
+ int operation;
+{
+ struct flock lock;
+
+ switch (operation & ~LOCK_NB) {
+ case LOCK_SH:
+ lock.l_type = F_RDLCK;
+ break;
+ case LOCK_EX:
+ lock.l_type = F_WRLCK;
+ break;
+ case LOCK_UN:
+ lock.l_type = F_UNLCK;
+ break;
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+ lock.l_whence = SEEK_SET;
+ lock.l_start = lock.l_len = 0L;
+
+ return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);
+}
+
+#elif defined(HAVE_LOCKF)
#include <unistd.h>
#include <errno.h>
@@ -50,6 +99,8 @@ flock(fd, operation)
/* LOCK_SH - get a shared lock */
case LOCK_SH:
+ rb_notimplement();
+ return -1;
/* LOCK_EX - get an exclusive lock */
case LOCK_EX:
i = lockf (fd, F_LOCK, 0);
@@ -57,6 +108,8 @@ flock(fd, operation)
/* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
case LOCK_SH|LOCK_NB:
+ rb_notimplement();
+ return -1;
/* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
case LOCK_EX|LOCK_NB:
i = lockf (fd, F_TLOCK, 0);
@@ -78,54 +131,6 @@ flock(fd, operation)
}
return i;
}
-#elif defined HAVE_FCNTL && defined HAVE_FCNTL_H
-
-/* These are the flock() constants. Since this sytems doesn't have
- flock(), the values of the constants are probably not available.
-*/
-# ifndef LOCK_SH
-# define LOCK_SH 1
-# endif
-# ifndef LOCK_EX
-# define LOCK_EX 2
-# endif
-# ifndef LOCK_NB
-# define LOCK_NB 4
-# endif
-# ifndef LOCK_UN
-# define LOCK_UN 8
-# endif
-
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
-int
-flock(fd, operation)
- int fd;
- int operation;
-{
- struct flock lock;
-
- switch (operation & ~LOCK_NB) {
- case LOCK_SH:
- lock.l_type = F_RDLCK;
- break;
- case LOCK_EX:
- lock.l_type = F_WRLCK;
- break;
- case LOCK_UN:
- lock.l_type = F_UNLCK;
- break;
- default:
- errno = EINVAL;
- return -1;
- }
- lock.l_whence = SEEK_SET;
- lock.l_start = lock.l_len = 0L;
-
- return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &lock);
-}
#elif !defined NT
int
flock(fd, operation)
diff --git a/missing/strftime.c b/missing/strftime.c
index 6bce490249..3042649aeb 100644
--- a/missing/strftime.c
+++ b/missing/strftime.c
@@ -113,12 +113,6 @@ extern char *getenv();
extern char *strchr();
#endif
-#ifdef __GNUC__
-#define inline __inline__
-#else
-#define inline /**/
-#endif
-
#define range(low, item, hi) max(low, min(item, hi))
#if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME)
diff --git a/missing/vsnprintf.c b/missing/vsnprintf.c
index d297209d06..489bf58361 100644
--- a/missing/vsnprintf.c
+++ b/missing/vsnprintf.c
@@ -108,9 +108,7 @@
#define __const
#endif /* People who don't like const sys_error */
-#if defined NT && !defined __MINGW32__
-typedef long size_t;
-#endif
+#include <stddef.h>
#ifndef NULL
#define NULL 0
@@ -1095,8 +1093,6 @@ vsnprintf(str, n, fmt, ap)
static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
-#include <stddef.h>
-
#if defined(__STDC__)
# include <stdarg.h>
#else
diff --git a/mkconfig.rb b/mkconfig.rb
index 175a4c3b15..c190861b5e 100644
--- a/mkconfig.rb
+++ b/mkconfig.rb
@@ -28,11 +28,11 @@ has_srcdir = false
has_version = false
File.foreach "config.status" do |$_|
next if /^#/
- if /^s%@program_transform_name@%s,(.*)%g$/
+ if /^s[%,]@program_transform_name@[%,]s,(.*)[%,]/
next if $install_name
ptn = $1.sub(/\$\$/, '$').split(/,/) #'
v_fast << " CONFIG[\"ruby_install_name\"] = \"" + "ruby".sub(ptn[0],ptn[1]) + "\"\n"
- elsif /^s%@(\w+)@%(.*)%g/
+ elsif /^s[%,]@(\w+)@[%,](.*)[%,]/
name = $1
val = $2 || ""
next if name =~ /^(INSTALL|DEFS|configure_input|srcdir|top_srcdir)$/
@@ -48,19 +48,6 @@ File.foreach "config.status" do |$_|
v_others << v
end
has_version = true if name == "MAJOR"
- if /DEFS/
- val.split(/\s*-D/).each do |i|
- if i =~ /(.*)=(\\")?([^\\]*)(\\")?/
- key, val = $1, $3
- if val == '1'
- val = "TRUE"
- else
- val.sub! /^\s*(.*)\s*$/, '"\1"'
- end
- print " CONFIG[\"#{key}\"] = #{val}\n"
- end
- end
- end
elsif /^ac_given_srcdir=(.*)/
v_fast << " CONFIG[\"srcdir\"] = \"" + File.expand_path($1) + "\"\n"
has_srcdir = true
diff --git a/node.h b/node.h
index 1904a0a072..19e95cd4f2 100644
--- a/node.h
+++ b/node.h
@@ -21,6 +21,7 @@ enum node_type {
NODE_METHOD,
NODE_FBODY,
NODE_CFUNC,
+ NODE_IFUNC,
NODE_SCOPE,
NODE_BLOCK,
NODE_IF,
@@ -234,6 +235,7 @@ typedef struct RNode {
#define NEW_DEFN(i,a,d,p) rb_node_newnode(NODE_DEFN,p,i,NEW_RFUNC(a,d))
#define NEW_DEFS(r,i,a,d) rb_node_newnode(NODE_DEFS,r,i,NEW_RFUNC(a,d))
#define NEW_CFUNC(f,c) rb_node_newnode(NODE_CFUNC,f,c,0)
+#define NEW_IFUNC(f,c) rb_node_newnode(NODE_IFUNC,f,c,0)
#define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2))
#define NEW_SCOPE(b) rb_node_newnode(NODE_SCOPE,local_tbl(),cur_cref,(b))
#define NEW_BLOCK(a) rb_node_newnode(NODE_BLOCK,a,0,0)
diff --git a/object.c b/object.c
index 4e3d5dd856..1cf78fae5d 100644
--- a/object.c
+++ b/object.c
@@ -162,6 +162,7 @@ inspect_i(id, value, str)
if (!rb_is_instance_id(id)) return ST_CONTINUE;
if (RSTRING(str)->ptr[0] == '-') { /* first element */
RSTRING(str)->ptr[0] = '#';
+ rb_str_cat2(str, " ");
}
else {
rb_str_cat2(str, ", ");
@@ -182,6 +183,7 @@ inspect_obj(obj, str)
{
st_foreach(ROBJECT(obj)->iv_tbl, inspect_i, str);
rb_str_cat2(str, ">");
+ RSTRING(str)->ptr[0] = '#';
OBJ_INFECT(str, obj);
return str;
@@ -286,6 +288,9 @@ rb_obj_taint(obj)
VALUE obj;
{
rb_secure(4);
+ if (OBJ_FROZEN(obj)) {
+ rb_error_frozen("object");
+ }
OBJ_TAINT(obj);
return obj;
}
@@ -532,11 +537,14 @@ rb_mod_clone(module)
}
static VALUE
-rb_mod_dup(module)
- VALUE module;
+rb_mod_dup(mod)
+ VALUE mod;
{
- VALUE dup = rb_mod_clone(module);
- OBJSETUP(dup, RBASIC(module)->klass, BUILTIN_TYPE(module));
+ VALUE dup = rb_mod_clone(mod);
+ OBJSETUP(dup, RBASIC(mod)->klass, BUILTIN_TYPE(mod));
+ if (FL_TEST(mod, FL_SINGLETON)) {
+ FL_SET(dup, FL_SINGLETON);
+ }
return dup;
}
diff --git a/pack.c b/pack.c
index 5538600449..9e05f46c5a 100644
--- a/pack.c
+++ b/pack.c
@@ -826,7 +826,7 @@ pack_pack(ary, fmt)
case 'm':
ptr = rb_str2cstr(NEXTFROM, &plen);
- if (len <= 1)
+ if (len <= 2)
len = 45;
else
len = len / 3 * 3;
@@ -1026,11 +1026,7 @@ qpencode(str, from, len)
}
}
-#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(RUBY_NO_INLINE)
-static __inline__ int
-#else
-static int
-#endif
+static inline int
hex2num(c)
char c;
{
diff --git a/parse.y b/parse.y
index d1f1a32321..29557aa90b 100644
--- a/parse.y
+++ b/parse.y
@@ -6,7 +6,7 @@
$Date$
created at: Fri May 28 18:02:42 JST 1993
- Copyright (C) 1993-2000 Yukihiro Matsumoto
+ Copyright (C) 1993-2001 Yukihiro Matsumoto
**********************************************************************/
@@ -49,7 +49,6 @@ static int yyerror();
static enum lex_state {
EXPR_BEG, /* ignore newline, +/- is a sign. */
EXPR_END, /* newline significant, +/- is a operator. */
- EXPR_PAREN, /* almost like EXPR_END, `do' works as `{'. */
EXPR_ARG, /* newline significant, +/- is a operator. */
EXPR_MID, /* newline significant, +/- is a operator. */
EXPR_FNAME, /* ignore newline, no reserved words. */
@@ -57,8 +56,16 @@ static enum lex_state {
EXPR_CLASS, /* immediate after `class', no here document. */
} lex_state;
+#if SIZEOF_LONG_LONG > 0
+typedef unsigned long long stack_type;
+#elif SIZEOF___INT64 > 0
+typedef unsigned __int64 stack_type;
+#else
+typedef unsigned long stack_type;
+#endif
+
static int cond_nest = 0;
-static unsigned long cond_stack = 0;
+static stack_type cond_stack = 0;
#define COND_PUSH do {\
cond_nest++;\
cond_stack = (cond_stack<<1)|1;\
@@ -67,10 +74,20 @@ static unsigned long cond_stack = 0;
cond_nest--;\
cond_stack >>= 1;\
} while (0)
-#define IN_COND (cond_nest > 0 && (cond_stack&1))
+#define COND_P() (cond_nest > 0 && (cond_stack&1))
+
+static stack_type cmdarg_stack = 0;
+#define CMDARG_PUSH do {\
+ cmdarg_stack = (cmdarg_stack<<1)|1;\
+} while(0)
+#define CMDARG_POP do {\
+ cmdarg_stack >>= 1;\
+} while (0)
+#define CMDARG_P() (cmdarg_stack && (cmdarg_stack&1))
static int class_nest = 0;
static int in_single = 0;
+static int in_def = 0;
static int compile_for_eval = 0;
static ID cur_mid = 0;
@@ -155,7 +172,8 @@ static void top_local_setup();
kRETRY
kIN
kDO
- kDO2
+ kDO_COND
+ kDO_BLOCK
kRETURN
kYIELD
kSUPER
@@ -184,11 +202,11 @@ static void top_local_setup();
%type <node> singleton string
%type <val> literal numeric
-%type <node> compstmt stmts stmt expr arg primary command_call method_call
+%type <node> compstmt stmts stmt expr arg primary command command_call method_call
%type <node> if_tail opt_else case_body cases rescue exc_list exc_var ensure
-%type <node> opt_call_args call_args ret_args args when_args
-%type <node> aref_args opt_block_arg block_arg stmt_rhs
-%type <node> mrhs mrhs_basic superclass generic_call block_call var_ref
+%type <node> args ret_args when_args call_args paren_args opt_paren_args
+%type <node> command_args aref_args opt_block_arg block_arg var_ref
+%type <node> mrhs mrhs_basic superclass block_call block_command
%type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg
%type <node> assoc_list assocs assoc undef_list backref
%type <node> block_var opt_block_var brace_block do_block lhs none
@@ -295,16 +313,15 @@ stmts : none
$$ = $2;
}
-stmt : block_call
- | kALIAS fitem {lex_state = EXPR_FNAME;} fitem
+stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem
{
- if (cur_mid || in_single)
+ if (in_def || in_single)
yyerror("alias within method");
$$ = NEW_ALIAS($2, $4);
}
| kALIAS tGVAR tGVAR
{
- if (cur_mid || in_single)
+ if (in_def || in_single)
yyerror("alias within method");
$$ = NEW_VALIAS($2, $3);
}
@@ -312,7 +329,7 @@ stmt : block_call
{
char buf[3];
- if (cur_mid || in_single)
+ if (in_def || in_single)
yyerror("alias within method");
sprintf(buf, "$%c", $3->nd_nth);
$$ = NEW_VALIAS($2, rb_intern(buf));
@@ -324,7 +341,7 @@ stmt : block_call
}
| kUNDEF undef_list
{
- if (cur_mid || in_single)
+ if (in_def || in_single)
yyerror("undef within method");
$$ = $2;
}
@@ -343,31 +360,21 @@ stmt : block_call
| stmt kWHILE_MOD expr
{
value_expr($3);
- if ($1) {
- if (nd_type($1) == NODE_BEGIN) {
- $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
- }
- else {
- $$ = NEW_WHILE(cond($3), $1, 1);
- }
+ if ($1 && nd_type($1) == NODE_BEGIN) {
+ $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
}
else {
- $$ = 0;
+ $$ = NEW_WHILE(cond($3), $1, 1);
}
}
| stmt kUNTIL_MOD expr
{
value_expr($3);
- if ($1) {
- if (nd_type($1) == NODE_BEGIN) {
- $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
- }
- else {
- $$ = NEW_UNTIL(cond($3), $1, 1);
- }
+ if ($1 && nd_type($1) == NODE_BEGIN) {
+ $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
}
else {
- $$ = 0;
+ $$ = NEW_UNTIL(cond($3), $1, 1);
}
}
| stmt kRESCUE_MOD stmt
@@ -376,7 +383,7 @@ stmt : block_call
}
| klBEGIN
{
- if (cur_mid || in_single) {
+ if (in_def || in_single) {
yyerror("BEGIN in method");
}
local_push();
@@ -390,18 +397,18 @@ stmt : block_call
}
| klEND '{' compstmt '}'
{
- if (compile_for_eval && (cur_mid || in_single)) {
+ if (compile_for_eval && (in_def || in_single)) {
yyerror("END in method; use at_exit");
}
$$ = NEW_ITER(0, NEW_POSTEXE(), $3);
}
- | lhs '=' stmt_rhs
+ | lhs '=' command_call
{
value_expr($3);
$$ = node_assign($1, $3);
}
- | mlhs '=' stmt_rhs
+ | mlhs '=' command_call
{
value_expr($3);
$1->nd_value = $3;
@@ -421,7 +428,7 @@ expr : mlhs '=' mrhs
}
| kRETURN ret_args
{
- if (!compile_for_eval && !cur_mid && !in_single)
+ if (!compile_for_eval && !in_def && !in_single)
yyerror("return appeared outside of method");
$$ = NEW_RETURN($2);
}
@@ -445,26 +452,41 @@ expr : mlhs '=' mrhs
}
| arg
-command_call : operation call_args
+command_call : command
+ | block_command
+
+block_command : block_call
+ | block_call '.' operation2 command_args
+ {
+ value_expr($1);
+ $$ = new_call($1, $3, $4);
+ }
+ | block_call tCOLON2 operation2 command_args
+ {
+ value_expr($1);
+ $$ = new_call($1, $3, $4);
+ }
+
+command : operation command_args
{
$$ = new_fcall($1, $2);
fixpos($$, $2);
}
- | primary '.' operation2 call_args
+ | primary '.' operation2 command_args
{
value_expr($1);
$$ = new_call($1, $3, $4);
fixpos($$, $1);
}
- | primary tCOLON2 operation2 call_args
+ | primary tCOLON2 operation2 command_args
{
value_expr($1);
$$ = new_call($1, $3, $4);
fixpos($$, $1);
}
- | kSUPER call_args
+ | kSUPER command_args
{
- if (!compile_for_eval && !cur_mid && !in_single)
+ if (!compile_for_eval && !in_def && !in_single)
yyerror("super called outside of method");
$$ = new_super($2);
fixpos($$, $2);
@@ -475,7 +497,6 @@ command_call : operation call_args
fixpos($$, $2);
}
-
mlhs : mlhs_basic
| tLPAREN mlhs_entry ')'
{
@@ -897,14 +918,6 @@ aref_args : none
{
$$ = list_append($1, $3);
}
- | block_call opt_nl
- {
- $$ = NEW_LIST($1);
- }
- | args ',' block_call opt_nl
- {
- $$ = list_append($1, $3);
- }
| args trailer
{
$$ = $1;
@@ -924,22 +937,31 @@ aref_args : none
$$ = NEW_RESTARGS($2);
}
-opt_call_args : none
- | call_args opt_nl
- | block_call opt_nl
+paren_args : '(' none ')'
{
- $$ = NEW_LIST($1);
+ $$ = $2;
}
- | args ',' block_call
+ | '(' call_args opt_nl ')'
{
- $$ = list_append($1, $3);
+ $$ = $2;
+ }
+ | '(' block_call opt_nl ')'
+ {
+ $$ = NEW_LIST($2);
}
+ | '(' args ',' block_call opt_nl ')'
+ {
+ $$ = list_append($2, $4);
+ }
+
+opt_paren_args : none
+ | paren_args
-call_args : command_call
+call_args : command
{
$$ = NEW_LIST($1);
}
- | args ',' command_call
+ | args ',' command
{
$$ = list_append($1, $3);
}
@@ -953,10 +975,6 @@ call_args : command_call
$$ = arg_concat($1, $4);
$$ = arg_blk_pass($$, $5);
}
- | assocs ','
- {
- $$ = NEW_LIST(NEW_HASH($1));
- }
| assocs opt_block_arg
{
$$ = NEW_LIST(NEW_HASH($1));
@@ -973,10 +991,6 @@ call_args : command_call
$$ = list_append($1, NEW_HASH($3));
$$ = arg_blk_pass($$, $4);
}
- | args ',' assocs ','
- {
- $$ = list_append($1, NEW_HASH($3));
- }
| args ',' assocs ',' tSTAR arg opt_block_arg
{
value_expr($6);
@@ -990,6 +1004,12 @@ call_args : command_call
}
| block_arg
+command_args : {CMDARG_PUSH;} call_args
+ {
+ CMDARG_POP;
+ $$ = $2;
+ }
+
block_arg : tAMPER arg
{
value_expr($2);
@@ -1119,20 +1139,20 @@ primary : literal
}
| kRETURN '(' ret_args ')'
{
- if (!compile_for_eval && !cur_mid && !in_single)
+ if (!compile_for_eval && !in_def && !in_single)
yyerror("return appeared outside of method");
value_expr($3);
$$ = NEW_RETURN($3);
}
| kRETURN '(' ')'
{
- if (!compile_for_eval && !cur_mid && !in_single)
+ if (!compile_for_eval && !in_def && !in_single)
yyerror("return appeared outside of method");
$$ = NEW_RETURN(0);
}
| kRETURN
{
- if (!compile_for_eval && !cur_mid && !in_single)
+ if (!compile_for_eval && !in_def && !in_single)
yyerror("return appeared outside of method");
$$ = NEW_RETURN(0);
}
@@ -1225,9 +1245,8 @@ primary : literal
}
| kCLASS cname superclass
{
- if (cur_mid || in_single)
+ if (in_def || in_single)
yyerror("class definition in method body");
-
class_nest++;
cref_push();
local_push();
@@ -1242,8 +1261,15 @@ primary : literal
cref_pop();
class_nest--;
}
- | kCLASS tLSHFT expr term
+ | kCLASS tLSHFT expr
{
+ $<num>$ = in_def;
+ in_def = 0;
+ }
+ term
+ {
+ $<num>$ = in_single;
+ in_single = 0;
class_nest++;
cref_push();
local_push();
@@ -1251,15 +1277,17 @@ primary : literal
compstmt
kEND
{
- $$ = NEW_SCLASS($3, $6);
+ $$ = NEW_SCLASS($3, $7);
fixpos($$, $3);
local_pop();
cref_pop();
class_nest--;
+ in_def = $<num>4;
+ in_single = $<num>6;
}
| kMODULE cname
{
- if (cur_mid || in_single)
+ if (in_def || in_single)
yyerror("module definition in method body");
class_nest++;
cref_push();
@@ -1277,9 +1305,11 @@ primary : literal
}
| kDEF fname
{
- if (cur_mid || in_single)
+ if (in_def || in_single)
yyerror("nested method definition");
+ $<id>$ = cur_mid;
cur_mid = $2;
+ in_def++;
local_push();
}
f_arglist
@@ -1301,7 +1331,8 @@ primary : literal
if (is_attrset_id($2)) $$->nd_noex = NOEX_PUBLIC;
fixpos($$, $4);
local_pop();
- cur_mid = 0;
+ in_def--;
+ cur_mid = $<id>3;
}
| kDEF singleton dot_or_colon {lex_state = EXPR_FNAME;} fname
{
@@ -1312,8 +1343,18 @@ primary : literal
}
f_arglist
compstmt
+ rescue
+ opt_else
+ ensure
kEND
{
+ if ($9) $8 = NEW_RESCUE($8, $9, $10);
+ else if ($10) {
+ rb_warn("else without rescue is useless");
+ $8 = block_append($8, $10);
+ }
+ if ($11) $8 = NEW_ENSURE($8, $11);
+
$$ = NEW_DEFS($2, $5, $7, $8);
fixpos($$, $2);
local_pop();
@@ -1341,7 +1382,7 @@ then : term
| term kTHEN
do : term
- | kDO
+ | kDO_COND
if_tail : opt_else
| kELSIF expr then
@@ -1377,7 +1418,7 @@ opt_block_var : none
}
-do_block : kDO
+do_block : kDO_BLOCK
{
$<vars>$ = dyna_push();
}
@@ -1390,47 +1431,7 @@ do_block : kDO
dyna_pop($<vars>2);
}
-brace_block : '{'
- {
- $<vars>$ = dyna_push();
- }
- opt_block_var
- compstmt '}'
- {
- $$ = NEW_ITER($3, 0, $4);
- fixpos($$, $4);
- dyna_pop($<vars>2);
- }
- | kDO2
- {
- $<vars>$ = dyna_push();
- }
- opt_block_var
- compstmt
- kEND
- {
- $$ = NEW_ITER($3, 0, $4);
- fixpos($$, $4);
- dyna_pop($<vars>2);
- }
-
-
-generic_call : tIDENTIFIER
- {
- $$ = NEW_VCALL($1);
- }
- | tCONSTANT
- {
- $$ = NEW_VCALL($1);
- }
- | tFID
- {
- $$ = NEW_VCALL($1);
- }
- | method_call
- | command_call
-
-block_call : generic_call do_block
+block_call : command do_block
{
if ($1 && nd_type($1) == NODE_BLOCK_PASS) {
rb_compile_error("both block arg and actual block given");
@@ -1439,28 +1440,32 @@ block_call : generic_call do_block
$$ = $2;
fixpos($$, $2);
}
-
-method_call : operation '(' opt_call_args close_paren
+ | block_call '.' operation2 opt_paren_args
{
- $$ = new_fcall($1, $3);
- fixpos($$, $3);
+ value_expr($1);
+ $$ = new_call($1, $3, $4);
}
- | primary '.' operation2 '(' opt_call_args close_paren
+ | block_call tCOLON2 operation2 opt_paren_args
{
value_expr($1);
- $$ = new_call($1, $3, $5);
- fixpos($$, $1);
+ $$ = new_call($1, $3, $4);
}
- | primary '.' operation2
+
+method_call : operation paren_args
+ {
+ $$ = new_fcall($1, $2);
+ fixpos($$, $2);
+ }
+ | primary '.' operation2 opt_paren_args
{
value_expr($1);
- $$ = new_call($1, $3, 0);
+ $$ = new_call($1, $3, $4);
fixpos($$, $1);
}
- | primary tCOLON2 operation2 '(' opt_call_args close_paren
+ | primary tCOLON2 operation2 paren_args
{
value_expr($1);
- $$ = new_call($1, $3, $5);
+ $$ = new_call($1, $3, $4);
fixpos($$, $1);
}
| primary tCOLON2 operation3
@@ -1468,28 +1473,43 @@ method_call : operation '(' opt_call_args close_paren
value_expr($1);
$$ = new_call($1, $3, 0);
}
- | kSUPER '(' opt_call_args close_paren
+ | kSUPER paren_args
{
- if (!compile_for_eval && !cur_mid &&
+ if (!compile_for_eval && !in_def &&
!in_single && !in_defined)
yyerror("super called outside of method");
- $$ = new_super($3);
+ $$ = new_super($2);
}
| kSUPER
{
- if (!compile_for_eval && !cur_mid &&
+ if (!compile_for_eval && !in_def &&
!in_single && !in_defined)
yyerror("super called outside of method");
$$ = NEW_ZSUPER();
}
-close_paren : ')'
+brace_block : '{'
{
- if (!IN_COND) lex_state = EXPR_PAREN;
+ $<vars>$ = dyna_push();
+ }
+ opt_block_var
+ compstmt '}'
+ {
+ $$ = NEW_ITER($3, 0, $4);
+ fixpos($$, $4);
+ dyna_pop($<vars>2);
+ }
+ | kDO
+ {
+ $<vars>$ = dyna_push();
+ }
+ opt_block_var
+ compstmt kEND
+ {
+ $$ = NEW_ITER($3, 0, $4);
+ fixpos($$, $4);
+ dyna_pop($<vars>2);
}
-
-stmt_rhs : block_call
- | command_call
case_body : kWHEN when_args then
compstmt
@@ -1967,6 +1987,7 @@ yycompile(f, line)
cond_stack = 0;
class_nest = 0;
in_single = 0;
+ in_def = 0;
cur_mid = 0;
if (n == 0) node = ruby_eval_tree;
@@ -2043,10 +2064,7 @@ rb_compile_file(f, file, start)
return yycompile(strdup(f), start);
}
-#if defined(__GNUC__) && __GNUC__ >= 2
-__inline__
-#endif
-static int
+static inline int
nextc()
{
int c;
@@ -2542,13 +2560,12 @@ parse_qstring(term, paren)
c = '\\';
break;
- case '\'':
- if (term == '\'') {
- c = '\'';
- break;
- }
- /* fall through */
default:
+ /* fall through */
+ if (c == term || (paren && c == paren)) {
+ tokadd(c);
+ continue;
+ }
tokadd('\\');
}
}
@@ -2603,7 +2620,7 @@ parse_quotedwords(term, paren)
c = '\\';
break;
default:
- if (c == term) {
+ if (c == term || (paren && c == paren)) {
tokadd(c);
continue;
}
@@ -2794,7 +2811,7 @@ arg_ambiguous()
rb_warning("ambiguous first argument; make sure");
}
-#ifndef strtod
+#if !defined(strtod) && !defined(HAVE_STDLIB_H)
double strtod ();
#endif
@@ -2919,8 +2936,7 @@ yylex()
case '<':
c = nextc();
if (c == '<' &&
- lex_state != EXPR_END && lex_state != EXPR_PAREN &&
- lex_state != EXPR_CLASS &&
+ lex_state != EXPR_END && lex_state != EXPR_CLASS &&
(lex_state != EXPR_ARG || space_seen)) {
int c2 = nextc();
int indent = 0;
@@ -2979,7 +2995,7 @@ yylex()
return parse_qstring(c,0);
case '?':
- if (lex_state == EXPR_END || lex_state == EXPR_PAREN) {
+ if (lex_state == EXPR_END) {
lex_state = EXPR_BEG;
return '?';
}
@@ -3306,7 +3322,7 @@ yylex()
return tCOLON2;
}
pushback(c);
- if (lex_state == EXPR_END || lex_state == EXPR_PAREN || ISSPACE(c)) {
+ if (lex_state == EXPR_END || ISSPACE(c)) {
lex_state = EXPR_BEG;
return ':';
}
@@ -3390,9 +3406,7 @@ yylex()
return c;
case '{':
- if (lex_state != EXPR_END &&
- lex_state != EXPR_PAREN &&
- lex_state != EXPR_ARG)
+ if (lex_state != EXPR_END && lex_state != EXPR_ARG)
c = tLBRACE;
lex_state = EXPR_BEG;
return c;
@@ -3616,10 +3630,10 @@ yylex()
if (state == EXPR_FNAME) {
yylval.id = rb_intern(kw->name);
}
- if (kw->id[0] == kDO &&
- (state == EXPR_PAREN ||
- (!IN_COND && state == EXPR_ARG))) {
- return kDO2;
+ if (kw->id[0] == kDO) {
+ if (COND_P()) return kDO_COND;
+ if (CMDARG_P()) return kDO_BLOCK;
+ return kDO;
}
return kw->id[state != EXPR_BEG];
}
@@ -4121,7 +4135,7 @@ assignable(id, val)
return NEW_IASGN(id, val);
}
else if (is_const_id(id)) {
- if (cur_mid || in_single)
+ if (in_def || in_single)
yyerror("dynamic constant assignment");
return NEW_CDECL(id, val);
}
@@ -4375,6 +4389,9 @@ void_expr(node)
}
}
+
+static NODE *cond2 _((NODE*));
+
static void
void_stmts(node)
NODE *node;
@@ -4390,8 +4407,6 @@ void_stmts(node)
}
}
-static NODE *cond2();
-
static int
assign_in_cond(node)
NODE *node;
diff --git a/prec.c b/prec.c
index 8dcd121bc0..fab5ea3899 100644
--- a/prec.c
+++ b/prec.c
@@ -43,7 +43,7 @@ prec_prec_f(x)
static VALUE
prec_induced_from(module, x)
-
+ VALUE module, x;
{
rb_raise(rb_eTypeError, "undefined conversion from %s into %s",
rb_class2name(CLASS_OF(x)), rb_class2name(module));
diff --git a/re.c b/re.c
index bb9898fdb4..0cf81ef607 100644
--- a/re.c
+++ b/re.c
@@ -288,11 +288,11 @@ rb_reg_desc(s, len, re)
rb_str_cat2(str, "/");
if (re) {
rb_reg_check(re);
- if (RREGEXP(re)->ptr->options & RE_OPTION_MULTILINE)
- rb_str_cat2(str, "m");
/* /p is obsolete; to be removed */
if ((RREGEXP(re)->ptr->options & RE_OPTION_POSIXLINE) == RE_OPTION_POSIXLINE)
rb_str_cat2(str, "p");
+ else if (RREGEXP(re)->ptr->options & RE_OPTION_MULTILINE)
+ rb_str_cat2(str, "m");
if (RREGEXP(re)->ptr->options & RE_OPTION_IGNORECASE)
rb_str_cat2(str, "i");
if (RREGEXP(re)->ptr->options & RE_OPTION_EXTENDED)
@@ -915,8 +915,7 @@ rb_reg_equal(re1, re2)
if (min > RREGEXP(re2)->len) min = RREGEXP(re2)->len;
if (memcmp(RREGEXP(re1)->str, RREGEXP(re2)->str, min) == 0 &&
rb_reg_cur_kcode(re1) == rb_reg_cur_kcode(re2) &&
- !((RREGEXP(re1)->ptr->options & RE_OPTION_IGNORECASE) ^
- (RREGEXP(re2)->ptr->options & RE_OPTION_IGNORECASE))) {
+ RREGEXP(re1)->ptr->options == RREGEXP(re2)->ptr->options) {
return Qtrue;
}
return Qfalse;
@@ -1015,6 +1014,7 @@ rb_reg_initialize_m(argc, argv, self)
p = rb_str2cstr(src, &len);
rb_reg_initialize(self, p, len, flag);
}
+ return self;
}
static VALUE
@@ -1123,6 +1123,12 @@ rb_reg_options(re)
rb_reg_check(re);
if (RREGEXP(re)->ptr->options & RE_OPTION_IGNORECASE)
options |= RE_OPTION_IGNORECASE;
+ if ((RREGEXP(re)->ptr->options & RE_OPTION_POSIXLINE) == RE_OPTION_POSIXLINE)
+ options |= RE_OPTION_POSIXLINE;
+ else if (RREGEXP(re)->ptr->options & RE_OPTION_MULTILINE)
+ options |= RE_OPTION_MULTILINE;
+ if (RREGEXP(re)->ptr->options & RE_OPTION_EXTENDED)
+ options |= RE_OPTION_EXTENDED;
if (FL_TEST(re, KCODE_FIXED)) {
options |= rb_reg_get_kcode(re);
}
diff --git a/regex.c b/regex.c
index d4c1c2a915..07963b5d1d 100644
--- a/regex.c
+++ b/regex.c
@@ -3461,7 +3461,8 @@ re_search(bufp, string, size, startpos, range, regs)
#define PREV_IS_A_LETTER(d) ((current_mbctype == MBCTYPE_SJIS)? \
IS_A_LETTER((d)-(!AT_STRINGS_BEG((d)-1)&& \
ismbchar((d)[-2])?2:1)): \
- ((d)[-1] >= 0x80 || IS_A_LETTER((d)-1)))
+ ((current_mbctype && ((d)[-1] >= 0x80)) || \
+ IS_A_LETTER((d)-1)))
static void
init_regs(regs, num_regs)
diff --git a/ruby.c b/ruby.c
index 9649b69af4..da1049533d 100644
--- a/ruby.c
+++ b/ruby.c
@@ -214,13 +214,23 @@ ruby_init_loadpath()
#elif defined(DJGPP)
extern char *__dos_argv0;
strncpy(libpath, __dos_argv0, FILENAME_MAX);
+#define CharNext(p) ((p) + mblen(p, MB_CUR_MAX))
#elif defined(__EMX__)
_execname(libpath, FILENAME_MAX);
#endif
- p = strrchr(libpath, '\\');
+
+#ifndef CharNext /* defined as CharNext[AW] on Windows. */
+#define CharNext(p) ((p) + 1)
+#endif
+
+ for (p = libpath; *p; p = CharNext(p))
+ if (*p == '\\')
+ *p = '/';
+
+ p = strrchr(libpath, '/');
if (p) {
*p = 0;
- if (p-libpath > 3 && !strcasecmp(p-4, "\\bin")) {
+ if (p-libpath > 3 && !strcasecmp(p-4, "/bin")) {
p -= 4;
*p = 0;
}
@@ -229,14 +239,6 @@ ruby_init_loadpath()
p = libpath + 1;
}
-#if !defined(__CYGWIN32__)
-#ifndef CharNext /* defined as CharNext[AW] on Windows. */
-#define CharNext(p) ((p) + 1)
-#endif
- for (p = libpath; *p; p = CharNext(p))
- if (*p == '\\')
- *p = '/';
-#endif
rest = FILENAME_MAX - (p - libpath);
#define RUBY_RELATIVE(path) (strncpy(p, (path), rest), libpath)
@@ -428,6 +430,10 @@ proc_options(argc, argv)
goto reswitch;
case 'v':
+ if (verbose) {
+ s++;
+ goto reswitch;
+ }
ruby_show_version();
verbose = 1;
case 'w':
@@ -728,7 +734,7 @@ load_file(fname, script)
FILE *fp = fopen(fname, "r");
if (fp == NULL) {
- rb_raise(rb_eLoadError, "No such file to load -- %s", fname);
+ rb_load_fail(fname);
}
fclose(fp);
@@ -983,6 +989,7 @@ ruby_set_argv(argc, argv)
if (origargv) dln_argv0 = origargv[0];
else dln_argv0 = argv[0];
#endif
+ rb_ary_clear(rb_argv);
for (i=0; i < argc; i++) {
rb_ary_push(rb_argv, rb_tainted_str_new2(argv[i]));
}
diff --git a/ruby.h b/ruby.h
index ca97ee2c42..0e9352c7e5 100644
--- a/ruby.h
+++ b/ruby.h
@@ -164,6 +164,7 @@ VALUE rb_uint2inum _((unsigned long));
#define T_MATCH 0x23
#define T_SYMBOL 0x24
+#define T_BLKTAG 0x3b
#define T_UNDEF 0x3c
#define T_VARMAP 0x3d
#define T_SCOPE 0x3e
@@ -541,12 +542,14 @@ EXTERN VALUE rb_eNameError;
EXTERN VALUE rb_eSyntaxError;
EXTERN VALUE rb_eLoadError;
-#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(RUBY_NO_INLINE)
-extern __inline__ VALUE rb_class_of _((VALUE));
-extern __inline__ int rb_type _((VALUE));
-extern __inline__ int rb_special_const_p _((VALUE));
+extern inline VALUE rb_class_of _((VALUE));
+extern inline int rb_type _((VALUE));
+extern inline int rb_special_const_p _((VALUE));
-extern __inline__ VALUE
+#ifndef RUBY_NO_INLINE
+extern inline
+#endif
+VALUE
rb_class_of(VALUE obj)
{
if (FIXNUM_P(obj)) return rb_cFixnum;
@@ -558,7 +561,10 @@ rb_class_of(VALUE obj)
return RBASIC(obj)->klass;
}
-extern __inline__ int
+#ifndef RUBY_NO_INLINE
+extern inline
+#endif
+int
rb_type(VALUE obj)
{
if (FIXNUM_P(obj)) return T_FIXNUM;
@@ -570,19 +576,16 @@ rb_type(VALUE obj)
return BUILTIN_TYPE(obj);
}
-extern __inline__ int
+#ifndef RUBY_NO_INLINE
+extern inline
+#endif
+int
rb_special_const_p(VALUE obj)
{
if (SPECIAL_CONST_P(obj)) return Qtrue;
return Qfalse;
}
-#else
-VALUE rb_class_of _((VALUE));
-int rb_type _((VALUE));
-int rb_special_const_p _((VALUE));
-#endif
-
#include "intern.h"
#if defined(EXTLIB) && defined(USE_DLN_A_OUT)
@@ -590,6 +593,10 @@ int rb_special_const_p _((VALUE));
static char *dln_libs_to_be_linked[] = { EXTLIB, 0 };
#endif
+#ifndef rb_sys_stat
+#define rb_sys_stat stat
+#endif
+
#if defined(__cplusplus)
} /* extern "C" { */
#endif
diff --git a/signal.c b/signal.c
index 2bb8bada28..48849a6554 100644
--- a/signal.c
+++ b/signal.c
@@ -252,7 +252,7 @@ rb_f_kill(argc, argv)
else {
for (i=1; i<argc; i++) {
Check_Type(argv[i], T_FIXNUM);
- if (kill(FIX2UINT(argv[i]), sig) < 0)
+ if (kill(FIX2INT(argv[i]), sig) < 0)
rb_sys_fail(0);
}
}
@@ -386,6 +386,16 @@ sigsegv(sig)
}
#endif
+#ifdef SIGPIPE
+static RETSIGTYPE sigpipe _((int));
+static RETSIGTYPE
+sigpipe(sig)
+ int sig;
+{
+ /* do nothing */
+}
+#endif
+
void
rb_trap_exit()
{
@@ -546,7 +556,7 @@ trap(arg)
#endif
#ifdef SIGPIPE
case SIGPIPE:
- func = SIG_IGN;
+ func = sigpipe;
break;
#endif
}
@@ -659,7 +669,7 @@ Init_signal()
ruby_signal(SIGSEGV, sigsegv);
#endif
#ifdef SIGPIPE
- ruby_signal(SIGPIPE, SIG_IGN);
+ ruby_signal(SIGPIPE, sigpipe);
#endif
#endif /* MACOS_UNUSE_SIGNAL */
}
diff --git a/sprintf.c b/sprintf.c
index 756de87ed9..178f81f192 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -573,7 +573,7 @@ rb_f_sprintf(argc, argv)
break;
case 8:
c = '7'; break;
- case '2':
+ case 2:
c = '1'; break;
}
s = &buf[pos];
diff --git a/string.c b/string.c
index ddf50e2eed..9ea6942e31 100644
--- a/string.c
+++ b/string.c
@@ -339,7 +339,6 @@ rb_str_substr(str, beg, len)
if (len < 0) return Qnil;
if (beg > RSTRING(str)->len) return Qnil;
- if (beg == RSTRING(str)->len && len > 0) return Qnil;
if (beg < 0) {
beg += RSTRING(str)->len;
if (beg < 0) return Qnil;
@@ -367,7 +366,6 @@ str_independent(str)
rb_raise(rb_eSecurityError, "Insecure: can't modify string");
if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return 1;
if (TYPE(RSTRING(str)->orig) != T_STRING) rb_bug("non string str->orig");
- RSTRING(str)->orig = 0;
return 0;
}
@@ -384,6 +382,7 @@ rb_str_modify(str)
}
ptr[RSTRING(str)->len] = 0;
RSTRING(str)->ptr = ptr;
+ RSTRING(str)->orig = 0;
}
VALUE
@@ -1278,6 +1277,9 @@ str_gsub(argc, argv, str, bang)
if (str_independent(str)) {
free(RSTRING(str)->ptr);
}
+ else {
+ RSTRING(str)->orig = 0;
+ }
}
else {
NEWOBJ(dup, struct RString);
@@ -1316,15 +1318,19 @@ static VALUE
rb_str_replace_m(str, str2)
VALUE str, str2;
{
+ if (str == str2) return str;
if (TYPE(str2) != T_STRING) str2 = rb_str_to_str(str2);
- rb_str_modify(str);
- if (RSTRING(str2)->orig && FL_TEST(str2, STR_NO_ORIG)) {
+ if (RSTRING(str2)->orig && !FL_TEST(str2, STR_NO_ORIG)) {
+ if (str_independent(str)) {
+ free(RSTRING(str)->ptr);
+ }
RSTRING(str)->len = RSTRING(str2)->len;
RSTRING(str)->ptr = RSTRING(str2)->ptr;
RSTRING(str)->orig = RSTRING(str2)->orig;
}
else {
+ rb_str_modify(str);
rb_str_resize(str, RSTRING(str2)->len);
memcpy(RSTRING(str)->ptr, RSTRING(str2)->ptr, RSTRING(str2)->len);
}
@@ -1395,6 +1401,7 @@ rb_str_reverse_bang(str)
char *s, *e;
char c;
+ rb_str_modify(str);
s = RSTRING(str)->ptr;
e = s + RSTRING(str)->len - 1;
while (s < e) {
@@ -1490,8 +1497,8 @@ rb_str_inspect(str)
char c = *p++;
if (ismbchar(c) && p < pend) {
int len = mbclen(c);
- rb_str_cat(result, p, len);
- p += len;
+ rb_str_cat(result, p - 1, len);
+ p += len - 1;
}
else if (c == '"'|| c == '\\') {
s[0] = '\\'; s[1] = c;
@@ -1644,7 +1651,7 @@ rb_str_upcase_bang(str)
if (ismbchar(*s)) {
s+=mbclen(*s) - 1;
}
- else if (islower(*s)) {
+ else if (ISLOWER(*s)) {
*s = toupper(*s);
modify = 1;
}
@@ -1784,7 +1791,10 @@ trnext(t)
if (!t->gen) {
if (t->p == t->pend) return -1;
t->now = *(USTR)t->p++;
- if (t->p < t->pend - 1 && *t->p == '-') {
+ if (t->p < t->pend - 1 && *t->p == '\\') {
+ t->p++;
+ }
+ else if (t->p < t->pend - 1 && *t->p == '-') {
t->p++;
if (t->p < t->pend) {
if (t->now > *(USTR)t->p) {
@@ -1965,6 +1975,9 @@ rb_str_delete_bang(argc, argv, str)
int init = 1;
int i;
+ if (argc < 1) {
+ rb_raise(rb_eArgError, "wrong # of arguments");
+ }
for (i=0; i<argc; i++) {
VALUE s = argv[i];
diff --git a/util.c b/util.c
index 9cbfb5fc74..25c00ae2d6 100644
--- a/util.c
+++ b/util.c
@@ -19,42 +19,6 @@
#define RUBY_NO_INLINE
#include "ruby.h"
-VALUE
-rb_class_of(obj)
- VALUE obj;
-{
- if (FIXNUM_P(obj)) return rb_cFixnum;
- if (obj == Qnil) return rb_cNilClass;
- if (obj == Qfalse) return rb_cFalseClass;
- if (obj == Qtrue) return rb_cTrueClass;
- if (SYMBOL_P(obj)) return rb_cSymbol;
-
- return RBASIC(obj)->klass;
-}
-
-int
-rb_type(obj)
- VALUE obj;
-{
- if (FIXNUM_P(obj)) return T_FIXNUM;
- if (obj == Qnil) return T_NIL;
- if (obj == Qfalse) return T_FALSE;
- if (obj == Qtrue) return T_TRUE;
- if (obj == Qundef) return T_UNDEF;
- if (SYMBOL_P(obj)) return T_SYMBOL;
-
- return BUILTIN_TYPE(obj);
-}
-
-int
-rb_special_const_p(obj)
- VALUE obj;
-{
- if (SPECIAL_CONST_P(obj)) return Qtrue;
-
- return Qfalse;
-}
-
#include "util.h"
#ifndef HAVE_STRING_H
char *strchr _((char*,char));
diff --git a/version.h b/version.h
index 71d484b8fd..293e1396c7 100644
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
-#define RUBY_VERSION "1.6.2"
-#define RUBY_RELEASE_DATE "2000-12-25"
-#define RUBY_VERSION_CODE 162
-#define RUBY_RELEASE_CODE 20001225
+#define RUBY_VERSION "1.6.3"
+#define RUBY_RELEASE_DATE "2001-03-20"
+#define RUBY_VERSION_CODE 163
+#define RUBY_RELEASE_CODE 20010320
diff --git a/win32/config.h.in b/win32/config.h.in
index a7e28120e6..f1ba8da5c3 100644
--- a/win32/config.h.in
+++ b/win32/config.h.in
@@ -1,6 +1,7 @@
#define HAVE_PROTOTYPES 1
#define HAVE_STDARG_PROTOTYPES 1
/* #define HAVE_ATTR_NORETURN 1 */
+#define inline __inline
/* #define HAVE_DIRENT_H 1 */
/* #define HAVE_UNISTD_H 1 */
#define HAVE_STDLIB_H 1
diff --git a/win32/config.status.in b/win32/config.status.in
index 461877b886..01af07f71a 100644
--- a/win32/config.status.in
+++ b/win32/config.status.in
@@ -3,8 +3,6 @@ s%@CFLAGS@%-nologo -DNT=1 -Zi -MD -O2b2x -G5%g
s%@CPPFLAGS@%%g
s%@CXXFLAGS@%%g
s%@FFLAGS@%%g
-s%@DEFS@%
- -DUSE_THREAD -DSIZEOF_INT=4 -DSIZEOF_SHORT=2 -DSIZEOF_LONG=4 -DSIZEOF_VOIDP=4 -DSIZEOF_FLOAT=4 -DSIZEOF_DOUBLE=8 -DHAVE_PROTOTYPES=1 -DHAVE_STDARG_PROTOTYPES=1 -DHAVE_STDLIB_H=1 -DHAVE_LIMITS_H=1 -DHAVE_FCNTL_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_ST_RDEV=1 -DGETGROUPS_T=int -DRETSIGTYPE=void -DHAVE_ALLOCA=1 -DHAVE_FMOD=1 -DHAVE_WAITPID=1 -DHAVE_GETCWD=1 -DHAVE_CHSIZE=1 -DHAVE_GETGROUPS=1 -DHAVE_GETLOGIN=1 -DRSHIFT=\(x,y\)\ \(\(x\)\>\>y\) -DFILE_COUNT=_cnt -DDLEXT=\".so\" -DDLEXT2=\".dll\" -DRUBY_PLATFORM=\"i586-mswin32\" %g
s%@LDFLAGS@%-nologo%g
s%@LIBS@%user32.lib advapi32.lib wsock32.lib%g
s%@exec_prefix@%${prefix}%g
diff --git a/win32/win32.c b/win32/win32.c
index bd07bb644e..14b4aeb9f0 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -29,6 +29,7 @@
#ifndef index
#define index(x, y) strchr((x), (y))
#endif
+#define isdirsep(x) ((x) == '/' || (x) == '\\')
#ifndef bool
#define bool int
@@ -357,7 +358,7 @@ isInternalCmd(char *cmd)
int vecc = NtMakeCmdVector(cmd, &vec, FALSE);
for( i = 0; szInternalCmds[i] ; i++){
- if(!strcmp(szInternalCmds[i], vec[0])){
+ if(!strcasecmp(szInternalCmds[i], vec[0])){
fRet = 1;
break;
}
@@ -777,10 +778,10 @@ char *cmd;
strcpy(cmd2, cmd);
a = argv;
for (s = cmd2; *s;) {
- while (*s && isspace(*s)) s++;
+ while (*s && ISSPACE(*s)) s++;
if (*s)
*(a++) = s;
- while (*s && !isspace(*s)) s++;
+ while (*s && !ISSPACE(*s)) s++;
if (*s)
*s++ = '\0';
}
@@ -1054,7 +1055,7 @@ NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
//
ptr = cmdline+(cmdlen - 1);
- while(ptr >= cmdline && isspace(*ptr))
+ while(ptr >= cmdline && ISSPACE(*ptr))
--ptr;
*++ptr = '\0';
@@ -1074,7 +1075,7 @@ NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd)
// zap any leading whitespace
//
- while(isspace(*ptr))
+ while(ISSPACE(*ptr))
ptr++;
base = ptr;
@@ -1311,7 +1312,7 @@ opendir(char *filename)
if ((stat (filename, &sbuf) < 0 ||
sbuf.st_mode & _S_IFDIR == 0) &&
- (!isalpha(filename[0]) || filename[1] != ':' || filename[2] != '\0' ||
+ (!ISALPHA(filename[0]) || filename[1] != ':' || filename[2] != '\0' ||
((1 << (filename[0] & 0x5f) - 'A') & GetLogicalDrives()) == 0)) {
return NULL;
}
@@ -2425,13 +2426,23 @@ waitpid (pid_t pid, int *stat_loc, int options)
int _cdecl
gettimeofday(struct timeval *tv, struct timezone *tz)
{
- struct timeb tb;
+ SYSTEMTIME st;
+ time_t t;
+ struct tm tm;
+
+ GetLocalTime(&st);
+ tm.tm_sec = st.wSecond;
+ tm.tm_min = st.wMinute;
+ tm.tm_hour = st.wHour;
+ tm.tm_mday = st.wDay;
+ tm.tm_mon = st.wMonth - 1;
+ tm.tm_year = st.wYear - 1900;
+ tm.tm_isdst = -1;
+ t = mktime(&tm);
+ tv->tv_sec = t;
+ tv->tv_usec = st.wMilliseconds * 1000;
- ftime(&tb);
- tv->tv_sec = tb.time;
- tv->tv_usec = tb.millitm * 1000;
-
- return 0;
+ return 0;
}
char *
@@ -2545,7 +2556,7 @@ myrename(const char *oldpath, const char *newpath)
newatts = GetFileAttributes(newpath);
if (oldatts == -1) {
- printf("file to move doesn't exist");
+ errno = GetLastError();
return -1;
}
@@ -2583,6 +2594,34 @@ myrename(const char *oldpath, const char *newpath)
return res;
}
+int
+win32_stat(const char *path, struct stat *st)
+{
+ const char *p;
+ char *buf1 = ALLOCA_N(char, strlen(path) + 1);
+ char *buf2 = ALLOCA_N(char, MAXPATHLEN);
+ char *s;
+ int len;
+
+ for (p = path, s = buf1; *p; p++, s++) {
+ if (*p == '/')
+ *s = '\\';
+ else
+ *s = *p;
+ }
+ *s = '\0';
+ len = strlen(buf1);
+ p = CharPrev(buf1, buf1 + len);
+ if (*p == '\\' || *p == ':')
+ strcat(buf1, ".");
+ else if (buf1[0] == '\\' && buf1[1] == '\\')
+ strcat(buf1, "\\.");
+ if (_fullpath(buf2, buf1, MAXPATHLEN))
+ return stat(buf2, st);
+ else
+ return -1;
+}
+
static long
filetime_to_clock(FILETIME *ft)
{
diff --git a/win32/win32.h b/win32/win32.h
index ebffc5c8ab..ffbe967703 100644
--- a/win32/win32.h
+++ b/win32/win32.h
@@ -162,6 +162,8 @@ extern "C++" {
#define pclose _pclose
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
+#undef rb_sys_stat
+#define rb_sys_stat win32_stat
/* these are defined in nt.c */
#ifdef __MINGW32__