rdtool 0.6.38 → 0.6.39

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/bin/rd2 CHANGED
@@ -1,4 +1,4 @@
1
- #! /usr/bin/ruby1.9.1 -Kn
1
+ #!/usr/bin/env ruby
2
2
  # -*- coding: ASCII-8BIT -*-
3
3
  =begin
4
4
  = NAME
@@ -52,232 +52,258 @@ end
52
52
  include RD
53
53
 
54
54
  SYSTEM_NAME = "RDtool -- rd2"
55
- SYSTEM_VERSION = "$Version: "+RD::VERSION + "$" #"
55
+ SYSTEM_VERSION = "$Version: " + RD::VERSION + "$" #"
56
56
  RD2_VERSION = Version.new_from_version_string(SYSTEM_NAME, SYSTEM_VERSION)
57
57
 
58
- # global vars
59
58
  $Visitor_Class = nil
60
59
  $Visitor = nil
61
60
  $RD2_Sub_OptionParser = nil
62
-
63
- # local vars
64
- include_path = []
65
- with_part = []
66
- output_file = nil
67
- output_index = nil
68
- out_code = nil
69
- from_rdo = nil
70
-
71
- # user option
61
+ $RD2_OptionParser = nil
72
62
  $DEFAULT_FORMAT_LIB = "rd/rd2html-lib"
73
63
  $RC = {}
74
64
  $RC["filter"] = Hash.new(RD::INCLUDE_FILTER)
75
- begin
76
- if test(?r, File.expand_path("~/.rd2rc"))
77
- load "~/.rd2rc"
78
- # STDERR << "#{$0}: loading ~/.rd2rc\n"
79
- else
80
- load "rd/dot.rd2rc"
81
- # STDERR << "#{$0}: loading rd/dot.rd2rc\n"
65
+
66
+ class RD2Command
67
+ PartArgument = Struct.new(:part, :filter)
68
+
69
+ def initialize(argv: ARGV, argf: ARGF, stdout: $stdout, stderr: $stderr, program_name: $PROGRAM_NAME)
70
+ @argv = argv
71
+ @argf = argf
72
+ @stdout = stdout
73
+ @stderr = stderr
74
+ @program_name = program_name
75
+ @include_path = []
76
+ @with_part = []
77
+ @output_file = nil
78
+ @output_index = false
79
+ @out_code = nil
80
+ @from_rdo = false
82
81
  end
83
- rescue
84
- load "rd/dot.rd2rc"
85
- end
86
82
 
87
- # initialize OptionParser
88
- ARGV.options do |q|
89
- q.banner = "Usage: #{$0} [options] rd-file > output\n"
90
- q.on_head("global options:")
91
-
92
- q.on("-rLIB", "--require=LIB",
93
- String,
94
- "choose format library.") do |i|
95
- # require LIB
96
- require i
97
- if $Visitor_Class && !$Visitor
98
- $Visitor = $Visitor_Class.new()
99
- if $RD2_Sub_OptionParser
100
- require $RD2_Sub_OptionParser
101
- $RD2_Sub_OptionParser = nil
102
- end
83
+ def run
84
+ load_user_config
85
+ require_implicit_format_lib
86
+
87
+ begin
88
+ option_parser.parse!(@argv)
89
+ rescue OptionParser::ParseError => e
90
+ @stderr.print("Error: #{e.inspect}\n")
91
+ @stderr.print(option_parser.to_s)
92
+ return 1
103
93
  end
104
- end
105
94
 
106
- q.on("-oNAME",
107
- String,
108
- "indicate base name of output file") do |i|
109
- output_file = i
95
+ load_default_format_library unless $Visitor_Class
96
+ ensure_visitor_loaded
97
+ $Visitor.input_filename = @argf.filename
98
+
99
+ tree = build_tree
100
+ configure_visitor
101
+ write_output(tree, $Visitor.visit(tree))
102
+ write_index(tree) if @output_index
103
+ 0
104
+ rescue Racc::ParseError => e
105
+ @stderr.puts(e.message)
106
+ 10
107
+ ensure
108
+ cleanup_tmp_files
110
109
  end
111
110
 
