rcodetools 0.7.0.0 → 0.8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +12 -0
- data/README +1 -1
- data/README.emacs +21 -4
- data/README.ja +1 -1
- data/README.xmpfilter +159 -74
- data/Rakefile +3 -37
- data/anything-rcodetools.el +142 -0
- data/bin/rct-complete +1 -1
- data/bin/rct-doc +1 -1
- data/bin/rct-meth-args +33 -2
- data/bin/xmpfilter +5 -1
- data/lib/rcodetools/compat.rb +14 -0
- data/lib/rcodetools/completion.rb +8 -6
- data/lib/rcodetools/fork.rb +15 -8
- data/lib/rcodetools/options.rb +8 -0
- data/lib/rcodetools/xmpfilter.rb +80 -33
- data/lib/rcodetools/xmptestunitfilter.rb +76 -21
- data/lib/ruby_toggle_file.rb +1 -1
- data/rcodetools.el +213 -20
- data/test/test_functional.rb +36 -68
- data/test/test_method_analyzer.rb +28 -20
- data/test/test_ruby_toggle_file.rb +118 -69
- data/test/test_xmpfilter.rb +75 -47
- data/test/test_xmptestunitfilter.rb +12 -11
- metadata +83 -133
- data/test/data/add_markers-input.rb +0 -2
- data/test/data/add_markers-output.rb +0 -2
- data/test/data/bindings-input.rb +0 -26
- data/test/data/bindings-output.rb +0 -31
- data/test/data/completion-input.rb +0 -1
- data/test/data/completion-output.rb +0 -2
- data/test/data/completion_class_info-input.rb +0 -1
- data/test/data/completion_class_info-output.rb +0 -10
- data/test/data/completion_class_info_no_candidates-input.rb +0 -1
- data/test/data/completion_class_info_no_candidates-output.rb +0 -1
- data/test/data/completion_detect_rbtest-input.rb +0 -7
- data/test/data/completion_detect_rbtest-output.rb +0 -2
- data/test/data/completion_detect_rbtest2-input.rb +0 -1
- data/test/data/completion_detect_rbtest2-output.rb +0 -2
- data/test/data/completion_emacs-input.rb +0 -1
- data/test/data/completion_emacs-output.rb +0 -6
- data/test/data/completion_emacs_icicles-input.rb +0 -1
- data/test/data/completion_emacs_icicles-output.rb +0 -6
- data/test/data/completion_in_method-input.rb +0 -3
- data/test/data/completion_in_method-output.rb +0 -1
- data/test/data/completion_in_method-test.rb +0 -6
- data/test/data/completion_rbtest-input.rb +0 -7
- data/test/data/completion_rbtest-output.rb +0 -2
- data/test/data/doc-input.rb +0 -1
- data/test/data/doc-output.rb +0 -1
- data/test/data/doc_detect_rbtest-input.rb +0 -1
- data/test/data/doc_detect_rbtest-output.rb +0 -1
- data/test/data/doc_detect_rbtest2-input.rb +0 -7
- data/test/data/doc_detect_rbtest2-output.rb +0 -1
- data/test/data/doc_rbtest-input.rb +0 -7
- data/test/data/doc_rbtest-output.rb +0 -1
- data/test/data/no_warnings-input.rb +0 -3
- data/test/data/no_warnings-output.rb +0 -4
- data/test/data/refe-input.rb +0 -1
- data/test/data/refe-output.rb +0 -1
- data/test/data/ri-input.rb +0 -1
- data/test/data/ri-output.rb +0 -1
- data/test/data/ri_emacs-input.rb +0 -1
- data/test/data/ri_emacs-output.rb +0 -1
- data/test/data/ri_vim-input.rb +0 -1
- data/test/data/ri_vim-output.rb +0 -1
- data/test/data/rspec-input.rb +0 -48
- data/test/data/rspec-output.rb +0 -52
- data/test/data/rspec_poetry-input.rb +0 -48
- data/test/data/rspec_poetry-output.rb +0 -52
- data/test/data/simple_annotation-input.rb +0 -8
- data/test/data/simple_annotation-output.rb +0 -8
- data/test/data/unit_test-input.rb +0 -50
- data/test/data/unit_test-output.rb +0 -52
- data/test/data/unit_test_detect_rbtest-input.rb +0 -50
- data/test/data/unit_test_detect_rbtest-output.rb +0 -52
- data/test/data/unit_test_detect_rbtest2-input.rb +0 -6
- data/test/data/unit_test_detect_rbtest2-output.rb +0 -6
- data/test/data/unit_test_poetry-input.rb +0 -50
- data/test/data/unit_test_poetry-output.rb +0 -52
- data/test/data/unit_test_rbtest-input.rb +0 -6
- data/test/data/unit_test_rbtest-output.rb +0 -6
- data/test/test_run.rb +0 -45
data/bin/rct-complete
CHANGED
data/bin/rct-doc
CHANGED
data/bin/rct-meth-args
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#! /home/
|
1
|
+
#! /home/mfp/ruby1.8/bin/ruby
|
2
2
|
# Copyright (c)
|
3
3
|
# 2006-2007 Mauricio Fernandez <mfp@acm.org> http://eigenclass.org
|
4
4
|
# 2006-2007 rubikitch <rubikitch@ruby-lang.org> http://www.rubyist.net/~rubikitch/
|
@@ -6,6 +6,7 @@
|
|
6
6
|
# Use and distribution subject to the same conditions as Ruby.
|
7
7
|
|
8
8
|
require 'rcodetools/options'
|
9
|
+
include Rcodetools
|
9
10
|
$VERBOSE = nil
|
10
11
|
$__method_args_off = true
|
11
12
|
|
@@ -22,6 +23,7 @@ rct-meth-args [-Idirectory] [-i] [-m] [-c] [-n] <file> [<file> ...]
|
|
22
23
|
|
23
24
|
-n print the filename and line number with output lines
|
24
25
|
-t generate TAGS output
|
26
|
+
--summarize summary output sorted by method name
|
25
27
|
|
26
28
|
The given files will be #require()d in order.
|
27
29
|
Examples:
|
@@ -29,7 +31,7 @@ Examples:
|
|
29
31
|
rct-meth-args thread
|
30
32
|
rct-meth-args -c rubygems
|
31
33
|
EOF
|
32
|
-
exit
|
34
|
+
exit # '
|
33
35
|
end
|
34
36
|
|
35
37
|
def debugprint(*args)
|
@@ -98,6 +100,33 @@ module MethodArgs
|
|
98
100
|
end
|
99
101
|
end
|
100
102
|
|
103
|
+
class SummarizePrinter
|
104
|
+
def initialize
|
105
|
+
@hash = Hash.new
|
106
|
+
at_exit { print_result }
|
107
|
+
end
|
108
|
+
|
109
|
+
def method_info(io, x)
|
110
|
+
@io = io
|
111
|
+
prefix = x[:location] ? "#{x[:location].filename}:#{x[:location].lineno}:" : ""
|
112
|
+
(@hash[x[:meth]]||=[]) << "#{prefix}#{x[:fullname]}#{x[:arg_desc]}" unless x[:klass].to_s == "<Struct>"
|
113
|
+
end
|
114
|
+
|
115
|
+
def included_location(io, x)
|
116
|
+
# not implemented
|
117
|
+
end
|
118
|
+
|
119
|
+
def print_result
|
120
|
+
@hash.keys.sort.each do |meth|
|
121
|
+
@io.puts meth
|
122
|
+
@hash[meth].each do |line|
|
123
|
+
@io.puts line
|
124
|
+
end
|
125
|
+
@io.puts
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
101
130
|
class TagsPrinter
|
102
131
|
def initialize
|
103
132
|
@previous_filename = ""
|
@@ -129,6 +158,7 @@ module MethodArgs
|
|
129
158
|
arg_desc = " " + arg_desc unless arg_desc.empty?
|
130
159
|
flag = is_singleton ? "." : "#"
|
131
160
|
x = { :arg_desc => arg_desc, :klass => klass,
|
161
|
+
:meth => meth.to_s,
|
132
162
|
:fullname => [klass, flag, meth].join,
|
133
163
|
:location => with_location && location,
|
134
164
|
}
|
@@ -255,6 +285,7 @@ ARGV.each do |arg|
|
|
255
285
|
case arg
|
256
286
|
when "-n"; $__with_location = true
|
257
287
|
when "-t"; $__printer = TagsPrinter.new; $__with_location = true
|
288
|
+
when "--summarize"; $__printer = SummarizePrinter.new
|
258
289
|
when /-I(.+)$/; $:.unshift $1
|
259
290
|
when "-I"; i_opt_p = true
|
260
291
|
when "--dev"; OptionHandler.auto_include_paths($:, Dir.pwd)
|
data/bin/xmpfilter
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#! /home/
|
1
|
+
#! /home/mfp/ruby1.8/bin/ruby
|
2
2
|
require 'rcodetools/xmpfilter'
|
3
3
|
require 'rcodetools/options'
|
4
4
|
|
@@ -25,6 +25,10 @@ opts = OptionParser.new do |opts|
|
|
25
25
|
klass = XMPRSpecFilter
|
26
26
|
options[:interpreter] = "spec"
|
27
27
|
end
|
28
|
+
opts.on("--expectations", "Complete expectations expectations.") do
|
29
|
+
require 'rcodetools/xmptestunitfilter'
|
30
|
+
klass = XMPExpectationsFilter
|
31
|
+
end
|
28
32
|
opts.on("-m", "--markers", "Add # => markers.") do
|
29
33
|
klass = XMPAddMarkers
|
30
34
|
end
|
@@ -81,8 +81,8 @@ module ProcessParticularLine
|
|
81
81
|
def aref_or_aset?(right_stripped, last_char)
|
82
82
|
if last_char == ?[
|
83
83
|
case right_stripped
|
84
|
-
when /\]\s
|
85
|
-
when /\]
|
84
|
+
when /\]\s*=/ then "[]="
|
85
|
+
when /\]/ then "[]"
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
@@ -182,7 +182,7 @@ XXX
|
|
182
182
|
code = <<-EOC
|
183
183
|
#{result} = #{v}.method(#{meth}).inspect.match( %r[\\A#<(?:Unbound)?Method: (.*?)>\\Z] )[1].sub(/\\A.*?\\((.*?)\\)(.*)\\Z/){ "\#{$1}\#{$2}" }.sub(/#<Class:(.*?)>#/) { "\#{$1}." }
|
184
184
|
#{result} = #{v}.to_s + ".new" if #{result} == 'Class#new' and #{v}.private_method_defined?(:initialize)
|
185
|
-
#{result} = "Object#" + #{meth} if #{result} =~ /^Kernel#/ and Kernel.instance_methods(false).include? #{meth}
|
185
|
+
#{result} = "Object#" + #{meth} if #{result} =~ /^Kernel#/ and Kernel.instance_methods(false).map{|x| x.to_s}.include? #{meth}
|
186
186
|
#{result}
|
187
187
|
EOC
|
188
188
|
end
|
@@ -212,7 +212,9 @@ class XMPCompletionFilter < XMPFilter
|
|
212
212
|
|
213
213
|
def methods_map_code(recv)
|
214
214
|
# delimiter is \0
|
215
|
-
|
215
|
+
m = "#{VAR}_m"
|
216
|
+
mhc = magic_help_code((recv), m)
|
217
|
+
%Q[map{|%s| "\#{%s}\\0" + %s}] % [m, m, mhc]
|
216
218
|
end
|
217
219
|
|
218
220
|
def split_method_info(minfo)
|
@@ -235,7 +237,7 @@ class XMPCompletionFilter < XMPFilter
|
|
235
237
|
%Q[#$1.constants + #$1.methods(true).#{methods_map_code($1)}]
|
236
238
|
when /^[A-Z]\w*$/ # normal constants
|
237
239
|
__prepare_line 'nil', 'Module.constants', '%n'
|
238
|
-
when /^(.*::.+)\.(
|
240
|
+
when /^(.*::.+)\.(.*)$/ # toplevel class methods
|
239
241
|
@prefix = $2
|
240
242
|
__prepare_line $1, "#$1.methods",
|
241
243
|
%Q[%n.#{methods_map_code($1)}]
|
@@ -274,7 +276,7 @@ class XMPCompletionFilter < XMPFilter
|
|
274
276
|
idx = 1
|
275
277
|
oneline_ize(<<EOC)
|
276
278
|
#{rcv} = (#{recv})
|
277
|
-
#{v} = (#{all_completion_expr}).grep(/^#{Regexp.quote(@prefix)}/)
|
279
|
+
#{v} = (#{all_completion_expr}).map{|x| x.to_s}.grep(/^#{Regexp.quote(@prefix)}/)
|
278
280
|
#{rcv} = Module === #{rcv} ? #{rcv} : #{rcv}.class
|
279
281
|
$stderr.puts("#{MARKER}[#{idx}] => " + #{rcv}.to_s + " " + #{v}.join(" ")) || #{v}
|
280
282
|
exit
|
data/lib/rcodetools/fork.rb
CHANGED
@@ -39,7 +39,7 @@ rct-fork and rct-fork-client (we) are originally ruby_fork/ruby_fork_client in Z
|
|
39
39
|
Completion or document browsing in a script with heavy libraries such as Rails takes a significant latency.
|
40
40
|
We eliminate constant overhead of loading heavy libraries.
|
41
41
|
|
42
|
-
rct-fork loads libraries you want to pre-load and opens up a server socket and waits for connection. When a connection comes in rct-fork forks to make a copy of the environment.
|
42
|
+
rct-fork loads libraries you want to pre-load and opens up a server socket and waits for connection. When a connection comes in rct-fork forks to make a copy of the environment. rct-fork loads rubygems at startup.
|
43
43
|
|
44
44
|
rct-fork-client connects to the rct-fork server and runs script in server's environment.
|
45
45
|
|
@@ -89,10 +89,9 @@ XXX
|
|
89
89
|
Process.setsid
|
90
90
|
fork and exit!
|
91
91
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
# STDERR.reopen io
|
92
|
+
STDIN.reopen io
|
93
|
+
STDOUT.reopen io
|
94
|
+
STDERR.reopen io
|
96
95
|
|
97
96
|
yield if block_given?
|
98
97
|
end
|
@@ -170,6 +169,10 @@ XXX
|
|
170
169
|
end
|
171
170
|
|
172
171
|
def self.start_server(args = ARGV)
|
172
|
+
begin
|
173
|
+
require 'rubygems'
|
174
|
+
rescue LoadError
|
175
|
+
end
|
173
176
|
write_pwd
|
174
177
|
settings = parse_server_args args
|
175
178
|
setup_environment settings
|
@@ -212,9 +215,13 @@ XXX
|
|
212
215
|
settings[:extra_paths].flatten!
|
213
216
|
settings[:extra_paths].each { |dir| $:.unshift dir }
|
214
217
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
+
begin
|
219
|
+
settings[:requires].each { |file| require file }
|
220
|
+
settings[:code].each { |code| eval code, TOPLEVEL_BINDING }
|
221
|
+
rescue Exception
|
222
|
+
$@.reject! {|s| s =~ %r!rcodetools/fork\.rb!}
|
223
|
+
raise
|
224
|
+
end
|
218
225
|
end
|
219
226
|
|
220
227
|
end
|
data/lib/rcodetools/options.rb
CHANGED
@@ -66,6 +66,12 @@ module OptionHandler
|
|
66
66
|
on("--debug", "Write transformed source code to xmp-tmp.PID.rb.") do
|
67
67
|
options[:dump] = "xmp-tmp.#{Process.pid}.rb"
|
68
68
|
end
|
69
|
+
on("--tmpfile", "--tempfile", "Use tmpfile instead of open3. (non-windows)") do
|
70
|
+
options[:execute_ruby_tmpfile] = true
|
71
|
+
end
|
72
|
+
on("-w N", "--width N", Integer, "Set width of multi-line annotation. (xmpfilter only)") do |width|
|
73
|
+
options[:width] = width
|
74
|
+
end
|
69
75
|
separator ""
|
70
76
|
on("-h", "--help", "Show this message") do
|
71
77
|
puts self
|
@@ -110,6 +116,7 @@ DEFAULT_OPTIONS = {
|
|
110
116
|
:interpreter => "ruby",
|
111
117
|
:options => ["hoge"],
|
112
118
|
:min_codeline_size => 50,
|
119
|
+
:width => 79,
|
113
120
|
:libs => [],
|
114
121
|
:evals => [],
|
115
122
|
:include_paths => [],
|
@@ -124,5 +131,6 @@ DEFAULT_OPTIONS = {
|
|
124
131
|
:detect_rct_fork => false,
|
125
132
|
:use_rbtest => false,
|
126
133
|
:detect_rbtest => false,
|
134
|
+
:execute_ruby_tmpfile => false,
|
127
135
|
}
|
128
136
|
end # /Rcodetools
|
data/lib/rcodetools/xmpfilter.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# Copyright (c) 2005-
|
2
|
+
# Copyright (c) 2005-2008 Mauricio Fernandez <mfp@acm.org> http://eigenclass.org
|
3
3
|
# rubikitch <rubikitch@ruby-lang.org>
|
4
4
|
# Use and distribution subject to the terms of the Ruby license.
|
5
5
|
|
6
|
+
ENV['HOME'] ||= "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
|
6
7
|
require 'rcodetools/fork_config'
|
8
|
+
require 'rcodetools/compat'
|
9
|
+
require 'tmpdir'
|
7
10
|
|
8
11
|
module Rcodetools
|
9
12
|
|
10
13
|
class XMPFilter
|
11
|
-
VERSION = "0.
|
14
|
+
VERSION = "0.8.0"
|
12
15
|
|
13
16
|
MARKER = "!XMP#{Time.new.to_i}_#{Process.pid}_#{rand(1000000)}!"
|
14
17
|
XMP_RE = Regexp.new("^" + Regexp.escape(MARKER) + '\[([0-9]+)\] (=>|~>|==>) (.*)')
|
@@ -21,17 +24,18 @@ class XMPFilter
|
|
21
24
|
:include_paths => [], :warnings => true,
|
22
25
|
:use_parentheses => true}
|
23
26
|
|
24
|
-
def
|
27
|
+
def windows?
|
25
28
|
/win|mingw/ =~ RUBY_PLATFORM && /darwin/ !~ RUBY_PLATFORM
|
26
29
|
end
|
27
30
|
|
28
|
-
Interpreter = Struct.new(:options, :execute_method, :accept_debug, :chdir_proc)
|
31
|
+
Interpreter = Struct.new(:options, :execute_method, :accept_debug, :accept_include_paths, :chdir_proc)
|
29
32
|
INTERPRETER_RUBY = Interpreter.new(["-w"],
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
INTERPRETER_FORK = Interpreter.new(["-S", "rct-fork-client"],
|
34
|
-
|
33
|
+
:execute_ruby, true, true, nil)
|
34
|
+
INTERPRETER_RBTEST = Interpreter.new(["-S", "rbtest"],
|
35
|
+
:execute_script, false, false, nil)
|
36
|
+
INTERPRETER_FORK = Interpreter.new(["-S", "rct-fork-client"],
|
37
|
+
:execute_tmpfile, false, true,
|
38
|
+
lambda { Fork::chdir_fork_directory })
|
35
39
|
|
36
40
|
def self.detect_rbtest(code, opts)
|
37
41
|
opts[:use_rbtest] ||= (opts[:detect_rbtest] and code =~ /^=begin test./) ? true : false
|
@@ -58,7 +62,10 @@ class XMPFilter
|
|
58
62
|
test_script = options[:test_script]
|
59
63
|
test_method = options[:test_method]
|
60
64
|
filename = options[:filename]
|
65
|
+
@execute_ruby_tmpfile = options[:execute_ruby_tmpfile]
|
61
66
|
@postfix = ""
|
67
|
+
@stdin_path = nil
|
68
|
+
@width = options[:width]
|
62
69
|
|
63
70
|
initialize_rct_fork if options[:detect_rct_fork]
|
64
71
|
initialize_rbtest if options[:use_rbtest]
|
@@ -82,7 +89,7 @@ class XMPFilter
|
|
82
89
|
basedir = common_path(test_script, filename)
|
83
90
|
relative_filename = filename[basedir.length+1 .. -1].sub(%r!^lib/!, '')
|
84
91
|
@evals << %Q!$LOADED_FEATURES << #{relative_filename.dump}!
|
85
|
-
@evals <<
|
92
|
+
@evals << safe_require_code('test/unit')
|
86
93
|
@evals << %Q!load #{test_script.dump}!
|
87
94
|
end
|
88
95
|
test_method = get_test_method_from_lineno(test_script, test_method.to_i) if test_method =~ /^\d/
|
@@ -114,24 +121,30 @@ class XMPFilter
|
|
114
121
|
ret
|
115
122
|
end
|
116
123
|
|
124
|
+
SINGLE_LINE_RE = /^(?!(?:\s+|(?:\s*#.+)?)# ?=>)(.*) # ?=>.*/
|
125
|
+
MULTI_LINE_RE = /^(.*)\n(( *)# ?=>.*(?:\n|\z))(?: *# .*\n)*/
|
117
126
|
def annotate(code)
|
118
127
|
idx = 0
|
119
|
-
newcode = code.gsub(
|
120
|
-
|
121
|
-
|
122
|
-
end
|
128
|
+
newcode = code.gsub(SINGLE_LINE_RE){ prepare_line($1, idx += 1) }
|
129
|
+
newcode.gsub!(MULTI_LINE_RE){ prepare_line($1, idx += 1, true)}
|
130
|
+
File.open(@dump, "w"){|f| f.puts newcode} if @dump
|
123
131
|
stdout, stderr = execute(newcode)
|
124
132
|
output = stderr.readlines
|
125
133
|
runtime_data = extract_data(output)
|
126
134
|
idx = 0
|
127
|
-
annotated = code.gsub(
|
135
|
+
annotated = code.gsub(SINGLE_LINE_RE) { |l|
|
128
136
|
expr = $1
|
129
137
|
if /^\s*#/ =~ l
|
130
138
|
l
|
131
139
|
else
|
132
140
|
annotated_line(l, expr, runtime_data, idx += 1)
|
133
141
|
end
|
134
|
-
|
142
|
+
}
|
143
|
+
annotated.gsub!(/ # !>.*/, '')
|
144
|
+
annotated.gsub!(/# (>>|~>)[^\n]*\n/m, "");
|
145
|
+
annotated.gsub!(MULTI_LINE_RE) { |l|
|
146
|
+
annotated_multi_line(l, $1, $3, runtime_data, idx += 1)
|
147
|
+
}
|
135
148
|
ret = final_decoration(annotated, output)
|
136
149
|
if @output_stdout and (s = stdout.read) != ""
|
137
150
|
ret << s.inject(""){|s,line| s + "# >> #{line}".chomp + "\n" }
|
@@ -143,13 +156,28 @@ class XMPFilter
|
|
143
156
|
"#{expression} # => " + (runtime_data.results[idx].map{|x| x[1]} || []).join(", ")
|
144
157
|
end
|
145
158
|
|
146
|
-
def
|
159
|
+
def annotated_multi_line(line, expression, indent, runtime_data, idx)
|
160
|
+
pretty = (runtime_data.results[idx].map{|x| x[1]} || []).join(", ")
|
161
|
+
first, *rest = pretty.to_a
|
162
|
+
rest.inject("#{expression}\n#{indent}# => #{first}") {|s, l| s << "#{indent}# " << l }
|
163
|
+
end
|
164
|
+
|
165
|
+
def prepare_line_annotation(expr, idx, multi_line=false)
|
147
166
|
v = "#{VAR}"
|
148
167
|
blocal = "__#{VAR}"
|
149
168
|
blocal2 = "___#{VAR}"
|
169
|
+
lastmatch = "____#{VAR}"
|
170
|
+
if multi_line
|
171
|
+
pp = safe_require_code "pp"
|
172
|
+
result = "((begin; #{lastmatch} = $~; PP.pp(#{v}, '', #{@width-5}).gsub(/\\r?\\n/, 'PPPROTECT'); ensure; $~ = #{lastmatch} end))"
|
173
|
+
else
|
174
|
+
pp = ''
|
175
|
+
result = "#{v}.inspect"
|
176
|
+
end
|
150
177
|
oneline_ize(<<-EOF).chomp
|
178
|
+
#{pp}
|
151
179
|
#{v} = (#{expr})
|
152
|
-
$stderr.puts("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " " + #{
|
180
|
+
$stderr.puts("#{MARKER}[#{idx}] => " + #{v}.class.to_s + " " + #{result}) || begin
|
153
181
|
$stderr.puts local_variables
|
154
182
|
local_variables.each{|#{blocal}|
|
155
183
|
#{blocal2} = eval(#{blocal})
|
@@ -168,6 +196,17 @@ end || #{v}
|
|
168
196
|
end
|
169
197
|
alias_method :prepare_line, :prepare_line_annotation
|
170
198
|
|
199
|
+
def safe_require_code(lib)
|
200
|
+
oldverbose = "$#{VAR}_old_verbose"
|
201
|
+
"#{oldverbose} = $VERBOSE; $VERBOSE = false; require '#{lib}'; $VERBOSE = #{oldverbose}"
|
202
|
+
end
|
203
|
+
private :safe_require_code
|
204
|
+
|
205
|
+
def execute_ruby(code)
|
206
|
+
meth = (windows? or @execute_ruby_tmpfile) ? :execute_tmpfile : :execute_popen
|
207
|
+
__send__ meth, code
|
208
|
+
end
|
209
|
+
|
171
210
|
def execute_tmpfile(code)
|
172
211
|
ios = %w[_ stdin stdout stderr]
|
173
212
|
stdin, stdout, stderr = (1..3).map do |i|
|
@@ -182,6 +221,7 @@ end || #{v}
|
|
182
221
|
end
|
183
222
|
stdin.puts code
|
184
223
|
stdin.close
|
224
|
+
@stdin_path = File.expand_path stdin.path
|
185
225
|
exe_line = <<-EOF.map{|l| l.strip}.join(";")
|
186
226
|
$stdout.reopen('#{File.expand_path(stdout.path)}', 'w')
|
187
227
|
$stderr.reopen('#{File.expand_path(stderr.path)}', 'w')
|
@@ -209,20 +249,25 @@ end || #{v}
|
|
209
249
|
end
|
210
250
|
|
211
251
|
def execute_script(code)
|
212
|
-
|
213
|
-
File.open(
|
214
|
-
path = File.expand_path(codefile)
|
252
|
+
path = File.expand_path("xmpfilter.tmpfile_#{Process.pid}.rb", Dir.tmpdir)
|
253
|
+
File.open(path, "w"){|f| f.puts code}
|
215
254
|
at_exit { File.unlink path if File.exist? path}
|
216
|
-
|
255
|
+
stdout_path, stderr_path = (1..2).map do |i|
|
217
256
|
fname = "xmpfilter.tmpfile_#{Process.pid}-#{i}.rb"
|
218
|
-
|
219
|
-
at_exit { File.unlink fullname if File.exist? fullname}
|
220
|
-
File.open(fname, "w+")
|
257
|
+
File.expand_path(fname, Dir.tmpdir)
|
221
258
|
end
|
222
|
-
args = *(interpreter_command << %["#{
|
223
|
-
|
259
|
+
args = *(interpreter_command << %["#{path}"] << "2>" <<
|
260
|
+
%["#{stderr_path}"] << ">" << %["#{stdout_path}"])
|
224
261
|
system(args.join(" "))
|
225
|
-
|
262
|
+
|
263
|
+
[stdout_path, stderr_path].map do |fullname|
|
264
|
+
f = File.open(fullname, "r")
|
265
|
+
at_exit {
|
266
|
+
f.close unless f.closed?
|
267
|
+
File.unlink fullname if File.exist? fullname
|
268
|
+
}
|
269
|
+
f
|
270
|
+
end
|
226
271
|
end
|
227
272
|
|
228
273
|
def execute(code)
|
@@ -232,7 +277,7 @@ end || #{v}
|
|
232
277
|
def interpreter_command
|
233
278
|
r = [ @interpreter ] + @interpreter_info.options
|
234
279
|
r << "-d" if $DEBUG and @interpreter_info.accept_debug
|
235
|
-
r << "-I#{@include_paths.join(":")}"
|
280
|
+
r << "-I#{@include_paths.join(":")}" if @interpreter_info.accept_include_paths and !@include_paths.empty?
|
236
281
|
@libs.each{|x| r << "-r#{x}" } unless @libs.empty?
|
237
282
|
(r << "-").concat @options unless @options.empty?
|
238
283
|
r
|
@@ -247,7 +292,7 @@ end || #{v}
|
|
247
292
|
case op
|
248
293
|
when "=>"
|
249
294
|
klass, value = /(\S+)\s+(.*)/.match(result).captures
|
250
|
-
results[result_id.to_i] << [klass, value]
|
295
|
+
results[result_id.to_i] << [klass, value.gsub(/PPPROTECT/, "\n")]
|
251
296
|
when "~>"
|
252
297
|
exceptions[result_id.to_i] << result
|
253
298
|
when "==>"
|
@@ -273,14 +318,16 @@ end || #{v}
|
|
273
318
|
end
|
274
319
|
end
|
275
320
|
output = output.reject{|x| /^-:[0-9]+: warning/.match(x)}
|
276
|
-
if exception =
|
277
|
-
|
321
|
+
if exception = /^-e?:[0-9]+:.*|^(?!!XMP)[^\n]+:[0-9]+:in .*/m.match(output.join)
|
322
|
+
err = exception[0]
|
323
|
+
err.gsub!(Regexp.union(@stdin_path), '-') if @stdin_path
|
324
|
+
ret << err.map{|line| "# ~> " + line }
|
278
325
|
end
|
279
326
|
ret
|
280
327
|
end
|
281
328
|
|
282
329
|
def oneline_ize(code)
|
283
|
-
"((" + code.gsub(/\r?\n|\r/, ';') + "))
|
330
|
+
"((" + code.gsub(/\r?\n|\r/, ';') + "));#{@postfix}\n"
|
284
331
|
end
|
285
332
|
|
286
333
|
def debugprint(*args)
|