blob: 3bbdaedb0a3d5c4348c57212f0a34795646bf83d [file] [log] [blame]
begin
require "sha1"
rescue LoadError
require "digest/sha1"
end
$i = 0
def getForLoopVar()
$i = $i + 1
return "_autogen_index_#{$i}"
end
module Target
end
class Target::Node
attr_accessor :created_by
def get_name()
if(@parent)
return "#{@parent.get_name}.#{@name}"
else
return "#{@name}"
end
end
end
class Target::QFile < Target::Node
def initialize() #needs to know repo_path,
@class_types = []
end
def add_type(type)
@class_types << type
end
def extern=(value)
@class_types.each do |type|
type.extern=value
end
end
def make_cpp_tree(rel_path)
cpp_tree = DepFilePair.new(rel_path)
cpp_tree.add_header_include("<array>")
cpp_tree.add_header_include("\"aos/macros.h\"")
cpp_tree.add_header_include("\"aos/queue.h\"")
@class_types.each do |type|
cpp_tree.get(type)
end
return cpp_tree
end
end
class Target::QInclude < Target::Node
def initialize(path)
@path = path
end
def extern=(value)
@extern=value
end
def create(cpp_tree)
return if (@extern)
# inc = cpp_tree.header.add_include("\"#{@path}\"")
inc = cpp_tree.add_header_include("\"#{@path}\"")
cpp_tree.set(self,inc)
end
end
class Target::QueueGroupDec < Target::Node
attr_accessor :name,:loc,:parent,:queues
def initialize(name)
@name = name
@queues = []
@subs = {}
end
def root()
@parent.root()
end
def []=(key,val)
#puts "#{key}= #{val}"
@subs[key] = val
end
def extern=(value)
@extern=value
end
def get_name()
if(@parent)
return "#{@parent.get_name}.#{@name}"
else
return "#{@name}"
end
end
def to_cpp_id(id)
name = "#{@name}::#{id}"
return @parent.to_cpp_id(name) if(@parent)
return name
end
def [](key)
#puts "#{key}"
@subs[key]
end
def add_queue(queue)
@queues.push(queue)
end
def hash_with_name(name)
ts = (@queues.collect { |queue|
queue.msg_hash()
}).join("") + name
return "0x#{Digest::SHA1.hexdigest(ts)[-8..-1]}"
end
def create(cpp_tree)
return if(@extern)
namespace = cpp_tree.get(@loc)
type_class = Types::Class.new(namespace,@name)
cpp_tree.set(self,type_class) #breaks infinite recursion
type_class.set_parent("public ::aos::QueueGroup")
@queues.each do |queue|
type_class.add_member(:public,queue.create_usage(cpp_tree))
end
create_Constructor(type_class,cpp_tree)
namespace.add(type_class)
end
def create_Constructor(type_class,cpp_tree)
member_func = CPP::Constructor.new(type_class)
type_class.add_member(:public,member_func)
#cpp_tree.cc_file.add_funct(member_func)
member_func.args << "const char *name";
member_func.add_cons("::aos::QueueGroup","name")
@queues.each do |queue|
member_func.args << "const char *#{queue.name}_name";
member_func.add_cons(queue.name,"#{queue.name}_name")
end
end
end
class Target::QueueGroup < Target::Node
attr_accessor :name,:loc
def initialize(type,name)
@type,@name = type,name
end
def type_name()
if(@type.loc == @loc) #use relative name
return @type.name
else #use full name
return @type.loc.to_cpp_id(@type.name)
end
end
def create(cpp_tree)
namespace = cpp_tree.get(@loc)
type = cpp_tree.get(@type)
cpp_tree.set(self,self)
namespace.add_cc("static #{type_name} *#{@name}_ptr")
counter = "#{@name}_counter"
namespace.add_cc("static int #{counter}")
str = <<COMMENT_END
Schwarz counter to construct and destruct the #{@name} object.
Must be constructed before &#{@name} is constructed so that #{@name}_ptr
is valid so we can store a reference to the object.
COMMENT_END
str.split(/\n/).each do |str_sec|
namespace.class_comment(str_sec)
end
init_class = namespace.add_class("InitializerFor_" + @name).add_dep(type)
init_class.add_cc_comment(
"The counter is initialized at load-time, i.e., before any of the static",
"objects are initialized.")
cons = CPP::Constructor.new(init_class)
init_class.add_member(:public,cons)
cons.suite << if_stmt = CPP::If.new("0 == #{counter}++")
cons_call = CPP::FuncCall.new("new #{type_name}")
cons_call.args.push(@loc.queue_name(@name).inspect)
@type.queues.collect do |queue|
cons_call.args.push(@loc.queue_name(@name + "." + queue.name).inspect)
end
if_stmt.suite << CPP::Assign.new("#{@name}_ptr",cons_call)
destruct = CPP::Destructor.new(init_class)
destruct.suite << if_stmt = CPP::If.new("0 == --#{counter}")
if_stmt.suite << "delete #{@name}_ptr"
if_stmt.suite << CPP::Assign.new("#{@name}_ptr","NULL")
init_class.add_member(:public,destruct)
init_class.static = true
init_class.dec = @name + "_initializer";
str = <<COMMENT_END
Create a reference to the new object in the pointer. Since we have already
created the initializer
COMMENT_END
str.split(/\n/).map{|str_sec| CPP::Comment.new(str_sec)}.each do |comment|
namespace.add(comment)
end
namespace.add("static UNUSED_VARIABLE #{type_name} &#{@name}" +
" = #{@name}_initializer.get()")
get = init_class.def_func(type_name,"get") #.add_dep(type)
get.pre_func_types = "&"
get.suite << CPP::Return.new("*#{@name}_ptr")
end
end