summaryrefslogtreecommitdiffstats
path: root/tools/genruby.rb
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2011-04-19 01:18:06 +0200
committerJérémy Zurcher <jeremy@asynk.ch>2011-04-19 01:18:06 +0200
commitc1f521cbc9ab6631ba82c5b709d444d91c23a913 (patch)
treef2b34269f1f089b6f91a2c00e3f83b53f8c7c2ef /tools/genruby.rb
parent039ece9d20908a7cac0dc5a45d27b55703c6605c (diff)
downloadffi-efl-c1f521cbc9ab6631ba82c5b709d444d91c23a913.zip
ffi-efl-c1f521cbc9ab6631ba82c5b709d444d91c23a913.tar.gz
fix sed-callbacks, update extract-api.sh, add genruby.rb
Diffstat (limited to 'tools/genruby.rb')
-rwxr-xr-xtools/genruby.rb252
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
+#