112
- q.on("--out-code=KCODE",
113
- Kconv::NAME2CONST.keys, Kconv::NAME_ALIAS,
114
- "character encoding of output.(jis|euc|sjis|utf8)") do |i|
115
- out_code = i
116
- end
117
-
118
- q.on("--output-index",
119
- "output method index file (*.rmi)") do |i|
120
- output_index = true
121
- end
111
+ private
112
+
113
+ def option_parser
114
+ @option_parser ||= @argv.options do |q|
115
+ $RD2_OptionParser = q
116
+ q.banner = "Usage: #{File.basename(@program_name)} [options] rd-file > output\n"
117
+ q.on_head("global options:")
118
+
119
+ q.on("-rLIB", "--require=LIB", String, "choose format library.") do |lib|
120
+ load_format_library(lib)
121
+ end
122
+
123
+ q.on("-oNAME", String, "indicate base name of output file") do |name|
124
+ @output_file = name
125
+ end
122
126
 
123
- q.on("-IPATH", "--include-path=PATH",
124
- String,
125
- "add PATH to list of include path") do |i|
126
- # add to include path
127
- include_path.unshift(i)
127
+ q.on("--out-code=KCODE",
128
+ Kconv::NAME2CONST.keys, Kconv::NAME_ALIAS,
129
+ "character encoding of output.(jis|euc|sjis|utf8)") do |code|
130
+ @out_code = code
131
+ end
132
+
133
+ q.on("--output-index", "output method index file (*.rmi)") do
134
+ @output_index = true
135
+ end
136
+
137
+ q.on("-IPATH", "--include-path=PATH", String,
138
+ "add PATH to list of include path") do |path|
139
+ @include_path.unshift(path)
140
+ end
141
+
142
+ q.accept(PartArgument, /(\w+)(?:\s*:\s*(\w+))?/) do |_src, part, filter|
143
+ PartArgument.new(part, filter || part)
144
+ end
145
+ q.on("--with-part=PART", PartArgument, "include PART with Filter") do |entry|
146
+ @with_part << entry
147
+ unless @include_path.include?(RD::RDTree.tmp_dir)
148
+ @include_path << RD::RDTree.tmp_dir
149
+ end
150
+ end
151
+
152
+ q.on("--from-rdo", "load from *.rdo instead of *.rd") do
153
+ @from_rdo = true
154
+ end
155
+
156
+ q.on("--version", "print versions.") do
157
+ @stderr.puts(RD2_VERSION)
158
+ @stderr.puts(Tree::version)
159
+ @stderr.puts(Visitor::version)
160
+ @stderr.puts($Visitor_Class.version) if $Visitor_Class
161
+ raise SystemExit.new(0)
162
+ end
163
+
164
+ q.on_tail("--help", "print this message") do
165
+ @stderr.print(q.to_s)
166
+ raise SystemExit.new(0)
167
+ end
168
+ end
128
169
  end
129
170
 
130
- # accept "PART:FILTER" and "PART"
131
- class PART ; end
132
- q.accept(PART, /(\w+)(?:\s*:\s*(\w+))?/) {|s, p, f| [s, p, f] }
133
- q.on("--with-part=PART",
134
- PART,
135
- "include PART with Filter") do |src, part, filter|
136
- with_part.push([part, filter || part])
137
- unless include_path.index(RD::RDTree.tmp_dir)
138
- include_path.push(RD::RDTree.tmp_dir)
171
+ def load_user_config
172
+ user_config = File.expand_path("~/.rd2rc")
173
+ if File.readable?(user_config)
174
+ load user_config
175
+ else
176
+ load "rd/dot.rd2rc"
139
177
  end
178
+ rescue LoadError, StandardError
179
+ load "rd/dot.rd2rc"
140
180
  end
141
181
 
142
- q.on("--from-rdo",
143
- "load from *.rdo instead of *.rd") do
144
- from_rdo = true
182
+ def require_implicit_format_lib
183
+ base = File.basename(@program_name, ".*").downcase
184
+ return unless /rd2.+/ =~ base
185
+
186
+ load_format_library("rd/#{$&}-lib.rb")
145
187
  end
146
188
 
