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