# HG changeset patch # User Jacob Carlborg # Date 1246820082 -7200 # Node ID d0162d8ca0f21794b831968d45e537921af7b455 # Parent 9fd439a28ce32cbf2bd782f1987db72039e5352e Added support for function pointers in dstepgen diff -r 9fd439a28ce3 -r d0162d8ca0f2 dstep/Cocoa/NSAutoreleasePool.d --- a/dstep/Cocoa/NSAutoreleasePool.d Sun Jul 05 17:16:19 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/** - * Copyright: Copyright (c) 2009 Jacob Carlborg. - * Authors: Jacob Carlborg - * Version: Initial created: Apr 19, 2009 - * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) - */ -module dstep.Cocoa.NSAutoreleasePool; - -import dstep.Cocoa.NSObject; -import dstep.objc.objc; -import dstep.objc.runtime; -/* -class NSAutoreleasePool : NSObject -{ - this (id object) - { - super(object); - } - - static NSAutoreleasePool alloc () - { - id r = objc.getClass!("NSAutoreleasePool").msgSend(sel.registerName!("alloc")); - return r ? new NSAutoreleasePool(r) : null; - } - - NSAutoreleasePool init () - { - return invokeObjcCall!(NSAutoreleasePool, "init"); - } - -}*/ \ No newline at end of file diff -r 9fd439a28ce3 -r d0162d8ca0f2 dstep/Cocoa/NSObject.d --- a/dstep/Cocoa/NSObject.d Sun Jul 05 17:16:19 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/** - * Copyright: Copyright (c) 2009 Jacob Carlborg. - * Authors: Jacob Carlborg - * Version: Initial created: Mar 28, 2009 - * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) - */ -module dstep.Cocoa.NSObject; - -import mambo.io; - -import dstep.objc.bridge.Bridge; -import dstep.objc.bridge.Wrapper; - - - -class NSObject : ObjcWrapper -{ - mixin ObjcWrap; - - int i = 34; - - NSObject foo (NSObject o) - { - println("foo in NSObject"); - o.add(1, 2); - println(this is o); - - this.add(3, 4); - - return this; - } - - mixin ObjcBindMethod!(foo); - - int add (int x, int y) - { - println(x + y); - return x + y; - } - - mixin ObjcBindMethod!(add); -} \ No newline at end of file diff -r 9fd439a28ce3 -r d0162d8ca0f2 dstep/Cocoa/NSString.d --- a/dstep/Cocoa/NSString.d Sun Jul 05 17:16:19 2009 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/** - * Copyright: Copyright (c) 2009 Jacob Carlborg. - * Authors: Jacob Carlborg - * Version: Initial created: Apr 19, 2009 - * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) - */ -module dstep.Cocoa.NSString; - -import tango.stdc.stringz; - -import dstep.Cocoa.NSObject; -import dstep.objc.bridge.Bridge; -import dstep.objc.bridge.Wrapper; -import dstep.internal.String; -import dstep.objc.objc; - -import mambo.io; - -class NSString : NSObject -{ - mixin ObjcWrap; - - string UTF8String () - { - char* s = invokeObjcSelf!(char*, "UTF8String"); - return fromStringz(s); - } - - int add (int x, int y) - { - println("NSString"); - return 0; - } - - mixin ObjcBindMethod!(add); -} \ No newline at end of file diff -r 9fd439a28ce3 -r d0162d8ca0f2 scripts/dgen.rb --- a/scripts/dgen.rb Sun Jul 05 17:16:19 2009 +0200 +++ b/scripts/dgen.rb Sun Jul 05 20:54:42 2009 +0200 @@ -154,7 +154,7 @@ self.class.instance_eval do define_method(method) do |*args| if args.length > 0 - self[method[0 ... -1]] = args[0] + #self[method[0 ... -1]] = args[0] self[eval(":#{method}"[0 ... -1])] = args[0] else result = self[method] diff -r 9fd439a28ce3 -r d0162d8ca0f2 scripts/dstepgen.rb --- a/scripts/dstepgen.rb Sun Jul 05 17:16:19 2009 +0200 +++ b/scripts/dstepgen.rb Sun Jul 05 20:54:42 2009 +0200 @@ -73,7 +73,7 @@ self.class.instance_eval do define_method(method) do |*args| if args.length > 0 - self[method[0 ... -1]] = args[0] + #self[method[0 ... -1]] = args[0] self[eval(":#{method}"[0 ... -1])] = args[0] else result = self[method] @@ -101,7 +101,7 @@ end # This Struct represents a C/Objective-C header -HeaderFile = Struct.new(:name, :framework, :cftypes, :constants, :defines, :enums, :externs, :functions, +HeaderFile = Struct.new(:name, :framework, :cftypes, :constants, :defines, :enums, :externs, :functions, :function_pointers, :imports, :inline_functions, :opaques, :path, :structs, :typedefs) do def initialize self.name = "" @@ -112,6 +112,7 @@ self.externs = [] self.framework = "" self.functions = [] + self.function_pointers = {} self.imports = [] self.inline_functions = [] self.opaques = [] @@ -146,7 +147,7 @@ @protocols = {} @categories = {} #@informal_protocols = {} - @function_pointer_types = {} + #@function_pointers = {} @do_64bit = false end @@ -206,7 +207,7 @@ end end - def function_pointer_types (header) + def function_pointers (header) re = /typedef\s+([\w\s]+)\s*\(\s*\*\s*(\w+)\s*\)\s*\(([^)]*)\)\s*;/ data = @cpp_result.scan(re) re = /typedef\s+([\w\s]+)\s*\(([^)]+)\)\s*;/ @@ -230,10 +231,37 @@ end type = "#{m[0]}(*)(#{args.join(', ')})" - @function_pointer_types[name] = type + header.function_pointers[name] = get_function_pointer(type) end end + def get_function_pointer (fp) + type = {} + re = /(.+)\(\*\)\((.+)\)/ + + if fp =~ /(.+)\(\*\)\((.+)\)/ + m1 = $1 + m2 = $2 + + type.const = m1 =~ /const/ ? true : false + m1.gsub!(/const/, "") + type.return_type = m1.strip + type.args = [] + + args = m2.split(",") + + args.each do |arg| + const = arg =~ /const/ ? true : false + arg.gsub!(/const/, "") + arg.strip! + arg.gsub!(/\s*\*/, "*") + type.args << {:type => arg, :const => const} + end + end + + type + end + def typedefs (header) re = /^\s*typedef\s+(.+)\s+([\w\*]+)\s*;$/ data = @cpp_result @@ -574,7 +602,7 @@ protocols(header) #informal_protocols(header) categories(header) - function_pointer_types(header) + function_pointers(header) end end @@ -595,7 +623,7 @@ protocols(header) #informal_protocols(header) categories(header) - function_pointer_types(header) + function_pointers(header) end end @@ -735,10 +763,10 @@ @stripped_return_type = t end - def function_pointer? (function_pointer_types) - type = @function_pointer_types[@stripped_return_type] || @stripped_return_type - @function_pointer_type ||= FunctionPointerInfo.new_from_type(type) - end + # def function_pointer? (function_pointers) + # type = @function_pointers[@stripped_return_type] || @stripped_return_type + # @function_pointer ||= FunctionPointerInfo.new_from_type(type) + # end def <=>(x) self.name <=> x.name @@ -1138,6 +1166,14 @@ end end + header.function_pointers.each do |fp, value| + types << value.return_type + + value.args.each do |arg| + types << arg.type + end + end + types end @@ -1247,6 +1283,18 @@ end end + header.function_pointers.each do |fp, value| + value.resolved_type = resolved_types[i] unless enable_64bit + value.resolved_type64 = resolved_types[i] if enable_64bit + i += 1 + + value.args.each do |arg| + arg.resolved_type = resolved_types[i] unless enable_64bit + arg.resolved_type64 = resolved_types[i] if enable_64bit + i += 1 + end + end + i end @@ -1449,6 +1497,16 @@ xml.returnValue :declaredType => function.return_type, :type => function.resolved_type, :type64 => function.resolved_type64, :const => function.const, :typeModifier => function.type_modifier end end + + header.function_pointers.each do |fp, value| + xml.functionPointer :name => fp do + value.args.each do |arg| + xml.arg :declaredType => arg.type, :type => arg.resolved_type, :type64 => arg.resolved_type64, :const => arg.const + end + + xml.returnValue :declaredType => value.return_type, :type => value.resolved_type, :type64 => value.resolved_type64, :const => value.const + end + end end end diff -r 9fd439a28ce3 -r d0162d8ca0f2 scripts/gen.rb --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/gen.rb Sun Jul 05 20:54:42 2009 +0200 @@ -0,0 +1,217 @@ +#!/usr/bin/env ruby + +## +# Copyright:: Copyright (c) 2009 Jacob Carlborg. +# Author:: Jacob Carlborg +# Version:: Initial created: 2009 +# License:: [Boost Software License 1.0]http://www.boost.org/LICENSE_1_0.txt +# + +require "rubygems" +gem "xml-simple" +require "xmlsimple" +require "optparse" +require "date" + +# Extensions to String +class String + + # Returns the index of the given character or length of the string if not found + # char:: the character to look for + # start:: the index where to start the search + # + # === Example: + # "012345789".index_of("1") #=> 1 + # "0123 0123".index_of("3", 6) #=> 8 + # + def index_of (char, start = 0) + return self.length if start >= self.length + + i = 0 + + if start == 0 + self.each_char do |c| + return i if char == c + i += 1 + end + else + self[start + 1 .. -1].each_char do |c| + return i + start + 1 if char == c + i += 1 + end + end + + return self.length + end +end + +class Generator + VERSION = 1.0 + + attr_accessor :dependencies_switch, :out_dir, :private + + def initialize + @frameworks = [] + @do_64bit = false + @dependencies_switch = false + @dependencies = {} + @private = false + end + + def framework_path (val) + return val if File.exist?(val) + + val += ".framework" unless /\.framework$/.match(val) + paths = ["/System/Library/Frameworks", "/Library/Frameworks", "#{ENV['HOME']}/Library/Frameworks"] + paths << "/System/Library/PrivateFrameworks" if @private + + paths.each do |dir| + path = File.join(dir, val) + return path if File.exist?(path) + end + + return nil + end + + def add_framework (framework) + @frameworks << framework_path(framework) + end + + def collect_dependencies (framework) + result = `./dstepgen.rb -f #{framework} -d` + @dependencies[framework] = {} + + result.each_line do |path| + path = path[0 .. -2] # remove the newline + @dependencies[framework][path] = true + collect_dependencies(path) unless @dependencies.key?(path) + end + end + + def write_dependencies + @frameworks.each do |framework| + collect_dependencies(framework) + end + + file = STDOUT + + @dependencies.each do |key, value| + file << "#{key}\n" + end + + exit + end + + def generate + dstep_file = "Frameworks.dstep" + + @frameworks.each do |framework| + collect_dependencies(framework) + end + + str = StringIO.new + + frameworks = [] + + @dependencies.each do |framework, value| + frameworks << get_umbrella_framework(framework) + end + + frameworks.uniq! + + frameworks.each do |framework| + str << " -f " + str << framework + end + + `./dstepgen.rb -o #{@out_dir}/#{dstep_file} #{str.string}` + `./dgen.rb -o #{@out_dir} #{@out_dir}/#{dstep_file}` + end + + def get_framework_name (framework) + i = framework.rindex(".framework") + return framework if i.nil? + x = framework.rindex("/", i) + framework[x + 1 ... i] + end + + def get_umbrella_framework (framework) + str = ".framework" + i = framework.index(str) + return framework[0 ... i + str.length] unless i.nil? + framework + end +end + +if __FILE__ == $0 + gen = Generator.new + + OptionParser.new do |opts| + opts.banner = "Usage: #{File.basename(__FILE__)} [options] " + opts.separator "" + opts.separator "Options:" + + opts.on("-u", "--umbrella FRAMEWORK", "Link againts the given umbrella framework.") do |opt| + gen.umbrella_framework(opt) + end + + opts.on(nil, "--64-bit", "Write 64-bit annotations.") do + gen.do_64bit = true + end + + opts.on("-p", "--private", "Include private frameworks.") do |opt| + gen.private = true + end + + opts.on("-o", "--output DIRECTORY", "Place the output file(s) in this directory.") do |opt| + die "The specified directory \"#{opt}\" does not exists" if File.exist?(opt) == false + die "Output directory cannot be specified more than once" if gen.out_dir + gen.out_dir = opt + end + + opts.on("-c", "--code CODE", "Inject CODE in the type file.") do |opt| + gen.code_to_inject = opt + end + + opts.on("-d", "--dependencies", "Write dependencies to stdout and exit.") do |opt| + gen.dependencies_switch = true + end + + help_msg = "Use the `-h' flag or for help." + + opts.on("-h", "--help", "Show this message and exit.") do + puts opts, help_msg + exit + end + + opts.on('-v', '--version', 'Show version and exit.') do + puts Generator::VERSION + exit + end + + opts.separator "" + + if ARGV.empty? + die opts.banner + else + #begin + opts.parse!(ARGV) + + ARGV.each do |framework| + gen.add_framework(framework) + end + + gen.write_dependencies if gen.dependencies_switch + + die "No output directory given" if gen.out_dir.nil? + + gen.generate + # rescue => e + # msg = e.message + # msg = "Internal error" if msg.empty? + # + # die msg, opts.banner, help_msg + # end + end + end +end \ No newline at end of file