rubysl-dl 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)