147
- q.on("--version",
148
- "print versions.") do
149
- STDERR.puts RD2_VERSION
150
- STDERR.puts Tree::version
151
- STDERR.puts Visitor::version
152
- STDERR.puts $Visitor_Class.version if $Visitor_Class
153
- exit(0)
189
+ def load_format_library(lib)
190
+ require lib
191
+ ensure_visitor_loaded
154
192
  end
155
193
 
156
- q.on_tail("--help",
157
- "print this message") do
158
- STDERR.print(q.to_s)
159
- exit(0)
194
+ def load_default_format_library
195
+ load_format_library($DEFAULT_FORMAT_LIB)
160
196
  end
161
- end # OptionParser.new
162
-
163
- # require format lib implicitly
164
- if /rd2.+/ =~ File.basename($0, ".*").downcase
165
- visitor_lib = "rd/" + $& + "-lib.rb"
166
- require visitor_lib
167
- require $RD2_Sub_OptionParser if $RD2_Sub_OptionParser
168
- # make visitor
169
- $Visitor = $Visitor_Class.new()
170
- end
171
197
 
172
- begin
173
- ARGV.parse!
174
- rescue
175
- STDERR.print("Error: " + $!.inspect + "\n")
176
- STDERR.print(ARGV.options.to_s)
177
- exit(1)
178
- end
198
+ def ensure_visitor_loaded
199
+ return unless $Visitor_Class
200
+ return if $Visitor
179
201
 
180
- unless $Visitor_Class
181
- require $DEFAULT_FORMAT_LIB
182
- $Visitor = $Visitor_Class.new
183
- end
202
+ $Visitor = $Visitor_Class.new
203
+ load_sub_option_parser
204
+ end
184
205
 
185
- $Visitor.input_filename = ARGF.filename
206
+ def load_sub_option_parser
207
+ return unless $RD2_Sub_OptionParser
186
208
 
187
- # make tree (but not parsed yet)
188
- if from_rdo
189
- rdos = []
190
- ARGV.each do |path|
191
- rdos.push(File.open(path))
192
- dirname = File.dirname(path)
193
- include_path.push(dirname, dirname + "/include")
194
- end
195
- tree = RDTree.new_from_rdo(*rdos)
196
- tree.include_path = include_path
197
- else
198
- # set Include_Path
199
- if ARGF.filename
200
- dir = File.dirname(ARGF.filename)
201
- else
202
- dir = "."
209
+ require $RD2_Sub_OptionParser
210
+ $RD2_Sub_OptionParser = nil
203
211
  end
204
- include_path.push(dir)
205
- include_path.push(dir + "/include")
206
212
 
207
- # input from ARGF
208
- src = readlines
209
- if src.find{|i| /\S/ === i } and !src.find{|i| /^=begin\b/ === i }
210
- src.unshift("=begin\n").push("=end\n")
213
+ def build_tree
214
+ if @from_rdo
215
+ build_tree_from_rdo
216
+ else
217
+ build_tree_from_rd
218
+ end
211
219
  end
212
220
 
213
- tree = RDTree.new(src, include_path, nil)
214
-
215
- # filter set tree.filter
216
- with_part.each do |i|
217
- tree.filter[i[0]] = $RC["filter"][i[1]]
221
+ def build_tree_from_rdo
222
+ rdos = []
223
+ @argv.each do |path|
224
+ rdos << File.open(path)
225
+ dirname = File.dirname(path)
226
+ @include_path.push(dirname, File.join(dirname, "include"))
227
+ end
228
+ tree = RDTree.new_from_rdo(*rdos)
229
+ tree.include_path = @include_path
230
+ tree
231
+ ensure
232
+ rdos&.each(&:close)
218
233
  end
219
-
220
- # parse
221
- begin
234
+
235
+ def build_tree_from_rd
236
+ dir = @argf.filename ? File.dirname(@argf.filename) : "."
237
+ @include_path.push(dir, File.join(dir, "include"))
238
+
239
+ src = read_input_lines
240
+ if src.find { |line| /\S/ === line } && !src.find { |line| /^=begin\b/ === line }
241
+ src.unshift("=begin\n").push("=end\n")
242
+ end
243
+
244
+ tree = RDTree.new(src, @include_path, nil)
245
+ @with_part.each do |entry|
246
+ tree.filter[entry.part] = $RC["filter"][entry.filter]
247
+ end
222
248
  tree.parse
