rubysl-dl 0.0.1 → 1.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.
@@ -0,0 +1,500 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- ruby -*-
3
+ # $Id: h2rb 11708 2007-02-12 23:01:19Z shyouhei $
4
+
5
+ require 'mkmf'
6
+ require 'ftools'
7
+
8
+ $recursive = false
9
+ $force = false
10
+ $conly = true
11
+ $inc_path = []
12
+ $infilename= nil
13
+ $insert_require = true
14
+
15
+ def valid_ruby_code?(code)
16
+ begin
17
+ eval("BEGIN {return true}; #{code}")
18
+ rescue SyntaxError
19
+ return false
20
+ end
21
+ return false
22
+ end
23
+
24
+ def print_usage
25
+ print <<EOF
26
+ h2rb [-r] [-I <path>] [-d] [<filename>]
27
+ EOF
28
+ end
29
+
30
+ while( ARGV[0] )
31
+ case( ARGV[0] )
32
+ when "-r"
33
+ ARGV.shift
34
+ $recursive = true
35
+ when "-R"
36
+ ARGV.shift
37
+ $recursive = false
38
+ when "-l"
39
+ ARGV.shift
40
+ $insert_require = true
41
+ when "-L"
42
+ ARGV.shift
43
+ $insert_require = false
44
+ when "-c"
45
+ ARGV.shift
46
+ $conly = true
47
+ when "-C"
48
+ ARGV.shift
49
+ $conly = false
50
+ when "-f"
51
+ ARGV.shift
52
+ $force = true
53
+ when "-F"
54
+ ARGV.shift
55
+ $force = false
56
+ when "-I"
57
+ ARGV.shift
58
+ $inc_path << ARGV.shift
59
+ when "-d"
60
+ ARGV.shift
61
+ $DEBUG = true
62
+ when "-h","--help"
63
+ print_usage()
64
+ exit 0
65
+ when /-.*/
66
+ $stderr.print("unknown option '#{ARGV[0]}'.\n")
67
+ print_usage()
68
+ exit 0
69
+ else
70
+ $infilename = ARGV.shift
71
+ end
72
+ end
73
+
74
+ $inc_dir = File.join(CONFIG["prefix"], "lib", "ruby",
75
+ CONFIG["MAJOR"] + "." + CONFIG["MINOR"],
76
+ "dl")
77
+
78
+ class H2RBError < StandardError; end
79
+
80
+
81
+ class H2RB
82
+ def initialize(inc_dir = nil, inc_path = nil, insert_require = nil)
83
+ @inc_path = inc_path || []
84
+ @inc_dir = inc_dir || '.'
85
+ @indent = 0
86
+ @parsed_files = []
87
+ @insert_require = insert_require || false
88
+ end
89
+
90
+ def find_path(file)
91
+ if( ! file )
92
+ return nil
93
+ end
94
+ if( File.exist?(file) )
95
+ if( file[0] == ?/ )
96
+ return file
97
+ else
98
+ return file
99
+ end
100
+ end
101
+ @inc_path.each{|path|
102
+ full = File.join(path, file)
103
+ if( File.exist?(full) )
104
+ return full
105
+ end
106
+ }
107
+ return nil
108
+ end
109
+
110
+ def strip_comment(line)
111
+ if( @commented )
112
+ if( e = line.index("*/") )
113
+ line[0..(e+1)] = ""
114
+ @commented = false
115
+ else
116
+ line = ""
117
+ end
118
+ else
119
+ if( s = line.index("/*") )
120
+ if( e = line.index("*/") )
121
+ line[s..(e+1)] = ""
122
+ else
123
+ line[s..-1] = ""
124
+ @commented = true
125
+ end
126
+ elsif( s = line.index("//") )
127
+ line[s..(-1)] = ""
128
+ end
129
+ end
130
+
131
+ line.gsub!(/\s+$/,"")
132
+ return line
133
+ end
134
+
135
+ def up_indent
136
+ @indent += 1
137
+ end
138
+
139
+ def down_indent
140
+ @indent -= 1
141
+ if( @indent < 0 )
142
+ raise
143
+ end
144
+ end
145
+
146
+ def indent
147
+ " " * @indent
148
+ end
149
+
150
+ def rescue_begin
151
+ line = "#{indent}begin"
152
+ up_indent
153
+ return line
154
+ end
155
+
156
+ def rescue_nameerror
157
+ down_indent
158
+ line = [
159
+ "#{indent}rescue NameError => e",
160
+ "#{indent} raise e if( $DEBUG )",
161
+ "#{indent}end"].join($/)
162
+ return line
163
+ end
164
+
165
+ def parse_enum(line)
166
+ if( line =~ /enum\s+(\S+\s+)?\{(.+)\}/ )
167
+ enum_name = $1
168
+ enum_block = $2
169
+ if( enum_name )
170
+ line = "#{indent}# -- enum #{enum_name}\n"
171
+ else
172
+ line = "#{indent}# -- enum\n"
173
+ end
174
+ enums = enum_block.split(/,/).collect{|e| e.strip}
175
+ i = 0
176
+ enums.each{|elem|
177
+ var,val = elem.split(/=/).collect{|e| e.strip}
178
+ if( val )
179
+ i = val.to_i
180
+ end
181
+ line += "#{indent}#{var} = #{i.to_s}\n"
182
+ i += 1
183
+ }
184
+ line += "#{indent}# -- end of enum"
185
+ return line
186
+ else
187
+ return nil
188
+ end
189
+ end
190
+
191
+ def parse_define(line)
192
+ case line
193
+ when /^#\s*define\s+(\S+)\(\)/
194
+ line = nil
195
+ when /^#\s*define\s+(\S+)\((.+)\)\s+(.+)$/
196
+ if( @conly )
197
+ line = nil
198
+ else
199
+ defname = $1
200
+ defargs = $2
201
+ defval = $3
202
+ if( !valid_ruby_code?(defval) )
203
+ defval = "nil # #{defval}"
204
+ end
205
+ if( defname[0,1] =~ /^[A-Z]$/ )
206
+ line = "#{indent}#{defname} = proc{|#{defargs}| #{defval}}"
207
+ else
208
+ line = [
209
+ "#{indent}def #{defname}(#{defargs})",
210
+ "#{indent} #{defval}",
211
+ "#{indent}end"
212
+ ].join("\n")
213
+ end
214
+ end
215
+ when /^#\s*define\s+(\S+)\((.+)\)$/
216
+ if( @conly )
217
+ line = nil
218
+ else
219
+ defname = $1
220
+ defargs = $2
221
+ defval = nil
222
+ if( !valid_ruby_code?(defval) )
223
+ defval = "nil # #{defval}"
224
+ end
225
+ if( defname[0,1] =~ /^[A-Z]$/ )
226
+ line = "#{indent}#{defname} = proc{|#{defargs}| #{defval}}"
227
+ else
228
+ line = [
229
+ "#{indent}def #{defname}(#{defargs})",
230
+ "#{indent} #{defval}",
231
+ "#{indent}end"
232
+ ].join("\n")
233
+ end
234
+ end
235
+ when /^#\s*define\s+(\S+)\s+(.+)$/
236
+ defname = $1
237
+ defval = $2
238
+ if( !valid_ruby_code?(defval) )
239
+ defval = "nil # #{defval}"
240
+ end
241
+ line = [rescue_begin, "#{indent}#{defname} = #{defval}", rescue_nameerror].join($/)
242
+ when /^#\s*define\s+(\S+)$/
243
+ defname = $1
244
+ line = "#{indent}#{defname} = nil"
245
+ else
246
+ line = nil
247
+ end
248
+ return line
249
+ end
250
+
251
+ def parse_undef(line)
252
+ case line
253
+ when /^#\s*undef\s+([A-Z]\S+)$/
254
+ defname = $1
255
+ line = "#{indent}remove_const(:#{defname})"
256
+ when /^#\s*undef\s+(\S+)$/
257
+ defname = $1
258
+ line = "#{indent}#{defname} = nil"
259
+ else
260
+ line = nil
261
+ end
262
+ return line
263
+ end
264
+
265
+ def parse_ifdef(line)
266
+ case line
267
+ when /^#\s*ifdef\s+(\S+)$/
268
+ defname = $1
269
+ line = [
270
+ rescue_begin,
271
+ "#{indent}if( defined?(#{defname}) && ! #{defname}.nil? )"].join($/)
272
+ else
273
+ line = nil
274
+ end
275
+ return line
276
+ end
277
+
278
+ def parse_ifndef(line)
279
+ case line
280
+ when /^#\s*ifndef\s+(\S+)$/
281
+ defname = $1
282
+ line = [
283
+ rescue_begin,
284
+ "#{indent}if( ! defined?(#{defname}) || #{defname}.nil? )"].join($/)
285
+ else
286
+ line = nil
287
+ end
288
+ return line
289
+ end
290
+
291
+ def parse_if(line)
292
+ case line
293
+ when /^#\s*if\s+(.+)$/
294
+ cond = $1
295
+ cond.gsub!(/defined(.+)/){ "defined?(#{$1}) && ! #{$1}.nil?" }
296
+ if( valid_ruby_code?(cond) )
297
+ line = "#{indent}if( #{cond} )"
298
+ else
299
+ line = "#{indent}if( false ) # #{cond}"
300
+ end
301
+ line = [rescue_begin, line].join($/)
302
+ else
303
+ line = nil
304
+ end
305
+ return line
306
+ end
307
+
308
+ def parse_elif(line)
309
+ case line
310
+ when /^#\s*elif\s+(.+)$/
311
+ cond = $1
312
+ cond.gsub!("defined","defined?")
313
+ line = "#{indent}elsif( #{cond} )"
314
+ else
315
+ line = nil
316
+ end
317
+ return line
318
+ end
319
+
320
+ def parse_else(line)
321
+ case line
322
+ when /^#\s*else\s*/
323
+ line = "#{indent}else"
324
+ else
325
+ line = nil
326
+ end
327
+ return line
328
+ end
329
+
330
+ def parse_endif(line)
331
+ case line
332
+ when /^#\s*endif\s*$/
333
+ line = ["#{indent}end", rescue_nameerror].join($/)
334
+ else
335
+ line = nil
336
+ end
337
+ return line
338
+ end
339
+
340
+ def parse_include(line)
341
+ if( ! @insert_require )
342
+ return nil
343
+ end
344
+
345
+ file = nil
346
+ case line
347
+ when /^#\s*include "(.+)"$/
348
+ file = $1
349
+ line = "#{indent}require '#{file}'"
350
+ when /^#\s*include \<(.+)\>$/
351
+ file = $1
352
+ line = "#{indent}require '#{file}'"
353
+ else
354
+ line = nil
355
+ end
356
+ if( @recursive && file && (!@parsed_files.include?(file)) )
357
+ parse(file, @recursive, @force, @conly)
358
+ end
359
+ return line
360
+ end
361
+
362
+
363
+ def open_files(infilename)
364
+ if( ! infilename )
365
+ return [$stdin, $stdout]
366
+ end
367
+
368
+ old_infilename = infilename
369
+ infilename = find_path(infilename)
370
+ if( ! infilename )
371
+ $stderr.print("'#{old_infilename}' was not found.\n")
372
+ return [nil,nil]
373
+ end
374
+
375
+ if( infilename )
376
+ if( infilename[0,1] == '/' )
377
+ outfilename = File.join(@inc_dir, infilename[1..-1] + ".rb")
378
+ else
379
+ outfilename = infilename + ".rb"
380
+ end
381
+ File.mkpath(File.dirname(outfilename))
382
+ else
383
+ outfilename = nil
384
+ end
385
+
386
+ if( infilename )
387
+ fin = File.open(infilename,"r")
388
+ else
389
+ fin = $stdin
390
+ end
391
+ if( outfilename )
392
+ if( File.exist?(outfilename) && (!@force) )
393
+ $stderr.print("'#{outfilename}' have already existed.\n")
394
+ return [fin, nil]
395
+ end
396
+ fout = File.open(outfilename,"w")
397
+ else
398
+ fout = $stdout
399
+ end
400
+
401
+ $stderr.print("#{infilename} -> #{outfilename}\n")
402
+ if( fout )
403
+ dir = File.dirname(outfilename)
404
+ if( dir[0,1] != "." && dir != "" )
405
+ fout.print("if( ! $LOAD_PATH.include?('#{dir}') )\n",
406
+ " $LOAD_PATH.push('#{dir}')\n",
407
+ "end\n")
408
+ end
409
+ end
410
+ return [fin,fout]
411
+ end
412
+
413
+ def parse(infilename = nil, recursive = false, force = false, conly = false)
414
+ @commented = false
415
+ @recursive = recursive
416
+ @force = force
417
+ @conly = conly
418
+ @parsed_files << infilename
419
+
420
+ fin,fout = open_files(infilename)
421
+ if( !fin )
422
+ return
423
+ end
424
+
425
+ begin
426
+ line_number = 0
427
+ pre_line = nil
428
+ fin.each_line{|line|
429
+ line_number += 1
430
+ line.chop!
431
+ if( $DEBUG )
432
+ $stderr.print("#{line_number}:(#{@indent}):", line, "\n")
433
+ end
434
+
435
+ if( pre_line )
436
+ line = pre_line + line
437
+ pre_line = nil
438
+ end
439
+
440
+ if( line[-1,1] == "\\" )
441
+ pre_line = line[0..-2]
442
+ next
443
+ end
444
+
445
+ if( eidx = line.index("enum ") )
446
+ pre_line = line[eidx .. -1]
447
+ if( i = line.index("{") && j = line.index("}") )
448
+ line = line[0..j]
449
+ pre_line = nil
450
+ else
451
+ next
452
+ end
453
+ end
454
+
455
+ line = strip_comment(line)
456
+ case line
457
+ when /^enum\s/
458
+ line = parse_enum(line)
459
+ when /^#\s*define\s/
460
+ line = parse_define(line)
461
+ when /^#\s*undef\s/
462
+ line = parse_undef(line)
463
+ when /^#\s*ifdef\s/
464
+ line = parse_ifdef(line)
465
+ up_indent
466
+ when /^#\s*ifndef\s/
467
+ line = parse_ifndef(line)
468
+ up_indent
469
+ when /^#\s*if\s/
470
+ line = parse_if(line)
471
+ up_indent
472
+ when /^#\s*elif\s/
473
+ down_indent
474
+ line = parse_elif(line)
475
+ up_indent
476
+ when /^#\s*else/
477
+ down_indent
478
+ line = parse_else(line)
479
+ up_indent
480
+ when /^#\s*endif/
481
+ down_indent
482
+ line = parse_endif(line)
483
+ when /^#\s*include\s/
484
+ line = parse_include(line)
485
+ else
486
+ line = nil
487
+ end
488
+ if( line && fout )
489
+ fout.print(line, " # #{line_number}",$/)
490
+ end
491
+ }
492
+ ensure
493
+ fin.close if fin
494
+ fout.close if fout
495
+ end
496
+ end
497
+ end
498
+
499
+ h2rb = H2RB.new($inc_dir, $inc_path, $insert_require)
500
+ h2rb.parse($infilename, $recursive, $force, $conly)