source: azure_iot_hub/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenHRP2Marshaler.rb@ 388

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

Azure IoT Hub Device C SDK を使ったサンプルの追加

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