source: EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecslib/plugin/TracePlugin.rb@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 17.0 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TECS Generator
4# Generator for TOPPERS Embedded Component System
5#
6# Copyright (C) 2008-2014 by TOPPERS Project
7#--
8# 上記著作権者
9は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
10# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11# 変・再é…
12å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
13# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15# スコード中に含まれていること.
16# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17# 用できる形で再é…
18å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
19å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
20# 者
21マニュアルなど)に,上記の著作権表示,この利用条件および下記
22# の無保証規定を掲載すること.
23# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
24# 用できない形で再é…
25å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
26# と.
27# (a) 再é…
28å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
29マニュアルなど)に,上記の著
30# 作権表示,この利用条件および下記の無保証規定を掲載すること.
31# (b) 再é…
32å¸ƒã®å½¢æ…
33‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
34# 報告すること.
35# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
36# 害からも,上記著作権者
37およびTOPPERSプロジェクトをå…
38è²¬ã™ã‚‹ã“と.
39# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
40# 由に基づく請求からも,上記著作権者
41およびTOPPERSプロジェクトを
42# å…
43è²¬ã™ã‚‹ã“と.
44#
45# 本ソフトウェアは,無保証で提供されているものである.上記著作権者
46お
47# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
48# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
49# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
50# の責任を負わない.
51#
52# $Id: TracePlugin.rb 1011 2016-07-11 02:20:01Z coas-nagasima $
53#++
54
55class TracePlugin < ThroughPlugin
56#@cellEntry_list::[ "Cell.eEntry", "Cell2.eEntry2", ... ]
57#@b_generate::bool : true : TracePlugin を生成する必
58要がある
59
60 #=== TracePlugin の initialize
61 # 説明は ThroughPlugin (plugin.rb) を参ç…
62§
63 def initialize( cell_name, plugin_arg, next_cell, next_cell_port_name, signature, celltype, caller_cell )
64
65 @maxArrayDisplay = 16
66 @cellEntry_list = []
67 @probeName = ""
68 @b_generate = false
69 @b_displayTime = false
70 @kernelCelltype = :"tKernel"
71 @syslogCelltype = :"tSysLog"
72
73 super
74 @plugin_arg_check_proc_tab = TracePluginArgProc
75 parse_plugin_arg
76
77 if @cellEntry_list.length > 0 then
78 @cellEntry_list.each{ |ce|
79 if "#{next_cell.get_name}.#{next_cell_port_name}".to_sym == ce.to_sym
80 @b_generate = true
81 end
82 }
83 else
84 @b_generate = true
85 end
86
87 if @b_generate == false then
88 # å…
89ƒã€…
90呼び出すセルに結合するものとする
91 @entry_port_name = next_cell_port_name
92 @cell_name = next_cell.get_name
93 end
94 end
95
96 #=== 宣言コードの生成
97 # typedef, signature, celltype など(cell 以外)のコードを生成
98 # 重複して生成してはならない(すでに生成されている場合は出力しないこと)
99 #file:: FILE 生成するファイル
100 def gen_plugin_decl_code( file )
101
102 # このセルタイプ(同じシグニチャ)は既に生成されているか?
103 if @@generated_celltype[ @ct_name ] == nil then
104 @@generated_celltype[ @ct_name ] = [ self ]
105 else
106 @@generated_celltype[ @ct_name ] << self
107 return
108 end
109
110 file2 = CFile.open( "#{$gen}/#{@ct_name}.cdl", "w" )
111
112 send_receive = []
113 if @signature != nil then
114 @signature.each_param{ |fd,param|
115 dir =param.get_direction
116 case dir
117 when :SEND, :RECEIVE
118 send_receive << [ dir, fd, param ]
119 end
120 }
121 end
122
123 file2.print <<EOT
124celltype #{@ct_name} {
125EOT
126
127 if send_receive.length > 0 then
128 file2.print " [ allocator(\n"
129 delim = ""
130 send_receive.each { |a|
131 file2.print "#{delim}\t#{a[1].get_name}.#{a[2].get_name}<=#{@call_port_name}.#{a[1].get_name}.#{a[2].get_name}"
132 delim = ",\n"
133 }
134 file2.print "\n )]\n"
135 end
136
137 file2.print <<EOT
138 entry #{@signature.get_namespace_path} #{@entry_port_name};
139 call #{@signature.get_namespace_path} #{@call_port_name};
140 attr{
141 char_t *probeName_str = "";
142 char_t *from_str = "";
143 };
144 require #{@syslogCelltype}.eSysLog;
145 require #{@kernelCelltype}.eKernel;
146};
147EOT
148# char_t *cell_port_name_str = "";
149
150 file2.close
151
152 file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
153 end
154
155 def gen_through_cell_code( file )
156
157 gen_plugin_decl_code( file )
158
159 if @b_generate != false then
160 nest = @region.gen_region_str_pre file
161 indent_str = " " * nest
162
163 if @probeName then
164 probeName_str = "#{indent_str} probeName_str = \"" + @probeName + ": \";\n"
165 else
166 probeName_str = ""
167 end
168 if @caller_cell then
169 caller_cell_str = "#{indent_str} from_str = \"#{@caller_cell.get_name}\";\n"
170 else
171 caller_cell_str = ""
172 end
173
174 file.print <<EOT
175#{indent_str}cell #{@ct_name} #{@cell_name} {
176#{indent_str} #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name};
177#{probeName_str}#{caller_cell_str}#{indent_str}};
178EOT
179# cell_port_name_str = \"#{@next_cell.get_name}.#{@next_cell_port_name}\";
180 @region.gen_region_str_post file
181 end
182
183 end
184
185 def gen_ep_func_body( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
186
187 if ! func_type.get_type.is_void? then
188 file.print( "\t#{func_type.get_type_str}\tretval;\n" )
189 end
190
191 file.print( "\tSYSUTM\tutime;\n" )
192
193 if ! b_singleton then
194
195 file.print <<EOT
196\t#{ct_name}_CB *p_cellcb;
197\tif( VALID_IDX( idx ) ){
198\t\tp_cellcb = #{global_ct_name}_GET_CELLCB(idx);
199\t}else{
200\t\t/* put code here for error */
201\t}
202
203EOT
204 end
205
206# p "celltype_name, sig_name, func_name, func_global_name"
207# p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
208
209
210 file.print <<EOT
211\tgetMicroTime( &utime );
212\tsyslog( LOG_INFO, \"Enter: %sTime=%d: #{@next_cell.get_name}.#{@next_cell_port_name}.#{func_name} calledFrom: %s\", ATTR_probeName_str, utime, ATTR_from_str );
213EOT
214
215 print_params( params, file, 0, :IN )
216
217 delim = ""
218 if ! func_type.get_type.is_void? then
219 file.print( "\tretval = " )
220 else
221 file.print( "\t" )
222 end
223
224 file.print( "#{@call_port_name}_#{func_name}(" )
225
226 params.each{ |param|
227 file.printf( "#{delim} #{param.get_name}" )
228 delim = ","
229 }
230 file.print( " );\n" )
231
232 file.print <<EOT
233\tgetMicroTime( &utime );
234\tsyslog( LOG_INFO, \"Leave: %sTime=%d: #{@next_cell.get_name}.#{@next_cell_port_name}.#{func_name}\", ATTR_probeName_str, utime );
235EOT
236
237 print_params( params, file, 0, :OUT )
238
239 if( ! func_type.get_type.is_void? ) then
240 print_param( "retval", func_type.get_type, file, 0, :RETURN, func_type.get_type.get_type_str, nil, nil)
241 file.print( "\treturn retval;\n" )
242 end
243
244 end
245
246 def print_params( params, file, nest, direction )
247 params.each{ |param|
248 dir = param.get_direction
249 if( direction == :IN )then
250 case dir
251 when :IN, :INOUT, :SEND
252 print_param( param.get_name, param.get_type, file, nest, dir, param.get_type.get_type_str, nil, nil )
253 end
254 else
255 case dir
256 when :OUT, :INOUT
257 print_param( param.get_name, param.get_type, file, nest, dir, param.get_type.get_type_str, nil, nil )
258 when :RECEIVE
259 outer = "*"
260 outer2 = nil
261 print_param( param.get_name, param.get_type.get_referto, file, nest, dir,
262 param.get_type.get_referto.get_type_str, outer, outer2 )
263 end
264 end
265 }
266 end
267
268 def print_param( name, type, file, nest, direction, type_str, outer, outer2, name_list = nil )
269 indent = " " * ( nest + 1 )
270
271 case type
272 when DefinedType
273 print_param( name, type.get_type, file, nest, direction, type_str, outer, outer2, name_list )
274 when VoidType
275 when BoolType
276 file.print( "#{indent}syslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %d;\", #{outer}#{name}#{outer2} );\n" )
277 when IntType
278 file.print <<EOT
279#{indent}if( sizeof(#{outer}#{name}#{outer2}) > sizeof(int_t) )
280#{indent}\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %ld;\", (long)#{outer}#{name}#{outer2} );
281#{indent}else
282#{indent}\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %d;\", #{outer}#{name}#{outer2} );
283EOT
284# file.print( "#{indent}syslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %ld;\", (long)#{outer}#{name}#{outer2} );\n" )
285 when FloatType
286 file.print( "#{indent}syslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{outer}#{name}#{outer2} = %g;\", (double)#{outer}#{name}#{outer2} );\n" )
287 when EnumType # mikan EnumType
288
289 when StructType
290 members_decl =type.get_members_decl
291 if outer || outer2
292 outer = "(#{outer}#{name}#{outer2})."
293 else
294 outer = "#{name}."
295 end
296 members_decl.get_items.each { |m|
297 print_param( m.get_name, m.get_type, file, nest, direction, m.get_type.get_type_str, outer, nil, members_decl )
298 }
299 when FuncType # mikan FuncType
300 when ArrayType # mikan ArrayType
301 when PtrType
302
303 se = type.get_size
304 ce = type.get_count
305 max_loop = @maxArrayDisplay
306 loop_count = nil
307
308 if se then
309 loop_count = "(((#{se.to_str( name_list, outer, outer2 )})>#{max_loop}) ? #{max_loop} : (#{se.to_str( name_list, outer, outer2 )}))"
310 file.print( "#{indent}syslog( LOG_INFO, \"#{indent}size_is(#{se.to_str( name_list, outer, outer2 )})=%d\", #{se.to_str( name_list, outer, outer2 )} );\n" )
311 size = "#{se.to_str( name_list, outer, outer2 )}"
312 elsif ce then
313 loop_count = "(((#{ce.to_str( name_list, outer, outer2 )})>#{max_loop}) ? #{max_loop} : (#{ce.to_str( name_list, outer, outer2 )})) "
314 file.print( "#{indent}syslog( LOG_INFO, \"#{indent}count_is(#{ce.to_str( name_list, outer, outer2 )})=%d\", #{ce.to_str( name_list, outer, outer2 )} );\n" )
315 size = "#{ce.to_str( name_list, outer, outer2 )}"
316 end
317
318 # mikan PtrType: string
319
320 referto = type.get_referto
321 type0 = type
322 type = referto
323 type_str = type.get_type_str
324 if type.kind_of?( DefinedType ) then
325 type = type.get_original_type
326 end
327
328 if type0.is_nullable? then
329 nest += 1
330 indent0 = indent
331 outer0 = outer
332 outer20 = outer2
333 indent += " "
334 file.print"#{indent0}if( #{outer}#{name}#{outer2} ){\n"
335 end
336
337 if loop_count == nil then
338 case type
339 when StructType
340 members = type.get_members_decl
341 if outer || outer2
342 outer = "(#{outer}#{name}#{outer2})->"
343 else
344 outer = "#{name}->"
345 end
346 outer2 = nil
347 members.get_items.each { |m|
348 print_param( m.get_name, m.get_type, file, nest, direction, m.get_type.get_type_str, outer, outer2, members )
349 }
350 when FuncType # mikan FuncType
351 when ArrayType # mikan ArrayType
352 when BoolType, IntType, FloatType, EnumType, PtrType
353 outer = "*#{outer}"
354 outer2 = "#{outer2}"
355 print_param( name, type, file, nest, direction, type_str, outer, outer2 )
356 end
357 else # loop_count != nil
358 if type.kind_of?( PtrType ) || type.kind_of?( StructType ) then
359 num_per_loop = 1
360 else
361 num_per_loop = 4
362 end
363
364 file.print <<EOT
365#{indent}{
366#{indent}\tint i__#{nest}, loop_count__ = #{loop_count};
367#{indent}\tfor( i__#{nest} = 0; i__#{nest} < loop_count__; i__#{nest}+=#{num_per_loop} ){
368EOT
369
370 case type
371 when StructType
372 members = type.get_members_decl
373 if outer || outer2
374 outer = "(#{outer}#{name}#{outer2})[i__#{nest}]."
375 else
376 outer = "#{name}[i__#{nest}]."
377 end
378 members.get_items.each { |m|
379 print_param( m.get_name, m.get_type, file, nest + 1, direction, m.get_type.get_type_str, outer, nil, members )
380 }
381 when FuncType # mikan FuncType
382 when ArrayType # mikan ArrayType
383
384 when BoolType, FloatType
385 if outer || outer2
386 outer = "(#{outer}"
387 outer2 = "#{outer2})"
388 end
389
390 file.print <<EOT
391#{indent}\t\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{name}[%d]: %d %d %d %d\",
392#{indent}\t\t\t\ti__#{nest}, #{outer}#{name}#{outer2}[i__#{nest}], #{outer}#{name}#{outer2}[i__#{nest}+1], #{outer}#{name}#{outer2}[i__#{nest}+2], #{outer}#{name}#{outer2}[i__#{nest}+3] );
393EOT
394 when IntType
395 if outer || outer2
396 outer = "(#{outer}"
397 outer2 = "#{outer2})"
398 end
399
400 file.print <<EOT
401#{indent}\t\tif( sizeof(#{outer}#{name}#{outer2}) > sizeof(int_t) )
402#{indent}\t\t\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{name}[%d]: %02x %02x %02x %02x\",
403#{indent}\t\t\t\t\ti__#{nest}, #{outer}#{name}#{outer2}[i__#{nest}], #{outer}#{name}#{outer2}[i__#{nest}+1], #{outer}#{name}#{outer2}[i__#{nest}+2], #{outer}#{name}#{outer2}[i__#{nest}+3] );
404#{indent}\t\telse
405#{indent}\t\t\tsyslog( LOG_INFO, \"#{indent}[#{direction}]#{type_str} #{name}[%d]: %02lx %02lx %02lx %02lx\",
406#{indent}\t\t\t\t\ti__#{nest}, #{outer}#{name}#{outer2}[i__#{nest}], #{outer}#{name}#{outer2}[i__#{nest}+1], #{outer}#{name}#{outer2}[i__#{nest}+2], #{outer}#{name}#{outer2}[i__#{nest}+3] );
407EOT
408
409 when PtrType
410 # type = type.get_referto
411 if outer || outer2
412 outer = "(#{outer}"
413 outer2 = "#{outer2})[i__#{nest}]"
414 else
415 outer = ""
416 outer2 = "[i__#{nest}]"
417 end
418 print_param( name, type, file, nest + 1, direction, type_str, outer, outer2 )
419 end
420
421 file.print <<EOT
422#{indent}\t} /* for ( i__#{nest} ) */
423#{indent}\tif( i__#{nest} < #{size} )
424#{indent}\t\tsyslog( LOG_INFO, \"#{indent}(%d elements are omitted)\", #{size} - i__#{nest} );
425#{indent}\telse if( i__#{nest} > #{size} )
426#{indent}\t\tsyslog( LOG_INFO, \"#{indent}(last %d elements are void)\", i__#{nest} - #{size} );
427#{indent}}
428EOT
429 end # loop_count == nil
430
431 if type0.is_nullable? then
432 file.print <<EOT
433#{indent0}} else {
434#{indent0} syslog( LOG_INFO, \"#{indent0}[#{direction}]#{outer0}#{name}#{outer20} = NULL\" );
435#{indent0}}
436EOT
437 end
438 end
439 end
440
441 # プラグイン引数名と Proc
442 TracePluginArgProc = {
443 "maxArrayDisplay" => Proc.new { |obj,rhs| obj.set_maxArrayDisplay rhs },
444 "cellEntry" => Proc.new { |obj,rhs| obj.set_cellEntry rhs },
445 "probeName" => Proc.new { |obj,rhs| obj.set_probeName rhs },
446 "displayTime" => Proc.new { |obj,rhs| obj.set_displayTime rhs },
447 "kernelCelltype" => Proc.new { |obj,rhs| obj.set_kernelCelltype rhs },
448 "syslogCelltype" => Proc.new { |obj,rhs| obj.set_syslogCelltype rhs },
449 }
450
451 def set_maxArrayDisplay rhs
452 @maxArrayDisplay = rhs
453 end
454
455 def set_cellEntry rhs
456 ces = rhs.to_s.split /\s*,\s*/
457 ces.each{ |ce|
458 if ce =~ /^[A-Za-z_]\w*\.[A-Za-z_]\w*$/ then
459 # OK
460 else
461 cdl_error( "#{ce}: TracePlugin arg not in \"symbol.symbol\" form" )
462 end
463 }
464 @cellEntry_list.concat ces
465 end
466
467 def set_probeName rhs
468 @probeName = rhs.to_s
469 end
470
471 def set_displayTime rhs
472 if rhs.to_s == "true"
473 @b_diplayTime = true
474 elsif rhs.to_s == "false"
475 @b_diplayTime = false
476 else
477 cdl_error( "displayTime : #{rhs} unsuitable: specify true or false" )
478 end
479 end
480
481 #=== プラグイン引数 tKernel のチェック
482 def set_kernelCelltype( rhs )
483 @kernelCelltype = rhs.to_sym
484 nsp = NamespacePath.analyze( @kernelCelltype.to_s )
485 obj = Namespace.find( nsp )
486 if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
487 cdl_error( "TracePlugin: kernelCelltype '#{rhs}' not celltype or not defined" )
488 end
489 end
490
491 #=== プラグイン引数 tSyslog のチェック
492 def set_syslogCelltype( rhs )
493 @syslogCelltype = rhs.to_sym
494 nsp = NamespacePath.analyze( @syslogCelltype.to_s )
495 obj = Namespace.find( nsp )
496 if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
497 cdl_error( "TracePlugin: syslogCelltype '#{rhs}' not celltype or not defined" )
498 end
499 end
500
501end
502
503
Note: See TracBrowser for help on using the repository browser.