rdtool 0.6.37 → 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,230 +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
122
112
 
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)
128
- end
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
126
+
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
129
151
 
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)
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
139
168
  end
140
169
  end
141
170
 
142
- q.on("--from-rdo",
143
- "load from *.rdo instead of *.rd") do
144
- from_rdo = true
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"
177
+ end
178
+ rescue LoadError, StandardError
179
+ load "rd/dot.rd2rc"
145
180
  end
146
181
 
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)
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")
154
187
  end
155
188
 
156
- q.on_tail("--help",
157
- "print this message") do
158
- STDERR.print(q.to_s)
159
- exit(0)
189
+ def load_format_library(lib)
190
+ require lib
191
+ ensure_visitor_loaded
160
192
  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
193
 
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
194
+ def load_default_format_library
195
+ load_format_library($DEFAULT_FORMAT_LIB)
196
+ end
179
197
 
180
- unless $Visitor_Class
181
- require $DEFAULT_FORMAT_LIB
182
- $Visitor = $Visitor_Class.new
183
- end
198
+ def ensure_visitor_loaded
199
+ return unless $Visitor_Class
200
+ return if $Visitor
184
201
 
185
- # make tree (but not parsed yet)
186
- if from_rdo
187
- rdos = []
188
- ARGV.each do |path|
189
- rdos.push(File.open(path))
190
- dirname = File.dirname(path)
191
- include_path.push(dirname, dirname + "/include")
202
+ $Visitor = $Visitor_Class.new
203
+ load_sub_option_parser
192
204
  end
193
- tree = RDTree.new_from_rdo(*rdos)
194
- tree.include_path = include_path
195
- else
196
- # input from ARGF
197
- src = readlines
198
- if src.find{|i| /\S/ === i } and !src.find{|i| /^=begin\b/ === i }
199
- src.unshift("=begin\n").push("=end\n")
205
+
206
+ def load_sub_option_parser
207
+ return unless $RD2_Sub_OptionParser
208
+
209
+ require $RD2_Sub_OptionParser
210
+ $RD2_Sub_OptionParser = nil
200
211
  end
201
212
 
202
- # set Include_Path
203
- if ARGF.filename
204
- dir = File.dirname(ARGF.filename)
205
- else
206
- dir = "."
213
+ def build_tree
214
+ if @from_rdo
215
+ build_tree_from_rdo
216
+ else
217
+ build_tree_from_rd
218
+ end
207
219
  end
208
- include_path.push(dir)
209
- include_path.push(dir + "/include")
210
-
211
- tree = RDTree.new(src, include_path, nil)
212
-
213
- # filter set tree.filter
214
- with_part.each do |i|
215
- tree.filter[i[0]] = $RC["filter"][i[1]]
220
+
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)
216
233
  end
217
-
218
- # parse
219
- 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
220
248
  tree.parse
221
- rescue Racc::ParseError
222
- STDERR.puts($!.message)
223
- exit(10)
249
+ tree
224
250
  end
225
- end
226
251
 
227
- # filter: set visitor.include_suffix
228
- with_part.each do |i|
229
- $Visitor.include_suffix.push(i[0])
230
- end
252
+ def read_input_lines
253
+ @argf.readlines
254
+ end
231
255
 
232
- # file base name setup
233
- $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
234
260
 
235
- # character encoding
236
- if out_code
237
- begin
238
- $Visitor.charcode = out_code
239
- $Visitor.lang = "ja"
240
- rescue NameError
241
- end
242
- end
261
+ $Visitor.filename = @output_file if @output_file
243
262
 
244
- # output
245
- out = $Visitor.visit(tree)
263
+ return unless @out_code
246
264
 
247
- # character encoding convert
248
- 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
249
271
 
250
- if output_file
251
- filename = output_file + "." + $Visitor.class::OUTPUT_SUFFIX
252
- file = open(filename, "w")
253
- file.print(out)
254
- file.close
255
- STDERR.print("#{$0}: output to #{filename}...\n")
256
- else
257
- print(out)
258
- 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
259
293
 
260
- # RMI
261
- if output_index
262
- if output_file
263
294
  require "rd/rd2rmi-lib"
264
295
  rmivisitor = RD2RMIVisitor.new
265
- rmivisitor.filename = output_file
266
- rmi = rmivisitor.visit(tree)
267
- filename = output_file + ".rmi"
268
- file = open(filename, "w")
269
- file.print(rmi)
270
- file.close
271
- STDERR.print("#{$0}: output to #{filename}...\n")
272
- else
273
- 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")
274
300
  end
275
- end
276
301
 
277
-
278
- # filter: remove tmp file
279
- Dir.glob("#{RD::RDTree.tmp_dir}/rdtmp.#{$$}.*.*").each do |i|
280
- 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
281
307
  end
308
+
309
+ exit(RD2Command.new.run)