blob: d98549ceaf727b6484af60b470ef4e7b446e338d [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001require File.dirname(__FILE__) + "/parser.rb"
2
3module Contents
4 class HasEntry < SimpleField
5 end
6 class Priority < SimpleField
7 def initialize
8 super :is_number
9 end
10 end
11
12 class OutputFile
13 def fillin_initials
14 @args_struct = nil # string
15 @status_struct = nil # string
16 @action_name = nil # string
17 @actions = []
18 @has = []
19 end
20 def fillin_defaults
21 @action_name = @base unless @action_name
22 @actions.push @action_name if @actions.empty?
23 @args_struct.add_hidden_field 'timespec', 'set_time'
24 @status_struct.add_hidden_field 'timespec', 'set_time'
25 end
26 def parse_token token, tokenizer
27 case token
28 when 'args'
29 throw :syntax_error, '"args" redefined' if @args_struct
30 @args_struct = Struct.parse tokenizer
31 when 'status'
32 throw :syntax_error, '"status" redefined' if @status_struct
33 @status_struct = Struct.parse tokenizer
34 when 'action_name'
35 throw :syntax_error, '"action_name" redefined' if @action_name
36 @action_name = NameField.parse tokenizer
37 when 'async_queue'
38 @actions.push(NameField.parse tokenizer)
39 when 'has'
40 @has.push(HasEntry.parse tokenizer)
41 when 'priority'
42 throw :syntax_error, '"priority" redefined' if @priority
43 @priority = Priority.parse tokenizer
44 else
45 throw :syntax_error, "unsupported field \"#{token}\""
46 end
47 end
48 def check_format tokenizer
49 tokenizer.item_missing("args") unless @args_struct
50 tokenizer.item_missing("status") unless @status_struct
51 tokenizer.item_missing("priority") unless @priority
52 end
53
54 def superclass
55 "aos::AsyncAction<#{@args_struct.name}, #{@status_struct.name}>"
56 end
57 def impl_class
58 @action_name + '_t'
59 end
60 def handle_class
61 @action_name + 'Handle'
62 end
63 def write_header
64 f = File.open(filename('h'), "w+")
65 f.puts <<END
66#ifndef AOS_GENERATED_ASYNC_ACTION_#{impl_class}_H_
67#define AOS_GENERATED_ASYNC_ACTION_#{impl_class}_H_
68// This file is autogenerated.
69// Edit #{@filename} to change its contents.
70
71#include "aos/common/messages/QueueHolder.h"
72#include "aos/atom_code/async_action/AsyncAction.h"
73#include "aos/atom_code/async_action/AsyncActionHandle.h"
74
75namespace #{$namespace} {
76#{@args_struct.writer}
77#{@status_struct.writer}
78 class #{impl_class} : public #{superclass} {
79 virtual void DoAction(#{@args_struct.name} &args __attribute__((unused))){
80 DoAction(#{@args_struct.params_from 'args'});
81 }
82 void DoAction(#{@args_struct.params});
83#{@has.grep('OnStart').empty? ? '' : "virtual void OnStart();"}
84#{@has.grep('OnEnd').empty? ? '' : "virtual void OnEnd();"}
85 using #{superclass}::PostStatus;
86 inline void PostStatus(#{@status_struct.params}){
87 #{@status_struct.copy_params_into 'new_stat'}
88 PostStatus(new_stat);
89 }
90 public:
91 #{impl_class}(const std::string name) : #{superclass}(name) {}
92#ifdef AOS_#{impl_class}_HEADER_FRAG
93 AOS_#{impl_class}_HEADER_FRAG
94#endif
95 };
96
97 class #{handle_class} : public aos::AsyncActionHandle {
98 friend class ::AsyncActionTest;
99 private:
100 const std::string name;
101 #{superclass} *instance;
102 #{superclass} &GetInstance(){
103 if(instance == NULL){
104 instance = new #{superclass}(name);
105 }
106 return *instance;
107 }
108 #{@status_struct.name} temp_status;
109 void Free(){
110 if(instance != NULL){
111 delete instance;
112 instance = NULL;
113 }
114 }
115 public:
116 inline uint16_t Start(#{@args_struct.name} &args){
117 return GetInstance().Start(args);
118 }
119 inline uint16_t Start(#{@args_struct.params}){
120 #{@args_struct.copy_params_into 'args_struct'}
121 return Start(args_struct);
122 }
123 inline void Execute(#{@args_struct.name} &args){
124 GetInstance().Join(GetInstance().Start(args));
125 }
126 inline bool Execute(#{@args_struct.params}){
127 #{@args_struct.copy_params_into 'args_struct'}
128 Execute(args_struct);
129 return GetStatus();
130 }
131 inline bool IsDone(){
132 return GetInstance().IsDone();
133 }
134 inline bool IsDone(int32_t count){
135 return GetInstance().IsDone(count);
136 }
137 inline uint16_t Join(){
138 return GetInstance().Join();
139 }
140 inline uint16_t Join(int32_t count){
141 return GetInstance().Join(count);
142 }
143 inline bool GetStatus(#{@status_struct.name} &status_out) __attribute__ ((warn_unused_result)){
144 return GetInstance().GetStatus(status_out);
145 }
146 inline bool GetStatus(#{@status_struct.name} &status_out, int32_t count) __attribute__ ((warn_unused_result)){
147 return GetInstance().GetStatus(status_out, count);
148 }
149 inline bool GetStatus() __attribute__ ((warn_unused_result)){
150 return GetInstance().GetStatus(temp_status);
151 }
152 inline bool GetStatus(int32_t count) __attribute__ ((warn_unused_result)){
153 return GetInstance().GetStatus(temp_status, count);
154 }
155 inline bool GetNextStatus(#{@status_struct.name} &status_out) __attribute__ ((warn_unused_result)){
156 return GetInstance().GetNextStatus(status_out);
157 }
158 inline bool GetNextStatus(#{@status_struct.name} &status_out, int32_t count) __attribute__ ((warn_unused_result)){
159 return GetInstance().GetNextStatus(status_out, count);
160 }
161 inline bool GetNextStatus() __attribute__ ((warn_unused_result)){
162 return GetInstance().GetNextStatus(temp_status);
163 }
164 inline bool GetNextStatus(int32_t count) __attribute__ ((warn_unused_result)){
165 return GetInstance().GetNextStatus(temp_status, count);
166 }
167 inline const #{@status_struct.name} &GetLastStatus(){
168 return temp_status;
169 }
170 inline void Stop(){
171 GetInstance().Stop();
172 }
173 inline void Stop(int32_t count){
174 GetInstance().Stop(count);
175 }
176
177 #{handle_class}(const std::string name) : name(name), instance(NULL) {}
178 };
179#{(@actions.collect do |a|
180<<END2
181 extern #{handle_class} #{a};
182END2
183end).join('')}
184
185} // namespace #{$namespace}
186
187#endif
188END
189 f.close
190 end
191 def write_cpp
192 f = File.open(filename('cc'), "w+")
193f.puts <<END
194// This file is autogenerated.
195// Edit #{@filename} to change its contents.
196
197#include "#{filename 'h'}"
198
199namespace #{$namespace} {
200
201#{(@actions.collect do |a|
202<<END2
203#{handle_class} #{a}("#{a}");
204END2
205end).join("\n")}
206
207} // namespace #{$namespace}
208END
209 f.close
210 end
211 def write_main
212 f = File.open(filename('main'), "w+")
213f.puts <<END
214// This file is autogenerated.
215// Edit #{@filename} to change its contents.
216
217#include "#{filename 'h'}"
218#include "aos/atom_code/async_action/AsyncActionRunner.h"
219#include <string>
220#include <cstring>
221#include <iostream>
222
223int main(int argc, char **argv) {
224 aos::Init();
225
226 std::string name = "#{@action_name}";
227 if(argc > 1)
228 name = std::string(argv[1]);
229 #{$namespace}::#{impl_class} action(name);
230 int rv = aos::AsyncActionRunner::Run(action, #{@priority});
231
232 aos::Cleanup();
233 return rv;
234}
235END
236 f.close
237 end
238 end
239end
240
241write_file_out
242