source: EcnlProtoTool/trunk/asp3_dcre/tecsgen/tecslib/core/plugin.rb@ 321

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

文字コードを設定

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