brians | 343bc11 | 2013-02-10 01:53:46 +0000 | [diff] [blame^] | 1 | require File.dirname(__FILE__) + "/parser.rb" |
| 2 | |
| 3 | module 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 | |
| 75 | namespace #{$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}; |
| 182 | END2 |
| 183 | end).join('')} |
| 184 | |
| 185 | } // namespace #{$namespace} |
| 186 | |
| 187 | #endif |
| 188 | END |
| 189 | f.close |
| 190 | end |
| 191 | def write_cpp |
| 192 | f = File.open(filename('cc'), "w+") |
| 193 | f.puts <<END |
| 194 | // This file is autogenerated. |
| 195 | // Edit #{@filename} to change its contents. |
| 196 | |
| 197 | #include "#{filename 'h'}" |
| 198 | |
| 199 | namespace #{$namespace} { |
| 200 | |
| 201 | #{(@actions.collect do |a| |
| 202 | <<END2 |
| 203 | #{handle_class} #{a}("#{a}"); |
| 204 | END2 |
| 205 | end).join("\n")} |
| 206 | |
| 207 | } // namespace #{$namespace} |
| 208 | END |
| 209 | f.close |
| 210 | end |
| 211 | def write_main |
| 212 | f = File.open(filename('main'), "w+") |
| 213 | f.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 | |
| 223 | int 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 | } |
| 235 | END |
| 236 | f.close |
| 237 | end |
| 238 | end |
| 239 | end |
| 240 | |
| 241 | write_file_out |
| 242 | |