source: EcnlProtoTool/trunk/asp3_dcre/cfg/pass2.rb

Last change on this file was 439, checked in by coas-nagasima, 4 years ago

mrubyを2.1.1に更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 16.1 KB
Line 
1# -*- coding: utf-8 -*-
2#
3# TOPPERS Configurator by Ruby
4#
5# Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
6# Copyright (C) 2015-2018 by Embedded and Real-Time Systems Laboratory
7# Graduate School of Information Science, Nagoya Univ., JAPAN
8#
9# 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
10# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
11# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
12# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
13# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
14# スコード中に含まれていること.
15# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
16# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
17# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
18# の無保証規定を掲載すること.
19# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
20# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
21# と.
22# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
23# 作権表示,この利用条件および下記の無保証規定を掲載すること.
24# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
25# 報告すること.
26# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
27# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
28# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
29# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
30# 免責すること.
31#
32# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
34# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
35# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
36# の責任を負わない.
37#
38# $Id$
39#
40
41#
42# パス2の処理
43#
44
45#
46# パス1の生成物の読み込み
47#
48module Cfg1Out
49 #
50 # Sレコードファイルからシンボルの値を取り出す
51 #
52 def self.GetSymbolValue(symbol, size, signed)
53 if @symbolAddress.has_key?(symbol)
54 return(@cfg1SRec.get_value(@symbolAddress[symbol], size, signed))
55 else
56 return(nil)
57 end
58 end
59
60 #
61 # Sレコードファイルからシンボルの文字列を取り出す
62 #
63 def self.GetSymbolString(symbol)
64 if @symbolAddress.has_key?(symbol) \
65 && !(address = @cfg1SRec.get_value(@symbolAddress[symbol], \
66 $sizeOfCharPtr, false)).nil?
67 return(@cfg1SRec.get_string(address))
68 else
69 return(nil)
70 end
71 end
72
73 #
74 # パス1の生成物の読み込み(メインの処理)
75 #
76 def self.Read
77 # cfg1_out.symsの読み込み
78 @symbolAddress = ReadSymbolFile(CFG1_OUT_SYMS)
79
80 # cfg1_out.srecの読み込み
81 begin
82 @cfg1SRec = SRecord.new(CFG1_OUT_SREC)
83 rescue Errno::ENOENT, Errno::EACCES => ex
84 abort(ex.message)
85 end
86
87 # マジックナンバーの取得とエンディアンの設定
88 if @symbolAddress.has_key?(CFG1_MAGIC_NUM)
89 $asmLabel = ""
90 $cfg1_prefix = CFG1_PREFIX
91 elsif @symbolAddress.has_key?("_" + CFG1_MAGIC_NUM)
92 $asmLabel = "_"
93 $cfg1_prefix = "_" + CFG1_PREFIX
94 else
95 error_exit("`#{CFG1_MAGIC_NUM}' is not found in `#{CFG1_OUT_SYMS}'")
96 end
97
98 magicNumberData = @cfg1SRec.get_data(@symbolAddress \
99 [$asmLabel + CFG1_MAGIC_NUM], 4)
100 if (magicNumberData == "12345678")
101 $endianLittle = false
102 elsif (magicNumberData == "78563412")
103 $endianLittle = true
104 else
105 error_exit("`#{CFG1_MAGIC_NUM}' is invalid in `#{CFG1_OUT_SREC}'")
106 end
107
108 # 固定出力した変数の取得
109 $sizeOfSigned = GetSymbolValue($asmLabel + CFG1_SIZEOF_SIGNED, 4, false)
110 $sizeOfIntptr = GetSymbolValue($asmLabel + CFG1_SIZEOF_INTPTR, 4, false)
111 $sizeOfCharPtr = GetSymbolValue($asmLabel + CFG1_SIZEOF_CHARPTR, 4, false)
112
113 # 値取得シンボルの取得
114 $symbolValueTable.each do |symbolName, symbolData|
115 symbol = $cfg1_prefix + symbolName
116 if symbolData.has_key?(:BOOL)
117 value = GetSymbolValue(symbol, $sizeOfSigned, true)
118 if !value.nil?
119 # C言語の真偽値をRubyの真偽値に変換して取り込む
120 symbolData[:VALUE] = (value != 0)
121 end
122 else
123 if symbolData.has_key?(:INTPTR)
124 value = GetSymbolValue(symbol, $sizeOfIntptr, \
125 symbolData.has_key?(:SIGNED))
126 else
127 value = GetSymbolValue(symbol, $sizeOfSigned, \
128 symbolData.has_key?(:SIGNED))
129 end
130 if !value.nil?
131 symbolData[:VALUE] = value
132 end
133 end
134 end
135
136 # SILによるエンディアン定義のチェック
137 if $symbolValueTable["SIL_ENDIAN_BIG"].has_key?(:VALUE)
138 if $symbolValueTable["SIL_ENDIAN_LITTLE"].has_key?(:VALUE)
139 error_exit("Both SIL_ENDIAN_BIG and SIL_ENDIAN_LITTLE are defined.")
140 else
141 if $endianLittle
142 error_exit("Definition of SIL_ENDIAN_BIG seems to be wrong.")
143 end
144 end
145 else
146 if $symbolValueTable["SIL_ENDIAN_LITTLE"].has_key?(:VALUE)
147 if !$endianLittle
148 error_exit("Definition of SIL_ENDIAN_LITTLE seems to be wrong.")
149 end
150 else
151 # 両方が未定義の場合のエラーチェックは,sil.hで実施する
152 end
153 end
154
155 #
156 # ハッシュの初期化
157 #
158 $cfgData = {}
159 @objidValues = {}
160 $apiDefinition.each do |apiName, apiDef|
161 if apiDef.has_key?(:API)
162 if !$cfgData.has_key?(apiDef[:API].to_sym)
163 $cfgData[apiDef[:API].to_sym] = {}
164 end
165 end
166 apiDef[:PARAM].each do |apiParam|
167 if apiParam.has_key?(:NAME) && apiParam.has_key?(:ID_DEF)
168 @objidValues[apiParam[:NAME]] = {}
169 end
170 end
171 end
172
173 #
174 # ドメインデータ($domData)を生成
175 #
176 if $supportDomain
177 $domData = {}
178 $domainId.each do |domainName, domainVal|
179 domid = NumStr.new(domainVal, domainName)
180 $domData[domainVal] = { :domid => domid }
181 end
182 $globalVars.push("domData")
183 end
184
185 ReadPhase(nil)
186 end
187
188 #
189 # パラメータの値を取り出す
190 #
191 # 生成スクリプト内で追加された静的APIの場合には,apiIndexがnilになる.
192 #
193 def self.GetParamValue(paramName, param, apiIndex, index, apiParam, cfgInfo)
194 if apiParam.has_key?(:ID_DEF) # オブジェクト識別名(定義)
195 value = @objidValues[paramName][param]
196 elsif apiParam.has_key?(:ID_REF) # オブジェクト識別名(参照)
197 if @objidValues[paramName].has_key?(param)
198 value = @objidValues[paramName][param]
199 else
200 apiDef = $apiDefinition[cfgInfo[:APINAME]]
201 error("#{apiDef.has_key?(:KEYPAR) ? "E_NOEXS" : "E_ID"}: " \
202 "`#{param}' in #{cfgInfo[:APINAME]} is not defined", \
203 "#{cfgInfo[:_FILE_]}:#{cfgInfo[:_LINE_]}:")
204 value = nil
205 end
206 elsif apiParam.has_key?(:STRING) # 文字列パラメータ
207 if !apiIndex.nil?
208 symbol = "#{$cfg1_prefix}valueof_#{paramName}_#{apiIndex}#{index}"
209 return(GetSymbolString(symbol))
210 else
211 return(param)
212 end
213 elsif apiParam.has_key?(:EXPTYPE) # 整数定数式パラメータ
214 if !apiIndex.nil?
215 symbol = "#{$cfg1_prefix}valueof_#{paramName}_#{apiIndex}#{index}"
216 if apiParam.has_key?(:INTPTR)
217 value = GetSymbolValue(symbol, $sizeOfIntptr, \
218 apiParam.has_key?(:SIGNED))
219 else
220 value = GetSymbolValue(symbol, $sizeOfSigned, \
221 apiParam.has_key?(:SIGNED))
222 end
223 else
224 if param.is_a?(NumStr)
225 return(param)
226 else
227 return(NumStr.new(param))
228 end
229 end
230 else # 一般定数式パラメータ
231 return(param)
232 end
233 return(NumStr.new(value, param))
234 end
235
236 #
237 # 指定したフェーズのためのパス1の生成物の読み込み
238 #
239 def self.ReadPhase(phase)
240 #
241 # オブジェクトIDの割当て
242 #
243 # 割り当てたオブジェクトIDは,@objidValuesに保持する.@objidValuesは,
244 # 2重のハッシュ(ハッシュのハッシュ)である.
245 #
246 # 具体的には,@objidValuesは,オブジェクトIDのパラメータ名(例えば,セ
247 # マフォIDであれば"semid".これを保持する変数名は,objidParamNameとす
248 # る)をキーとし,そのオブジェクトIDの割当て表(これを保持する変数名
249 # は,objidListとする)を値とするハッシュである.オブジェクトIDの割当
250 # て表は,オブジェクト名(これを保持する変数名は,objNameとする)をキー
251 # とし,そのID番号(これを保持する変数名は,objidNumberとする)を値と
252 # するハッシュである.
253 #
254 # 例えば,セマフォSEM1のID番号が1の場合には,次のように設定される.
255 # @objidValues["semid"]["SEM1"] == 1
256 #
257
258 # ID番号割り当ての前処理
259 $cfgFileInfo.each do |cfgInfo|
260 # プリプロセッサディレクティブは読み飛ばす
261 next if cfgInfo.has_key?(:DIRECTIVE)
262
263 apiDef = $apiDefinition[cfgInfo[:APINAME]]
264 # 異なるフェーズの静的APIは読み飛ばす
265 next if apiDef[:PHASE] != phase
266
267 apiIndex = cfgInfo[:INDEX]
268 if !apiIndex.nil?
269 # シンボルファイルに静的APIのインデックスが存在しなければ読み飛
270 # ばす(ifdef等で消えた静的API)
271 symbol = "#{$cfg1_prefix}static_api_#{apiIndex}"
272 next unless @symbolAddress.has_key?(symbol)
273 end
274
275 apiDef[:PARAM].each do |apiParam|
276 if apiParam.has_key?(:NAME) && apiParam.has_key?(:ID_DEF)
277 objidParamName = apiParam[:NAME]
278 objName = cfgInfo[objidParamName]
279 if $inputObjid.has_key?(objName)
280 # ID番号入力ファイルに定義されていた場合
281 @objidValues[objidParamName][objName] = $inputObjid[objName]
282 else
283 @objidValues[objidParamName][objName] = nil
284 end
285 end
286 end
287 end
288
289 # ID番号の割当て処理
290 @objidValues.each do |objidParamName, objidList|
291 # 未使用のID番号のリスト(使用したものから消していく)
292 unusedObjidList = (1.upto(objidList.keys.size)).to_a
293
294 # 割り当て済みのID番号の処理
295 objidList.each do |objName, objidNumber|
296 if $inputObjid.has_key?(objName)
297 objidIndex = unusedObjidList.index($inputObjid[objName])
298 if objidIndex.nil?
299 # ID番号入力ファイルで指定された値が不正
300 error_exit("value of `#{objName}' in ID input file is illegal")
301 else
302 # 未使用のID番号のリストから削除
303 unusedObjidList.delete_at(objidIndex)
304 end
305 end
306 end
307
308 # ID番号の割当て
309 objidList.each do |objName, objidNumber|
310 if objidList[objName].nil?
311 # 以下で,@objidValuesを書き換えている
312 objidList[objName] = unusedObjidList.shift
313 end
314 end
315 end
316
317 #
318 # 静的APIデータをコンフィギュレーションデータ($cfgData)に格納
319 #
320 $cfgFileInfo.each do |cfgInfo|
321 # プリプロセッサディレクティブは読み飛ばす
322 next if cfgInfo.has_key?(:DIRECTIVE)
323
324 apiDef = $apiDefinition[cfgInfo[:APINAME]]
325 # 異なるフェーズの静的APIは読み飛ばす
326 next if apiDef[:PHASE] != phase
327
328 apiSym = apiDef[:API].to_sym
329 apiIndex = cfgInfo[:INDEX]
330 if !apiIndex.nil?
331 # シンボルファイルに静的APIのインデックスが存在しなければ読み飛
332 # ばす(ifdef等で消えた静的API)
333 symbol = "#{$cfg1_prefix}static_api_#{apiIndex}"
334 next unless @symbolAddress.has_key?(symbol)
335 end
336
337 # パラメータの値をハッシュ形式に格納
338 params = {}
339 apiDef[:PARAM].each do |apiParam|
340 next unless apiParam.has_key?(:NAME)
341 paramName = apiParam[:NAME]
342 next unless cfgInfo.has_key?(paramName) # パラメータがない場合
343 paramData = cfgInfo[paramName]
344
345 if apiParam.has_key?(:LIST)
346 params[paramName.to_sym] = []
347 paramData.each.with_index(1) do |param, index|
348 params[paramName.to_sym].push(GetParamValue(paramName, param, \
349 apiIndex, "_#{index}", apiParam, cfgInfo))
350 end
351 else
352 params[paramName.to_sym] = GetParamValue(paramName, paramData, \
353 apiIndex, "", apiParam, cfgInfo)
354 end
355 end
356
357 # ドメインIDを追加
358 if cfgInfo.has_key?(:DOMAIN)
359 domainName = cfgInfo[:DOMAIN]
360 params[:domain] = $domainId[domainName]
361 end
362
363 # クラスIDを追加
364 if cfgInfo.has_key?(:CLASS)
365 if !apiIndex.nil?
366 symbol = "#{$cfg1_prefix}valueof_CLASS_#{apiIndex}"
367 value = GetSymbolValue(symbol, $sizeOfSigned, true)
368 params[:class] = NumStr.new(value, cfgInfo[:CLASS])
369 else
370 params[:class] = cfgInfo[:CLASS]
371 end
372 end
373
374 # API名,ファイル名,行番号を追加
375 params[:apiname] = cfgInfo[:APINAME]
376 params[:_file_] = cfgInfo[:_FILE_]
377 params[:_line_] = cfgInfo[:_LINE_]
378
379 # 登録キーを決定する
380 if apiDef.has_key?(:KEYPAR)
381 keyParam = params[apiDef[:KEYPAR].to_sym]
382 key = keyParam.val
383 if $cfgData[apiSym].has_key?(key)
384 # 登録キーの重複
385 error("E_OBJ: #{apiDef[:KEYPAR]} `#{keyParam}' " \
386 "is duplicated in #{cfgInfo[:APINAME]}",
387 "#{cfgInfo[:_FILE_]}:#{cfgInfo[:_LINE_]}:")
388 end
389 else
390 key = $cfgData[apiSym].count + 1
391 end
392 $cfgData[apiSym][key] = params
393 end
394 end
395
396 #
397 # ID番号の割当て結果の上書き
398 #
399 def self.SetObjidList(objidParamName, objidList)
400 @objidValues[objidParamName] = objidList
401 end
402
403 #
404 # ID番号出力ファイルの生成
405 #
406 def self.OutputId(fileName)
407 idOutputFile = GenFile.new(fileName)
408 @objidValues.each do |objidParamName, objidList|
409 objidList.each do |objName, objidNumber|
410 idOutputFile.add("#{objName} #{objidNumber}")
411 end
412 end
413 end
414end
415
416#
417# パス2の処理
418#
419def Pass2
420 #
421 # パス1から引き渡される情報をファイルから読み込む
422 #
423 db = PStore.new(CFG1_OUT_DB)
424 db.transaction(true) do
425 db.roots.each do |var|
426 eval("$#{var} = db[:#{var}]")
427 end
428 end
429
430 #
431 # パス3以降に引き渡す情報の定義
432 #
433 $globalVars = [ "globalVars",
434 "apiDefinition",
435 "symbolValueTable",
436 "cfgFileInfo",
437 "cfgData",
438 "asmLabel",
439 "endianLittle" ]
440
441 #
442 # パス1の生成物を読み込む
443 #
444 Cfg1Out.Read()
445 abort if $errorFlag # エラー発生時はabortする
446
447 #
448 # 値取得シンボルをグローバル変数として定義する
449 #
450 DefineSymbolValue()
451
452 #
453 # 生成スクリプト(trbファイル)を実行する
454 #
455 $trbFileNames.each do |trbFileName|
456 if /^(.+):(\w+)$/ =~ trbFileName
457 trbFileName = $1
458 Cfg1Out.ReadPhase($2.to_sym)
459 end
460 IncludeTrb(trbFileName)
461 end
462
463 #
464 # ID番号出力ファイルの生成
465 #
466 if !$idOutputFileName.nil?
467 Cfg1Out.OutputId($idOutputFileName)
468 end
469
470 #
471 # パス3に引き渡す情報をファイルに生成
472 #
473 if !$omitOutputDb
474 db = PStore.new(CFG2_OUT_DB)
475 db.transaction do
476 $globalVars.each do |var|
477 eval("db[:#{var}] = $#{var}")
478 end
479 end
480 end
481end
Note: See TracBrowser for help on using the repository browser.