tecscde 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rubocop.yml +125 -0
  4. data/.rubocop_todo.yml +188 -0
  5. data/CHANGELOG.md +3 -0
  6. data/Gemfile +6 -0
  7. data/LICENSE +46 -0
  8. data/LICENSE.ja +32 -0
  9. data/README.ja.md +200 -0
  10. data/README.md +35 -0
  11. data/Rakefile +27 -0
  12. data/bin/tecscde +64 -0
  13. data/glade/tecscde-cell-property.glade +205 -0
  14. data/glade/tecscde-celltype-property.glade +172 -0
  15. data/glade/tecscde-celltype.glade +414 -0
  16. data/glade/tecscde-export.glade +161 -0
  17. data/glade/test-cell-plugin.rb +51 -0
  18. data/glade/test-cell-property.rb +35 -0
  19. data/glade/test-export.rb +35 -0
  20. data/glade/test-palette.rb +26 -0
  21. data/lib/tcflow.rb +148 -0
  22. data/lib/tecscde.rb +65 -0
  23. data/lib/tecscde/NewCell.png +0 -0
  24. data/lib/tecscde/SelectArrow.png +0 -0
  25. data/lib/tecscde/attr_tree_view.rb +253 -0
  26. data/lib/tecscde/cell_plugin_dialog.glade +294 -0
  27. data/lib/tecscde/cell_plugin_dialog.rb +89 -0
  28. data/lib/tecscde/celltype_tree_view.rb +105 -0
  29. data/lib/tecscde/change_set_control.rb +35 -0
  30. data/lib/tecscde/change_set_control/change_set.rb +32 -0
  31. data/lib/tecscde/change_set_control/change_set_manager.rb +62 -0
  32. data/lib/tecscde/command.rb +35 -0
  33. data/lib/tecscde/control.rb +491 -0
  34. data/lib/tecscde/highlighted_objects.rb +180 -0
  35. data/lib/tecscde/logger.rb +74 -0
  36. data/lib/tecscde/main_view_and_model.rb +80 -0
  37. data/lib/tecscde/palette.glade +553 -0
  38. data/lib/tecscde/palette.rb +174 -0
  39. data/lib/tecscde/preferences.glade +117 -0
  40. data/lib/tecscde/preferences.rb +44 -0
  41. data/lib/tecscde/tecs_model.rb +1137 -0
  42. data/lib/tecscde/tecs_model/hbar.rb +68 -0
  43. data/lib/tecscde/tecs_model/tm_c_port.rb +122 -0
  44. data/lib/tecscde/tecs_model/tm_c_port_array.rb +98 -0
  45. data/lib/tecscde/tecs_model/tm_cell.rb +496 -0
  46. data/lib/tecscde/tecs_model/tm_e_port.rb +126 -0
  47. data/lib/tecscde/tecs_model/tm_e_port_array.rb +78 -0
  48. data/lib/tecscde/tecs_model/tm_join.rb +293 -0
  49. data/lib/tecscde/tecs_model/tm_join_bar.rb +146 -0
  50. data/lib/tecscde/tecs_model/tm_port.rb +238 -0
  51. data/lib/tecscde/tecs_model/tm_port_array.rb +246 -0
  52. data/lib/tecscde/tecs_model/tm_region.rb +107 -0
  53. data/lib/tecscde/tecs_model/tm_uneditable.rb +68 -0
  54. data/lib/tecscde/tecs_model/vbar.rb +68 -0
  55. data/lib/tecscde/templates/_cell_info.cde.erb +15 -0
  56. data/lib/tecscde/templates/_join_info.cde.erb +28 -0
  57. data/lib/tecscde/templates/main.cde.erb +49 -0
  58. data/lib/tecscde/tm_object.rb +91 -0
  59. data/lib/tecscde/version.rb +4 -0
  60. data/lib/tecscde/view.rb +58 -0
  61. data/lib/tecscde/view/cairo_matrix.rb +90 -0
  62. data/lib/tecscde/view/canvas.rb +59 -0
  63. data/lib/tecscde/view/constants.rb +114 -0
  64. data/lib/tecscde/view/main_view.rb +1245 -0
  65. data/lib/tecsflow.rb +475 -0
  66. data/lib/tecsflow/C_parser.tab.rb +2471 -0
  67. data/lib/tecsflow/C_parser.y.rb +1087 -0
  68. data/lib/tecsflow/classes.rb +421 -0
  69. data/lib/tecsgen.rb +581 -0
  70. data/lib/tecsgen/core/C_parser.tab.rb +2477 -0
  71. data/lib/tecsgen/core/C_parser.y +1032 -0
  72. data/lib/tecsgen/core/bnf-deb.tab.rb +5193 -0
  73. data/lib/tecsgen/core/bnf.tab.rb +5193 -0
  74. data/lib/tecsgen/core/bnf.y +2211 -0
  75. data/lib/tecsgen/core/componentobj.rb +7901 -0
  76. data/lib/tecsgen/core/ctypes.rb +226 -0
  77. data/lib/tecsgen/core/expression.rb +1031 -0
  78. data/lib/tecsgen/core/gen_xml.rb +374 -0
  79. data/lib/tecsgen/core/generate.rb +5206 -0
  80. data/lib/tecsgen/core/location.rb +116 -0
  81. data/lib/tecsgen/core/messages.rb +101 -0
  82. data/lib/tecsgen/core/optimize.rb +456 -0
  83. data/lib/tecsgen/core/plugin.rb +332 -0
  84. data/lib/tecsgen/core/pluginModule.rb +165 -0
  85. data/lib/tecsgen/core/syntaxobj.rb +1234 -0
  86. data/lib/tecsgen/core/tecs_lang.rb +306 -0
  87. data/lib/tecsgen/core/tecsgen.rb +453 -0
  88. data/lib/tecsgen/core/tecsinfo.rb +860 -0
  89. data/lib/tecsgen/core/tool_info.rb +258 -0
  90. data/lib/tecsgen/core/types.rb +1632 -0
  91. data/lib/tecsgen/core/unjoin_plugin.rb +218 -0
  92. data/lib/tecsgen/core/value.rb +650 -0
  93. data/lib/tecsgen/messages/messages_console_en_US.rb +1171 -0
  94. data/lib/tecsgen/messages/messages_console_ja_JP.rb +1171 -0
  95. data/lib/tecsgen/messages/messages_file_en_US.rb +334 -0
  96. data/lib/tecsgen/messages/messages_file_ja_JP.rb +163 -0
  97. data/lib/tecsgen/plugin/ATK1AlarmPlugin.rb +196 -0
  98. data/lib/tecsgen/plugin/ATK1DelayTaskPlugin.rb +106 -0
  99. data/lib/tecsgen/plugin/ATK1EventPlugin.rb +147 -0
  100. data/lib/tecsgen/plugin/ATK1ISRPlugin.rb +174 -0
  101. data/lib/tecsgen/plugin/ATK1KernelPlugin.rb +287 -0
  102. data/lib/tecsgen/plugin/ATK1ResourcePlugin.rb +124 -0
  103. data/lib/tecsgen/plugin/ATK1TaskPlugin.rb +220 -0
  104. data/lib/tecsgen/plugin/C2TECSBridgePlugin.rb +210 -0
  105. data/lib/tecsgen/plugin/CellPlugin.rb +61 -0
  106. data/lib/tecsgen/plugin/CelltypePlugin.rb +72 -0
  107. data/lib/tecsgen/plugin/CompositePlugin.rb +66 -0
  108. data/lib/tecsgen/plugin/DomainPlugin.rb +89 -0
  109. data/lib/tecsgen/plugin/HRP2AlarmHandlerPlugin.rb +76 -0
  110. data/lib/tecsgen/plugin/HRP2Cache.rb +1 -0
  111. data/lib/tecsgen/plugin/HRP2CyclicHandlerPlugin.rb +75 -0
  112. data/lib/tecsgen/plugin/HRP2DataqueuePlugin.rb +68 -0
  113. data/lib/tecsgen/plugin/HRP2EventflagPlugin.rb +68 -0
  114. data/lib/tecsgen/plugin/HRP2FixedSizeMemoryPoolPlugin.rb +68 -0
  115. data/lib/tecsgen/plugin/HRP2HandlerPlugin.rb +117 -0
  116. data/lib/tecsgen/plugin/HRP2KernelObjectPlugin.rb +372 -0
  117. data/lib/tecsgen/plugin/HRP2ObjectPlugin.rb +94 -0
  118. data/lib/tecsgen/plugin/HRP2Plugin.rb +140 -0
  119. data/lib/tecsgen/plugin/HRP2PostHook.rb +111 -0
  120. data/lib/tecsgen/plugin/HRP2PriorityDataqueuePlugin.rb +66 -0
  121. data/lib/tecsgen/plugin/HRP2RPCPlugin.rb +319 -0
  122. data/lib/tecsgen/plugin/HRP2SVCPlugin.rb +473 -0
  123. data/lib/tecsgen/plugin/HRP2SemaphorePlugin.rb +67 -0
  124. data/lib/tecsgen/plugin/HRP2TaskPlugin.rb +200 -0
  125. data/lib/tecsgen/plugin/HRPHandlerPlugin.rb +125 -0
  126. data/lib/tecsgen/plugin/HRPKernelObjectManager.rb +72 -0
  127. data/lib/tecsgen/plugin/HRPKernelObjectPlugin.rb +333 -0
  128. data/lib/tecsgen/plugin/HRPObjectPlugin.rb +93 -0
  129. data/lib/tecsgen/plugin/HRPPlugin.rb +356 -0
  130. data/lib/tecsgen/plugin/HRPRPCPlugin.rb +407 -0
  131. data/lib/tecsgen/plugin/HRPSVCPlugin.rb +859 -0
  132. data/lib/tecsgen/plugin/HRPTaskPlugin.rb +107 -0
  133. data/lib/tecsgen/plugin/Mruby2CBridgePlugin.rb +86 -0
  134. data/lib/tecsgen/plugin/MrubyBridgeCellPlugin.rb +264 -0
  135. data/lib/tecsgen/plugin/MrubyBridgeCelltypePlugin.rb +293 -0
  136. data/lib/tecsgen/plugin/MrubyBridgeCompositePlugin.rb +49 -0
  137. data/lib/tecsgen/plugin/MrubyBridgePlugin.rb +67 -0
  138. data/lib/tecsgen/plugin/MrubyBridgeSignaturePlugin.rb +1307 -0
  139. data/lib/tecsgen/plugin/MrubyInfoBridgePlugin.rb +14 -0
  140. data/lib/tecsgen/plugin/MrubyInfoBridgeSignaturePlugin.rb +994 -0
  141. data/lib/tecsgen/plugin/MultiPlugin.rb +57 -0
  142. data/lib/tecsgen/plugin/NotifierPlugin.rb +1217 -0
  143. data/lib/tecsgen/plugin/OpaqueMarshalerPlugin.rb +81 -0
  144. data/lib/tecsgen/plugin/OpaqueRPCPlugin.rb +323 -0
  145. data/lib/tecsgen/plugin/RPCPlugin.rb +266 -0
  146. data/lib/tecsgen/plugin/RepeatCellPlugin.rb +166 -0
  147. data/lib/tecsgen/plugin/RepeatJoinPlugin.rb +130 -0
  148. data/lib/tecsgen/plugin/SharedOpaqueRPCPlugin.rb +357 -0
  149. data/lib/tecsgen/plugin/SharedRPCPlugin.rb +329 -0
  150. data/lib/tecsgen/plugin/SignaturePlugin.rb +77 -0
  151. data/lib/tecsgen/plugin/TECS2CBridgePlugin.rb +178 -0
  152. data/lib/tecsgen/plugin/TECSInfoPlugin.rb +280 -0
  153. data/lib/tecsgen/plugin/ThroughPlugin.rb +333 -0
  154. data/lib/tecsgen/plugin/TracePlugin.rb +484 -0
  155. data/lib/tecsgen/plugin/lib/GenHRP2Marshaler.rb +761 -0
  156. data/lib/tecsgen/plugin/lib/GenOpaqueMarshaler.rb +1107 -0
  157. data/lib/tecsgen/plugin/lib/GenParamCopy.rb +365 -0
  158. data/lib/tecsgen/plugin/lib/GenTransparentMarshaler.rb +683 -0
  159. data/lib/tecsgen/plugin/lib/MrubyBridgeCelltypePluginModule.rb +283 -0
  160. data/lib/tecsgen/plugin/lib/MrubyBridgeSignaturePluginModule.rb +277 -0
  161. data/lib/tecsgen/version.rb +6 -0
  162. data/samples/FigureSamples/active/active.cde +104 -0
  163. data/samples/FigureSamples/active/active.cdl +20 -0
  164. data/samples/FigureSamples/active/active.pdf +0 -0
  165. data/samples/FigureSamples/active/active.png +0 -0
  166. data/samples/FigureSamples/active/gen/tmp_C_src.c +36 -0
  167. data/samples/FigureSamples/active/gen/tmp_cygwin_tecs.h +1908 -0
  168. data/samples/FigureSamples/active/gen/tmp_plugin_post_code.cdl +0 -0
  169. data/samples/FigureSamples/allocator/allocator-internal.png +0 -0
  170. data/samples/FigureSamples/allocator/allocator.cde +171 -0
  171. data/samples/FigureSamples/allocator/allocator.cdl +58 -0
  172. data/samples/FigureSamples/allocator/allocator.png +0 -0
  173. data/samples/FigureSamples/basic/Makefile +87 -0
  174. data/samples/FigureSamples/basic/SimpleSample-trace.cdl +50 -0
  175. data/samples/FigureSamples/basic/SimpleSample.cde +91 -0
  176. data/samples/FigureSamples/basic/SimpleSample.cdl +47 -0
  177. data/samples/FigureSamples/basic/basic.cde +93 -0
  178. data/samples/FigureSamples/basic/basic.cdl +46 -0
  179. data/samples/FigureSamples/basic/basic.png +0 -0
  180. data/samples/FigureSamples/callback/callback.cde +130 -0
  181. data/samples/FigureSamples/callback/callback.cdl +29 -0
  182. data/samples/FigureSamples/callback/callback.png +0 -0
  183. data/samples/FigureSamples/carray/carray.cde +144 -0
  184. data/samples/FigureSamples/carray/carray.cdl +38 -0
  185. data/samples/FigureSamples/carray/carray.png +0 -0
  186. data/samples/FigureSamples/cearray/cearray.cde +314 -0
  187. data/samples/FigureSamples/cearray/cearray.cdl +60 -0
  188. data/samples/FigureSamples/cearray/cearray.png +0 -0
  189. data/samples/FigureSamples/composite/composite-internal.png +0 -0
  190. data/samples/FigureSamples/composite/composite.cde +216 -0
  191. data/samples/FigureSamples/composite/composite.cdl +95 -0
  192. data/samples/FigureSamples/composite/composite.png +0 -0
  193. data/samples/FigureSamples/earray/earray.cde +142 -0
  194. data/samples/FigureSamples/earray/earray.cdl +38 -0
  195. data/samples/FigureSamples/earray/earray.png +0 -0
  196. data/samples/FigureSamples/join/Makefile +87 -0
  197. data/samples/FigureSamples/join/join.cde +132 -0
  198. data/samples/FigureSamples/join/join.cdl +40 -0
  199. data/samples/FigureSamples/join/join.png +0 -0
  200. data/samples/FigureSamples/relay/Makefile +99 -0
  201. data/samples/FigureSamples/relay/relay-internal.png +0 -0
  202. data/samples/FigureSamples/relay/relay.cde +284 -0
  203. data/samples/FigureSamples/relay/relay.cdl +52 -0
  204. data/samples/FigureSamples/relay/relay.png +0 -0
  205. data/samples/FigureSamples/rpc/Makefile +123 -0
  206. data/samples/FigureSamples/rpc/rpc-expand.png +0 -0
  207. data/samples/FigureSamples/rpc/rpc.cde +245 -0
  208. data/samples/FigureSamples/rpc/rpc.png +0 -0
  209. data/samples/FigureSamples/rpc/rpc_sample.cdl +53 -0
  210. data/samples/SimpleSample/Makefile +25 -0
  211. data/samples/SimpleSample/SimpleSample/Makefile +86 -0
  212. data/samples/SimpleSample/SimpleSample/Makefile-trace +91 -0
  213. data/samples/SimpleSample/SimpleSample/README.txt +106 -0
  214. data/samples/SimpleSample/SimpleSample/SimpleSample-trace.cdl +50 -0
  215. data/samples/SimpleSample/SimpleSample/SimpleSample.cdl +45 -0
  216. data/samples/SimpleSample/SimpleSample/src/tSample.c +77 -0
  217. data/samples/SimpleSample/SimpleSample/src/tSimple.c +48 -0
  218. data/samples/SimpleSample/SimpleSample/src/tecs-types.h +27 -0
  219. data/samples/SimpleSample/SimpleSampleOpaqueRPC/Makefile +51 -0
  220. data/samples/SimpleSample/SimpleSampleOpaqueRPC/Makefile-trace +91 -0
  221. data/samples/SimpleSample/SimpleSampleOpaqueRPC/README.txt +106 -0
  222. data/samples/SimpleSample/SimpleSampleOpaqueRPC/SimpleSample-trace.cdl +80 -0
  223. data/samples/SimpleSample/SimpleSampleOpaqueRPC/SimpleSample.cdl +77 -0
  224. data/samples/SimpleSample/SimpleSampleOpaqueRPC/rSample/Makefile +112 -0
  225. data/samples/SimpleSample/SimpleSampleOpaqueRPC/rSimple/Makefile +109 -0
  226. data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tSample.c +80 -0
  227. data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tSimple.c +47 -0
  228. data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tTaskMain.c +66 -0
  229. data/samples/SimpleSample/SimpleSampleOpaqueRPC/src/tecs-types.h +27 -0
  230. data/samples/SimpleSample/SimpleSampleTransparentRPC/Makefile +125 -0
  231. data/samples/SimpleSample/SimpleSampleTransparentRPC/Makefile-trace +130 -0
  232. data/samples/SimpleSample/SimpleSampleTransparentRPC/SimpleSample-trace.cdl +54 -0
  233. data/samples/SimpleSample/SimpleSampleTransparentRPC/SimpleSample.cdl +53 -0
  234. data/samples/SimpleSample/SimpleSampleTransparentRPC/src/tSample.c +80 -0
  235. data/samples/SimpleSample/SimpleSampleTransparentRPC/src/tSimple.c +54 -0
  236. data/tecscde.gemspec +41 -0
  237. metadata +353 -0
