diff options
Diffstat (limited to 'tools/genruby.rb')
-rwxr-xr-x | tools/genruby.rb | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/tools/genruby.rb b/tools/genruby.rb new file mode 100755 index 0000000..442c59b --- /dev/null +++ b/tools/genruby.rb @@ -0,0 +1,252 @@ +#! /usr/bin/env ruby +# -*- coding: UTF-8 -*- +# +path = File.dirname __FILE__ +lib_path = File.join path, '..', 'lib', 'e17' +# +libraries = [ + [ 'eina_types.h', 'eina'], + [ 'Eet.h', 'eet'], + [ 'Evas.h', 'evas'], + [ 'Evas_GL.h', 'evas'], + [ 'Edje.h', 'edje'], + [ 'Ecore.h', 'ecore'], + [ 'Ecore_Con.h', 'ecore'], + [ 'Ecore_Input.h', 'ecore'], + [ 'Ecore_Getopt.h', 'ecore'], + [ 'Ecore_Evas.h', 'ecore'], + [ 'Ecore_Fb.h', 'ecore'], + [ 'Ecore_File.h', 'ecore'], + [ 'Elementary.h', 'libelementary-ver-pre-svn-09.so.0' ], +] +# +INDENT=' '*8 +# +HEADER =<<-EOF +#! /usr/bin/env ruby +# -*- coding: UTF-8 -*- +# +require 'e17/ffi_helper' +# +module E17 + module MNAME + # + extend FFI::Library + extend FFIHelper +EOF +FOOTER =<<-EOF + end +end +# +# EOF +EOF +# +TYPES = { + 'int' => ':int', + 'char' => ':char', + 'void' => ':void', + 'long' => ':long', + 'short' => ':short', + 'float' => ':float', + 'pid_t' => ':ulong', + 'size_t' => ':ulong', + 'double' => ':double', + 'long int' => ':long', + 'long long' => ':long_long', + 'unsigned int' => ':uint', + 'unsigned char' => ':uchar', + 'unsigned short' => ':ushort', + 'unsigned long long' => ':ulong_long', + 'int *' => ':int_p', + 'void *' => ':void_p', + 'short *' => ':short_p', + 'float *' => ':float_p', + 'size_t *' => ':ulong_p', + 'double *' => ':double_p', + 'unsigned int *' => ':uint_p', + 'unsigned char *' => ':uchar_p', + 'char *' => ':string', # FIXME ?!?! + 'char **' => ':string_array', # FIXME ?!?! + 'char ***' => ':string_array_p', # FIXME ?!?! + 'fd_set *' => ':pointer', + 'FILE *' => ':pointer', + 'va_list' => ':pointer', # FIXME ?!?! + 'struct tm *' => ':pointer', + 'struct timeval *' => ':pointer', + 'struct sockaddr *' => ':pointer', + # E17 BASE TYPES +# 'Eina_Bool' => ':bool', +# 'Eina_Bool *' => ':bool_p', + 'Eina_List' => ':eina_list', + 'Eina_List *' => ':eina_list_p', + 'Eina_Hash' => ':eina_hash', + 'Eina_Hash *' => ':eina_hash_p', + 'Eina_Iterator' => ':eina_iterator', + 'Eina_Iterator *' => ':eina_iterator_p', + 'Eina_Accessor' => ':eina_accessor', + 'Eina_Accessor *' => ':eina_accessor_p', +} +# +def set_type t, v, cb=false + v = v.downcase.gsub(/(const|enum|union)/,'').strip + if not TYPES[t].nil? + puts "type already exists >#{t}< #{v}" + exit 1 + end + r = TYPES[v] + v =r[1..-1] if not r.nil? + TYPES[t]=':'+v + if cb + TYPES[t+' *']=':'+v + else + TYPES[t+' *']=':'+v+'_p' + TYPES[t+' **']=':'+v+'_pp' + TYPES[t+' ***']=':'+v+'_ppp' + end +end +# +def get_type t + k = t.gsub(/(const|enum|union)/, '').strip + k.sub!(/\*/,' *') if k=~/\w+\*/ + r = TYPES[k] + if r.nil? + puts "unknown type >#{k}< #{t}" + exit 1 + end + r +end +# +def get_type_from_arg arg + if arg=~ /^\s*void\s*$/ + return get_type 'void' + end + if arg =~ /\.\.\./ + return '... FIXME' + end + k = arg.gsub(/const/,'').gsub(/\s{2,}/,' ').strip +# if not k=~/^((?:\w+\s)+\**)\s?(\w+)$/ + if not k=~/(.*?)(\w+)$/ + puts "wrong arg >#{k}< #{arg}" + exit 1 + end + get_type $1 +end +# +def wrap_text txt, col, indent + txt.gsub( /(.{1,#{col}})(?: +|$\n?)|(.{1,#{col}})/,"\\1\\2\n#{indent}").sub(/\n\s+$/,'') +end +# +def gen_enums path, indent + r = '' + open(path+'-enums','r').readlines.each do |l| + l.strip! + if not l=~/(typedef enum(?: \w+)?) {([A-Z0-9_ ,]+)} (\w+);/ + r << indent+"# #{l}\n#{indent}# FIXME\n" + next + end + typedef = $1 + values = $2 + typename = $3 + set_type typename, typename +# args = values.split(',').collect { |cst| ':'+cst.strip.downcase }.join ', ' + args = values.split(',').collect { |cst| ':'+cst.strip.downcase.sub(typename.downcase+'_','') }.join ', ' + r << indent+"# #{typedef} {...} #{typename};\n" + r << wrap_text( indent+"enum :#{typename.downcase}, [ #{args} ]", 150, indent+' '*4 )+"\n" + end + r +end +# +def gen_typedefs path, indent + r = '' + open(path+'-types','r').readlines.each do |l| + l.strip! + if l=~/typedef struct _\w+ (\w+);/ + t = $1 + set_type t, t + r << indent+"# #{l}\n" + r << indent+"typedef :pointer, :#{t.downcase}\n" + r << indent+"typedef :pointer, :#{t.downcase}_p\n" + elsif l =~/typedef ((?:\w+\**\s)+)(\w+);/ + t = $2 + v = $1 + set_type t, v + r << indent+"# #{l}\n" + r << indent+"typedef :#{v.downcase}, :#{t.downcase}\n" +# r << indent+"typedef :#{v.downcase}, :#{t.downcase}_p\n" + else + r << indent+"# #{l}\n#{indent}# FIXME\n" + next + end + end + r +end +# +def gen_callbacks path, indent + r = '' + open(path+'-callbacks','r').readlines.each do |l| + l.strip! + if not l=~/^\s*typedef\s+([a-zA-Z0-9_\* ]+?)\s+\**((?:\(\*)?\w+\)?)\s*\((.*)\);\s*$/ + r << indent+"# #{l}\n#{indent}# FIXME\n" + next + end + ret = $1 + name = $2 + args = $3.split(',').collect { |arg| get_type_from_arg arg }.join ', ' + k = name.sub(/\(/,'').sub(/\)/,'').sub(/\*/,'') + t = name.downcase.sub(/\(/,'').sub(/\)/,'').sub(/\*/,'') + set_type k, t, true + r << indent+"# #{l}\n" + r << wrap_text(indent+"callback :#{t}, [ #{args} ], #{get_type ret}", 150, indent+' '*4 )+"\n" + end + r +end +# +def gen_functions path, indent + r = '' + r << indent+"fcts = [\n" + open(path+'-functions','r').readlines.each do |l| + l.strip! + if not l=~ /EAPI ([a-zA-Z0-9_\* ]+?)(\w+) ?\(([a-zA-Z0-9_ \*,\.]+)\)( *[A-Z]{2,})?/ + r << indent+"# #{l}\n#{indent}# FIXME\n" + next + end + ret = $1 + func = $2.downcase + args = $3.split(',').collect { |arg| get_type_from_arg arg }.join ', ' + r << indent+"# #{l}\n" + r << wrap_text(indent+"[ :#{func}, [ #{args} ], #{get_type ret} ],", 150, indent+' '*4)+"\n" + end + r << indent+"]\n" + r +end +# +libraries.each do |header,lib| + module_name = header[0..-3].sub(/_/,'') + base = File.join path, 'api', header + dir = File.join lib_path, header[0..-3].split('_').first.downcase + Dir.mkdir dir unless Dir.exists? dir + output = File.join dir, "#{header[0..-3].downcase}-defs.rb" + puts "generate #{output}" + open(output,'w:utf-8') do |f| + f << HEADER.sub(/MNAME/,module_name) + f << "#{INDENT}#\n#{INDENT}# ENUMS\n" + f << gen_enums(base, INDENT) + f << "#{INDENT}#\n#{INDENT}# TYPEDEFS\n" + f << gen_typedefs(base, INDENT) + f << "#{INDENT}#\n#{INDENT}# CALLBACKS\n" + f << gen_callbacks(base, INDENT) + f << FOOTER + end + output = File.join dir, "#{header[0..-3].downcase}-funcs.rb" + puts "generate #{output}" + open(output,'w:utf-8') do |f| + f << HEADER.sub(/MNAME/,module_name) + f << "#{INDENT}#\n#{INDENT}ffi_lib '#{lib}'\n" + f << "#{INDENT}#\n#{INDENT}# FUNCTIONS\n" + f << gen_functions(base, INDENT) + f << "#{INDENT}#\n#{INDENT}attach_fcts fcts\n" + f << "#{INDENT}#\n#{INDENT}create_aliases '#{module_name.downcase}_'.length, fcts\n#{INDENT}#\n" + f << FOOTER + end +end +# |