source: EcnlProtoTool/trunk/asp3_dcre/cfg/cfg.rb@ 429

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

ASP3, TINET, mbed を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 18.1 KB
Line 
1#!/usr/bin/env ruby -Eutf-8 -w
2# -*- coding: utf-8 -*-
3#
4# TOPPERS Configurator by Ruby
5#
6# Copyright (C) 2015 by FUJI SOFT INCORPORATED, JAPAN
7# Copyright (C) 2015-2019 by Embedded and Real-Time Systems Laboratory
8# Graduate School of Information Science, Nagoya Univ., JAPAN
9#
10# 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
11# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12# 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
13# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15# スコード中に含まれていること.
16# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17# 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
18# 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
19# の無保証規定を掲載すること.
20# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
21# 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
22# と.
23# (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
24# 作権表示,この利用条件および下記の無保証規定を掲載すること.
25# (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
26# 報告すること.
27# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
28# 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
29# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
30# 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
31# 免責すること.
32#
33# 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
35# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
36# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
37# の責任を負わない.
38#
39# $Id: cfg.rb 175 2019-06-19 01:51:58Z ertl-hiro $
40#
41
42if $0 == __FILE__
43 TOOL_ROOT = File.expand_path(File.dirname(__FILE__)) + "/"
44 $LOAD_PATH.unshift(TOOL_ROOT)
45end
46
47require "pp"
48require "csv"
49require "optparse"
50require "pstore"
51require "GenFile.rb"
52require "SRecord.rb"
53
54#
55# 定数定義
56#
57# 共通
58VERSION = "1.5.0"
59
60# cfg1_out関係
61CFG1_PREFIX = "TOPPERS_cfg_"
62CFG1_MAGIC_NUM = "TOPPERS_magic_number"
63CFG1_SIZEOF_SIGNED = "TOPPERS_sizeof_signed_t"
64CFG1_SIZEOF_INTPTR = "TOPPERS_sizeof_intptr_t"
65CFG1_SIZEOF_CHARPTR = "TOPPERS_sizeof_char_ptr_t"
66CFG1_OUT_C = "cfg1_out.c"
67CFG1_OUT_DB = "cfg1_out.db"
68CFG1_OUT_SREC = "cfg1_out.srec"
69CFG1_OUT_SYMS = "cfg1_out.syms"
70CFG1_OUT_TIMESTAMP = "cfg1_out.timestamp"
71CFG1_OUT_TARGET_H = "target_cfg1_out.h"
72
73# cfg2_out関係
74CFG2_OUT_DB = "cfg2_out.db"
75
76# cfg3_out関係
77CFG3_OUT_DB = "cfg3_out.db"
78
79#
80# エラー発生有無フラグ
81#
82$errorFlag = false
83
84#
85# エラー/警告表示関数
86#
87# 一般的なエラー表示(処理を中断)
88def error_exit(message, location = "")
89 location += " " if location != ""
90 abort("#{location}error: #{message}")
91end
92
93# 一般的なエラー表示(処理を継続)
94def error(message, location = "")
95 location += " " if location != ""
96 STDERR.puts("#{location}error: #{message}")
97 $errorFlag = true
98end
99
100# 一般的な警告表示
101def warning(message, location = "")
102 location += " " if location != ""
103 STDERR.puts("#{location}warning: #{message}")
104end
105
106# システムコンフィギュレーションファイルの構文解析時のエラー
107$noParseError = 0
108def parse_error(cfgFile, message)
109 error(message, "#{cfgFile.getFileName}:#{cfgFile.getLineNo}:")
110 if ($noParseError += 1) >= 10
111 abort("too many errors emitted, stopping now")
112 end
113end
114
115# システムコンフィギュレーションファイルの構文解析時の警告
116def parse_warning(cfgFile, message)
117 warning(message, "#{cfgFile.getFileName}:#{cfgFile.getLineNo}:")
118end
119
120#
121# 静的API処理時のエラー/警告表示関数
122#
123# 静的API処理時のエラー/警告を短く記述できるように,メッセージ中の%ま
124# たは%%で始まる記述を以下のように展開する.
125# %label → #{params[:label]}
126# %%label → label `#{params[:label]}'
127#
128# エラー/警告メッセージの展開
129def expand_message(message, params)
130 result = message.dup
131 while /%%(\w+)\b/ =~ result
132 param = $1
133 paramVal = params[param.to_sym].to_s
134 result.sub!(/%%#{param}\b/, "#{param} `#{paramVal}'")
135 end
136 while /%(\w+)\b/ =~ result
137 param = $1
138 paramVal = params[param.to_sym].to_s
139 result.sub!(/%#{param}\b/, paramVal)
140 end
141 return(result)
142end
143
144# 静的API処理時のエラー
145def error_api(params, message)
146 error(expand_message(message, params), \
147 "#{params[:_file_]}:#{params[:_line_]}:")
148end
149
150# 静的API処理時の警告
151def warning_api(params, message)
152 warning(expand_message(message, params), \
153 "#{params[:_file_]}:#{params[:_line_]}:")
154end
155
156# 静的API処理時のエラー(エラーコード付き)
157def error_ercd(errorCode, params, message)
158 error_api(params, "#{errorCode}: #{message}")
159end
160
161# パラメータのエラー
162def error_wrong(errorCode, params, symbol, wrong)
163 error_ercd(errorCode, params, "%%#{symbol} is #{wrong} in %apiname")
164end
165
166def error_wrong_id(errorCode, params, symbol, objid, wrong)
167 error_ercd(errorCode, params, "%%#{symbol} is #{wrong} " \
168 "in %apiname of %#{objid}")
169end
170
171def error_wrong_sym(errorCode, params, symbol, symbol2, wrong)
172 error_ercd(errorCode, params, "%%#{symbol} is #{wrong} " \
173 "in %apiname of %%#{symbol2}")
174end
175
176# パラメータ不正のエラー
177def error_illegal(errorCode, params, symbol)
178 error_ercd(errorCode, params, "illegal %%#{symbol} in %apiname")
179end
180
181def error_illegal_id(errorCode, params, symbol, objid)
182 error_ercd(errorCode, params, "illegal %%#{symbol} " \
183 "in %apiname of %#{objid}")
184end
185
186def error_illegal_sym(errorCode, params, symbol, symbol2)
187 error_ercd(errorCode, params, "illegal %%#{symbol} " \
188 "in %apiname of %%#{symbol2}")
189end
190
191#
192# Stringクラスの拡張(二重引用符で囲まれた文字列の作成/展開)
193#
194class String
195 #
196 # 二重引用符で囲まれた文字列の作成
197 #
198 def quote
199 result = ""
200 self.chars do |c|
201 case c
202 when "'"
203 result += "\\\'"
204 when "\""
205 result += "\\\""
206 when "\0"
207 result += "\\0"
208 when "\a"
209 result += "\\a"
210 when "\b"
211 result += "\\b"
212 when "\f"
213 result += "\\f"
214 when "\n"
215 result += "\\n"
216 when "\r"
217 result += "\\r"
218 when "\t"
219 result += "\\t"
220 when "\v"
221 result += "\\v"
222 when "\\"
223 result += "\\\\"
224 else
225 result += c
226 end
227 end
228 return("\"" + result + "\"")
229 end
230
231 #
232 # 二重引用符で囲まれた文字列の展開
233 #
234 def unquote
235 if /^\"(.*)\"$/m =~ self
236 str = $1
237 result = ""
238 while (/^(.*)\\(.*)$/m =~ str)
239 result += $1
240 str = $2
241 case str
242 when /^[aA](.*)$/m
243 result += "\a"
244 str = $1
245 when /^[bB](.*)$/m
246 result += "\b"
247 str = $1
248 when /^[fF](.*)$/m
249 result += "\f"
250 str = $1
251 when /^[nN](.*)$/m
252 result += "\n"
253 str = $1
254 when /^[rR](.*)$/m
255 result += "\r"
256 str = $1
257 when /^[tT](.*)$/m
258 result += "\t"
259 str = $1
260 when /^[vV](.*)$/m
261 result += "\v"
262 str = $1
263 when /^[xX]([0-9a-fA-F][0-9a-fA-F]?)(.*)$/m
264 result += $1.hex
265 str = $2
266 when /^([0-7][0-7]?[0-7]?)(.*)$/m
267 result += $1.oct
268 str = $2
269 when /^\\(.*)$/m
270 result += "\\"
271 str = $1
272 end
273 end
274 return(result + str)
275 else
276 return(self.dup)
277 end
278 end
279end
280
281#
282# NumStrクラス(数値に文字列を付加したもの)の定義
283#
284class NumStr
285 def initialize(val, str = val.to_s)
286 @val = val
287 @str = str
288 end
289
290 # 数値情報を返す
291 def val
292 return @val
293 end
294 alias_method :to_i, :val
295
296 # 文字列情報を返す
297 def str
298 return @str
299 end
300 alias_method :to_s, :str
301
302 # 比較は数値情報で行う
303 def ==(other)
304 @val == other
305 end
306 def !=(other)
307 @val != other
308 end
309 def <=>(other)
310 @val <=> other
311 end
312
313 # ハッシュのキーとして使う時の比較も数値情報で行う
314 def eql?(other)
315 @val == other
316 end
317
318 # ハッシュ値の定義も上書きする
319 def hash
320 return @val.hash
321 end
322
323 # 数値クラスと演算できるようにする
324 def coerce(other)
325 if other.kind_of?(Numeric)
326 return other, @val
327 else
328 raise
329 end
330 end
331
332 # 二重引用符で囲まれた文字列の作成
333 def quote
334 str.quote
335 end
336
337 # 二重引用符で囲まれた文字列の展開
338 def unquote
339 str.unquote
340 end
341
342 # pp時の表示
343 def pretty_print(q)
344 q.text("[#{@val}(=0x#{@val.to_s(16)}),")
345 @str.pretty_print(q)
346 q.text("]")
347 end
348
349 # 未定義のメソッドは@valに送る
350 def method_missing(*method)
351 @val.send(*method)
352 end
353end
354
355#
356# シンボルファイルの読み込み
357#
358# 以下のメソッドは,GNUのnmが生成するシンボルファイルに対応している.
359# 別のツールに対応する場合には,このメソッドを書き換えればよい.
360#
361def ReadSymbolFile(symbolFileName)
362 begin
363 symbolFile = File.open(symbolFileName)
364 rescue Errno::ENOENT, Errno::EACCES => ex
365 abort(ex.message)
366 end
367
368 symbolAddress = {}
369 symbolFile.each do |line|
370 # スペース区切りで分解
371 fields = line.split(/\s+/)
372
373 # 3列になっていない行は除外
374 if fields.size == 3
375 symbolAddress[fields[2]] = fields[0].hex
376 end
377 end
378 symbolFile.close
379 return(symbolAddress)
380end
381
382#
383# 値取得シンボルをグローバル変数として定義する
384#
385def DefineSymbolValue
386 $symbolValueTable.each do |symbolName, symbolData|
387 if symbolData.has_key?(:VALUE)
388 eval("$#{symbolName} = #{symbolData[:VALUE]}")
389 if symbolData.has_key?(:NUMSTRVAR)
390 eval("$#{symbolData[:NUMSTRVAR]} = " \
391 "NumStr.new(symbolData[:VALUE], symbolData[:EXPR])")
392 end
393 end
394 end
395end
396
397#
398# インクルードパスからファイルを探す
399#
400def SearchFilePath(fileName)
401 if File.exist?(fileName)
402 # 指定したファイルパスに存在する
403 return fileName
404 elsif /^\./ =~ fileName
405 # 相対パスを指定していて見つからなかった場合,存在しないものとする
406 #(意図しないファイルが対象となることを防止)
407 return nil
408 else
409 # 各インクルードパスからファイル存在チェック
410 $includeDirectories.each do |includeDirectory|
411 path = includeDirectory + "/" + fileName
412 # 見つかったら相対パスを返す
413 if File.exist?(path)
414 return path
415 end
416 end
417 return nil
418 end
419end
420
421#
422# 指定した生成スクリプト(trbファイル)を検索してloadする
423#
424def IncludeTrb(fileName)
425 filePath = SearchFilePath(fileName)
426 if filePath.nil?
427 error_exit("`#{fileName}' not found")
428 else
429 load(filePath)
430 end
431end
432
433#
434# インクルードディレクティブ(#include)の生成
435#
436def GenerateIncludes(genFile)
437 $cfgFileInfo.each do |cfgInfo|
438 if cfgInfo.has_key?(:DIRECTIVE)
439 genFile.add(cfgInfo[:DIRECTIVE])
440 end
441 end
442end
443
444#
445# パス3の処理
446#
447def Pass3
448 #
449 # パス2から引き渡される情報をファイルから読み込む
450 #
451 db = PStore.new(CFG2_OUT_DB)
452 db.transaction(true) do
453 db.roots.each do |var|
454 eval("$#{var} = db[:#{var}]")
455 end
456 end
457
458 #
459 # 値取得シンボルをグローバル変数として定義する
460 #
461 DefineSymbolValue()
462
463 #
464 # 生成スクリプト(trbファイル)を実行する
465 #
466 $trbFileNames.each do |trbFileName|
467 IncludeTrb(trbFileName)
468 end
469
470 #
471 # パス4に引き渡す情報をファイルに生成
472 #
473 if !$omitOutputDb
474 db = PStore.new(CFG3_OUT_DB)
475 db.transaction do
476 $globalVars.each do |var|
477 eval("db[:#{var}] = $#{var}")
478 end
479 end
480 end
481end
482
483#
484# パス4の処理
485#
486def Pass4
487 #
488 # パス3から引き渡される情報をファイルから読み込む
489 #
490 db = PStore.new(CFG3_OUT_DB)
491 db.transaction(true) do
492 db.roots.each do |var|
493 eval("$#{var} = db[:#{var}]")
494 end
495 end
496
497 #
498 # 値取得シンボルをグローバル変数として定義する
499 #
500 DefineSymbolValue()
501
502 #
503 # 生成スクリプト(trbファイル)を実行する
504 #
505 $trbFileNames.each do |trbFileName|
506 IncludeTrb(trbFileName)
507 end
508end
509
510#
511# 生成スクリプト(trbファイル)向けの関数
512#
513def SYMBOL(symbol)
514 if !$romSymbol.nil? && $romSymbol.has_key?($asmLabel + symbol)
515 return $romSymbol[$asmLabel + symbol]
516 else
517 return nil
518 end
519end
520
521def BCOPY(fromAddress, toAddress, size)
522 if !$romImage.nil?
523 copyData = $romImage.get_data(fromAddress, size)
524 if !copyData.nil?
525 $romImage.set_data(toAddress, copyData)
526 end
527 end
528end
529
530def BZERO(address, size)
531 if !$romImage.nil?
532 $romImage.set_data(address, "00" * size)
533 end
534end
535
536def PEEK(address, size, signed=false)
537 if !$romImage.nil?
538 return $romImage.get_value(address, size, signed)
539 else
540 return nil
541 end
542end
543
544#
545# グローバル変数の初期化
546#
547$kernel = nil
548$pass = nil
549$includeDirectories = []
550$trbFileNames = []
551$apiTableFileNames = []
552$symvalTableFileNames = []
553$romImageFileName = nil
554$romSymbolFileName = nil
555$idInputFileName = nil
556$idOutputFileName = nil
557$dependencyFileName = nil
558$omitOutputDb = false
559$supportDomain = false
560$supportClass = false
561
562#
563# オプションの処理
564#
565OptionParser.new("Usage: cfg.rb [options] CONFIG-FILE", 40) do |opt|
566 opt.version = VERSION
567 opt.release = nil
568 opt.on("-k KERNEL", "--kernel KERNEL", "kernel profile name") do |val|
569 $kernel = val
570 end
571 opt.on("-p NUM", "--pass NUM", "processing pass number") do |val|
572 $pass = val
573 end
574 opt.on("-I DIRECTORY", "--include-directory DIRECTORY",
575 "include directory") do |val|
576 $includeDirectories.push(val)
577 end
578 opt.on("-T TRB-FILE", "--trb-file TRB-FILE",
579 "generation script (trb file)") do |val|
580 $trbFileNames.push(val)
581 end
582 opt.on("--api-table API-TABLE-FILE", "static API table file") do |val|
583 $apiTableFileNames.push(val)
584 end
585 opt.on("--symval-table SYMVAL-TABLE-FILE", "symbol-value table file") do |val|
586 $symvalTableFileNames.push(val)
587 end
588 opt.on("--rom-image SREC-FILE", "rom image file (s-record)") do |val|
589 $romImageFileName = val
590 end
591 opt.on("--rom-symbol SYMS-FILE", "rom symbol table file (nm)") do |val|
592 $romSymbolFileName = val
593 end
594 opt.on("--id-input-file ID-FILE", "ID input file") do |val|
595 $idInputFileName = val
596 end
597 opt.on("--id-output-file ID-FILE", "ID output file") do |val|
598 $idOutputFileName = val
599 end
600 opt.on("-M [DEPEND-FILE]", "--print-dependencies [DEPEND-FILE]",
601 "dependency file") do |val|
602 $dependencyFileName = val.nil? ? "" : val
603 end
604 opt.on("-O", "--omit-output-db", "omit DB file output") do
605 $omitOutputDb = true
606 end
607 opt.on("--enable-domain", "enable DOMAIN support") do
608 $supportDomain = true
609 end
610 opt.on("--enable-class", "enable CLASS support") do
611 $supportClass = true
612 end
613 opt.on("-v", "--version", "show version number") do
614 puts(opt.ver)
615 exit(0)
616 end
617 opt.on("-h", "--help", "show help (this)") do
618 puts(opt.help)
619 exit(0)
620 end
621 opt.parse!(ARGV)
622end
623$configFileNames = ARGV
624
625#
626# オプションのチェック
627#
628if $pass.nil?
629 # パスの指定は必須
630 abort("`--pass' option is mandatory")
631elsif /^[1234]$/ !~ $pass
632 abort("pass number `#{$pass}' is not valid")
633end
634
635# パス1では,静的APIテーブルは必須
636if ($pass == "1" && $apiTableFileNames.empty?)
637 abort("`--api-table' option must be specified in pass 1")
638end
639
640# パス1以外では,生成スクリプト(trbファイル)が必須
641if ($pass != "1" && $trbFileNames.empty?)
642 abort("`--trb-file' must be specified except in pass 1")
643end
644
645#
646# カーネルオプションの処理
647#
648case $kernel
649when /^hrp/
650 $supportDomain = true
651when /^fmp/
652 $supportClass = true
653when /^hrmp/
654 $supportDomain = true
655 $supportClass = true
656end
657
658#
659# ID番号入力ファイルの取り込み
660#
661$inputObjid = {}
662if !$idInputFileName.nil?
663 begin
664 idInputFile = File.open($idInputFileName)
665 rescue Errno::ENOENT, Errno::EACCES => ex
666 abort(ex.message)
667 end
668
669 idInputFile.each do |line|
670 ( objName, objidNumber ) = line.split(/\s+/)
671 $inputObjid[objName] = objidNumber.to_i
672 end
673
674 idInputFile.close
675end
676
677#
678# 指定されたシンボルファイルの読み込み
679#
680if !$romSymbolFileName.nil?
681 if File.exist?($romSymbolFileName)
682 $romSymbol = ReadSymbolFile($romSymbolFileName)
683 else
684 error_exit("`#{$romSymbolFileName}' not found")
685 end
686end
687
688#
689# 指定されたSレコードファイルの読み込み
690#
691if !$romImageFileName.nil?
692 if File.exist?($romImageFileName)
693 $romImage = SRecord.new($romImageFileName)
694 else
695 error_exit("`#{$romImageFileName}' not found")
696 end
697end
698
699#
700# パスに従って各処理を実行
701#
702case $pass
703when "1"
704 load("pass1.rb")
705 Pass1()
706when "2"
707 load("pass2.rb")
708 Pass2()
709when "3"
710 Pass3()
711when "4"
712 Pass4()
713else
714 error_exit("invalid pass: #{$pass}")
715end
716
717# エラー発生時はabortする
718if $errorFlag
719 if ($0 == __FILE__)
720 abort()
721 else
722 # simplecov対応
723 raise()
724 end
725end
726
727#
728# 作成したすべてのファイルを出力する
729#
730GenFile.output
731
732#
733# タイムスタンプファイルの生成
734#
735if !$timeStampFileName.nil?
736 File.open($timeStampFileName, "w").close
737end
Note: See TracBrowser for help on using the repository browser.