@@ -0,0 +1,407 @@
1
+ #
2
+ # TECS Generator
3
+ # Generator for TOPPERS Embedded Component System
4
+ #
5
+ # Copyright (C) 2008-2018 by TOPPERS Project
6
+ #--
7
+ # 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
8
+ # ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9
+ # 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10
+ # (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11
+ # 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12
+ # スコード中に含まれていること.
13
+ # (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14
+ # 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15
+ # 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16
+ # の無保証規定を掲載すること.
17
+ # (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18
+ # 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19
+ # と.
20
+ # (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21
+ # 作権表示,この利用条件および下記の無保証規定を掲載すること.
22
+ # (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23
+ # 報告すること.
24
+ # (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25
+ # 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26
+ # また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27
+ # 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28
+ # 免責すること.
29
+ #
30
+ # 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31
+ # よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32
+ # に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33
+ # アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34
+ # の責任を負わない.
35
+ #
36
+ # $Id: HRPRPCPlugin.rb 2952 2018-05-07 10:19:07Z okuma-top $
37
+ #++
38
+
39
+ require_tecsgen_lib "lib/GenOpaqueMarshaler.rb"
40
+ require_tecsgen_lib "lib/GenParamCopy.rb"
41
+
42
+ #= HRPRPCPlugin プラグイン
43
+ # スループラグイン (through)
44
+ # ・OpaqueMarshalerPlugin を使用してマーシャラセルタイプを生成する
45
+ # ・マーシャラ、TDR、チャンネル、メッセージバッファを生成する
46
+ #
47
+ class HRPRPCPlugin < ThroughPlugin
48
+ include GenOpaqueMarshaler
49
+ include GenParamCopy
50
+
51
+ # RPCPlugin 専用のオプション
52
+ HRPRPCPluginArgProc = RPCPluginArgProc.dup # 複製を作って元を変更しないようにする
53
+ HRPRPCPluginArgProc["noClientSemaphore"] = Proc.new {|obj, rhs| obj.set_noClientSemaphore rhs }
54
+ HRPRPCPluginArgProc["semaphoreCelltype"] = Proc.new {|obj, rhs| obj.set_semaphoreCelltype rhs }
55
+ @@isFirstInstance = true
56
+
57
+ #=== RPCPlugin の initialize
58
+ # 説明は ThroughPlugin (plugin.rb) を参照
59
+ def initialize(cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell)
60
+ super
61
+ @b_noClientSemaphore = false
62
+ @semaphoreCelltype = "tSemaphore"
63
+ initialize_opaque_marshaler
64
+
65
+ # オプション:GenOpaqueMarshaler 参照
66
+ @plugin_arg_check_proc_tab = HRPRPCPluginArgProc
67
+ parse_plugin_arg
68
+
69
+ @rpc_channel_celltype_name = "tRPCPlugin_#{@TDRCelltype}_#{@channelCelltype}_#{@signature.get_name}"
70
+ @rpc_channel_celltype_file_name = "#{$gen}/#{@rpc_channel_celltype_name}.cdl"
71
+
72
+ if @signature.get_context == "non-task"
73
+ cdl_error("HRP9999 RPC cannot be applied to non-task context signature '$1'", @signature.get_name)
74
+ elsif @signature.get_context == "any"
75
+ cdl_info("HRP9999 RPC is applied to any context signature '$1'", @signature.get_name)
76
+ end
77
+
78
+ if @signature.need_PPAllocator?(true)
79
+ if @PPAllocatorSize.nil?
80
+ cdl_error("HRP9999 PPAllocatorSize must be speicified for pointer argments")
81
+ # @PPAllocatorSize = 0 # 仮に 0 としておく (cdl の構文エラーを避けるため)
82
+ end
83
+ elsif @PPAllocatorSize
84
+ cdl_warning("HRP9999 PPAllocatorSize speicified in spite of PPAllocator unnecessary")
85
+ @PPAllocatorSize = nil
86
+ end
87
+
88
+ # @signature.each_param{ |func_decl, param_decl|
89
+ # if func_decl.get_type.is_oneway? then
90
+ # if ( param_decl.get_size || param_decl.get_count ) && param_decl.get_string then
91
+ # cdl_error( "array of string not supported for oneway function in Transparent RPC" ) # mikan 文字列の配列
92
+ # elsif param_decl.get_string == -1 then
93
+ # cdl_error( "length unspecified string is not permited for oneway function in Transparent RPC" ) # mikan 長さ未指定文字列
94
+ # end
95
+ # end
96
+ # }
97
+
98
+ #
99
+ # tecsgen/tecs/rpcにincludeパスを通す
100
+ # #include "tecs_rpc.h" を実現するために必要
101
+ # 大山:削除 Makefile.tecsgen に vpath, INCLUDES を入れるのは、よくない考え
102
+ # TECSGEN.add_search_path で Makefile_templ に入れるのがよい
103
+ # if @@isFirstInstance
104
+ # f = AppFile.open( "#{$gen}/Makefile.tecsgen" )
105
+ # f.puts "INCLUDES := $(INCLUDES) -I $(TECSPATH) -I $(TECSPATH)/rpc"
106
+ # f.puts "vpath %.c $(TECSPATH) $(TECSPATH)/rpc"
107
+ # f.close()
108
+ # @@isFirstInstance = false
109
+ # end
110
+ end
111
+
112
+ #=== plugin の宣言コード (celltype の定義) 生成
113
+ def gen_plugin_decl_code(file)
114
+ ct_name = "#{@ct_name}_#{@channelCelltype}"
115
+
116
+ # このセルタイプ(同じシグニチャ)は既に生成されているか?
117
+ if @@generated_celltype[ct_name].nil?
118
+ @@generated_celltype[ct_name] = [self]
119
+ else
120
+ @@generated_celltype[ct_name] << self
121
+ return
122
+ end
123
+
124
+ f = CFile.open(@rpc_channel_celltype_file_name, "w")
125
+ # 同じ内容を二度書く可能性あり (AppFile は不可)
126
+
127
+ f.print <<EOT
128
+ import( <rpc.cdl> );
129
+ import( <tMessageBufferCEP.cdl> );
130
+ generate( OpaqueMarshalerPlugin, #{@signature.get_namespace_path}, "" );
131
+
132
+ composite tOpaqueMarshaler_#{@signature.get_global_name}_through {
133
+ entry #{@signature.get_namespace_path} eThroughEntry;
134
+ call sTDR cTDR;
135
+ [optional]
136
+ call sSemaphore cLockChannel;
137
+ [optional]
138
+ call sRPCErrorHandler cErrorHandler;
139
+
140
+ cell tOpaqueMarshaler_#{@signature.get_global_name} Marshaler{
141
+ cTDR => composite.cTDR;
142
+ cLockChannel => composite.cLockChannel;
143
+ cErrorHandler => composite.cErrorHandler;
144
+ };
145
+ composite.eThroughEntry => Marshaler.eClientEntry;
146
+ };
147
+
148
+ EOT
149
+
150
+ f.close
151
+ end
152
+
153
+ #=== through cell コードを生成
154
+ #
155
+ #
156
+ def gen_through_cell_code(file)
157
+ gen_plugin_decl_code(file)
158
+ file.print <<EOT
159
+ import( <#{@rpc_channel_celltype_file_name}> );
160
+ EOT
161
+
162
+ case @start_region.get_domain_root.get_domain_type.get_kind
163
+ when :kernel
164
+ tacp_str = "\"TACP_KERNEL"
165
+ when :user
166
+ tacp_str = "\"TACP(#{@start_region.get_domain_root.get_name})"
167
+ when :OutOfDomain
168
+ tacp_str = "\"TACP_SHARED"
169
+ end
170
+ # p "end_region=#{@end_region.get_name} kind=#{@end_region.get_domain_root.get_domain_type.get_kind}"
171
+ case @end_region.get_domain_root.get_domain_type.get_kind
172
+ when :kernel
173
+ tacp_str += "|TACP_KERNEL\""
174
+ when :user
175
+ tacp_str += "|TACP(#{@end_region.get_domain_root.get_name})\""
176
+ when :OutOfDomain
177
+ tacp_str += "|TACP_SHARED\""
178
+ end
179
+ nest_str = ""
180
+ file.print <<EOT
181
+ #{nest_str} // MessageBuffer client=>server
182
+ #{nest_str} cell tMessageBuffer #{@clientChannelCell}Body0{
183
+ #{nest_str} maxMessageSize = 64; /* This value must be same as MessageBufferCEP's buffer size */
184
+ #{nest_str} bufferSize = 128;
185
+ #{nest_str} accessPattern1 = C_EXP( #{tacp_str} );
186
+ #{nest_str} accessPattern2 = C_EXP( #{tacp_str} );
187
+ #{nest_str} accessPattern3 = C_EXP( #{tacp_str} );
188
+ #{nest_str} accessPattern4 = C_EXP( #{tacp_str} );
189
+ #{nest_str} };
190
+ EOT
191
+ file.print <<EOT
192
+
193
+ #{nest_str} // MessageBuffer server=>client
194
+ #{nest_str} cell tMessageBuffer #{@clientChannelCell}Body1{
195
+ #{nest_str} maxMessageSize = 64; /* This value must be same as MessageBufferCEP's buffer size */
196
+ #{nest_str} bufferSize = 128;
197
+ #{nest_str} accessPattern1 = C_EXP( #{tacp_str} );
198
+ #{nest_str} accessPattern2 = C_EXP( #{tacp_str} );
199
+ #{nest_str} accessPattern3 = C_EXP( #{tacp_str} );
200
+ #{nest_str} accessPattern4 = C_EXP( #{tacp_str} );
201
+ #{nest_str} };
202
+ EOT
203
+
204
+ ##### クライアント側のセルの生成 #####
205
+ nest = @start_region.gen_region_str_pre file
206
+ nest_str = " " * nest
207
+
208
+ # セマフォの生成
209
+ if @b_noClientSemaphore == false
210
+ file.print <<EOT
211
+ #{nest_str} // Semaphore for Multi-task use ("specify noClientSemaphore" option to delete this)
212
+ #{nest_str} cell #{@semaphoreCelltype} #{@serverChannelCell}_Semaphore{
213
+ #{nest_str} initialCount = 1;
214
+ #{nest_str} };
215
+ EOT
216
+ end
217
+
218
+ # クライアント側チャンネル (tMessageBufferCEP)の生成
219
+ # チャンネルは必ずリージョン下にあるので、 '::' でつなぐ (でなければ、ルートリージョンにないかチェックが必要)
220
+
221
+ file.print <<EOT
222
+ #{nest_str} // Client Side Channel
223
+ #{nest_str} cell tMessageBufferCEP #{@clientChannelCell}_CEP{
224
+ #{nest_str} cMessageBuffer0 = #{@clientChannelCell}Body0.eMessageBuffer;
225
+ #{nest_str} cMessageBuffer1 = #{@clientChannelCell}Body1.eMessageBuffer;
226
+ #{nest_str} };
227
+
228
+ #{nest_str} // Client Side TDR
229
+ #{nest_str} cell tTDR #{@clientChannelCell}_TDR{
230
+ #{nest_str} cChannel = #{@clientChannelCell}_CEP.eChannel;
231
+ #{nest_str} };
232
+
233
+ #{nest_str} // Marshaler
234
+ EOT
235
+
236
+ # セマフォの結合文
237
+ if @b_noClientSemaphore == false
238
+ semaphore = "#{nest_str} cLockChannel = #{@serverChannelCell}_Semaphore.eSemaphore;\n"
239
+ else
240
+ semaphore = ""
241
+ end
242
+
243
+ ### クライアント側チャンネル (マーシャラ+TDR)の生成 ###
244
+ cell = @next_cell
245
+ # アロケータの指定があるか?
246
+ if cell.get_allocator_list.length > 0
247
+
248
+ file.print nest_str
249
+ file.print "[allocator("
250
+
251
+ delim = ""
252
+ cell.get_allocator_list.each do |type, eport, subsc, func, buf, alloc|
253
+
254
+ alloc_str = alloc.to_s
255
+ subst = @substituteAllocator[alloc_str.to_sym]
256
+ if subst
257
+ alloc_str = subst[2] + "." + subst[3]
258
+ end
259
+
260
+ file.print delim
261
+ delim = ",\n" # 最終行には出さない
262
+
263
+ if subsc # 配列添数
264
+ subsc_str = '[#{subsc}]'
265
+ else
266
+ subsc_str = ""
267
+ end
268
+
269
+ eport = "eThroughEntry" # RPCの受け口名に変更
270
+ file.print nest_str
271
+ file.print "#{eport}#{subsc_str}.#{func}.#{buf} = #{alloc_str}"
272
+ end
273
+
274
+ file.puts ")]"
275
+ end
276
+
277
+ if @clientErrorHandler
278
+ clientErrorHandler_str = "#{nest_str} cErrorHandler = #{@clientErrorHandler};\n"
279
+ else
280
+ clientErrorHandler_str = ""
281
+ end
282
+
283
+ file.print <<EOT
284
+ #{nest_str} cell tOpaqueMarshaler_#{@signature.get_global_name}_through #{@cell_name} {
285
+ #{nest_str} cTDR = #{@clientChannelCell}_TDR.eTDR;
286
+ #{clientErrorHandler_str}#{semaphore}#{nest_str} };
287
+ EOT
288
+ ### END: クライアント側チャンネル (マーシャラ+TDR)の生成 ###
289
+ @start_region.gen_region_str_post file
290
+ file.print "\n\n"
291
+
292
+ ##### サーバー側のセルの生成 #####
293
+ nest = @end_region.gen_region_str_pre file
294
+ nest_str = " " * nest
295
+
296
+ if @serverErrorHandler
297
+ serverErrorHandler_str = "#{nest_str} cErrorHandler = #{@serverErrorHandler};\n"
298
+ else
299
+ serverErrorHandler_str = ""
300
+ end
301
+
302
+ if @b_genOpener
303
+ opener = "#{nest_str} cOpener = #{@serverChannelCell}.eOpener;\n"
304
+ else
305
+ opener = ""
306
+ end
307
+
308
+ # サーバー側チャンネル (tMessageBufferCEP)
309
+ if @PPAllocatorSize
310
+ alloc_cell = <<EOT
311
+
312
+ #{nest_str} cell tPPAllocator #{@serverChannelCell}_PPAllocator {
313
+ #{nest_str} heapSize = #{@PPAllocatorSize};
314
+ #{nest_str} };
315
+ EOT
316
+ alloc_call_port_join = "#{nest_str} cPPAllocator = #{@serverChannelCell}_PPAllocator.ePPAllocator;\n"
317
+ else
318
+ alloc_cell = ""
319
+ alloc_call_port_join = ""
320
+ end
321
+
322
+ file.print <<EOT
323
+ #{nest_str} // Server Side Channel
324
+ #{nest_str} cell tMessageBufferCEP #{@serverChannelCell}_CEP{
325
+ #{nest_str} cMessageBuffer0 = #{@clientChannelCell}Body1.eMessageBuffer;
326
+ #{nest_str} cMessageBuffer1 = #{@clientChannelCell}Body0.eMessageBuffer;
327
+ #{nest_str} };
328
+ EOT
329
+
330
+ # サーバー側TDR
331
+ file.print <<EOT
332
+
333
+ #{nest_str} // Server Side TDR
334
+ #{nest_str} cell tTDR #{@serverChannelCell}_TDR{
335
+ #{nest_str} cChannel = #{@serverChannelCell}_CEP.eChannel;
336
+ #{nest_str} };
337
+ EOT
338
+
339
+ if @next_cell_port_subscript
340
+ subscript = "[" + @next_cell_port_subscript.to_s + "]"
341
+ else
342
+ subscript = ""
343
+ end
344
+
345
+ # サーバー側チャンネル (アンマーシャラ)
346
+ file.print <<EOT
347
+ #{alloc_cell}
348
+ #{nest_str} // Unmarshaler
349
+ #{nest_str} cell tOpaqueUnmarshaler_#{@signature.get_global_name} #{@serverChannelCell}_Unmarshaler {
350
+ #{nest_str} cTDR = #{@serverChannelCell}_TDR.eTDR;
351
+ #{nest_str} cServerCall = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
352
+ #{alloc_call_port_join}#{serverErrorHandler_str}#{nest_str} };
353
+ EOT
354
+
355
+ # サーバー側タスクメイン
356
+ file.print <<EOT
357
+
358
+ #{nest_str} // Unmarshaler Task Main
359
+ #{nest_str} cell #{@taskMainCelltype} #{@serverChannelCell}_TaskMain {
360
+ #{nest_str} cMain = #{@serverChannelCell}_Unmarshaler.eService;
361
+ #{opener}#{nest_str} };
362
+ EOT
363
+
364
+ # サーバー側タスク
365
+ file.print <<EOT
366
+
367
+ #{nest_str} // Unmarshaler Task
368
+ #{nest_str} cell #{@taskCelltype} #{@serverChannelCell}_Task {
369
+ #{nest_str} cTaskBody = #{@serverChannelCell}_TaskMain.eMain;
370
+ #{nest_str} priority = #{@taskPriority};
371
+ #{nest_str} stackSize = #{@stackSize};
372
+ #{nest_str} attribute = C_EXP( "TA_ACT" ); /* mikan : marshaler task starts at beginning */
373
+ #{nest_str} };
374
+ EOT
375
+ @end_region.gen_region_str_post file
376
+ end
377
+
378
+ #=== プラグイン引数 noClientSemaphore のチェック
379
+ def set_noClientSemaphore(rhs)
380
+ rhs = rhs.to_sym
381
+ if rhs == :true
382
+ @b_noClientSemaphore = true
383
+ elsif rhs == :false
384
+ @b_noClientSemaphore = false
385
+ else
386
+ cdl_error("RPCPlugin: specify true or false for noClientSemaphore")
387
+ end
388
+ end
389
+
390
+ #=== プラグイン引数 semaphoreCelltype のチェック
391
+ def set_semaphoreCelltype(rhs)
392
+ @semaphoreCelltype = rhs.to_sym
393
+ nsp = NamespacePath.analyze(@semaphoreCelltype.to_s)
394
+ obj = Namespace.find(nsp)
395
+ if !obj.instance_of?(Celltype) && !obj.instance_of?(CompositeCelltype)
396
+ cdl_error("RPCPlugin: semaphoreCelltype '#{rhs}' not celltype or not defined")
397
+ end
398
+ end
399
+
400
+ #=== NamespacePath を得る
401
+ # 生成するセルの namespace path を生成する
402
+ def get_cell_namespace_path
403
+ # nsp = @region.get_namespace.get_namespace_path
404
+ nsp = @start_region.get_namespace_path
405
+ return nsp.append(@cell_name)
406
+ end
407
+ end
@@ -0,0 +1,859 @@
1
+ #
2
+ # TECS Generator
3
+ # Generator for TOPPERS Embedded Component System
4
+ #
5
+ # Copyright (C) 2008-2018 by TOPPERS Project
6
+ #--
7
+ # 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
8
+ # ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
9
+ # 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
10
+ # (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
11
+ # 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
12
+ # スコード中に含まれていること.
13
+ # (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
14
+ # 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
15
+ # 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
16
+ # の無保証規定を掲載すること.
17
+ # (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
18
+ # 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
19
+ # と.
20
+ # (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
21
+ # 作権表示,この利用条件および下記の無保証規定を掲載すること.
22
+ # (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
23
+ # 報告すること.
24
+ # (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
25
+ # 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
26
+ # また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
27
+ # 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
28
+ # 免責すること.
29
+ #
30
+ # 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
31
+ # よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
32
+ # に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
33
+ # アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
34
+ # の責任を負わない.
35
+ #
36
+ # $Id: HRPSVCPlugin.rb 3017 2018-08-15 11:35:42Z okuma-top $
37
+ #++
38
+
39
+ # mikan through plugin: namespace が考慮されていない
40
+ # これを利用する場合、以下のように toppers_jsp.cdl sChannel.cdl を指定する必要がある
41
+ # tecsgen toppers_jsp.cdl sChannel.cdl your_description.cdl
42
+
43
+ # 以下を仮定(制限事項)
44
+ # 呼び元、呼び先のエンディアン、char, short, int_t, long_t, intptr_t のサイズが同じ
45
+ # 有符号、無符号でサイズが同じ
46
+
47
+ class SVCManage
48
+ #
49
+ # @@id: TECSのプラグインで生成した拡張サービスコールに割り当てるid
50
+ # 実際の拡張サービスコールIDは,TFN_TECSGEN_ORIGINで下駄を
51
+ # 履かせた値となる
52
+ # TFN_TECSGEN_ORIGINは,hrp3/include/extsvc_fncode.h で定義
53
+ # される
54
+ # @@func_ids: 拡張サービスコールの関数名と拡張サービスコールIDを
55
+ #    対応づけるハッシュ
56
+ #
57
+ @@id = 0
58
+ @@func_ids = {}
59
+ def initialize
60
+ #
61
+ # 本クラスはインスタンスを持たない仮想的なクラスである
62
+ #
63
+ raise "class #{self.class.name} shall not have instances"
64
+ end
65
+
66
+ def self.get_func_id(func_name)
67
+ return @@func_ids[func_name]
68
+ end
69
+
70
+ def self.set_func_id(func_name)
71
+ @@func_ids[func_name] = self.assign_id
72
+ # puts @@func_ids[ func_name ]
73
+ end
74
+
75
+ def self.get_id
76
+ return @@id
77
+ end
78
+
79
+ def self.set_id(id)
80
+ @@id = id
81
+ end
82
+
83
+ def self.assign_id
84
+ assignedId = @@id
85
+ @@id += 1
86
+ return assignedId
87
+ end
88
+ end
89
+
90
+ #
91
+ # 拡張サービスコールを用いたドメイン間通信の
92
+ # throughプラグイン
93
+ # HRPドメインプラグインによって挿入される
94
+ # 前提条件: 呼出し先がカーネルオブジェクトかどうかの判定はHRPドメインプラグイン
95
+ #      で実施されるため,ここでは判定しないこととした
96
+ #
97
+ class HRPSVCPlugin < ThroughPlugin
98
+ NUM_SVC_ARG_MAX = 5 # HRP3 の拡張サービスコールで扱うことのできる引数の最大個数
99
+
100
+ #=== RPCPlugin の initialize
101
+ # 説明は ThroughPlugin (plugin.rb) を参照
102
+ @@generated_celltype_header = {}
103
+
104
+ def initialize(cell_name, plugin_arg, next_cell, next_cell_port_name, next_cell_port_subscript, signature, celltype, caller_cell)
105
+ super
106
+
107
+ # 受け口配列の場合、配列添数ごとに別のセルタイプとする
108
+ # セルタイプをシングルトン化したいため。
109
+ # さもないと、セルを識別する引数を渡す必要があり、NUM_SVC_ARG_MAX(5) つしか渡せない引数の一つを消費することになるため。
110
+ if @next_cell_port_subscript
111
+ subscript = "__" + @next_cell_port_subscript.to_s
112
+ else
113
+ subscript = ""
114
+ end
115
+ @ct_name_body = "#{@ct_name}SVCBody_#{@next_cell.get_name}_#{@next_cell_port_name}#{subscript}".to_sym
116
+ @ct_name = "#{@ct_name}SVCCaller_#{@next_cell.get_name}_#{@next_cell_port_name}#{subscript}".to_sym
117
+ @cell_name_body = "#{@cell_name}SVCBody".to_sym
118
+ @cell_name = "#{@cell_name}SVCCaller".to_sym
119
+ # puts "%%%% "
120
+ # p @next_cell.get_name
121
+ # p @caller_cell.get_name
122
+ @b_printed_include_stdint = false
123
+ check_signature signature
124
+ end
125
+
126
+ #=== NamespacePath を得る
127
+ # 生成するセルの namespace path を生成する
128
+ def get_cell_namespace_path
129
+ # nsp = @region.get_namespace.get_namespace_path
130
+ nsp = @start_region.get_namespace_path
131
+ return nsp.append(@cell_name)
132
+ end
133
+
134
+ def gen_plugin_decl_code(file)
135
+ # このセルタイプ(同じシグニチャ)は既に生成されているか?
136
+ if @@generated_celltype[@ct_name_body].nil?
137
+ @@generated_celltype[@ct_name_body] = [self]
138
+ file2 = CFile.open("#{$gen}/#{@ct_name_body}.cdl", "w")
139
+ file2.print <<EOT
140
+ import_C( "t_stdlib.h" );
141
+
142
+ /* HRPSVC0001 */
143
+ [active,singleton]
144
+ celltype #{@ct_name_body} {
145
+ call #{@signature.get_name} #{@call_port_name};
146
+ FACTORY {
147
+ write("$ct$_tecsgen.h", "#include \\"kernel_cfg.h\\"");
148
+ };
149
+ };
150
+ EOT
151
+ file2.close
152
+ else
153
+ @@generated_celltype[@ct_name_body] << self
154
+ end
155
+ file.print "import( \"#{$gen}/#{@ct_name_body}.cdl\" );\n"
156
+
157
+ # このセルタイプ(同じシグニチャ)は既に生成されているか?
158
+ if @@generated_celltype[@ct_name].nil?
159
+ @@generated_celltype[@ct_name] = [self]
160
+ file2 = CFile.open("#{$gen}/#{@ct_name}.cdl", "w")
161
+ file2.print <<EOT
162
+ /* HRPSVC0002 */
163
+ celltype #{@ct_name} {
164
+ entry #{@signature.get_name} #{@entry_port_name};
165
+ FACTORY {
166
+ write("$ct$_tecsgen.h", "#include \\"extsvc_fncode.h\\"");
167
+ };
168
+ };
169
+ EOT
170
+ file2.close
171
+ else
172
+ @@generated_celltype[@ct_name] << self
173
+ end
174
+ file.print "import( \"#{$gen}/#{@ct_name}.cdl\" );\n"
175
+
176
+ =begin
177
+ # TODO: send. receive 対応
178
+ send_receive = []
179
+ if @signature != nil then
180
+ @signature.each_param{ |fd,param|
181
+ dir =param.get_direction
182
+ case dir
183
+ when :SEND, :RECEIVE
184
+ send_receive << [ dir, fd, param ]
185
+ end
186
+ }
187
+ end
188
+ =end
189
+
190
+ =begin
191
+ composite #{@ct_name} {
192
+ entry #{@signature.get_name} #{@entry_port_name};
193
+ call #{@signature.get_name} #{@call_port_name};
194
+
195
+ cell #{@ct_name}Client #{@cell_name}Client{
196
+ };
197
+
198
+ [active]
199
+ cell #{@ct_name}Server #{@cell_name}Server{
200
+ #{@call_port_name} => composite.#{@call_port_name};
201
+ };
202
+
203
+ composite.#{@entry_port_name} => #{@cell_name}.#{@entry_port_name};
204
+ };
205
+ =end
206
+ end
207
+
208
+ #=== through cell コードを生成
209
+ #
210
+ #
211
+ def gen_through_cell_code(file)
212
+ gen_plugin_decl_code(file)
213
+
214
+ # セルを探す
215
+ # path =["::",@next_cell.get_name] # mikan namespace
216
+ # cell = Namespace.find( path )
217
+ # cell = Namespace.find( @next_cell.get_namespace_path )
218
+
219
+ ##### クライアント側のセルの生成 #####
220
+ # file.print "[domain(HRP, \"kernel\")]"
221
+ nest = @start_region.gen_region_str_pre file
222
+ nest_str = " " * nest
223
+
224
+ # クライアント側チャンネルの生成
225
+ # 拡張サービスコール呼出し
226
+ file.print <<EOT
227
+ /* HRPSVC0003 */
228
+ #{nest_str} // Client Side Channel
229
+ #{nest_str} cell #{@ct_name} #{@cell_name}{
230
+ #{nest_str} };
231
+
232
+ EOT
233
+
234
+ @start_region.gen_region_str_post file
235
+ file.print "\n\n"
236
+
237
+ ##### サーバー側のセルの生成 #####
238
+ nest = @end_region.gen_region_str_pre file
239
+ nest_str = " " * nest
240
+ if @next_cell_port_subscript
241
+ subscript = "[" + @next_cell_port_subscript.to_s + "]"
242
+ else
243
+ subscript = ""
244
+ end
245
+
246
+ # サーバー側チャンネルの生成
247
+ # 拡張サービスコール本体
248
+ file.print <<EOT
249
+
250
+ /* HRPSVC0004 */
251
+ #{nest_str} // Server Side Channel
252
+ #{nest_str} cell #{@ct_name_body} #{@cell_name_body}{
253
+ #{nest_str} #{@call_port_name} = #{@next_cell.get_namespace_path.get_path_str}.#{@next_cell_port_name}#{subscript};
254
+ #{nest_str} };
255
+ EOT
256
+
257
+ @end_region.gen_region_str_post file
258
+
259
+ file2 = AppFile.open("#{$gen}/tecsgen.cfg")
260
+ file2.print "\n/* Generated by HRPSVCPlugin */\n\n"
261
+ file2.print <<EOT
262
+ /* HRPSVC0005 */
263
+ #include "#{@ct_name_body}_factory.h"
264
+ EOT
265
+ file2.close
266
+
267
+ # callee_cell のget_restricted_regions を呼び出しておく
268
+ # restrict が参照された印をつけるため
269
+ @callee_cell.get_restricted_regions( :dummy_entry_name, :dummy_func_name )
270
+ end
271
+
272
+ #=== 受け口関数の本体(C言語)を生成する
273
+ # 通常であれば、ジェネレータは受け口関数のテンプレートを生成する
274
+ # プラグインの場合、変更する必要のないセルタイプコードを生成する
275
+ # file:: FILE 出力先ファイル
276
+ # b_singleton:: bool true if singleton
277
+ # ct_name:: Symbol
278
+ # global_ct_name:: string
279
+ # sig_name:: string
280
+ # ep_name:: string
281
+ # func_name:: string
282
+ # func_global_name:: string
283
+ # func_type:: class derived from Type
284
+ 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)
285
+ # puts "generate ep_func for #{ct_name}"
286
+
287
+ #
288
+ # 拡張サービスコール呼出し側の関数生成
289
+ #
290
+ # 完成形のイメージ
291
+ #
292
+ # ER_UINT
293
+ # eThroughEntry_write(CELLIDX idx, const char* buffer, uint_t length)
294
+ # {
295
+ # ER_UINT retval;
296
+ # tHRPSVCPlugin_<Sig>SVCCaller_<Cell>_<Entry>_CB *p_cellcb;
297
+ # if( VALID_IDX( idx ) ){
298
+ # p_cellcb = tHRPSVCPlugin_<Sig>SVCBody_<Cell>_<Entry>_GET_CELLCB(idx);
299
+ # }else{
300
+ # /* エラー処理コードをここに記述 */
301
+ # }
302
+ #
303
+ # retval = (ER_UINT)cal_svc( TFN_TECSGEN_ORIGIN + svcid,
304
+ # (intptr_t)par1, (intptr_t)par2, 0, 0, 0 );
305
+ #
306
+ # return retval;
307
+ # }
308
+
309
+ if !func_type.get_type.is_a?(VoidType)
310
+ file.print(" #{func_type.get_type_str} retval;\n")
311
+ end
312
+
313
+ # p "celltype_name, sig_name, func_name, func_global_name"
314
+ # p "#{ct_name}, #{sig_name}, #{func_name}, #{func_global_name}"
315
+
316
+ delim = ""
317
+ if !func_type.get_type.is_a?(VoidType)
318
+ file.print(" retval = (#{func_type.get_type_str})")
319
+ else
320
+ file.print(" ")
321
+ end
322
+
323
+ # file.print( "#{@call_port_name}_#{func_name}(" )
324
+ SVCManage.set_func_id("#{@ct_name_body}_#{func_name}")
325
+ svcid = SVCManage.get_func_id("#{@ct_name_body}_#{func_name}")
326
+ # file.print( "cal_svc( #{@ct_name_body}_#{func_name}" )
327
+ file.print("cal_svc( TFN_TECSGEN_ORIGIN + #{svcid}")
328
+
329
+ # if ( ! b_singleton ) then
330
+ # file.print( " tecs_this" )
331
+ # delim = ","
332
+ # end
333
+
334
+ i = 0
335
+ passed_param = {}
336
+ params.each{|param|
337
+ delim = ","
338
+ file.printf("#{delim} (intptr_t)#{param.get_name}")
339
+ passed_param[i] = param.get_name
340
+ i += 1
341
+ }
342
+
343
+ while i < NUM_SVC_ARG_MAX do
344
+ delim = ","
345
+ file.printf("#{delim} 0")
346
+ passed_param[i] = "par#{i + 1}"
347
+ i += 1
348
+ end
349
+
350
+ file.print(" );\n\n")
351
+
352
+ if !func_type.get_type.is_a?(VoidType)
353
+ file.print(" return retval;\n")
354
+ end
355
+
356
+ #
357
+ # 拡張サービスコール本体側の関数生成
358
+ #
359
+ # 完成形のイメージ
360
+ #
361
+ # ER_UINT
362
+ # eThroughEntry_write(CELLIDX idx, const char* buffer, uint_t length)
363
+ # {
364
+ # ER_UINT retval;
365
+ # tHRPSVCPlugin_<Sig>SVCBody_<Cell>_<Entry>_CB *p_cellcb;
366
+ # if( VALID_IDX( idx ) ){
367
+ # p_cellcb = tHRPSVCPlugin_<Sig>SVCBody_<Cell>_<Entry>_GET_CELLCB(idx);
368
+ # }else{
369
+ # /* エラー処理コードをここに記述 */
370
+ # }
371
+ #
372
+ # retval = (ER_UINT)cal_svc( TFN_TECSGEN_ORIGIN + svcid,
373
+ # (intptr_t)par1, (intptr_t)par2, 0, 0, 0 );
374
+ #
375
+ # return retval;
376
+ # }
377
+ file2 = AppFile.open("#{$gen}/#{@ct_name_body}.c")
378
+ if @b_printed_include_stdint == false
379
+ file2.print <<EOT
380
+ #ifndef SIZE_MAX
381
+ #define SIZE_MAX (~0UL)
382
+ #endif
383
+
384
+ EOT
385
+ @b_printed_include_stdint = true
386
+ end
387
+
388
+ if func_type.get_type.is_a?(VoidType)
389
+ retval_assign = ""
390
+ else
391
+ retval_assign = "retval = (ER_UINT)"
392
+ end
393
+
394
+ file2.print <<EOT
395
+ /* HRPSVC0006 */
396
+ ER_UINT
397
+ #{@ct_name_body}_#{func_name}(intptr_t #{passed_param[0]}, intptr_t #{passed_param[1]}, intptr_t #{passed_param[2]}, intptr_t #{passed_param[3]}, intptr_t #{passed_param[4]}, ID cdmid)
398
+ {
399
+ ER_UINT retval = E_OK;
400
+
401
+ EOT
402
+
403
+ #
404
+ # エラーチェック処理の生成
405
+ #
406
+
407
+ #
408
+ # 呼出し元ドメインのチェック
409
+ # * private method: gen_caller_check_code参照
410
+ #
411
+ generated_check_code = gen_caller_check_code(func_name)
412
+ check_code = generated_check_code["check_code"]
413
+ user_cannot_callable = generated_check_code["user_cannot_callable"]
414
+
415
+ #
416
+ # パラメータにポインタが存在する場合,呼出し元タスクに対する
417
+ # アクセス権のチェック処理を出力する
418
+ # ※ cdmidがカーネルドメイン(拡張サービスコール呼出し中のユーザ
419
+ # ドメインを含む)であればprb_memの処理をスキップし,初段の
420
+ # 拡張サービスコールのみprb_memを呼出し元タスクに発行する
421
+ #
422
+ num = 0
423
+ params.each{|param|
424
+ if param.get_declarator.get_ptr_level > 0
425
+ align_check_str = "!ALIGN_TYPE(#{passed_param[num]}, #{param.get_type.get_referto.get_type_str}) || "
426
+
427
+ if param.get_type.get_referto.is_a?(IntType)
428
+ case param.get_type.get_referto.get_bit_size
429
+ when -11, -1, 8 # char, char_t, int8_t (無符号含む)
430
+ #
431
+ # charデータの場合,ALIGN_TYPEは必ずTRUE
432
+ # となるので,エラーチェックを省略
433
+ # char型の@bit_sizeは-11
434
+ # tecsgen/tecslib/core/types.rbを参照
435
+ #
436
+ align_check_str = ""
437
+ end
438
+ end
439
+ if param.get_direction == :IN
440
+ #
441
+ # 入力([in])のポインタパラメータは,呼出し元タスクに
442
+ # TPM_READ(読出し可能)のアクセス権が必要
443
+ #
444
+ # 二重ポインタが不可のため、size_is と string が同時に設定されることはない
445
+ prb_func = "prb_mem"
446
+ if param.get_size
447
+ size_str = param.get_size.to_s
448
+ elsif param.get_string == -1
449
+ size_str = "SIZE_MAX"
450
+ prb_func = "prb_str"
451
+ elsif param.get_string
452
+ size_str = param.get_string.to_s
453
+ prb_func = "prb_str"
454
+ else
455
+ size_str = "1"
456
+ end
457
+ check_code.concat <<EOT
458
+ /* HRPSVC0007 */
459
+ if (#{align_check_str}#{prb_func}((void *)#{passed_param[num]}, sizeof(#{param.get_type.get_referto.get_type_str}) * (#{size_str}), TSK_SELF, TPM_READ) != E_OK) {
460
+ return E_MACV;
461
+ }
462
+ EOT
463
+
464
+ elsif param.get_direction == :OUT || param.get_direction == :INOUT
465
+ #
466
+ # 出力([out])のポインタパラメータは,呼出し元タスクに
467
+ # TPM_WRITE(書込み可能)のアクセス権が必要
468
+ #
469
+ prb_func = "prb_mem"
470
+ if param.get_size
471
+ size_str = param.get_size.to_s
472
+ elsif param.get_string # 引数なしの string はない
473
+ size_str = param.get_string.to_s
474
+ # prb_func = "prb_str" # out, inout の場合、必ず領域を確保する. prb_mem を用いる
475
+ else
476
+ size_str = "1"
477
+ end
478
+ check_code.concat <<EOT
479
+ /* HRPSVC0008 */
480
+ if (#{align_check_str}#{prb_func}((void *)#{passed_param[num]}, sizeof(#{param.get_type.get_referto.get_type_str}) * (#{size_str}), TSK_SELF, TPM_WRITE) != E_OK) {
481
+ return E_MACV;
482
+ }
483
+ EOT
484
+
485
+ end
486
+ end
487
+ num += 1
488
+ }
489
+
490
+ #
491
+ # 呼出し元がカーネルドメインのみ許可されている場合,
492
+ # すべてのユーザドメインからの呼出しに対し,E_OACVを返す
493
+ #
494
+ if user_cannot_callable
495
+ check_code = "\t\treturn E_OACV;"
496
+ end
497
+
498
+ if check_code != ""
499
+ #
500
+ # 呼出し元がカーネルドメインの場合,アクセス権のチェック
501
+ # 処理をスキップさせる
502
+ #
503
+ file2.print <<eot
504
+ if (cdmid != TDOM_KERNEL) {
505
+ #{check_code}
506
+ }
507
+ eot
508
+ end
509
+
510
+ #
511
+ # 拡張サービスコール本体(本来の受け口関数)を呼び出す
512
+ #
513
+ file2.print" #{retval_assign}#{@call_port_name}_#{func_name}("
514
+
515
+ delim = ""
516
+ num = 0
517
+ params.each{|param|
518
+ file2.print delim.to_s
519
+ delim = ", "
520
+ file2.print "(#{param.get_type.get_type_str})"
521
+ file2.print passed_param[num]
522
+ file2.print param.get_type.get_type_str_post
523
+ num += 1
524
+ }
525
+
526
+ file2.print ");\n"
527
+
528
+ file2.print "\n return retval;\n"
529
+ file2.print "}\n\n"
530
+
531
+ file2.close
532
+
533
+ #
534
+ # 拡張サービスコールの登録
535
+ #
536
+ file2 = AppFile.open("#{$gen}/tecsgen.cfg")
537
+ file2.print "\n/* Generated by HRPSVCPlugin */\n\n"
538
+ file2.print <<EOT
539
+ /* HRPSVC0009 */
540
+ KERNEL_DOMAIN{
541
+ DEF_SVC( TFN_TECSGEN_ORIGIN + #{svcid}, { TA_NULL, #{@ct_name_body}_#{func_name}, SSZ_#{func_global_name} } );
542
+ }
543
+ EOT
544
+ file2.close
545
+
546
+ #
547
+ # 拡張サービスコール登録に必要な情報をヘッダに出力
548
+ # - 拡張サービスコール呼出し時のチェックで使用するスタックサイズを出力
549
+ # - 拡張サービスコールとして登録する関数名のextern宣言を出力
550
+ #
551
+ file2 = AppFile.open("#{$gen}/#{@ct_name_body}_factory.h")
552
+ file2.print "\n/* Generated by HRPSVCPlugin */\n\n"
553
+ file2.print <<EOT
554
+ /* HRPSVC0010 */
555
+ #ifndef SSZ_#{func_global_name}
556
+ #define SSZ_#{func_global_name} DefaultExtsvcStackSize
557
+ #endif /* SSZ_#{func_global_name} */
558
+
559
+ /* HRPSVC0011 */
560
+ extern ER_UINT #{@ct_name_body}_#{func_name}(intptr_t par1, intptr_t par2, intptr_t par3, intptr_t par4, intptr_t par5, ID cdmid);
561
+ EOT
562
+ file2.close
563
+ end
564
+
565
+ def get_callee_cell
566
+ return @callee_cell
567
+ end
568
+
569
+ def get_caller_cell
570
+ return @caller_cell
571
+ end
572
+
573
+ def get_callee_ep_name
574
+ return @join.get_port_name
575
+ end
576
+
577
+ private
578
+ #
579
+ # 拡張サービスコール本体における,呼出し元チェックのコードを
580
+ # 出力する
581
+ # gen_ep_func_body からのみ呼び出される
582
+ # 引数: 対象の関数名
583
+ # 返り値: 下記のハッシュ
584
+ # {"check_code"=>出力するエラーチェックコード,
585
+ # "user_cannot_callable"=>ユーザドメインが呼出し不可能かどうかのフラグ}
586
+ #
587
+ def gen_caller_check_code(func_name)
588
+ dbgPrint "gen_caller_check_code(func_name): #{@callee_cell.get_name}\n"
589
+ #
590
+ # エラーチェック処理
591
+ #
592
+ check_code = ""
593
+ user_cannot_callable = false
594
+ all_domain_callable = false
595
+ caller_unrestricted = false
596
+
597
+ #
598
+ # 呼出し元ドメインのチェック処理
599
+ # callable_domains: 拡張サービスコールを呼出し可能なドメインのリスト
600
+ # - 無所属のセルから結合されている場合,すべてのセルに対して,
601
+ #  callable?をチェックし,呼出し可能なすべてのドメインを返す
602
+ # - 無所属以外のセルから結合されている場合,そのセルに対して
603
+ # callable?をチェックし,呼出し可能であれば,そのドメインを返す
604
+ #
605
+ callable_domains = []
606
+ @@generated_celltype[@ct_name_body].each {|svcplugin|
607
+ if svcplugin.get_caller_cell.get_region.get_domain_root.get_domain_type.get_option == "OutOfDomain"
608
+ # 無所属かつ active な場合も、restrict に従う
609
+ # if svcplugin.get_caller_cell.get_celltype.is_active?
610
+ # #
611
+ # # 無所属かつactiveなセルは、TECSから存在が認識されていないのを
612
+ # # 含む任意のドメインから呼び出される可能性も存在する
613
+ # #
614
+ # caller_unrestricted = true
615
+ # else
616
+ # #
617
+ # # 無所属から接続されている場合は,すべてのセルの
618
+ # # restrictをチェック
619
+ # #
620
+ # Cell.get_cell_list2.each { |cell|
621
+ # if cell.callable?(svcplugin.get_callee_cell, svcplugin.get_callee_ep_name, func_name)
622
+ # callable_domains << cell.get_region.get_domain_root
623
+ # end
624
+ # }
625
+ # print "callable_domains: "
626
+ # callable_domains.each{ |dm| print dm.get_name, " " }
627
+ # print "\n"
628
+ # end
629
+
630
+ # restrict 指定がある場合には、それに従う。さもなければ、チェックしない
631
+ callable_domains = @callee_cell.get_restricted_regions( get_callee_ep_name, func_name )
632
+ if callable_domains.nil?
633
+ caller_unrestricted = true
634
+ end
635
+ # print "restrict_list: "
636
+ # delim = ""
637
+ # callable_domains.each{ |domain|
638
+ # print delim, domain
639
+ # delim = ", "
640
+ # }
641
+ # print "\n"
642
+ elsif svcplugin.get_caller_cell.callable?(svcplugin.get_callee_cell, svcplugin.get_callee_ep_name, func_name)
643
+ #
644
+ # 特定のドメインから接続されている場合は,呼出し元セルの
645
+ # restrictをチェック
646
+ #
647
+ callable_domains << svcplugin.get_caller_cell.get_region.get_domain_root
648
+ else
649
+ #
650
+ # 無所属から結合されておらず,特定の呼出し元ドメインにアクセス権
651
+ # がない場合,callable_domainsは空となる
652
+ #
653
+ # pp "#{svcplugin.get_caller_cell.get_name} cannot call #{svcplugin.get_callee_cell.get_name}_#{svcplugin.get_callee_ep_name}_#{func_name}"
654
+ end
655
+ }
656
+
657
+ if caller_unrestricted
658
+ # pp "caller_unrestricted: #{@ct_name_body}"
659
+ return {"check_code" => "", "user_cannot_callable" => false}
660
+ end
661
+
662
+ #
663
+ # 重複を削除
664
+ #
665
+ callable_domains.uniq!
666
+ #
667
+ # 無所属に対するドメインチェックは実施しない
668
+ # カーネルドメインに対するドメインチェックは実施しない
669
+ #
670
+ callable_domains = callable_domains.select {|domain|
671
+ ((domain.get_domain_type.get_option != "OutOfDomain") && \
672
+ (domain.get_domain_type.get_option != "kernel"))
673
+ }
674
+ # pp "callable_domains"
675
+ # pp callable_domains.map{|domain| domain.get_name }
676
+ #
677
+ # すべてのユーザドメインから呼出し可能な場合,ドメインチェックは
678
+ # 実施しない
679
+ #
680
+ all_domain_regions = DomainType.get_domain_regions[:HRP].select {|reg|
681
+ ((reg.get_domain_type.get_option != "OutOfDomain") && \
682
+ (reg.get_domain_type.get_option != "kernel"))
683
+
684
+ }
685
+ # pp "all domains"
686
+ # pp all_domain_regions.map {|reg| reg.get_name}
687
+ if all_domain_regions.all? {|reg| callable_domains.include?(reg) }
688
+ all_domain_callable = true
689
+ end
690
+
691
+ #
692
+ # 呼出し元ドメインのチェック処理本体の生成
693
+ #
694
+ if callable_domains.length == 0
695
+ dbgPrint "callable_domain.length = 0\n"
696
+ #
697
+ # ユーザドメインから呼出し不可能な場合は
698
+ # 個別のエラーチェックはせず,問答無用でE_OACVを返す
699
+ #
700
+ user_cannot_callable = true
701
+ elsif callable_domains.length == 1
702
+ dbgPrint "callable_domain.length = 1\n"
703
+ #
704
+ # 呼出し可能なユーザドメインが単一の場合は
705
+ # cdmid != <domain名> の形式でチェックする
706
+ #
707
+ check_code += "\t/* HRPSVC0012.1 */\n"
708
+ check_code += "\tif (cdmid != #{callable_domains[0].get_name}) {\n"
709
+ elsif callable_domains.length > 1 && !all_domain_callable
710
+ dbgPrint "callable_domain.length > 1 && not all_domains \n"
711
+ #
712
+ # 呼出し可能なユーザドメインが複数の場合は
713
+ # TACP(cdmid) & (TACP(<domain名>) | ...) != 0U
714
+ # の形式でチェックする
715
+ #
716
+ check_code += "\t/* HRPSVC0012.2 */\n"
717
+ check_code += "\tif (TACP(cdmid) & ("
718
+ check_code += (callable_domains.map {|domain| "TACP(#{domain.get_name})" }).join("|")
719
+ check_code += ") != 0U) {\n"
720
+ else
721
+ dbgPrint "callable_all_domains\n"
722
+ end
723
+ if check_code != ""
724
+ #
725
+ # 呼出し可能なユーザドメインのチェックがある場合は
726
+ # エラーコードを返すためのコードを出力する
727
+ #
728
+ check_code += <<EOS
729
+ /* HRPSVC0013 */
730
+ return E_OACV;
731
+ }
732
+ EOS
733
+ end
734
+
735
+ return {"check_code" => check_code, "user_cannot_callable" => user_cannot_callable}
736
+ end
737
+
738
+ #---------------------------------------------------------#
739
+ #=== シグニチャのチェック
740
+ def check_signature(signature)
741
+ signature.get_function_head_array.each{|fh|
742
+ type = fh.get_return_type
743
+ check_return_type signature, fh, type
744
+ if fh.get_paramlist.get_items.length > NUM_SVC_ARG_MAX
745
+ cdl_error("HSV0005 $1.$2: # of parameter more than #{NUM_SVC_ARG_MAX}", signature.get_name, fh.get_name)
746
+ end
747
+ fh.get_paramlist.get_items.each{|param|
748
+ check_param signature, fh, param
749
+ }
750
+ }
751
+ end
752
+
753
+ #=== 戻り値の型のチェック
754
+ # ER, ER_UINT は推奨される型
755
+ # 整数、ブール、void は可能、他は不可
756
+ def check_return_type(signature, fh, type)
757
+ ot = type.get_original_type
758
+ if type.get_type_str == "ER" || type.get_type_str == "ER_UINT"
759
+ # OK!
760
+ elsif ot.is_a?(IntType) || ot.is_a?(VoidType) || ot.is_a?(BoolType)
761
+ cdl_warning("HSW0001 $1.$2: $3 return type cannot get access violation error", signature.get_name, fh.get_name, type.get_type_str.downcase)
762
+ check_intptr "#{signature.get_name}.#{fh.get_name} return type", type
763
+ else
764
+ cdl_error("HSV0001 $1.$2 return type $3 cannot be used", signature.get_name, fh.get_name, type.get_type_str.to_s + type.get_type_str_post.to_s)
765
+ end
766
+ end
767
+
768
+ #=== 引数の型のチェック
769
+ def check_param(signature, fh, param)
770
+ type = param.get_type
771
+ ot = type.get_original_type
772
+ dir = param.get_direction
773
+ case dir
774
+ when :IN
775
+ if ot.is_a?(IntType) || ot.is_a?(BoolType)
776
+ # OK!
777
+ check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}", type
778
+ elsif ot.is_a? PtrType
779
+ check_ptr signature, fh, param, dir
780
+ else
781
+ cdl_error("HSV0002 $1.$2.$3 $4 param type cannot be used", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s + type.get_type_str_post.to_s)
782
+ end
783
+ when :OUT, :INOUT
784
+ if ot.is_a? PtrType
785
+ check_ptr signature, fh, param, dir
786
+ else
787
+ # error
788
+ end
789
+ when :SEND, :RECEIVE
790
+ cdl_error("HSV0008 $1.$2.$3 param direction '$4' cannot be used", signature.get_name, fh.get_name, param.get_name, param.get_direction.to_s.downcase)
791
+ end
792
+ end
793
+
794
+ def check_ptr(signature, fh, param, dir)
795
+ type = param.get_type.get_referto
796
+ ot = type.get_original_type
797
+ if ot.is_a?(IntType) || ot.is_a?(BoolType) || ot.is_a?(FloatType)
798
+ # OK!
799
+ check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}", type
800
+ elsif ot.is_a? PtrType
801
+ cdl_error("HSV0003 $1.$2.$3 multi-pointer type cannot be used", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s + type.get_type_str_post.to_s)
802
+ elsif ot.is_a? StructType
803
+ check_struct signature, fh, param
804
+ else
805
+ cdl_error("HSV0004 $1.$2.$3 $4 type cannot be used", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s + type.get_type_str_post.to_s)
806
+ end
807
+ if (dir == :OUT || dir == :INOUT) && param.get_string == -1
808
+ cdl_error("HSV0009 $1.$2.$3 string argment is necessary for out/inout parameter", signature.get_name, fh.get_name, param.get_name)
809
+ end
810
+ end
811
+
812
+ def check_struct(signature, fh, param)
813
+ type = param.get_type.get_referto
814
+ ot = type.get_original_type
815
+ ot.get_members_decl.get_items.each{|decl|
816
+ type = decl.get_type
817
+ ot = type.get_original_type
818
+ if ot.is_a?(IntType) || ot.is_a?(BoolType) || ot.is_a?(FloatType)
819
+ # OK!
820
+ check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}.#{decl.get_name} member", type
821
+ else
822
+ dbgPrint "struct member #{decl.get_name} #{type} #{decl.get_type} #{decl.get_type.get_original_type}\n"
823
+ if decl.get_type.get_original_type.is_a? ArrayType
824
+ dbgPrint "member array type #{decl.get_type.get_original_type.get_type} #{decl.get_type.get_original_type.get_type.get_original_type}\n"
825
+ check_struct_member_array signature, fh, param, decl
826
+ else
827
+ cdl_error("HSV0006 $1.$2.$3 $4 type cannot be used as struct member", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s + type.get_type_str_post.to_s)
828
+ end
829
+ end
830
+ }
831
+ end
832
+
833
+ def check_struct_member_array(signature, fh, param, member_decl)
834
+ # p "check_struct_member_array: #{member_decl.get_type.get_type_str}"
835
+ type = member_decl.get_type.get_type
836
+ ot = type.get_original_type
837
+ if ot.is_a?(IntType) || ot.is_a?(BoolType) || ot.is_a?(FloatType)
838
+ # OK!
839
+ check_intptr "#{signature.get_name}.#{fh.get_name}.#{param.get_name}.#{member_decl.get_name} member", type
840
+ else
841
+ cdl_error("HSV0007 $1.$2.$3 $4 type cannot be used as struct member", signature.get_name, fh.get_name, param.get_name, type.get_type_str.to_s + type.get_type_str_post)
842
+ end
843
+ end
844
+
845
+ def check_intptr(msg, type)
846
+ dbgPrint "check_intptr IN\n"
847
+ t = type
848
+ while t.is_a? DefinedType
849
+ dbgPrint "check_intptr #{msg} #{t.get_type_str} #{t.get_original_type.get_type_str}\n"
850
+ tstr = t.get_type_str
851
+ tstr.sub!(/const /, "")
852
+ tstr.sub!(/volatile /, "")
853
+ if tstr == "intptr_t" || tstr == "uintptr_t"
854
+ cdl_info("HSI0001 $1 type '$2' not checked by plugin", msg, type.get_type_str)
855
+ end
856
+ t = t.get_type
857
+ end
858
+ end
859
+ end