blob: 1ef47a41300957ad2e7eb78d28c8010c618c5ca7 [file] [log] [blame]
Brian Silverman8efe23e2013-07-07 23:31:37 -07001begin
2 require "sha1"
3rescue LoadError
4 require "digest/sha1"
5end
6
brians343bc112013-02-10 01:53:46 +00007module Target
8end
9class Target::Node
10 attr_accessor :created_by
Parker Schuh343481e2014-02-09 18:28:43 -080011 def get_name()
12 if(@parent)
13 return "#{@parent.get_name}.#{@name}"
14 else
15 return "#{@name}"
16 end
17 end
brians343bc112013-02-10 01:53:46 +000018end
19class Target::QFile < Target::Node
20 def initialize() #needs to know repo_path,
21 @class_types = []
22 end
23 def add_type(type)
24 @class_types << type
25 end
26 def extern=(value)
27 @class_types.each do |type|
28 type.extern=value
29 end
30 end
31 def make_cpp_tree(rel_path)
32 cpp_tree = DepFilePair.new(rel_path)
33 cpp_tree.add_header_include("\"aos/common/macros.h\"")
34 cpp_tree.add_header_include("\"aos/common/queue.h\"")
35 @class_types.each do |type|
36 cpp_tree.get(type)
37 end
38 return cpp_tree
39 end
40end
41class Target::QInclude < Target::Node
42 def initialize(path)
43 @path = path
44 end
45 def create(cpp_tree)
46# inc = cpp_tree.header.add_include("\"#{@path}\"")
47 inc = cpp_tree.add_header_include("\"#{@path}\"")
48 cpp_tree.set(self,inc)
49 end
50end
51class Target::QueueGroupDec < Target::Node
52 attr_accessor :name,:loc,:parent,:queues
53 def initialize(name)
54 @name = name
55 @queues = []
56 @subs = {}
57 end
58 def root()
59 @parent.root()
60 end
61 def []=(key,val)
62 #puts "#{key}= #{val}"
63 @subs[key] = val
64 end
65 def extern=(value)
66 @extern=value
67 end
68 def get_name()
69 if(@parent)
70 return "#{@parent.get_name}.#{@name}"
71 else
72 return "#{@name}"
73 end
74 end
75 def to_cpp_id(id)
76 name = "#{@name}::#{id}"
77 return @parent.to_cpp_id(name) if(@parent)
78 return name
79 end
80 def [](key)
81 #puts "#{key}"
82 @subs[key]
83 end
84 def add_queue(queue)
85 @queues.push(queue)
86 end
87 def hash_with_name(name)
88 ts = (@queues.collect { |queue|
89 queue.msg_hash()
90 }).join("") + name
Brian Silverman8efe23e2013-07-07 23:31:37 -070091 return "0x#{Digest::SHA1.hexdigest(ts)[-8..-1]}"
brians343bc112013-02-10 01:53:46 +000092 end
93 def create(cpp_tree)
94 return if(@extern)
95 namespace = cpp_tree.get(@loc)
96 type_class = Types::Class.new(namespace,@name)
97 cpp_tree.set(self,type_class) #breaks infinite recursion
98 type_class.set_parent("public ::aos::QueueGroup")
99 @queues.each do |queue|
100 type_class.add_member(:public,queue.create_usage(cpp_tree))
101 namespace.add_pre_swig("%immutable #{@name}::#{queue.name}")
102 end
103 create_Constructor(type_class,cpp_tree)
104 namespace.add(type_class)
105 end
106 def create_Constructor(type_class,cpp_tree)
107 member_func = CPP::Constructor.new(type_class)
108 type_class.add_member(:public,member_func)
109 #cpp_tree.cc_file.add_funct(member_func)
110 member_func.args << "const char *name";
111 member_func.args << "uint32_t hash";
112 member_func.add_cons("::aos::QueueGroup","name", "hash")
113 @queues.each do |queue|
114 member_func.args << "const char *#{queue.name}_name";
115 member_func.add_cons(queue.name,"#{queue.name}_name")
116 end
117 end
118end
119class Target::QueueGroup < Target::Node
120 attr_accessor :name,:loc
121 def initialize(type,name)
122 @type,@name = type,name
123 end
124 def type_name()
125 if(@type.loc == @loc) #use relative name
126 return @type.name
127 else #use full name
128 return @type.loc.to_cpp_id(@type.name)
129 end
130 end
131 def create(cpp_tree)
132 namespace = cpp_tree.get(@loc)
133 type = cpp_tree.get(@type)
134 cpp_tree.set(self,self)
135 namespace.add_cc("static #{type_name} *#{@name}_ptr")
136 counter = "#{@name}_counter"
137 namespace.add_cc("static int #{counter}")
138
139 str = <<COMMENT_END
140Schwarz counter to construct and destruct the #{@name} object.
141Must be constructed before &#{@name} is constructed so that #{@name}_ptr
142is valid so we can store a reference to the object.
143COMMENT_END
144 str.split(/\n/).each do |str_sec|
145 namespace.class_comment(str_sec)
146 end
147 init_class = namespace.add_class("InitializerFor_" + @name).add_dep(type)
148
149
150 init_class.add_cc_comment(
151 "The counter is initialized at load-time, i.e., before any of the static",
152 "objects are initialized.")
153
154
155 cons = CPP::Constructor.new(init_class)
156 init_class.add_member(:public,cons)
157 cons.suite << if_stmt = CPP::If.new("0 == #{counter}++")
158 if_stmt.suite << "printf(#{"making a #{@name}!\n".inspect})"
159
160 cons_call = CPP::FuncCall.new("new #{type_name}")
161 cons_call.args.push(@loc.queue_name(@name).inspect)
162
163 cons_call.args.push(@type.hash_with_name(@loc.queue_name(@name).inspect))
164 @type.queues.collect do |queue|
165 cons_call.args.push(@loc.queue_name(@name + "." + queue.name).inspect)
166 end
167 if_stmt.suite << CPP::Assign.new("#{@name}_ptr",cons_call)
168 if_stmt.else_suite << CPP::FuncCall.build("printf","already made a #{@name}\n".inspect)
169
170
171 destruct = CPP::Destructor.new(init_class)
172 destruct.suite << if_stmt = CPP::If.new("0 == --#{counter}")
173 if_stmt.suite << "printf(#{"deleting a #{@name}!! :) !!\n".inspect})"
174 if_stmt.suite << "delete #{@name}_ptr"
175 if_stmt.suite << CPP::Assign.new("#{@name}_ptr","NULL")
176
177 init_class.add_member(:public,destruct)
178 init_class.static = true
179 init_class.dec = @name + "_initializer";
180
181 str = <<COMMENT_END
182Create a reference to the new object in the pointer. Since we have already
183created the initializer
184COMMENT_END
185 comments = str.split(/\n/).map{|str_sec| CPP::Comment.new(str_sec)}
186 comments << "static UNUSED_VARIABLE #{type_name} &#{@name} = " +
187 "#{@name}_initializer.get()"
188 namespace.add_post_swig("%immutable #{@name}_initializer")
189 namespace.add_post_swig(CPP::SwigPragma.new("java", "modulecode", CPP::Suite.new(["public static final #{@name} = get#{@name.capitalize}_initializer().get()"])))
190 ifdef_statement = CPP::IfnDef.new(CPP::Suite.new(comments))
191 ifdef_statement.name = "SWIG"
192 namespace.add(ifdef_statement)
193
194
195 get = init_class.def_func(type_name,"get") #.add_dep(type)
196 get.pre_func_types = "&"
197 get.suite << CPP::Return.new("*#{@name}_ptr")
198 end
199end