Top Level Namespace

Defined Under Namespace

Classes: ImageScience

Instance Method Summary collapse

Instance Method Details

#expand_constantsObject

expand comments in image_science_ext.c.in and generate image_science_ext.c. creates constant definitions (rb_define_const)



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'ext/extconf.rb', line 5

def expand_constants

  File.open("conftest.c", "w") { |f| f.puts "#include <FreeImage.h>" }
  cpp = cpp_command('')
  system "#{cpp} > confout"

  constants = {}
  headers = []

  config = File.readlines("confout")
  config.each do |include|
    next unless include.match(/"(.*?FreeImage.h)"/)
    filename = include.split('"')[1]
    headers << filename
  end
  
  headers.uniq!

  # add typedef constants
  config.each do |define|
    next unless define.match(/^\s*(\w+)\s*=\s*\d/)  # typedef
    name = $1
    next unless name.match(/^(FIT|FICC|FIC|FIF|FILTER)_/)
    constants[$1] ||= []
    constants[$1] << [name]
  end

  if RUBY_VERSION >= "1.9"
    raw_headers = headers.collect { |i| File.read(i, :encoding => "ISO-8859-1") }.join
  else
    raw_headers = headers.collect { |i| File.read(i) }.join
  end
  
  # add #defined constants (load/save flags)
  constants['FLAG'] ||= []
  flag_defines = raw_headers.scan(/(flag constants\s*---.*?)^\/\//m)
  flag_defines.each do |flag_data|
    flag_data[0].split(/\n/).each do |define|
      next unless define.match(/^\#define\s*(\w+)\s(.*?(\/\/.+)$)?/)  # #define
      constants['FLAG'] << [$1, $3]
    end
  end

  File.unlink("confout")

  constants.keys.each { |i| constants[i].uniq! }

  File.open("image_science_ext.c", "w") do |newf|
    File.foreach("image_science_ext.c.in") do |l|
      if l.match(/\/\* expand FreeImage constants\s+(\w+)\s+(\w+)\s*\*\//)
        klass_name = $1
        const_type = $2
        const_list = constants[const_type]
        unless const_list
          puts "warning: no constants found matching #{const_type}"
          next
        end
        const_list.each do |c, comment|
          if comment
            comment.sub!('//', '')
            comment.sub!(/[\r\n]+$/, '')
            comment.gsub!(/:/, '-')  # colons break rdoc..
            comment.strip!
            newf.puts %Q{  /* #{comment} */}
          end
          newf.puts %Q{  rb_define_const(#{klass_name}, "#{c}", INT2FIX(#{c}));}
        end
      else
        newf.puts l
      end
    end
  end

end