source: azure_iot_hub/trunk/asp3_dcre/tecsgen/tecslib/plugin/TracePlugin.rb@ 389

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

ビルドが通るよう更新

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