mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Merge -r16241:16456 from ruby_1_8.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8_7@16458 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
32378c5abe
commit
8480bcc8d5
64 changed files with 5134 additions and 851 deletions
326
ChangeLog
326
ChangeLog
|
@ -1,3 +1,329 @@
|
||||||
|
Sun May 18 22:26:51 2008 GOTOU Yuuzou <gotoyuzo@notwork.org>
|
||||||
|
|
||||||
|
* lib/webrick/httpservlet/filehandler.rb: should normalize path
|
||||||
|
name in path_info to prevent script disclosure vulnerability on
|
||||||
|
DOSISH filesystems. (fix: CVE-2008-1891)
|
||||||
|
Note: NTFS/FAT filesystem should not be published by the platforms
|
||||||
|
other than Windows. Pathname interpretation (including short
|
||||||
|
filename) is less than perfect.
|
||||||
|
|
||||||
|
* lib/webrick/httpservlet/abstract.rb
|
||||||
|
(WEBrick::HTTPServlet::AbstracServlet#redirect_to_directory_uri):
|
||||||
|
should escape the value of Location: header.
|
||||||
|
|
||||||
|
* lib/webrick/httpservlet/cgi_runner.rb: accept interpreter
|
||||||
|
command line arguments.
|
||||||
|
|
||||||
|
Sat May 17 23:53:57 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* file.c (file_expand_path): fix for short file name on Cygwin.
|
||||||
|
|
||||||
|
Sat May 17 11:29:11 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* file.c (rb_file_s_extname): first dot is not an extension name.
|
||||||
|
|
||||||
|
Sat May 17 10:18:44 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* re.c (rb_reg_search): need to free allocated buffer in re_register.
|
||||||
|
|
||||||
|
Fri May 16 17:01:44 2008 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
|
* win32/Makefile.sub (test-rubyspec): added.
|
||||||
|
|
||||||
|
Fri May 16 16:22:40 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
|
* ext/tk/tcltklib.c: sometimes freeze when receive Interrupt signal.
|
||||||
|
|
||||||
|
Fri May 16 14:54:56 2008 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* Makefile.in (update-rubyspec): move rubyspec to srcdir.
|
||||||
|
(test-rubyspec): ditto.
|
||||||
|
|
||||||
|
Fri May 16 14:25:22 2008 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* Makefile.in (test-rubyspec): use RUNRUBY. suggested by nobu.
|
||||||
|
|
||||||
|
Fri May 16 13:01:43 2008 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* Makefile.in (update-rubyspec): new target to download rubyspec.
|
||||||
|
(test-rubyspec): new target to run rubyspec. this doesn't work
|
||||||
|
before install.
|
||||||
|
|
||||||
|
Fri May 16 08:15:52 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
|
* ext/tk/lib/tk.rb: fix memory (object) leak bug.
|
||||||
|
|
||||||
|
* ext/tk/sample/demos-jp/aniwave.rb, ext/tk/sample/demos-en/aniwave.rb:
|
||||||
|
bug fix.
|
||||||
|
|
||||||
|
Thu May 15 17:00:22 2008 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
|
* string.c (Init_String): Define #bytesize as an alias for #size
|
||||||
|
for compatibility with 1.9.
|
||||||
|
|
||||||
|
Thu May 15 15:33:59 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* file.c (file_expand_path): support for alternative data stream
|
||||||
|
and ignored trailing garbages of NTFS.
|
||||||
|
|
||||||
|
* file.c (rb_file_s_basename): ditto.
|
||||||
|
|
||||||
|
* file.c (rb_file_s_extname): ditto.
|
||||||
|
|
||||||
|
Wed May 14 19:24:59 2008 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
|
* array.c (rb_ary_count): Override Enumerable#count for better
|
||||||
|
performance.
|
||||||
|
(rb_ary_nitems): Undo the backport. Use #count {} instead.
|
||||||
|
|
||||||
|
* enumerator.c (enumerator_iter_i): Remove an unused function.
|
||||||
|
(enumerator_with_index, enumerator_each): Remove unused
|
||||||
|
variables.
|
||||||
|
|
||||||
|
Wed May 14 17:15:11 2008 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/tk/tkutil/extronf.rb: check stdndup() because it's not standard
|
||||||
|
function of C.
|
||||||
|
|
||||||
|
* ext/tk/tkutil/tkutil.c (cbsubst_table_setup): use malloc() and
|
||||||
|
strncpy() instead of strndup() if not available.
|
||||||
|
|
||||||
|
Wed May 14 09:52:02 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
|
* ext/tk/tkutil/tkutil.c: improve handling callback-subst-keys.
|
||||||
|
Now, support longnam-keys (e.g. '%CTT' on tkdnd-2.0; however, still
|
||||||
|
not support tkdnd-2.0 on tkextlib), and symbols of parameters (e.g.
|
||||||
|
:widget=>'%W', :keycode=>'%k', '%x'=>:x, '%X'=>:root_x, and so on;
|
||||||
|
those are attributes of event object). It means that Ruby/Tk accepts
|
||||||
|
not only "widget.bind(ev, '%W', '%k', ...){|w, k, ...| ... }", but
|
||||||
|
also "widget.bind(ev, :widget, :keycode, ...){|w, k, ...| ... }".
|
||||||
|
It is potentially incompatible, when user passes symbols to the
|
||||||
|
arguments of the callback block (the block receives the symbols as
|
||||||
|
strings). I think that is very rare case (probably, used by Ruby/Tk
|
||||||
|
experts only). When causes such trouble, please give strings instead
|
||||||
|
of such symbol parameters (e.g. call Symbol#to_s method).
|
||||||
|
|
||||||
|
* ext/tk/lib/tk/event.rb, ext/tk/lib/tk/validation.rb,
|
||||||
|
ext/tk/lib/tkextlib/blt/treeview.rb,
|
||||||
|
ext/tk/lib/tkextlib/winico/winico.rb: ditto.
|
||||||
|
|
||||||
|
* ext/tk/tkutil/tkutil.c: strings are available on subst_tables on
|
||||||
|
TkUtil::CallbackSubst class (it is useful on Ruby 1.9).
|
||||||
|
|
||||||
|
* ext/tk/lib/tk/spinbox.rb, ext/tk/lib/tkextlib/iwidgets/hierarchy.rb,
|
||||||
|
ext/tk/lib/tkextlib/iwidgets/spinner.rb,
|
||||||
|
ext/tk/lib/tkextlib/iwidgets/entryfield.rb,
|
||||||
|
ext/tk/lib/tkextlib/iwidgets/calendar.rb,
|
||||||
|
ext/tk/lib/tkextlib/blt/dragdrop.rb,
|
||||||
|
ext/tk/lib/tkextlib/tkDND/tkdnd.rb,
|
||||||
|
ext/tk/lib/tkextlib/treectrl/tktreectrl.rb,
|
||||||
|
ext/tk/lib/tkextlib/tktable/tktable.rb: disable code piece became
|
||||||
|
unnecessary by reason of the changes of ext/tk/tkutil/tkutil.c.
|
||||||
|
|
||||||
|
Tue May 13 15:10:50 2008 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
|
* enumerator.c: Update rdoc.
|
||||||
|
(enumerator_initialize): Discourage the use.
|
||||||
|
(enum_each_slice, enum_each_cons, enumerator_each)
|
||||||
|
(enumerator_with_index): Add a note about a call without a block.
|
||||||
|
|
||||||
|
* NEWS: Intentionally omit enum_slice and enum_cons, which are
|
||||||
|
removed in 1.9.
|
||||||
|
|
||||||
|
Tue May 13 07:56:36 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* string.c (rb_str_cat): fixed buffer overrun reported by
|
||||||
|
Christopher Thompson <cthompson at nexopia.com> in [ruby-core:16746]
|
||||||
|
|
||||||
|
Mon May 12 13:57:19 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (is_defined): add NODE_OP_ASGN_{OR,AND}. "defined?(a||=1)"
|
||||||
|
should not operate assignment. [ruby-dev:34645]
|
||||||
|
|
||||||
|
Mon May 12 12:59:23 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
|
* ext/tk/lib/tk/wm.rb: Wm#overrideredirect overwrites arguemnt to
|
||||||
|
an invalid value.
|
||||||
|
|
||||||
|
* ext/tk/sample/ttk_wrapper.rb: support "if __FILE__ == $0" idiom.
|
||||||
|
|
||||||
|
Mon May 12 12:36:55 2008 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
|
* win32/win32.c (rb_w32_select): backport from trunk.
|
||||||
|
[ruby-talk:300743]
|
||||||
|
|
||||||
|
Mon May 12 12:33:21 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* common.mk (RUBYLIB, RUBYOPT): clear.
|
||||||
|
|
||||||
|
Mon May 12 10:41:10 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* lib/delegate.rb (SimpleDelegator::dup): removed needless argument.
|
||||||
|
[ruby-list:44910]
|
||||||
|
|
||||||
|
* lib/delegate.rb (clone, dup): keep relationship with the target
|
||||||
|
object.
|
||||||
|
|
||||||
|
Sun May 11 23:19:39 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* enum.c (all_iter_i, any_iter_i): reduced duplicated code.
|
||||||
|
|
||||||
|
Sun May 11 17:57:36 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* configure.in (MINIRUBY): should not include extension library path.
|
||||||
|
|
||||||
|
Sun May 11 10:36:10 2008 Kazuhiro NISHIYAMA <zn@mbf.nifty.com>
|
||||||
|
|
||||||
|
* eval.c (method_name, method_owner): New methods; backported
|
||||||
|
from 1.9. (UnboundMethod#name, UnboundMethod#owner)
|
||||||
|
|
||||||
|
Sun May 11 02:48:13 2008 <nagai@orca16.orcabay.ddo.jp>
|
||||||
|
|
||||||
|
* ext/tk/lib/tk/pack.rb, ext/tk/lib/tk/grid.rb: fail to do pack/grid
|
||||||
|
without options.
|
||||||
|
|
||||||
|
* ext/tk/lib/tk.rb: add TkWindow#grid_anchor, grid_column, grid_row.
|
||||||
|
|
||||||
|
Sat May 10 18:19:16 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* string.c (rb_str_each_line): RDoc updated. [ruby-dev:34586]
|
||||||
|
|
||||||
|
Sat May 10 13:17:56 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
|
* ext/tk/lib/tk/pack.rb, ext/tk/lib/tk/grid.rb: increase supported
|
||||||
|
parameter patterns of configure method.
|
||||||
|
|
||||||
|
Sat May 10 09:16:13 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* util.c (ruby_strtod): backported from 1.9. a patch from Satoshi
|
||||||
|
Nakagawa <psychs at limechat.net> in [ruby-dev:34625].
|
||||||
|
fixed: [ruby-dev:34623]
|
||||||
|
|
||||||
|
Fri May 9 23:33:25 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
|
* ext/tk/lib/tk/wm.rb: methods of Tk::Wm_for_General module cannot
|
||||||
|
pass the given block to methods of Tk::Wm module.
|
||||||
|
|
||||||
|
* ext/tk/lib/tk/grid.rb: lack of module-method definitions.
|
||||||
|
|
||||||
|
* ext/tk/lib/tkextlib/tile.rb: lack of autoload definitions.
|
||||||
|
|
||||||
|
* ext/tk/lib/tkextlib/tile/tnotebook.rb: cannot use kanji (not UTF-8)
|
||||||
|
characters for headings.
|
||||||
|
|
||||||
|
* ext/tk/tcltklib.c: maybe a little more stable about @encoding value
|
||||||
|
of TclTkIp object.
|
||||||
|
|
||||||
|
Wed May 7 08:46:44 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* struct.c (rb_struct_s_def): to_str should be called only once.
|
||||||
|
[ruby-core:16647]
|
||||||
|
|
||||||
|
Wed May 7 00:54:25 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/zlib/zlib.c (gzreader_gets): may cause infinite loop.
|
||||||
|
a patch from Kouya <kouyataifu4 at gmail.com> in
|
||||||
|
[ruby-reference-manual:762].
|
||||||
|
|
||||||
|
Sun May 4 09:35:51 2008 Masatoshi SEKI <m_seki@mva.biglobe.ne.jp>
|
||||||
|
|
||||||
|
* sample/erb/erb4html.rb (ERB4Html) : add example of ERB#set_eoutvar.
|
||||||
|
ERB4Html is an auto-quote ERB.
|
||||||
|
|
||||||
|
Sat May 3 22:52:48 2008 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
|
* ext/tk/lib/tkextlib/tile.rb, ext/tk/lib/tkextlib/tile/style.rb,
|
||||||
|
ext/tk/sample/ttk_wrapper.rb: improve treating and control themes.
|
||||||
|
add Tk::Tile.themes and Tk::Tile.set_theme(theme).
|
||||||
|
|
||||||
|
Fri May 2 14:52:33 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* misc/ruby-mode.el: move fontifying code from hook. a patch from
|
||||||
|
Phil Hagelberg <phil at hagelb.org> in [ruby-core:16636].
|
||||||
|
|
||||||
|
Fri May 2 13:47:51 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* re.c (match_select): restore previous behavior of MatchData#select.
|
||||||
|
RDoc updated as well, mentioning the plan to remove this method
|
||||||
|
in the future. [ruby-dev:34556]
|
||||||
|
|
||||||
|
Fri May 2 13:04:04 2008 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/dbm/dbm.c (Init_dbm): defines DBM::VERSION even when
|
||||||
|
DB_VERSION_STRING is not available. [ruby-dev:34569]
|
||||||
|
|
||||||
|
Thu May 1 23:57:06 2008 James Edward Gray II <jeg2@ruby-lang.org>
|
||||||
|
|
||||||
|
Merged 16257 from trunk.
|
||||||
|
|
||||||
|
* lib/net/telnet.rb: This patch from Brian Candler adds a FailEOF mode which
|
||||||
|
can be activated to have net/telnet raise EOFError exceptions when the
|
||||||
|
remote connection is closed. The default behavior remains unchanged though.
|
||||||
|
|
||||||
|
Thu May 1 23:43:21 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* range.c (range_step): check if step can be converted to an integer.
|
||||||
|
[ruby-dev:34558]
|
||||||
|
|
||||||
|
* range.c (range_step): allow float step bigger than zero but less
|
||||||
|
than one. [ruby-dev:34557]
|
||||||
|
|
||||||
|
Wed Apr 30 20:22:40 2008 James Edward Gray II <jeg2@ruby-lang.org>
|
||||||
|
|
||||||
|
Merged 16241 from trunk.
|
||||||
|
|
||||||
|
* lib/net/telnet.rb: Fixing a bug where line endings would not be properly
|
||||||
|
escaped when the two character ending was broken up into separate TCP
|
||||||
|
packets. Issue reported and patched by Brian Candler.
|
||||||
|
|
||||||
|
Thu May 1 23:57:06 2008 James Edward Gray II <jeg2@ruby-lang.org>
|
||||||
|
|
||||||
|
Merged 16257 from trunk.
|
||||||
|
|
||||||
|
* lib/net/telnet.rb: This patch from Brian Candler adds a FailEOF mode which
|
||||||
|
can be activated to have net/telnet raise EOFError exceptions when the
|
||||||
|
remote connection is closed. The default behavior remains unchanged though.
|
||||||
|
|
||||||
|
Thu May 1 23:43:21 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* range.c (range_step): check if step can be converted to an integer.
|
||||||
|
[ruby-dev:34558]
|
||||||
|
|
||||||
|
* range.c (range_step): allow float step bigger than zero but less
|
||||||
|
than one. [ruby-dev:34557]
|
||||||
|
|
||||||
|
Wed Apr 30 20:22:40 2008 James Edward Gray II <jeg2@ruby-lang.org>
|
||||||
|
|
||||||
|
Merged 16241 from trunk.
|
||||||
|
|
||||||
|
* lib/net/telnet.rb: Fixing a bug where line endings would not be properly
|
||||||
|
escaped when the two character ending was broken up into separate TCP
|
||||||
|
packets. Issue reported and patched by Brian Candler.
|
||||||
|
|
||||||
|
Thu May 1 23:57:06 2008 James Edward Gray II <jeg2@ruby-lang.org>
|
||||||
|
|
||||||
|
Merged 16257 from trunk.
|
||||||
|
|
||||||
|
* lib/net/telnet.rb: This patch from Brian Candler adds a FailEOF mode which
|
||||||
|
can be activated to have net/telnet raise EOFError exceptions when the
|
||||||
|
remote connection is closed. The default behavior remains unchanged though.
|
||||||
|
|
||||||
|
Thu May 1 23:43:21 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* range.c (range_step): check if step can be converted to an integer.
|
||||||
|
[ruby-dev:34558]
|
||||||
|
|
||||||
|
* range.c (range_step): allow float step bigger than zero but less
|
||||||
|
than one. [ruby-dev:34557]
|
||||||
|
|
||||||
|
Wed Apr 30 20:22:40 2008 James Edward Gray II <jeg2@ruby-lang.org>
|
||||||
|
|
||||||
|
Merged 16241 from trunk.
|
||||||
|
|
||||||
|
* lib/net/telnet.rb: Fixing a bug where line endings would not be properly
|
||||||
|
escaped when the two character ending was broken up into separate TCP
|
||||||
|
packets. Issue reported and patched by Brian Candler.
|
||||||
|
|
||||||
Wed Apr 30 17:47:21 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Wed Apr 30 17:47:21 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* re.c (rb_reg_search): use local variable. a patch from wanabe
|
* re.c (rb_reg_search): use local variable. a patch from wanabe
|
||||||
|
|
19
Makefile.in
19
Makefile.in
|
@ -181,3 +181,22 @@ distclean-local::
|
||||||
|
|
||||||
ext/extinit.$(OBJEXT): ext/extinit.c $(SETUP)
|
ext/extinit.$(OBJEXT): ext/extinit.c $(SETUP)
|
||||||
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ -c ext/extinit.c
|
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ -c ext/extinit.c
|
||||||
|
|
||||||
|
MSPEC_GIT_URL=git://github.com/brixen/mspec.git
|
||||||
|
RUBYSPEC_GIT_URL=git://github.com/brixen/rubyspec.git
|
||||||
|
|
||||||
|
update-rubyspec:
|
||||||
|
if [ -d $(srcdir)/rubyspec ]; then \
|
||||||
|
cd $(srcdir)/rubyspec/mspec; \
|
||||||
|
git pull; \
|
||||||
|
cd ../spec/rubyspec; \
|
||||||
|
git pull; \
|
||||||
|
else \
|
||||||
|
git clone $(MSPEC_GIT_URL) $(srcdir)/rubyspec/mspec; \
|
||||||
|
git clone $(RUBYSPEC_GIT_URL) $(srcdir)/rubyspec/spec/rubyspec; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
test-rubyspec:
|
||||||
|
@if [ ! -d $(srcdir)/rubyspec ]; then echo No rubyspec here. make update-rubyspec first.; exit 1; fi
|
||||||
|
$(RUNRUBY) $(srcdir)/rubyspec/mspec/bin/mspec -r$(srcdir)/ext/purelib.rb $(srcdir)/rubyspec/spec/rubyspec/$(MAJOR).$(MINOR)
|
||||||
|
|
||||||
|
|
12
NEWS
12
NEWS
|
@ -17,10 +17,6 @@ with all sufficient information, see the ChangeLog file.
|
||||||
|
|
||||||
* builtin classes
|
* builtin classes
|
||||||
|
|
||||||
* Array#nitems now takes a block optionally, which is used to
|
|
||||||
determine if each element should be counted instead of checking if
|
|
||||||
the element is non-nil.
|
|
||||||
|
|
||||||
* Array#flatten
|
* Array#flatten
|
||||||
* Array#flatten!
|
* Array#flatten!
|
||||||
|
|
||||||
|
@ -87,9 +83,7 @@ with all sufficient information, see the ChangeLog file.
|
||||||
New class for various enumeration defined by the enumerator library.
|
New class for various enumeration defined by the enumerator library.
|
||||||
|
|
||||||
* Enumerable#each_slice
|
* Enumerable#each_slice
|
||||||
* Enumerable#enum_slice
|
|
||||||
* Enumerable#each_cons
|
* Enumerable#each_cons
|
||||||
* Enumerable#enum_cons
|
|
||||||
* Object#to_enum
|
* Object#to_enum
|
||||||
* Object#enum_for
|
* Object#enum_for
|
||||||
|
|
||||||
|
@ -187,6 +181,8 @@ with all sufficient information, see the ChangeLog file.
|
||||||
* Method#receiver
|
* Method#receiver
|
||||||
* Method#name
|
* Method#name
|
||||||
* Method#owner
|
* Method#owner
|
||||||
|
* UnboundMethod#name
|
||||||
|
* UnboundMethod#owner
|
||||||
|
|
||||||
New methods.
|
New methods.
|
||||||
|
|
||||||
|
@ -209,6 +205,10 @@ with all sufficient information, see the ChangeLog file.
|
||||||
|
|
||||||
* Regexp.union accepts an array of patterns.
|
* Regexp.union accepts an array of patterns.
|
||||||
|
|
||||||
|
* String#bytesize
|
||||||
|
|
||||||
|
New method, returning the size in bytes. (alias length and size)
|
||||||
|
|
||||||
* String#chars
|
* String#chars
|
||||||
* String#each_char
|
* String#each_char
|
||||||
* String#partition
|
* String#partition
|
||||||
|
|
55
array.c
55
array.c
|
@ -3032,16 +3032,12 @@ rb_ary_compact(ary)
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* array.nitems -> int
|
* array.nitems -> int
|
||||||
* array.nitems { |item| block } -> int
|
|
||||||
*
|
*
|
||||||
* Returns the number of non-<code>nil</code> elements in _self_.
|
* Returns the number of non-<code>nil</code> elements in _self_.
|
||||||
* If a block is given, the elements yielding a true value are
|
|
||||||
* counted.
|
|
||||||
*
|
*
|
||||||
* May be zero.
|
* May be zero.
|
||||||
*
|
*
|
||||||
* [ 1, nil, 3, nil, 5 ].nitems #=> 3
|
* [ 1, nil, 3, nil, 5 ].nitems #=> 3
|
||||||
* [5,6,7,8,9].nitems { |x| x % 2 != 0 } #=> 3
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -3049,24 +3045,54 @@ rb_ary_nitems(ary)
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
{
|
{
|
||||||
long n = 0;
|
long n = 0;
|
||||||
|
VALUE *p, *pend;
|
||||||
|
|
||||||
if (rb_block_given_p()) {
|
for (p = RARRAY(ary)->ptr, pend = p + RARRAY(ary)->len; p < pend; p++) {
|
||||||
long i;
|
if (!NIL_P(*p)) n++;
|
||||||
|
}
|
||||||
|
return LONG2NUM(n);
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
/*
|
||||||
VALUE v = RARRAY(ary)->ptr[i];
|
* call-seq:
|
||||||
if (RTEST(rb_yield(v))) n++;
|
* array.count(obj) -> int
|
||||||
|
* array.count { |item| block } -> int
|
||||||
|
*
|
||||||
|
* Returns the number of elements which equals to <i>obj</i>.
|
||||||
|
* If a block is given, counts tthe number of elements yielding a true value.
|
||||||
|
*
|
||||||
|
* ary = [1, 2, 4, 2]
|
||||||
|
* ary.count(2) # => 2
|
||||||
|
* ary.count{|x|x%2==0} # => 3
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_ary_count(int argc, VALUE *argv, VALUE ary)
|
||||||
|
{
|
||||||
|
long n = 0;
|
||||||
|
|
||||||
|
if (argc == 0) {
|
||||||
|
VALUE *p, *pend;
|
||||||
|
|
||||||
|
RETURN_ENUMERATOR(ary, 0, 0);
|
||||||
|
|
||||||
|
for (p = RARRAY_PTR(ary), pend = p + RARRAY_LEN(ary); p < pend; p++) {
|
||||||
|
if (RTEST(rb_yield(*p))) n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE *p = RARRAY(ary)->ptr;
|
VALUE obj, *p, *pend;
|
||||||
VALUE *pend = p + RARRAY(ary)->len;
|
|
||||||
|
|
||||||
while (p < pend) {
|
rb_scan_args(argc, argv, "1", &obj);
|
||||||
if (!NIL_P(*p)) n++;
|
if (rb_block_given_p()) {
|
||||||
p++;
|
rb_warn("given block not used");
|
||||||
|
}
|
||||||
|
for (p = RARRAY_PTR(ary), pend = p + RARRAY_LEN(ary); p < pend; p++) {
|
||||||
|
if (rb_equal(*p, obj)) n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LONG2NUM(n);
|
return LONG2NUM(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3789,6 +3815,7 @@ Init_Array()
|
||||||
rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
|
rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1);
|
||||||
rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1);
|
rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1);
|
||||||
rb_define_method(rb_cArray, "nitems", rb_ary_nitems, 0);
|
rb_define_method(rb_cArray, "nitems", rb_ary_nitems, 0);
|
||||||
|
rb_define_method(rb_cArray, "count", rb_ary_count, -1);
|
||||||
rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 0);
|
rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 0);
|
||||||
rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 0);
|
rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 0);
|
||||||
rb_define_method(rb_cArray, "choice", rb_ary_choice, 0);
|
rb_define_method(rb_cArray, "choice", rb_ary_choice, 0);
|
||||||
|
|
|
@ -2,7 +2,8 @@ bin: $(PROGRAM) $(WPROGRAM)
|
||||||
lib: $(LIBRUBY)
|
lib: $(LIBRUBY)
|
||||||
dll: $(LIBRUBY_SO)
|
dll: $(LIBRUBY_SO)
|
||||||
|
|
||||||
RUBYOPT =
|
RUBYLIB = -
|
||||||
|
RUBYOPT = -
|
||||||
|
|
||||||
STATIC_RUBY = static-ruby
|
STATIC_RUBY = static-ruby
|
||||||
|
|
||||||
|
|
|
@ -1402,6 +1402,7 @@ if test x"$cross_compiling" = xyes; then
|
||||||
RUNRUBY='$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`'
|
RUNRUBY='$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`'
|
||||||
else
|
else
|
||||||
MINIRUBY='./miniruby$(EXEEXT) -I$(srcdir)/lib'
|
MINIRUBY='./miniruby$(EXEEXT) -I$(srcdir)/lib'
|
||||||
|
MINIRUBY="$MINIRUBY"' -I$(EXTOUT)/common -I./- -r$(srcdir)/ext/purelib.rb'
|
||||||
PREP='miniruby$(EXEEXT)'
|
PREP='miniruby$(EXEEXT)'
|
||||||
RUNRUBY='$(MINIRUBY) $(srcdir)/runruby.rb --extout=$(EXTOUT)'
|
RUNRUBY='$(MINIRUBY) $(srcdir)/runruby.rb --extout=$(EXTOUT)'
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -254,6 +254,14 @@ void rb_ia64_flushrs(void);
|
||||||
#define ENV_IGNORECASE
|
#define ENV_IGNORECASE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CASEFOLD_FILESYSTEM
|
||||||
|
# if defined DOSISH || defined __VMS
|
||||||
|
# define CASEFOLD_FILESYSTEM 1
|
||||||
|
# else
|
||||||
|
# define CASEFOLD_FILESYSTEM 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DLEXT_MAXLEN
|
#ifndef DLEXT_MAXLEN
|
||||||
#define DLEXT_MAXLEN 4
|
#define DLEXT_MAXLEN 4
|
||||||
#endif
|
#endif
|
||||||
|
|
40
enum.c
40
enum.c
|
@ -843,18 +843,6 @@ enum_sort_by(obj)
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
|
||||||
all_iter_i(i, memo)
|
|
||||||
VALUE i;
|
|
||||||
VALUE *memo;
|
|
||||||
{
|
|
||||||
if (!RTEST(rb_yield(i))) {
|
|
||||||
*memo = Qfalse;
|
|
||||||
rb_iter_break();
|
|
||||||
}
|
|
||||||
return Qnil;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
all_i(i, memo)
|
all_i(i, memo)
|
||||||
VALUE i;
|
VALUE i;
|
||||||
|
@ -867,6 +855,14 @@ all_i(i, memo)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
all_iter_i(i, memo)
|
||||||
|
VALUE i;
|
||||||
|
VALUE *memo;
|
||||||
|
{
|
||||||
|
return all_i(rb_yield(i), memo);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* enum.all? [{|obj| block } ] => true or false
|
* enum.all? [{|obj| block } ] => true or false
|
||||||
|
@ -894,18 +890,6 @@ enum_all(obj)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
|
||||||
any_iter_i(i, memo)
|
|
||||||
VALUE i;
|
|
||||||
VALUE *memo;
|
|
||||||
{
|
|
||||||
if (RTEST(rb_yield(i))) {
|
|
||||||
*memo = Qtrue;
|
|
||||||
rb_iter_break();
|
|
||||||
}
|
|
||||||
return Qnil;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
any_i(i, memo)
|
any_i(i, memo)
|
||||||
VALUE i;
|
VALUE i;
|
||||||
|
@ -918,6 +902,14 @@ any_i(i, memo)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
any_iter_i(i, memo)
|
||||||
|
VALUE i;
|
||||||
|
VALUE *memo;
|
||||||
|
{
|
||||||
|
return any_i(rb_yield(i), memo);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* enum.any? [{|obj| block } ] => true or false
|
* enum.any? [{|obj| block } ] => true or false
|
||||||
|
|
32
enumerator.c
32
enumerator.c
|
@ -72,16 +72,6 @@ enumerator_ptr(obj)
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE enumerator_iter_i _((VALUE, VALUE));
|
|
||||||
static VALUE
|
|
||||||
enumerator_iter_i(i, enum_obj)
|
|
||||||
VALUE i;
|
|
||||||
VALUE enum_obj;
|
|
||||||
{
|
|
||||||
struct enumerator *e = (struct enumerator *)enum_obj;
|
|
||||||
return rb_yield(proc_call(e->proc, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* obj.to_enum(method = :each, *args)
|
* obj.to_enum(method = :each, *args)
|
||||||
|
@ -138,8 +128,10 @@ each_slice_i(val, memo)
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* e.each_slice(n) {...}
|
* e.each_slice(n) {...}
|
||||||
|
* e.each_slice(n)
|
||||||
*
|
*
|
||||||
* Iterates the given block for each slice of <n> elements.
|
* Iterates the given block for each slice of <n> elements. If no
|
||||||
|
* block is given, returns an enumerator.
|
||||||
*
|
*
|
||||||
* e.g.:
|
* e.g.:
|
||||||
* (1..10).each_slice(3) {|a| p a}
|
* (1..10).each_slice(3) {|a| p a}
|
||||||
|
@ -192,9 +184,10 @@ each_cons_i(val, memo)
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* each_cons(n) {...}
|
* each_cons(n) {...}
|
||||||
|
* each_cons(n)
|
||||||
*
|
*
|
||||||
* Iterates the given block for each array of consecutive <n>
|
* Iterates the given block for each array of consecutive <n>
|
||||||
* elements.
|
* elements. If no block is given, returns an enumerator.a
|
||||||
*
|
*
|
||||||
* e.g.:
|
* e.g.:
|
||||||
* (1..10).each_cons(3) {|a| p a}
|
* (1..10).each_cons(3) {|a| p a}
|
||||||
|
@ -271,12 +264,8 @@ enumerator_init(enum_obj, obj, meth, argc, argv)
|
||||||
* used as an Enumerable object using the given object's given
|
* used as an Enumerable object using the given object's given
|
||||||
* method with the given arguments.
|
* method with the given arguments.
|
||||||
*
|
*
|
||||||
* e.g.:
|
* Use of this method is not discouraged. Use Kernel#enum_for()
|
||||||
* str = "xyz"
|
* instead.
|
||||||
*
|
|
||||||
* enum = Enumerable::Enumerator.new(str, :each_byte)
|
|
||||||
* a = enum.map {|b| '%02x' % b } #=> ["78", "79", "7a"]
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
enumerator_initialize(argc, argv, obj)
|
enumerator_initialize(argc, argv, obj)
|
||||||
|
@ -330,7 +319,7 @@ rb_enumeratorize(obj, meth, argc, argv)
|
||||||
* enum.each {...}
|
* enum.each {...}
|
||||||
*
|
*
|
||||||
* Iterates the given block using the object and the method specified
|
* Iterates the given block using the object and the method specified
|
||||||
* in the first place.
|
* in the first place. If no block is given, returns self.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -340,7 +329,6 @@ enumerator_each(obj)
|
||||||
struct enumerator *e;
|
struct enumerator *e;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
VALUE *argv = 0;
|
VALUE *argv = 0;
|
||||||
VALUE method;
|
|
||||||
|
|
||||||
if (!rb_block_given_p()) return obj;
|
if (!rb_block_given_p()) return obj;
|
||||||
e = enumerator_ptr(obj);
|
e = enumerator_ptr(obj);
|
||||||
|
@ -364,9 +352,10 @@ enumerator_with_index_i(val, memo)
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* e.with_index {|(*args), idx| ... }
|
* e.with_index {|(*args), idx| ... }
|
||||||
|
* e.with_index
|
||||||
*
|
*
|
||||||
* Iterates the given block for each elements with an index, which
|
* Iterates the given block for each elements with an index, which
|
||||||
* start from 0.
|
* start from 0. If no block is given, returns an enumerator.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -377,7 +366,6 @@ enumerator_with_index(obj)
|
||||||
VALUE memo = 0;
|
VALUE memo = 0;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
VALUE *argv = 0;
|
VALUE *argv = 0;
|
||||||
VALUE method;
|
|
||||||
|
|
||||||
RETURN_ENUMERATOR(obj, 0, 0);
|
RETURN_ENUMERATOR(obj, 0, 0);
|
||||||
if (e->args) {
|
if (e->args) {
|
||||||
|
|
4
eval.c
4
eval.c
|
@ -2440,6 +2440,8 @@ is_defined(self, node, buf)
|
||||||
case NODE_ATTRSET:
|
case NODE_ATTRSET:
|
||||||
case NODE_OP_ASGN1:
|
case NODE_OP_ASGN1:
|
||||||
case NODE_OP_ASGN2:
|
case NODE_OP_ASGN2:
|
||||||
|
case NODE_OP_ASGN_OR:
|
||||||
|
case NODE_OP_ASGN_AND:
|
||||||
case NODE_MASGN:
|
case NODE_MASGN:
|
||||||
case NODE_LASGN:
|
case NODE_LASGN:
|
||||||
case NODE_DASGN:
|
case NODE_DASGN:
|
||||||
|
@ -9917,6 +9919,8 @@ Init_Proc()
|
||||||
rb_define_method(rb_cUnboundMethod, "arity", method_arity, 0);
|
rb_define_method(rb_cUnboundMethod, "arity", method_arity, 0);
|
||||||
rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
|
rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
|
||||||
rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
|
rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
|
||||||
|
rb_define_method(rb_cUnboundMethod, "name", method_name, 0);
|
||||||
|
rb_define_method(rb_cUnboundMethod, "owner", method_owner, 0);
|
||||||
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
|
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
|
||||||
rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
|
rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -812,5 +812,7 @@ Init_dbm()
|
||||||
|
|
||||||
#ifdef DB_VERSION_STRING
|
#ifdef DB_VERSION_STRING
|
||||||
rb_define_const(rb_cDBM, "VERSION", rb_str_new2(DB_VERSION_STRING));
|
rb_define_const(rb_cDBM, "VERSION", rb_str_new2(DB_VERSION_STRING));
|
||||||
|
#else
|
||||||
|
rb_define_const(rb_cDBM, "VERSION", rb_str_new2("unknown"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
if nul = $:.index("-")
|
if nul = $:.find_index {|path| /\A(?:\.\/)*-\z/ =~ path}
|
||||||
$:[nul..-1] = ["."]
|
$:[nul..-1] = ["."]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2008-05-12 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
|
* ext/tk/lib/tkextlib/tkDND/shape.rb: wrong package name.
|
||||||
|
|
||||||
|
--------------< ... some changes ... >------------------
|
||||||
|
|
||||||
2007-05-26 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
2007-05-26 Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
|
||||||
|
|
||||||
* ext/tk/lib/tkextlib/tcllib/tablelist.rb: fix typo.
|
* ext/tk/lib/tkextlib/tcllib/tablelist.rb: fix typo.
|
||||||
|
|
|
@ -775,7 +775,7 @@ end
|
||||||
private :_curr_cmd_id, :_next_cmd_id
|
private :_curr_cmd_id, :_next_cmd_id
|
||||||
module_function :_curr_cmd_id, :_next_cmd_id
|
module_function :_curr_cmd_id, :_next_cmd_id
|
||||||
|
|
||||||
def TkComm.install_cmd(cmd)
|
def TkComm.install_cmd(cmd, local_cmdtbl=nil)
|
||||||
return '' if cmd == ''
|
return '' if cmd == ''
|
||||||
begin
|
begin
|
||||||
ns = TkCore::INTERP._invoke_without_enc('namespace', 'current')
|
ns = TkCore::INTERP._invoke_without_enc('namespace', 'current')
|
||||||
|
@ -794,6 +794,15 @@ end
|
||||||
@cmdtbl = [] unless defined? @cmdtbl
|
@cmdtbl = [] unless defined? @cmdtbl
|
||||||
@cmdtbl.taint unless @cmdtbl.tainted?
|
@cmdtbl.taint unless @cmdtbl.tainted?
|
||||||
@cmdtbl.push id
|
@cmdtbl.push id
|
||||||
|
|
||||||
|
if local_cmdtbl && local_cmdtbl.kind_of?(Array)
|
||||||
|
begin
|
||||||
|
local_cmdtbl << id
|
||||||
|
rescue Exception
|
||||||
|
# ignore
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
#return Kernel.format("rb_out %s", id);
|
#return Kernel.format("rb_out %s", id);
|
||||||
if ns
|
if ns
|
||||||
'rb_out' << TkCore::INTERP._ip_id_ << ' ' << ns << ' ' << id
|
'rb_out' << TkCore::INTERP._ip_id_ << ' ' << ns << ' ' << id
|
||||||
|
@ -801,19 +810,29 @@ end
|
||||||
'rb_out' << TkCore::INTERP._ip_id_ << ' ' << id
|
'rb_out' << TkCore::INTERP._ip_id_ << ' ' << id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
def TkComm.uninstall_cmd(id)
|
def TkComm.uninstall_cmd(id, local_cmdtbl=nil)
|
||||||
#id = $1 if /rb_out\S* (c(_\d+_)?\d+)/ =~ id
|
#id = $1 if /rb_out\S* (c(_\d+_)?\d+)/ =~ id
|
||||||
id = $4 if id =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/
|
id = $4 if id =~ /rb_out\S*(?:\s+(::\S*|[{](::.*)[}]|["](::.*)["]))? (c(_\d+_)?(\d+))/
|
||||||
|
|
||||||
|
if local_cmdtbl && local_cmdtbl.kind_of?(Array)
|
||||||
|
begin
|
||||||
|
local_cmdtbl.delete(id)
|
||||||
|
rescue Exception
|
||||||
|
# ignore
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@cmdtbl.delete(id)
|
||||||
|
|
||||||
#Tk_CMDTBL.delete(id)
|
#Tk_CMDTBL.delete(id)
|
||||||
TkCore::INTERP.tk_cmd_tbl.delete(id)
|
TkCore::INTERP.tk_cmd_tbl.delete(id)
|
||||||
end
|
end
|
||||||
# private :install_cmd, :uninstall_cmd
|
# private :install_cmd, :uninstall_cmd
|
||||||
# module_function :install_cmd, :uninstall_cmd
|
# module_function :install_cmd, :uninstall_cmd
|
||||||
def install_cmd(cmd)
|
def install_cmd(cmd)
|
||||||
TkComm.install_cmd(cmd)
|
TkComm.install_cmd(cmd, @cmdtbl)
|
||||||
end
|
end
|
||||||
def uninstall_cmd(id)
|
def uninstall_cmd(id)
|
||||||
TkComm.uninstall_cmd(id)
|
TkComm.uninstall_cmd(id, @cmdtbl)
|
||||||
end
|
end
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
@ -1447,7 +1466,9 @@ module TkCore
|
||||||
|
|
||||||
def after(ms, cmd=Proc.new)
|
def after(ms, cmd=Proc.new)
|
||||||
cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret})
|
cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret})
|
||||||
tk_call_without_enc("after",ms,cmdid) # return id
|
after_id = tk_call_without_enc("after",ms,cmdid)
|
||||||
|
after_id.instance_variable_set('@cmdid', cmdid)
|
||||||
|
after_id
|
||||||
end
|
end
|
||||||
=begin
|
=begin
|
||||||
def after(ms, cmd=Proc.new)
|
def after(ms, cmd=Proc.new)
|
||||||
|
@ -1477,7 +1498,9 @@ module TkCore
|
||||||
|
|
||||||
def after_idle(cmd=Proc.new)
|
def after_idle(cmd=Proc.new)
|
||||||
cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret})
|
cmdid = install_cmd(proc{ret = cmd.call;uninstall_cmd(cmdid); ret})
|
||||||
tk_call_without_enc('after','idle',cmdid)
|
after_id = tk_call_without_enc('after','idle',cmdid)
|
||||||
|
after_id.instance_variable_set('@cmdid', cmdid)
|
||||||
|
after_id
|
||||||
end
|
end
|
||||||
=begin
|
=begin
|
||||||
def after_idle(cmd=Proc.new)
|
def after_idle(cmd=Proc.new)
|
||||||
|
@ -1495,6 +1518,11 @@ module TkCore
|
||||||
|
|
||||||
def after_cancel(afterId)
|
def after_cancel(afterId)
|
||||||
tk_call_without_enc('after','cancel',afterId)
|
tk_call_without_enc('after','cancel',afterId)
|
||||||
|
if (cmdid = afterId.instance_variable_get('@cmdid'))
|
||||||
|
afterId.instance_variable_set('@cmdid', nil)
|
||||||
|
uninstall_cmd(cmdid)
|
||||||
|
end
|
||||||
|
afterId
|
||||||
end
|
end
|
||||||
|
|
||||||
def windowingsystem
|
def windowingsystem
|
||||||
|
@ -4947,6 +4975,15 @@ class TkWindow<TkObject
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def grid_anchor(anchor=None)
|
||||||
|
if anchor == None
|
||||||
|
TkGrid.anchor(self)
|
||||||
|
else
|
||||||
|
TkGrid.anchor(self, anchor)
|
||||||
|
self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def grid_forget
|
def grid_forget
|
||||||
#tk_call('grid', 'forget', epath)
|
#tk_call('grid', 'forget', epath)
|
||||||
TkGrid.forget(self)
|
TkGrid.forget(self)
|
||||||
|
@ -4978,12 +5015,14 @@ class TkWindow<TkObject
|
||||||
TkGrid.columnconfigure(self, index, keys)
|
TkGrid.columnconfigure(self, index, keys)
|
||||||
end
|
end
|
||||||
alias grid_columnconfigure grid_columnconfig
|
alias grid_columnconfigure grid_columnconfig
|
||||||
|
alias grid_column grid_columnconfig
|
||||||
|
|
||||||
def grid_rowconfig(index, keys)
|
def grid_rowconfig(index, keys)
|
||||||
#tk_call('grid', 'rowconfigure', epath, index, *hash_kv(keys))
|
#tk_call('grid', 'rowconfigure', epath, index, *hash_kv(keys))
|
||||||
TkGrid.rowconfigure(self, index, keys)
|
TkGrid.rowconfigure(self, index, keys)
|
||||||
end
|
end
|
||||||
alias grid_rowconfigure grid_rowconfig
|
alias grid_rowconfigure grid_rowconfig
|
||||||
|
alias grid_row grid_rowconfig
|
||||||
|
|
||||||
def grid_columnconfiginfo(index, slot=nil)
|
def grid_columnconfiginfo(index, slot=nil)
|
||||||
#if slot
|
#if slot
|
||||||
|
@ -5226,11 +5265,13 @@ class TkWindow<TkObject
|
||||||
end
|
end
|
||||||
|
|
||||||
children.each{|path, obj|
|
children.each{|path, obj|
|
||||||
|
obj.instance_eval{
|
||||||
if defined?(@cmdtbl)
|
if defined?(@cmdtbl)
|
||||||
for id in @cmdtbl
|
for id in @cmdtbl
|
||||||
uninstall_cmd id
|
uninstall_cmd id
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
}
|
||||||
TkCore::INTERP.tk_windows.delete(path)
|
TkCore::INTERP.tk_windows.delete(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5348,7 +5389,7 @@ TkWidget = TkWindow
|
||||||
#Tk.freeze
|
#Tk.freeze
|
||||||
|
|
||||||
module Tk
|
module Tk
|
||||||
RELEASE_DATE = '2008-04-18'.freeze
|
RELEASE_DATE = '2008-05-16'.freeze
|
||||||
|
|
||||||
autoload :AUTO_PATH, 'tk/variable'
|
autoload :AUTO_PATH, 'tk/variable'
|
||||||
autoload :TCL_PACKAGE_PATH, 'tk/variable'
|
autoload :TCL_PACKAGE_PATH, 'tk/variable'
|
||||||
|
|
|
@ -352,6 +352,14 @@ module TkEvent
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# [ <'%' subst-key str>, <proc type char>, <instance var (accessor) name>]
|
||||||
|
# the subst-key string will be converted to a bytecode (128+idx).
|
||||||
|
LONGKEY_TBL = [
|
||||||
|
# for example, for %CTT and %CST subst-key on tkdnd-2.0
|
||||||
|
# ['CTT', ?l, :drop_target_type],
|
||||||
|
# ['CST', ?l, :drop_source_type],
|
||||||
|
]
|
||||||
|
|
||||||
# [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>]
|
# [ <proc type char>, <proc/method to convert tcl-str to ruby-obj>]
|
||||||
PROC_TBL = [
|
PROC_TBL = [
|
||||||
[ ?n, TkComm.method(:num_or_str) ],
|
[ ?n, TkComm.method(:num_or_str) ],
|
||||||
|
@ -371,6 +379,7 @@ module TkEvent
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -386,6 +395,7 @@ module TkEvent
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
# setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys
|
# setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys
|
||||||
#
|
#
|
||||||
|
@ -399,7 +409,8 @@ module TkEvent
|
||||||
# ( which are Tcl strings ) to ruby objects based on the key string
|
# ( which are Tcl strings ) to ruby objects based on the key string
|
||||||
# that is generated by _get_subst_key() or _get_all_subst_keys().
|
# that is generated by _get_subst_key() or _get_all_subst_keys().
|
||||||
#
|
#
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL)
|
||||||
|
# _setup_subst_table(KEY_TBL, LONGKEY_TBL, PROC_TBL) # if use longname-keys
|
||||||
|
|
||||||
#
|
#
|
||||||
# NOTE: The order of parameters which passed to callback procedure is
|
# NOTE: The order of parameters which passed to callback procedure is
|
||||||
|
@ -447,6 +458,7 @@ module TkEvent
|
||||||
extra_args_tbl = klass._get_extra_args_tbl
|
extra_args_tbl = klass._get_extra_args_tbl
|
||||||
|
|
||||||
if args.compact.size > 0
|
if args.compact.size > 0
|
||||||
|
args.map!{|arg| klass._sym2subst(arg)}
|
||||||
args = args.join(' ')
|
args = args.join(' ')
|
||||||
keys = klass._get_subst_key(args)
|
keys = klass._get_subst_key(args)
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ module TkGrid
|
||||||
list(tk_call_without_enc('grid', 'bbox', *args))
|
list(tk_call_without_enc('grid', 'bbox', *args))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
def configure(win, *args)
|
def configure(win, *args)
|
||||||
if args[-1].kind_of?(Hash)
|
if args[-1].kind_of?(Hash)
|
||||||
opts = args.pop
|
opts = args.pop
|
||||||
|
@ -53,6 +54,48 @@ module TkGrid
|
||||||
tk_call_without_enc('grid', 'configure', *params)
|
tk_call_without_enc('grid', 'configure', *params)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
=end
|
||||||
|
def configure(*args)
|
||||||
|
if args[-1].kind_of?(Hash)
|
||||||
|
opts = args.pop
|
||||||
|
else
|
||||||
|
opts = {}
|
||||||
|
end
|
||||||
|
fail ArgumentError, 'no widget is given' if args.empty?
|
||||||
|
params = []
|
||||||
|
args.flatten(1).each{|win|
|
||||||
|
case win
|
||||||
|
when '-', ?- # RELATIVE PLACEMENT (increase columnspan)
|
||||||
|
params.push('-')
|
||||||
|
when /^-+$/ # RELATIVE PLACEMENT (increase columnspan)
|
||||||
|
params.concat(win.to_s.split(//))
|
||||||
|
when '^', ?^ # RELATIVE PLACEMENT (increase rowspan)
|
||||||
|
params.push('^')
|
||||||
|
when /^\^+$/ # RELATIVE PLACEMENT (increase rowspan)
|
||||||
|
params.concat(win.to_s.split(//))
|
||||||
|
when 'x', :x, ?x, nil, '' # RELATIVE PLACEMENT (empty column)
|
||||||
|
params.push('x')
|
||||||
|
when /^x+$/ # RELATIVE PLACEMENT (empty column)
|
||||||
|
params.concat(win.to_s.split(//))
|
||||||
|
else
|
||||||
|
params.push(_epath(win))
|
||||||
|
end
|
||||||
|
}
|
||||||
|
opts.each{|k, v|
|
||||||
|
params.push("-#{k}")
|
||||||
|
params.push(_epath(v)) # have to use 'epath' (hash_kv() is unavailable)
|
||||||
|
}
|
||||||
|
if Tk::TCL_MAJOR_VERSION < 8 ||
|
||||||
|
(Tk::TCL_MAJOR_VERSION == 8 && Tk::TCL_MINOR_VERSION <= 3)
|
||||||
|
if params[0] == '-' || params[0] == 'x' || params[0] == '^'
|
||||||
|
tk_call_without_enc('grid', *params)
|
||||||
|
else
|
||||||
|
tk_call_without_enc('grid', 'configure', *params)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
tk_call_without_enc('grid', 'configure', *params)
|
||||||
|
end
|
||||||
|
end
|
||||||
alias grid configure
|
alias grid configure
|
||||||
|
|
||||||
def columnconfigure(master, index, args)
|
def columnconfigure(master, index, args)
|
||||||
|
@ -61,12 +104,14 @@ module TkGrid
|
||||||
tk_call_without_enc("grid", 'columnconfigure',
|
tk_call_without_enc("grid", 'columnconfigure',
|
||||||
master, index, *hash_kv(args))
|
master, index, *hash_kv(args))
|
||||||
end
|
end
|
||||||
|
alias column columnconfigure
|
||||||
|
|
||||||
def rowconfigure(master, index, args)
|
def rowconfigure(master, index, args)
|
||||||
# master = master.epath if master.kind_of?(TkObject)
|
# master = master.epath if master.kind_of?(TkObject)
|
||||||
master = _epath(master)
|
master = _epath(master)
|
||||||
tk_call_without_enc("grid", 'rowconfigure', master, index, *hash_kv(args))
|
tk_call_without_enc("grid", 'rowconfigure', master, index, *hash_kv(args))
|
||||||
end
|
end
|
||||||
|
alias row rowconfigure
|
||||||
|
|
||||||
def columnconfiginfo(master, index, slot=nil)
|
def columnconfiginfo(master, index, slot=nil)
|
||||||
# master = master.epath if master.kind_of?(TkObject)
|
# master = master.epath if master.kind_of?(TkObject)
|
||||||
|
@ -189,10 +234,10 @@ module TkGrid
|
||||||
list(tk_call_without_enc('grid', 'slaves', master, *hash_kv(args)))
|
list(tk_call_without_enc('grid', 'slaves', master, *hash_kv(args)))
|
||||||
end
|
end
|
||||||
|
|
||||||
module_function :bbox, :forget, :propagate, :info
|
module_function :anchor, :bbox, :add, :forget, :propagate, :info
|
||||||
module_function :remove, :size, :slaves, :location
|
module_function :remove, :size, :slaves, :location
|
||||||
module_function :grid, :configure, :columnconfigure, :rowconfigure
|
module_function :grid, :configure, :columnconfigure, :rowconfigure
|
||||||
module_function :columnconfiginfo, :rowconfiginfo
|
module_function :column, :row, :columnconfiginfo, :rowconfiginfo
|
||||||
end
|
end
|
||||||
=begin
|
=begin
|
||||||
def TkGrid(win, *args)
|
def TkGrid(win, *args)
|
||||||
|
|
|
@ -9,6 +9,7 @@ module TkPack
|
||||||
|
|
||||||
TkCommandNames = ['pack'.freeze].freeze
|
TkCommandNames = ['pack'.freeze].freeze
|
||||||
|
|
||||||
|
=begin
|
||||||
def configure(win, *args)
|
def configure(win, *args)
|
||||||
if args[-1].kind_of?(Hash)
|
if args[-1].kind_of?(Hash)
|
||||||
opts = args.pop
|
opts = args.pop
|
||||||
|
@ -29,6 +30,22 @@ module TkPack
|
||||||
}
|
}
|
||||||
tk_call_without_enc("pack", 'configure', *params)
|
tk_call_without_enc("pack", 'configure', *params)
|
||||||
end
|
end
|
||||||
|
=end
|
||||||
|
def configure(*args)
|
||||||
|
if args[-1].kind_of?(Hash)
|
||||||
|
opts = args.pop
|
||||||
|
else
|
||||||
|
opts = {}
|
||||||
|
end
|
||||||
|
fail ArgumentError, 'no widget is given' if args.empty?
|
||||||
|
params = []
|
||||||
|
args.flatten(1).each{|win| params.push(_epath(win))}
|
||||||
|
opts.each{|k, v|
|
||||||
|
params.push("-#{k}")
|
||||||
|
params.push(_epath(v)) # have to use 'epath' (hash_kv() is unavailable)
|
||||||
|
}
|
||||||
|
tk_call_without_enc("pack", 'configure', *params)
|
||||||
|
end
|
||||||
alias pack configure
|
alias pack configure
|
||||||
|
|
||||||
def forget(*args)
|
def forget(*args)
|
||||||
|
|
|
@ -37,6 +37,7 @@ class Tk::Spinbox<Tk::Entry
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -52,6 +53,7 @@ class Tk::Spinbox<Tk::Entry
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,8 @@ module Tk
|
||||||
key2class.each{|key, klass|
|
key2class.each{|key, klass|
|
||||||
if keys[key].kind_of?(Array)
|
if keys[key].kind_of?(Array)
|
||||||
cmd, *args = keys[key]
|
cmd, *args = keys[key]
|
||||||
keys[key] = klass.new(cmd, args.join(' '))
|
#keys[key] = klass.new(cmd, args.join(' '))
|
||||||
|
keys[key] = klass.new(cmd, *args)
|
||||||
# elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method)
|
# elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method)
|
||||||
elsif TkComm._callback_entry?(keys[key])
|
elsif TkComm._callback_entry?(keys[key])
|
||||||
keys[key] = klass.new(keys[key])
|
keys[key] = klass.new(keys[key])
|
||||||
|
@ -151,7 +152,8 @@ module Tk
|
||||||
key2class.each{|key, klass|
|
key2class.each{|key, klass|
|
||||||
if keys[key].kind_of?(Array)
|
if keys[key].kind_of?(Array)
|
||||||
cmd, *args = keys[key]
|
cmd, *args = keys[key]
|
||||||
keys[key] = klass.new(cmd, args.join(' '))
|
#keys[key] = klass.new(cmd, args.join(' '))
|
||||||
|
keys[key] = klass.new(cmd, *args)
|
||||||
# elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method)
|
# elsif keys[key].kind_of?(Proc) || keys[key].kind_of?(Method)
|
||||||
elsif TkComm._callback_entry?(keys[key])
|
elsif TkComm._callback_entry?(keys[key])
|
||||||
keys[key] = klass.new(keys[key])
|
keys[key] = klass.new(keys[key])
|
||||||
|
@ -249,6 +251,7 @@ class TkValidateCommand
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -264,6 +267,7 @@ class TkValidateCommand
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
@ -293,6 +297,7 @@ class TkValidateCommand
|
||||||
extra_args_tbl = klass._get_extra_args_tbl
|
extra_args_tbl = klass._get_extra_args_tbl
|
||||||
|
|
||||||
if args.compact.size > 0
|
if args.compact.size > 0
|
||||||
|
args.map!{|arg| klass._sym2subst(arg)}
|
||||||
args = args.join(' ')
|
args = args.join(' ')
|
||||||
keys = klass._get_subst_key(args)
|
keys = klass._get_subst_key(args)
|
||||||
if cmd.kind_of?(String)
|
if cmd.kind_of?(String)
|
||||||
|
|
|
@ -362,7 +362,7 @@ module Tk
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
def overrideredirect(mode=TkComm::None)
|
def overrideredirect(mode=TkComm::None)
|
||||||
Wm.overrideredirect(self, mode=TkComm::None)
|
Wm.overrideredirect(self, mode)
|
||||||
end
|
end
|
||||||
alias wm_overrideredirect overrideredirect
|
alias wm_overrideredirect overrideredirect
|
||||||
TOPLEVEL_METHODCALL_OPTKEYS['overrideredirect'] = 'overrideredirect'
|
TOPLEVEL_METHODCALL_OPTKEYS['overrideredirect'] = 'overrideredirect'
|
||||||
|
@ -545,7 +545,7 @@ module Tk
|
||||||
module Wm_for_General
|
module Wm_for_General
|
||||||
Wm.instance_methods.each{|m|
|
Wm.instance_methods.each{|m|
|
||||||
if (m = m.to_s) =~ /^wm_(.*)$/
|
if (m = m.to_s) =~ /^wm_(.*)$/
|
||||||
eval "def #{m}(*args); Tk::Wm.#{$1}(self, *args); end"
|
eval "def #{m}(*args, &b); Tk::Wm.#{$1}(self, *args, &b); end"
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -81,6 +81,7 @@ module Tk::BLT
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -96,6 +97,7 @@ module Tk::BLT
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL)
|
_setup_subst_table(KEY_TBL, PROC_TBL)
|
||||||
|
|
||||||
|
@ -123,6 +125,7 @@ module Tk::BLT
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -138,6 +141,7 @@ module Tk::BLT
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL)
|
_setup_subst_table(KEY_TBL, PROC_TBL)
|
||||||
|
|
||||||
|
@ -177,6 +181,7 @@ module Tk::BLT
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -192,6 +197,7 @@ module Tk::BLT
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL)
|
_setup_subst_table(KEY_TBL, PROC_TBL)
|
||||||
end
|
end
|
||||||
|
|
|
@ -239,6 +239,7 @@ class Tk::BLT::Treeview
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -254,6 +255,7 @@ class Tk::BLT::Treeview
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
@ -492,6 +494,7 @@ class Tk::BLT::Treeview
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -507,6 +510,7 @@ class Tk::BLT::Treeview
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
@ -523,7 +527,8 @@ class Tk::BLT::Treeview
|
||||||
def _find_exec_flag_value(val)
|
def _find_exec_flag_value(val)
|
||||||
if val.kind_of?(Array)
|
if val.kind_of?(Array)
|
||||||
cmd, *args = val
|
cmd, *args = val
|
||||||
FindExecFlagValue.new(cmd, args.join(' '))
|
#FindExecFlagValue.new(cmd, args.join(' '))
|
||||||
|
FindExecFlagValue.new(cmd, *args)
|
||||||
elsif TkComm._callback_entry?(val)
|
elsif TkComm._callback_entry?(val)
|
||||||
FindExecFlagValue.new(val)
|
FindExecFlagValue.new(val)
|
||||||
else
|
else
|
||||||
|
|
|
@ -46,6 +46,7 @@ class Tk::Iwidgets::Calendar
|
||||||
KEY_TBL = [ [?d, ?s, :date], nil ]
|
KEY_TBL = [ [?d, ?s, :date], nil ]
|
||||||
PROC_TBL = [ [?s, TkComm.method(:string) ], nil ]
|
PROC_TBL = [ [?s, TkComm.method(:string) ], nil ]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -61,6 +62,7 @@ class Tk::Iwidgets::Calendar
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ class Tk::Iwidgets::Entryfield
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -58,6 +59,7 @@ class Tk::Iwidgets::Entryfield
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,6 +31,7 @@ class Tk::Iwidgets::Hierarchy
|
||||||
KEY_TBL = [ [?n, ?s, :node], nil ]
|
KEY_TBL = [ [?n, ?s, :node], nil ]
|
||||||
PROC_TBL = [ [?s, TkComm.method(:string) ], nil ]
|
PROC_TBL = [ [?s, TkComm.method(:string) ], nil ]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -46,6 +47,7 @@ class Tk::Iwidgets::Hierarchy
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
@ -74,6 +76,7 @@ class Tk::Iwidgets::Hierarchy
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -89,6 +92,7 @@ class Tk::Iwidgets::Hierarchy
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
@ -112,6 +116,7 @@ class Tk::Iwidgets::Hierarchy
|
||||||
]
|
]
|
||||||
PROC_TBL = [ [ ?s, TkComm.method(:string) ], nil ]
|
PROC_TBL = [ [ ?s, TkComm.method(:string) ], nil ]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -127,6 +132,7 @@ class Tk::Iwidgets::Hierarchy
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class Tk::Iwidgets::Spinner
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -53,6 +54,7 @@ class Tk::Iwidgets::Spinner
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
end
|
end
|
||||||
|
|
|
@ -201,6 +201,38 @@ module Tk
|
||||||
args.map!{|arg| TkComm._get_eval_string(arg)}.join('.')
|
args.map!{|arg| TkComm._get_eval_string(arg)}.join('.')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.themes(glob_ptn = nil)
|
||||||
|
if TILE_SPEC_VERSION_ID < 8 && Tk.info(:commands, '::ttk::themes').empty?
|
||||||
|
fail RuntimeError, 'not support glob option' if glob_ptn
|
||||||
|
cmd = ['::tile::availableThemes']
|
||||||
|
else
|
||||||
|
glob_ptn = '*' unless glob_ptn
|
||||||
|
cmd = ['::ttk::themes', glob_ptn]
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
TkComm.simplelist(Tk.tk_call_without_enc(*cmd))
|
||||||
|
rescue
|
||||||
|
TkComm.simplelist(Tk.tk_call('lsearch', '-all', '-inline',
|
||||||
|
Tk::Tile::Style.theme_names,
|
||||||
|
glob_ptn))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.set_theme(theme)
|
||||||
|
if TILE_SPEC_VERSION_ID < 8 && Tk.info(:commands, '::ttk::setTheme').empty?
|
||||||
|
cmd = '::tile::setTheme'
|
||||||
|
else
|
||||||
|
cmd = '::ttk::setTheme'
|
||||||
|
end
|
||||||
|
|
||||||
|
begin
|
||||||
|
Tk.tk_call_without_enc(cmd, theme)
|
||||||
|
rescue
|
||||||
|
Tk::Tile::Style.theme_use(theme)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
module KeyNav
|
module KeyNav
|
||||||
if Tk::Tile::TILE_SPEC_VERSION_ID < 8
|
if Tk::Tile::TILE_SPEC_VERSION_ID < 8
|
||||||
def self.enableMnemonics(w)
|
def self.enableMnemonics(w)
|
||||||
|
@ -332,12 +364,16 @@ module Tk
|
||||||
|
|
||||||
autoload :TLabelframe, 'tkextlib/tile/tlabelframe'
|
autoload :TLabelframe, 'tkextlib/tile/tlabelframe'
|
||||||
autoload :Labelframe, 'tkextlib/tile/tlabelframe'
|
autoload :Labelframe, 'tkextlib/tile/tlabelframe'
|
||||||
|
autoload :TLabelFrame, 'tkextlib/tile/tlabelframe'
|
||||||
|
autoload :LabelFrame, 'tkextlib/tile/tlabelframe'
|
||||||
|
|
||||||
autoload :TLabel, 'tkextlib/tile/tlabel'
|
autoload :TLabel, 'tkextlib/tile/tlabel'
|
||||||
autoload :Label, 'tkextlib/tile/tlabel'
|
autoload :Label, 'tkextlib/tile/tlabel'
|
||||||
|
|
||||||
autoload :TMenubutton, 'tkextlib/tile/tmenubutton'
|
autoload :TMenubutton, 'tkextlib/tile/tmenubutton'
|
||||||
autoload :Menubutton, 'tkextlib/tile/tmenubutton'
|
autoload :Menubutton, 'tkextlib/tile/tmenubutton'
|
||||||
|
autoload :TMenuButton, 'tkextlib/tile/tmenubutton'
|
||||||
|
autoload :MenuButton, 'tkextlib/tile/tmenubutton'
|
||||||
|
|
||||||
autoload :TNotebook, 'tkextlib/tile/tnotebook'
|
autoload :TNotebook, 'tkextlib/tile/tnotebook'
|
||||||
autoload :Notebook, 'tkextlib/tile/tnotebook'
|
autoload :Notebook, 'tkextlib/tile/tnotebook'
|
||||||
|
|
|
@ -33,6 +33,8 @@ class << Tk::Tile::Style
|
||||||
# conflict with some definitions on Tcl/Tk scripts.
|
# conflict with some definitions on Tcl/Tk scripts.
|
||||||
if Tk::Tile::TILE_SPEC_VERSION_ID < 7
|
if Tk::Tile::TILE_SPEC_VERSION_ID < 7
|
||||||
def __define_wrapper_proc_for_compatibility__!
|
def __define_wrapper_proc_for_compatibility__!
|
||||||
|
__define_themes_and_setTheme_proc__!
|
||||||
|
|
||||||
unless Tk.info(:commands, '::ttk::style').empty?
|
unless Tk.info(:commands, '::ttk::style').empty?
|
||||||
# fail RuntimeError,
|
# fail RuntimeError,
|
||||||
# "can't define '::ttk::style' command (already exist)"
|
# "can't define '::ttk::style' command (already exist)"
|
||||||
|
@ -59,6 +61,8 @@ class << Tk::Tile::Style
|
||||||
end
|
end
|
||||||
else ### TILE_SPEC_VERSION_ID == 7
|
else ### TILE_SPEC_VERSION_ID == 7
|
||||||
def __define_wrapper_proc_for_compatibility__!
|
def __define_wrapper_proc_for_compatibility__!
|
||||||
|
__define_themes_and_setTheme_proc__!
|
||||||
|
|
||||||
unless Tk.info(:commands, '::ttk::style').empty?
|
unless Tk.info(:commands, '::ttk::style').empty?
|
||||||
# fail RuntimeError,
|
# fail RuntimeError,
|
||||||
# "can't define '::ttk::style' command (already exist)"
|
# "can't define '::ttk::style' command (already exist)"
|
||||||
|
@ -91,6 +95,8 @@ class << Tk::Tile::Style
|
||||||
TkCommandNames = ['::ttk::style'.freeze].freeze
|
TkCommandNames = ['::ttk::style'.freeze].freeze
|
||||||
|
|
||||||
def __define_wrapper_proc_for_compatibility__!
|
def __define_wrapper_proc_for_compatibility__!
|
||||||
|
__define_themes_and_setTheme_proc__!
|
||||||
|
|
||||||
unless Tk.info(:commands, '::style').empty?
|
unless Tk.info(:commands, '::style').empty?
|
||||||
# fail RuntimeError, "can't define '::style' command (already exist)"
|
# fail RuntimeError, "can't define '::style' command (already exist)"
|
||||||
|
|
||||||
|
@ -120,6 +126,36 @@ class << Tk::Tile::Style
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def __define_themes_and_setTheme_proc__!
|
||||||
|
TkCore::INTERP.add_tk_procs('::ttk::themes', '{ptn *}', <<-'EOS')
|
||||||
|
#set themes [list]
|
||||||
|
set themes [::ttk::style theme names]
|
||||||
|
foreach pkg [lsearch -inline -all -glob [package names] ttk::theme::$ptn] {
|
||||||
|
set theme [namespace tail $pkg]
|
||||||
|
if {[lsearch -exact $themes $theme] < 0} {
|
||||||
|
lappend themes $theme
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach pkg [lsearch -inline -all -glob [package names] tile::theme::$ptn] {
|
||||||
|
set theme [namespace tail $pkg]
|
||||||
|
if {[lsearch -exact $themes $theme] < 0} {
|
||||||
|
lappend themes $theme
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $themes
|
||||||
|
EOS
|
||||||
|
#########################
|
||||||
|
TkCore::INTERP.add_tk_procs('::ttk::setTheme', 'theme', <<-'EOS')
|
||||||
|
variable currentTheme
|
||||||
|
if {[lsearch -exact [::ttk::style theme names] $theme] < 0} {
|
||||||
|
package require [lsearch -inline -regexp [package names] (ttk|tile)::theme::$theme]
|
||||||
|
}
|
||||||
|
::ttk::style theme use $theme
|
||||||
|
set currentTheme $theme
|
||||||
|
EOS
|
||||||
|
end
|
||||||
|
private :__define_themes_and_setTheme_proc__!
|
||||||
|
|
||||||
def configure(style=nil, keys=nil)
|
def configure(style=nil, keys=nil)
|
||||||
if style.kind_of?(Hash)
|
if style.kind_of?(Hash)
|
||||||
keys = style
|
keys = style
|
||||||
|
|
|
@ -77,9 +77,9 @@ class Tk::Tile::TNotebook < TkWindow
|
||||||
|
|
||||||
def add(child, keys=nil)
|
def add(child, keys=nil)
|
||||||
if keys && keys != None
|
if keys && keys != None
|
||||||
tk_send_without_enc('add', _epath(child), *hash_kv(keys))
|
tk_send('add', _epath(child), *hash_kv(keys))
|
||||||
else
|
else
|
||||||
tk_send_without_enc('add', _epath(child))
|
tk_send('add', _epath(child))
|
||||||
end
|
end
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,15 +11,15 @@ require 'tkextlib/setup.rb'
|
||||||
# call setup script
|
# call setup script
|
||||||
require 'tkextlib/tkDND/setup.rb'
|
require 'tkextlib/tkDND/setup.rb'
|
||||||
|
|
||||||
# TkPackage.require('shape', '0.3')
|
# TkPackage.require('Shape', '0.3')
|
||||||
TkPackage.require('shape')
|
TkPackage.require('Shape')
|
||||||
|
|
||||||
module Tk
|
module Tk
|
||||||
module TkDND
|
module TkDND
|
||||||
module Shape
|
module Shape
|
||||||
extend TkCore
|
extend TkCore
|
||||||
|
|
||||||
PACKAGE_NAME = 'shape'.freeze
|
PACKAGE_NAME = 'Shape'.freeze
|
||||||
def self.package_name
|
def self.package_name
|
||||||
PACKAGE_NAME
|
PACKAGE_NAME
|
||||||
end
|
end
|
||||||
|
@ -27,26 +27,28 @@ module Tk
|
||||||
=begin
|
=begin
|
||||||
def self.package_version
|
def self.package_version
|
||||||
begin
|
begin
|
||||||
TkPackage.require('shape')
|
TkPackage.require('Shape')
|
||||||
rescue
|
rescue
|
||||||
''
|
''
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
=end
|
=end
|
||||||
def self.package_version
|
class << self
|
||||||
|
def package_version
|
||||||
Tk.tk_call('set', 'shape_version')
|
Tk.tk_call('set', 'shape_version')
|
||||||
end
|
end
|
||||||
alias shape_version package_version
|
alias shape_version package_version
|
||||||
|
|
||||||
def self.package_patchlevel
|
def package_patchlevel
|
||||||
Tk.tk_call('set', 'shape_patchlevel')
|
Tk.tk_call('set', 'shape_patchLevel')
|
||||||
end
|
end
|
||||||
alias shape_patchlevel package_patchlevel
|
alias shape_patchlevel package_patchlevel
|
||||||
|
|
||||||
def self.version
|
def version
|
||||||
tk_call('shape', 'version')
|
tk_call('shape', 'version')
|
||||||
end
|
end
|
||||||
alias xshape_version version
|
alias xshape_version version
|
||||||
|
end
|
||||||
|
|
||||||
############################
|
############################
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@ module Tk
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -72,6 +73,7 @@ module Tk
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
# setup tables
|
# setup tables
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
|
@ -291,6 +291,7 @@ class Tk::TkTable
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -306,6 +307,7 @@ class Tk::TkTable
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
@ -340,6 +342,7 @@ class Tk::TkTable
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -355,6 +358,7 @@ class Tk::TkTable
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
@ -387,6 +391,7 @@ class Tk::TkTable
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -402,6 +407,7 @@ class Tk::TkTable
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
@ -437,6 +443,7 @@ class Tk::TkTable
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -452,6 +459,7 @@ class Tk::TkTable
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
end
|
end
|
||||||
|
|
|
@ -137,6 +137,7 @@ class Tk::TreeCtrl::NotifyEvent
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -152,6 +153,7 @@ class Tk::TreeCtrl::NotifyEvent
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
# setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys
|
# setup tables to be used by scan_args, _get_subst_key, _get_all_subst_keys
|
||||||
#
|
#
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
# release date of tkextlib
|
# release date of tkextlib
|
||||||
#
|
#
|
||||||
module Tk
|
module Tk
|
||||||
Tkextlib_RELEASE_DATE = '2008-04-18'.freeze
|
Tkextlib_RELEASE_DATE = '2008-05-14'.freeze
|
||||||
end
|
end
|
||||||
|
|
|
@ -150,6 +150,7 @@ class Tk::Winico
|
||||||
nil
|
nil
|
||||||
]
|
]
|
||||||
|
|
||||||
|
=begin
|
||||||
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
# for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
|
||||||
KEY_TBL.map!{|inf|
|
KEY_TBL.map!{|inf|
|
||||||
if inf.kind_of?(Array)
|
if inf.kind_of?(Array)
|
||||||
|
@ -165,6 +166,7 @@ class Tk::Winico
|
||||||
end
|
end
|
||||||
inf
|
inf
|
||||||
}
|
}
|
||||||
|
=end
|
||||||
|
|
||||||
_setup_subst_table(KEY_TBL, PROC_TBL);
|
_setup_subst_table(KEY_TBL, PROC_TBL);
|
||||||
|
|
||||||
|
@ -185,7 +187,8 @@ class Tk::Winico
|
||||||
Winico_callback._config_keys.each{|k|
|
Winico_callback._config_keys.each{|k|
|
||||||
if keys[k].kind_of?(Array)
|
if keys[k].kind_of?(Array)
|
||||||
cmd, *args = keys[k]
|
cmd, *args = keys[k]
|
||||||
keys[k] = Winico_callback.new(cmd, args.join(' '))
|
#keys[k] = Winico_callback.new(cmd, args.join(' '))
|
||||||
|
keys[k] = Winico_callback.new(cmd, *args)
|
||||||
# elsif keys[k].kind_of?(Proc)
|
# elsif keys[k].kind_of?(Proc)
|
||||||
elsif TkComm._callback_entry?(keys[k])
|
elsif TkComm._callback_entry?(keys[k])
|
||||||
keys[k] = Winico_callback.new(keys[k])
|
keys[k] = Winico_callback.new(keys[k])
|
||||||
|
@ -201,7 +204,8 @@ class Tk::Winico
|
||||||
Winico_callback._config_keys.each{|k|
|
Winico_callback._config_keys.each{|k|
|
||||||
if keys[k].kind_of?(Array)
|
if keys[k].kind_of?(Array)
|
||||||
cmd, *args = keys[k]
|
cmd, *args = keys[k]
|
||||||
keys[k] = Winico_callback.new(cmd, args.join(' '))
|
#keys[k] = Winico_callback.new(cmd, args.join(' '))
|
||||||
|
keys[k] = Winico_callback.new(cmd, *args)
|
||||||
# elsif keys[k].kind_of?(Proc)
|
# elsif keys[k].kind_of?(Proc)
|
||||||
elsif TkComm._callback_entry?(keys[k])
|
elsif TkComm._callback_entry?(keys[k])
|
||||||
keys[k] = Winico_callback.new(keys[k])
|
keys[k] = Winico_callback.new(keys[k])
|
||||||
|
|
|
@ -58,6 +58,7 @@ class AnimatedWaveDemo
|
||||||
@backupCoords = []
|
@backupCoords = []
|
||||||
n = 0
|
n = 0
|
||||||
(-10..300).step(5){|n| @waveCoords << [n, 100]; @backupCoords << [n, 100] }
|
(-10..300).step(5){|n| @waveCoords << [n, 100]; @backupCoords << [n, 100] }
|
||||||
|
n = 305
|
||||||
@waveCoords << [n, 0]; @backupCoords << [n, 0]
|
@waveCoords << [n, 0]; @backupCoords << [n, 0]
|
||||||
@waveCoords << [n+5, 200]; @backupCoords << [n+5, 200]
|
@waveCoords << [n+5, 200]; @backupCoords << [n+5, 200]
|
||||||
@coordsLen = @waveCoords.length
|
@coordsLen = @waveCoords.length
|
||||||
|
|
|
@ -60,6 +60,7 @@ class AnimatedWaveDemo
|
||||||
@backupCoords = []
|
@backupCoords = []
|
||||||
n = 0
|
n = 0
|
||||||
(-10..300).step(5){|n| @waveCoords << [n, 100]; @backupCoords << [n, 100] }
|
(-10..300).step(5){|n| @waveCoords << [n, 100]; @backupCoords << [n, 100] }
|
||||||
|
n = 305
|
||||||
@waveCoords << [n, 0]; @backupCoords << [n, 0]
|
@waveCoords << [n, 0]; @backupCoords << [n, 0]
|
||||||
@waveCoords << [n+5, 200]; @backupCoords << [n+5, 200]
|
@waveCoords << [n+5, 200]; @backupCoords << [n+5, 200]
|
||||||
@coordsLen = @waveCoords.length
|
@coordsLen = @waveCoords.length
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
#
|
#
|
||||||
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
|
||||||
#
|
#
|
||||||
version = '0.1.1'
|
version = '0.1.3'
|
||||||
#
|
#
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# parse commandline arguments
|
# parse commandline arguments
|
||||||
|
@ -107,38 +107,37 @@ TkConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__! true
|
||||||
TkItemConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__! true
|
TkItemConfigMethod.__set_IGNORE_UNKNOWN_CONFIGURE_OPTION__! true
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
|
||||||
# define utility method
|
|
||||||
##########################################################################
|
|
||||||
def setTheme(theme)
|
|
||||||
unless Tk::Tile::Style.theme_names.find{|n| n == theme}
|
|
||||||
if (pkg = TkPackage.names.find{|n| n =~ /(tile|ttk)::theme::#{theme}/})
|
|
||||||
TkPackage.require(pkg)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Tk::Tile::Style.theme_use(theme)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
|
||||||
# make theme name list
|
|
||||||
##########################################################################
|
|
||||||
ThemesList = Tk::Tile::Style.theme_names
|
|
||||||
TkPackage.names.find_all{|n| n =~ /^(tile|ttk)::theme::/}.each{|pkg|
|
|
||||||
ThemesList << pkg.split('::')[-1]
|
|
||||||
}
|
|
||||||
ThemesList.uniq!
|
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
# set theme of widget style
|
# set theme of widget style
|
||||||
##########################################################################
|
##########################################################################
|
||||||
if OPTS[:list] || OPTS[:verbose]
|
if OPTS[:list] || OPTS[:verbose]
|
||||||
print "supported theme names: #{ThemesList.inspect}\n"
|
print "supported theme names: #{Tk::Tile.themes.inspect}\n"
|
||||||
exit if OPTS[:list] && ARGV.empty?
|
exit if OPTS[:list] && ARGV.empty?
|
||||||
end
|
end
|
||||||
print "use theme: \"#{OPTS[:theme]}\"\n" if OPTS[:theme] && OPTS[:verbose]
|
print "use theme: \"#{OPTS[:theme]}\"\n" if OPTS[:theme] && OPTS[:verbose]
|
||||||
setTheme(OPTS[:theme]) if OPTS[:theme]
|
#setTheme(OPTS[:theme]) if OPTS[:theme]
|
||||||
|
Tk::Tile.set_theme(OPTS[:theme]) if OPTS[:theme]
|
||||||
|
|
||||||
|
|
||||||
|
##########################################################################
|
||||||
|
# replace $0 and $RPAGRAM_NAME
|
||||||
|
##########################################################################
|
||||||
|
# When the expand_path of the target script is long, ruby sometimes
|
||||||
|
# fails to set the path to $0 (the path string is trimmed).
|
||||||
|
# The following replaces $0 and $PROGNAME to avoid such trouble.
|
||||||
|
progname_obj = $0.dup
|
||||||
|
$program_name = progname_obj
|
||||||
|
|
||||||
|
alias $REAL_PROGRAM_NAME $0
|
||||||
|
alias $PROGRAM_NAME $program_name
|
||||||
|
alias $0 $program_name
|
||||||
|
|
||||||
|
trace_var(:$program_name){|val|
|
||||||
|
unless progname_obj.object_id == val.object_id
|
||||||
|
progname_obj.replace(val.to_s)
|
||||||
|
$program_name = progname_obj
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
@ -146,6 +145,7 @@ setTheme(OPTS[:theme]) if OPTS[:theme]
|
||||||
##########################################################################
|
##########################################################################
|
||||||
if (path = ARGV.shift) && (script = File.expand_path(path))
|
if (path = ARGV.shift) && (script = File.expand_path(path))
|
||||||
print "load script \"#{script}\"\n" if OPTS[:verbose]
|
print "load script \"#{script}\"\n" if OPTS[:verbose]
|
||||||
|
$0 = script
|
||||||
load(script)
|
load(script)
|
||||||
else
|
else
|
||||||
print "Error: no script is given.\n"
|
print "Error: no script is given.\n"
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Oct. 24, 1997 Y. Matsumoto
|
* Oct. 24, 1997 Y. Matsumoto
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TCLTKLIB_RELEASE_DATE "2008-04-02"
|
#define TCLTKLIB_RELEASE_DATE "2008-05-16"
|
||||||
|
|
||||||
#include "ruby.h"
|
#include "ruby.h"
|
||||||
|
|
||||||
|
@ -3153,6 +3153,7 @@ ip_ruby_cmd(clientData, interp, argc, argv)
|
||||||
str, "'", (char *)NULL);
|
str, "'", (char *)NULL);
|
||||||
rbtk_pending_exception = rb_exc_new2(rb_eArgError,
|
rbtk_pending_exception = rb_exc_new2(rb_eArgError,
|
||||||
Tcl_GetStringResult(interp));
|
Tcl_GetStringResult(interp));
|
||||||
|
if (old_gc == Qfalse) rb_gc_enable();
|
||||||
return TCL_ERROR;
|
return TCL_ERROR;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -5155,6 +5156,8 @@ ip_finalize(ip)
|
||||||
Tcl_CreateCommand(ip, "ruby_cmd", ip_null_proc,
|
Tcl_CreateCommand(ip, "ruby_cmd", ip_null_proc,
|
||||||
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
|
(ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
|
||||||
#endif
|
#endif
|
||||||
|
rb_thread_critical = thr_crit_bup;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delete root widget */
|
/* delete root widget */
|
||||||
|
@ -5162,7 +5165,7 @@ ip_finalize(ip)
|
||||||
DUMP1("check `destroy'");
|
DUMP1("check `destroy'");
|
||||||
if (Tcl_GetCommandInfo(ip, "destroy", &info)) {
|
if (Tcl_GetCommandInfo(ip, "destroy", &info)) {
|
||||||
DUMP1("call `destroy'");
|
DUMP1("call `destroy'");
|
||||||
Tcl_GlobalEval(ip, "destroy .");
|
Tcl_GlobalEval(ip, "catch {destroy .}");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -7106,7 +7109,8 @@ lib_toUTF8_core(ip_obj, src, encodename)
|
||||||
if (NIL_P(enc)) {
|
if (NIL_P(enc)) {
|
||||||
encoding = (Tcl_Encoding)NULL;
|
encoding = (Tcl_Encoding)NULL;
|
||||||
} else {
|
} else {
|
||||||
StringValue(enc);
|
/* StringValue(enc); */
|
||||||
|
enc = rb_funcall(enc, ID_to_s, 0, 0);
|
||||||
/* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */
|
/* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */
|
||||||
encoding = Tcl_GetEncoding((Tcl_Interp*)NULL,
|
encoding = Tcl_GetEncoding((Tcl_Interp*)NULL,
|
||||||
RSTRING_PTR(enc));
|
RSTRING_PTR(enc));
|
||||||
|
@ -7292,7 +7296,8 @@ lib_fromUTF8_core(ip_obj, src, encodename)
|
||||||
if (NIL_P(enc)) {
|
if (NIL_P(enc)) {
|
||||||
encoding = (Tcl_Encoding)NULL;
|
encoding = (Tcl_Encoding)NULL;
|
||||||
} else {
|
} else {
|
||||||
StringValue(enc);
|
/* StringValue(enc); */
|
||||||
|
enc = rb_funcall(enc, ID_to_s, 0, 0);
|
||||||
/* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */
|
/* encoding = Tcl_GetEncoding(interp, RSTRING_PTR(enc)); */
|
||||||
encoding = Tcl_GetEncoding((Tcl_Interp*)NULL,
|
encoding = Tcl_GetEncoding((Tcl_Interp*)NULL,
|
||||||
RSTRING_PTR(enc));
|
RSTRING_PTR(enc));
|
||||||
|
|
|
@ -8,5 +8,6 @@ end
|
||||||
if has_tk
|
if has_tk
|
||||||
require 'mkmf'
|
require 'mkmf'
|
||||||
have_func("rb_obj_instance_exec", "ruby.h")
|
have_func("rb_obj_instance_exec", "ruby.h")
|
||||||
|
have_func("strndup", "string.h")
|
||||||
create_makefile('tkutil')
|
create_makefile('tkutil')
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
************************************************/
|
************************************************/
|
||||||
|
|
||||||
#define TKUTIL_RELEASE_DATE "2008-03-29"
|
#define TKUTIL_RELEASE_DATE "2008-05-14"
|
||||||
|
|
||||||
#include "ruby.h"
|
#include "ruby.h"
|
||||||
|
|
||||||
|
@ -1073,11 +1073,13 @@ tcl2rb_num_or_str(self, value)
|
||||||
|
|
||||||
/*************************************/
|
/*************************************/
|
||||||
|
|
||||||
|
#define CBSUBST_TBL_MAX (256)
|
||||||
struct cbsubst_info {
|
struct cbsubst_info {
|
||||||
int size;
|
int full_subst_length;
|
||||||
char *key;
|
int keylen[CBSUBST_TBL_MAX];
|
||||||
char *type;
|
unsigned char *key[CBSUBST_TBL_MAX];
|
||||||
ID *ivar;
|
unsigned char type[CBSUBST_TBL_MAX];
|
||||||
|
ID ivar[CBSUBST_TBL_MAX];
|
||||||
VALUE proc;
|
VALUE proc;
|
||||||
VALUE aliases;
|
VALUE aliases;
|
||||||
};
|
};
|
||||||
|
@ -1094,33 +1096,33 @@ static void
|
||||||
subst_free(ptr)
|
subst_free(ptr)
|
||||||
struct cbsubst_info *ptr;
|
struct cbsubst_info *ptr;
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
if (ptr->key != (char*)NULL) free(ptr->key);
|
for(i = 0; i < CBSUBST_TBL_MAX; i++) {
|
||||||
if (ptr->type != (char*)NULL) free(ptr->type);
|
if (ptr->key[i] != (unsigned char *)NULL) free(ptr->key[i]);
|
||||||
if (ptr->ivar != (ID*)NULL) free(ptr->ivar);
|
}
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static struct cbsubst_info *
|
||||||
cbsubst_init()
|
allocate_cbsubst_info()
|
||||||
{
|
{
|
||||||
struct cbsubst_info *inf;
|
struct cbsubst_info *inf;
|
||||||
ID *ivar;
|
|
||||||
volatile VALUE proc, aliases;
|
volatile VALUE proc, aliases;
|
||||||
|
int idx;
|
||||||
|
|
||||||
inf = ALLOC(struct cbsubst_info);
|
inf = ALLOC(struct cbsubst_info);
|
||||||
|
|
||||||
inf->size = 0;
|
inf->full_subst_length = 0;
|
||||||
|
|
||||||
inf->key = ALLOC_N(char, 1);
|
for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
|
||||||
inf->key[0] = '\0';
|
inf->keylen[idx] = 0;
|
||||||
|
inf->key[idx] = (unsigned char *) NULL;
|
||||||
inf->type = ALLOC_N(char, 1);
|
inf->type[idx] = '\0';
|
||||||
inf->type[0] = '\0';
|
inf->ivar[idx] = (ID) 0;
|
||||||
|
}
|
||||||
ivar = ALLOC_N(ID, 1);
|
|
||||||
inf->ivar = ivar;
|
|
||||||
|
|
||||||
proc = rb_hash_new();
|
proc = rb_hash_new();
|
||||||
inf->proc = proc;
|
inf->proc = proc;
|
||||||
|
@ -1128,8 +1130,15 @@ cbsubst_init()
|
||||||
aliases = rb_hash_new();
|
aliases = rb_hash_new();
|
||||||
inf->aliases = aliases;
|
inf->aliases = aliases;
|
||||||
|
|
||||||
|
return inf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cbsubst_init()
|
||||||
|
{
|
||||||
rb_const_set(cCB_SUBST, ID_SUBST_INFO,
|
rb_const_set(cCB_SUBST, ID_SUBST_INFO,
|
||||||
Data_Wrap_Struct(cSUBST_INFO, subst_mark, subst_free, inf));
|
Data_Wrap_Struct(cSUBST_INFO, subst_mark, subst_free,
|
||||||
|
allocate_cbsubst_info()));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -1139,24 +1148,29 @@ cbsubst_initialize(argc, argv, self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct cbsubst_info *inf;
|
struct cbsubst_info *inf;
|
||||||
int idx;
|
int idx, iv_idx;
|
||||||
|
|
||||||
Data_Get_Struct(rb_const_get(rb_obj_class(self), ID_SUBST_INFO),
|
Data_Get_Struct(rb_const_get(rb_obj_class(self), ID_SUBST_INFO),
|
||||||
struct cbsubst_info, inf);
|
struct cbsubst_info, inf);
|
||||||
|
|
||||||
for(idx = 0; idx < argc; idx++) {
|
idx = 0;
|
||||||
rb_ivar_set(self, inf->ivar[idx], argv[idx]);
|
for(iv_idx = 0; iv_idx < CBSUBST_TBL_MAX; iv_idx++) {
|
||||||
|
if ( inf->ivar[iv_idx] == (ID) 0 ) continue;
|
||||||
|
rb_ivar_set(self, inf->ivar[iv_idx], argv[idx++]);
|
||||||
|
if (idx >= argc) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
cbsubst_ret_val(self, val)
|
cbsubst_ret_val(self, val)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
VALUE val;
|
VALUE val;
|
||||||
{
|
{
|
||||||
|
/* This method may be overwritten on some sub-classes. */
|
||||||
|
/* This method is used for converting from ruby's callback-return-value */
|
||||||
|
/* to tcl's value (e.g. validation procedure of entry widget). */
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1216,6 +1230,59 @@ cbsubst_def_attr_aliases(self, tbl)
|
||||||
return rb_funcall(inf->aliases, rb_intern("update"), 1, tbl);
|
return rb_funcall(inf->aliases, rb_intern("update"), 1, tbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
cbsubst_sym_to_subst(self, sym)
|
||||||
|
VALUE self;
|
||||||
|
VALUE sym;
|
||||||
|
{
|
||||||
|
struct cbsubst_info *inf;
|
||||||
|
const char *str;
|
||||||
|
unsigned char *buf, *ptr;
|
||||||
|
int idx, len;
|
||||||
|
ID id;
|
||||||
|
volatile VALUE ret;
|
||||||
|
|
||||||
|
if (TYPE(sym) != T_SYMBOL) return sym;
|
||||||
|
|
||||||
|
Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
|
||||||
|
struct cbsubst_info, inf);
|
||||||
|
|
||||||
|
if (!NIL_P(ret = rb_hash_aref(inf->aliases, sym))) {
|
||||||
|
str = rb_id2name(SYM2ID(ret));
|
||||||
|
} else {
|
||||||
|
str = rb_id2name(SYM2ID(sym));
|
||||||
|
}
|
||||||
|
|
||||||
|
id = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2("@"), str)));
|
||||||
|
|
||||||
|
for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
|
||||||
|
if (inf->ivar[idx] == id) break;
|
||||||
|
}
|
||||||
|
if (idx >= CBSUBST_TBL_MAX) return sym;
|
||||||
|
|
||||||
|
ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);
|
||||||
|
|
||||||
|
*(ptr++) = '%';
|
||||||
|
|
||||||
|
if (len = inf->keylen[idx]) {
|
||||||
|
/* longname */
|
||||||
|
strncpy(ptr, inf->key[idx], len);
|
||||||
|
ptr += len;
|
||||||
|
} else {
|
||||||
|
/* single char */
|
||||||
|
*(ptr++) = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
*(ptr++) = ' ';
|
||||||
|
*(ptr++) = '\0';
|
||||||
|
|
||||||
|
ret = rb_str_new2(buf);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
cbsubst_get_subst_arg(argc, argv, self)
|
cbsubst_get_subst_arg(argc, argv, self)
|
||||||
int argc;
|
int argc;
|
||||||
|
@ -1224,17 +1291,15 @@ cbsubst_get_subst_arg(argc, argv, self)
|
||||||
{
|
{
|
||||||
struct cbsubst_info *inf;
|
struct cbsubst_info *inf;
|
||||||
const char *str;
|
const char *str;
|
||||||
char *buf, *ptr;
|
unsigned char *buf, *ptr;
|
||||||
int i, j, len;
|
int i, idx, len;
|
||||||
ID id;
|
ID id;
|
||||||
volatile VALUE arg_sym, ret;
|
volatile VALUE arg_sym, ret;
|
||||||
|
|
||||||
Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
|
Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
|
||||||
struct cbsubst_info, inf);
|
struct cbsubst_info, inf);
|
||||||
|
|
||||||
buf = ALLOC_N(char, 3*argc + 1);
|
ptr = buf = ALLOC_N(char, inf->full_subst_length + 1);
|
||||||
ptr = buf;
|
|
||||||
len = strlen(inf->key);
|
|
||||||
|
|
||||||
for(i = 0; i < argc; i++) {
|
for(i = 0; i < argc; i++) {
|
||||||
switch(TYPE(argv[i])) {
|
switch(TYPE(argv[i])) {
|
||||||
|
@ -1256,16 +1321,24 @@ cbsubst_get_subst_arg(argc, argv, self)
|
||||||
|
|
||||||
id = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2("@"), str)));
|
id = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2("@"), str)));
|
||||||
|
|
||||||
for(j = 0; j < len; j++) {
|
for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
|
||||||
if (inf->ivar[j] == id) break;
|
if (inf->ivar[idx] == id) break;
|
||||||
}
|
}
|
||||||
|
if (idx >= CBSUBST_TBL_MAX) {
|
||||||
if (j >= len) {
|
|
||||||
rb_raise(rb_eArgError, "cannot find attribute :%s", str);
|
rb_raise(rb_eArgError, "cannot find attribute :%s", str);
|
||||||
}
|
}
|
||||||
|
|
||||||
*(ptr++) = '%';
|
*(ptr++) = '%';
|
||||||
*(ptr++) = *(inf->key + j);
|
|
||||||
|
if (len = inf->keylen[idx]) {
|
||||||
|
/* longname */
|
||||||
|
strncpy(ptr, inf->key[idx], len);
|
||||||
|
ptr += len;
|
||||||
|
} else {
|
||||||
|
/* single char */
|
||||||
|
*(ptr++) = idx;
|
||||||
|
}
|
||||||
|
|
||||||
*(ptr++) = ' ';
|
*(ptr++) = ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1283,27 +1356,50 @@ cbsubst_get_subst_key(self, str)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
VALUE str;
|
VALUE str;
|
||||||
{
|
{
|
||||||
|
struct cbsubst_info *inf;
|
||||||
volatile VALUE list;
|
volatile VALUE list;
|
||||||
volatile VALUE ret;
|
volatile VALUE ret;
|
||||||
int i, len;
|
VALUE keyval;
|
||||||
char *buf, *ptr;
|
int i, len, keylen, idx;
|
||||||
|
unsigned char *buf, *ptr, *key;
|
||||||
|
|
||||||
list = rb_funcall(cTclTkLib, ID_split_tklist, 1, str);
|
list = rb_funcall(cTclTkLib, ID_split_tklist, 1, str);
|
||||||
|
|
||||||
len = RARRAY_LEN(list);
|
len = RARRAY_LEN(list);
|
||||||
buf = ALLOC_N(char, len + 1);
|
|
||||||
|
Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
|
||||||
|
struct cbsubst_info, inf);
|
||||||
|
|
||||||
|
ptr = buf = ALLOC_N(unsigned char, inf->full_subst_length + len + 1);
|
||||||
|
|
||||||
for(i = 0; i < len; i++) {
|
for(i = 0; i < len; i++) {
|
||||||
ptr = RSTRING_PTR(RARRAY_PTR(list)[i]);
|
keyval = RARRAY_PTR(list)[i];
|
||||||
if (*ptr == '%' && *(ptr + 2) == '\0') {
|
key = (unsigned char*)RSTRING_PTR(keyval);
|
||||||
*(buf + i) = *(ptr + 1);
|
if (*key == '%') {
|
||||||
|
if (*(key + 2) == '\0') {
|
||||||
|
/* single char */
|
||||||
|
*(ptr++) = *(key + 1);
|
||||||
} else {
|
} else {
|
||||||
*(buf + i) = ' ';
|
/* search longname-key */
|
||||||
|
keylen = RSTRING_LEN(keyval) - 1;
|
||||||
|
for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
|
||||||
|
if (inf->keylen[idx] != keylen) continue;
|
||||||
|
if (inf->key[idx][0] != *(key + 1)) continue;
|
||||||
|
if (strncmp(inf->key[idx], key + 1, keylen)) continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (idx < CBSUBST_TBL_MAX) {
|
||||||
|
*(ptr++) = (unsigned char)idx;
|
||||||
|
} else {
|
||||||
|
*(ptr++) = ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*(buf + len) = '\0';
|
} else {
|
||||||
|
*(ptr++) = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ptr = '\0';
|
||||||
|
|
||||||
ret = rb_str_new2(buf);
|
ret = rb_str_new2((const char*)buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1313,24 +1409,40 @@ cbsubst_get_all_subst_keys(self)
|
||||||
VALUE self;
|
VALUE self;
|
||||||
{
|
{
|
||||||
struct cbsubst_info *inf;
|
struct cbsubst_info *inf;
|
||||||
char *buf, *ptr;
|
unsigned char *buf, *ptr;
|
||||||
int i, len;
|
unsigned char *keys_buf, *keys_ptr;
|
||||||
|
int idx, len;
|
||||||
volatile VALUE ret;
|
volatile VALUE ret;
|
||||||
|
|
||||||
Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
|
Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
|
||||||
struct cbsubst_info, inf);
|
struct cbsubst_info, inf);
|
||||||
|
|
||||||
len = strlen(inf->key);
|
ptr = buf = ALLOC_N(unsigned char, inf->full_subst_length + 1);
|
||||||
buf = ALLOC_N(char, 3*len + 1);
|
keys_ptr = keys_buf = ALLOC_N(unsigned char, CBSUBST_TBL_MAX + 1);
|
||||||
ptr = buf;
|
|
||||||
for(i = 0; i < len; i++) {
|
for(idx = 0; idx < CBSUBST_TBL_MAX; idx++) {
|
||||||
|
if (inf->ivar[idx] == (ID) 0) continue;
|
||||||
|
|
||||||
|
*(keys_ptr++) = (unsigned char)idx;
|
||||||
|
|
||||||
*(ptr++) = '%';
|
*(ptr++) = '%';
|
||||||
*(ptr++) = *(inf->key + i);
|
|
||||||
|
if (len = inf->keylen[idx]) {
|
||||||
|
/* longname */
|
||||||
|
strncpy(ptr, inf->key[idx], len);
|
||||||
|
ptr += len;
|
||||||
|
} else {
|
||||||
|
/* single char */
|
||||||
|
*(ptr++) = (unsigned char)idx;
|
||||||
|
}
|
||||||
|
|
||||||
*(ptr++) = ' ';
|
*(ptr++) = ' ';
|
||||||
}
|
}
|
||||||
*(buf + 3*len) = '\0';
|
|
||||||
|
|
||||||
ret = rb_ary_new3(2, rb_str_new2(inf->key), rb_str_new2(buf));
|
*ptr = '\0';
|
||||||
|
*keys_ptr = '\0';
|
||||||
|
|
||||||
|
ret = rb_ary_new3(2, rb_str_new2(keys_buf), rb_str_new2((const char*)buf));
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
|
|
||||||
|
@ -1338,68 +1450,117 @@ cbsubst_get_all_subst_keys(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
cbsubst_table_setup(self, key_inf, proc_inf)
|
cbsubst_table_setup(argc, argv, self)
|
||||||
|
int argc;
|
||||||
|
VALUE *argv;
|
||||||
VALUE self;
|
VALUE self;
|
||||||
VALUE key_inf;
|
|
||||||
VALUE proc_inf;
|
|
||||||
{
|
{
|
||||||
|
volatile VALUE key_inf;
|
||||||
|
volatile VALUE longkey_inf;
|
||||||
|
volatile VALUE proc_inf;
|
||||||
|
VALUE inf;
|
||||||
|
ID id;
|
||||||
struct cbsubst_info *subst_inf;
|
struct cbsubst_info *subst_inf;
|
||||||
int idx;
|
int idx, len;
|
||||||
int len = RARRAY_LEN(key_inf);
|
unsigned char chr;
|
||||||
int real_len = 0;
|
|
||||||
char *key = ALLOC_N(char, len + 1);
|
/* accept (key_inf, proc_inf) or (key_inf, longkey_inf, procinf) */
|
||||||
char *type = ALLOC_N(char, len + 1);
|
if (rb_scan_args(argc, argv, "21", &key_inf, &longkey_inf, &proc_inf) == 2) {
|
||||||
ID *ivar = ALLOC_N(ID, len + 1);
|
proc_inf = longkey_inf;
|
||||||
volatile VALUE proc = rb_hash_new();
|
longkey_inf = rb_ary_new();
|
||||||
volatile VALUE aliases = rb_hash_new();
|
}
|
||||||
volatile VALUE inf;
|
|
||||||
|
/* check the number of longkeys */
|
||||||
|
if (RARRAY_LEN(longkey_inf) > 125 /* from 0x80 to 0xFD */) {
|
||||||
|
rb_raise(rb_eArgError, "too many longname-key definitions");
|
||||||
|
}
|
||||||
|
|
||||||
/* init */
|
/* init */
|
||||||
subst_inf = ALLOC(struct cbsubst_info);
|
subst_inf = allocate_cbsubst_info();
|
||||||
/* subst_inf->size = len; */
|
|
||||||
subst_inf->key = key;
|
|
||||||
subst_inf->type = type;
|
|
||||||
subst_inf->ivar = ivar;
|
|
||||||
subst_inf->proc = proc;
|
|
||||||
subst_inf->aliases = aliases;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* keys : array of [subst, type, ivar]
|
* keys : array of [subst, type, ivar]
|
||||||
* subst ==> char code
|
* subst ==> char code or string
|
||||||
* type ==> char code
|
* type ==> char code or string
|
||||||
* ivar ==> symbol
|
* ivar ==> symbol
|
||||||
*/
|
*/
|
||||||
|
len = RARRAY_LEN(key_inf);
|
||||||
for(idx = 0; idx < len; idx++) {
|
for(idx = 0; idx < len; idx++) {
|
||||||
inf = RARRAY_PTR(key_inf)[idx];
|
inf = RARRAY_PTR(key_inf)[idx];
|
||||||
if (TYPE(inf) != T_ARRAY) continue;
|
if (TYPE(inf) != T_ARRAY) continue;
|
||||||
*(key + real_len) = NUM2CHR(RARRAY_PTR(inf)[0]);
|
|
||||||
*(type + real_len) = NUM2CHR(RARRAY_PTR(inf)[1]);
|
|
||||||
|
|
||||||
*(ivar + real_len)
|
if (TYPE(RARRAY_PTR(inf)[0]) == T_STRING) {
|
||||||
= rb_intern(
|
chr = *(RSTRING_PTR(RARRAY_PTR(inf)[0]));
|
||||||
RSTRING_PTR(
|
} else {
|
||||||
rb_str_cat2(rb_str_new2("@"),
|
chr = NUM2CHR(RARRAY_PTR(inf)[0]);
|
||||||
rb_id2name(SYM2ID(RARRAY_PTR(inf)[2])))
|
}
|
||||||
)
|
if (TYPE(RARRAY_PTR(inf)[1]) == T_STRING) {
|
||||||
);
|
subst_inf->type[chr] = *(RSTRING_PTR(RARRAY_PTR(inf)[1]));
|
||||||
|
} else {
|
||||||
rb_attr(self, SYM2ID(RARRAY_PTR(inf)[2]), 1, 0, Qtrue);
|
subst_inf->type[chr] = NUM2CHR(RARRAY_PTR(inf)[1]);
|
||||||
real_len++;
|
}
|
||||||
|
|
||||||
|
subst_inf->full_subst_length += 3;
|
||||||
|
|
||||||
|
id = SYM2ID(RARRAY_PTR(inf)[2]);
|
||||||
|
subst_inf->ivar[chr] = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2("@"), rb_id2name(id))));
|
||||||
|
|
||||||
|
rb_attr(self, id, 1, 0, Qtrue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* longkeys : array of [name, type, ivar]
|
||||||
|
* name ==> longname key string
|
||||||
|
* type ==> char code or string
|
||||||
|
* ivar ==> symbol
|
||||||
|
*/
|
||||||
|
len = RARRAY_LEN(longkey_inf);
|
||||||
|
for(idx = 0; idx < len; idx++) {
|
||||||
|
inf = RARRAY_PTR(longkey_inf)[idx];
|
||||||
|
if (TYPE(inf) != T_ARRAY) continue;
|
||||||
|
|
||||||
|
chr = (unsigned char)(0x80 + idx);
|
||||||
|
subst_inf->keylen[chr] = RSTRING_LEN(RARRAY_PTR(inf)[0]);
|
||||||
|
#if HAVE_STRNDUP
|
||||||
|
subst_inf->key[chr] = strndup(RSTRING_PTR(RARRAY_PTR(inf)[0]),
|
||||||
|
RSTRING_LEN(RARRAY_PTR(inf)[0]));
|
||||||
|
#else
|
||||||
|
subst_inf->key[chr] = malloc(RSTRING_LEN(RARRAY_PTR(inf)[0]) + 1);
|
||||||
|
if (subst_inf->key[chr]) {
|
||||||
|
strncpy(subst_inf->key[chr], RSTRING_PTR(RARRAY_PTR(inf)[0]),
|
||||||
|
RSTRING_LEN(RARRAY_PTR(inf)[0]) + 1);
|
||||||
|
subst_inf->key[chr][RSTRING_LEN(RARRAY_PTR(inf)[0])] = '\0';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (TYPE(RARRAY_PTR(inf)[1]) == T_STRING) {
|
||||||
|
subst_inf->type[chr] = *(RSTRING_PTR(RARRAY_PTR(inf)[1]));
|
||||||
|
} else {
|
||||||
|
subst_inf->type[chr] = NUM2CHR(RARRAY_PTR(inf)[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
subst_inf->full_subst_length += (subst_inf->keylen[chr] + 2);
|
||||||
|
|
||||||
|
id = SYM2ID(RARRAY_PTR(inf)[2]);
|
||||||
|
subst_inf->ivar[chr] = rb_intern(RSTRING_PTR(rb_str_cat2(rb_str_new2("@"), rb_id2name(id))));
|
||||||
|
|
||||||
|
rb_attr(self, id, 1, 0, Qtrue);
|
||||||
}
|
}
|
||||||
*(key + real_len) = '\0';
|
|
||||||
*(type + real_len) = '\0';
|
|
||||||
subst_inf->size = real_len;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* procs : array of [type, proc]
|
* procs : array of [type, proc]
|
||||||
* type ==> char code
|
* type ==> char code or string
|
||||||
* proc ==> proc/method/obj (must respond to 'call')
|
* proc ==> proc/method/obj (must respond to 'call')
|
||||||
*/
|
*/
|
||||||
len = RARRAY_LEN(proc_inf);
|
len = RARRAY_LEN(proc_inf);
|
||||||
for(idx = 0; idx < len; idx++) {
|
for(idx = 0; idx < len; idx++) {
|
||||||
inf = RARRAY_PTR(proc_inf)[idx];
|
inf = RARRAY_PTR(proc_inf)[idx];
|
||||||
if (TYPE(inf) != T_ARRAY) continue;
|
if (TYPE(inf) != T_ARRAY) continue;
|
||||||
rb_hash_aset(proc, RARRAY_PTR(inf)[0], RARRAY_PTR(inf)[1]);
|
rb_hash_aset(subst_inf->proc,
|
||||||
|
((TYPE(RARRAY_PTR(inf)[0]) == T_STRING)?
|
||||||
|
INT2FIX(*(RSTRING_PTR(RARRAY_PTR(inf)[0]))) :
|
||||||
|
RARRAY_PTR(inf)[0]),
|
||||||
|
RARRAY_PTR(inf)[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_const_set(self, ID_SUBST_INFO,
|
rb_const_set(self, ID_SUBST_INFO,
|
||||||
|
@ -1424,10 +1585,11 @@ cbsubst_scan_args(self, arg_key, val_ary)
|
||||||
{
|
{
|
||||||
struct cbsubst_info *inf;
|
struct cbsubst_info *inf;
|
||||||
int idx;
|
int idx;
|
||||||
int len = RARRAY_LEN(val_ary);
|
unsigned char *keyptr = (unsigned char*)RSTRING_PTR(arg_key);
|
||||||
char c;
|
int keylen = RSTRING_LEN(arg_key);
|
||||||
char *ptr;
|
int vallen = RARRAY_LEN(val_ary);
|
||||||
volatile VALUE dst = rb_ary_new2(len);
|
unsigned char type_chr;
|
||||||
|
volatile VALUE dst = rb_ary_new2(vallen);
|
||||||
volatile VALUE proc;
|
volatile VALUE proc;
|
||||||
int thr_crit_bup;
|
int thr_crit_bup;
|
||||||
VALUE old_gc;
|
VALUE old_gc;
|
||||||
|
@ -1440,25 +1602,24 @@ cbsubst_scan_args(self, arg_key, val_ary)
|
||||||
Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
|
Data_Get_Struct(rb_const_get(self, ID_SUBST_INFO),
|
||||||
struct cbsubst_info, inf);
|
struct cbsubst_info, inf);
|
||||||
|
|
||||||
for(idx = 0; idx < len; idx++) {
|
for(idx = 0; idx < vallen; idx++) {
|
||||||
if (idx >= RSTRING_LEN(arg_key)) {
|
if (idx >= keylen) {
|
||||||
proc = Qnil;
|
proc = Qnil;
|
||||||
} else if (*(RSTRING_PTR(arg_key) + idx) == ' ') {
|
} else if (*(keyptr + idx) == ' ') {
|
||||||
proc = Qnil;
|
proc = Qnil;
|
||||||
} else {
|
} else {
|
||||||
ptr = strchr(inf->key, *(RSTRING_PTR(arg_key) + idx));
|
if (type_chr = inf->type[*(keyptr + idx)]) {
|
||||||
if (ptr == (char*)NULL) {
|
proc = rb_hash_aref(inf->proc, INT2FIX((int)type_chr));
|
||||||
proc = Qnil;
|
|
||||||
} else {
|
} else {
|
||||||
c = *(inf->type + (ptr - inf->key));
|
proc = Qnil;
|
||||||
proc = rb_hash_aref(inf->proc, INT2FIX(c));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NIL_P(proc)) {
|
if (NIL_P(proc)) {
|
||||||
rb_ary_push(dst, RARRAY_PTR(val_ary)[idx]);
|
rb_ary_push(dst, RARRAY_PTR(val_ary)[idx]);
|
||||||
} else {
|
} else {
|
||||||
rb_ary_push(dst, rb_funcall(proc, ID_call, 1, RARRAY_PTR(val_ary)[idx]));
|
rb_ary_push(dst, rb_funcall(proc, ID_call, 1,
|
||||||
|
RARRAY_PTR(val_ary)[idx]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1543,6 +1704,8 @@ Init_tkutil()
|
||||||
ID_SUBST_INFO = rb_intern("SUBST_INFO");
|
ID_SUBST_INFO = rb_intern("SUBST_INFO");
|
||||||
rb_define_singleton_method(cCB_SUBST, "ret_val", cbsubst_ret_val, 1);
|
rb_define_singleton_method(cCB_SUBST, "ret_val", cbsubst_ret_val, 1);
|
||||||
rb_define_singleton_method(cCB_SUBST, "scan_args", cbsubst_scan_args, 2);
|
rb_define_singleton_method(cCB_SUBST, "scan_args", cbsubst_scan_args, 2);
|
||||||
|
rb_define_singleton_method(cCB_SUBST, "_sym2subst",
|
||||||
|
cbsubst_sym_to_subst, 1);
|
||||||
rb_define_singleton_method(cCB_SUBST, "subst_arg",
|
rb_define_singleton_method(cCB_SUBST, "subst_arg",
|
||||||
cbsubst_get_subst_arg, -1);
|
cbsubst_get_subst_arg, -1);
|
||||||
rb_define_singleton_method(cCB_SUBST, "_get_subst_key",
|
rb_define_singleton_method(cCB_SUBST, "_get_subst_key",
|
||||||
|
@ -1550,7 +1713,7 @@ Init_tkutil()
|
||||||
rb_define_singleton_method(cCB_SUBST, "_get_all_subst_keys",
|
rb_define_singleton_method(cCB_SUBST, "_get_all_subst_keys",
|
||||||
cbsubst_get_all_subst_keys, 0);
|
cbsubst_get_all_subst_keys, 0);
|
||||||
rb_define_singleton_method(cCB_SUBST, "_setup_subst_table",
|
rb_define_singleton_method(cCB_SUBST, "_setup_subst_table",
|
||||||
cbsubst_table_setup, 2);
|
cbsubst_table_setup, -1);
|
||||||
rb_define_singleton_method(cCB_SUBST, "_get_extra_args_tbl",
|
rb_define_singleton_method(cCB_SUBST, "_get_extra_args_tbl",
|
||||||
cbsubst_get_extra_args_tbl, 0);
|
cbsubst_get_extra_args_tbl, 0);
|
||||||
rb_define_singleton_method(cCB_SUBST, "_define_attribute_aliases",
|
rb_define_singleton_method(cCB_SUBST, "_define_attribute_aliases",
|
||||||
|
|
|
@ -3111,6 +3111,8 @@ gzreader_gets(argc, argv, obj)
|
||||||
if (NIL_P(rs)) {
|
if (NIL_P(rs)) {
|
||||||
dst = gzfile_read_all(gz);
|
dst = gzfile_read_all(gz);
|
||||||
if (RSTRING(dst)->len != 0) gz->lineno++;
|
if (RSTRING(dst)->len != 0) gz->lineno++;
|
||||||
|
else
|
||||||
|
return Qnil;
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
213
file.c
213
file.c
|
@ -15,6 +15,10 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "missing/file.h"
|
#include "missing/file.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#include <windows.h>
|
||||||
|
#include <sys/cygwin.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ruby.h"
|
#include "ruby.h"
|
||||||
#include "rubyio.h"
|
#include "rubyio.h"
|
||||||
|
@ -2310,6 +2314,18 @@ rb_file_s_umask(argc, argv)
|
||||||
#define isdirsep(x) ((x) == '/')
|
#define isdirsep(x) ((x) == '/')
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
|
#define USE_NTFS 1
|
||||||
|
#else
|
||||||
|
#define USE_NTFS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if USE_NTFS
|
||||||
|
#define istrailinggabage(x) ((x) == '.' || (x) == ' ')
|
||||||
|
#else
|
||||||
|
#define istrailinggabage(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CharNext /* defined as CharNext[AW] on Windows. */
|
#ifndef CharNext /* defined as CharNext[AW] on Windows. */
|
||||||
# if defined(DJGPP)
|
# if defined(DJGPP)
|
||||||
# define CharNext(p) ((p) + mblen(p, MB_CUR_MAX))
|
# define CharNext(p) ((p) + mblen(p, MB_CUR_MAX))
|
||||||
|
@ -2454,6 +2470,30 @@ rb_path_end(path)
|
||||||
return chompdirsep(path);
|
return chompdirsep(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if USE_NTFS
|
||||||
|
static char *
|
||||||
|
ntfs_tail(const char *path)
|
||||||
|
{
|
||||||
|
while (*path && *path != ':') {
|
||||||
|
if (istrailinggabage(*path)) {
|
||||||
|
const char *last = path++;
|
||||||
|
while (istrailinggabage(*path)) path++;
|
||||||
|
if (!*path || *path == ':') return (char *)last;
|
||||||
|
}
|
||||||
|
else if (isdirsep(*path)) {
|
||||||
|
const char *last = path++;
|
||||||
|
while (isdirsep(*path)) path++;
|
||||||
|
if (!*path) return (char *)last;
|
||||||
|
if (*path == ':') path++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
path = CharNext(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (char *)path;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BUFCHECK(cond) do {\
|
#define BUFCHECK(cond) do {\
|
||||||
long bdiff = p - buf;\
|
long bdiff = p - buf;\
|
||||||
while (cond) {\
|
while (cond) {\
|
||||||
|
@ -2480,7 +2520,8 @@ static VALUE
|
||||||
file_expand_path(fname, dname, result)
|
file_expand_path(fname, dname, result)
|
||||||
VALUE fname, dname, result;
|
VALUE fname, dname, result;
|
||||||
{
|
{
|
||||||
char *s, *buf, *b, *p, *pend, *root;
|
const char *s, *b;
|
||||||
|
char *buf, *p, *pend, *root;
|
||||||
long buflen, dirlen;
|
long buflen, dirlen;
|
||||||
int tainted;
|
int tainted;
|
||||||
|
|
||||||
|
@ -2621,15 +2662,21 @@ file_expand_path(fname, dname, result)
|
||||||
case '.':
|
case '.':
|
||||||
if (*(s+1) == '\0' || isdirsep(*(s+1))) {
|
if (*(s+1) == '\0' || isdirsep(*(s+1))) {
|
||||||
/* We must go back to the parent */
|
/* We must go back to the parent */
|
||||||
|
char *n;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
if (!(b = strrdirsep(root))) {
|
if (!(n = strrdirsep(root))) {
|
||||||
*p = '/';
|
*p = '/';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = b;
|
p = n;
|
||||||
}
|
}
|
||||||
b = ++s;
|
b = ++s;
|
||||||
}
|
}
|
||||||
|
#if USE_NTFS
|
||||||
|
else {
|
||||||
|
do *++s; while (istrailinggabage(*s));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
#if defined DOSISH || defined __CYGWIN__
|
#if defined DOSISH || defined __CYGWIN__
|
||||||
|
@ -2642,6 +2689,19 @@ file_expand_path(fname, dname, result)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if USE_NTFS
|
||||||
|
else {
|
||||||
|
--s;
|
||||||
|
case ' ': {
|
||||||
|
const char *e = s;
|
||||||
|
while (istrailinggabage(*s)) s++;
|
||||||
|
if (!*s) {
|
||||||
|
s = e;
|
||||||
|
goto endpath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case '/':
|
case '/':
|
||||||
#if defined DOSISH || defined __CYGWIN__
|
#if defined DOSISH || defined __CYGWIN__
|
||||||
|
@ -2664,15 +2724,79 @@ file_expand_path(fname, dname, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s > b) {
|
if (s > b) {
|
||||||
|
#if USE_NTFS
|
||||||
|
endpath:
|
||||||
|
if (s > b + 6 && strncasecmp(s - 6, ":$DATA", 6) == 0) {
|
||||||
|
/* alias of stream */
|
||||||
|
/* get rid of a bug of x64 VC++ */
|
||||||
|
if (*(s-7) == ':') s -= 7; /* prime */
|
||||||
|
else if (memchr(b, ':', s - 6 - b)) s -= 6; /* alternative */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
BUFCHECK(bdiff + (s-b) >= buflen);
|
BUFCHECK(bdiff + (s-b) >= buflen);
|
||||||
memcpy(++p, b, s-b);
|
memcpy(++p, b, s-b);
|
||||||
p += s-b;
|
p += s-b;
|
||||||
}
|
}
|
||||||
if (p == skiproot(buf) - 1) p++;
|
if (p == skiproot(buf) - 1) p++;
|
||||||
|
buflen = p - buf;
|
||||||
|
|
||||||
|
#if USE_NTFS
|
||||||
|
*p = '\0';
|
||||||
|
if (1 &&
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
!(buf[0] == '/' && !buf[1]) &&
|
||||||
|
#endif
|
||||||
|
!strpbrk(b = buf, "*?")) {
|
||||||
|
size_t len;
|
||||||
|
WIN32_FIND_DATA wfd;
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
int lnk_added = 0, is_symlink = 0;
|
||||||
|
struct stat st;
|
||||||
|
char w32buf[MAXPATHLEN], sep = 0;
|
||||||
|
p = 0;
|
||||||
|
if (lstat(buf, &st) == 0 && S_ISLNK(st.st_mode)) {
|
||||||
|
is_symlink = 1;
|
||||||
|
p = strrdirsep(buf);
|
||||||
|
if (!p) p = skipprefix(buf);
|
||||||
|
if (p) {
|
||||||
|
sep = *p;
|
||||||
|
*p = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cygwin_conv_to_win32_path(buf, w32buf) == 0) {
|
||||||
|
b = w32buf;
|
||||||
|
}
|
||||||
|
if (p) *p = sep;
|
||||||
|
else p = buf;
|
||||||
|
if (is_symlink && b == w32buf) {
|
||||||
|
len = strlen(p);
|
||||||
|
if (len > 4 && strcasecmp(p + len - 4, ".lnk") != 0) {
|
||||||
|
lnk_added = 1;
|
||||||
|
strlcat(w32buf, ".lnk", sizeof(w32buf));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
HANDLE h = FindFirstFile(b, &wfd);
|
||||||
|
if (h != INVALID_HANDLE_VALUE) {
|
||||||
|
FindClose(h);
|
||||||
|
p = strrdirsep(buf);
|
||||||
|
len = strlen(wfd.cFileName);
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
if (lnk_added && len > 4 &&
|
||||||
|
strcasecmp(wfd.cFileName + len - 4, ".lnk") == 0) {
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!p) p = buf;
|
||||||
|
buflen = ++p - buf + len;
|
||||||
|
rb_str_resize(result, buflen);
|
||||||
|
memcpy(p, wfd.cFileName, len + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tainted) OBJ_TAINT(result);
|
if (tainted) OBJ_TAINT(result);
|
||||||
RSTRING(result)->len = p - buf;
|
rb_str_set_len(result, buflen);
|
||||||
*p = '\0';
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2716,23 +2840,31 @@ rb_file_s_expand_path(argc, argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rmext(p, e)
|
rmext(p, l1, e)
|
||||||
const char *p, *e;
|
const char *p, *e;
|
||||||
|
int l1;
|
||||||
{
|
{
|
||||||
int l1, l2;
|
int l2;
|
||||||
|
|
||||||
if (!e) return 0;
|
if (!e) return 0;
|
||||||
|
|
||||||
l1 = chompdirsep(p) - p;
|
|
||||||
l2 = strlen(e);
|
l2 = strlen(e);
|
||||||
if (l2 == 2 && e[1] == '*') {
|
if (l2 == 2 && e[1] == '*') {
|
||||||
e = strrchr(p, *e);
|
unsigned char c = *e;
|
||||||
if (!e) return 0;
|
e = p + l1;
|
||||||
|
do {
|
||||||
|
if (e <= p) return 0;
|
||||||
|
} while (*--e != c);
|
||||||
return e - p;
|
return e - p;
|
||||||
}
|
}
|
||||||
if (l1 < l2) return l1;
|
if (l1 < l2) return l1;
|
||||||
|
|
||||||
if (strncmp(p+l1-l2, e, l2) == 0) {
|
#if CASEFOLD_FILESYSTEM
|
||||||
|
#define fncomp strncasecmp
|
||||||
|
#else
|
||||||
|
#define fncomp strncmp
|
||||||
|
#endif
|
||||||
|
if (fncomp(p+l1-l2, e, l2) == 0) {
|
||||||
return l1-l2;
|
return l1-l2;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2762,7 +2894,7 @@ rb_file_s_basename(argc, argv)
|
||||||
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
|
#if defined DOSISH_DRIVE_LETTER || defined DOSISH_UNC
|
||||||
char *root;
|
char *root;
|
||||||
#endif
|
#endif
|
||||||
int f;
|
int f, n;
|
||||||
|
|
||||||
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
|
if (rb_scan_args(argc, argv, "11", &fname, &fext) == 2) {
|
||||||
StringValue(fext);
|
StringValue(fext);
|
||||||
|
@ -2796,18 +2928,22 @@ rb_file_s_basename(argc, argv)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (!(p = strrdirsep(name))) {
|
else {
|
||||||
if (NIL_P(fext) || !(f = rmext(name, StringValueCStr(fext)))) {
|
if (!(p = strrdirsep(name))) {
|
||||||
f = chompdirsep(name) - name;
|
|
||||||
if (f == RSTRING(fname)->len) return fname;
|
|
||||||
}
|
|
||||||
p = name;
|
p = name;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while (isdirsep(*p)) p++; /* skip last / */
|
while (isdirsep(*p)) p++; /* skip last / */
|
||||||
if (NIL_P(fext) || !(f = rmext(p, StringValueCStr(fext)))) {
|
|
||||||
f = chompdirsep(p) - p;
|
|
||||||
}
|
}
|
||||||
|
#if USE_NTFS
|
||||||
|
n = ntfs_tail(p) - p;
|
||||||
|
#else
|
||||||
|
n = chompdirsep(p) - p;
|
||||||
|
#endif
|
||||||
|
if (NIL_P(fext) || !(f = rmext(p, n, StringValueCStr(fext)))) {
|
||||||
|
f = n;
|
||||||
|
}
|
||||||
|
if (f == RSTRING_LEN(fname)) return fname;
|
||||||
}
|
}
|
||||||
basename = rb_str_new(p, f);
|
basename = rb_str_new(p, f);
|
||||||
OBJ_INFECT(basename, fname);
|
OBJ_INFECT(basename, fname);
|
||||||
|
@ -2883,7 +3019,7 @@ static VALUE
|
||||||
rb_file_s_extname(klass, fname)
|
rb_file_s_extname(klass, fname)
|
||||||
VALUE klass, fname;
|
VALUE klass, fname;
|
||||||
{
|
{
|
||||||
char *name, *p, *e;
|
const char *name, *p, *e;
|
||||||
VALUE extname;
|
VALUE extname;
|
||||||
|
|
||||||
name = StringValueCStr(fname);
|
name = StringValueCStr(fname);
|
||||||
|
@ -2891,12 +3027,39 @@ rb_file_s_extname(klass, fname)
|
||||||
if (!p)
|
if (!p)
|
||||||
p = name;
|
p = name;
|
||||||
else
|
else
|
||||||
p++;
|
name = ++p;
|
||||||
|
|
||||||
e = strrchr(p, '.'); /* get the last dot of the last component */
|
e = 0;
|
||||||
if (!e || e == p || !e[1]) /* no dot, or the only dot is first or end? */
|
while (*p) {
|
||||||
return rb_str_new2("");
|
if (*p == '.' || istrailinggabage(*p)) {
|
||||||
extname = rb_str_new(e, chompdirsep(e) - e); /* keep the dot, too! */
|
#if USE_NTFS
|
||||||
|
const char *last = p++, *dot = last;
|
||||||
|
while (istrailinggabage(*p)) {
|
||||||
|
if (*p == '.') dot = p;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (!*p || *p == ':') {
|
||||||
|
p = last;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
e = dot;
|
||||||
|
continue;
|
||||||
|
#else
|
||||||
|
e = p; /* get the last dot of the last component */
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if USE_NTFS
|
||||||
|
else if (*p == ':') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (isdirsep(*p))
|
||||||
|
break;
|
||||||
|
p = CharNext(p);
|
||||||
|
}
|
||||||
|
if (!e || e == name || e+1 == p) /* no dot, or the only dot is first or end? */
|
||||||
|
return rb_str_new(0, 0);
|
||||||
|
extname = rb_str_new(e, p - e); /* keep the dot, too! */
|
||||||
OBJ_INFECT(extname, fname);
|
OBJ_INFECT(extname, fname);
|
||||||
return extname;
|
return extname;
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,13 +227,15 @@ class SimpleDelegator<Delegator
|
||||||
|
|
||||||
# Clone support for the object returned by \_\_getobj\_\_.
|
# Clone support for the object returned by \_\_getobj\_\_.
|
||||||
def clone
|
def clone
|
||||||
super
|
new = super
|
||||||
__setobj__(__getobj__.clone)
|
new.__setobj__(__getobj__.clone)
|
||||||
|
new
|
||||||
end
|
end
|
||||||
# Duplication support for the object returned by \_\_getobj\_\_.
|
# Duplication support for the object returned by \_\_getobj\_\_.
|
||||||
def dup(obj)
|
def dup
|
||||||
super
|
new = super
|
||||||
__setobj__(__getobj__.dup)
|
new.__setobj__(__getobj__.clone)
|
||||||
|
new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -280,12 +282,14 @@ def DelegateClass(superclass)
|
||||||
@_dc_obj = obj
|
@_dc_obj = obj
|
||||||
end
|
end
|
||||||
def clone # :nodoc:
|
def clone # :nodoc:
|
||||||
super
|
new = super
|
||||||
__setobj__(__getobj__.clone)
|
new.__setobj__(__getobj__.clone)
|
||||||
|
new
|
||||||
end
|
end
|
||||||
def dup # :nodoc:
|
def dup # :nodoc:
|
||||||
super
|
new = super
|
||||||
__setobj__(__getobj__.dup)
|
new.__setobj__(__getobj__.clone)
|
||||||
|
new
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
for method in methods
|
for method in methods
|
||||||
|
|
|
@ -520,10 +520,15 @@ module Net
|
||||||
# value specified when this instance was created will be
|
# value specified when this instance was created will be
|
||||||
# used, or, failing that, the default value of 0 seconds,
|
# used, or, failing that, the default value of 0 seconds,
|
||||||
# which means not to wait for more input.
|
# which means not to wait for more input.
|
||||||
|
# FailEOF:: if true, when the remote end closes the connection then an
|
||||||
|
# EOFError will be raised. Otherwise, defaults to the old
|
||||||
|
# behaviour that the function will return whatever data
|
||||||
|
# has been received already, or nil if nothing was received.
|
||||||
#
|
#
|
||||||
def waitfor(options) # :yield: recvdata
|
def waitfor(options) # :yield: recvdata
|
||||||
time_out = @options["Timeout"]
|
time_out = @options["Timeout"]
|
||||||
waittime = @options["Waittime"]
|
waittime = @options["Waittime"]
|
||||||
|
fail_eof = @options["FailEOF"]
|
||||||
|
|
||||||
if options.kind_of?(Hash)
|
if options.kind_of?(Hash)
|
||||||
prompt = if options.has_key?("Match")
|
prompt = if options.has_key?("Match")
|
||||||
|
@ -535,6 +540,7 @@ module Net
|
||||||
end
|
end
|
||||||
time_out = options["Timeout"] if options.has_key?("Timeout")
|
time_out = options["Timeout"] if options.has_key?("Timeout")
|
||||||
waittime = options["Waittime"] if options.has_key?("Waittime")
|
waittime = options["Waittime"] if options.has_key?("Waittime")
|
||||||
|
fail_eof = options["FailEOF"] if options.has_key?("FailEOF")
|
||||||
else
|
else
|
||||||
prompt = options
|
prompt = options
|
||||||
end
|
end
|
||||||
|
@ -559,7 +565,8 @@ module Net
|
||||||
Integer(c.rindex(/#{IAC}#{SB}/no))
|
Integer(c.rindex(/#{IAC}#{SB}/no))
|
||||||
buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/no)])
|
buf = preprocess(c[0 ... c.rindex(/#{IAC}#{SB}/no)])
|
||||||
rest = c[c.rindex(/#{IAC}#{SB}/no) .. -1]
|
rest = c[c.rindex(/#{IAC}#{SB}/no) .. -1]
|
||||||
elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no)
|
elsif pt = c.rindex(/#{IAC}[^#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]?\z/no) ||
|
||||||
|
c.rindex(/\r\z/no)
|
||||||
buf = preprocess(c[0 ... pt])
|
buf = preprocess(c[0 ... pt])
|
||||||
rest = c[pt .. -1]
|
rest = c[pt .. -1]
|
||||||
else
|
else
|
||||||
|
@ -571,14 +578,21 @@ module Net
|
||||||
#
|
#
|
||||||
# We cannot use preprocess() on this data, because that
|
# We cannot use preprocess() on this data, because that
|
||||||
# method makes some Telnetmode-specific assumptions.
|
# method makes some Telnetmode-specific assumptions.
|
||||||
buf = c
|
buf = rest + c
|
||||||
buf.gsub!(/#{EOL}/no, "\n") unless @options["Binmode"]
|
|
||||||
rest = ''
|
rest = ''
|
||||||
|
unless @options["Binmode"]
|
||||||
|
if pt = buf.rindex(/\r\z/no)
|
||||||
|
buf = buf[0 ... pt]
|
||||||
|
rest = buf[pt .. -1]
|
||||||
|
end
|
||||||
|
buf.gsub!(/#{EOL}/no, "\n")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
@log.print(buf) if @options.has_key?("Output_log")
|
@log.print(buf) if @options.has_key?("Output_log")
|
||||||
line += buf
|
line += buf
|
||||||
yield buf if block_given?
|
yield buf if block_given?
|
||||||
rescue EOFError # End of file reached
|
rescue EOFError # End of file reached
|
||||||
|
raise if fail_eof
|
||||||
if line == ''
|
if line == ''
|
||||||
line = nil
|
line = nil
|
||||||
yield nil if block_given?
|
yield nil if block_given?
|
||||||
|
|
|
@ -58,7 +58,7 @@ module WEBrick
|
||||||
|
|
||||||
def redirect_to_directory_uri(req, res)
|
def redirect_to_directory_uri(req, res)
|
||||||
if req.path[-1] != ?/
|
if req.path[-1] != ?/
|
||||||
location = req.path + "/"
|
location = WEBrick::HTTPUtils.escape_path(req.path + "/")
|
||||||
if req.query_string && req.query_string.size > 0
|
if req.query_string && req.query_string.size > 0
|
||||||
location << "?" << req.query_string
|
location << "?" << req.query_string
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,7 +39,9 @@ dir = File::dirname(ENV["SCRIPT_FILENAME"])
|
||||||
Dir::chdir dir
|
Dir::chdir dir
|
||||||
|
|
||||||
if interpreter = ARGV[0]
|
if interpreter = ARGV[0]
|
||||||
exec(interpreter, ENV["SCRIPT_FILENAME"])
|
argv = ARGV.dup
|
||||||
|
argv << ENV["SCRIPT_FILENAME"]
|
||||||
|
exec(*argv)
|
||||||
# NOTREACHED
|
# NOTREACHED
|
||||||
end
|
end
|
||||||
exec ENV["SCRIPT_FILENAME"]
|
exec ENV["SCRIPT_FILENAME"]
|
||||||
|
|
|
@ -199,26 +199,38 @@ module WEBrick
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def trailing_pathsep?(path)
|
||||||
|
# check for trailing path separator:
|
||||||
|
# File.dirname("/aaaa/bbbb/") #=> "/aaaa")
|
||||||
|
# File.dirname("/aaaa/bbbb/x") #=> "/aaaa/bbbb")
|
||||||
|
# File.dirname("/aaaa/bbbb") #=> "/aaaa")
|
||||||
|
# File.dirname("/aaaa/bbbbx") #=> "/aaaa")
|
||||||
|
return File.dirname(path) != File.dirname(path+"x")
|
||||||
|
end
|
||||||
|
|
||||||
def prevent_directory_traversal(req, res)
|
def prevent_directory_traversal(req, res)
|
||||||
# Preventing directory traversal on DOSISH platforms;
|
# Preventing directory traversal on Windows platforms;
|
||||||
# Backslashes (0x5c) in path_info are not interpreted as special
|
# Backslashes (0x5c) in path_info are not interpreted as special
|
||||||
# character in URI notation. So the value of path_info should be
|
# character in URI notation. So the value of path_info should be
|
||||||
# normalize before accessing to the filesystem.
|
# normalize before accessing to the filesystem.
|
||||||
if File::ALT_SEPARATOR
|
|
||||||
|
if trailing_pathsep?(req.path_info)
|
||||||
# File.expand_path removes the trailing path separator.
|
# File.expand_path removes the trailing path separator.
|
||||||
# Adding a character is a workaround to save it.
|
# Adding a character is a workaround to save it.
|
||||||
# File.expand_path("/aaa/") #=> "/aaa"
|
# File.expand_path("/aaa/") #=> "/aaa"
|
||||||
# File.expand_path("/aaa/" + "x") #=> "/aaa/x"
|
# File.expand_path("/aaa/" + "x") #=> "/aaa/x"
|
||||||
expanded = File.expand_path(req.path_info + "x")
|
expanded = File.expand_path(req.path_info + "x")
|
||||||
expanded[-1, 1] = "" # remove trailing "x"
|
expanded.chop! # remove trailing "x"
|
||||||
req.path_info = expanded
|
else
|
||||||
|
expanded = File.expand_path(req.path_info)
|
||||||
end
|
end
|
||||||
|
req.path_info = expanded
|
||||||
end
|
end
|
||||||
|
|
||||||
def exec_handler(req, res)
|
def exec_handler(req, res)
|
||||||
raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
|
raise HTTPStatus::NotFound, "`#{req.path}' not found" unless @root
|
||||||
if set_filename(req, res)
|
if set_filename(req, res)
|
||||||
handler = get_handler(req)
|
handler = get_handler(req, res)
|
||||||
call_callback(:HandlerCallback, req, res)
|
call_callback(:HandlerCallback, req, res)
|
||||||
h = handler.get_instance(@config, res.filename)
|
h = handler.get_instance(@config, res.filename)
|
||||||
h.service(req, res)
|
h.service(req, res)
|
||||||
|
@ -228,9 +240,13 @@ module WEBrick
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_handler(req)
|
def get_handler(req, res)
|
||||||
suffix1 = (/\.(\w+)$/ =~ req.script_name) && $1.downcase
|
suffix1 = (/\.(\w+)\z/ =~ res.filename) && $1.downcase
|
||||||
suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ req.script_name) && $1.downcase
|
if /\.(\w+)\.([\w\-]+)\z/ =~ res.filename
|
||||||
|
if @options[:AcceptableLanguages].include?($2.downcase)
|
||||||
|
suffix2 = $1.downcase
|
||||||
|
end
|
||||||
|
end
|
||||||
handler_table = @options[:HandlerTable]
|
handler_table = @options[:HandlerTable]
|
||||||
return handler_table[suffix1] || handler_table[suffix2] ||
|
return handler_table[suffix1] || handler_table[suffix2] ||
|
||||||
HandlerTable[suffix1] || HandlerTable[suffix2] ||
|
HandlerTable[suffix1] || HandlerTable[suffix2] ||
|
||||||
|
@ -243,15 +259,13 @@ module WEBrick
|
||||||
|
|
||||||
path_info.unshift("") # dummy for checking @root dir
|
path_info.unshift("") # dummy for checking @root dir
|
||||||
while base = path_info.first
|
while base = path_info.first
|
||||||
check_filename(req, res, base)
|
|
||||||
break if base == "/"
|
break if base == "/"
|
||||||
break unless File.directory?(res.filename + base)
|
break unless File.directory?(File.expand_path(res.filename + base))
|
||||||
shift_path_info(req, res, path_info)
|
shift_path_info(req, res, path_info)
|
||||||
call_callback(:DirectoryCallback, req, res)
|
call_callback(:DirectoryCallback, req, res)
|
||||||
end
|
end
|
||||||
|
|
||||||
if base = path_info.first
|
if base = path_info.first
|
||||||
check_filename(req, res, base)
|
|
||||||
if base == "/"
|
if base == "/"
|
||||||
if file = search_index_file(req, res)
|
if file = search_index_file(req, res)
|
||||||
shift_path_info(req, res, path_info, file)
|
shift_path_info(req, res, path_info, file)
|
||||||
|
@ -272,12 +286,10 @@ module WEBrick
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_filename(req, res, name)
|
def check_filename(req, res, name)
|
||||||
@options[:NondisclosureName].each{|pattern|
|
if nondisclosure_name?(name) || windows_ambiguous_name?(name)
|
||||||
if File.fnmatch("/#{pattern}", name, File::FNM_CASEFOLD)
|
|
||||||
@logger.warn("the request refers nondisclosure name `#{name}'.")
|
@logger.warn("the request refers nondisclosure name `#{name}'.")
|
||||||
raise HTTPStatus::NotFound, "`#{req.path}' not found."
|
raise HTTPStatus::NotFound, "`#{req.path}' not found."
|
||||||
end
|
end
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def shift_path_info(req, res, path_info, base=nil)
|
def shift_path_info(req, res, path_info, base=nil)
|
||||||
|
@ -285,7 +297,8 @@ module WEBrick
|
||||||
base = base || tmp
|
base = base || tmp
|
||||||
req.path_info = path_info.join
|
req.path_info = path_info.join
|
||||||
req.script_name << base
|
req.script_name << base
|
||||||
res.filename << base
|
res.filename = File.expand_path(res.filename + base)
|
||||||
|
check_filename(req, res, File.basename(res.filename))
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_index_file(req, res)
|
def search_index_file(req, res)
|
||||||
|
@ -325,6 +338,12 @@ module WEBrick
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def windows_ambiguous_name?(name)
|
||||||
|
return true if /[. ]+\z/ =~ name
|
||||||
|
return true if /::\$DATA\z/ =~ name
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
def nondisclosure_name?(name)
|
def nondisclosure_name?(name)
|
||||||
@options[:NondisclosureName].each{|pattern|
|
@options[:NondisclosureName].each{|pattern|
|
||||||
if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
|
if File.fnmatch(pattern, name, File::FNM_CASEFOLD)
|
||||||
|
@ -343,7 +362,8 @@ module WEBrick
|
||||||
list = Dir::entries(local_path).collect{|name|
|
list = Dir::entries(local_path).collect{|name|
|
||||||
next if name == "." || name == ".."
|
next if name == "." || name == ".."
|
||||||
next if nondisclosure_name?(name)
|
next if nondisclosure_name?(name)
|
||||||
st = (File::stat(local_path + name) rescue nil)
|
next if windows_ambiguous_name?(name)
|
||||||
|
st = (File::stat(File.join(local_path, name)) rescue nil)
|
||||||
if st.nil?
|
if st.nil?
|
||||||
[ name, nil, -1 ]
|
[ name, nil, -1 ]
|
||||||
elsif st.directory?
|
elsif st.directory?
|
||||||
|
@ -383,7 +403,7 @@ module WEBrick
|
||||||
res.body << "<A HREF=\"?S=#{d1}\">Size</A>\n"
|
res.body << "<A HREF=\"?S=#{d1}\">Size</A>\n"
|
||||||
res.body << "<HR>\n"
|
res.body << "<HR>\n"
|
||||||
|
|
||||||
list.unshift [ "..", File::mtime(local_path+".."), -1 ]
|
list.unshift [ "..", File::mtime(local_path+"/.."), -1 ]
|
||||||
list.each{ |name, time, size|
|
list.each{ |name, time, size|
|
||||||
if name == ".."
|
if name == ".."
|
||||||
dname = "Parent Directory"
|
dname = "Parent Directory"
|
||||||
|
|
|
@ -255,6 +255,11 @@ The variable ruby-indent-level controls the amount of indentation.
|
||||||
(make-local-variable 'add-log-current-defun-function)
|
(make-local-variable 'add-log-current-defun-function)
|
||||||
(setq add-log-current-defun-function 'ruby-add-log-current-method)
|
(setq add-log-current-defun-function 'ruby-add-log-current-method)
|
||||||
|
|
||||||
|
(set (make-local-variable 'font-lock-defaults) '((ruby-font-lock-keywords) nil nil))
|
||||||
|
(set (make-local-variable 'font-lock-keywords) ruby-font-lock-keywords)
|
||||||
|
(set (make-local-variable 'font-lock-syntax-table) ruby-font-lock-syntax-table)
|
||||||
|
(set (make-local-variable 'font-lock-syntactic-keywords) ruby-font-lock-syntactic-keywords)
|
||||||
|
|
||||||
(run-mode-hooks 'ruby-mode-hook))
|
(run-mode-hooks 'ruby-mode-hook))
|
||||||
|
|
||||||
(defun ruby-current-indentation ()
|
(defun ruby-current-indentation ()
|
||||||
|
@ -1020,24 +1025,13 @@ balanced expression is found."
|
||||||
("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
|
("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil))
|
||||||
("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))))
|
("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil))))
|
||||||
|
|
||||||
(cond ((featurep 'xemacs)
|
(if (featurep 'xemacs)
|
||||||
(put 'ruby-mode 'font-lock-defaults
|
(put 'ruby-mode 'font-lock-defaults
|
||||||
'((ruby-font-lock-keywords)
|
'((ruby-font-lock-keywords)
|
||||||
nil nil nil
|
nil nil nil
|
||||||
beginning-of-line
|
beginning-of-line
|
||||||
(font-lock-syntactic-keywords
|
(font-lock-syntactic-keywords
|
||||||
. ruby-font-lock-syntactic-keywords))))
|
. ruby-font-lock-syntactic-keywords))))
|
||||||
(t
|
|
||||||
(add-hook 'ruby-mode-hook
|
|
||||||
'(lambda ()
|
|
||||||
(make-local-variable 'font-lock-defaults)
|
|
||||||
(make-local-variable 'font-lock-keywords)
|
|
||||||
(make-local-variable 'font-lock-syntax-table)
|
|
||||||
(make-local-variable 'font-lock-syntactic-keywords)
|
|
||||||
(setq font-lock-defaults '((ruby-font-lock-keywords) nil nil))
|
|
||||||
(setq font-lock-keywords ruby-font-lock-keywords)
|
|
||||||
(setq font-lock-syntax-table ruby-font-lock-syntax-table)
|
|
||||||
(setq font-lock-syntactic-keywords ruby-font-lock-syntactic-keywords)))))
|
|
||||||
|
|
||||||
(defun ruby-font-lock-docs (limit)
|
(defun ruby-font-lock-docs (limit)
|
||||||
(if (re-search-forward "^=begin\\(\\s \\|$\\)" limit t)
|
(if (re-search-forward "^=begin\\(\\s \\|$\\)" limit t)
|
||||||
|
|
13
range.c
13
range.c
|
@ -307,24 +307,29 @@ range_step(argc, argv, range)
|
||||||
VALUE *argv;
|
VALUE *argv;
|
||||||
VALUE range;
|
VALUE range;
|
||||||
{
|
{
|
||||||
VALUE b, e, step;
|
VALUE b, e, step, tmp;
|
||||||
long unit;
|
long unit;
|
||||||
|
|
||||||
RETURN_ENUMERATOR(range, argc, argv);
|
RETURN_ENUMERATOR(range, argc, argv);
|
||||||
|
|
||||||
b = rb_ivar_get(range, id_beg);
|
b = rb_ivar_get(range, id_beg);
|
||||||
e = rb_ivar_get(range, id_end);
|
e = rb_ivar_get(range, id_end);
|
||||||
if (rb_scan_args(argc, argv, "01", &step) == 0) {
|
if (argc == 0) {
|
||||||
step = INT2FIX(1);
|
step = INT2FIX(1);
|
||||||
unit = 1;
|
unit = 1;
|
||||||
}
|
}
|
||||||
else if (FIXNUM_P(step)) {
|
else {
|
||||||
|
rb_scan_args(argc, argv, "01", &step);
|
||||||
|
tmp = rb_check_to_integer(step, "to_int");
|
||||||
|
if (!NIL_P(tmp)) {
|
||||||
|
step = tmp;
|
||||||
unit = NUM2LONG(step);
|
unit = NUM2LONG(step);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VALUE tmp = rb_to_int(step);
|
tmp = rb_funcall(rb_funcall(b, '+', 1, step), '-', 1, b);
|
||||||
unit = rb_cmpint(tmp, step, INT2FIX(0));
|
unit = rb_cmpint(tmp, step, INT2FIX(0));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (unit < 0) {
|
if (unit < 0) {
|
||||||
rb_raise(rb_eArgError, "step can't be negative");
|
rb_raise(rb_eArgError, "step can't be negative");
|
||||||
}
|
}
|
||||||
|
|
44
re.c
44
re.c
|
@ -927,6 +927,7 @@ rb_reg_search(re, str, pos, reverse)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
|
re_free_registers(®s);
|
||||||
rb_backref_set(Qnil);
|
rb_backref_set(Qnil);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -943,6 +944,7 @@ rb_reg_search(re, str, pos, reverse)
|
||||||
}
|
}
|
||||||
|
|
||||||
re_copy_registers(RMATCH(match)->regs, ®s);
|
re_copy_registers(RMATCH(match)->regs, ®s);
|
||||||
|
re_free_registers(®s);
|
||||||
RMATCH(match)->str = rb_str_new4(str);
|
RMATCH(match)->str = rb_str_new4(str);
|
||||||
rb_backref_set(match);
|
rb_backref_set(match);
|
||||||
|
|
||||||
|
@ -1219,7 +1221,6 @@ match_entry(match, n)
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* mtch.values_at([index]*) => array
|
* mtch.values_at([index]*) => array
|
||||||
* mtch.select([index]*) => array
|
|
||||||
*
|
*
|
||||||
* Uses each <i>index</i> to access the matching values, returning an array of
|
* Uses each <i>index</i> to access the matching values, returning an array of
|
||||||
* the corresponding matches.
|
* the corresponding matches.
|
||||||
|
@ -1239,6 +1240,45 @@ match_values_at(argc, argv, match)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* mtch.select{|obj| block} => array
|
||||||
|
*
|
||||||
|
* Returns an array containing match strings for which <em>block</em>
|
||||||
|
* gives <code>true</code>. MatchData#select will be removed from Ruby 1.9.
|
||||||
|
*
|
||||||
|
* m = /(.)(.)(\d+)(\d)/.match("THX1138: The Movie")
|
||||||
|
* p m.select{|x| /X/ =~ x} #=> ["HX1138", "X"]
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
match_select(argc, argv, match)
|
||||||
|
int argc;
|
||||||
|
VALUE *argv;
|
||||||
|
VALUE match;
|
||||||
|
{
|
||||||
|
if (argc > 0) {
|
||||||
|
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
struct re_registers *regs = RMATCH(match)->regs;
|
||||||
|
VALUE target = RMATCH(match)->str;
|
||||||
|
VALUE result = rb_ary_new();
|
||||||
|
int i;
|
||||||
|
int taint = OBJ_TAINTED(match);
|
||||||
|
|
||||||
|
for (i=0; i<regs->num_regs; i++) {
|
||||||
|
VALUE str = rb_str_substr(target, regs->beg[i], regs->end[i]-regs->beg[i]);
|
||||||
|
if (taint) OBJ_TAINT(str);
|
||||||
|
if (RTEST(rb_yield(str))) {
|
||||||
|
rb_ary_push(result, str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
|
@ -2326,7 +2366,7 @@ Init_Regexp()
|
||||||
rb_define_method(rb_cMatch, "[]", match_aref, -1);
|
rb_define_method(rb_cMatch, "[]", match_aref, -1);
|
||||||
rb_define_method(rb_cMatch, "captures", match_captures, 0);
|
rb_define_method(rb_cMatch, "captures", match_captures, 0);
|
||||||
rb_define_method(rb_cMatch, "values_at", match_values_at, -1);
|
rb_define_method(rb_cMatch, "values_at", match_values_at, -1);
|
||||||
rb_define_method(rb_cMatch, "select", match_values_at, -1);
|
rb_define_method(rb_cMatch, "select", match_select, -1);
|
||||||
rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0);
|
rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0);
|
||||||
rb_define_method(rb_cMatch, "post_match", rb_reg_match_post, 0);
|
rb_define_method(rb_cMatch, "post_match", rb_reg_match_post, 0);
|
||||||
rb_define_method(rb_cMatch, "to_s", match_to_s, 0);
|
rb_define_method(rb_cMatch, "to_s", match_to_s, 0);
|
||||||
|
|
60
sample/erb/erb4html.rb
Normal file
60
sample/erb/erb4html.rb
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
require 'erb'
|
||||||
|
|
||||||
|
class ERB
|
||||||
|
class ERBString < String
|
||||||
|
def to_s; self; end
|
||||||
|
|
||||||
|
def erb_concat(s)
|
||||||
|
if self.class === s
|
||||||
|
concat(s)
|
||||||
|
else
|
||||||
|
concat(erb_quote(s))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def erb_quote(s); s; end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class ERB4Html < ERB
|
||||||
|
def self.quoted(s)
|
||||||
|
HtmlString.new(s)
|
||||||
|
end
|
||||||
|
|
||||||
|
class HtmlString < ERB::ERBString
|
||||||
|
def erb_quote(s)
|
||||||
|
ERB::Util::html_escape(s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_eoutvar(compiler, eoutvar = '_erbout')
|
||||||
|
compiler.put_cmd = "#{eoutvar}.concat"
|
||||||
|
compiler.insert_cmd = "#{eoutvar}.erb_concat"
|
||||||
|
|
||||||
|
cmd = []
|
||||||
|
cmd.push "#{eoutvar} = ERB4Html.quoted('')"
|
||||||
|
|
||||||
|
compiler.pre_cmd = cmd
|
||||||
|
|
||||||
|
cmd = []
|
||||||
|
cmd.push(eoutvar)
|
||||||
|
|
||||||
|
compiler.post_cmd = cmd
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if __FILE__ == $0
|
||||||
|
page = <<EOP
|
||||||
|
<title><%=title%></title>
|
||||||
|
<p><%=para%></p>
|
||||||
|
EOP
|
||||||
|
erb = ERB4Html.new(page)
|
||||||
|
|
||||||
|
title = "<auto-quote>"
|
||||||
|
para = "<quoted>"
|
||||||
|
puts erb.result
|
||||||
|
|
||||||
|
title = "<auto-quote>"
|
||||||
|
para = ERB4Html.quoted("<quoted>")
|
||||||
|
puts erb.result
|
||||||
|
end
|
8
string.c
8
string.c
|
@ -761,7 +761,7 @@ rb_str_cat(str, ptr, len)
|
||||||
}
|
}
|
||||||
if (FL_TEST(str, STR_ASSOC)) {
|
if (FL_TEST(str, STR_ASSOC)) {
|
||||||
rb_str_modify(str);
|
rb_str_modify(str);
|
||||||
REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+len);
|
REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+len+1);
|
||||||
memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
|
memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
|
||||||
RSTRING(str)->len += len;
|
RSTRING(str)->len += len;
|
||||||
RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */
|
RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */
|
||||||
|
@ -3698,9 +3698,8 @@ rb_f_split(argc, argv)
|
||||||
*
|
*
|
||||||
* Splits <i>str</i> using the supplied parameter as the record separator
|
* Splits <i>str</i> using the supplied parameter as the record separator
|
||||||
* (<code>$/</code> by default), passing each substring in turn to the supplied
|
* (<code>$/</code> by default), passing each substring in turn to the supplied
|
||||||
* block. If a zero-length record separator is supplied, the string is split on
|
* block. If a zero-length record separator is supplied, the string is split
|
||||||
* <code>\n</code> characters, except that multiple successive newlines are
|
* into paragraphs delimited by multiple successive newlines.
|
||||||
* appended together.
|
|
||||||
*
|
*
|
||||||
* print "Example one\n"
|
* print "Example one\n"
|
||||||
* "hello\nworld".each {|s| p s}
|
* "hello\nworld".each {|s| p s}
|
||||||
|
@ -4922,6 +4921,7 @@ Init_String()
|
||||||
rb_define_method(rb_cString, "insert", rb_str_insert, 2);
|
rb_define_method(rb_cString, "insert", rb_str_insert, 2);
|
||||||
rb_define_method(rb_cString, "length", rb_str_length, 0);
|
rb_define_method(rb_cString, "length", rb_str_length, 0);
|
||||||
rb_define_method(rb_cString, "size", rb_str_length, 0);
|
rb_define_method(rb_cString, "size", rb_str_length, 0);
|
||||||
|
rb_define_method(rb_cString, "bytesize", rb_str_length, 0);
|
||||||
rb_define_method(rb_cString, "empty?", rb_str_empty, 0);
|
rb_define_method(rb_cString, "empty?", rb_str_empty, 0);
|
||||||
rb_define_method(rb_cString, "=~", rb_str_match, 1);
|
rb_define_method(rb_cString, "=~", rb_str_match, 1);
|
||||||
rb_define_method(rb_cString, "match", rb_str_match_m, 1);
|
rb_define_method(rb_cString, "match", rb_str_match_m, 1);
|
||||||
|
|
13
struct.c
13
struct.c
|
@ -310,19 +310,14 @@ rb_struct_s_def(argc, argv, klass)
|
||||||
ID id;
|
ID id;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "1*", &name, &rest);
|
rb_scan_args(argc, argv, "1*", &name, &rest);
|
||||||
|
if (!NIL_P(name) && SYMBOL_P(name)) {
|
||||||
|
rb_ary_unshift(rest, name);
|
||||||
|
name = Qnil;
|
||||||
|
}
|
||||||
for (i=0; i<RARRAY(rest)->len; i++) {
|
for (i=0; i<RARRAY(rest)->len; i++) {
|
||||||
id = rb_to_id(RARRAY(rest)->ptr[i]);
|
id = rb_to_id(RARRAY(rest)->ptr[i]);
|
||||||
RARRAY(rest)->ptr[i] = ID2SYM(id);
|
RARRAY(rest)->ptr[i] = ID2SYM(id);
|
||||||
}
|
}
|
||||||
if (!NIL_P(name)) {
|
|
||||||
VALUE tmp = rb_check_string_type(name);
|
|
||||||
|
|
||||||
if (NIL_P(tmp)) {
|
|
||||||
id = rb_to_id(name);
|
|
||||||
rb_ary_unshift(rest, ID2SYM(id));
|
|
||||||
name = Qnil;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
st = make_struct(name, rest, klass);
|
st = make_struct(name, rest, klass);
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
rb_mod_module_eval(0, 0, st);
|
rb_mod_module_eval(0, 0, st);
|
||||||
|
|
|
@ -528,6 +528,14 @@ class TestArray < Test::Unit::TestCase
|
||||||
assert_equal([1, 2, 3, 1, 2, 3], a)
|
assert_equal([1, 2, 3, 1, 2, 3], a)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_count
|
||||||
|
a = @cls[1, 2, 3, 1, 2]
|
||||||
|
assert_equal(2, a.count(1))
|
||||||
|
assert_equal(3, a.count {|x| x % 2 == 1 })
|
||||||
|
assert_equal(2, a.count(1) {|x| x % 2 == 1 })
|
||||||
|
assert_raise(ArgumentError) { a.count(0, 1) }
|
||||||
|
end
|
||||||
|
|
||||||
def test_delete
|
def test_delete
|
||||||
a = @cls[*('cab'..'cat').to_a]
|
a = @cls[*('cab'..'cat').to_a]
|
||||||
assert_equal('cap', a.delete('cap'))
|
assert_equal('cap', a.delete('cap'))
|
||||||
|
|
|
@ -47,5 +47,7 @@ class TestMethod < Test::Unit::TestCase
|
||||||
assert_equal(o, m.receiver)
|
assert_equal(o, m.receiver)
|
||||||
assert_equal("foo", m.name)
|
assert_equal("foo", m.name)
|
||||||
assert_equal(class << o; self; end, m.owner)
|
assert_equal(class << o; self; end, m.owner)
|
||||||
|
assert_equal("foo", m.unbind.name)
|
||||||
|
assert_equal(class << o; self; end, m.unbind.owner)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
1
test/webrick/.htaccess
Normal file
1
test/webrick/.htaccess
Normal file
|
@ -0,0 +1 @@
|
||||||
|
this file should not be published.
|
|
@ -1,20 +1,13 @@
|
||||||
require "webrick"
|
require "webrick"
|
||||||
require File.join(File.dirname(__FILE__), "utils.rb")
|
require File.join(File.dirname(__FILE__), "utils.rb")
|
||||||
require "test/unit"
|
require "test/unit"
|
||||||
begin
|
|
||||||
loadpath = $:.dup
|
|
||||||
$:.replace($: | [File.expand_path("../ruby", File.dirname(__FILE__))])
|
|
||||||
require 'envutil'
|
|
||||||
ensure
|
|
||||||
$:.replace(loadpath)
|
|
||||||
end
|
|
||||||
|
|
||||||
class TestWEBrickCGI < Test::Unit::TestCase
|
class TestWEBrickCGI < Test::Unit::TestCase
|
||||||
def test_cgi
|
def test_cgi
|
||||||
accepted = started = stopped = 0
|
accepted = started = stopped = 0
|
||||||
requested0 = requested1 = 0
|
requested0 = requested1 = 0
|
||||||
config = {
|
config = {
|
||||||
:CGIInterpreter => EnvUtil.rubybin,
|
:CGIInterpreter => TestWEBrick::RubyBin,
|
||||||
:DocumentRoot => File.dirname(__FILE__),
|
:DocumentRoot => File.dirname(__FILE__),
|
||||||
:DirectoryIndex => ["webrick.cgi"],
|
:DirectoryIndex => ["webrick.cgi"],
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,10 @@ class WEBrick::TestFileHandler < Test::Unit::TestCase
|
||||||
klass.new(WEBrick::Config::HTTP, filename)
|
klass.new(WEBrick::Config::HTTP, filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def windows?
|
||||||
|
File.directory?("\\")
|
||||||
|
end
|
||||||
|
|
||||||
def get_res_body(res)
|
def get_res_body(res)
|
||||||
return res.body.read rescue res.body
|
return res.body.read rescue res.body
|
||||||
end
|
end
|
||||||
|
@ -115,10 +119,82 @@ class WEBrick::TestFileHandler < Test::Unit::TestCase
|
||||||
http = Net::HTTP.new(addr, port)
|
http = Net::HTTP.new(addr, port)
|
||||||
req = Net::HTTP::Get.new("/../../")
|
req = Net::HTTP::Get.new("/../../")
|
||||||
http.request(req){|res| assert_equal("400", res.code) }
|
http.request(req){|res| assert_equal("400", res.code) }
|
||||||
req = Net::HTTP::Get.new(
|
req = Net::HTTP::Get.new("/..%5c../#{File.basename(__FILE__)}")
|
||||||
"/..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5cboot.ini"
|
http.request(req){|res| assert_equal(windows? ? "200" : "404", res.code) }
|
||||||
)
|
req = Net::HTTP::Get.new("/..%5c..%5cruby.c")
|
||||||
http.request(req){|res| assert_equal("404", res.code) }
|
http.request(req){|res| assert_equal("404", res.code) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_unwise_in_path
|
||||||
|
if windows?
|
||||||
|
config = { :DocumentRoot => File.dirname(__FILE__), }
|
||||||
|
this_file = File.basename(__FILE__)
|
||||||
|
TestWEBrick.start_httpserver(config) do |server, addr, port|
|
||||||
|
http = Net::HTTP.new(addr, port)
|
||||||
|
req = Net::HTTP::Get.new("/..%5c..")
|
||||||
|
http.request(req){|res| assert_equal("301", res.code) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_short_filename
|
||||||
|
config = {
|
||||||
|
:CGIInterpreter => TestWEBrick::RubyBin,
|
||||||
|
:DocumentRoot => File.dirname(__FILE__),
|
||||||
|
:CGIPathEnv => ENV['PATH'],
|
||||||
|
}
|
||||||
|
TestWEBrick.start_httpserver(config) do |server, addr, port|
|
||||||
|
http = Net::HTTP.new(addr, port)
|
||||||
|
|
||||||
|
req = Net::HTTP::Get.new("/webric~1.cgi/test")
|
||||||
|
http.request(req) do |res|
|
||||||
|
if windows?
|
||||||
|
assert_equal("200", res.code)
|
||||||
|
assert_equal("/test", res.body)
|
||||||
|
else
|
||||||
|
assert_equal("404", res.code)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
req = Net::HTTP::Get.new("/.htaccess")
|
||||||
|
http.request(req) {|res| assert_equal("404", res.code) }
|
||||||
|
req = Net::HTTP::Get.new("/htacce~1")
|
||||||
|
http.request(req) {|res| assert_equal("404", res.code) }
|
||||||
|
req = Net::HTTP::Get.new("/HTACCE~1")
|
||||||
|
http.request(req) {|res| assert_equal("404", res.code) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_script_disclosure
|
||||||
|
config = {
|
||||||
|
:CGIInterpreter => TestWEBrick::RubyBin,
|
||||||
|
:DocumentRoot => File.dirname(__FILE__),
|
||||||
|
:CGIPathEnv => ENV['PATH'],
|
||||||
|
}
|
||||||
|
TestWEBrick.start_httpserver(config) do |server, addr, port|
|
||||||
|
http = Net::HTTP.new(addr, port)
|
||||||
|
|
||||||
|
req = Net::HTTP::Get.new("/webrick.cgi/test")
|
||||||
|
http.request(req) do |res|
|
||||||
|
assert_equal("200", res.code)
|
||||||
|
assert_equal("/test", res.body)
|
||||||
|
end
|
||||||
|
|
||||||
|
response_assertion = Proc.new do |res|
|
||||||
|
if windows?
|
||||||
|
assert_equal("200", res.code)
|
||||||
|
assert_equal("/test", res.body)
|
||||||
|
else
|
||||||
|
assert_equal("404", res.code)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
req = Net::HTTP::Get.new("/webrick.cgi%20/test")
|
||||||
|
http.request(req, &response_assertion)
|
||||||
|
req = Net::HTTP::Get.new("/webrick.cgi./test")
|
||||||
|
http.request(req, &response_assertion)
|
||||||
|
req = Net::HTTP::Get.new("/webrick.cgi::$DATA/test")
|
||||||
|
http.request(req, &response_assertion)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
begin
|
||||||
|
loadpath = $:.dup
|
||||||
|
$:.replace($: | [File.expand_path("../ruby", File.dirname(__FILE__))])
|
||||||
|
require 'envutil'
|
||||||
|
ensure
|
||||||
|
$:.replace(loadpath)
|
||||||
|
end
|
||||||
require "webrick"
|
require "webrick"
|
||||||
begin
|
begin
|
||||||
require "webrick/https"
|
require "webrick/https"
|
||||||
|
@ -12,6 +19,11 @@ module TestWEBrick
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RubyBin = "\"#{EnvUtil.rubybin}\""
|
||||||
|
RubyBin << " \"-I#{File.expand_path("../..", File.dirname(__FILE__))}/lib\""
|
||||||
|
RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/common\""
|
||||||
|
RubyBin << " \"-I#{File.dirname(EnvUtil.rubybin)}/.ext/#{RUBY_PLATFORM}\""
|
||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def start_server(klass, config={}, &block)
|
def start_server(klass, config={}, &block)
|
||||||
|
|
36
test/webrick/webrick_long_filename.cgi
Normal file
36
test/webrick/webrick_long_filename.cgi
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
#!ruby -d
|
||||||
|
require "webrick/cgi"
|
||||||
|
|
||||||
|
class TestApp < WEBrick::CGI
|
||||||
|
def do_GET(req, res)
|
||||||
|
res["content-type"] = "text/plain"
|
||||||
|
if (p = req.path_info) && p.length > 0
|
||||||
|
res.body = p
|
||||||
|
elsif (q = req.query).size > 0
|
||||||
|
res.body = q.keys.sort.collect{|key|
|
||||||
|
q[key].list.sort.collect{|v|
|
||||||
|
"#{key}=#{v}"
|
||||||
|
}.join(", ")
|
||||||
|
}.join(", ")
|
||||||
|
elsif %r{/$} =~ req.request_uri.to_s
|
||||||
|
res.body = ""
|
||||||
|
res.body << req.request_uri.to_s << "\n"
|
||||||
|
res.body << req.script_name
|
||||||
|
elsif !req.cookies.empty?
|
||||||
|
res.body = req.cookies.inject(""){|result, cookie|
|
||||||
|
result << "%s=%s\n" % [cookie.name, cookie.value]
|
||||||
|
}
|
||||||
|
res.cookies << WEBrick::Cookie.new("Customer", "WILE_E_COYOTE")
|
||||||
|
res.cookies << WEBrick::Cookie.new("Shipping", "FedEx")
|
||||||
|
else
|
||||||
|
res.body = req.script_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_POST(req, res)
|
||||||
|
do_GET(req, res)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
cgi = TestApp.new
|
||||||
|
cgi.start
|
|
@ -639,6 +639,11 @@ class File
|
||||||
end
|
end
|
||||||
<<KEEP
|
<<KEEP
|
||||||
|
|
||||||
|
test-rubyspec:
|
||||||
|
@if not exist $(srcdir:/=\)\rubyspec\nul echo No rubyspec here. put rubyspec to srcdir first. && exit 1
|
||||||
|
$(RUNRUBY) $(srcdir)/rubyspec/mspec/bin/mspec -r$(srcdir)/ext/purelib.rb $(srcdir)/rubyspec/spec/rubyspec/$(MAJOR).$(MINOR)
|
||||||
|
|
||||||
|
|
||||||
{$(srcdir)/missing}.c.obj:
|
{$(srcdir)/missing}.c.obj:
|
||||||
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/)
|
$(CC) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/)
|
||||||
{$(srcdir)/win32}.c.obj:
|
{$(srcdir)/win32}.c.obj:
|
||||||
|
|
280
win32/win32.c
280
win32/win32.c
|
@ -371,6 +371,7 @@ static void invalid_parameter(const wchar_t *expr, const wchar_t *func, const wc
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static CRITICAL_SECTION select_mutex;
|
||||||
static BOOL fWinsock;
|
static BOOL fWinsock;
|
||||||
static char *envarea;
|
static char *envarea;
|
||||||
static void
|
static void
|
||||||
|
@ -384,6 +385,7 @@ exit_handler(void)
|
||||||
FreeEnvironmentStrings(envarea);
|
FreeEnvironmentStrings(envarea);
|
||||||
envarea = NULL;
|
envarea = NULL;
|
||||||
}
|
}
|
||||||
|
DeleteCriticalSection(&select_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -472,6 +474,8 @@ NtInitialize(int *argc, char ***argv)
|
||||||
|
|
||||||
init_stdhandle();
|
init_stdhandle();
|
||||||
|
|
||||||
|
InitializeCriticalSection(&select_mutex);
|
||||||
|
|
||||||
atexit(exit_handler);
|
atexit(exit_handler);
|
||||||
|
|
||||||
// Initialize Winsock
|
// Initialize Winsock
|
||||||
|
@ -2057,87 +2061,250 @@ rb_w32_fdisset(int fd, fd_set *set)
|
||||||
static int NtSocketsInitialized = 0;
|
static int NtSocketsInitialized = 0;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
extract_file_fd(fd_set *set, fd_set *fileset)
|
extract_fd(fd_set *dst, fd_set *src, int (*func)(SOCKET))
|
||||||
{
|
{
|
||||||
int idx;
|
int s = 0;
|
||||||
|
if (!src || !dst) return 0;
|
||||||
|
|
||||||
fileset->fd_count = 0;
|
while (s < src->fd_count) {
|
||||||
if (!set)
|
SOCKET fd = src->fd_array[s];
|
||||||
|
|
||||||
|
if (!func || (*func)(fd)) { /* move it to dst */
|
||||||
|
int d;
|
||||||
|
|
||||||
|
for (d = 0; d < dst->fd_count; d++) {
|
||||||
|
if (dst->fd_array[d] == fd) break;
|
||||||
|
}
|
||||||
|
if (d == dst->fd_count && dst->fd_count < FD_SETSIZE) {
|
||||||
|
dst->fd_array[dst->fd_count++] = fd;
|
||||||
|
}
|
||||||
|
memmove(
|
||||||
|
&src->fd_array[s],
|
||||||
|
&src->fd_array[s+1],
|
||||||
|
sizeof(src->fd_array[0]) * (--src->fd_count - s));
|
||||||
|
}
|
||||||
|
else s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst->fd_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_not_socket(SOCKET sock)
|
||||||
|
{
|
||||||
|
return !is_socket(sock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_pipe(SOCKET sock) /* DONT call this for SOCKET! it clains it is PIPE. */
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
RUBY_CRITICAL(
|
||||||
|
ret = (GetFileType((HANDLE)sock) == FILE_TYPE_PIPE)
|
||||||
|
);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_readable_pipe(SOCKET sock) /* call this for pipe only */
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
DWORD n = 0;
|
||||||
|
|
||||||
|
RUBY_CRITICAL(
|
||||||
|
if (PeekNamedPipe((HANDLE)sock, NULL, 0, NULL, &n, NULL)) {
|
||||||
|
ret = (n > 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = (GetLastError() == ERROR_BROKEN_PIPE); /* pipe was closed */
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_console(SOCKET sock) /* DONT call this for SOCKET! */
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
DWORD n = 0;
|
||||||
|
INPUT_RECORD ir;
|
||||||
|
|
||||||
|
RUBY_CRITICAL(
|
||||||
|
ret = (PeekConsoleInput((HANDLE)sock, &ir, 1, &n))
|
||||||
|
);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_readable_console(SOCKET sock) /* call this for console only */
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
DWORD n = 0;
|
||||||
|
INPUT_RECORD ir;
|
||||||
|
|
||||||
|
RUBY_CRITICAL(
|
||||||
|
if (PeekConsoleInput((HANDLE)sock, &ir, 1, &n) && n > 0) {
|
||||||
|
if (ir.EventType == KEY_EVENT && ir.Event.KeyEvent.bKeyDown &&
|
||||||
|
ir.Event.KeyEvent.uChar.AsciiChar) {
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ReadConsoleInput((HANDLE)sock, &ir, 1, &n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_select(int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
||||||
|
struct timeval *timeout)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
if (nfds == 0) {
|
||||||
|
if (timeout)
|
||||||
|
rb_w32_sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
|
||||||
|
else
|
||||||
|
rb_w32_sleep(INFINITE);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
RUBY_CRITICAL(
|
||||||
|
EnterCriticalSection(&select_mutex);
|
||||||
|
r = select(nfds, rd, wr, ex, timeout);
|
||||||
|
LeaveCriticalSection(&select_mutex);
|
||||||
|
if (r == SOCKET_ERROR) {
|
||||||
|
errno = map_errno(WSAGetLastError());
|
||||||
|
r = -1;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
subst(struct timeval *rest, const struct timeval *wait)
|
||||||
|
{
|
||||||
|
while (rest->tv_usec < wait->tv_usec) {
|
||||||
|
if (rest->tv_sec <= wait->tv_sec) {
|
||||||
return 0;
|
return 0;
|
||||||
for (idx = 0; idx < set->fd_count; idx++) {
|
|
||||||
SOCKET fd = set->fd_array[idx];
|
|
||||||
|
|
||||||
if (!is_socket(fd)) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < fileset->fd_count; i++) {
|
|
||||||
if (fileset->fd_array[i] == fd) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
rest->tv_sec -= 1;
|
||||||
|
rest->tv_usec += 1000 * 1000;
|
||||||
}
|
}
|
||||||
if (i == fileset->fd_count) {
|
rest->tv_sec -= wait->tv_sec;
|
||||||
if (fileset->fd_count < FD_SETSIZE) {
|
rest->tv_usec -= wait->tv_usec;
|
||||||
fileset->fd_array[i] = fd;
|
return 1;
|
||||||
fileset->fd_count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fileset->fd_count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
compare(const struct timeval *t1, const struct timeval *t2)
|
||||||
|
{
|
||||||
|
if (t1->tv_sec < t2->tv_sec)
|
||||||
|
return -1;
|
||||||
|
if (t1->tv_sec > t2->tv_sec)
|
||||||
|
return 1;
|
||||||
|
if (t1->tv_usec < t2->tv_usec)
|
||||||
|
return -1;
|
||||||
|
if (t1->tv_usec > t2->tv_usec)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef Sleep
|
||||||
long
|
long
|
||||||
rb_w32_select (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
rb_w32_select (int nfds, fd_set *rd, fd_set *wr, fd_set *ex,
|
||||||
struct timeval *timeout)
|
struct timeval *timeout)
|
||||||
{
|
{
|
||||||
long r;
|
long r;
|
||||||
fd_set file_rd;
|
fd_set pipe_rd;
|
||||||
fd_set file_wr;
|
fd_set cons_rd;
|
||||||
#ifdef USE_INTERRUPT_WINSOCK
|
fd_set else_rd;
|
||||||
fd_set trap;
|
fd_set else_wr;
|
||||||
#endif /* USE_INTERRUPT_WINSOCK */
|
int nonsock = 0;
|
||||||
int file_nfds;
|
|
||||||
|
|
||||||
|
if (nfds < 0 || (timeout && (timeout->tv_sec < 0 || timeout->tv_usec < 0))) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if (!NtSocketsInitialized) {
|
if (!NtSocketsInitialized) {
|
||||||
StartSockets();
|
StartSockets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// assume else_{rd,wr} (other than socket, pipe reader, console reader)
|
||||||
|
// are always readable/writable. but this implementation still has
|
||||||
|
// problem. if pipe's buffer is full, writing to pipe will block
|
||||||
|
// until some data is read from pipe. but ruby is single threaded system,
|
||||||
|
// so whole system will be blocked forever.
|
||||||
|
|
||||||
|
else_rd.fd_count = 0;
|
||||||
|
nonsock += extract_fd(&else_rd, rd, is_not_socket);
|
||||||
|
|
||||||
|
pipe_rd.fd_count = 0;
|
||||||
|
extract_fd(&pipe_rd, &else_rd, is_pipe); // should not call is_pipe for socket
|
||||||
|
|
||||||
|
cons_rd.fd_count = 0;
|
||||||
|
extract_fd(&cons_rd, &else_rd, is_console); // ditto
|
||||||
|
|
||||||
|
else_wr.fd_count = 0;
|
||||||
|
nonsock += extract_fd(&else_wr, wr, is_not_socket);
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
if (rd && rd->fd_count > r) r = rd->fd_count;
|
if (rd && rd->fd_count > r) r = rd->fd_count;
|
||||||
if (wr && wr->fd_count > r) r = wr->fd_count;
|
if (wr && wr->fd_count > r) r = wr->fd_count;
|
||||||
if (ex && ex->fd_count > r) r = ex->fd_count;
|
if (ex && ex->fd_count > r) r = ex->fd_count;
|
||||||
if (nfds > r) nfds = r;
|
if (nfds > r) nfds = r;
|
||||||
if (nfds == 0 && timeout) {
|
|
||||||
Sleep(timeout->tv_sec * 1000 + timeout->tv_usec / 1000);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
file_nfds = extract_file_fd(rd, &file_rd);
|
|
||||||
file_nfds += extract_file_fd(wr, &file_wr);
|
|
||||||
if (file_nfds)
|
|
||||||
{
|
{
|
||||||
// assume normal files are always readable/writable
|
struct timeval rest;
|
||||||
// fake read/write fd_set and return value
|
struct timeval wait;
|
||||||
if (rd) *rd = file_rd;
|
struct timeval zero;
|
||||||
if (wr) *wr = file_wr;
|
if (timeout) rest = *timeout;
|
||||||
return file_nfds;
|
wait.tv_sec = 0; wait.tv_usec = 10 * 1000; // 10ms
|
||||||
|
zero.tv_sec = 0; zero.tv_usec = 0; // 0ms
|
||||||
|
do {
|
||||||
|
if (nonsock) {
|
||||||
|
// modifying {else,pipe,cons}_rd is safe because
|
||||||
|
// if they are modified, function returns immediately.
|
||||||
|
extract_fd(&else_rd, &pipe_rd, is_readable_pipe);
|
||||||
|
extract_fd(&else_rd, &cons_rd, is_readable_console);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if USE_INTERRUPT_WINSOCK
|
if (else_rd.fd_count || else_wr.fd_count) {
|
||||||
if (ex)
|
r = do_select(nfds, rd, wr, ex, &zero); // polling
|
||||||
trap = *ex;
|
if (r < 0) break; // XXX: should I ignore error and return signaled handles?
|
||||||
else
|
r += extract_fd(rd, &else_rd, NULL); // move all
|
||||||
trap.fd_count = 0;
|
r += extract_fd(wr, &else_wr, NULL); // move all
|
||||||
if (trap.fd_count < FD_SETSIZE)
|
break;
|
||||||
trap.fd_array[trap.fd_count++] = (SOCKET)interrupted_event;
|
|
||||||
// else unable to catch interrupt.
|
|
||||||
ex = &trap;
|
|
||||||
#endif /* USE_INTERRUPT_WINSOCK */
|
|
||||||
|
|
||||||
RUBY_CRITICAL({
|
|
||||||
r = select(nfds, rd, wr, ex, timeout);
|
|
||||||
if (r == SOCKET_ERROR) {
|
|
||||||
errno = map_errno(WSAGetLastError());
|
|
||||||
}
|
}
|
||||||
});
|
else {
|
||||||
|
struct timeval *dowait =
|
||||||
|
compare(&rest, &wait) < 0 ? &rest : &wait;
|
||||||
|
|
||||||
|
fd_set orig_rd;
|
||||||
|
fd_set orig_wr;
|
||||||
|
fd_set orig_ex;
|
||||||
|
if (rd) orig_rd = *rd;
|
||||||
|
if (wr) orig_wr = *wr;
|
||||||
|
if (ex) orig_ex = *ex;
|
||||||
|
r = do_select(nfds, rd, wr, ex, &zero); // polling
|
||||||
|
if (r != 0) break; // signaled or error
|
||||||
|
if (rd) *rd = orig_rd;
|
||||||
|
if (wr) *wr = orig_wr;
|
||||||
|
if (ex) *ex = orig_ex;
|
||||||
|
|
||||||
|
// XXX: should check the time select spent
|
||||||
|
Sleep(dowait->tv_sec * 1000 + dowait->tv_usec / 1000);
|
||||||
|
}
|
||||||
|
} while (!timeout || subst(&rest, &wait));
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3272,7 +3439,6 @@ rb_w32_times(struct tms *tmbuf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef Sleep
|
|
||||||
#define yield_once() Sleep(0)
|
#define yield_once() Sleep(0)
|
||||||
#define yield_until(condition) do yield_once(); while (!(condition))
|
#define yield_until(condition) do yield_once(); while (!(condition))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue