source: rubycfg_asp/trunk/asp_dcre/cfg/cfg.rb@ 313

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

ソースを追加

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