[#34911] erb still treats $KCODE — "Yusuke ENDOH" <mame@...>

遠藤です。

16 messages 2008/06/03

[#34923] open() and encodings — "NARUSE, Yui" <naruse@...>

成瀬です。

53 messages 2008/06/03
[#34924] Re: open() and encodings — Yukihiro Matsumoto <matz@...> 2008/06/04

まつもと ゆきひろです

[#34931] Re: open() and encodings — "NARUSE, Yui" <naruse@...> 2008/06/04

成瀬です。

[#34934] Re: open() and encodings — Yukihiro Matsumoto <matz@...> 2008/06/05

まつもと ゆきひろです

[#34935] Re: open() and encodings — "U.Nakamura" <usa@...> 2008/06/05

こんにちは、なかむら(う)です。

[#34936] Re: open() and encodings — Yukihiro Matsumoto <matz@...> 2008/06/05

まつもと ゆきひろです

[#34937] Re: open() and encodings — "U.Nakamura" <usa@...> 2008/06/05

こんにちは、なかむら(う)です。

[#34948] Re: open() and encodings — Hidetoshi NAGAI <nagai@...> 2008/06/05

永井@知能.九工大です.

[#34961] Re: open() and encodings — "NARUSE, Yui" <naruse@...> 2008/06/05

成瀬です。

[#34997] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — SASADA Koichi <ko1@...>

 ささだです.

19 messages 2008/06/08
[#34998] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — Yukihiro Matsumoto <matz@...> 2008/06/08

まつもと ゆきひろです

[#34999] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — SASADA Koichi <ko1@...> 2008/06/08

 ささだです.

[#35000] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — Yukihiro Matsumoto <matz@...> 2008/06/08

まつもと ゆきひろです

[#35001] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — SASADA Koichi <ko1@...> 2008/06/08

 ささだです.

[#35003] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — Yukihiro Matsumoto <matz@...> 2008/06/08

まつもと ゆきひろです

[#35007] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — "Yusuke ENDOH" <mame@...> 2008/06/09

遠藤です。

[#35013] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — Yukihiro Matsumoto <matz@...> 2008/06/09

まつもと ゆきひろです

[#35019] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — "Yusuke ENDOH" <mame@...> 2008/06/09

遠藤です。

[#35021] Re: [ruby-changes:5517] Ruby:r17021 (trunk): * vm_insnhelper.c, vm.c, proc.c (proc_call): allow call method with — Yukihiro Matsumoto <matz@...> 2008/06/09

まつもと ゆきひろです

[#35020] Ruby 1.8.7-p17 has been released — "Akinori MUSHA" <knu@...>

 Ruby 1.8.7-p17 をリリースしました。

13 messages 2008/06/09

[#35044] deadlock detection for 1.9 — "Yusuke ENDOH" <mame@...>

遠藤です。

14 messages 2008/06/10

[#35108] Re: [ruby-list:44988] Re: 各ブランチの計画 — Urabe Shyouhei <shyouhei@...>

卜部です。

15 messages 2008/06/15

[#35200] Win32 Unicode console output — Tietew <tietew@...>

Tietew です。

22 messages 2008/06/22
[#35270] Re: Win32 Unicode console output — "NARUSE, Yui" <naruse@...> 2008/06/29

[#35226] [PATCH] freeze required_paths in gem_prelude.rb — "Keita Yamaguchi" <keita.yamaguchi@...>

山口と申します。

14 messages 2008/06/25
[#35228] Re: [PATCH] freeze required_paths in gem_prelude.rb — "Yusuke ENDOH" <mame@...> 2008/06/25

遠藤です。

[#35230] Re: [PATCH] freeze required_paths in gem_prelude.rb — Yukihiro Matsumoto <matz@...> 2008/06/25

まつもと ゆきひろです

[#35227] [Bug:trunk] Re: [ruby-cvs:24798] Ruby:r17573 (trunk): * parse.y (primary): make functional-style not operator to act — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

7 messages 2008/06/25

[#35247] Re: [ruby-list:45128] Re: Ruby 1.9.0/1.8.7/1.8.6/1.8.5 new releases (Security Fix) — Urabe Shyouhei <shyouhei@...>

卜部です。-devに振ります。ひょっとしてこんなパッチでSEGVのほうはおさまっ

13 messages 2008/06/26
[#35250] Re: [ruby-list:45128] Re: Ruby 1.9.0/1.8.7/1.8.6/1.8.5 new releases (Security Fix) — Yukihiro Matsumoto <matz@...> 2008/06/26

まつもと ゆきひろです

[#35273] $SAFEの今後 — Urabe Shyouhei <shyouhei@...>

〜これまでのあらすじ〜

24 messages 2008/06/30
[#35293] Re: $SAFEの今後 — Yukihiro Matsumoto <matz@...> 2008/07/01

まつもと ゆきひろです

[#35298] Re: $SAFEの今後 — Urabe Shyouhei <shyouhei@...> 2008/07/01

卜部です。

[#35303] Re: $SAFEの今後 — Yukihiro Matsumoto <matz@...> 2008/07/01

まつもと ゆきひろです

[#35304] Re: $SAFEの今後 — Urabe Shyouhei <shyouhei@...> 2008/07/01

卜部です。

[#35305] Re: $SAFEの今後 — Yukihiro Matsumoto <matz@...> 2008/07/01

まつもと ゆきひろです

[#35306] Re: $SAFEの今後 — "Shugo Maeda" <shugo@...> 2008/07/02

前田です。

[#35278] [BUG] test_win32ole_event.rb in trunk — Masaki Suketa <masaki.suketa@...>

助田です。

22 messages 2008/06/30
[#35281] Re: [BUG] test_win32ole_event.rb in trunk — "U.Nakamura" <usa@...> 2008/06/30

こんにちは、なかむら(う)です。

[#35282] Re: [BUG] test_win32ole_event.rb in trunk — arton <artonx@...> 2008/06/30

artonです。

[#35295] Re: [BUG] test_win32ole_event.rb in trunk — Masaki Suketa <masaki.suketa@...> 2008/07/01

助田です。

[ruby-dev:35274] [Feature:trunk] test-coverage measurement

From: "Yusuke ENDOH" <mame@...>
Date: 2008-06-30 13:02:15 UTC
List: ruby-dev #35274
遠藤です。

Ruby 本体にカバレッジ測定機能を提供するのはどうでしょうか。

具体的には、ソースごとの各行の実行回数を表す定数 COVERAGE__ を
導入したいです。SCRIPT_LINES__ のカバレッジ版のようなイメージです。

  1. ユーザが COVERAGE__ に {} を設定する
  2. ユーザがソースファイルを require や load する
  3. COVERAGE__[ファイル名] が各行の実行回数を表す配列を返すようになる
     (この配列は実行に従って勝手に更新される)

  ※ COVERAGE__ が設定されなければ何もしません。
  ※ 空行など実行される可能性がない行は nil になります。
  ※ eval は測定対象にしません。


動作の具体例です。

$ cat foo.rb
s = 0
10.times do |x|
  s += x
end

if s == 45
  p :ok
else
  p :ng
end

$ ./ruby -e 'COVERAGE__ = {}; require "foo.rb"; p COVERAGE__'
:ok
{"/home/mame/work/ruby19/ruby/foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]}

この配列は各行の実行回数を表しています。


上記の仕様を実装したものを添付します。

サンプルとして、lib/coverage.rb を同梱しています。
以下のように使えます。

$ ./ruby -rcoverage foo.rb

$ cat foo.rb.cov
        1:    0:s = 0
        1:    1:10.times do |x|
       10:    2:  s += x
        -:    3:end
        -:    4:
        1:    5:if s == 45
        1:    6:  p :ok
        -:    7:else
    #####:    8:  p :ng
        -:    9:end


また、RUNRUBYOPT="-rcoverage" make test-all した結果を集計して
みました。バグとかで不正確な結果になってる可能性はありますが、
このくらいは動くと言うことで。

$ ./ruby -e '
aan = acn = 0
Dir["{lib,.ext}/**/*.cov"].each do |f|
  an, cn = File.readlines(f).inject([0, 0]) do |(an, cn), l|
    next [an, cn] if l.start_with?("        -")
    an += 1
    cn += 1 if !l.start_with?("    #####")
    [an, cn]
  end
  puts "%s %.2f%% (%d/%d)" % [f, cn.to_f * 100 / an, cn, an]
  aan += an
  acn += cn
end
puts "(total) %.2f%% (%d/%d)" % [acn.to_f * 100 / aan, acn, aan]
'
lib/drb/unix.rb.cov 86.11% (62/72)
lib/drb/drb.rb.cov 81.70% (491/601)
lib/drb/eq.rb.cov 100.00% (9/9)
lib/drb/ssl.rb.cov 83.90% (99/118)
lib/drb/acl.rb.cov 85.71% (66/77)
lib/drb/extservm.rb.cov 96.23% (51/53)
lib/drb/invokemethod.rb.cov 27.78% (5/18)
lib/irb/notifier.rb.cov 75.00% (54/72)
lib/irb/output-method.rb.cov 52.00% (13/25)
lib/irb/slex.rb.cov 20.39% (31/152)
lib/net/https.rb.cov 77.78% (14/18)
lib/net/http.rb.cov 87.73% (772/880)
lib/net/imap.rb.cov 35.81% (467/1304)
lib/net/protocol.rb.cov 59.49% (116/195)
lib/rss/content/1.0.rb.cov 100.00% (6/6)
lib/rss/content/2.0.rb.cov 100.00% (7/7)
lib/rss/1.0.rb.cov 98.08% (204/208)
lib/rss/image.rb.cov 96.26% (103/107)
lib/rss/syndication.rb.cov 96.55% (28/29)
lib/rss/maker/1.0.rb.cov 99.55% (223/224)
lib/rss/maker/image.rb.cov 100.00% (58/58)
lib/rss/maker/syndication.rb.cov 100.00% (10/10)
lib/rss/maker/taxonomy.rb.cov 97.67% (42/43)
lib/rss/maker/0.9.rb.cov 98.79% (245/248)
lib/rss/maker/2.0.rb.cov 98.45% (127/129)
lib/rss/maker/base.rb.cov 98.22% (441/449)
lib/rss/maker/dublincore.rb.cov 100.00% (42/42)
lib/rss/maker/entry.rb.cov 97.89% (93/95)
lib/rss/maker/feed.rb.cov 98.28% (228/232)
lib/rss/maker/itunes.rb.cov 97.62% (123/126)
lib/rss/maker/slash.rb.cov 100.00% (18/18)
lib/rss/maker/atom.rb.cov 98.73% (78/79)
lib/rss/maker/trackback.rb.cov 100.00% (31/31)
lib/rss/maker/content.rb.cov 100.00% (12/12)
lib/rss/taxonomy.rb.cov 98.75% (79/80)
lib/rss/rexmlparser.rb.cov 82.14% (23/28)
lib/rss/parser.rb.cov 93.00% (279/300)
lib/rss/0.9.rb.cov 99.51% (205/206)
lib/rss/xmlparser.rb.cov 6.67% (3/45)
lib/rss/utils.rb.cov 98.31% (58/59)
lib/rss/2.0.rb.cov 100.00% (49/49)
lib/rss/dublincore.rb.cov 100.00% (39/39)
lib/rss/xml.rb.cov 89.74% (35/39)
lib/rss/xml-stylesheet.rb.cov 100.00% (63/63)
lib/rss/itunes.rb.cov 91.83% (191/208)
lib/rss/rss.rb.cov 93.23% (592/635)
lib/rss/slash.rb.cov 100.00% (25/25)
lib/rss/atom.rb.cov 99.50% (397/399)
lib/rss/dublincore/1.0.rb.cov 100.00% (9/9)
lib/rss/dublincore/2.0.rb.cov 100.00% (8/8)
lib/rss/dublincore/atom.rb.cov 100.00% (10/10)
lib/rss/maker.rb.cov 96.55% (28/29)
lib/rss/trackback.rb.cov 100.00% (125/125)
lib/rss/xmlscanner.rb.cov 1.64% (1/61)
lib/rss/content.rb.cov 100.00% (19/19)
lib/rss/converter.rb.cov 30.00% (21/70)
lib/uri/ftp.rb.cov 82.46% (47/57)
lib/uri/ldaps.rb.cov 100.00% (5/5)
lib/uri/https.rb.cov 100.00% (5/5)
lib/uri/common.rb.cov 95.07% (135/142)
lib/uri/generic.rb.cov 90.04% (416/462)
lib/uri/ldap.rb.cov 74.23% (72/97)
lib/uri/http.rb.cov 93.33% (14/15)
lib/uri/mailto.rb.cov 81.40% (70/86)
lib/date/format.rb.cov 35.96% (233/648)
lib/rdoc/ri/paths.rb.cov 57.50% (23/40)
lib/rdoc/ri/display.rb.cov 81.89% (104/127)
lib/rdoc/ri/formatter.rb.cov 69.23% (216/312)
lib/rdoc/ri/driver.rb.cov 13.45% (30/223)
lib/rdoc/options.rb.cov 31.82% (70/220)
lib/rdoc/ri.rb.cov 100.00% (2/2)
lib/rdoc/rdoc.rb.cov 32.74% (37/113)
lib/rdoc/dot.rb.cov 47.06% (40/85)
lib/rdoc/markup.rb.cov 92.86% (117/126)
lib/rdoc/tokenstream.rb.cov 58.33% (7/12)
lib/rdoc/markup/lines.rb.cov 95.00% (57/60)
lib/rdoc/markup/to_flow.rb.cov 49.44% (44/89)
lib/rdoc/markup/to_test.rb.cov 100.00% (23/23)
lib/rdoc/markup/fragments.rb.cov 95.89% (140/146)
lib/rdoc/markup/inline.rb.cov 76.60% (36/47)
lib/rdoc/markup/attribute_manager.rb.cov 90.08% (118/131)
lib/rdoc/markup/preprocess.rb.cov 24.14% (7/29)
lib/rdoc/markup/formatter.rb.cov 83.33% (5/6)
lib/rdoc/stats.rb.cov 58.33% (7/12)
lib/rdoc/parsers/parse_c.rb.cov 49.80% (125/251)
lib/rdoc/parsers/parse_rb.rb.cov 13.46% (178/1322)
lib/rdoc/parsers/parse_simple.rb.cov 43.75% (7/16)
lib/rdoc/parsers/parse_f95.rb.cov 6.02% (53/881)
lib/rdoc/parsers/parserfactory.rb.cov 41.67% (10/24)
lib/rdoc/code_objects.rb.cov 57.22% (218/381)
lib/rdoc/diagram.rb.cov 10.00% (14/140)
lib/test/unit/ui/console/testrunner.rb.cov 92.96% (66/71)
lib/test/unit/ui/testrunnermediator.rb.cov 100.00% (32/32)
lib/test/unit/ui/testrunnerutilities.rb.cov 66.67% (10/15)
lib/test/unit/collector/objectspace.rb.cov 100.00% (18/18)
lib/test/unit/collector/dir.rb.cov 95.89% (70/73)
lib/test/unit/util/backtracefilter.rb.cov 100.00% (28/28)
lib/test/unit/util/observable.rb.cov 100.00% (31/31)
lib/test/unit/util/procwrapper.rb.cov 100.00% (12/12)
lib/test/unit/failure.rb.cov 95.00% (19/20)
lib/test/unit/testcase.rb.cov 91.78% (67/73)
lib/test/unit/testsuite.rb.cov 100.00% (31/31)
lib/test/unit/collector.rb.cov 100.00% (25/25)
lib/test/unit/autorunner.rb.cov 66.94% (81/121)
lib/test/unit/testresult.rb.cov 100.00% (30/30)
lib/test/unit/error.rb.cov 95.24% (20/21)
lib/test/unit/assertions.rb.cov 97.01% (227/234)
lib/test/unit/assertionfailederror.rb.cov 100.00% (3/3)
lib/test/unit.rb.cov 90.91% (10/11)
lib/yaml/rubytypes.rb.cov 74.58% (176/236)
lib/yaml/syck.rb.cov 100.00% (6/6)
lib/yaml/store.rb.cov 95.83% (23/24)
lib/yaml/tag.rb.cov 88.89% (16/18)
lib/yaml/stream.rb.cov 61.11% (11/18)
lib/yaml/constants.rb.cov 100.00% (15/15)
lib/yaml/types.rb.cov 49.02% (50/102)
lib/yaml/ypath.rb.cov 92.59% (25/27)
lib/yaml/error.rb.cov 100.00% (18/18)
lib/yaml/basenode.rb.cov 15.38% (16/104)
lib/tempfile.rb.cov 79.59% (78/98)
lib/rdoc.rb.cov 100.00% (11/11)
lib/fileutils.rb.cov 81.93% (544/664)
lib/rexml/node.rb.cov 44.44% (16/36)
lib/rexml/rexml.rb.cov 100.00% (7/7)
lib/rexml/attribute.rb.cov 72.22% (52/72)
lib/rexml/streamlistener.rb.cov 100.00% (16/16)
lib/rexml/parseexception.rb.cov 28.57% (8/28)
lib/rexml/syncenumerator.rb.cov 50.00% (7/14)
lib/rexml/undefinednamespaceexception.rb.cov 80.00% (4/5)
lib/rexml/encodings/UTF-8.rb.cov 100.00% (10/10)
lib/rexml/encodings/ICONV.rb.cov 100.00% (13/13)
lib/rexml/text.rb.cov 47.13% (74/157)
lib/rexml/xpath_parser.rb.cov 33.78% (125/370)
lib/rexml/functions.rb.cov 27.39% (43/157)
lib/rexml/encoding.rb.cov 73.33% (33/45)
lib/rexml/validation/validationexception.rb.cov 80.00% (4/5)
lib/rexml/source.rb.cov 54.92% (67/122)
lib/rexml/document.rb.cov 68.75% (55/80)
lib/rexml/xpath.rb.cov 80.65% (25/31)
lib/rexml/formatters/pretty.rb.cov 22.22% (16/72)
lib/rexml/formatters/default.rb.cov 78.43% (40/51)
lib/rexml/element.rb.cov 45.36% (181/399)
lib/rexml/doctype.rb.cov 37.60% (47/125)
lib/rexml/instruction.rb.cov 56.25% (18/32)
lib/rexml/attlistdecl.rb.cov 60.00% (12/20)
lib/rexml/entity.rb.cov 52.94% (45/85)
lib/rexml/parsers/baseparser.rb.cov 61.00% (183/300)
lib/rexml/parsers/xpathparser.rb.cov 45.59% (181/397)
lib/rexml/parsers/streamparser.rb.cov 83.33% (20/24)
lib/rexml/parsers/treeparser.rb.cov 51.72% (30/58)
lib/rexml/xmldecl.rb.cov 80.88% (55/68)
lib/rexml/comment.rb.cov 51.85% (14/27)
lib/rexml/output.rb.cov 61.54% (8/13)
lib/rexml/cdata.rb.cov 55.00% (11/20)
lib/rexml/xmltokens.rb.cov 100.00% (9/9)
lib/rexml/parent.rb.cov 58.67% (44/75)
lib/rexml/namespace.rb.cov 81.82% (18/22)
lib/rexml/child.rb.cov 70.00% (21/30)
lib/rinda/tuplespace.rb.cov 66.67% (152/228)
lib/rinda/rinda.rb.cov 67.47% (56/83)
lib/delegate.rb.cov 54.44% (49/90)
lib/ostruct.rb.cov 58.93% (33/56)
lib/pathname.rb.cov 83.97% (309/368)
lib/pp.rb.cov 41.95% (146/348)
lib/open-uri.rb.cov 18.48% (61/330)
lib/e2mmap.rb.cov 68.29% (28/41)
lib/rubygems/source_index.rb.cov 94.12% (208/221)
lib/rubygems/ext/rake_builder.rb.cov 90.91% (10/11)
lib/rubygems/ext/ext_conf_builder.rb.cov 100.00% (8/8)
lib/rubygems/ext/builder.rb.cov 100.00% (27/27)
lib/rubygems/ext/configure_builder.rb.cov 100.00% (8/8)
lib/rubygems/spec_fetcher.rb.cov 96.23% (102/106)
lib/rubygems/dependency_list.rb.cov 86.76% (59/68)
lib/rubygems/command_manager.rb.cov 85.39% (76/89)
lib/rubygems/package.rb.cov 64.81% (35/54)
lib/rubygems/server.rb.cov 78.66% (129/164)
lib/rubygems/exceptions.rb.cov 100.00% (28/28)
lib/rubygems/command.rb.cov 90.18% (147/163)
lib/rubygems/source_info_cache.rb.cov 93.20% (137/147)
lib/rubygems/rubygems_version.rb.cov 100.00% (2/2)
lib/rubygems/install_update_options.rb.cov 94.74% (36/38)
lib/rubygems/source_info_cache_entry.rb.cov 91.30% (21/23)
lib/rubygems/security.rb.cov 72.99% (100/137)
lib/rubygems/version.rb.cov 98.25% (56/57)
lib/rubygems/remote_fetcher.rb.cov 90.28% (130/144)
lib/rubygems/config_file.rb.cov 94.12% (112/119)
lib/rubygems/dependency.rb.cov 95.12% (39/41)
lib/rubygems/local_remote_options.rb.cov 97.73% (43/44)
lib/rubygems/digest/md5.rb.cov 50.00% (4/8)
lib/rubygems/digest/sha2.rb.cov 66.67% (4/6)
lib/rubygems/digest/sha1.rb.cov 66.67% (4/6)
lib/rubygems/commands/mirror_command.rb.cov 14.55% (8/55)
lib/rubygems/commands/fetch_command.rb.cov 85.71% (30/35)
lib/rubygems/commands/outdated_command.rb.cov 100.00% (19/19)
lib/rubygems/commands/pristine_command.rb.cov 95.00% (38/40)
lib/rubygems/commands/unpack_command.rb.cov 89.74% (35/39)
lib/rubygems/commands/dependency_command.rb.cov 89.58% (86/96)
lib/rubygems/commands/server_command.rb.cov 94.12% (16/17)
lib/rubygems/commands/cert_command.rb.cov 100.00% (45/45)
lib/rubygems/commands/update_command.rb.cov 64.84% (59/91)
lib/rubygems/commands/specification_command.rb.cov 88.10% (37/42)
lib/rubygems/commands/generate_index_command.rb.cov 41.18% (7/17)
lib/rubygems/commands/stale_command.rb.cov 93.75% (15/16)
lib/rubygems/commands/contents_command.rb.cov 91.89% (34/37)
lib/rubygems/commands/build_command.rb.cov 96.55% (28/29)
lib/rubygems/commands/sources_command.rb.cov 92.41% (73/79)
lib/rubygems/commands/query_command.rb.cov 98.33% (118/120)
lib/rubygems/commands/install_command.rb.cov 81.67% (49/60)
lib/rubygems/commands/check_command.rb.cov 33.33% (14/42)
lib/rubygems/commands/uninstall_command.rb.cov 66.67% (22/33)
lib/rubygems/commands/environment_command.rb.cov 95.45% (42/44)
lib/rubygems/uninstaller.rb.cov 15.46% (15/97)
lib/rubygems/installer.rb.cov 97.99% (195/199)
lib/rubygems/indexer.rb.cov 14.88% (25/168)
lib/rubygems/defaults.rb.cov 80.95% (17/21)
lib/rubygems/builder.rb.cov 91.67% (33/36)
lib/rubygems/format.rb.cov 92.59% (25/27)
lib/rubygems/gem_runner.rb.cov 51.61% (16/31)
lib/rubygems/package/tar_writer.rb.cov 98.89% (89/90)
lib/rubygems/package/tar_input.rb.cov 79.81% (83/104)
lib/rubygems/package/tar_reader/entry.rb.cov 100.00% (50/50)
lib/rubygems/package/tar_header.rb.cov 100.00% (63/63)
lib/rubygems/package/f_sync_dir.rb.cov 85.71% (6/7)
lib/rubygems/package/tar_output.rb.cov 86.27% (44/51)
lib/rubygems/package/tar_reader.rb.cov 84.62% (33/39)
lib/rubygems/gem_openssl.rb.cov 67.86% (19/28)
lib/rubygems/ext.rb.cov 100.00% (6/6)
lib/rubygems/user_interaction.rb.cov 83.19% (99/119)
lib/rubygems/dependency_installer.rb.cov 93.75% (105/112)
lib/rubygems/require_paths_builder.rb.cov 40.00% (4/10)
lib/rubygems/version_option.rb.cov 100.00% (17/17)
lib/rubygems/platform.rb.cov 94.57% (87/92)
lib/rubygems/requirement.rb.cov 100.00% (61/61)
lib/rubygems/gem_path_searcher.rb.cov 100.00% (19/19)
lib/rubygems/test_utilities.rb.cov 100.00% (54/54)
lib/rubygems/doc_manager.rb.cov 63.16% (48/76)
lib/rubygems/specification.rb.cov 90.23% (397/440)
lib/rubygems/validator.rb.cov 35.96% (32/89)
lib/date.rb.cov 48.27% (307/636)
lib/singleton.rb.cov 24.44% (33/135)
lib/prettyprint.rb.cov 39.55% (157/397)
lib/timeout.rb.cov 70.73% (29/41)
lib/set.rb.cov 91.18% (186/204)
lib/rubygems.rb.cov 91.90% (261/284)
lib/erb.rb.cov 95.47% (274/287)
lib/webrick.rb.cov 100.00% (17/17)
lib/tmpdir.rb.cov 60.38% (32/53)
lib/shellwords.rb.cov 77.78% (28/36)
lib/monitor.rb.cov 87.65% (71/81)
lib/rss.rb.cov 100.00% (12/12)
lib/thread.rb.cov 76.86% (93/121)
lib/open3.rb.cov 59.26% (16/27)
lib/pstore.rb.cov 72.47% (129/178)
lib/find.rb.cov 82.61% (19/23)
lib/xmlrpc/config.rb.cov 100.00% (10/10)
lib/xmlrpc/server.rb.cov 48.29% (113/234)
lib/xmlrpc/create.rb.cov 78.18% (86/110)
lib/xmlrpc/parser.rb.cov 51.20% (213/416)
lib/xmlrpc/utils.rb.cov 57.58% (38/66)
lib/xmlrpc/datetime.rb.cov 100.00% (36/36)
lib/xmlrpc/marshal.rb.cov 100.00% (29/29)
lib/xmlrpc/client.rb.cov 57.14% (100/175)
lib/xmlrpc/base64.rb.cov 80.00% (12/15)
lib/uri.rb.cov 100.00% (11/11)
lib/forwardable.rb.cov 75.00% (15/20)
lib/optparse.rb.cov 77.87% (482/619)
lib/yaml.rb.cov 72.53% (66/91)
lib/webrick/config.rb.cov 100.00% (13/13)
lib/webrick/server.rb.cov 77.31% (92/119)
lib/webrick/httprequest.rb.cov 90.53% (220/243)
lib/webrick/utils.rb.cov 90.72% (88/97)
lib/webrick/compat.rb.cov 100.00% (4/4)
lib/webrick/httpauth/digestauth.rb.cov 14.78% (30/203)
lib/webrick/httpauth/basicauth.rb.cov 86.11% (31/36)
lib/webrick/httpauth/htpasswd.rb.cov 93.33% (42/45)
lib/webrick/httpauth/htdigest.rb.cov 26.92% (14/52)
lib/webrick/httpauth/htgroup.rb.cov 27.27% (9/33)
lib/webrick/httpauth/authenticator.rb.cov 86.96% (40/46)
lib/webrick/httpauth/userdb.rb.cov 80.00% (8/10)
lib/webrick/version.rb.cov 100.00% (2/2)
lib/webrick/log.rb.cov 84.78% (39/46)
lib/webrick/httpservlet.rb.cov 100.00% (9/9)
lib/webrick/https.rb.cov 69.70% (23/33)
lib/webrick/httpproxy.rb.cov 83.77% (129/154)
lib/webrick/httputils.rb.cov 78.50% (168/214)
lib/webrick/ssl.rb.cov 60.29% (41/68)
lib/webrick/htmlutils.rb.cov 100.00% (10/10)
lib/webrick/httpservlet/filehandler.rb.cov 80.59% (191/237)
lib/webrick/httpservlet/prochandler.rb.cov 100.00% (11/11)
lib/webrick/httpservlet/abstract.rb.cov 71.43% (25/35)
lib/webrick/httpservlet/cgihandler.rb.cov 80.88% (55/68)
lib/webrick/httpservlet/erbhandler.rb.cov 38.46% (10/26)
lib/webrick/httpserver.rb.cov 87.68% (121/138)
lib/webrick/httpversion.rb.cov 90.00% (18/20)
lib/webrick/httpstatus.rb.cov 88.10% (37/42)
lib/webrick/httpauth.rb.cov 95.45% (21/22)
lib/webrick/httpresponse.rb.cov 67.93% (125/184)
lib/webrick/cookie.rb.cov 92.54% (62/67)
lib/webrick/accesslog.rb.cov 82.93% (34/41)
lib/logger.rb.cov 79.69% (153/192)
lib/cgi.rb.cov 17.86% (115/644)
lib/scanf.rb.cov 98.43% (188/191)
lib/ipaddr.rb.cov 78.35% (181/231)
lib/time.rb.cov 38.83% (160/412)
lib/English.rb.cov 100.00% (25/25)
lib/tsort.rb.cov 57.75% (41/71)
lib/rational.rb.cov 100.00% (10/10)
.ext/common/io/nonblock.rb.cov 64.29% (9/14)
.ext/common/json/add/core.rb.cov 97.83% (45/46)
.ext/common/json/add/rails.rb.cov 42.86% (9/21)
.ext/common/json/version.rb.cov 100.00% (7/7)
.ext/common/json/common.rb.cov 64.71% (77/119)
.ext/common/json/ext.rb.cov 100.00% (8/8)
.ext/common/openssl.rb.cov 100.00% (6/6)
.ext/common/ripper.rb.cov 100.00% (4/4)
.ext/common/digest/hmac.rb.cov 90.24% (37/41)
.ext/common/digest/sha2.rb.cov 46.43% (13/28)
.ext/common/ripper/lexer.rb.cov 60.56% (43/71)
.ext/common/ripper/sexp.rb.cov 90.48% (19/21)
.ext/common/ripper/filter.rb.cov 41.67% (10/24)
.ext/common/ripper/core.rb.cov 93.75% (15/16)
.ext/common/kconv.rb.cov 94.29% (66/70)
.ext/common/json.rb.cov 77.78% (7/9)
.ext/common/openssl/x509.rb.cov 83.33% (70/84)
.ext/common/openssl/ssl.rb.cov 95.65% (88/92)
.ext/common/openssl/cipher.rb.cov 81.82% (18/22)
.ext/common/openssl/buffering.rb.cov 83.09% (113/136)
.ext/common/openssl/bn.rb.cov 83.33% (5/6)
.ext/common/openssl/digest.rb.cov 95.24% (20/21)
.ext/common/digest.rb.cov 58.33% (14/24)
(total) 66.40% (23543/35456)

ご検討お願いします。

-- 
Yusuke ENDOH <mame@tsg.ne.jp>

Attachments (1)

coverage.patch (10.8 KB, text/x-diff)
Index: insns.def
===================================================================
--- insns.def	(revision 17736)
+++ insns.def	(working copy)
@@ -897,11 +897,21 @@
  */
 DEFINE_INSN
 trace
-(rb_num_t nf)
+(rb_num_t nf, VALUE coverage)
 ()
 ()
 {
     rb_event_flag_t flag = nf;
+    if (coverage) {
+	long line = rb_sourceline() - 1;
+	if (RARRAY_PTR(coverage)[line] == Qnil) {
+	    rb_bug("bug");
+	}
+	long count = FIX2LONG(RARRAY_PTR(coverage)[line]) + 1;
+	if (POSFIXABLE(count)) {
+	    RARRAY_PTR(coverage)[line] = LONG2FIX(count);
+	}
+    }
     EXEC_EVENT_HOOK(th, flag, GET_SELF(), 0, 0 /* TODO: id, klass */);
 }
 
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 17736)
+++ vm_core.h	(working copy)
@@ -201,6 +201,7 @@
     VALUE *iseq_encoded; /* encoded iseq */
     unsigned long iseq_size;
     VALUE mark_ary;	/* Array: includes operands which should be GC marked */
+    VALUE coverage;     /* coverage array */
 
     /* insn info, must be freed */
     struct iseq_insn_info_entry *insn_info_table;
@@ -448,6 +449,7 @@
     struct rb_vm_trap_tag *trap_tag;
 
     int parse_in_eval;
+    int mild_compile_error;
 
     /* storage */
     st_table *local_storage;
Index: iseq.c
===================================================================
--- iseq.c	(revision 17736)
+++ iseq.c	(working copy)
@@ -81,6 +81,7 @@
 	RUBY_MARK_UNLESS_NULL(iseq->filename);
 	RUBY_MARK_UNLESS_NULL((VALUE)iseq->cref_stack);
 	RUBY_MARK_UNLESS_NULL(iseq->klass);
+	RUBY_MARK_UNLESS_NULL(iseq->coverage);
 /* 	RUBY_MARK_UNLESS_NULL((VALUE)iseq->node); */
 /*	RUBY_MARK_UNLESS_NULL(iseq->cached_special_block); */
 
@@ -191,6 +192,17 @@
 
     set_relation(iseq, parent);
 
+    iseq->coverage = Qfalse;
+    if (!GET_THREAD()->parse_in_eval) {
+	if (rb_const_defined_at(rb_cObject, rb_intern("COVERAGE__"))) {
+	    VALUE hash = rb_const_get_at(rb_cObject, rb_intern("COVERAGE__"));
+	    if (TYPE(hash) == T_HASH) {
+		iseq->coverage = rb_hash_aref(hash, filename);
+		if (NIL_P(iseq->coverage)) iseq->coverage = Qfalse;
+	    }
+	}
+    }
+
     return Qtrue;
 }
 
Index: load.c
===================================================================
--- load.c	(revision 17736)
+++ load.c	(working copy)
@@ -240,8 +240,8 @@
     rb_thread_t *th = GET_THREAD();
     volatile VALUE wrapper = th->top_wrapper;
     volatile VALUE self = th->top_self;
-    volatile int parse_in_eval;
     volatile int loaded = Qfalse;
+    volatile int mild_compile_error;
 #ifndef __GNUC__
     rb_thread_t *volatile th0 = th;
 #endif
@@ -267,19 +267,19 @@
 	rb_extend_object(th->top_self, th->top_wrapper);
     }
 
-    parse_in_eval = th->parse_in_eval;
+    mild_compile_error = th->mild_compile_error;
     PUSH_TAG();
     state = EXEC_TAG();
     if (state == 0) {
 	NODE *node;
 	VALUE iseq;
 
-	th->parse_in_eval++;
+	th->mild_compile_error++;
 	node = (NODE *)rb_load_file(RSTRING_PTR(fname));
-	th->parse_in_eval--;
 	loaded = Qtrue;
 	iseq = rb_iseq_new(node, rb_str_new2("<top (required)>"),
 			   fname, Qfalse, ISEQ_TYPE_TOP);
+	th->mild_compile_error--;
 	rb_iseq_eval(iseq);
     }
     POP_TAG();
@@ -288,7 +288,7 @@
     th = th0;
     fname = RB_GC_GUARD(fname);
 #endif
-    th->parse_in_eval = parse_in_eval;
+    th->mild_compile_error = mild_compile_error;
     th->top_self = self;
     th->top_wrapper = wrapper;
 
Index: lib/coverage.rb
===================================================================
--- lib/coverage.rb	(revision 0)
+++ lib/coverage.rb	(revision 0)
@@ -0,0 +1,57 @@
+COVERAGE__ ||= {}
+ext = ENV["COVERUBY_EXT"] || ".cov"
+accum = ENV["COVERUBY_ACCUM"]
+accum = !accum || accum == "" || !(%w(f n 0).include?(accum[0]))
+pwd = Dir.pwd
+
+at_exit do
+  Dir.chdir(pwd) do
+    COVERAGE__.each do |sfile, covs|
+      cfile = sfile + ext
+
+      writable = proc do |f|
+        File.writable?(f) || File.writable?(File.dirname(f))
+      end
+      unless writable[cfile]
+        cfile = cfile.gsub(File.PATH_SEPARATOR, "#")
+        next unless writable[cfile]
+      end
+
+      readlines = proc do |f|
+        File.read(f).force_encoding("ASCII-8BIT").lines.to_a
+      end
+
+      sources = (readlines[sfile] rescue [])
+
+      pcovs = []
+      if accum
+        pcovs = (readlines[cfile] rescue []).map.with_index do |line, idx|
+          if line[/^\s*(?:(#####)|(\d+)|-):\s*\d+:(.*)$/n]
+            cov, line = $1 ? 0 : ($2 ? $2.to_i : nil), $3
+            if !sources[idx] || sources[idx].chomp != line.chomp
+              warn("source file changed, ignoring: `#{ cfile }'")
+              break []
+            end
+            cov
+          else
+	    p line
+            warn("coverage file corrupted, ignoring: #{ cfile }")
+            break []
+          end
+        end
+        unless pcovs.empty? || pcovs.size == covs.size
+          warn("coverage file changed, ignoring: `#{ cfile }'")
+          pcovs = []
+        end
+      end
+
+      open(cfile, "w") do |out|
+        covs.zip(sources, pcovs).each_with_index do |(cov, line, pcov), idx|
+          cov += pcov || 0 if cov
+          cov = (cov ? (cov == 0 ? "#####" : cov.to_s) : "-").rjust(9)
+          out.puts("%s:% 5d:%s" % [cov, idx + 1, line])
+        end
+      end
+    end
+  end
+end
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 17736)
+++ vm_eval.c	(working copy)
@@ -667,6 +667,7 @@
     rb_env_t *env = NULL;
     rb_block_t block;
     volatile int parse_in_eval;
+    volatile int mild_compile_error;
 
     if (file == 0) {
 	file = rb_sourcefile();
@@ -674,6 +675,7 @@
     }
 
     parse_in_eval = th->parse_in_eval;
+    mild_compile_error = th->mild_compile_error;
     PUSH_TAG();
     if ((state = EXEC_TAG()) == 0) {
 	rb_iseq_t *iseq;
@@ -708,7 +710,9 @@
 
 	/* make eval iseq */
 	th->parse_in_eval++;
+	th->mild_compile_error++;
 	iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line));
+	th->mild_compile_error--;
 	th->parse_in_eval--;
 
 	vm_set_eval_stack(th, iseqval, cref);
@@ -730,6 +734,7 @@
 	result = vm_eval_body(th);
     }
     POP_TAG();
+    th->mild_compile_error = mild_compile_error;
     th->parse_in_eval = parse_in_eval;
 
     if (state) {
Index: compile.h
===================================================================
--- compile.h	(revision 17736)
+++ compile.h	(working copy)
@@ -163,9 +163,16 @@
                          (VALUE)id, (VALUE)argc, (VALUE)block, (VALUE)flag))
 
 #define ADD_TRACE(seq, line, event) \
-  if (iseq->compile_data->option->trace_instruction) { \
-      ADD_INSN1(seq, line, trace, INT2FIX(event)); \
-  }
+  do { \
+      VALUE coverage = Qfalse; \
+      if ((event) == RUBY_EVENT_LINE && iseq->coverage && RARRAY_PTR(iseq->coverage)[(line) - 1] == Qnil) { \
+          RARRAY_PTR(iseq->coverage)[(line) - 1] = INT2FIX(0); \
+          coverage = iseq->coverage; \
+      } \
+      if (iseq->compile_data->option->trace_instruction || coverage) { \
+          ADD_INSN2(seq, line, trace, INT2FIX(event), coverage); \
+      } \
+  }while(0);
 
 /* add label */
 #define ADD_LABEL(seq, label) \
Index: thread.c
===================================================================
--- thread.c	(revision 17736)
+++ thread.c	(working copy)
@@ -2100,6 +2100,31 @@
 }
 
 static int
+clear_coverage_i(st_data_t key, st_data_t val, st_data_t dummy)
+{
+    int i;
+    VALUE lines = (VALUE)val;
+
+    for (i = 0; i < RARRAY_LEN(lines); i++) {
+	if (RARRAY_PTR(lines)[i] != Qnil) {
+	    RARRAY_PTR(lines)[i] = INT2FIX(0);
+	}
+    }
+    return ST_CONTINUE;
+}
+
+static void
+clear_coverage(void)
+{
+    if (rb_const_defined_at(rb_cObject, rb_intern("COVERAGE__"))) {
+	VALUE hash = rb_const_get_at(rb_cObject, rb_intern("COVERAGE__"));
+	if (TYPE(hash) == T_HASH) {
+	    st_foreach(RHASH_TBL(hash), clear_coverage_i, 0);
+	}
+    }
+}
+
+static int
 terminate_atfork_i(st_data_t key, st_data_t val, rb_thread_t *current_th)
 {
     VALUE thval = key;
@@ -2124,6 +2149,7 @@
     st_clear(vm->living_threads);
     st_insert(vm->living_threads, thval, (st_data_t) th->thread_id);
     vm->sleeper = 0;
+    clear_coverage();
     rb_reset_random_seed();
 }
 
@@ -2152,6 +2178,7 @@
     st_clear(vm->living_threads);
     st_insert(vm->living_threads, thval, (st_data_t) th->thread_id);
     vm->sleeper = 0;
+    clear_coverage();
 }
 
 struct thgroup {
Index: parse.y
===================================================================
--- parse.y	(revision 17736)
+++ parse.y	(working copy)
@@ -249,6 +249,7 @@
     NODE *parser_eval_tree_begin;
     NODE *parser_eval_tree;
     VALUE debug_lines;
+    VALUE coverage;
     int nerr;
 #else
     /* Ripper only */
@@ -322,6 +323,7 @@
 #define ruby_eval_tree		(parser->parser_eval_tree)
 #define ruby_eval_tree_begin	(parser->parser_eval_tree_begin)
 #define ruby_debug_lines	(parser->debug_lines)
+#define ruby_coverage		(parser->coverage)
 #endif
 
 static int yylex(void*, void*);
@@ -4668,6 +4670,32 @@
 }
 
 static VALUE
+coverage(const char *f, int n)
+{
+    if (rb_const_defined_at(rb_cObject, rb_intern("COVERAGE__"))) {
+	VALUE hash = rb_const_get_at(rb_cObject, rb_intern("COVERAGE__"));
+	if (TYPE(hash) == T_HASH) {
+	    VALUE fname = rb_str_new2(f);
+	    VALUE lines = rb_ary_new2(n);
+	    int i;
+	    for (i = 0; i < n; i++) RARRAY_PTR(lines)[i] = Qnil;
+	    RARRAY(lines)->len = n;
+	    rb_hash_aset(hash, fname, lines);
+	    return lines;
+	}
+    }
+    return 0;
+}
+
+static int
+e_option_supplied(struct parser_params *parser)
+{
+    if (strcmp(ruby_sourcefile, "-e") == 0)
+	return Qtrue;
+    return Qfalse;
+}
+
+static VALUE
 yycompile0(VALUE arg, int tracing)
 {
     int n;
@@ -4683,11 +4711,19 @@
 		rb_ary_push(ruby_debug_lines, str);
 	    } while (--n);
 	}
+
+	if (!e_option_supplied(parser)) {
+	    ruby_coverage = coverage(ruby_sourcefile, ruby_sourceline);
+	}
     }
 
     parser_prepare(parser);
     n = yyparse((void*)parser);
+    if (ruby_coverage) {
+	rb_ary_freeze(ruby_coverage);
+    }
     ruby_debug_lines = 0;
+    ruby_coverage = 0;
     compile_for_eval = 0;
 
     lex_strterm = 0;
@@ -4750,6 +4786,9 @@
     if (ruby_debug_lines && !NIL_P(line)) {
 	rb_ary_push(ruby_debug_lines, line);
     }
+    if (ruby_coverage && !NIL_P(line)) {
+	rb_ary_push(ruby_coverage, Qnil);
+    }
 #endif
     return line;
 }
@@ -8126,14 +8165,6 @@
     return 1;
 }
 
-static int
-e_option_supplied(struct parser_params *parser)
-{
-    if (strcmp(ruby_sourcefile, "-e") == 0)
-	return Qtrue;
-    return Qfalse;
-}
-
 static void
 warn_unless_e_option(struct parser_params *parser, NODE *node, const char *str)
 {
Index: error.c
===================================================================
--- error.c	(revision 17736)
+++ error.c	(working copy)
@@ -1546,7 +1546,7 @@
     rb_thread_t *th = GET_THREAD();
     VALUE err = th->errinfo;
 
-    if (th->parse_in_eval) {
+    if (th->mild_compile_error) {
 	if (!RTEST(err)) {
 	    err = rb_exc_new2(rb_eSyntaxError, s);
 	    th->errinfo = err;

In This Thread

Prev Next