source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/tecsgen/tecslib/core/plugin.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: 12.3 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#== Plugin クラス
41# ThroughPlugin, SignaturePlugin, CelltypePlugin に include する
42class Plugin < Node
43#@error_backlog:: [msg1, msg2, ... ] @locale が設定される前に発生したエラー
44
45 PluginArgProc = {
46 "silent" => Proc.new { |obj,rhs| obj.set_silent rhs },
47 }
48
49 def initialize
50 super
51 @b_silent = false
52 @locale = nil # set_locale が呼び出されるまで nil となる
53 @error_backlog = []
54 end
55
56 #=== Plugin#cdl_error
57 # set_locale が呼び出されるまで @error_backlog に保存し保留する
58 def cdl_error *arg
59 if @locale then
60 Generator.error2( @locale, *arg )
61 else
62 @error_backlog << arg
63 end
64 end
65
66 #=== locale を設定する
67 # Node は initialize で locale を設定するが、plugin は parse とは
68 # 異なるタイミング new されるため、locale を再設定する
69 # このメソッドを2度呼び出すと @error_backlog のエラーが2度出力されてしまう
70 def set_locale locale
71 @locale = locale
72 @error_backlog.each { |arg|
73 Generator.error2( locale, *arg )
74 }
75 end
76
77### 構文解釈 または 意味解析段階で呼び出されるメソッド ###
78# generate 指定子の場合、構文解釈次第(end_of_parseで)呼び出される
79# generate 文の場合、出現次第呼び出される
80 ### 意味解析段階で呼び出されるメソッド ### <<< コメント誤り (V1.4.2)
81 #=== CDL ファイルの生成
82 # typedef, signature, celltype, cell のコードを生成
83 # 重複して生成してはならない
84 # すでに生成されている場合は出力しないこと。
85 # もしくは同名の import により、重複を避けること。
86 #file:: FILE 生成するファイル
87 def gen_cdl_file file
88 end
89
90
91### コード生段階で呼び出されるメソッド ###
92 #=== プラグインは gen_ep_func を提供するか
93 # gen_ep_func 定義 ⇒ テンプレートではない、セルタイプコード(tCelltype.c)を生成
94 # gen_ep_func 未定義 ⇒ テンプレート(tCelltype_templ.c)を生成
95 def gen_ep_func?
96 self.class.method_defined?( :gen_ep_func_body )
97 end
98
99 #=== 受け口関数の本体(C言語)を生成する
100 # プラグインの場合、変更する必要のないセルタイプコードを生成する
101 # このメソッドが未定義であれば、プラグインはセルタイプコードを生成しない (通常通りテンプレートを生成する)
102 # gen_cdl_file の中で生成されたセルタイプに対して呼び出される
103 #file:: FILE 出力先ファイル (tCelltype.c)
104 #b_singleton:: bool true if singleton
105 #ct_name:: Symbol
106 #global_ct_name:: string
107 #sig_name:: string
108 #ep_name:: string
109 #func_name:: string
110 #func_global_name:: string
111 #func_type:: class derived from Type
112# 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 )
113# end
114
115 #=== 受け口関数の preamble (C言語)を生成する
116 # 必要なら preamble 部に出力する
117 # gen_cdl_file の中でで生成されたセルタイプに対して呼び出される
118 #file:: FILE 出力先ファイル
119 #b_singleton:: bool true if singleton
120 #ct_name:: Symbol
121 #global_ct_name:: string
122 def gen_preamble( file, b_singleton, ct_name, global_ct_name )
123 # デフォルトでは何も出力しない
124 end
125
126 #=== 受け口関数の postamble (C言語)を生成する
127 # 必要なら postamble 部に出力する
128 # gen_cdl_file の中で生成されたセルタイプに対して呼び出される
129 #file:: FILE 出力先ファイル
130 #b_singleton:: bool true if singleton
131 #ct_name:: Symbol
132 #global_ct_name:: string
133 def gen_postamble( file, b_singleton, ct_name, global_ct_name )
134 # デフォルトでは何も出力しない
135 end
136
137 #=== gen_cdl_file の中で生成されたセルタイプに新しいセルが生成された
138 # どのセルタイプかは cell.get_celltype で分かる
139 #
140 #file:: FILE 出力先ファイル
141 #b_singleton:: bool true if singleton
142 #ct_name:: Symbol
143 #global_ct_name:: string
144 def new_cell cell
145 # デフォルトでは何もしない
146 end
147
148### プラグイン引数の解釈 ###
149 def parse_plugin_arg
150 arg = @plugin_arg_str.dup
151
152 # 改行を消す
153 arg.gsub!( /\\\n/, "" )
154
155 while arg != ""
156
157 # 前の空白読み飛ばす
158 arg.sub!( /\A\s*(?:\\\n)*\s*(.*)/, '\1')
159
160 # 識別子取得
161 if arg =~ /\A[a-zA-Z_]\w*/ then
162 ident = $~
163 arg = $'
164 else
165 cdl_error( "P1001 plugin arg: cannot find identifier in $1" , arg )
166 return
167 end
168
169 # 前の空白読み飛ばす
170 arg.sub!( /\A\s*(?:\\\n)*\s*(.*)/, '\1')
171
172 if arg =~ /=/ then
173 arg = $'
174 else
175 cdl_error( "P1002 plugin arg: expecting \'=\' not \'$1\'" , arg )
176 return
177 end
178
179 # 前の空白読み飛ばす
180 arg.sub!( /\A\s*(?:\\\n)*\s*(.*)/, '\1')
181
182 # 右辺文字列
183 if arg =~ /\A\\"(.*?)\\"\s*,/ then # \" \" で囲まれている場合
184 rhs = $1
185 remain = $'
186 elsif arg =~ /\A%(.*?)%\s*,/ then # % % で囲まれている場合
187 rhs = $1
188 remain = $'
189 elsif arg =~ /\A!(.*?)!\s*,/ then # $ $ で囲まれている場合
190 rhs = $1
191 remain = $'
192 elsif arg =~ /\A'(.*?)'\s*,/ then # $ $ で囲まれている場合
193 rhs = $1
194 remain = $'
195 elsif arg =~ /\A\\"(.*?)\\"\s*,/ then # || にも [,$] にもできなかった
196 rhs = $1
197 remain = $'
198 # elsif arg =~ /\A(.*?)\s*$/ then
199 elsif arg =~ /\A\\"(.*?)\\"\s*\z/ then # \" \" で囲まれている場合
200 rhs = $1
201 remain = $'
202 elsif arg =~ /\A%(.*?)%\s*\z/ then # % % で囲まれている場合
203 rhs = $1
204 remain = $'
205 elsif arg =~ /\A!(.*?)!\s*\z/ then # $ $ で囲まれている場合
206 rhs = $1
207 remain = $'
208 elsif arg =~ /\A'(.*?)'\s*\z/ then # $ $ で囲まれている場合
209 rhs = $1
210 remain = $'
211 elsif arg =~ /\A\\"(.*?)\\"\s*\z/ then # || にも [,$] にもできなかった
212 rhs = $1
213 remain = $'
214 elsif arg =~ /\A(.*?),/ then
215 rhs = $1
216 remain = $'
217 # 前の空白読み飛ばす
218 rhs.sub!( /\A\s*(.*)\s*\z/, '\1')
219 elsif arg =~ /\A(.*?)\s*\z/ then
220 rhs = $1
221 remain = $'
222 else
223 cdl_error( "P1003 plugin arg: unexpected $1" , arg )
224 return
225 end
226
227 # 0文字の文字列を to_sym すると例外発生するので空白文字とする
228 if rhs == "" then
229 rhs = " "
230 end
231
232 arg = remain # arg の残りの部分
233 arg.sub!( /\A\s*(?:\\\n)*\s*(.*)/, '\1') # 前の空白読み飛ばす
234
235 # \ を外す
236 rhs = rhs.gsub( /\\(.)/, "\\1" ) # ここで $' が変わることに注意!
237 # print "parse_plugin_arg: #{ident} #{rhs}\n"
238 @plugin_arg_list[ ident ] = rhs
239
240 check_plugin_arg( ident, rhs )
241 end
242 # @plugin_arg_list.each{|i,r| print "ident: #{i} rhs: #{r}\n" }
243 end
244
245 #=== プラグイン引数をチェックする
246 # @plugin_arg_check_proc_tab に従ってプラグイン引数をチェックすする
247 # 古い用法:子クラスでオーバーライドし、引数識別子が正しいかチェックする
248 #ident:: string: 引数識別子
249 #rhs:: string: 右辺文字列
250 def check_plugin_arg( ident, rhs )
251
252 dbgPrint "check_plugin_arg: #{ident} #{rhs.to_str}\n"
253 proc = nil
254 if @plugin_arg_check_proc_tab then
255 proc = @plugin_arg_check_proc_tab[ident.to_s]
256 end
257 if proc == nil then
258 proc = PluginArgProc[ ident.to_s ]
259 end
260 if proc.instance_of? Proc then
261 dbgPrint "calling: #{self.class.name}.#{proc.to_s}\n"
262 proc.call( self, rhs )
263 else
264 params = ""
265 delim = ""
266 @plugin_arg_check_proc_tab.each{ |j,p|
267 params = "#{params}#{delim}#{j}"
268 delim = ", "
269 }
270 cdl_error( "P1004 $1: unknown plugin argument\'s identifier\n $2 are acceptible for RPCPlugin." , ident, params )
271 end
272 end
273
274 #=== プラグインのメッセージ出力
275 def print_msg( msg )
276 if @b_silent == true then
277 return
278 end
279 print msg
280 end
281
282 #=== プラグイン引数 silent
283 def set_silent rhs
284 if rhs == "true" || rhs == nil then
285 @b_silent = true
286 end
287 end
288end
289
290#== 出力文字列を utf-8 から出力ファイルに convert する
291# tecsgen のソースコードは utf-8 で記述されている
292# これを、出力ファイルの文字コードに変換して出力する
293#
294# generate.rb で出力するものは message.rb で変換している
295# generate.rb で出力するものは APPFile クラスを使用している
296# mikan: CFile で出力したものに factory で追記できない (cdl ファイルの場合、追記できても意味がない)
297class CFile
298 def self.open( path, mode )
299 CFile.new( path, mode )
300 end
301
302 def initialize( path, mode )
303 if $b_no_kcode then
304 mode += ":" + $Ruby19_File_Encode
305 end
306 @file = File.open( path, mode )
307 end
308
309 def print str
310 if $b_no_kcode && $KCONV_CONSOLE == Kconv::BINARY then
311 @file.print( str )
312 else
313 @file.print( str.kconv( $KCONV_CDL, $KCONV_TECSGEN ) )
314 end
315 end
316
317 def puts str
318 if $b_no_kcode && $KCONV_CONSOLE == Kconv::BINARY then
319 @file.print( str )
320 else
321 @file.print( str.kconv( $KCONV_CDL, $KCONV_TECSGEN ) )
322 end
323 @file.print( "\n" )
324 end
325
326 def printf( format, *arg )
327 if $b_no_kcode && $KCONV_CONSOLE == Kconv::BINARY then
328 @file.print( sprintf( format, *arg ) )
329 else
330 @file.print( sprintf( format, *arg ).kconv( $KCONV_CDL, $KCONV_TECSGEN ) )
331 end
332 end
333
334 def close
335 @file.close
336 end
337end
Note: See TracBrowser for help on using the repository browser.