223
- rescue Racc::ParseError
224
- STDERR.puts($!.message)
225
- exit(10)
249
+ tree
226
250
  end
227
- end
228
251
 
229
- # filter: set visitor.include_suffix
230
- with_part.each do |i|
231
- $Visitor.include_suffix.push(i[0])
232
- end
252
+ def read_input_lines
253
+ @argf.readlines
254
+ end
233
255
 
234
- # file base name setup
235
- $Visitor.filename = output_file if output_file
256
+ def configure_visitor
257
+ @with_part.each do |entry|
258
+ $Visitor.include_suffix.push(entry.part)
259
+ end
236
260
 
237
- # character encoding
238
- if out_code
239
- begin
240
- $Visitor.charcode = out_code
241
- $Visitor.lang = "ja"
242
- rescue NameError
243
- end
244
- end
261
+ $Visitor.filename = @output_file if @output_file
245
262
 
246
- # output
247
- out = $Visitor.visit(tree)
263
+ return unless @out_code
248
264
 
249
- # character encoding convert
250
- out = Kconv.kconv(out, Kconv::NAME2CONST[out_code], Kconv::AUTO) if out_code
265
+ begin
266
+ $Visitor.charcode = @out_code
267
+ $Visitor.lang = "ja"
268
+ rescue NameError
269
+ end
270
+ end
251
271
 
252
- if output_file
253
- filename = output_file + "." + $Visitor.class::OUTPUT_SUFFIX
254
- file = open(filename, "w")
255
- file.print(out)
256
- file.close
257
- STDERR.print("#{$0}: output to #{filename}...\n")
258
- else
259
- print(out)
260
- end
272
+ def write_output(tree, out)
273
+ out = Kconv.kconv(out, Kconv::NAME2CONST[@out_code], Kconv::AUTO) if @out_code
274
+
275
+ if @output_file
276
+ suffix = if $Visitor.respond_to?(:output_suffix)
277
+ $Visitor.output_suffix
278
+ else
279
+ $Visitor.class::OUTPUT_SUFFIX
280
+ end
281
+ filename = @output_file + "." + suffix
282
+ File.open(filename, "w") { |file| file.print(out) }
283
+ @stderr.print("#{File.basename(@program_name)}: output to #{filename}...\n")
284
+ else
285
+ @stdout.print(out)
286
+ end
287
+ end
288
+
289
+ def write_index(tree)
290
+ unless @output_file
291
+ raise %Q[Error: option "--output-index" must be used with option "-oNAME"]
292
+ end
261
293
 
262
- # RMI
263
- if output_index
264
- if output_file
265
294
  require "rd/rd2rmi-lib"
266
295
  rmivisitor = RD2RMIVisitor.new
267
- rmivisitor.filename = output_file
268
- rmi = rmivisitor.visit(tree)
269
- filename = output_file + ".rmi"
270
- file = open(filename, "w")
271
- file.print(rmi)
272
- file.close
273
- STDERR.print("#{$0}: output to #{filename}...\n")
274
- else
275
- raise %Q[Error: option "--output-index" must be used with option "-oNAME"]
296
+ rmivisitor.filename = @output_file
297
+ filename = @output_file + ".rmi"
298
+ File.open(filename, "w") { |file| file.print(rmivisitor.visit(tree)) }
299
+ @stderr.print("#{File.basename(@program_name)}: output to #{filename}...\n")
276
300
  end
277
- end
278
-
279
301
 
280
- # filter: remove tmp file
281
- Dir.glob("#{RD::RDTree.tmp_dir}/rdtmp.#{$$}.*.*").each do |i|
282
- File.delete(i)
302
+ def cleanup_tmp_files
303
+ Dir.glob("#{RD::RDTree.tmp_dir}/rdtmp.#{$$}.*.*").each do |path|
304
+ File.delete(path)
305
+ end
306
+ end
283
307
  end
308
+
309
+ exit(RD2Command.new.run)