source: EcnlProtoTool/trunk/asp3_dcre/cfg/pass2.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: 14.2 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,2016 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 # パス1の生成物の読み込み(メインの処理)
62 #
63 def self.Read
64 # cfg1_out.symsの読み込み
65 @symbolAddress = ReadSymbolFile(CFG1_OUT_SYMS)
66
67 # cfg1_out.srecの読み込み
68 begin
69 @cfg1SRec = SRecord.new(CFG1_OUT_SREC)
70 rescue Errno::ENOENT, Errno::EACCES => ex
71 abort(ex.message)
72 end
73
74 # マジックナンバーの取得
75 if @symbolAddress.has_key?(CFG1_MAGIC_NUM)
76 $asmLabel = ""
77 $cfg1_prefix = CFG1_PREFIX
78 elsif @symbolAddress.has_key?("_" + CFG1_MAGIC_NUM)
79 $asmLabel = "_"
80 $cfg1_prefix = "_" + CFG1_PREFIX
81 else
82 error_exit("`#{CFG1_MAGIC_NUM}' is not found in `#{CFG1_OUT_SYMS}'")
83 end
84
85 magicNumberData = @cfg1SRec.get_data(@symbolAddress \
86 [$asmLabel + CFG1_MAGIC_NUM], 4)
87 if (magicNumberData == "12345678")
88 $endianLittle = false
89 elsif (magicNumberData == "78563412")
90 $endianLittle = true
91 else
92 error_exit("`#{CFG1_MAGIC_NUM}' is invalid in `#{CFG1_OUT_SREC}'")
93 end
94
95 # 固定出力した変数の取得
96 $sizeOfSigned = GetSymbolValue($asmLabel + CFG1_SIZEOF_SIGNED, 4, false)
97
98 # 値取得シンボルの取得
99 $symbolValueTable.each do |symbolName, symbolData|
100 symbol = $cfg1_prefix + symbolName
101 if symbolData.has_key?(:BOOL)
102 value = GetSymbolValue(symbol, $sizeOfSigned, true)
103 if !value.nil?
104 # C言語の真偽値をRubyの真偽値に変換して取り込む
105 symbolData[:VALUE] = (value != 0)
106 end
107 else
108 value = GetSymbolValue(symbol, $sizeOfSigned, \
109 symbolData.has_key?(:SIGNED))
110 if !value.nil?
111 symbolData[:VALUE] = value
112 end
113 end
114 end
115
116 #
117 # ハッシュの初期化
118 #
119 $cfgData = {}
120 @objidValues = {}
121 $apiDefinition.each do |apiName, apiDef|
122 if apiDef.has_key?(:API)
123 if !$cfgData.has_key?(apiDef[:API].to_sym)
124 $cfgData[apiDef[:API].to_sym] = {}
125 end
126 end
127 apiDef[:PARAM].each do |apiParam|
128 if apiParam.has_key?(:NAME) && apiParam.has_key?(:ID_DEF)
129 @objidValues[apiParam[:NAME]] = {}
130 end
131 end
132 end
133
134 #
135 # ドメイン生成データをコンフィギュレーションデータ($cfgData)に格納
136 #
137 $cfgData[:CRE_DOM] = {}
138 $domainId.each do |domainName, domainVal|
139 domid = NumStr.new(domainVal, domainName)
140 $cfgData[:CRE_DOM][domainVal] = { :domid => domid }
141 end
142
143 ReadPhase(nil)
144 end
145
146 #
147 # パラメータの値を取り出す
148 #
149 def self.GetParamValue(paramName, param, apiIndex, index, apiParam, cfgInfo)
150 if apiParam.has_key?(:ID_DEF) # オブジェクト識別名(定義)
151 value = @objidValues[paramName][param]
152 elsif apiParam.has_key?(:ID_REF) # オブジェクト識別名(参照)
153 if @objidValues[paramName].has_key?(param)
154 value = @objidValues[paramName][param]
155 else
156 error("#{apiDef.has_key?(:KEYPAR) ? "E_NOEXS" : "E_ID"}: " \
157 "`#{param}' in #{cfgInfo[:APINAME]} is not defined", \
158 "#{cfgInfo[:_FILE_]}:#{cfgInfo[:_LINE_]}:")
159 value = nil
160 end
161 elsif apiParam.has_key?(:EXPTYPE) # 整数定数式パラメータ
162 if apiIndex.nil?
163 if param.is_a?(NumStr)
164 return(param)
165 else
166 return(NumStr.new(param))
167 end
168 else
169 symbol = "#{$cfg1_prefix}valueof_#{paramName}_#{apiIndex}#{index}"
170 value = GetSymbolValue(symbol, $sizeOfSigned, \
171 apiParam.has_key?(:SIGNED))
172 end
173 else # 一般定数式/文字列パラメータ
174 return(param)
175 end
176 return(NumStr.new(value, param))
177 end
178
179 #
180 # 指定したフェーズのためのパス1の生成物の読み込み
181 #
182 def self.ReadPhase(phase)
183 #
184 # オブジェクトIDの割当て
185 #
186 # 割り当てたオブジェクトIDは,@objidValuesに保持する.@objidValuesは,
187 # 2重のハッシュ(ハッシュのハッシュ)である.
188 #
189 # 具体的には,@objidValuesは,オブジェクトIDのパラメータ名(例えば,セ
190 # マフォIDであれば"semid".これを保持する変数名は,objidParamNameとす
191 # る)をキーとし,そのオブジェクトIDの割当て表(これを保持する変数名
192 # は,objidListとする)を値とするハッシュである.オブジェクトIDの割当
193 # て表は,オブジェクト名(これを保持する変数名は,objNameとする)をキー
194 # とし,そのID番号(これを保持する変数名は,objidNumberとする)を値と
195 # するハッシュである.
196 #
197 # 例えば,セマフォSEM1のID番号が1の場合には,次のように設定される.
198 # @objidValues["semid"]["SEM1"] == 1
199 #
200
201 # ID番号割り当ての前処理
202 objidParamNameList = []
203 $cfgFileInfo.each do |cfgInfo|
204 # プリプロセッサディレクティブは読み飛ばす
205 next if cfgInfo.has_key?(:DIRECTIVE)
206
207 apiDef = $apiDefinition[cfgInfo[:APINAME]]
208 # 異なるフェーズの静的APIは読み飛ばす
209 next if apiDef[:PHASE] != phase
210
211 apiIndex = cfgInfo[:INDEX]
212 if !apiIndex.nil?
213 # シンボルファイルに静的APIのインデックスが存在しなければ読み飛
214 # ばす(ifdef等で消えた静的API)
215 symbol = "#{$cfg1_prefix}static_api_#{apiIndex}"
216 next unless @symbolAddress.has_key?(symbol)
217 end
218
219 apiDef[:PARAM].each do |apiParam|
220 if apiParam.has_key?(:NAME) && apiParam.has_key?(:ID_DEF)
221 objidParamName = apiParam[:NAME]
222 objName = cfgInfo[objidParamName]
223 if $inputObjid.has_key?(objName)
224 # ID番号入力ファイルに定義されていた場合
225 @objidValues[objidParamName][objName] = $inputObjid[objName]
226 else
227 @objidValues[objidParamName][objName] = nil
228 end
229 objidParamNameList.push(objidParamName)
230 end
231 end
232 end
233
234 # ID番号の割当て処理
235 objidParamNameList.each do |objidParamName|
236 objidList = @objidValues[objidParamName]
237
238 # 未使用のID番号のリスト(使用したものから消していく)
239 unusedObjidList = (1.upto(objidList.keys.size)).to_a
240
241 # 割り当て済みのID番号の処理
242 objidList.each do |objName, objidNumber|
243 if $inputObjid.has_key?(objName)
244 objidIndex = unusedObjidList.index($inputObjid[objName])
245 if objidIndex.nil?
246 # ID番号入力ファイルで指定された値が不正
247 error_exit("value of `#{objName}' in ID input file is illegal")
248 else
249 # 未使用のID番号のリストから削除
250 unusedObjidList.delete_at(objidIndex)
251 end
252 end
253 end
254
255 # ID番号の割当て
256 objidList.each do |objName, objidNumber|
257 if objidList[objName].nil?
258 # 以下で,@objidValuesを書き換えている
259 objidList[objName] = unusedObjidList.shift
260 end
261 end
262 end
263
264 #
265 # 静的APIデータをコンフィギュレーションデータ($cfgData)に格納
266 #
267 $cfgFileInfo.each do |cfgInfo|
268 # プリプロセッサディレクティブは読み飛ばす
269 next if cfgInfo.has_key?(:DIRECTIVE)
270
271 apiDef = $apiDefinition[cfgInfo[:APINAME]]
272 # 異なるフェーズの静的APIは読み飛ばす
273 next if apiDef[:PHASE] != phase
274
275 apiSym = apiDef[:API].to_sym
276 apiIndex = cfgInfo[:INDEX]
277 if !apiIndex.nil?
278 # シンボルファイルに静的APIのインデックスが存在しなければ読み飛
279 # ばす(ifdef等で消えた静的API)
280 symbol = "#{$cfg1_prefix}static_api_#{apiIndex}"
281 next unless @symbolAddress.has_key?(symbol)
282 end
283
284 # パラメータの値をハッシュ形式に格納
285 params = {}
286 apiDef[:PARAM].each do |apiParam|
287 next unless apiParam.has_key?(:NAME)
288 paramName = apiParam[:NAME]
289 next unless cfgInfo.has_key?(paramName) # パラメータがない場合
290 paramData = cfgInfo[paramName]
291
292 if apiParam.has_key?(:LIST)
293 params[paramName.to_sym] = []
294 paramData.each.with_index(1) do |param, index|
295 params[paramName.to_sym].push(GetParamValue(paramName, param, \
296 apiIndex, "_#{index}", apiParam, cfgInfo))
297 end
298 else
299 params[paramName.to_sym] = GetParamValue(paramName, paramData, \
300 apiIndex, "", apiParam, cfgInfo)
301 end
302 end
303
304 # ドメインIDを追加
305 if cfgInfo.has_key?(:DOMAIN)
306 domainName = cfgInfo[:DOMAIN]
307 params[:domain] = $domainId[domainName]
308 end
309
310 # クラスIDを追加
311 if cfgInfo.has_key?(:CLASS)
312 if apiIndex.nil?
313 params[:class] = cfgInfo[:CLASS]
314 else
315 symbol = "#{$cfg1_prefix}valueof_CLASS_#{apiIndex}"
316 value = GetSymbolValue(symbol, $sizeOfSigned, true)
317 params[:class] = NumStr.new(value, cfgInfo[:CLASS])
318 end
319 end
320
321 # API名,ファイル名,行番号を追加
322 params[:apiname] = cfgInfo[:APINAME]
323 params[:_file_] = cfgInfo[:_FILE_]
324 params[:_line_] = cfgInfo[:_LINE_]
325
326 # 登録キーを決定する
327 if apiDef.has_key?(:KEYPAR)
328 keyParam = params[apiDef[:KEYPAR].to_sym]
329 key = keyParam.val
330 if $cfgData[apiSym].has_key?(key)
331 # 登録キーの重複
332 error("E_OBJ: #{apiDef[:KEYPAR]} `#{keyParam}' " \
333 "is duplicated in #{cfgInfo[:APINAME]}",
334 "#{cfgInfo[:_FILE_]}:#{cfgInfo[:_LINE_]}:")
335 end
336 else
337 key = $cfgData[apiSym].count + 1
338 end
339 $cfgData[apiSym][key] = params
340 end
341 end
342
343 #
344 # ID番号出力ファイルの生成
345 #
346 def self.OutputId(fileName)
347 idOutputFile = GenFile.new(fileName)
348 @objidValues.each do |objidParamName, objidList|
349 objidList.each do |objName, objidNumber|
350 idOutputFile.add("#{objName} #{objidNumber}")
351 end
352 end
353 end
354end
355
356#
357# パス2の処理
358#
359def Pass2
360 #
361 # パス1から引き渡される情報をファイルから読み込む
362 #
363 db = PStore.new(CFG1_OUT_DB)
364 db.transaction(true) do
365 $apiDefinition = db[:apiDefinition]
366 $symbolValueTable = db[:symbolValueTable]
367 $cfgFileInfo = db[:cfgFileInfo]
368 $includeFiles = db[:includeFiles]
369 $domainId = db[:domainId]
370 end
371 $cfg2Data = {}
372
373 #
374 # パス1の生成物を読み込む
375 #
376 Cfg1Out.Read()
377 abort if $errorFlag # エラー発生時はabortする
378
379 #
380 # 値取得シンボルをグローバル変数として定義する
381 #
382 DefineSymbolValue()
383
384 #
385 # 生成スクリプト(trbファイル)を実行する
386 #
387 $trbFileNames.each do |trbFileName|
388 if /^(.+):(\w+)$/ =~ trbFileName
389 trbFileName = $1
390 Cfg1Out.ReadPhase($2.to_sym)
391 end
392 IncludeTrb(trbFileName)
393 end
394
395 #
396 # ID番号出力ファイルの生成
397 #
398 if !$idOutputFileName.nil?
399 Cfg1Out.OutputId($idOutputFileName)
400 end
401
402 #
403 # パス3に引き渡す情報をファイルに生成
404 #
405 if $omitOutputDb.nil?
406 db = PStore.new(CFG2_OUT_DB)
407 db.transaction do
408 db[:apiDefinition] = $apiDefinition
409 db[:symbolValueTable] = $symbolValueTable
410 db[:cfgFileInfo] = $cfgFileInfo
411 db[:includeFiles] = $includeFiles
412 db[:cfgData] = $cfgData
413 db[:asmLabel] = $asmLabel
414 db[:endianLittle] = $endianLittle
415 db[:cfg2Data] = $cfg2Data
416 end
417 end
418end
Note: See TracBrowser for help on using the repository browser.