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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
# File 'lib/ffi/tools/types_generator.rb', line 46
def self.generate(options = {})
typedefs = nil
Tempfile.open 'ffi_types_generator' do |io|
io.puts "#include <stdint.h>\n#include <stddef.h>\n#include <sys/types.h>\n#if !(defined(WIN32))\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <sys/resource.h>\n#endif\n C\n\n io.close\n cc = ENV['CC'] || 'gcc'\n cmd = \"\#{cc} -E -x c \#{options[:cppflags]} -D_DARWIN_USE_64_BIT_INODE -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -c\"\n if options[:input]\n typedefs = File.read(options[:input])\n elsif options[:remote]\n typedefs = `ssh \#{options[:remote]} \#{cmd} - < \#{io.path}`\n else\n typedefs = `\#{cmd} \#{io.path}`\n end\n end\n\n code = []\n\n typedefs.each_line do |type|\n # We only care about single line typedef\n next unless type =~ /typedef/\n # Ignore unions or structs\n next if type =~ /union|struct/\n\n # strip off the starting typedef and ending ;\n type.gsub!(/^(.*typedef\\s*)/, \"\")\n type.gsub!(/\\s*;\\s*$/, \"\")\n\n parts = type.split(/\\s+/)\n def_type = parts.join(\" \")\n\n # GCC does mapping with __attribute__ stuf, also see\n # http://hal.cs.berkeley.edu/cil/cil016.html section 16.2.7. Problem\n # with this is that the __attribute__ stuff can either occur before or\n # after the new type that is defined...\n if type =~ /__attribute__/\n if parts.last =~ /__QI__|__HI__|__SI__|__DI__|__word__/\n\n # In this case, the new type is BEFORE __attribute__ we need to\n # find the final_type as the type before the part that starts with\n # __attribute__\n final_type = \"\"\n parts.each do |p|\n break if p =~ /__attribute__/\n final_type = p\n end\n else\n final_type = parts.pop\n end\n\n def_type = case type\n when /__QI__/ then \"char\"\n when /__HI__/ then \"short\"\n when /__SI__/ then \"int\"\n when /__DI__/ then \"long long\"\n when /__word__/ then \"long\"\n else \"int\"\n end\n\n def_type = \"unsigned \#{def_type}\" if type =~ /unsigned/\n else\n final_type = parts.pop\n def_type = parts.join(\" \")\n end\n\n if type = TYPE_MAP[def_type]\n code << \"rbx.platform.typedef.\#{final_type} = \#{type}\"\n TYPE_MAP[final_type] = TYPE_MAP[def_type]\n else\n # Fallback to an ordinary pointer if we don't know the type\n if def_type =~ /\\*/\n code << \"rbx.platform.typedef.\#{final_type} = pointer\"\n TYPE_MAP[final_type] = :pointer\n end\n end\n end\n\n code.sort.join(\"\\n\")\nend\n"
|