[117] | 1 | #!ruby -Ke
|
---|
| 2 | #
|
---|
| 3 | # ABREX
|
---|
| 4 | # AUTOSAR BSW and RTE XML Generator
|
---|
| 5 | #
|
---|
| 6 | # Copyright (C) 2013-2015 by Center for Embedded Computing Systems
|
---|
| 7 | # Graduate School of Information Science, Nagoya Univ., JAPAN
|
---|
| 8 | # Copyright (C) 2014-2015 by AISIN COMCRUISE Co., Ltd., JAPAN
|
---|
| 9 | # Copyright (C) 2013-2015 by FUJI SOFT INCORPORATED, JAPAN
|
---|
| 10 | # Copyright (C) 2014-2015 by NEC Communication Systems, Ltd., JAPAN
|
---|
| 11 | # Copyright (C) 2013-2015 by Panasonic Advanced Technology Development Co., Ltd., JAPAN
|
---|
| 12 | # Copyright (C) 2013-2014 by Renesas Electronics Corporation, JAPAN
|
---|
| 13 | # Copyright (C) 2014-2015 by SCSK Corporation, JAPAN
|
---|
| 14 | # Copyright (C) 2013-2015 by Sunny Giken Inc., JAPAN
|
---|
| 15 | # Copyright (C) 2013-2015 by TOSHIBA CORPORATION, JAPAN
|
---|
| 16 | # Copyright (C) 2013-2015 by Witz Corporation
|
---|
| 17 | #
|
---|
| 18 | # 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
|
---|
| 19 | # ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
|
---|
| 20 | # 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
|
---|
| 21 | # (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
|
---|
| 22 | # 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
|
---|
| 23 | # スコード中に含まれていること.
|
---|
| 24 | # (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
|
---|
| 25 | # 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
|
---|
| 26 | # 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
|
---|
| 27 | # の無保証規定を掲載すること.
|
---|
| 28 | # (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
|
---|
| 29 | # 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
|
---|
| 30 | # と.
|
---|
| 31 | # (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
|
---|
| 32 | # 作権表示,この利用条件および下記の無保証規定を掲載すること.
|
---|
| 33 | # (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
|
---|
| 34 | # 報告すること.
|
---|
| 35 | # (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
|
---|
| 36 | # 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
|
---|
| 37 | # また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
|
---|
| 38 | # 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
|
---|
| 39 | # 免責すること.
|
---|
| 40 | #
|
---|
| 41 | # 本ソフトウェアは,AUTOSAR(AUTomotive Open System ARchitecture)仕
|
---|
| 42 | # 様に基づいている.上記の許諾は,AUTOSARの知的財産権を許諾するもので
|
---|
| 43 | # はない.AUTOSARは,AUTOSAR仕様に基づいたソフトウェアを商用目的で利
|
---|
| 44 | # 用する者に対して,AUTOSARパートナーになることを求めている.
|
---|
| 45 | #
|
---|
| 46 | # 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
|
---|
| 47 | # よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
|
---|
| 48 | # に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
|
---|
| 49 | # アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
|
---|
| 50 | # の責任を負わない.
|
---|
| 51 | #
|
---|
| 52 | # $Id: abrex.rb 8481 2014-03-07 03:54:06Z shigihara $
|
---|
| 53 | #
|
---|
| 54 |
|
---|
| 55 | if ($0 == __FILE__)
|
---|
| 56 | TOOL_ROOT = File.expand_path(File.dirname(__FILE__) + "/")
|
---|
| 57 | $LOAD_PATH.unshift(TOOL_ROOT)
|
---|
| 58 | end
|
---|
| 59 |
|
---|
| 60 | require "pp"
|
---|
| 61 | require "yaml"
|
---|
| 62 | require "optparse"
|
---|
| 63 | require "kconv.rb"
|
---|
| 64 | require "rexml/document.rb"
|
---|
| 65 | include REXML
|
---|
| 66 |
|
---|
| 67 | ######################################################################
|
---|
| 68 | # 定数定義
|
---|
| 69 | ######################################################################
|
---|
| 70 | VERSION = "1.1.0"
|
---|
| 71 | VER_INFO = " Generated by ABREX Ver. #{VERSION} "
|
---|
| 72 | XML_ROOT_PATH = "/AUTOSAR/EcucDefs/"
|
---|
| 73 | XML_EDITION = "4.2.0"
|
---|
| 74 | XML_SNAME = "SHORT-NAME"
|
---|
| 75 | XML_PARAM = "PARAMETER-VALUES"
|
---|
| 76 | XML_REFER = "REFERENCE-VALUES"
|
---|
| 77 | XML_SUB = "SUB-CONTAINERS"
|
---|
| 78 | XML_AUTOSAR_FIXED_ATT = {"xmlns" => "http://autosar.org/schema/r4.0",
|
---|
| 79 | "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
|
---|
| 80 | "xsi:schemaLocation" => "http://autosar.org/schema/r4.0 AUTOSAR_4-0-3_STRICT.xsd"}
|
---|
| 81 |
|
---|
| 82 | # パラメータデータ型種別格納ハッシュ
|
---|
| 83 | # (これ以外はすべてECUC-NUMERICAL-PARAM-VALUE)
|
---|
| 84 | XML_VALUE_TYPE = {"ECUC-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE",
|
---|
| 85 | "ECUC-FOREIGN-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE",
|
---|
| 86 | "ECUC-SYMBOLIC-NAME-REFERENCE-DEF" => "ECUC-REFERENCE-VALUE",
|
---|
| 87 | "ECUC-INSTANCE-REFERENCE-DEF" => "ECUC-INSTANCE-REFERENCE-VALUE",
|
---|
| 88 | "ECUC-CHOICE-REFERENCE-DEF" => "ECUC-CHOICE-REFERENCE-DEF",
|
---|
| 89 | "ECUC-ENUMERATION-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
|
---|
| 90 | "ECUC-STRING-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
|
---|
| 91 | "ECUC-MULTILINE-STRING-PARAM-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
|
---|
| 92 | "ECUC-FUNCTION-NAME-DEF" => "ECUC-TEXTUAL-PARAM-VALUE",
|
---|
| 93 | "ECUC-LINKER-SYMBOL-DEF" => "ECUC-TEXTUAL-PARAM-VALUE"}
|
---|
| 94 |
|
---|
| 95 | # インスタンス参照型の特別コンテナ
|
---|
| 96 | XML_INSTANCE_REF_CONTAINER = {"EcucPartitionSoftwareComponentInstanceRef" =>
|
---|
| 97 | {"CONTEXT-ELEMENT-REF" => "ROOT-SW-COMPOSITION-PROTOTYPE",
|
---|
| 98 | "TARGET-REF" => "SW-COMPONENT-PROTOTYPE"}}
|
---|
| 99 |
|
---|
| 100 | ######################################################################
|
---|
| 101 | # YAML → XML 実行機能
|
---|
| 102 | ######################################################################
|
---|
| 103 | def YamlToXml(aArgData, sEcuExtractRef)
|
---|
| 104 | # 各パラメータのデータ型定義(-pオプションで生成したものを使用する)
|
---|
| 105 | sFileName = "#{TOOL_ROOT}/param_info.yaml"
|
---|
| 106 | if (!File.exist?(sFileName))
|
---|
| 107 | abort("#{sFileName} not found !!")
|
---|
| 108 | end
|
---|
| 109 | hParamInfo = YAML.load_file(sFileName)
|
---|
| 110 | # ハッシュでない(YAMLでない)場合エラー
|
---|
| 111 | if (!hParamInfo.is_a?(Hash))
|
---|
| 112 | abort("not YAML file !! [#{sFileName}]")
|
---|
| 113 | end
|
---|
| 114 |
|
---|
| 115 | # 外部参照先のデータ型格納ハッシュを分離
|
---|
| 116 | $hForeignRefType = hParamInfo.delete(:FOREIGN_REF_TYPE)
|
---|
| 117 |
|
---|
| 118 | # インスタンス参照先のデータ型を保持
|
---|
| 119 | $aInstanceRefType = hParamInfo["ECUC-INSTANCE-REFERENCE-DEF"]
|
---|
| 120 |
|
---|
| 121 | # コンテナ名変換テーブル
|
---|
| 122 | $hEcuc = {}
|
---|
| 123 | $hDest = {}
|
---|
| 124 |
|
---|
| 125 | hParamInfo.each{|sType, aParam|
|
---|
| 126 | aParam.each{|sName|
|
---|
| 127 | if (XML_VALUE_TYPE.has_key?(sType))
|
---|
| 128 | $hEcuc[sName] = XML_VALUE_TYPE[sType]
|
---|
| 129 | else
|
---|
| 130 | $hEcuc[sName] = "ECUC-NUMERICAL-PARAM-VALUE"
|
---|
| 131 | end
|
---|
| 132 | $hDest[sName] = sType
|
---|
| 133 | }
|
---|
| 134 | }
|
---|
| 135 |
|
---|
| 136 | # 参照型のパラメータ一覧
|
---|
| 137 | $hReferenceParam = hParamInfo["ECUC-REFERENCE-DEF"] + hParamInfo["ECUC-FOREIGN-REFERENCE-DEF"] + hParamInfo["ECUC-SYMBOLIC-NAME-REFERENCE-DEF"] + hParamInfo["ECUC-INSTANCE-REFERENCE-DEF"]
|
---|
| 138 |
|
---|
| 139 | # 与えられた全YAMLをマージする
|
---|
| 140 | hYaml = {}
|
---|
| 141 | sArxmlName = nil
|
---|
| 142 | aArgData.each{|sFileName|
|
---|
| 143 | # ファイルが存在しない場合エラー
|
---|
| 144 | if (!File.exist?(sFileName))
|
---|
| 145 | abort("Argument error !! [#{sFileName}]")
|
---|
| 146 | end
|
---|
| 147 |
|
---|
| 148 | # 出力ファイル名作成(複数ある場合,最初のファイル名を採用する)
|
---|
| 149 | if (File.extname(sFileName) == ".yaml")
|
---|
| 150 | if (sArxmlName.nil?())
|
---|
| 151 | sArxmlName = File.dirname(sFileName) + "/" + File.basename(sFileName, ".yaml") + ".arxml"
|
---|
| 152 | end
|
---|
| 153 | else
|
---|
| 154 | abort("not YAML file name !! [#{sFileName}]")
|
---|
| 155 | end
|
---|
| 156 |
|
---|
| 157 | hTmpData = YAML.load(File.read(sFileName).toutf8())
|
---|
| 158 | # ハッシュでない(YAMLでない)場合エラー
|
---|
| 159 | if (!hTmpData.is_a?(Hash))
|
---|
| 160 | abort("not YAML file !! [#{sFileName}]")
|
---|
| 161 | end
|
---|
| 162 |
|
---|
| 163 | # 読み込んだデータをマージしていく
|
---|
| 164 | YamlToXml_merge_hash(hYaml, hTmpData)
|
---|
| 165 | }
|
---|
| 166 |
|
---|
| 167 | cXmlInfo = Document.new()
|
---|
| 168 | cXmlInfo.add(XMLDecl.new("1.0", "UTF-8"))
|
---|
| 169 | REXML::Comment.new(VER_INFO, cXmlInfo)
|
---|
| 170 | cXmlAutosar = cXmlInfo.add_element("AUTOSAR", XML_AUTOSAR_FIXED_ATT)
|
---|
| 171 | cXmlArPackages = cXmlAutosar.add_element("AR-PACKAGES")
|
---|
| 172 |
|
---|
| 173 | # IMPLEMENTATION-DATA-TYPE格納ハッシュを分離して先に登録
|
---|
| 174 | hImplDataType = hYaml.delete("IMPLEMENTATION-DATA-TYPE")
|
---|
| 175 | if (!hImplDataType.nil?())
|
---|
| 176 | cXmlArPackage = cXmlArPackages.add_element("AR-PACKAGE")
|
---|
| 177 | cXmlArPackage.add_element(XML_SNAME).add_text("ImplementationDataTypes")
|
---|
| 178 | cXmlElements = cXmlArPackage.add_element("ELEMENTS")
|
---|
| 179 | hImplDataType.each{|sShortName, hData|
|
---|
| 180 | cXmlEcucModuleConfVal = cXmlElements.add_element("IMPLEMENTATION-DATA-TYPE")
|
---|
| 181 | cXmlEcucModuleConfVal.add_element(XML_SNAME).add_text(sShortName)
|
---|
| 182 | cXmlEcucModuleConfVal.add_element("CATEGORY").add_text(hData["CATEGORY"])
|
---|
| 183 | }
|
---|
| 184 | end
|
---|
| 185 |
|
---|
| 186 | aModulePaths = []
|
---|
| 187 | hYaml.each{|sPackageName, hPackageData|
|
---|
| 188 | cXmlArPackage = cXmlArPackages.add_element("AR-PACKAGE")
|
---|
| 189 | cXmlArPackage.add_element(XML_SNAME).add_text(sPackageName)
|
---|
| 190 | cXmlElements = cXmlArPackage.add_element("ELEMENTS")
|
---|
| 191 |
|
---|
| 192 | hPackageData.each{|sEcucModuleName, hEcucModuleData|
|
---|
| 193 | aModulePaths.push("/#{sPackageName}/#{sEcucModuleName}")
|
---|
| 194 | cXmlEcucModuleConfVal = cXmlElements.add_element("ECUC-MODULE-CONFIGURATION-VALUES")
|
---|
| 195 | cXmlEcucModuleConfVal.add_element(XML_SNAME).add_text(sEcucModuleName)
|
---|
| 196 | cXmlEcucModuleConfVal.add_element("DEFINITION-REF", {"DEST" => "ECUC-MODULE-DEF"}).add_text(XML_ROOT_PATH + sEcucModuleName)
|
---|
| 197 | cXmlEcucModuleConfVal.add_element("ECUC-DEF-EDITION").add_text(XML_EDITION)
|
---|
| 198 | cXmlEcucModuleConfVal.add_element("IMPLEMENTATION-CONFIG-VARIANT").add_text("VARIANT-PRE-COMPILE")
|
---|
| 199 | cXmlContainers = cXmlEcucModuleConfVal.add_element("CONTAINERS")
|
---|
| 200 |
|
---|
| 201 | # 各パラメータ用コンテナを作成する
|
---|
| 202 | hEcucModuleData.each{|sShortName, hParamInfo|
|
---|
| 203 | # DefinitionRef補完
|
---|
| 204 | if (!hParamInfo.has_key?("DefinitionRef"))
|
---|
| 205 | hParamInfo["DefinitionRef"] = sShortName
|
---|
| 206 | end
|
---|
| 207 |
|
---|
| 208 | cContainer = YamlToXml_make_container(sShortName, hParamInfo, XML_ROOT_PATH + sEcucModuleName)
|
---|
| 209 | cXmlContainers.add_element(cContainer)
|
---|
| 210 | }
|
---|
| 211 | }
|
---|
| 212 | }
|
---|
| 213 |
|
---|
| 214 | # ECU-EXTRACT-REF指定がある場合、<ECUC-VALUE-COLLECTION>を追加する
|
---|
| 215 | if (!sEcuExtractRef.nil?())
|
---|
| 216 | cXmlArPackage = cXmlArPackages.add_element("AR-PACKAGE")
|
---|
| 217 | cXmlArPackage.add_element(XML_SNAME).add_text("EcucValueCollection")
|
---|
| 218 | cXmlElements = cXmlArPackage.add_element("ELEMENTS")
|
---|
| 219 | cXmlEcucValueCollection = cXmlElements.add_element("ECUC-VALUE-COLLECTION")
|
---|
| 220 | cXmlEcucValueCollection.add_element(XML_SNAME).add_text("EcucValueCollection")
|
---|
| 221 | cXmlEcucValueCollection.add_element("ECU-EXTRACT-REF", {"DEST" => "SYSTEM"}).add_text(sEcuExtractRef)
|
---|
| 222 | cXmlEcucValues = cXmlEcucValueCollection.add_element("ECUC-VALUES")
|
---|
| 223 | aModulePaths.each{|sPath|
|
---|
| 224 | cTemp = cXmlEcucValues.add_element("ECUC-MODULE-CONFIGURATION-VALUES-REF-CONDITIONAL")
|
---|
| 225 | cTemp.add_element("ECUC-MODULE-CONFIGURATION-VALUES-REF", {"DEST" => "ECUC-MODULE-CONFIGURATION-VALUES"}).add_text(sPath)
|
---|
| 226 | }
|
---|
| 227 | end
|
---|
| 228 |
|
---|
| 229 | # XML文字列生成
|
---|
| 230 | sXmlCode = String.new()
|
---|
| 231 | cXmlInfo.write(sXmlCode, 2, false)
|
---|
| 232 |
|
---|
| 233 | # XML宣言の属性のコーテーションをダブルに出来ない(?)ため,ここで置換する
|
---|
| 234 | sXmlCode.gsub!("'", "\"")
|
---|
| 235 |
|
---|
| 236 | # ダブルコーテーションが"に変換されるのを抑止できない(?)ため,ここで置換する
|
---|
| 237 | sXmlCode.gsub!(""", "\"")
|
---|
| 238 |
|
---|
| 239 | # 値を定義する部分だけインデントを入れないように出来ない(?)ため,ここで置換する
|
---|
| 240 | sXmlCode.gsub!(/>\n[\s]+([\w\.\[\]\(\)\+-\/\*~&;\s]*?)\n[\s]+</, ">\\1<")
|
---|
| 241 |
|
---|
| 242 | # XMLDeclのコンストラクタではEUC-JPを指定出来ない(?)ため,ここで文字コードを置換する
|
---|
| 243 | sXmlCode.sub!("UTF-8", "EUC-JP")
|
---|
| 244 |
|
---|
| 245 | # インデントをタブに出来ない(?)ため,ここで置換する
|
---|
| 246 | sXmlCode.gsub!(" ", "\t")
|
---|
| 247 |
|
---|
| 248 | # ファイル出力
|
---|
| 249 | #puts(sXmlCode)
|
---|
| 250 | File.open(sArxmlName, "w") {|io|
|
---|
| 251 | io.puts(sXmlCode)
|
---|
| 252 | }
|
---|
| 253 |
|
---|
| 254 | puts("Generated #{sArxmlName}")
|
---|
| 255 | end
|
---|
| 256 |
|
---|
| 257 | # ハッシュマージ関数
|
---|
| 258 | def YamlToXml_merge_hash(hBase, hAdd)
|
---|
| 259 | hAdd.each{|sKey, xVal|
|
---|
| 260 | # 追加先にキーが存在しなければ,そのまま追加するのみ
|
---|
| 261 | if (!hBase.has_key?(sKey))
|
---|
| 262 | hBase[sKey] = xVal
|
---|
| 263 | # 同じキーで値が違う場合
|
---|
| 264 | elsif (hBase[sKey] != hAdd[sKey])
|
---|
| 265 | # ハッシュ同士であれば,再帰で追加
|
---|
| 266 | if (hBase[sKey].is_a?(Hash) && hAdd[sKey].is_a?(Hash))
|
---|
| 267 | YamlToXml_merge_hash(hBase[sKey], hAdd[sKey])
|
---|
| 268 | # 追加先が配列であれば,配列に合わせて追加
|
---|
| 269 | elsif (hBase[sKey].is_a?(Array))
|
---|
| 270 | if (hAdd[sKey].is_a?(Array))
|
---|
| 271 | hBase[sKey].concat(hAdd[sKey])
|
---|
| 272 | else
|
---|
| 273 | hBase[sKey].push(hAdd[sKey])
|
---|
| 274 | end
|
---|
| 275 | # 追加先が配列でなければ,配列にしてから追加
|
---|
| 276 | elsif (hAdd[sKey].is_a?(Array))
|
---|
| 277 | hBase[sKey] = [hBase[sKey]]
|
---|
| 278 | hBase[sKey].concat(hAdd[sKey])
|
---|
| 279 | # どちらも配列でない場合,配列として両方をマージ
|
---|
| 280 | else
|
---|
| 281 | hBase[sKey] = [hBase[sKey]]
|
---|
| 282 | hBase[sKey].push(hAdd[sKey])
|
---|
| 283 | end
|
---|
| 284 | else
|
---|
| 285 | # 同じパラメータの場合,何もしない
|
---|
| 286 | end
|
---|
| 287 | }
|
---|
| 288 | end
|
---|
| 289 |
|
---|
| 290 | # コンテナ作成関数
|
---|
| 291 | def YamlToXml_make_container(sShortName, hParamInfo, sPath)
|
---|
| 292 | # 一律"ECUC-CONTAINER-VALUE"を入れた状態で初期化
|
---|
| 293 | cContainer = Element.new().add_element("ECUC-CONTAINER-VALUE")
|
---|
| 294 |
|
---|
| 295 | # ショートネーム追加
|
---|
| 296 | cContainer.add_element(XML_SNAME).add_text(sShortName)
|
---|
| 297 |
|
---|
| 298 | # コンテナまでのパス追加
|
---|
| 299 | cContainer.add_element("DEFINITION-REF", {"DEST" => "ECUC-PARAM-CONF-CONTAINER-DEF"}).add_text("#{sPath}/#{hParamInfo["DefinitionRef"]}")
|
---|
| 300 |
|
---|
| 301 | # 各パラメータ設定(パラメータが無い場合は不要)
|
---|
| 302 | hCheck= {}
|
---|
| 303 | if (hParamInfo.size() != 1)
|
---|
| 304 | hCheck[XML_PARAM] = false
|
---|
| 305 | hCheck[XML_REFER] = false
|
---|
| 306 | hCheck[XML_SUB] = false
|
---|
| 307 |
|
---|
| 308 | # まず参照型,サブコンテナ以外を生成(AUTOSARスキーマ制約)
|
---|
| 309 | hParamInfo.each{|sParamName, sahValue|
|
---|
| 310 | if ((sParamName == "DefinitionRef") || (sahValue.is_a?(Hash)))
|
---|
| 311 | next
|
---|
| 312 | end
|
---|
| 313 |
|
---|
| 314 | # 参照型,サブコンテナ以外のパラメータ
|
---|
| 315 | if (!$hReferenceParam.include?(sParamName))
|
---|
| 316 | # パラメータ名チェック
|
---|
| 317 | if (!$hEcuc.has_key?(sParamName) || !$hDest.has_key?(sParamName))
|
---|
| 318 | abort("Unknown parameter: #{sParamName}")
|
---|
| 319 | end
|
---|
| 320 |
|
---|
| 321 | if (hCheck[XML_PARAM] == false)
|
---|
| 322 | cContainer.add_element(XML_PARAM)
|
---|
| 323 | hCheck[XML_PARAM] = true
|
---|
| 324 | end
|
---|
| 325 |
|
---|
| 326 | # 多重度*対応
|
---|
| 327 | aTemp = []
|
---|
| 328 | if (sahValue.is_a?(Array))
|
---|
| 329 | aTemp = sahValue
|
---|
| 330 | else
|
---|
| 331 | aTemp.push(sahValue)
|
---|
| 332 | end
|
---|
| 333 | aTemp.each{|sVal|
|
---|
| 334 | cParamContainer_ = Element.new()
|
---|
| 335 | cParamContainer = cParamContainer_.add_element($hEcuc[sParamName])
|
---|
| 336 | cParamContainer.add_element("DEFINITION-REF", {"DEST" => $hDest[sParamName]}).add_text("#{sPath}/#{hParamInfo["DefinitionRef"]}/#{sParamName}")
|
---|
| 337 | cParamContainer.add_element("VALUE").add_text(sVal.to_s())
|
---|
| 338 | cContainer.elements[XML_PARAM].add_element(cParamContainer)
|
---|
| 339 | }
|
---|
| 340 | end
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 | # 次に参照型を生成(AUTOSARスキーマ制約)
|
---|
| 344 | hParamInfo.each{|sParamName, sahValue|
|
---|
| 345 | if ((sParamName == "DefinitionRef") || (sahValue.is_a?(Hash)))
|
---|
| 346 | next
|
---|
| 347 | end
|
---|
| 348 |
|
---|
| 349 | # インスタンス参照型の場合
|
---|
| 350 | if ($aInstanceRefType.include?(sParamName))
|
---|
| 351 | if (!sahValue.is_a?(Array))
|
---|
| 352 | abort("#{sParamName} must be Array !!")
|
---|
| 353 | end
|
---|
| 354 | # 未サポートコンテナは生成できないためエラーとする
|
---|
| 355 | if (!XML_INSTANCE_REF_CONTAINER.has_key?(sParamName))
|
---|
| 356 | abort("#{sParamName} is not supported !!")
|
---|
| 357 | end
|
---|
| 358 | if (hCheck[XML_REFER] == false)
|
---|
| 359 | cContainer.add_element(XML_REFER)
|
---|
| 360 | hCheck[XML_REFER] = true
|
---|
| 361 | end
|
---|
| 362 |
|
---|
| 363 | # 多重度*対応(2次元配列かチェック)
|
---|
| 364 | aTemp = []
|
---|
| 365 | if (sahValue[0].is_a?(Array))
|
---|
| 366 | aTemp = sahValue
|
---|
| 367 | else
|
---|
| 368 | aTemp.push(sahValue)
|
---|
| 369 | end
|
---|
| 370 | aTemp.each{|aVal|
|
---|
| 371 | cParamContainer_ = Element.new()
|
---|
| 372 | cParamContainer = cParamContainer_.add_element($hEcuc[sParamName])
|
---|
| 373 | cParamContainer.add_element("DEFINITION-REF", {"DEST" => $hDest[sParamName]}).add_text("#{sPath}/#{hParamInfo["DefinitionRef"]}/#{sParamName}")
|
---|
| 374 | cInstanceRef = cParamContainer.add_element("VALUE-IREF")
|
---|
| 375 | aVal.each{|hVal|
|
---|
| 376 | XML_INSTANCE_REF_CONTAINER[sParamName].each{|sParam, sDest|
|
---|
| 377 | if (hVal.has_key?(sParam))
|
---|
| 378 | cInstanceRef.add_element(sParam, {"DEST" => sDest}).add_text(hVal[sParam].to_s())
|
---|
| 379 | end
|
---|
| 380 | }
|
---|
| 381 | }
|
---|
| 382 | cContainer.elements[XML_REFER].add_element(cParamContainer)
|
---|
| 383 | }
|
---|
| 384 |
|
---|
| 385 | # 参照型の場合
|
---|
| 386 | elsif ($hReferenceParam.include?(sParamName))
|
---|
| 387 | if (hCheck[XML_REFER] == false)
|
---|
| 388 | cContainer.add_element(XML_REFER)
|
---|
| 389 | hCheck[XML_REFER] = true
|
---|
| 390 | end
|
---|
| 391 |
|
---|
| 392 | # 多重度*対応
|
---|
| 393 | aTemp = []
|
---|
| 394 | if (sahValue.is_a?(Array))
|
---|
| 395 | aTemp = sahValue
|
---|
| 396 | else
|
---|
| 397 | aTemp.push(sahValue)
|
---|
| 398 | end
|
---|
| 399 | aTemp.each{|sVal|
|
---|
| 400 | cParamContainer_ = Element.new()
|
---|
| 401 | cParamContainer = cParamContainer_.add_element($hEcuc[sParamName])
|
---|
| 402 | cParamContainer.add_element("DEFINITION-REF", {"DEST" => $hDest[sParamName]}).add_text("#{sPath}/#{hParamInfo["DefinitionRef"]}/#{sParamName}")
|
---|
| 403 | if (!$hForeignRefType.nil? && $hForeignRefType.has_key?(sParamName))
|
---|
| 404 | cParamContainer.add_element("VALUE-REF", {"DEST" => $hForeignRefType[sParamName]}).add_text(sVal.to_s())
|
---|
| 405 | else
|
---|
| 406 | cParamContainer.add_element("VALUE-REF", {"DEST" => "ECUC-CONTAINER-VALUE"}).add_text(sVal.to_s())
|
---|
| 407 | end
|
---|
| 408 | cContainer.elements[XML_REFER].add_element(cParamContainer)
|
---|
| 409 | }
|
---|
| 410 | end
|
---|
| 411 | }
|
---|
| 412 |
|
---|
| 413 | # 最後にサブコンテナを生成
|
---|
| 414 | hParamInfo.each{|sParamName, sahValue|
|
---|
| 415 | if ((sParamName == "DefinitionRef") || (!sahValue.is_a?(Hash)))
|
---|
| 416 | next
|
---|
| 417 | end
|
---|
| 418 |
|
---|
| 419 | if (hCheck[XML_SUB] == false)
|
---|
| 420 | cContainer.add_element(XML_SUB)
|
---|
| 421 | hCheck[XML_SUB] = true
|
---|
| 422 | end
|
---|
| 423 |
|
---|
| 424 | # DefinitionRef補完
|
---|
| 425 | if (!sahValue.has_key?("DefinitionRef"))
|
---|
| 426 | sahValue["DefinitionRef"] = sParamName
|
---|
| 427 | end
|
---|
| 428 |
|
---|
| 429 | # 再帰でサブコンテナを作成する
|
---|
| 430 | cContainer.elements[XML_SUB].add_element(YamlToXml_make_container(sParamName, sahValue, "#{sPath}/#{hParamInfo["DefinitionRef"]}"))
|
---|
| 431 | }
|
---|
| 432 | end
|
---|
| 433 |
|
---|
| 434 | return cContainer
|
---|
| 435 | end
|
---|
| 436 |
|
---|
| 437 |
|
---|
| 438 | ######################################################################
|
---|
| 439 | # XML → YAML 実行機能
|
---|
| 440 | ######################################################################
|
---|
| 441 | def XmlToYaml(sFirstFile, aExtraFile)
|
---|
| 442 | aExtraFile.unshift(sFirstFile)
|
---|
| 443 | aExtraFile.each{|sFileName|
|
---|
| 444 | # ファイルが存在しない場合エラー
|
---|
| 445 | if (!File.exist?(sFileName))
|
---|
| 446 | abort("Argument error !! [#{sFileName}]")
|
---|
| 447 | end
|
---|
| 448 |
|
---|
| 449 | # 出力ファイル名作成
|
---|
| 450 | if (File.extname(sFileName) == ".arxml")
|
---|
| 451 | sYamlName = File.dirname(sFileName) + "/" + File.basename(sFileName, ".arxml") + ".yaml"
|
---|
| 452 | else
|
---|
| 453 | abort("not ARXML file !! [#{sFileName}]")
|
---|
| 454 | end
|
---|
| 455 |
|
---|
| 456 | # XMLライブラリでの読み込み
|
---|
| 457 | cXmlData = REXML::Document.new(open(sFileName))
|
---|
| 458 |
|
---|
| 459 | hResult = {}
|
---|
| 460 |
|
---|
| 461 | cXmlData.elements.each("AUTOSAR/AR-PACKAGES/AR-PACKAGE"){|cElement1|
|
---|
| 462 | cElement1.elements.each("ELEMENTS/ECUC-MODULE-CONFIGURATION-VALUES"){|cElement2|
|
---|
| 463 | sPackageName = cElement1.elements["SHORT-NAME"].text()
|
---|
| 464 | if (!hResult.has_key?(sPackageName))
|
---|
| 465 | hResult[sPackageName] = {}
|
---|
| 466 | end
|
---|
| 467 |
|
---|
| 468 | sModuleName = cElement2.elements["SHORT-NAME"].text()
|
---|
| 469 | hResult[sPackageName][sModuleName] = {}
|
---|
| 470 |
|
---|
| 471 | cElement2.elements.each("CONTAINERS/ECUC-CONTAINER-VALUE"){|cElement3|
|
---|
| 472 | XmlToYaml_parse_parameter(cElement3, hResult[sPackageName][sModuleName])
|
---|
| 473 | }
|
---|
| 474 | }
|
---|
| 475 | }
|
---|
| 476 |
|
---|
| 477 | # YAMLファイル出力
|
---|
| 478 | open(sYamlName, "w") do |io|
|
---|
| 479 | YAML.dump(hResult, io)
|
---|
| 480 | end
|
---|
| 481 |
|
---|
| 482 | # YAML整形処理
|
---|
| 483 | # ・先頭の区切り文字削除
|
---|
| 484 | # ・コーテーションの削除
|
---|
| 485 | # ・配列のインデント整列
|
---|
| 486 | sFileData = File.read(sYamlName)
|
---|
| 487 | sFileData.gsub!(/^---$/, "")
|
---|
| 488 | sFileData.gsub!("'", "")
|
---|
| 489 | sFileData.gsub!(/^(\s+)-(\s.*)$/, "\\1 -\\2")
|
---|
| 490 | File.write(sYamlName, sFileData)
|
---|
| 491 |
|
---|
| 492 | puts("Generated #{sYamlName}")
|
---|
| 493 | }
|
---|
| 494 | end
|
---|
| 495 |
|
---|
| 496 | # コンテナパース関数
|
---|
| 497 | def XmlToYaml_parse_parameter(cElement, hTarget)
|
---|
| 498 | sParamShortName = cElement.elements["SHORT-NAME"].text()
|
---|
| 499 | sParamDefName = cElement.elements["DEFINITION-REF"].text().split("/")[-1]
|
---|
| 500 | hTarget[sParamShortName] = {}
|
---|
| 501 | if (sParamShortName != sParamDefName)
|
---|
| 502 | hTarget[sParamShortName]["DefinitionRef"] = sParamDefName
|
---|
| 503 | end
|
---|
| 504 |
|
---|
| 505 | # パラメータ
|
---|
| 506 | cElement.elements.each("PARAMETER-VALUES"){|cElementC|
|
---|
| 507 | ["ECUC-NUMERICAL-PARAM-VALUE", "ECUC-TEXTUAL-PARAM-VALUE"].each{|sParamValue|
|
---|
| 508 | cElementC.elements.each(sParamValue){|cElementG|
|
---|
| 509 | sName = cElementG.elements["DEFINITION-REF"].text().split("/")[-1]
|
---|
| 510 | sValue = cElementG.elements["VALUE"].text()
|
---|
| 511 | # 複数多重度対応
|
---|
| 512 | if (hTarget[sParamShortName].has_key?(sName))
|
---|
| 513 | if (hTarget[sParamShortName][sName].is_a?(Array))
|
---|
| 514 | # 既に複数ある場合は配列に追加
|
---|
| 515 | hTarget[sParamShortName][sName].push(sValue)
|
---|
| 516 | else
|
---|
| 517 | # 1つだけ定義されていた場合は配列に変更
|
---|
| 518 | sTemp = hTarget[sParamShortName][sName]
|
---|
| 519 | hTarget[sParamShortName][sName] = [sTemp, sValue]
|
---|
| 520 | end
|
---|
| 521 | else
|
---|
| 522 | hTarget[sParamShortName][sName] = sValue
|
---|
| 523 | end
|
---|
| 524 | }
|
---|
| 525 | }
|
---|
| 526 | }
|
---|
| 527 |
|
---|
| 528 | # 参照,外部参照,選択参照
|
---|
| 529 | cElement.elements.each("REFERENCE-VALUES/ECUC-REFERENCE-VALUE"){|cElementC|
|
---|
| 530 | sName = cElementC.elements["DEFINITION-REF"].text().split("/")[-1]
|
---|
| 531 | if (cElementC.elements["VALUE-REF"].nil?)
|
---|
| 532 | abort("<VALUE> is not found in '#{sParamShortName}'")
|
---|
| 533 | end
|
---|
| 534 | sValue = cElementC.elements["VALUE-REF"].text()
|
---|
| 535 | # 複数多重度対応
|
---|
| 536 | if (hTarget[sParamShortName].has_key?(sName))
|
---|
| 537 | if (hTarget[sParamShortName][sName].is_a?(Array))
|
---|
| 538 | # 既に複数ある場合は配列に追加
|
---|
| 539 | hTarget[sParamShortName][sName].push(sValue)
|
---|
| 540 | else
|
---|
| 541 | # 1つだけ定義されていた場合は配列に変更
|
---|
| 542 | sTemp = hTarget[sParamShortName][sName]
|
---|
| 543 | hTarget[sParamShortName][sName] = [sTemp, sValue]
|
---|
| 544 | end
|
---|
| 545 | else
|
---|
| 546 | hTarget[sParamShortName][sName] = sValue
|
---|
| 547 | end
|
---|
| 548 | }
|
---|
| 549 |
|
---|
| 550 | # インスタンス参照
|
---|
| 551 | cElement.elements.each("REFERENCE-VALUES/ECUC-INSTANCE-REFERENCE-VALUE"){|cElementC|
|
---|
| 552 | sName = cElementC.elements["DEFINITION-REF"].text().split("/")[-1]
|
---|
| 553 | hTarget[sParamShortName][sName] = []
|
---|
| 554 | hTarget[sParamShortName][sName].push({"CONTEXT-ELEMENT-REF" => cElementC.elements["VALUE-IREF"].elements["CONTEXT-ELEMENT-REF"].text()})
|
---|
| 555 | hTarget[sParamShortName][sName].push({"TARGET-REF" => cElementC.elements["VALUE-IREF"].elements["TARGET-REF"].text()})
|
---|
| 556 | }
|
---|
| 557 |
|
---|
| 558 | # サブコンテナ(再帰呼出し)
|
---|
| 559 | cElement.elements.each("SUB-CONTAINERS/ECUC-CONTAINER-VALUE"){|cElementC|
|
---|
| 560 | XmlToYaml_parse_parameter(cElementC, hTarget[sParamShortName])
|
---|
| 561 | }
|
---|
| 562 | end
|
---|
| 563 |
|
---|
| 564 |
|
---|
| 565 | ######################################################################
|
---|
| 566 | # AUTOSARパラメータ情報ファイル作成
|
---|
| 567 | ######################################################################
|
---|
| 568 | def MakeParamInfo(sFileName)
|
---|
| 569 | # ファイルが存在しない場合エラー
|
---|
| 570 | if (!File.exist?(sFileName))
|
---|
| 571 | abort("Argument error !! [#{sFileName}]")
|
---|
| 572 | end
|
---|
| 573 |
|
---|
| 574 | sParamFileName = File.dirname(sFileName) + "/param_info.yaml"
|
---|
| 575 |
|
---|
| 576 | # 読み込み対象モジュール
|
---|
| 577 | aTargetModule = ["Rte", "Os", "Com", "PduR", "CanIf", "Can", "EcuC", "EcuM", "WdgM", "WdgIf", "Wdg", "Dem"]
|
---|
| 578 |
|
---|
| 579 | # XMLライブラリでの読み込み
|
---|
| 580 | cXmlData = REXML::Document.new(open(sFileName))
|
---|
| 581 |
|
---|
| 582 | # 外部参照先のデータ型格納ハッシュ
|
---|
| 583 | $hForeignRefType = {}
|
---|
| 584 |
|
---|
| 585 | # パース結果格納ハッシュ初期化(NCES仕様コンテナは予め設定)
|
---|
| 586 | sNcesContainer = <<-EOS
|
---|
| 587 | ECUC-ENUMERATION-PARAM-DEF:
|
---|
| 588 | - OsViolationHandlingLevel
|
---|
| 589 | - OsTimingProtectionLevel
|
---|
| 590 | - OsMemoryProtectionLevel
|
---|
| 591 | - OsMemorySectionInitialize
|
---|
| 592 | - OsIsrInterruptSource
|
---|
| 593 | - OsInterCoreInterruptInterruptSource
|
---|
| 594 | - OsSpinlockLockMethod
|
---|
| 595 | - WdgTriggerMode
|
---|
| 596 | - WdgTimeoutReaction
|
---|
| 597 | ECUC-INTEGER-PARAM-DEF:
|
---|
| 598 | - OsMasterCoreId
|
---|
| 599 | - OsHookStackSize
|
---|
| 600 | - OsHookStackStartAddress
|
---|
| 601 | - OsHookStackCoreAssignment
|
---|
| 602 | - OsOsStackSize
|
---|
| 603 | - OsOsStackStartAddress
|
---|
| 604 | - OsOsStackCoreAssignment
|
---|
| 605 | - OsNonTrustedHookStackSize
|
---|
| 606 | - OsNonTrustedHookStackStartAddress
|
---|
| 607 | - OsNonTrustedHookStackCoreAssignment
|
---|
| 608 | - OsTaskStackSize
|
---|
| 609 | - OsTaskStackStartAddress
|
---|
| 610 | - OsTaskSystemStackSize
|
---|
| 611 | - OsTaskSystemStackStartAddress
|
---|
| 612 | - OsIsrInterruptNumber
|
---|
| 613 | - OsIsrInterruptPriority
|
---|
| 614 | - OsIsrStackSize
|
---|
| 615 | - OsTrustedFunctionStackSize
|
---|
| 616 | - OsInterCoreInterruptStackSize
|
---|
| 617 | - OsInterCoreInterruptStackStartAddress
|
---|
| 618 | - OsMemoryRegionStartAddress
|
---|
| 619 | - OsMemoryRegionSize
|
---|
| 620 | - OsMemoryAreaSize
|
---|
| 621 | - OsStandardMemoryCoreAssignment
|
---|
| 622 | - OsIsrMaxFrequency
|
---|
| 623 | - WdgWindowOpenRate
|
---|
| 624 | ECUC-STRING-PARAM-DEF:
|
---|
| 625 | - OsIncludeFileName
|
---|
| 626 | - OsMemoryRegionName
|
---|
| 627 | - OsMemoryAreaStartAddress
|
---|
| 628 | - OsMemorySectionName
|
---|
| 629 | - OsMemoryModuleName
|
---|
| 630 | - OsLinkSectionName
|
---|
| 631 | - OsIocPrimitiveDataType
|
---|
| 632 | - OsIocIncludeFile
|
---|
| 633 | ECUC-BOOLEAN-PARAM-DEF:
|
---|
| 634 | - OsMemoryRegionWriteable
|
---|
| 635 | - OsMemoryAreaWritable
|
---|
| 636 | - OsMemoryAreaReadable
|
---|
| 637 | - OsMemoryAreaExecutable
|
---|
| 638 | - OsMemoryAreaCacheable
|
---|
| 639 | - OsMemoryAreaDevice
|
---|
| 640 | - OsMemorySectionWritable
|
---|
| 641 | - OsMemorySectionReadable
|
---|
| 642 | - OsMemorySectionExecutable
|
---|
| 643 | - OsMemorySectionShort
|
---|
| 644 | - OsMemorySectionCacheable
|
---|
| 645 | - OsMemorySectionDevice
|
---|
| 646 | - OsMemorySectionExport
|
---|
| 647 | - OsMemoryModuleExport
|
---|
| 648 | - OsTaskOsInterruptLockMonitor
|
---|
| 649 | - OsTaskResourceLockMonitor
|
---|
| 650 | ECUC-REFERENCE-DEF:
|
---|
| 651 | - OsStandardMemoryRomRegionRef
|
---|
| 652 | - OsStandardMemoryRamRegionRef
|
---|
| 653 | - OsAppStandardMemoryRomRegionRef
|
---|
| 654 | - OsAppStandardMemoryRamRegionRef
|
---|
| 655 | - OsMemorySectionMemoryRegionRef
|
---|
| 656 | - OsLinkSectionMemoryRegionRef
|
---|
| 657 | - OsResourceLinkedResourceRef
|
---|
| 658 | - OsCounterIsrRef
|
---|
| 659 | - OsAppMemorySectionRef
|
---|
| 660 | - OsAppMemoryModuleRef
|
---|
| 661 | - OsAppMemoryAreaRef
|
---|
| 662 | - OsAppInterCoreInterruptRef
|
---|
| 663 | - OsInterCoreInterruptAccessingApplication
|
---|
| 664 | - OsInterCoreInterruptResourceRef
|
---|
| 665 | - WdgMOsCounterRef
|
---|
| 666 | - OsSystemCycleTimeWindowRef
|
---|
| 667 | ECUC-FLOAT-PARAM-DEF:
|
---|
| 668 | - OsSystemCycleTime
|
---|
| 669 | - OsSystemCycleTimeWindowStart
|
---|
| 670 | - OsSystemCycleTimeWindowLength
|
---|
| 671 | - OsOsInterruptLockBudget
|
---|
| 672 | - OsResourceLockBudget
|
---|
| 673 | - WdgTimeout
|
---|
| 674 | - WdgTriggerInterruptPeriod
|
---|
| 675 | EOS
|
---|
| 676 | $hResult = YAML.load(sNcesContainer)
|
---|
| 677 |
|
---|
| 678 | cXmlData.elements.each("AUTOSAR/AR-PACKAGES/AR-PACKAGE/AR-PACKAGES/AR-PACKAGE/ELEMENTS/ECUC-MODULE-DEF"){|cElement1|
|
---|
| 679 | # 対象モジュールのみを処理する
|
---|
| 680 | if (!aTargetModule.include?(cElement1.elements["SHORT-NAME"].text()))
|
---|
| 681 | next
|
---|
| 682 | end
|
---|
| 683 |
|
---|
| 684 | cElement1.elements.each("CONTAINERS/ECUC-PARAM-CONF-CONTAINER-DEF"){|cElement2|
|
---|
| 685 | MakeParamInfo_parse_parameter(cElement2)
|
---|
| 686 | }
|
---|
| 687 | }
|
---|
| 688 |
|
---|
| 689 | # パラメータ名でソートと重複除去
|
---|
| 690 | hResultSort = {}
|
---|
| 691 | $hResult.each{|sType, aParam|
|
---|
| 692 | hResultSort[sType] = aParam.uniq().sort()
|
---|
| 693 | }
|
---|
| 694 |
|
---|
| 695 | # 外部参照先のデータ型格納ハッシュを結合
|
---|
| 696 | if (!$hForeignRefType.empty?())
|
---|
| 697 | hResultSort[:FOREIGN_REF_TYPE] = $hForeignRefType
|
---|
| 698 | end
|
---|
| 699 |
|
---|
| 700 | # RteSoftwareComponentInstanceRefは外部参照とインスタンス参照の
|
---|
| 701 | # 両方に含まれるが,外部参照として扱う
|
---|
| 702 | hResultSort["ECUC-INSTANCE-REFERENCE-DEF"].delete("RteSoftwareComponentInstanceRef")
|
---|
| 703 |
|
---|
| 704 | # YAMLファイル出力
|
---|
| 705 | open(sParamFileName, "w") do |io|
|
---|
| 706 | YAML.dump(hResultSort, io)
|
---|
| 707 | end
|
---|
| 708 |
|
---|
| 709 | puts("Generated #{sParamFileName}")
|
---|
| 710 | end
|
---|
| 711 |
|
---|
| 712 | # サブコンテナ再帰パース関数
|
---|
| 713 | def MakeParamInfo_parse_sub_container(cElement)
|
---|
| 714 | # "ECUC-PARAM-CONF-CONTAINER-DEF"が登場するまで再帰する
|
---|
| 715 | cElement.elements.each{|cElementC|
|
---|
| 716 | # CHOICEはさらにネストする
|
---|
| 717 | if (cElementC.name == "ECUC-CHOICE-CONTAINER-DEF")
|
---|
| 718 | MakeParamInfo_parse_sub_container(cElementC)
|
---|
| 719 | elsif (cElementC.name == "ECUC-PARAM-CONF-CONTAINER-DEF")
|
---|
| 720 | MakeParamInfo_parse_parameter(cElementC)
|
---|
| 721 | else
|
---|
| 722 | MakeParamInfo_parse_sub_container(cElementC)
|
---|
| 723 | end
|
---|
| 724 | }
|
---|
| 725 | end
|
---|
| 726 |
|
---|
| 727 | # コンテナパース関数
|
---|
| 728 | def MakeParamInfo_parse_parameter(cElement)
|
---|
| 729 | # パラメータ
|
---|
| 730 | cElement.elements.each("PARAMETERS"){|cElementC|
|
---|
| 731 | cElementC.elements.each{|cElementG|
|
---|
| 732 | # 初出のデータ型処理
|
---|
| 733 | if (!$hResult.has_key?(cElementG.name))
|
---|
| 734 | $hResult[cElementG.name] = []
|
---|
| 735 | end
|
---|
| 736 |
|
---|
| 737 | # 取得したパラメータ名を格納する
|
---|
| 738 | $hResult[cElementG.name].push(cElementG.elements["SHORT-NAME"].text())
|
---|
| 739 | }
|
---|
| 740 | }
|
---|
| 741 |
|
---|
| 742 | # 参照
|
---|
| 743 | cElement.elements.each("REFERENCES/ECUC-REFERENCE-DEF"){|cElementC|
|
---|
| 744 | $hResult["ECUC-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
|
---|
| 745 | }
|
---|
| 746 |
|
---|
| 747 | # 外部参照
|
---|
| 748 | cElement.elements.each("REFERENCES/ECUC-FOREIGN-REFERENCE-DEF"){|cElementC|
|
---|
| 749 | # 初出のデータ型処理
|
---|
| 750 | if (!$hResult.has_key?("ECUC-FOREIGN-REFERENCE-DEF"))
|
---|
| 751 | $hResult["ECUC-FOREIGN-REFERENCE-DEF"] = []
|
---|
| 752 | end
|
---|
| 753 | $hResult["ECUC-FOREIGN-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
|
---|
| 754 | $hForeignRefType[cElementC.elements["SHORT-NAME"].text()] = cElementC.elements["DESTINATION-TYPE"].text()
|
---|
| 755 | }
|
---|
| 756 |
|
---|
| 757 | # 選択参照
|
---|
| 758 | cElement.elements.each("REFERENCES/ECUC-CHOICE-REFERENCE-DEF"){|cElementC|
|
---|
| 759 | # 初出のデータ型処理
|
---|
| 760 | if (!$hResult.has_key?("ECUC-CHOICE-REFERENCE-DEF"))
|
---|
| 761 | $hResult["ECUC-CHOICE-REFERENCE-DEF"] = []
|
---|
| 762 | end
|
---|
| 763 | $hResult["ECUC-CHOICE-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
|
---|
| 764 | }
|
---|
| 765 |
|
---|
| 766 | # シンボル参照
|
---|
| 767 | cElement.elements.each("REFERENCES/ECUC-SYMBOLIC-NAME-REFERENCE-DEF"){|cElementC|
|
---|
| 768 | # 初出のデータ型処理
|
---|
| 769 | if (!$hResult.has_key?("ECUC-SYMBOLIC-NAME-REFERENCE-DEF"))
|
---|
| 770 | $hResult["ECUC-SYMBOLIC-NAME-REFERENCE-DEF"] = []
|
---|
| 771 | end
|
---|
| 772 | $hResult["ECUC-SYMBOLIC-NAME-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
|
---|
| 773 | }
|
---|
| 774 |
|
---|
| 775 | # インスタンス参照
|
---|
| 776 | cElement.elements.each("REFERENCES/ECUC-INSTANCE-REFERENCE-DEF"){|cElementC|
|
---|
| 777 | # 初出のデータ型処理
|
---|
| 778 | if (!$hResult.has_key?("ECUC-INSTANCE-REFERENCE-DEF"))
|
---|
| 779 | $hResult["ECUC-INSTANCE-REFERENCE-DEF"] = []
|
---|
| 780 | end
|
---|
| 781 | $hResult["ECUC-INSTANCE-REFERENCE-DEF"].push(cElementC.elements["SHORT-NAME"].text())
|
---|
| 782 | }
|
---|
| 783 |
|
---|
| 784 | # サブコンテナ(再帰呼出し)
|
---|
| 785 | cElement.elements.each("SUB-CONTAINERS"){|cElementC|
|
---|
| 786 | MakeParamInfo_parse_sub_container(cElementC)
|
---|
| 787 | }
|
---|
| 788 | end
|
---|
| 789 |
|
---|
| 790 |
|
---|
| 791 | ######################################################################
|
---|
| 792 | # ジェネレータ用csvファイルの生成
|
---|
| 793 | ######################################################################
|
---|
| 794 | def MakeCsv(sFileName, sTargetModule)
|
---|
| 795 | # ファイルが存在しない場合エラー
|
---|
| 796 | if (!File.exist?(sFileName))
|
---|
| 797 | abort("Argument error !! [#{sFileName}]")
|
---|
| 798 | end
|
---|
| 799 |
|
---|
| 800 | sCsvFileName = File.dirname(sFileName) + "/" + sTargetModule + ".csv"
|
---|
| 801 |
|
---|
| 802 | # XMLライブラリでの読み込み
|
---|
| 803 | cXmlData = REXML::Document.new(open(sFileName))
|
---|
| 804 |
|
---|
| 805 | $hResult = {}
|
---|
| 806 | $sNowContainer = ""
|
---|
| 807 |
|
---|
| 808 | cXmlData.elements.each("AUTOSAR/AR-PACKAGES/AR-PACKAGE/AR-PACKAGES/AR-PACKAGE/ELEMENTS/ECUC-MODULE-DEF"){|cElement1|
|
---|
| 809 | # 対象モジュールのみを処理する
|
---|
| 810 | if (cElement1.elements["SHORT-NAME"].text() != sTargetModule)
|
---|
| 811 | next
|
---|
| 812 | end
|
---|
| 813 |
|
---|
| 814 | cElement1.elements.each("CONTAINERS/ECUC-PARAM-CONF-CONTAINER-DEF"){|cElement2|
|
---|
| 815 | $sContainer = cElement2.elements["SHORT-NAME"].text()
|
---|
| 816 | $hResult[$sContainer] = MakeCsv_add_parameter_info(cElement2, nil)
|
---|
| 817 | MakeCsv_parse_parameter(cElement2)
|
---|
| 818 | }
|
---|
| 819 | }
|
---|
| 820 |
|
---|
| 821 | sModulePath = "/AUTOSAR/EcucDefs/#{sTargetModule}"
|
---|
| 822 | sCsvData = "#{sModulePath},,,1\n"
|
---|
| 823 |
|
---|
| 824 | hDataTypeTable = {"ECUC-REFERENCE-DEF" => "REF",
|
---|
| 825 | "ECUC-FOREIGN-REFERENCE-DEF" => "REF",
|
---|
| 826 | "ECUC-CHOICE-REFERENCE-DEF" => "REF",
|
---|
| 827 | "ECUC-SYMBOLIC-NAME-REFERENCE-DEF" => "REF",
|
---|
| 828 | "ECUC-INSTANCE-REFERENCE-DEF" => "REF",
|
---|
| 829 | "ECUC-BOOLEAN-PARAM-DEF" => "BOOLEAN",
|
---|
| 830 | "ECUC-INTEGER-PARAM-DEF" => "INT",
|
---|
| 831 | "ECUC-FUNCTION-NAME-DEF" => "FUNCTION",
|
---|
| 832 | "ECUC-ENUMERATION-PARAM-DEF" => "ENUM",
|
---|
| 833 | "ECUC-STRING-PARAM-DEF" => "STRING",
|
---|
| 834 | "ECUC-FLOAT-PARAM-DEF" => "FLOAT",
|
---|
| 835 | "ECUC-LINKER-SYMBOL-DEF" => "STRING",
|
---|
| 836 | nil => ""}
|
---|
| 837 |
|
---|
| 838 | $hResult.each{|sParam, aInfo|
|
---|
| 839 | if (!hDataTypeTable.has_key?(aInfo[0]))
|
---|
| 840 | abort("[#{__FILE__}] #{__LINE__}: #{aInfo[0]}")
|
---|
| 841 | end
|
---|
| 842 | if ((aInfo[1] == "1") && (aInfo[2] == "1"))
|
---|
| 843 | sCsvData += "#{sModulePath}/#{sParam},#{sParam.split("/")[-1]},#{hDataTypeTable[aInfo[0]]},1\n"
|
---|
| 844 | else
|
---|
| 845 | sCsvData += "#{sModulePath}/#{sParam},#{sParam.split("/")[-1]},#{hDataTypeTable[aInfo[0]]},#{aInfo[1]},#{aInfo[2]}\n"
|
---|
| 846 | end
|
---|
| 847 | }
|
---|
| 848 |
|
---|
| 849 | File.open(sCsvFileName, "w") {|io|
|
---|
| 850 | io.puts(sCsvData)
|
---|
| 851 | }
|
---|
| 852 |
|
---|
| 853 | puts("Generated #{sCsvFileName}")
|
---|
| 854 | end
|
---|
| 855 |
|
---|
| 856 | # パラメータ情報追加関数
|
---|
| 857 | def MakeCsv_add_parameter_info(cElement, sName = cElement.name)
|
---|
| 858 | # パラメータ毎に,型・多重度下限,上限の情報を取得
|
---|
| 859 | sLower = nil
|
---|
| 860 | if (!cElement.elements["LOWER-MULTIPLICITY"].nil?)
|
---|
| 861 | sLower = cElement.elements["LOWER-MULTIPLICITY"].text()
|
---|
| 862 | else
|
---|
| 863 | abort("[#{__FILE__}] #{__LINE__}")
|
---|
| 864 | end
|
---|
| 865 | sUpper = nil
|
---|
| 866 | if (!cElement.elements["UPPER-MULTIPLICITY"].nil?)
|
---|
| 867 | sUpper = cElement.elements["UPPER-MULTIPLICITY"].text()
|
---|
| 868 | elsif (!cElement.elements["UPPER-MULTIPLICITY-INFINITE"].nil? && (cElement.elements["UPPER-MULTIPLICITY-INFINITE"].text() == "true"))
|
---|
| 869 | sUpper = "*"
|
---|
| 870 | else
|
---|
| 871 | abort("[#{__FILE__}] #{__LINE__}")
|
---|
| 872 | end
|
---|
| 873 |
|
---|
| 874 | return [sName, sLower, sUpper]
|
---|
| 875 | end
|
---|
| 876 |
|
---|
| 877 | # サブコンテナ再帰パース関数
|
---|
| 878 | def MakeCsv_parse_sub_container(cElement)
|
---|
| 879 | # "ECUC-PARAM-CONF-CONTAINER-DEF"が登場するまで再帰する
|
---|
| 880 | cElement.elements.each{|cElementC|
|
---|
| 881 | # CHOICEはさらにネストする
|
---|
| 882 | if (cElementC.name == "ECUC-CHOICE-CONTAINER-DEF")
|
---|
| 883 | $sContainer += "/#{cElementC.elements["SHORT-NAME"].text()}"
|
---|
| 884 | $hResult[$sContainer] = MakeCsv_add_parameter_info(cElementC, nil)
|
---|
| 885 | MakeCsv_parse_sub_container(cElementC)
|
---|
| 886 |
|
---|
| 887 | aTemp = $sContainer.split("/")
|
---|
| 888 | aTemp.pop()
|
---|
| 889 | $sContainer = aTemp.join("/")
|
---|
| 890 | elsif (cElementC.name == "ECUC-PARAM-CONF-CONTAINER-DEF")
|
---|
| 891 | $sContainer += "/#{cElementC.elements["SHORT-NAME"].text()}"
|
---|
| 892 | $hResult[$sContainer] = MakeCsv_add_parameter_info(cElementC, nil)
|
---|
| 893 | MakeCsv_parse_parameter(cElementC)
|
---|
| 894 |
|
---|
| 895 | aTemp = $sContainer.split("/")
|
---|
| 896 | aTemp.pop()
|
---|
| 897 | $sContainer = aTemp.join("/")
|
---|
| 898 | else
|
---|
| 899 | MakeCsv_parse_sub_container(cElementC)
|
---|
| 900 | end
|
---|
| 901 | }
|
---|
| 902 | end
|
---|
| 903 |
|
---|
| 904 | # コンテナパース関数
|
---|
| 905 | def MakeCsv_parse_parameter(cElement)
|
---|
| 906 | # パラメータ
|
---|
| 907 | cElement.elements.each("PARAMETERS"){|cElementC|
|
---|
| 908 | cElementC.elements.each{|cElementG|
|
---|
| 909 | sParamName = "#{$sContainer}/#{cElementG.elements["SHORT-NAME"].text()}"
|
---|
| 910 | $hResult[sParamName] = MakeCsv_add_parameter_info(cElementG)
|
---|
| 911 | }
|
---|
| 912 | }
|
---|
| 913 |
|
---|
| 914 | # 参照
|
---|
| 915 | cElement.elements.each("REFERENCES/ECUC-REFERENCE-DEF"){|cElementC|
|
---|
| 916 | sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
|
---|
| 917 | $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
|
---|
| 918 | }
|
---|
| 919 |
|
---|
| 920 | # 外部参照
|
---|
| 921 | cElement.elements.each("REFERENCES/ECUC-FOREIGN-REFERENCE-DEF"){|cElementC|
|
---|
| 922 | sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
|
---|
| 923 | $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
|
---|
| 924 | }
|
---|
| 925 |
|
---|
| 926 | # 選択参照
|
---|
| 927 | cElement.elements.each("REFERENCES/ECUC-CHOICE-REFERENCE-DEF"){|cElementC|
|
---|
| 928 | sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
|
---|
| 929 | $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
|
---|
| 930 | }
|
---|
| 931 |
|
---|
| 932 | # シンボルネーム参照
|
---|
| 933 | cElement.elements.each("REFERENCES/ECUC-SYMBOLIC-NAME-REFERENCE-DEF"){|cElementC|
|
---|
| 934 | sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
|
---|
| 935 | $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
|
---|
| 936 | }
|
---|
| 937 |
|
---|
| 938 | # インスタンス参照
|
---|
| 939 | cElement.elements.each("REFERENCES/ECUC-INSTANCE-REFERENCE-DEF"){|cElementC|
|
---|
| 940 | sParamName = "#{$sContainer}/#{cElementC.elements["SHORT-NAME"].text()}"
|
---|
| 941 | $hResult[sParamName] = MakeCsv_add_parameter_info(cElementC)
|
---|
| 942 | }
|
---|
| 943 |
|
---|
| 944 | # サブコンテナ(再帰呼出し)
|
---|
| 945 | cElement.elements.each("SUB-CONTAINERS"){|cElementC|
|
---|
| 946 | MakeCsv_parse_sub_container(cElementC)
|
---|
| 947 | }
|
---|
| 948 | end
|
---|
| 949 |
|
---|
| 950 |
|
---|
| 951 | ######################################################################
|
---|
| 952 | # オプション処理
|
---|
| 953 | ######################################################################
|
---|
| 954 | lMode = :YamlToXml
|
---|
| 955 | sEcuExtractRef = nil
|
---|
| 956 | cOpt = OptionParser.new(banner="Usage: abrex.rb [options]... [yaml|xml files]...", 18)
|
---|
| 957 | cOpt.version = VERSION
|
---|
| 958 | sOptData = nil
|
---|
| 959 | sBswName = nil
|
---|
| 960 | cOpt.on("-i XML_FILE", "ARXML to YAML conversion") {|xVal|
|
---|
| 961 | sOptData = xVal
|
---|
| 962 | lMode = :XmlToYaml
|
---|
| 963 | }
|
---|
| 964 | cOpt.on("-p XML_FILE", "Generate 'param_info.yaml' from AUTOSAR Ecu Configuration Parameters file") {|xVal|
|
---|
| 965 | sOptData = xVal
|
---|
| 966 | lMode = :MakeParamInfo
|
---|
| 967 | }
|
---|
| 968 | cOpt.on("-c XML_FILE", "Generate '{BSW_NAME}.csv' from AUTOSAR Ecu Configuration Parameters file") {|xVal|
|
---|
| 969 | sOptData = xVal
|
---|
| 970 | lMode = :MakeCsv
|
---|
| 971 | }
|
---|
| 972 | cOpt.on("-b BSW_NAME", "set a BSW Module Name (for '-c' additional optipn)") {|xVal|
|
---|
| 973 | sBswName = xVal
|
---|
| 974 | lMode = :MakeCsv
|
---|
| 975 | }
|
---|
| 976 | cOpt.on("-e ECU-EXTRACT-REF", "set a ECU-EXTRACT-REF path if <ECUC-VALUE-COLLECTION> is needed") {|xVal|
|
---|
| 977 | sEcuExtractRef = xVal
|
---|
| 978 | lMode = :YamlToXml
|
---|
| 979 | }
|
---|
| 980 | cOpt.on("-v", "--version", "show version information"){
|
---|
| 981 | puts(cOpt.ver())
|
---|
| 982 | exit(1)
|
---|
| 983 | }
|
---|
| 984 | cOpt.on("-h", "--help", "show help (this)"){
|
---|
| 985 | puts(cOpt.help())
|
---|
| 986 | exit(1)
|
---|
| 987 | }
|
---|
| 988 |
|
---|
| 989 | begin
|
---|
| 990 | aArgData = cOpt.parse(ARGV)
|
---|
| 991 | rescue OptionParser::ParseError
|
---|
| 992 | puts(cOpt.help())
|
---|
| 993 | exit(1)
|
---|
| 994 | end
|
---|
| 995 |
|
---|
| 996 | if (((lMode == :YamlToXml) && aArgData.empty?()) ||
|
---|
| 997 | ((lMode != :YamlToXml) && sOptData.nil?()))
|
---|
| 998 | puts(cOpt.help())
|
---|
| 999 | exit(1)
|
---|
| 1000 | end
|
---|
| 1001 |
|
---|
| 1002 | if ((lMode == :MakeCsv) && sBswName.nil?())
|
---|
| 1003 | puts(cOpt.help())
|
---|
| 1004 | exit(1)
|
---|
| 1005 | end
|
---|
| 1006 |
|
---|
| 1007 |
|
---|
| 1008 | ######################################################################
|
---|
| 1009 | # オプションに従って各処理を実行
|
---|
| 1010 | ######################################################################
|
---|
| 1011 | case lMode
|
---|
| 1012 | when :YamlToXml
|
---|
| 1013 | YamlToXml(aArgData, sEcuExtractRef)
|
---|
| 1014 | when :XmlToYaml
|
---|
| 1015 | XmlToYaml(sOptData, aArgData)
|
---|
| 1016 | when :MakeParamInfo
|
---|
| 1017 | MakeParamInfo(sOptData)
|
---|
| 1018 | when :MakeCsv
|
---|
| 1019 | MakeCsv(sOptData, sBswName)
|
---|
| 1020 | end
|
---|