diff options
| -rwxr-xr-x | tools/extract-api.sh | 16 | ||||
| -rwxr-xr-x | tools/genruby.rb | 252 | ||||
| -rw-r--r-- | tools/sed-callbacks | 12 | 
3 files changed, 273 insertions, 7 deletions
| diff --git a/tools/extract-api.sh b/tools/extract-api.sh index 00c3a5d..d9141f8 100755 --- a/tools/extract-api.sh +++ b/tools/extract-api.sh @@ -1,7 +1,9 @@  #! /bin/bash  # -CURRENT=$(dirname $0)/api -PREV=$(dirname $0)/api-prev +P=$(dirname $0) +# +CURRENT=$P/api +PREV=$P/api-prev  INCLUDE=$(pkg-config --libs ecore |gawk '{ print substr($1,3) }' | sed s/lib/include/)  #  [ ! -d $PREV ] && mkdir $PREV @@ -9,6 +11,7 @@ INCLUDE=$(pkg-config --libs ecore |gawk '{ print substr($1,3) }' | sed s/lib/inc  rm *-diff 2>/dev/null  #  for header in \ +    "${INCLUDE}/eina-1/eina/eina_types.h" \      "${INCLUDE}/eet-1/Eet.h" \      "${INCLUDE}/edje-1/Edje.h" \      "${INCLUDE}/evas-1/Evas.h" \ @@ -16,6 +19,7 @@ for header in \      "${INCLUDE}/ecore-1/Ecore.h" \      "${INCLUDE}/ecore-1/Ecore_Con.h" \      "${INCLUDE}/ecore-1/Ecore_Input.h" \ +    "${INCLUDE}/ecore-1/Ecore_Getopt.h" \      "${INCLUDE}/ecore-1/Ecore_Evas.h" \      "${INCLUDE}/ecore-1/Ecore_Fb.h" \      "${INCLUDE}/ecore-1/Ecore_File.h" \ @@ -29,11 +33,11 @@ for header in \      #      for what in functions enums types callbacks; do          F=$FILE-$what -        cat $header | sed -r -n -f sed-$what > $CURRENT/$F +        cat $header | sed -r -n -f $P/sed-$what > $CURRENT/$F          if [ -f $PREV/$F ]; then -            diff -u0 $PREV/$F $CURRENT/$F > $F-diff -            N=$(cat $F-diff | wc -l) -            [ $N -eq 0 ] && rm $F-diff +            diff -u0 $PREV/$F $CURRENT/$F > $P/$F-diff +            N=$(cat $P/$F-diff | wc -l) +            [ $N -eq 0 ] && rm $P/$F-diff          fi      done      # 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 +# diff --git a/tools/sed-callbacks b/tools/sed-callbacks index af9c2b7..37444a8 100644 --- a/tools/sed-callbacks +++ b/tools/sed-callbacks @@ -1 +1,11 @@ -/^\s*typedef\s+([a-zA-Z0-9_\* ]+?)\s+\*?(\(\*)?(\w+)\)?\s*\(.*\);\s*$/p +s/^\s*typedef\s+(.*)(\(\*?\w+\))?\s*(\(.*\));/typedef \1 \2 \3;/ +t finish +s/^\s*typedef\s+(.*)(\(\*?\w+\))?\s*(\(.*,)/typedef \1 \2 \3/ +T;h +:loop;n +/,$/ { H; b loop } +/;$/ { H;x} +:finish +s/\n//g +s/ {2,}/ /g +p | 
