source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/cfg/pass1.rb@ 352

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

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby;charset=UTF-8
File size: 27.8 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-2017 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# パス1の処理
43#
44
45#
46# 値取得シンボルテーブルへの固定登録
47#
48$symbolValueTable = {
49 "CHAR_BIT" => { EXPR: "CHAR_BIT" },
50 "SCHAR_MAX" => { EXPR: "SCHAR_MAX", SIGNED: true },
51 "SCHAR_MIN" => { EXPR: "SCHAR_MIN", SIGNED: true },
52 "UCHAR_MAX" => { EXPR: "UCHAR_MAX" },
53 "CHAR_MAX" => { EXPR: "CHAR_MAX", SIGNED: true },
54 "CHAR_MIN" => { EXPR: "CHAR_MIN", SIGNED: true },
55 "SHRT_MAX" => { EXPR: "SHRT_MAX", SIGNED: true },
56 "SHRT_MIN" => { EXPR: "SHRT_MIN", SIGNED: true },
57 "USHRT_MAX" => { EXPR: "USHRT_MAX" },
58 "INT_MAX" => { EXPR: "INT_MAX", SIGNED: true },
59 "INT_MIN" => { EXPR: "INT_MIN", SIGNED: true },
60 "UINT_MAX" => { EXPR: "UINT_MAX" },
61 "LONG_MAX" => { EXPR: "LONG_MAX", SIGNED: true },
62 "LONG_MIN" => { EXPR: "LONG_MIN", SIGNED: true },
63 "ULONG_MAX" => { EXPR: "ULONG_MAX" }
64}
65
66#
67# 静的APIテーブルへの固定登録
68#
69$apiDefinition = { "INCLUDE" =>
70 { :PARAM => [ { :NAME => :file, :STRING => true }]}}
71
72#
73# 静的APIテーブルの読み込み
74#
75def ReadApiTableFile
76 $apiTableFileNames.each do |apiTableFileName|
77 if /^(.+):(\w+)$/ =~ apiTableFileName
78 apiTableFileName = $1
79 apiPhase = $2.to_sym
80 end
81
82 if !File.exist?(apiTableFileName)
83 error_exit("`#{apiTableFileName}' not found")
84 next
85 end
86
87 apiFile = File.open(apiTableFileName)
88 apiFile.each do |line|
89 next if /^#/ =~ line # コメントをスキップ
90
91 fields = line.split(/\s+/) # フィールドに分解
92
93 apiName = fields.shift # API名の取り出し
94 if /^(.+)\[(.+)\]$/ =~ apiName
95 apiName = $1
96 apiDef = { APINAME: apiName, API: $2 }
97 else
98 apiDef = { APINAME: apiName, API: apiName }
99 end
100 if !apiPhase.nil?
101 apiDef[:PHASE] = apiPhase
102 end
103
104 apiParams = []
105 fields.each do |param|
106 case param
107 when /^(\W*)(\w+)(\W*)$/
108 prefix = $1
109 name = $2
110 postfix = $3
111 apiParam = { :NAME => name }
112
113 case prefix
114 when "#" # オブジェクト識別名(定義)
115 apiParam[:ID_DEF] = true
116 when "%" # オブジェクト識別名(参照)
117 apiParam[:ID_REF] = true
118 when "." # 符号無し整数定数式パラメータ
119 apiParam[:EXPTYPE] = "unsigned_t"
120 when "+" # 符号付き整数定数式パラメータ
121 apiParam[:EXPTYPE] = "signed_t"
122 apiParam[:SIGNED] = true
123 when "&" # 一般整数定数式パラメータ
124 # do nothing
125 when "$" # 文字列定数式パラメータ
126 apiParam[:STRING] = true
127 else
128 error_exit("`#{param}' is invalid")
129 end
130
131 case postfix
132 when "*" # キーを決めるパラメータ
133 apiDef[:KEYPAR] = name
134 when "?" # オプションパラメータ
135 apiParam[:OPTIONAL] = true
136 when "\.\.\." # リストパラメータ
137 apiParam[:LIST] = true
138 end
139
140 when "{" # {
141 apiParam = { :BRACE => "{" }
142 when "{?" # {?
143 apiParam = { :BRACE => "{", :OPTBRACE => true }
144
145 when "}" # }
146 apiParam = { :BRACE => "}" }
147
148 else
149 error_exit("`#{param}' is invalid")
150 end
151 apiParams.push(apiParam)
152 end
153 apiDef[:PARAM] = apiParams
154 $apiDefinition[apiName] = apiDef
155 end
156 apiFile.close
157 end
158end
159
160#
161# 値取得シンボルテーブルの読み込み
162#
163def ReadSymvalTable
164 $symvalTableFileNames.each do |symvalTableFileName|
165 if !File.exist?(symvalTableFileName)
166 error_exit("`#{symvalTableFileName}' not found")
167 next
168 end
169
170 symvalCsv = CSV.open(symvalTableFileName,
171 { skip_blanks: true, skip_lines: /^#/ })
172 symvalCsv.each do |record|
173 # 変数名
174 if record[0].nil?
175 error_exit("invalid variable name in " \
176 "`#{symvalTableFileName}:#{symvalCsv.to_io.lineno}'")
177 end
178
179 symbol = {}
180 variable = record[0]
181
182 # 式
183 if record[1].nil? || record[1].empty?
184 symbol[:EXPR] = variable
185 else
186 symbol[:EXPR] = record[1]
187 end
188
189 # 式の型
190 if !record[2].nil? && !record[2].empty?
191 case record[2]
192 when /^[bB]/ # 真偽値
193 symbol[:BOOL] = true
194 when /^[uU]/ # 符号無し整数値
195 # 何も設定しない
196 else # 符号付き整数値
197 symbol[:SIGNED] = true
198 end
199 end
200
201 # コンパイル条件
202 if !record[3].nil? && !record[3].empty?
203 symbol[:CONDITION] = record[3]
204 end
205
206 # 条件が成立しない時の式
207 if !record[4].nil? && !record[4].empty?
208 symbol[:ELSE_EXPR] = record[4]
209 end
210
211 $symbolValueTable[variable] = symbol
212 end
213 symvalCsv.close
214 end
215end
216
217#
218# システムコンフィギュレーションファイルからの読み込みクラス
219#
220class ConfigFile
221 def initialize(fileName)
222 @cfgFileName = fileName
223 begin
224 @cfgFile = File.open(@cfgFileName)
225 rescue Errno::ENOENT, Errno::EACCES => ex
226 abort(ex.message)
227 end
228 @lineNo = 0
229 @withinComment = false
230 end
231
232 def close
233 @cfgFile.close
234 end
235
236 def getNextLine(withinApi)
237 line = @cfgFile.gets
238 return(nil) if line.nil?
239
240 line.encode!("UTF-16BE", "UTF-8", # 不正なバイト列を除外する
241 :invalid => :replace,
242 :undef => :replace,
243 :replace => '?').encode!("UTF-8")
244 @lineNo += 1
245
246 line.chomp!
247 if @withinComment
248 case line
249 when /\*\// # C言語スタイルのコメント終了
250 line.sub!(/^.*?\*\//, "") # 最初の*/にマッチさせる */
251 @withinComment = false
252 else
253 line = ""
254 end
255 end
256 if !@withinComment
257 line.gsub!(/\/\*.*?\*\//, "") # C言語スタイルのコメントの除去
258 # 最初の*/にマッチさせる */
259 case line
260 when /^\s*#/ # プリプロセッサディレクティブ
261 if withinApi
262 parse_error(self, \
263 "preprocessor directive must not be within static API")
264 line = ""
265 end
266 when /\/\*/ # C言語スタイルのコメント開始
267 line.sub!(/\/\*.*$/, "")
268 @withinComment = true
269 when /\/\// # C++言語スタイルのコメント
270 line.sub!(/\/\/.*$/, "")
271 end
272 end
273 return(line)
274 end
275
276 def getFileName
277 return(@cfgFileName)
278 end
279
280 def getLineNo
281 return(@lineNo)
282 end
283end
284
285#
286# システムコンフィギュレーションファイルのパーサークラス
287#
288class CfgParser
289 @@lastApiIndex = 0
290 @@currentDomain = nil
291 @@currentClass = nil
292 @@nestDC = []
293
294 def initialize
295 @line = ""
296 @skipComma = false # 次が,であれば読み飛ばす
297 end
298
299 #
300 # 文字列末まで読む
301 #
302 def parseString(cfgFile)
303 string = ""
304 begin
305 case @line
306 when /^([^"]*\\\\)(.*)$/ # \\まで読む
307 string += $1
308 @line = $2
309 when /^([^"]*\\\")(.*)$/ # \"まで読む
310 string += $1
311 @line = $2
312 when /^([^"]*\")(.*)$/ # "まで読む
313 string += $1
314 @line = $2
315 return(string)
316 else # 行末まで読む
317 string += @line + "\n"
318 @line = cfgFile.getNextLine(true)
319 end
320 end while (@line)
321 error_exit("unterminated string meets end-of-file")
322 return(string)
323 end
324
325 #
326 # 文字末まで読む
327 #
328 def parseChar(cfgFile)
329 string = ""
330 begin
331 case @line
332 when /^([^']*\\\\)(.*)$/ # \\まで読む
333 string += $1
334 @line = $2
335 when /^([^']*\\\')(.*)$/ # \'まで読む
336 string += $1
337 @line = $2
338 when /^([^']*\')(.*)$/ # 'まで読む
339 string += $1
340 @line = $2
341 return(string)
342 else # 行末まで読む
343 string += @line + "\n"
344 @line = cfgFile.getNextLine(true)
345 end
346 end while (@line)
347 error_exit("unterminated string meets end-of-file")
348 return(string)
349 end
350
351 #
352 # 改行と空白文字を読み飛ばす
353 #
354 def skipSpace(cfgFile, withinApi)
355 loop do
356 return if @line.nil? # ファイル末であればリターン
357 @line.lstrip! # 先頭の空白を削除
358 return if @line != "" # 空行でなければリターン
359 @line = cfgFile.getNextLine(withinApi) # 次の行を読む
360 end
361 end
362
363 #
364 # 次の文字まで読み飛ばす
365 #
366 def skipToToken(cfgFile, withinApi=true)
367 skipSpace(cfgFile, withinApi)
368 if @line.nil? # ファイル末であればエラー終了
369 error_exit("unexpexced end-of-file")
370 end
371 end
372
373 #
374 # パラメータを1つ読む
375 #
376 # @lineの先頭からパラメータを1つ読んで,それを文字列で返す.読んだパ
377 # ラメータは,@lineからは削除する.パラメータの途中で行末に達した時は,
378 # cfgFileから次の行を取り出す.ファイル末に達した時は,nilを返す.
379 #
380 def parseParam(cfgFile)
381 param = "" # 読んだ文字列
382 parenLevel = 0 # 括弧のネストレベル
383 skipComma = @skipComma
384 @skipComma = false
385
386 skipToToken(cfgFile) # 次の文字まで読み飛ばす
387 begin
388 if parenLevel == 0
389 case @line
390 when /^(\s*,)(.*)$/ # ,
391 @line = $2
392 if param == "" && skipComma
393 skipComma = false
394 return(parseParam(cfgFile)) # 再帰呼び出し
395 else
396 return(param.strip)
397 end
398 when /^(\s*{)(.*)$/ # {
399 if param != ""
400 return(param.strip)
401 else
402 @line = $2
403 return("{")
404 end
405 when /^(\s*\()(.*)$/ # (
406 param += $1
407 @line = $2
408 parenLevel += 1
409 when /^(\s*([)}]))(.*)$/ # }か)
410 if param != ""
411 return(param.strip)
412 else
413 @line = $3
414 @skipComma = true if $2 == "}"
415 return($2)
416 end
417 when /^(\s*\")(.*)$/ # "
418 @line = $2
419 param += $1 + parseString(cfgFile)
420 when /^(\s*\')(.*)$/ # '
421 @line = $2
422 param += $1 + parseChar(cfgFile)
423 when /^(\s*[^,{}()"'\s]+)(.*)$/ # その他の文字列
424 param += $1
425 @line = $2
426 else # 行末
427 param += " "
428 @line = cfgFile.getNextLine(true)
429 end
430 else
431 # 括弧内の処理
432 case @line
433 when /^(\s*\()(.*)$/ # "("
434 param += $1
435 @line = $2
436 parenLevel += 1
437 when /^(\s*\))(.*)$/ # ")"
438 param += $1
439 @line = $2
440 parenLevel -= 1
441 when /^(\s*\")(.*)$/ # "
442 @line = $2
443 param += $1 + parseString(cfgFile)
444 when /^(\s*\')(.*)$/ # '
445 @line = $2
446 param += $1 + parseChar(cfgFile)
447 when /^(\s*[^()"'\s]+)(.*)$/ # その他の文字列
448 param += $1
449 @line = $2
450 else # 行末
451 param += " "
452 @line = cfgFile.getNextLine(true)
453 end
454 end
455 end while (@line)
456 return(param.strip)
457 end
458
459 def getParam(apiParam, param, cfgFile)
460 if param == ""
461 if !apiParam.has_key?(:OPTIONAL)
462 parse_error(cfgFile, "unexpected `,'")
463 end
464 return(param)
465 end
466
467 if apiParam.has_key?(:ID_DEF) || apiParam.has_key?(:ID_REF)
468 if (/^[A-Za-z_]\w*$/ !~ param)
469 parse_error(cfgFile, "`#{param}' is illegal object ID")
470 end
471 return(param)
472 end
473
474 if apiParam.has_key?(:STRING)
475 return(param.unquote)
476 else
477 return(param)
478 end
479 end
480
481 def parseApi(cfgFile, apiName)
482 # 静的APIの読み込み
483 staticApi = {}
484 tooFewParams = false
485 skipUntilBrace = 0
486
487 skipToToken(cfgFile) # 次の文字まで読み飛ばす
488 if (/^\((.*)$/ =~ @line)
489 @line = $1
490
491 staticApi[:APINAME] = apiName
492 staticApi[:_FILE_] = cfgFile.getFileName
493 staticApi[:_LINE_] = cfgFile.getLineNo
494 apiDef = $apiDefinition[apiName]
495 param = parseParam(cfgFile)
496
497 apiDef[:PARAM].each do |apiParam|
498 return(staticApi) if param.nil? # ファイル末であればリターン
499
500 if skipUntilBrace > 0
501 # API定義を}までスキップ中
502 if apiParam.has_key?(:BRACE)
503 case apiParam[:BRACE]
504 when "{"
505 skipUntilBrace += 1
506 when "}"
507 skipUntilBrace -= 1
508 end
509 end
510 elsif apiParam.has_key?(:OPTIONAL)
511 if /^([{})])$/ !~ param
512 store_param = getParam(apiParam, param, cfgFile)
513 if store_param != ""
514 staticApi[apiParam[:NAME]] = store_param
515 end
516 param = parseParam(cfgFile)
517 end
518 elsif apiParam.has_key?(:LIST)
519 staticApi[apiParam[:NAME]] = []
520 while /^([{})])$/ !~ param
521 staticApi[apiParam[:NAME]].push(getParam(apiParam, param, cfgFile))
522 param = parseParam(cfgFile)
523 break if param.nil? # ファイル末の場合
524 end
525 elsif apiParam.has_key?(:OPTBRACE)
526 if param == apiParam[:BRACE]
527 param = parseParam(cfgFile)
528 break if param.nil? # ファイル末の場合
529 else
530 if param == ""
531 param = parseParam(cfgFile)
532 break if param.nil? # ファイル末の場合
533 elsif /^([})])$/ !~ param
534 parse_error(cfgFile, "`{...}' expected before #{param}")
535 end
536 skipUntilBrace += 1 # API定義を}までスキップ
537 end
538 elsif !apiParam.has_key?(:BRACE)
539 if /^([{})])$/ !~ param
540 staticApi[apiParam[:NAME]] = getParam(apiParam, param, cfgFile)
541 param = parseParam(cfgFile)
542 elsif !tooFewParams
543 parse_error(cfgFile, "too few parameters before `#{$1}'")
544 tooFewParams = true
545 end
546 elsif param == apiParam[:BRACE]
547 param = parseParam(cfgFile)
548 tooFewParams = false
549 else
550 parse_error(cfgFile, "`#{apiParam[:BRACE]}' expected before #{param}")
551 # )かファイル末まで読み飛ばす
552 loop do
553 param = parseParam(cfgFile)
554 break if (param.nil? || param == ")")
555 end
556 break
557 end
558 end
559
560 # 期待されるパラメータをすべて読んだ後の処理
561 if param != ")"
562 begin
563 param = parseParam(cfgFile)
564 return(staticApi) if param.nil? # ファイル末であればリターン
565 end while param != ")"
566 parse_error(cfgFile, "too many parameters before `)'")
567 end
568 else
569 parse_error(cfgFile, "syntax error: #{@line}")
570 @line = ""
571 end
572 return(staticApi)
573 end
574
575 def parseOpenBrace(cfgFile)
576 # {の読み込み
577 skipToToken(cfgFile) # 次の文字まで読み飛ばす
578 if (/^\{(.*)$/ =~ @line)
579 @line = $1
580 else
581 parse_error(cfgFile, "`{' expected before #{@line}")
582 end
583 end
584
585 def parseFile(cfgFileName)
586 cfgFiles = [ ConfigFile.new(cfgFileName) ]
587 @line = ""
588 loop do
589 cfgFile = cfgFiles.last
590
591 skipSpace(cfgFile, false) # 改行と空白文字を読み飛ばす
592 if @line.nil?
593 # ファイル末の処理
594 cfgFiles.pop.close
595 if cfgFiles.empty?
596 break # パース処理終了
597 else
598 @line = "" # 元のファイルに戻って続ける
599 end
600 elsif /^;(.*)$/ =~ @line
601 # ;は読み飛ばす
602 @line = $1
603 elsif /^#/ =~ @line
604 # プリプロセッサディレクティブを読む
605 case @line
606 when /^#include\b(.*)$/
607 $includeFiles.push($1.strip)
608 when /^#(ifdef|ifndef|if|endif|else|elif)\b/
609 directive = { :DIRECTIVE => @line.strip }
610 $cfgFileInfo.push(directive)
611 else
612 parse_error(cfgFile, "unknown preprocessor directive: #{@line}")
613 end
614 @line = ""
615 elsif (/^([A-Z_][A-Z0-9_]*)\b(.*)$/ =~ @line)
616 apiName = $1
617 @line = $2
618
619 case apiName
620 when "KERNEL_DOMAIN"
621 if $supportDomain.nil?
622 parse_warning(cfgFile, "`KERNEL_DOMAIN' is not supported")
623 end
624 if !@@currentDomain.nil?
625 parse_error(cfgFile, "`DOMAIN' must not be nested")
626 end
627 @@currentDomain = "TDOM_KERNEL"
628 parseOpenBrace(cfgFile)
629 @@nestDC.push("domain")
630 when "DOMAIN"
631 if $supportDomain.nil?
632 parse_warning(cfgFile, "`DOMAIN' is not supported")
633 end
634 if !@@currentDomain.nil?
635 parse_error(cfgFile, "`DOMAIN' must not be nested")
636 end
637 domid = parseParam(cfgFile).sub(/^\((.+)\)$/m, "\\1").strip
638 if (/^[A-Za-z_]\w*$/ !~ domid)
639 parse_error(cfgFile, "`#{domid}' is illegal domain ID")
640 else
641 if !$domainId.has_key?(domid)
642 if $inputObjid.has_key?(domid)
643 # ID番号入力ファイルに定義されていた場合
644 $domainId[domid] = $inputObjid[domid]
645 if $domainId[domid] > 32
646 error_exit("domain ID for `#{domid}' is too large")
647 end
648 else
649 $domainId[domid] = nil
650 end
651 end
652 @@currentDomain = domid
653 end
654 parseOpenBrace(cfgFile)
655 @@nestDC.push("domain")
656 when "CLASS"
657 if $supportClass.nil?
658 parse_warning(cfgFile, "`CLASS' is not supported")
659 end
660 if !@@currentClass.nil?
661 parse_error(cfgFile, "`CLASS' must not be nested")
662 end
663 @@currentClass = parseParam(cfgFile).sub(/^\((.+)\)$/m, "\\1").strip
664 @@classFile = cfgFile.getFileName
665 @@classLine = cfgFile.getLineNo
666 parseOpenBrace(cfgFile)
667 @@nestDC.push("class")
668 else
669 if $apiDefinition.has_key?(apiName)
670 # 静的APIを1つ読む
671 staticApi = parseApi(cfgFile, apiName)
672 if staticApi.empty?
673 # ファイル末か文法エラー
674 elsif (staticApi[:APINAME] == "INCLUDE")
675 # INCLUDEの処理
676 includeFilePath = SearchFilePath(staticApi[:file])
677 if includeFilePath.nil?
678 parse_error(cfgFile, "`#{staticApi[:file]}' not found")
679 else
680 $dependencyFiles.push(includeFilePath)
681 cfgFiles.push(ConfigFile.new(includeFilePath))
682 end
683 else
684 # 静的APIの処理
685 if !@@currentDomain.nil?
686 staticApi[:DOMAIN] = @@currentDomain
687 end
688 if !@@currentClass.nil?
689 staticApi[:CLASS] = @@currentClass
690 staticApi[:CLASS_FILE_] = @@classFile
691 staticApi[:CLASS_LINE_] = @@classLine
692 end
693 staticApi[:INDEX] = (@@lastApiIndex += 1)
694 $cfgFileInfo.push(staticApi)
695 end
696 else
697 parse_error(cfgFile, "unknown static API: #{apiName}")
698 end
699 end
700 elsif (/^\}(.*)$/ =~ @line)
701 # }の処理
702 if @@nestDC.size > 0
703 case @@nestDC.pop
704 when "domain"
705 @@currentDomain = nil
706 when "class"
707 @@currentClass = nil
708 end
709 else
710 error_exit("unexpected `}'")
711 end
712 @line = $1
713 else
714 parse_error(cfgFile, "syntax error: #{@line}")
715 @line = ""
716 end
717 end
718 end
719end
720
721#
722# cfg1_out.cの生成
723#
724module Cfg1OutC
725 #
726 # 静的APIのファイル名と行番号の出力
727 #
728 def self.OutLineNumber(cfgInfo)
729 @cfg1Out.add("#line #{cfgInfo[:_LINE_]} \"#{cfgInfo[:_FILE_]}\"")
730 end
731
732 #
733 # クラス記述のファイル名と行番号の出力
734 #
735 def self.OutClassLineNumber(cfgInfo)
736 @cfg1Out.add("#line #{cfgInfo[:CLASS_LINE_]} \"#{cfgInfo[:CLASS_FILE_]}\"")
737 end
738
739 #
740 # パラメータに関する定義の出力
741 #
742 def self.OutParamDef(param, index, apiParam, cfgInfo)
743 if apiParam.has_key?(:ID_DEF)
744 @cfg1Out.add("#define #{param}\t(<>)")
745 elsif apiParam.has_key?(:EXPTYPE)
746 OutLineNumber(cfgInfo)
747 @cfg1Out.add("const #{apiParam[:EXPTYPE]} #{CFG1_PREFIX}valueof_" \
748 "#{apiParam[:NAME]}_#{index} = " \
749 "(#{apiParam[:EXPTYPE]})(#{param});")
750 end
751 end
752
753 #
754 # cfg1_out.cの生成(メインの処理)
755 #
756 def self.Generate
757 @cfg1Out = GenFile.new(CFG1_OUT_C)
758
759 @cfg1Out.append(<<EOS)
760/* #{CFG1_OUT_C} */
761#define TOPPERS_CFG1_OUT
762#include "kernel/kernel_int.h"
763EOS
764
765 # インクルードヘッダファイル
766 $includeFiles.each do |file|
767 @cfg1Out.add("#include #{file}")
768 end
769
770 @cfg1Out.add(<<EOS)
771
772#ifdef INT64_MAX
773 typedef int64_t signed_t;
774 typedef uint64_t unsigned_t;
775#else
776 typedef int32_t signed_t;
777 typedef uint32_t unsigned_t;
778#endif
779
780#include "#{CFG1_OUT_TARGET_H}"
781
782#if defined(SIL_ENDIAN_BIG) && defined(SIL_ENDIAN_LITTLE)
783#error Both SIL_ENDIAN_BIG and SIL_ENDIAN_LITTLE are defined.
784#endif
785#if !defined(SIL_ENDIAN_BIG) && !defined(SIL_ENDIAN_LITTLE)
786#error Neither SIL_ENDIAN_BIG nor SIL_ENDIAN_LITTLE is defined.
787#endif
788
789const uint32_t #{CFG1_MAGIC_NUM} = 0x12345678;
790const uint32_t #{CFG1_SIZEOF_SIGNED} = sizeof(signed_t);
791EOS
792
793 # 値取得シンボルの処理
794 $symbolValueTable.each do |symbolName, symbolData|
795 if symbolData.has_key?(:BOOL) || symbolData.has_key?(:SIGNED)
796 type = "signed_t"
797 else
798 type = "unsigned_t"
799 end
800 if symbolData.has_key?(:CONDITION)
801 @cfg1Out.add("#if #{symbolData[:CONDITION]}")
802 end
803 @cfg1Out.add("const #{type} #{CFG1_PREFIX}#{symbolName} = " \
804 "(#{type})(#{symbolData[:EXPR]});")
805 if symbolData.has_key?(:ELSE_EXPR)
806 @cfg1Out.add("#else")
807 @cfg1Out.add("const #{type} #{CFG1_PREFIX}#{symbolName} = " \
808 "(#{type})(#{symbolData[:ELSE_EXPR]});")
809 end
810 if symbolData.has_key?(:CONDITION)
811 @cfg1Out.add("#endif")
812 end
813 end
814 @cfg1Out.add
815
816 # ドメインIDの定義の生成
817 $domainId.each do |domainName, domainVal|
818 if domainVal > 0
819 @cfg1Out.add("#define #{domainName} #{domainVal}")
820 end
821 end
822 @cfg1Out.add
823
824 # 静的API/プリプロセッサディレクティブの処理
825 $cfgFileInfo.each do |cfgInfo|
826 if cfgInfo.has_key?(:DIRECTIVE)
827 @cfg1Out.add2(cfgInfo[:DIRECTIVE])
828 else
829 apiDef = $apiDefinition[cfgInfo[:APINAME]]
830 apiIndex = cfgInfo[:INDEX]
831 OutLineNumber(cfgInfo)
832 @cfg1Out.add("const unsigned_t #{CFG1_PREFIX}static_api_" \
833 "#{apiIndex} = #{apiIndex};")
834 apiDef[:PARAM].each do |apiParam|
835 next unless apiParam.has_key?(:NAME)
836 paramName = apiParam[:NAME]
837 next unless cfgInfo.has_key?(paramName) # パラメータがない場合
838 paramData = cfgInfo[paramName]
839
840 if apiParam.has_key?(:LIST)
841 paramData.each.with_index(1) do |param, index|
842 OutParamDef(param, "#{apiIndex}_#{index}", apiParam, cfgInfo)
843 end
844 else
845 OutParamDef(paramData, "#{apiIndex}", apiParam, cfgInfo)
846 end
847 end
848 if cfgInfo.has_key?(:CLASS)
849 # クラスIDの取得のための処理
850 OutClassLineNumber(cfgInfo)
851 @cfg1Out.add("const signed_t #{CFG1_PREFIX}valueof_CLASS_" \
852 "#{apiIndex} = (signed_t)(#{cfgInfo[:CLASS]});")
853 end
854 @cfg1Out.add
855 end
856 end
857 end
858end
859
860#
861# パス1の処理
862#
863def Pass1
864 #
865 # タイムスタンプファイルの指定
866 #
867 $timeStampFileName = CFG1_OUT_TIMESTAMP
868
869 #
870 # 静的APIテーブルの読み込み
871 #
872 ReadApiTableFile()
873
874 #
875 # 値取得シンボルテーブルの読み込み
876 #
877 ReadSymvalTable()
878
879 #
880 # システムコンフィギュレーションファイルの読み込み
881 #
882 $cfgFileInfo = []
883 $dependencyFiles = $configFileNames.dup
884 $includeFiles = []
885 $domainId = { "TDOM_KERNEL" => -1, "TDOM_NONE" => -2 }
886 $configFileNames.each do |configFileName|
887 CfgParser.new.parseFile(configFileName)
888 end
889 abort if $errorFlag # エラー発生時はabortする
890
891 #
892 # ドメインIDの割当て処理
893 #
894 nextDomainId = 1
895 $domainId.each do |domainName, domainVal|
896 if domainVal.nil?
897 while $domainId.has_value?(nextDomainId)
898 nextDomainId += 1
899 end
900 $domainId[domainName] = nextDomainId
901 if nextDomainId > 32
902 error_exit("too large number of user domains")
903 end
904 nextDomainId += 1
905 end
906 end
907
908 #
909 # cfg1_out.cの生成
910 #
911 Cfg1OutC::Generate()
912
913 #
914 # 依存関係の出力
915 #
916 if !$dependencyFileName.nil?
917 if $dependencyFileName == ""
918 depFile = STDOUT
919 else
920 begin
921 depFile = File.open($dependencyFileName, "w")
922 rescue Errno::ENOENT, Errno::EACCES => ex
923 abort(ex.message)
924 end
925 end
926
927 depFile.print("#{CFG1_OUT_TIMESTAMP}:")
928 $dependencyFiles.each do |fileName|
929 depFile.print(" #{fileName}")
930 end
931 depFile.puts("")
932
933 if $dependencyFileName != ""
934 depFile.close
935 end
936 end
937
938 #
939 # パス2に引き渡す情報をファイルに生成
940 #
941 if $omitOutputDb.nil?
942 db = PStore.new(CFG1_OUT_DB)
943 db.transaction do
944 db[:apiDefinition] = $apiDefinition
945 db[:symbolValueTable] = $symbolValueTable
946 db[:cfgFileInfo] = $cfgFileInfo
947 db[:includeFiles] = $includeFiles
948 db[:domainId] = $domainId
949 end
950 end
951end
Note: See TracBrowser for help on using the repository browser.