]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/AutoGen/BuildEngine.py
bb915344779338541949dec4ae80c7233daf920a
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / BuildEngine.py
1 ## @file
2 # The engine for building files
3 #
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # SPDX-License-Identifier: BSD-2-Clause-Patent
6 #
7
8 ##
9 # Import Modules
10 #
11 from __future__ import print_function
12 import Common.LongFilePathOs as os
13 import re
14 import copy
15 import string
16 from Common.LongFilePathSupport import OpenLongFilePath as open
17
18 from Common.GlobalData import *
19 from Common.BuildToolError import *
20 from Common.Misc import tdict, PathClass
21 from Common.StringUtils import NormPath
22 from Common.DataType import *
23 from Common.TargetTxtClassObject import TargetTxt
24 gDefaultBuildRuleFile = 'build_rule.txt'
25 AutoGenReqBuildRuleVerNum = '0.1'
26
27 import Common.EdkLogger as EdkLogger
28
29 ## Convert file type to file list macro name
30 #
31 # @param FileType The name of file type
32 #
33 # @retval string The name of macro
34 #
35 def FileListMacro(FileType):
36 return "%sS" % FileType.replace("-", "_").upper()
37
38 ## Convert file type to list file macro name
39 #
40 # @param FileType The name of file type
41 #
42 # @retval string The name of macro
43 #
44 def ListFileMacro(FileType):
45 return "%s_LIST" % FileListMacro(FileType)
46
47 class TargetDescBlock(object):
48 def __init__(self, Inputs, Outputs, Commands, Dependencies):
49 self.InitWorker(Inputs, Outputs, Commands, Dependencies)
50
51 def InitWorker(self, Inputs, Outputs, Commands, Dependencies):
52 self.Inputs = Inputs
53 self.Outputs = Outputs
54 self.Commands = Commands
55 self.Dependencies = Dependencies
56 if self.Outputs:
57 self.Target = self.Outputs[0]
58 else:
59 self.Target = None
60
61 def __str__(self):
62 return self.Target.Path
63
64 def __hash__(self):
65 return hash(self.Target.Path)
66
67 def __eq__(self, Other):
68 if isinstance(Other, type(self)):
69 return Other.Target.Path == self.Target.Path
70 else:
71 return str(Other) == self.Target.Path
72
73 def AddInput(self, Input):
74 if Input not in self.Inputs:
75 self.Inputs.append(Input)
76
77 def IsMultipleInput(self):
78 return len(self.Inputs) > 1
79
80 ## Class for one build rule
81 #
82 # This represents a build rule which can give out corresponding command list for
83 # building the given source file(s). The result can be used for generating the
84 # target for makefile.
85 #
86 class FileBuildRule:
87 INC_LIST_MACRO = "INC_LIST"
88 INC_MACRO = "INC"
89
90 ## constructor
91 #
92 # @param Input The dictionary representing input file(s) for a rule
93 # @param Output The list representing output file(s) for a rule
94 # @param Command The list containing commands to generate the output from input
95 #
96 def __init__(self, Type, Input, Output, Command, ExtraDependency=None):
97 # The Input should not be empty
98 if not Input:
99 Input = []
100 if not Output:
101 Output = []
102 if not Command:
103 Command = []
104
105 self.FileListMacro = FileListMacro(Type)
106 self.ListFileMacro = ListFileMacro(Type)
107 self.IncListFileMacro = self.INC_LIST_MACRO
108
109 self.SourceFileType = Type
110 # source files listed not in TAB_STAR or "?" pattern format
111 if not ExtraDependency:
112 self.ExtraSourceFileList = []
113 else:
114 self.ExtraSourceFileList = ExtraDependency
115
116 #
117 # Search macros used in command lines for <FILE_TYPE>_LIST and INC_LIST.
118 # If found, generate a file to keep the input files used to get over the
119 # limitation of command line length
120 #
121 self.MacroList = []
122 self.CommandList = []
123 for CmdLine in Command:
124 self.MacroList.extend(gMacroRefPattern.findall(CmdLine))
125 # replace path separator with native one
126 self.CommandList.append(CmdLine)
127
128 # Indicate what should be generated
129 if self.FileListMacro in self.MacroList:
130 self.GenFileListMacro = True
131 else:
132 self.GenFileListMacro = False
133
134 if self.ListFileMacro in self.MacroList:
135 self.GenListFile = True
136 self.GenFileListMacro = True
137 else:
138 self.GenListFile = False
139
140 if self.INC_LIST_MACRO in self.MacroList:
141 self.GenIncListFile = True
142 else:
143 self.GenIncListFile = False
144
145 # Check input files
146 self.IsMultipleInput = False
147 self.SourceFileExtList = set()
148 for File in Input:
149 Base, Ext = os.path.splitext(File)
150 if Base.find(TAB_STAR) >= 0:
151 # There's TAB_STAR in the file name
152 self.IsMultipleInput = True
153 self.GenFileListMacro = True
154 elif Base.find("?") < 0:
155 # There's no TAB_STAR and "?" in file name
156 self.ExtraSourceFileList.append(File)
157 continue
158 self.SourceFileExtList.add(Ext)
159
160 # Check output files
161 self.DestFileList = []
162 for File in Output:
163 self.DestFileList.append(File)
164
165 # All build targets generated by this rule for a module
166 self.BuildTargets = {}
167
168 ## str() function support
169 #
170 # @retval string
171 #
172 def __str__(self):
173 SourceString = ""
174 SourceString += " %s %s %s" % (self.SourceFileType, " ".join(self.SourceFileExtList), self.ExtraSourceFileList)
175 DestString = ", ".join(self.DestFileList)
176 CommandString = "\n\t".join(self.CommandList)
177 return "%s : %s\n\t%s" % (DestString, SourceString, CommandString)
178
179 def Instantiate(self, Macros={}):
180 NewRuleObject = copy.copy(self)
181 NewRuleObject.BuildTargets = {}
182 NewRuleObject.DestFileList = []
183 for File in self.DestFileList:
184 NewRuleObject.DestFileList.append(PathClass(NormPath(File, Macros)))
185 return NewRuleObject
186
187 ## Apply the rule to given source file(s)
188 #
189 # @param SourceFile One file or a list of files to be built
190 # @param RelativeToDir The relative path of the source file
191 # @param PathSeparator Path separator
192 #
193 # @retval tuple (Source file in full path, List of individual sourcefiles, Destination file, List of build commands)
194 #
195 def Apply(self, SourceFile, BuildRuleOrder=None):
196 if not self.CommandList or not self.DestFileList:
197 return None
198
199 # source file
200 if self.IsMultipleInput:
201 SrcFileName = ""
202 SrcFileBase = ""
203 SrcFileExt = ""
204 SrcFileDir = ""
205 SrcPath = ""
206 # SourceFile must be a list
207 SrcFile = "$(%s)" % self.FileListMacro
208 else:
209 SrcFileName, SrcFileBase, SrcFileExt = SourceFile.Name, SourceFile.BaseName, SourceFile.Ext
210 if SourceFile.Root:
211 SrcFileDir = SourceFile.SubDir
212 if SrcFileDir == "":
213 SrcFileDir = "."
214 else:
215 SrcFileDir = "."
216 SrcFile = SourceFile.Path
217 SrcPath = SourceFile.Dir
218
219 # destination file (the first one)
220 if self.DestFileList:
221 DestFile = self.DestFileList[0].Path
222 DestPath = self.DestFileList[0].Dir
223 DestFileName = self.DestFileList[0].Name
224 DestFileBase, DestFileExt = self.DestFileList[0].BaseName, self.DestFileList[0].Ext
225 else:
226 DestFile = ""
227 DestPath = ""
228 DestFileName = ""
229 DestFileBase = ""
230 DestFileExt = ""
231
232 BuildRulePlaceholderDict = {
233 # source file
234 "src" : SrcFile,
235 "s_path" : SrcPath,
236 "s_dir" : SrcFileDir,
237 "s_name" : SrcFileName,
238 "s_base" : SrcFileBase,
239 "s_ext" : SrcFileExt,
240 # destination file
241 "dst" : DestFile,
242 "d_path" : DestPath,
243 "d_name" : DestFileName,
244 "d_base" : DestFileBase,
245 "d_ext" : DestFileExt,
246 }
247
248 DstFile = []
249 for File in self.DestFileList:
250 File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict)
251 File = string.Template(str(File)).safe_substitute(BuildRulePlaceholderDict)
252 DstFile.append(PathClass(File, IsBinary=True))
253
254 if DstFile[0] in self.BuildTargets:
255 TargetDesc = self.BuildTargets[DstFile[0]]
256 if BuildRuleOrder and SourceFile.Ext in BuildRuleOrder:
257 Index = BuildRuleOrder.index(SourceFile.Ext)
258 for Input in TargetDesc.Inputs:
259 if Input.Ext not in BuildRuleOrder or BuildRuleOrder.index(Input.Ext) > Index:
260 #
261 # Command line should be regenerated since some macros are different
262 #
263 CommandList = self._BuildCommand(BuildRulePlaceholderDict)
264 TargetDesc.InitWorker([SourceFile], DstFile, CommandList, self.ExtraSourceFileList)
265 break
266 else:
267 TargetDesc.AddInput(SourceFile)
268 else:
269 CommandList = self._BuildCommand(BuildRulePlaceholderDict)
270 TargetDesc = TargetDescBlock([SourceFile], DstFile, CommandList, self.ExtraSourceFileList)
271 TargetDesc.ListFileMacro = self.ListFileMacro
272 TargetDesc.FileListMacro = self.FileListMacro
273 TargetDesc.IncListFileMacro = self.IncListFileMacro
274 TargetDesc.GenFileListMacro = self.GenFileListMacro
275 TargetDesc.GenListFile = self.GenListFile
276 TargetDesc.GenIncListFile = self.GenIncListFile
277 self.BuildTargets[DstFile[0]] = TargetDesc
278 return TargetDesc
279
280 def _BuildCommand(self, Macros):
281 CommandList = []
282 for CommandString in self.CommandList:
283 CommandString = string.Template(CommandString).safe_substitute(Macros)
284 CommandString = string.Template(CommandString).safe_substitute(Macros)
285 CommandList.append(CommandString)
286 return CommandList
287
288 ## Class for build rules
289 #
290 # BuildRule class parses rules defined in a file or passed by caller, and converts
291 # the rule into FileBuildRule object.
292 #
293 class BuildRule:
294 _SectionHeader = "SECTIONHEADER"
295 _Section = "SECTION"
296 _SubSectionHeader = "SUBSECTIONHEADER"
297 _SubSection = "SUBSECTION"
298 _InputFile = "INPUTFILE"
299 _OutputFile = "OUTPUTFILE"
300 _ExtraDependency = "EXTRADEPENDENCY"
301 _Command = "COMMAND"
302 _UnknownSection = "UNKNOWNSECTION"
303
304 _SubSectionList = [_InputFile, _OutputFile, _Command]
305
306 _PATH_SEP = "(+)"
307 _FileTypePattern = re.compile("^[_a-zA-Z][_\-0-9a-zA-Z]*$")
308 _BinaryFileRule = FileBuildRule(TAB_DEFAULT_BINARY_FILE, [], [os.path.join("$(OUTPUT_DIR)", "${s_name}")],
309 ["$(CP) ${src} ${dst}"], [])
310
311 ## Constructor
312 #
313 # @param File The file containing build rules in a well defined format
314 # @param Content The string list of build rules in a well defined format
315 # @param LineIndex The line number from which the parsing will begin
316 # @param SupportedFamily The list of supported tool chain families
317 #
318 def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=[TAB_COMPILER_MSFT, "INTEL", "GCC", "RVCT"]):
319 self.RuleFile = File
320 # Read build rules from file if it's not none
321 if File is not None:
322 try:
323 self.RuleContent = open(File, 'r').readlines()
324 except:
325 EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File)
326 elif Content is not None:
327 self.RuleContent = Content
328 else:
329 EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given")
330
331 self.SupportedToolChainFamilyList = SupportedFamily
332 self.RuleDatabase = tdict(True, 4) # {FileExt, ModuleType, Arch, Family : FileBuildRule object}
333 self.Ext2FileType = {} # {ext : file-type}
334 self.FileTypeList = set()
335
336 self._LineIndex = LineIndex
337 self._State = ""
338 self._RuleInfo = tdict(True, 2) # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}}
339 self._FileType = ''
340 self._BuildTypeList = set()
341 self._ArchList = set()
342 self._FamilyList = []
343 self._TotalToolChainFamilySet = set()
344 self._RuleObjectList = [] # FileBuildRule object list
345 self._FileVersion = ""
346
347 self.Parse()
348
349 # some intrinsic rules
350 self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, TAB_COMMON, TAB_COMMON, TAB_COMMON] = self._BinaryFileRule
351 self.FileTypeList.add(TAB_DEFAULT_BINARY_FILE)
352
353 ## Parse the build rule strings
354 def Parse(self):
355 self._State = self._Section
356 for Index in range(self._LineIndex, len(self.RuleContent)):
357 # Clean up the line and replace path separator with native one
358 Line = self.RuleContent[Index].strip().replace(self._PATH_SEP, os.path.sep)
359 self.RuleContent[Index] = Line
360
361 # find the build_rule_version
362 if Line and Line[0] == "#" and Line.find(TAB_BUILD_RULE_VERSION) != -1:
363 if Line.find("=") != -1 and Line.find("=") < (len(Line) - 1) and (Line[(Line.find("=") + 1):]).split():
364 self._FileVersion = (Line[(Line.find("=") + 1):]).split()[0]
365 # skip empty or comment line
366 if Line == "" or Line[0] == "#":
367 continue
368
369 # find out section header, enclosed by []
370 if Line[0] == '[' and Line[-1] == ']':
371 # merge last section information into rule database
372 self.EndOfSection()
373 self._State = self._SectionHeader
374 # find out sub-section header, enclosed by <>
375 elif Line[0] == '<' and Line[-1] == '>':
376 if self._State != self._UnknownSection:
377 self._State = self._SubSectionHeader
378
379 # call section handler to parse each (sub)section
380 self._StateHandler[self._State](self, Index)
381 # merge last section information into rule database
382 self.EndOfSection()
383
384 ## Parse definitions under a section
385 #
386 # @param LineIndex The line index of build rule text
387 #
388 def ParseSection(self, LineIndex):
389 pass
390
391 ## Parse definitions under a subsection
392 #
393 # @param LineIndex The line index of build rule text
394 #
395 def ParseSubSection(self, LineIndex):
396 # currently nothing here
397 pass
398
399 ## Placeholder for not supported sections
400 #
401 # @param LineIndex The line index of build rule text
402 #
403 def SkipSection(self, LineIndex):
404 pass
405
406 ## Merge section information just got into rule database
407 def EndOfSection(self):
408 Database = self.RuleDatabase
409 # if there's specific toolchain family, 'COMMON' doesn't make sense any more
410 if len(self._TotalToolChainFamilySet) > 1 and TAB_COMMON in self._TotalToolChainFamilySet:
411 self._TotalToolChainFamilySet.remove(TAB_COMMON)
412 for Family in self._TotalToolChainFamilySet:
413 Input = self._RuleInfo[Family, self._InputFile]
414 Output = self._RuleInfo[Family, self._OutputFile]
415 Command = self._RuleInfo[Family, self._Command]
416 ExtraDependency = self._RuleInfo[Family, self._ExtraDependency]
417
418 BuildRule = FileBuildRule(self._FileType, Input, Output, Command, ExtraDependency)
419 for BuildType in self._BuildTypeList:
420 for Arch in self._ArchList:
421 Database[self._FileType, BuildType, Arch, Family] = BuildRule
422 for FileExt in BuildRule.SourceFileExtList:
423 self.Ext2FileType[FileExt] = self._FileType
424
425 ## Parse section header
426 #
427 # @param LineIndex The line index of build rule text
428 #
429 def ParseSectionHeader(self, LineIndex):
430 self._RuleInfo = tdict(True, 2)
431 self._BuildTypeList = set()
432 self._ArchList = set()
433 self._FamilyList = []
434 self._TotalToolChainFamilySet = set()
435 FileType = ''
436 RuleNameList = self.RuleContent[LineIndex][1:-1].split(',')
437 for RuleName in RuleNameList:
438 Arch = TAB_COMMON
439 BuildType = TAB_COMMON
440 TokenList = [Token.strip().upper() for Token in RuleName.split('.')]
441 # old format: Build.File-Type
442 if TokenList[0] == "BUILD":
443 if len(TokenList) == 1:
444 EdkLogger.error("build", FORMAT_INVALID, "Invalid rule section",
445 File=self.RuleFile, Line=LineIndex + 1,
446 ExtraData=self.RuleContent[LineIndex])
447
448 FileType = TokenList[1]
449 if FileType == '':
450 EdkLogger.error("build", FORMAT_INVALID, "No file type given",
451 File=self.RuleFile, Line=LineIndex + 1,
452 ExtraData=self.RuleContent[LineIndex])
453 if self._FileTypePattern.match(FileType) is None:
454 EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex + 1,
455 ExtraData="Only character, number (non-first character), '_' and '-' are allowed in file type")
456 # new format: File-Type.Build-Type.Arch
457 else:
458 if FileType == '':
459 FileType = TokenList[0]
460 elif FileType != TokenList[0]:
461 EdkLogger.error("build", FORMAT_INVALID,
462 "Different file types are not allowed in the same rule section",
463 File=self.RuleFile, Line=LineIndex + 1,
464 ExtraData=self.RuleContent[LineIndex])
465 if len(TokenList) > 1:
466 BuildType = TokenList[1]
467 if len(TokenList) > 2:
468 Arch = TokenList[2]
469 self._BuildTypeList.add(BuildType)
470 self._ArchList.add(Arch)
471
472 if TAB_COMMON in self._BuildTypeList and len(self._BuildTypeList) > 1:
473 EdkLogger.error("build", FORMAT_INVALID,
474 "Specific build types must not be mixed with common one",
475 File=self.RuleFile, Line=LineIndex + 1,
476 ExtraData=self.RuleContent[LineIndex])
477 if TAB_COMMON in self._ArchList and len(self._ArchList) > 1:
478 EdkLogger.error("build", FORMAT_INVALID,
479 "Specific ARCH must not be mixed with common one",
480 File=self.RuleFile, Line=LineIndex + 1,
481 ExtraData=self.RuleContent[LineIndex])
482
483 self._FileType = FileType
484 self._State = self._Section
485 self.FileTypeList.add(FileType)
486
487 ## Parse sub-section header
488 #
489 # @param LineIndex The line index of build rule text
490 #
491 def ParseSubSectionHeader(self, LineIndex):
492 SectionType = ""
493 List = self.RuleContent[LineIndex][1:-1].split(',')
494 FamilyList = []
495 for Section in List:
496 TokenList = Section.split('.')
497 Type = TokenList[0].strip().upper()
498
499 if SectionType == "":
500 SectionType = Type
501 elif SectionType != Type:
502 EdkLogger.error("build", FORMAT_INVALID,
503 "Two different section types are not allowed in the same sub-section",
504 File=self.RuleFile, Line=LineIndex + 1,
505 ExtraData=self.RuleContent[LineIndex])
506
507 if len(TokenList) > 1:
508 Family = TokenList[1].strip().upper()
509 else:
510 Family = TAB_COMMON
511
512 if Family not in FamilyList:
513 FamilyList.append(Family)
514
515 self._FamilyList = FamilyList
516 self._TotalToolChainFamilySet.update(FamilyList)
517 self._State = SectionType.upper()
518 if TAB_COMMON in FamilyList and len(FamilyList) > 1:
519 EdkLogger.error("build", FORMAT_INVALID,
520 "Specific tool chain family should not be mixed with general one",
521 File=self.RuleFile, Line=LineIndex + 1,
522 ExtraData=self.RuleContent[LineIndex])
523 if self._State not in self._StateHandler:
524 EdkLogger.error("build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex + 1,
525 ExtraData="Unknown subsection: %s" % self.RuleContent[LineIndex])
526 ## Parse <InputFile> sub-section
527 #
528 # @param LineIndex The line index of build rule text
529 #
530 def ParseInputFileSubSection(self, LineIndex):
531 FileList = [File.strip() for File in self.RuleContent[LineIndex].split(",")]
532 for ToolChainFamily in self._FamilyList:
533 if self._RuleInfo[ToolChainFamily, self._State] is None:
534 self._RuleInfo[ToolChainFamily, self._State] = []
535 self._RuleInfo[ToolChainFamily, self._State].extend(FileList)
536
537 ## Parse <ExtraDependency> sub-section
538 ## Parse <OutputFile> sub-section
539 ## Parse <Command> sub-section
540 #
541 # @param LineIndex The line index of build rule text
542 #
543 def ParseCommonSubSection(self, LineIndex):
544 for ToolChainFamily in self._FamilyList:
545 if self._RuleInfo[ToolChainFamily, self._State] is None:
546 self._RuleInfo[ToolChainFamily, self._State] = []
547 self._RuleInfo[ToolChainFamily, self._State].append(self.RuleContent[LineIndex])
548
549 ## Get a build rule via [] operator
550 #
551 # @param FileExt The extension of a file
552 # @param ToolChainFamily The tool chain family name
553 # @param BuildVersion The build version number. TAB_STAR means any rule
554 # is applicable.
555 #
556 # @retval FileType The file type string
557 # @retval FileBuildRule The object of FileBuildRule
558 #
559 # Key = (FileExt, ModuleType, Arch, ToolChainFamily)
560 def __getitem__(self, Key):
561 if not Key:
562 return None
563
564 if Key[0] in self.Ext2FileType:
565 Type = self.Ext2FileType[Key[0]]
566 elif Key[0].upper() in self.FileTypeList:
567 Type = Key[0].upper()
568 else:
569 return None
570
571 if len(Key) > 1:
572 Key = (Type,) + Key[1:]
573 else:
574 Key = (Type,)
575 return self.RuleDatabase[Key]
576
577 _StateHandler = {
578 _SectionHeader : ParseSectionHeader,
579 _Section : ParseSection,
580 _SubSectionHeader : ParseSubSectionHeader,
581 _SubSection : ParseSubSection,
582 _InputFile : ParseInputFileSubSection,
583 _OutputFile : ParseCommonSubSection,
584 _ExtraDependency : ParseCommonSubSection,
585 _Command : ParseCommonSubSection,
586 _UnknownSection : SkipSection,
587 }
588
589 def GetBuildRule():
590 BuildRuleFile = None
591 if TAB_TAT_DEFINES_BUILD_RULE_CONF in TargetTxt.TargetTxtDictionary:
592 BuildRuleFile = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]
593 if not BuildRuleFile:
594 BuildRuleFile = gDefaultBuildRuleFile
595 RetVal = BuildRule(BuildRuleFile)
596 if RetVal._FileVersion == "":
597 RetVal._FileVersion = AutoGenReqBuildRuleVerNum
598 else:
599 if RetVal._FileVersion < AutoGenReqBuildRuleVerNum :
600 # If Build Rule's version is less than the version number required by the tools, halting the build.
601 EdkLogger.error("build", AUTOGEN_ERROR,
602 ExtraData="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\
603 % (RetVal._FileVersion, AutoGenReqBuildRuleVerNum))
604 return RetVal
605
606 BuildRuleObj = GetBuildRule()
607
608 # This acts like the main() function for the script, unless it is 'import'ed into another
609 # script.
610 if __name__ == '__main__':
611 import sys
612 EdkLogger.Initialize()
613 if len(sys.argv) > 1:
614 Br = BuildRule(sys.argv[1])
615 print(str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", TAB_COMPILER_MSFT][1]))
616 print()
617 print(str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", "INTEL"][1]))
618 print()
619 print(str(Br[".c", SUP_MODULE_DXE_DRIVER, "IA32", "GCC"][1]))
620 print()
621 print(str(Br[".ac", "ACPI_TABLE", "IA32", TAB_COMPILER_MSFT][1]))
622 print()
623 print(str(Br[".h", "ACPI_TABLE", "IA32", "INTEL"][1]))
624 print()
625 print(str(Br[".ac", "ACPI_TABLE", "IA32", TAB_COMPILER_MSFT][1]))
626 print()
627 print(str(Br[".s", SUP_MODULE_SEC, "IPF", "COMMON"][1]))
628 print()
629 print(str(Br[".s", SUP_MODULE_SEC][1]))
630