diff scripts/gen.rb @ 3:d0162d8ca0f2

Added support for function pointers in dstepgen
author Jacob Carlborg <doob@me.com>
date Sun, 05 Jul 2009 20:54:42 +0200
parents
children 6255d355d752
line wrap: on
line diff
--- /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] <frameworks...>"
+		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