source: EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenHRP2Marshaler.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: 24.4 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#++
53
54#プラグインオプション用変数
55#@task_priority:: Integer
56#@channelCelltype:: String
57#@channelCellName:: String
58#@PPAllocatorSize:: Integer
59module GenTransparentMarshaler
60
61 # プラグイン引数名と Proc
62 RPCPluginArgProc = {
63 "taskPriority" => Proc.new { |obj,rhs| obj.set_taskPriority rhs },
64 "channelCelltype" => Proc.new { |obj,rhs| obj.set_channelCelltype rhs },
65 "TDRCelltype" => Proc.new { |obj,rhs| obj.set_TDRCelltype rhs },
66 "channelCell" => Proc.new { |obj,rhs| obj.set_channelCellName rhs },
67 "PPAllocatorSize" => Proc.new { |obj,rhs| obj.set_PPAllocatorSize rhs },
68 }
69
70 #=== プラグイン引数 taskPriority のチェック
71 def set_taskPriority( rhs )
72 @task_priority = rhs
73 end
74
75 #=== プラグイン引数 channelCelltype のチェック
76 def set_channelCelltype( rhs )
77 @channelCelltype = rhs.to_sym
78 # path = [ "::", @channelCelltype ]
79 # obj = Namespace.find( path )
80 nsp = NamespacePath.analyze( @channelCelltype.to_s )
81 obj = Namespace.find( nsp )
82 if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
83 cdl_error( "RPCPlugin: channeclCelltype '#{rhs}' not celltype or not found" )
84 end
85 end
86
87 #=== プラグイン引数 TDRCelltype のチェック
88 def set_TDRCelltype( rhs )
89 @TDRCelltype = rhs.to_sym
90 # path = [ "::", @TDRCelltype ]
91 # obj = Namespace.find( path )
92 nsp = NamespacePath.analyze( @TDRCelltype.to_s )
93 obj = Namespace.find( nsp )
94 if ! obj.instance_of?( Celltype ) && ! obj.instance_of?( CompositeCelltype ) then
95 cdl_error( "RPCPlugin: TDRCelltype '#{rhs}' not celltype or not found" )
96 end
97 end
98
99 #=== プラグイン引数 channelCellName のチェック
100 def set_channelCellName( rhs )
101 @channelCellName = rhs
102 if @channelCellName =~ /\A[a-zA-Z_]\w*/ then
103 # OK
104 else
105 cdl_error( "RPCPlugin: channeclCellName '#{rhs}' unsuitable for identifier" )
106 end
107 end
108
109 #=== プラグイン引数 PPAllocatorSize のチェック
110 def set_PPAllocatorSize( rhs )
111 @PPAllocatorSize = rhs
112 end
113
114 #=== marshaler のセルタイプ名を設定する
115 def initialize_transparent_marshaler cell_name
116 @task_priority = 8
117 @channelCelltype = "tDataqueueOWChannel"
118 @TDRCelltype = "tTDR"
119 @channelCellName = "#{cell_name}_Channel"
120 @PPAllocatorSize = nil
121
122 @marshaler_celltype_name = "tMarshaler_#{@signature.get_name}"
123 @unmarshaler_celltype_name = "tUnmarshaler_#{@signature.get_name}"
124 @marshaler_celltype_file_name = "#{$gen}/#{@marshaler_celltype_name}.cdl"
125 end
126
127 def gen_marshaler_celltype
128
129 if @PPAllocatorSize then
130 alloc_call_port = " call sPPAllocator cPPAllocator;\n"
131 else
132 alloc_call_port = ""
133 end
134
135 f = CFile.open( @marshaler_celltype_file_name, "w" )
136 # 同じ内
137容を二度書く可能性あり (AppFile は不可)
138
139 # modified by ishikawa
140 f.print <<EOT
141
142celltype #{@marshaler_celltype_name} {
143 entry #{@signature.get_name} eClientEntry;
144 call sEventflag cEventflag;
145 call sSemaphore cSemaphore;
146 call sMessageBuffer cMessageBuffer;
147 //[optional]
148 // call sSemaphore cLockChannel; // this port is eliminated by optimize
149};
150celltype #{@unmarshaler_celltype_name} {
151 call #{@signature.get_name} cServerCall;
152 call sEventflag cEventflag;
153 call sSemaphore cSemaphore;
154 call sMessageBuffer cMessageBuffer;
155 entry sTaskBody eUnmarshalAndCallFunction;
156#{alloc_call_port}
157 FACTORY{
158 write("$ct$_factory.h", "#include <t_syslog.h>");
159 };
160};
161EOT
162 f.close
163 end
164
165 #=== 受け口関数の本体コードを生成(頭部と末尾は別途出力)
166 #ct_name:: Symbol (through プラグインで生成された) セルタイプ名 .Symbol として送られてくる(らしい)
167 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 )
168
169 # unmarshaler クラスか?
170 if ct_name == @unmarshaler_celltype_name.to_sym then
171 gen_ep_func_body_unmarshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
172 else
173 gen_ep_func_body_marshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
174 end
175 end
176
177 #=== marshal コードの生成
178 def gen_ep_func_body_marshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
179
180 b_void = false
181 b_ret_er = false
182
183 # 関数の戻り値のå…
184ƒã®åž‹ã‚’å¾—ã‚‹(typedef されている場合)
185 type = func_type.get_type.get_original_type
186
187 # 戻り値記憶用の変数を出力(void 型の関数では出力しない)
188 if ! type.kind_of?( VoidType ) then
189 if func_type.get_type.kind_of?( DefinedType ) && ( func_type.get_type.get_type_str == "ER" || func_type.get_type.get_type_str == "ER_INT" ) then
190 file.print( " #{func_type.get_type.get_type_str} retval_ = E_OK;\n" )
191 b_ret_er = true
192 else
193 file.print( " #{func_type.get_type.get_type_str} retval_;\n" )
194 end
195 else
196 b_void = true
197 end
198
199 file.print( " ER ercd_;\n" )
200 file.print( " FLGPTN flgptn;\n" )
201
202 # 呼びå…
203ˆã® signature を取り出す
204 signature = @signature
205
206 # 関数 ID (整数値)
207 func_id = signature.get_id_from_func_name( func_name )
208 file.print( " int16_t func_id_ = #{func_id}; /* id of #{func_name}: #{func_id} */\n" )
209
210 file.print( " uint8_t msg[256];\n" )
211
212 # シングルトンでないか?
213 if ! b_singleton then
214
215 # singleton でなければ p_cellcb 取得コードを出力
216 file.print <<EOT
217 #{ct_name}_CB *p_cellcb;
218
219 if( VALID_IDX( idx ) ){
220 p_cellcb = GET_CELLCB(idx);
221EOT
222
223 # エラーを返すか?
224 if b_ret_er then
225 file.print <<EOT
226 }else{
227 return ERCD( E_RPC, E_ID );
228 }
229EOT
230 else
231 file.print <<EOT
232 }else{
233 /* エラー処理コードをここに記述 */
234 }
235EOT
236 end
237 end
238
239 # channel lock コード
240 file.print <<EOT
241 ///* Channel Lock */
242 //if( is_cLockChannel_joined() )
243 // cLockChannel_wait();
244
245EOT
246
247=begin
248 # SOP を送信
249 file.print " /* SOPの送出 */\n"
250 file.print " if( ( ercd_ = cTDR_sendSOP( true ) ) != E_OK )\n"
251 file.print " goto error_reset;\n"
252=end
253
254 # func_id を送信
255 file.print " /* 関数 id の送出 */\n"
256=begin
257 file.print " if( ( ercd_ = cTDR_putInt16( func_id_ ) ) != E_OK )\n"
258 file.print " goto error_reset;\n"
259=end
260 file.print " *((int16_t *)(&msg[0])) = func_id_;\n"
261
262 # p "celltype_name, sig_name, func_name, func_global_name"
263 # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
264
265 b_get = false # marshal なら put
266 b_marshal = true # marshal
267
268 # in 方向のå…
269¥å‡ºåŠ›ã‚’出力
270 @index = 2
271 file.print " /* å…
272¥åŠ›å¼•æ•°é€å‡º */\n"
273 print_params( params, file, 1, b_marshal, b_get, true, func_type.is_oneway? )
274 print_params( params, file, 1, b_marshal, b_get, false, func_type.is_oneway? )
275=begin
276 if ! b_void && ! func_type.is_oneway? then
277 ret_ptr_type = PtrType.new( func_type.get_type )
278 print_param_nc( "retval_", ret_ptr_type, file, 1, :RETURN, "&", nil, b_get )
279 end
280=end
281
282 file.print " /* EOPの送出(パケットの掃きだし) */\n"
283 if ! func_type.is_oneway? then
284 b_continue = "true"
285 else
286 b_continue = "false"
287 end
288=begin
289 file.print " if( (ercd_=cTDR_sendEOP(#{b_continue})) != E_OK )\n"
290 file.print " goto error_reset;\n\n"
291=end
292 file.print " if( (ercd_=cMessageBuffer_send(msg, #{@index})) != E_OK )\n"
293 file.print " goto error_reset;\n\n"
294
295 file.print " cSemaphore_signal();\n\n"
296
297 if ! func_type.is_oneway? then
298 file.print <<EOT
299 if( (ercd_=cEventflag_wait( 0x01, TWF_ANDW, &flgptn )) != E_OK ){
300 ercd_ = ERCD(E_RPC,ercd_);
301 goto error_reset;
302 }
303 if( (ercd_=cEventflag_clear( 0x00 ) ) != E_OK ){
304 ercd_ = ERCD(E_RPC,ercd_);
305 goto error_reset;
306 }
307EOT
308 end # ! func_type.is_oneway?
309
310 file.print <<EOT
311 ///* Channel Lock */
312 //if( is_cLockChannel_joined() )
313 // cLockChannel_signal();
314EOT
315
316 if( b_void == false )then
317 # 呼びå…
318ƒã«æˆ»ã‚Šå€¤ã‚’リターン
319 file.print( " cMessageBuffer_receive(&retval_);\n" )
320 file.print( " return retval_;\n" )
321 else
322 file.print( " return;\n" )
323 end
324
325 file.print <<EOT
326
327error_reset:
328#if 0
329 if( ercd_ != ERCD( E_RPC, E_RESET ) )
330 (void)cTDR_reset();
331#endif
332EOT
333
334 # channel lock コード
335 file.print <<EOT
336 ///* Channel Lock */
337 //if( is_cLockChannel_joined() )
338 // cLockChannel_signal();
339
340EOT
341
342 if( b_ret_er != false )then
343 # 呼びå…
344ƒã«æˆ»ã‚Šå€¤ã‚’リターン
345 file.print( " return ercd_;\n" )
346 else
347 file.print( " return;\n" )
348 end
349
350 end
351
352 #=== unmarshal コードの生成
353 def gen_ep_func_body_unmarshal( file, b_singleton, ct_name, global_ct_name, sig_name, ep_name, func_name, func_global_name, func_type, params )
354
355# b_ret_er = true
356 b_ret_er = false
357
358 # func_id を得るコードを生成
359 file.print <<EOT
360
361 int16_t func_id_;
362 ER ercd_;
363
364 #{ct_name}_CB *p_cellcb;
365
366 if( VALID_IDX( idx ) ){
367 p_cellcb = GET_CELLCB(idx);
368EOT
369
370 if b_ret_er then
371 file.print <<EOT
372 }else{
373 return ERCD( E_RPC, E_ID );
374 }
375EOT
376 else
377 file.print <<EOT
378 }else{
379 /* エラー処理コードをここに記述 */
380 }
381EOT
382 end
383
384 file.print <<EOT
385
386 cSemaphore_wait();
387
388#if 0
389 /* SOPのチェック */
390 if( (ercd_=cTDR_receiveSOP( false )) != E_OK )
391 goto error_reset;
392 /* func_id の取得 */
393 if( (ercd_=cTDR_getInt16( &func_id_ )) != E_OK )
394 goto error_reset;
395#endif
396
397 if( (ercd_ = cMessageBuffer_receive(msg) < 0 ) )
398 goto error_reset;
399 func_id_ = ((int16_t *)msg)[0];
400
401#ifdef RPC_DEBUG
402 syslog(LOG_INFO, "unmarshaler task: func_id: %d", func_id_ );
403#endif
404 switch( func_id_ ){
405EOT
406
407 # 呼びå…
408ˆã® signature を取り出す
409 # port = @celltype.find( @next_cell_port_name )
410 # signature = port.get_signature
411 signature = @signature
412
413 # through の signature に含まれる すべての関数について
414 signature.get_function_head_array.each { |f|
415 f_name = f.get_name
416 f_type = f.get_declarator.get_type
417 id = signature.get_id_from_func_name( f_name )
418
419 # 関数は返り値を持つか?
420 if f_type.get_type.kind_of?( VoidType ) then
421 b_void = true
422 else
423 b_void = false
424 end
425
426 # パケットの終わりをチェック(未受け取りのデータが残っていないかチェック)
427 file.print " case #{id}: /*** #{f_name} ***/ \n"
428 file.print " if( tTransparentUnmarshaler_#{@signature.get_name}_#{f_name}() != E_OK )\n"
429 file.print " goto error_reset;\n"
430 file.print " break;\n"
431
432 } #
433
434 if @PPAllocatorSize then
435 ppallocator_dealloc_str = " /* PPAllocator のすべてを解放 */\n cPPAllocator_dealloc_all();"
436 else
437 ppallocator_dealloc_str = ""
438 end
439
440
441 file.print <<EOT
442 default:
443#if 0 // deleted by ishikawa: tSysLogが未実装
444
445 syslog(LOG_INFO, "unmarshaler task: ERROR: unknown func_id: %d", func_id_ );
446#endif /* 0 */
447 break;
448 };
449#{ppallocator_dealloc_str}
450 return;
451
452error_reset:
453#if 0
454 if( ercd_ != ERCD( E_RPC, E_RESET ) )
455 (void)cTDR_reset();
456#else
457 return ercd_;
458#endif
459#{ppallocator_dealloc_str}
460EOT
461
462 end
463
464 # IN b_marshal, b_get
465 # b_marshal = true && b_get == false : マーシャラでå…
466¥åŠ›å¼•æ•°é€å‡º
467 # b_marshal = true && b_get == true : マーシャラで出力引数受取
468 # b_marshal = false && b_get == true : アンマーシャラでå…
469¥åŠ›å¼•æ•°å—取
470 # b_marshal = false && b_get == get : アンマーシャラで出力引数送出
471 def print_params( params, file, nest, b_marshal, b_get, b_referenced, b_oneway = false )
472 params.each{ |param|
473# p "#{param.get_name}: b_marshal: #{b_marshal} b_get: #{b_get}"
474 if ! ( b_referenced == param.is_referenced? ) then
475 next
476 end
477
478 dir = param.get_direction
479 type = param.get_type
480 if b_oneway && dir == :IN && type.get_original_type.kind_of?( PtrType ) || type.get_original_type.kind_of?( ArrayType ) then
481 # oneway, in, PtrType の場合コピー
482 alloc_cp = "cPPAllocator_alloc"
483 alloc_cp_extra = nil
484 print_param( param.get_name, type, file, nest, dir, nil, nil, b_get, alloc_cp, alloc_cp_extra )
485 else
486 if( b_get == false && b_marshal == true || b_get == true && b_marshal == false )then
487 case dir
488# when :IN, :INOUT, :SEND
489 when :IN, :INOUT, :OUT, :SEND, :RECEIVE
490 print_param_nc( param.get_name, type, file, nest, b_marshal, nil, nil, b_get )
491 end
492 else
493# case dir
494# when :OUT, :INOUT, :RECEIVE
495# when :RECEIVE
496# print_param_nc( param.get_name, type, file, nest, b_marshal, nil, nil, b_get )
497# end
498 end
499 end
500 }
501 end
502
503 #=== コピーしない引数渡しコードの出力
504 def print_param_nc( name, type, file, nest, b_marshal, outer, outer2, b_get )
505 indent = " " * ( nest + 1 )
506
507 case type
508 when DefinedType
509 print_param_nc( name, type.get_type, file, nest, b_marshal, outer, outer2, b_get )
510 when BoolType, IntType, FloatType, PtrType, ArrayType
511 case type
512 when BoolType
513 type_str = "Int8"
514 cast_str = "int8_t"
515 when IntType
516 bit_size = type.get_bit_size
517 case type.get_sign
518 when :UNSIGNED
519 signC = "U"
520 sign = "u"
521 when :SIGNED
522 if bit_size == -1 || bit_size == -11 then
523 # signed char の場合、signed を指定する
524 signC = "S"
525 sign = "s"
526 else
527 signC = ""
528 sign = ""
529 end
530 else
531 signC = ""
532 sign = ""
533 end
534
535 # p "pn:: #{name} #{bit_size} #{type.get_type_str}"
536 case bit_size
537 when -1, -11 # -1: char_t, -11: char
538 type_str = "#{signC}Char"
539 cast_str = "#{sign}char_t"
540 when -2
541 type_str = "#{signC}Short"
542 cast_str = "#{sign}short_t"
543 when -3
544 type_str = "#{signC}Int"
545 cast_str = "#{sign}int_t"
546 when -4
547 type_str = "#{signC}Long"
548 cast_str = "#{sign}long_t"
549 when -5
550 type_str = "Intptr"
551 cast_str = "intptr_t"
552 when 8, 16, 32, 64, 128
553 type_str = "#{signC}Int#{bit_size}"
554 cast_str = "#{sign}int#{bit_size}_t"
555 else
556 raise "unknown bit_size '#{bit_size}' for int type "
557 end
558
559 when FloatType
560 bit_size = type.get_bit_size
561 if bit_size == 32 then
562 type_str = "Float32"
563 cast_str = "float32_t"
564 else
565 type_str = "Double64"
566 cast_str = "double64_t"
567 end
568
569 when PtrType
570 type_str = "Intptr"
571 cast_str = "intptr_t"
572 when ArrayType
573 type_str = "Intptr"
574 cast_str = "intptr_t"
575 end
576
577 if type.get_type_str == cast_str then
578 cast_str = ""
579 else
580 cast_str = "(" + cast_str + ")"
581 end
582
583 if( b_get )then
584 cast_str.gsub!( /\)$/, "*)" )
585 file.print " " * nest
586=begin
587 file.print "if( ( ercd_ = cTDR_get#{type_str}( #{cast_str}&(#{outer}#{name}#{outer2}) ) ) != E_OK )\n"
588 file.print " " * nest
589 file.print " goto error_reset;\n"
590=end
591 file.print "#{name} = *((#{type.get_type_str} *)(&msg[#{@index}]));\n"
592 if bit_size.nil?
593 raise "HRP2 RPC supports only specified bit_size"
594 else
595 case bit_size
596 when 8, 16, 32, 64, 128
597 else
598 raise "HRP2 RPC supports only specified bit_size"
599 end
600 end
601 @index += bit_size / 8
602 else
603 file.print " " * nest
604=begin
605 file.print "if( ( ercd_ = cTDR_put#{type_str}( #{cast_str}#{outer}#{name}#{outer2} ) ) != E_OK )\n"
606 file.print " " * nest
607 file.print " goto error_reset;\n"
608=end
609 file.print "*((#{type.get_type_str} *)(&msg[#{@index}])) = #{name};\n"
610 if bit_size.nil?
611 raise "HRP2 RPC supports only specified bit_size"
612 else
613 case bit_size
614 when 8, 16, 32, 64, 128
615 else
616 raise "HRP2 RPC supports only specified bit_size"
617 end
618 end
619 @index += bit_size / 8
620 end
621
622 when StructType
623 members_decl =type.get_members_decl
624 members_decl.get_items.each { |m|
625 if m.is_referenced? then
626 print_param_nc( m.get_name, m.get_type, file, nest, b_marshal, "#{outer}#{name}#{outer2}.", nil, b_get )
627 end
628 }
629 members_decl.get_items.each { |m|
630 if ! m.is_referenced? then
631 print_param_nc( m.get_name, m.get_type, file, nest, b_marshal, "#{outer}#{name}#{outer2}.", nil, b_get )
632 end
633 }
634
635 when VoidType
636 when EnumType # mikan EnumType
637 when FuncType # mikan FuncType
638 end
639 end
640
641
642 #=== PREAMBLE 部のコード生成
643 # アンマーシャラセルタイプの場合、アンマーシャラ関数のプロトタイプ宣言を生成
644 def gen_preamble file, b_singleton, ct_name, global_name
645 if ct_name != @unmarshaler_celltype_name.to_sym then
646 return
647 end
648
649 file.print "/* アンマーシャラ関数のプロトタイプ宣言 */\n"
650 # signature に含まれる すべての関数について
651 @signature.get_function_head_array.each { |f|
652 f_name = f.get_name
653 f_type = f.get_declarator.get_type
654 id = @signature.get_id_from_func_name( f_name )
655 file.print "static ER tTransparentUnmarshaler_#{@signature.get_name}_#{f_name}();\t/* func_id: #{id} */\n"
656 }
657 file.print "\n"
658 file.print "static uint8_t msg[256];\n"
659 file.print "\n"
660 end
661
662 #=== POSTAMBLE 部のコード生成
663 # アンマーシャラセルタイプの場合、アンマーシャラ関数の生成
664 def gen_postamble file, b_singleton, ct_name, global_name
665 if ct_name != @unmarshaler_celltype_name.to_sym then
666 return
667 end
668
669 file.print "\n/*** アンマーシャラ関数 ***/\n\n"
670 @signature.get_function_head_array.each { |f|
671 f_name = f.get_name
672 f_type = f.get_declarator.get_type
673 id = @signature.get_id_from_func_name( f_name )
674
675 # 関数は返り値を持つか?
676 if f_type.get_type.kind_of?( VoidType ) then
677 b_void = true
678 else
679 b_void = false
680 end
681
682 file.print <<EOT
683/*
684 * name: #{f_name}
685 * func_id: #{id}
686 */
687EOT
688 file.print "static ER\n"
689 file.print "tTransparentUnmarshaler_#{@signature.get_name}_#{f_name}()\n"
690 file.print "{\n"
691 file.print " ER ercd_;\n"
692
693 # 引数を受取る変数の定義
694 param_list = f.get_declarator.get_type.get_paramlist.get_items
695 # FuncHead-> Decl-> FuncType->ParamList
696 param_list.each{ |par|
697 name = par.get_name
698 type = par.get_type
699 if type.kind_of? ArrayType then
700 type = type.get_type
701 aster = "(*"
702 aster2 = ")"
703 else
704 aster = ""
705 aster2 = ""
706 end
707
708 type_str = type.get_type_str.gsub( /\bconst\b */, "" ) # "const" を外す
709
710 file.printf( " %-12s %s%s%s%s;\n", type_str, aster, name, aster2, type.get_type_str_post )
711 }
712
713 # 戻り値を受け取る変数の定義
714 if ! b_void then
715 if f.is_oneway? then
716 retval_ptr = "" # oneway の場合、受け取るが捨てられる
717 else
718 # =begin ishikawa modified
719 # retval_ptr = "*"
720 retval_ptr = ""
721 # =end ishikawa modified
722 end
723 file.printf( " %-12s #{retval_ptr}retval_%s;\n", f_type.get_type.get_type_str, f_type.get_type.get_type_str_post )
724 end
725
726 # in 方向のå…
727¥å‡ºåŠ›ã‚’å…
728¥åŠ›
729 file.print "\n /* å…
730¥åŠ›å¼•æ•°å—取 */\n"
731 b_get = true # unmarshal では get
732 b_marshal = false
733 @index = 2
734 print_params( param_list, file, 1, b_marshal, b_get, true, f.is_oneway? )
735 print_params( param_list, file, 1, b_marshal, b_get, false, f.is_oneway? )
736=begin
737 if ! b_void && ! f.is_oneway? then
738 ret_ptr_type = PtrType.new( f_type.get_type )
739 print_param_nc( "retval_", ret_ptr_type, file, 2, :RETURN, nil, nil, b_get )
740 end
741=end
742 # パケットの受信完了
743 # mikan 本当は、対象関数を呼出す後に実施したい.呼出しパケットの使用終わりを宣言する目的として
744 file.print " /* パケット終わりをチェック */\n"
745 if ! f.is_oneway? then
746 b_continue = "true"
747 else
748 b_continue = "false"
749 end
750=begin
751 file.print " if( (ercd_=cTDR_receiveEOP(#{b_continue})) != E_OK )\n"
752 file.print " goto error_reset;\n\n"
753=end
754 # 対象関数を呼出す
755 file.print " /* 対象関数の呼出し */\n"
756 if b_void then
757 file.print( " cServerCall_#{f_name}(" )
758 else
759 file.print( " #{retval_ptr}retval_ = cServerCall_#{f_name}(" )
760 end
761
762 delim = " "
763 param_list.each{ |par|
764 file.print delim
765 delim = ", "
766 file.print "#{par.get_name}"
767 }
768 file.print( " );\n" )
769
770 # 戻り値、出力引数の受取コードの生成
771
772 if ! b_void && ! f.is_oneway? then
773 file.print " if( (ercd_ = cMessageBuffer_send(&retval_, sizeof(#{f_type.get_type.get_type_str})) != E_OK ) )\n"
774 file.print " goto error_reset;\n"
775
776 end
777 # oneway の場合出力、戻り値が無く、受取を待
778たない(非同期な呼出し)
779 if ! f.is_oneway? then
780 file.print <<EOT
781 /* 関数処理の終了を通知 */
782 if( ( ercd_ = cEventflag_set( 0x01 ) ) != E_OK ){
783 goto error_reset;
784 }
785EOT
786 end # ! f.is_oneway?
787 file.print <<EOT
788 return E_OK;
789error_reset:
790 return ercd_;
791}
792
793EOT
794
795 }
796
797 end
798
799end
Note: See TracBrowser for help on using the repository browser.