source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tecsgen/tecslib/plugin/lib/GenParamCopy.rb@ 352

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

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 16.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# 上記著作権者は,以下の(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
40#= ParamCopy
41#
42# パラメータコピーするマーシャラ/アンマーシャラコードを生成するメソッド print_param を提供する.
43# RPCPlugin, OpaqueRPCPlugin に include される.
44# RPCPlugin (トランスペアレント) では、oneway 関数で in のポインタ引数の場合に限って print_param が用いられる.
45#
46module GenParamCopy
47
48 #=== 引数の転送コードを生成
49
50 def print_param( name, type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp = nil, alloc_cp_extra = nil, name_list = nil )
51 if type.get_original_type.kind_of?( ArrayType ) && b_get && dir != :OUT then
52 indent = " " * nest
53 subsc = type.get_subscript
54 if subsc == nil
55 raise "Unsubscripted Array Not Supported"
56 else
57 size_str = subsc.to_str( name_list, outer, outer2 )
58 file.print <<EOT
59#{indent}if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*(#{size_str}),(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenParamCopy 1 */
60#{indent} goto error_reset;
61EOT
62 if ( dir == :SEND || dir == :RECEIVE ) && type.get_type.has_pointer? then
63 # send, receive の場合は、エラーリセットに備え NULL にする
64 file.print <<EOT
65#{indent}memset( (void *)#{outer}#{name}#{outer2}#{alloc_cp_extra}, 0, sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*(#{size_str}); /* GenParamCopy Alloc1 */
66EOT
67 end
68 end
69 end
70 print_param0( name, type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp, alloc_cp_extra, name_list )
71 end
72
73 def print_param0( name, type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp = nil, alloc_cp_extra = nil, name_list = nil )
74 indent = " " * nest
75
76 case type
77 when DefinedType
78 print_param0( name, type.get_type, file, nest, dir, outer, outer2, b_marshal, b_get, alloc_cp, alloc_cp_extra )
79 when BoolType, IntType, FloatType
80 case type
81 when BoolType
82 type_str = "Bool"
83 when IntType
84 bit_size = type.get_bit_size
85 case type.get_sign
86 when :UNSIGNED
87 sign = "U"
88 when :SIGNED
89 if bit_size == -1 || bit_size == -11 then
90 sign = "S" # signed char の場合のみ S がつく
91 else
92 sign = ""
93 end
94 else
95 sign = ""
96 end
97
98 case bit_size
99 when -1, -11 # -1: char_t, -11: char
100 type_str = "#{sign}Char"
101 when -2
102 type_str = "#{sign}Short"
103 when -3
104 type_str = "#{sign}Int"
105 when -4
106 type_str = "#{sign}Long"
107 when -5
108 type_str = "Intptr"
109 when 8, 16, 32, 64, 128
110 type_str = "#{sign}Int#{bit_size}"
111 else
112 raise "unknown bit_size '#{bit_size}' for int type "
113 end
114
115 when FloatType
116 bit_size = type.get_bit_size
117 if bit_size == 32 then
118 type_str = "Float32"
119 else
120 type_str = "Double64"
121 end
122
123 end
124
125 if( b_get )then
126 file.print indent
127 file.print "if( ( ercd_ = cTDR_get#{type_str}( &(#{outer}#{name}#{outer2}) ) ) != E_OK )\t/* GenParamCopy 2 */\n"
128 file.print indent
129 file.print " goto error_reset;\n"
130 else
131 file.print indent
132 file.print "if( ( ercd_ = cTDR_put#{type_str}( #{outer}#{name}#{outer2} ) ) != E_OK )\t/* GenParamCopy 3 */\n"
133 file.print indent
134 file.print " goto error_reset;\n"
135 end
136
137 when PtrType
138
139 count = type.get_count; size = type.get_size; string = type.get_string
140 if count || size || string then
141 nest = print_nullable_pre( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
142 indent = "\t" * nest
143 loop_counter_type = IntType.new(32) # mikan 型を size_is, count_is の引数の型とする
144 file.print "#{indent}{\t/* GenParamCopy 4 */\n"
145 file.print "#{indent} #{loop_counter_type.get_type_str} i__#{nest}, length__#{nest};\n"
146
147 if size || count then
148 if size then
149 size_str = size.to_str( name_list, outer, outer2 )
150 end
151
152 if count then
153 count_str = count.to_str( name_list, outer, outer2 )
154 else
155 # size_is は必須. count_is はオプション
156 count_str = size_str
157 end
158 file.print "#{indent} length__#{nest} = #{count_str};\t/* GenParamCopy 5 */\n"
159
160 # size_is に max 指定がある場合、length が max を超えているかチェックするコードを生成
161 # alloc_cp == nil のとき dir は INOUT, OUT のはず (条件が冗長)。試験が終わっているので、次回見直し時に外す
162 if b_get && type.get_max != nil && ! ( ( dir == :INOUT || dir == :OUT ) && alloc_cp == nil ) then
163 file.print "#{indent} if( length__#{nest} > #{type.get_max.to_s} ){\t/* GenParamCopy max check 1 */\n"
164 file.print "#{indent} ercd_ = E_PAR;\n"
165 file.print "#{indent} goto error_reset;\n"
166 file.print "#{indent} }\n"
167 end
168
169 else # if string then
170 case type.get_type.get_bit_size
171 when -1 # char_t
172 b_size = 8
173 when 8, 16, 32, 64 # intN_t, uintN_t
174 b_size = type.get_type.get_bit_size
175 else
176 cdl_error( "R9999 $1: string specifier cannot be specified to '$2' in current implementation",
177 name, type.get_type.get_type_str + type.get_type.get_type_str_post )
178 end
179 if ! b_get then
180 if string.instance_of? Expression then
181 len = string.to_str( name_list, outer, outer2 )
182 file.print "#{indent} length__#{nest} = STRNLEN#{b_size}(#{outer}#{name}#{outer2},(#{len}-1))+1;\t/* GenParamCopy 6 */\n"
183 file.print "#{indent} if( length__#{nest} < #{len})\tlength__#{nest} += 1;\n"
184 else
185 file.print "#{indent} length__#{nest} = STRLEN#{b_size}(#{outer}#{name}#{outer2})+1;\t/* GenParamCopy 7 */\n"
186 end
187 size_str = "length__#{nest}" # string の場合、strnlen 以上の領域を確保しない
188 else
189 if ( dir == :INOUT ) then
190 if ( string.instance_of? Expression ) then
191 len = string.to_str( name_list, outer, outer2 )
192 size_str = "#{len}" # string(len) の場合 len を確保する
193 else
194 raise "unsuscripted string used for inout parameter #{name}"
195 end
196 else
197 size_str = "length__#{nest}" # string の場合、strnlen 以上の領域を確保しない
198 end
199 end
200 print_param0( "length__#{nest}", loop_counter_type, file, nest + 1, dir, nil, nil, b_marshal, b_get )
201 end
202
203 if b_get && ( dir == :IN || dir == :INOUT || dir == :SEND || dir == :RECEIVE ) && alloc_cp then
204 file.print <<EOT
205#{indent} if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*(#{size_str}),(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenParamCopy 8 */
206#{indent} goto error_reset;
207EOT
208 if ( dir == :SEND || dir == :RECEIVE ) && type.get_type.has_pointer? then
209 # send, receive の場合は、エラーリセットに備え NULL にする
210 file.print <<EOT
211#{indent} memset( (void *)#{outer}#{name}#{outer2}#{alloc_cp_extra}, 0, sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post})*(#{size_str}) ); /* GenParamCopy Alloc2 */
212EOT
213 end
214 end
215 file.print "#{indent} for( i__#{nest} = 0; i__#{nest} < length__#{nest}; i__#{nest}++ ){\t/* GenParamCopy 9 */\n"
216
217 print_param0( name, type.get_type, file, nest + 2, dir, outer, "#{outer2}[i__#{nest}]", b_marshal, b_get, alloc_cp, alloc_cp_extra )
218 file.print "#{indent} }\n"
219 file.print "#{indent}}\n"
220
221 nest = print_nullable_post( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
222 indent = "\t" * nest
223 else
224
225 # nullable (pre)
226 nest = print_nullable_pre( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
227 indent = " " * nest
228
229 # allocate memory for getting value
230 if b_get && ( dir == :IN || dir == :INOUT || dir == :SEND || dir == :RECEIVE ) && alloc_cp then
231 file.print <<EOT
232#{indent}if((ercd_=#{alloc_cp}(sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post}),(void **)&#{outer}#{name}#{outer2}#{alloc_cp_extra}))!=E_OK)\t/* GenParamCopy 10 */
233#{indent} goto error_reset;
234EOT
235 if ( dir == :SEND || dir == :RECEIVE ) && type.get_type.has_pointer? then
236 # send, receive の場合は、エラーリセットに備え NULL にする
237 file.print <<EOT
238#{indent}memset( (void *)#{outer}#{name}#{outer2}#{alloc_cp_extra}, 0, sizeof(#{type.get_type.get_type_str}#{type.get_type.get_type_str_post}) ); /* GenParamCopy Alloc3 */
239EOT
240 end
241 end
242
243 print_param0( name, type.get_type, file, nest, dir, "(*#{outer}", "#{outer2})", b_marshal, b_get, alloc_cp, alloc_cp_extra )
244 # nullable (post)
245 nest = print_nullable_post( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
246 indent = " " * nest
247 end
248 when StructType
249 members_decl =type.get_members_decl
250 members_decl.get_items.each { |m|
251 if m.is_referenced?
252 print_param0( m.get_name, m.get_type, file, nest, dir, "#{outer}#{name}#{outer2}.", nil, b_marshal, b_get, alloc_cp, alloc_cp_extra, members_decl )
253 end
254 }
255 members_decl.get_items.each { |m|
256 if ! m.is_referenced?
257 print_param0( m.get_name, m.get_type, file, nest, dir, "#{outer}#{name}#{outer2}.", nil, b_marshal, b_get, alloc_cp, alloc_cp_extra, members_decl )
258 end
259 }
260
261 when VoidType
262 when EnumType # mikan EnumType
263 when FuncType # mikan FuncType
264 when ArrayType # mikan ArrayType
265 subsc = type.get_subscript
266 if subsc == nil
267 raise "Unsubscripted Array Not Supported"
268 else
269 size_str = subsc.to_str( name_list, outer, outer2 )
270
271 loop_counter_type = IntType.new(32) # mikan 型を size_is, count_is の引数の型とする
272 file.print "#{indent}{\t/* GenParamCopy 11 */\n"
273 file.print "#{indent} #{loop_counter_type.get_type_str} i__#{nest}, length__#{nest} = #{size_str};\n"
274
275 file.print "#{indent} for( i__#{nest} = 0; i__#{nest} < length__#{nest}; i__#{nest}++ ){\n"
276 print_param0( name, type.get_type, file, nest + 2, dir, outer, "#{outer2}[i__#{nest}]", b_marshal, b_get, alloc_cp, alloc_cp_extra )
277 file.print "#{indent} }\n"
278 file.print "#{indent}}\n"
279 end
280 end
281 end
282
283 #=== nullable (pre)
284 def print_nullable_pre( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
285 if type.is_nullable? then
286 indent = " " * nest
287 if dir == :OUT then # OUT の場合 print_out_nullable で NULL かどうかの情報を渡す
288 # 'null or not' is sent in the function 'print_out_nullable'
289 if b_get then
290 file.print "#{indent}if( #{outer}#{name}#{outer2} ){\t/* GenParamCopy Null 10 */\n"
291 else
292 file.print "#{indent}if( ! b_#{name}_null_ ){\t/* GenParamCopy Null 11 */\n"
293 end
294 nest += 1
295 else # dir = :IN, :INOUT, :SEND, :RECEIVE
296 if b_get then
297 file.print "#{indent}{\n"
298 if ! ( dir == :INOUT && b_marshal == true ) then
299 file.print <<EOT
300#{indent} int8_t b_null_;
301#{indent} if((ercd_=cTDR_getInt8( &b_null_ )) != E_OK )\t/* GenParamCopy Null 20 */
302#{indent} goto error_reset;
303#{indent} if( ! b_null_ ){
304EOT
305 else # dir = :INOUT, b_marshal = true, b_get = true の場合、NULL かどうかの情報を渡さない
306 file.print <<EOT
307#{indent} int8_t b_null_ = (#{outer}#{name}#{outer2} == NULL);\t/* GenParamCopy Null 21 */
308#{indent} if( ! b_null_ ){
309EOT
310 end
311 else
312 file.print <<EOT
313#{indent}{
314#{indent} int8_t b_null_ = (int8_t)(#{outer}#{name}#{outer2} == NULL);\t/* GenParamCopy Null 31 */
315EOT
316
317 if ! ( dir == :INOUT && b_marshal == false ) then
318 # dir = :INOUT, b_marshal = false, b_get = false の場合
319 file.print <<EOT
320#{indent} if((ercd_=cTDR_putInt8( b_null_ )) != E_OK )\t/* GenParamCopy Null 32 */
321#{indent} goto error_reset;
322EOT
323 end
324
325 file.print <<EOT
326#{indent} if( ! b_null_ ){\t/* GenParamCopy Null 33 */
327EOT
328 end
329 nest += 2
330 end
331 end
332 return nest
333 end
334
335 #== nullable (post)
336 def print_nullable_post( name, type, file, nest, dir, outer, outer2, b_marshal, b_get )
337 if type.is_nullable? then
338 if dir == :OUT then # OUT の場合 print_out_nullable で NULL かどうかの情報を渡す
339 nest -= 1
340 indent = " " * nest
341 file.print "#{indent}} /* ! b_#{name}_null_ GenParamCopy Null 50 */\n"
342 else # ( dir == :IN || dir == :INOUT || dir == :SEND || dir == :RECEIVE )
343 nest -= 2
344 indent = " " * nest
345 if b_get then
346 if ! ( dir == :INOUT && b_marshal == true ) then
347 file.print <<EOT
348
349#{indent} } else { /* null GenParamCopy Null 51 */
350#{indent} #{outer}#{name}#{outer2} = NULL;
351#{indent} } /* ! b_null_ */
352EOT
353 else # dir = :INOUT, b_marshal = true # inout の out 方向
354 file.print "#{indent} } /* ! b_null_ GenParamCopy Null 52 */\n"
355 end
356 else
357 file.print "#{indent} }\t/* GenParamCopy Null 53 */\n"
358 end
359 file.print "#{indent}}\t/* GenParamCopy Null 54 */\n"
360 end
361 end
362 return nest
363 end
364end
Note: See TracBrowser for help on using the repository browser.