2 # Trim files preprocessed by compiler
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 import Common
.LongFilePathOs
as os
20 from io
import BytesIO
22 from optparse
import OptionParser
23 from optparse
import make_option
24 from Common
.BuildToolError
import *
25 from Common
.Misc
import *
26 from Common
.DataType
import *
27 from Common
.BuildVersion
import gBUILD_VERSION
28 import Common
.EdkLogger
as EdkLogger
29 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
31 # Version and Copyright
32 __version_number__
= ("0.10" + " " + gBUILD_VERSION
)
33 __version__
= "%prog Version " + __version_number__
34 __copyright__
= "Copyright (c) 2007-2017, Intel Corporation. All rights reserved."
36 ## Regular expression for matching Line Control directive like "#line xxx"
37 gLineControlDirective
= re
.compile('^\s*#(?:line)?\s+([0-9]+)\s+"*([^"]*)"')
38 ## Regular expression for matching "typedef struct"
39 gTypedefPattern
= re
.compile("^\s*typedef\s+struct(\s+\w+)?\s*[{]*$", re
.MULTILINE
)
40 ## Regular expression for matching "#pragma pack"
41 gPragmaPattern
= re
.compile("^\s*#pragma\s+pack", re
.MULTILINE
)
42 ## Regular expression for matching "typedef"
43 gTypedef_SinglePattern
= re
.compile("^\s*typedef", re
.MULTILINE
)
44 ## Regular expression for matching "typedef struct, typedef union, struct, union"
45 gTypedef_MulPattern
= re
.compile("^\s*(typedef)?\s+(struct|union)(\s+\w+)?\s*[{]*$", re
.MULTILINE
)
48 # The following number pattern match will only match if following criteria is met:
49 # There is leading non-(alphanumeric or _) character, and no following alphanumeric or _
50 # as the pattern is greedily match, so it is ok for the gDecNumberPattern or gHexNumberPattern to grab the maximum match
52 ## Regular expression for matching HEX number
53 gHexNumberPattern
= re
.compile("(?<=[^a-zA-Z0-9_])(0[xX])([0-9a-fA-F]+)(U(?=$|[^a-zA-Z0-9_]))?")
54 ## Regular expression for matching decimal number with 'U' postfix
55 gDecNumberPattern
= re
.compile("(?<=[^a-zA-Z0-9_])([0-9]+)U(?=$|[^a-zA-Z0-9_])")
56 ## Regular expression for matching constant with 'ULL' 'LL' postfix
57 gLongNumberPattern
= re
.compile("(?<=[^a-zA-Z0-9_])(0[xX][0-9a-fA-F]+|[0-9]+)U?LL(?=$|[^a-zA-Z0-9_])")
59 ## Regular expression for matching "Include ()" in asl file
60 gAslIncludePattern
= re
.compile("^(\s*)[iI]nclude\s*\(\"?([^\"\(\)]+)\"\)", re
.MULTILINE
)
61 ## Regular expression for matching C style #include "XXX.asl" in asl file
62 gAslCIncludePattern
= re
.compile(r
'^(\s*)#include\s*[<"]\s*([-\\/\w.]+)\s*([>"])', re
.MULTILINE
)
63 ## Patterns used to convert EDK conventions to EDK2 ECP conventions
64 gImportCodePatterns
= [
66 re
.compile('^(\s*)\(\*\*PeiServices\)\.PciCfg\s*=\s*([^;\s]+);', re
.MULTILINE
),
68 \\1 STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = {
69 \\1 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
70 \\1 &gEcpPeiPciCfgPpiGuid,
73 \\1 (**PeiServices).InstallPpi (PeiServices, &gEcpPeiPciCfgPpiList);
78 re
.compile('^(\s*)\(\*PeiServices\)->PciCfg\s*=\s*([^;\s]+);', re
.MULTILINE
),
80 \\1 STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = {
81 \\1 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
82 \\1 &gEcpPeiPciCfgPpiGuid,
85 \\1 (**PeiServices).InstallPpi (PeiServices, &gEcpPeiPciCfgPpiList);
90 re
.compile("(\s*).+->Modify[\s\n]*\(", re
.MULTILINE
),
91 '\\1PeiLibPciCfgModify ('
95 re
.compile("(\W*)gRT->ReportStatusCode[\s\n]*\(", re
.MULTILINE
),
96 '\\1EfiLibReportStatusCode ('
100 re
.compile('#include\s+EFI_GUID_DEFINITION\s*\(FirmwareFileSystem\)', re
.MULTILINE
),
101 '#include EFI_GUID_DEFINITION (FirmwareFileSystem)\n#include EFI_GUID_DEFINITION (FirmwareFileSystem2)'
105 re
.compile('gEfiFirmwareFileSystemGuid', re
.MULTILINE
),
106 'gEfiFirmwareFileSystem2Guid'
110 re
.compile('EFI_FVH_REVISION', re
.MULTILINE
),
111 'EFI_FVH_PI_REVISION'
115 re
.compile("(\s*)\S*CreateEvent\s*\([\s\n]*EFI_EVENT_SIGNAL_READY_TO_BOOT[^,]*,((?:[^;]+\n)+)(\s*\));", re
.MULTILINE
),
116 '\\1EfiCreateEventReadyToBoot (\\2\\3;'
120 re
.compile("(\s*)\S*CreateEvent\s*\([\s\n]*EFI_EVENT_SIGNAL_LEGACY_BOOT[^,]*,((?:[^;]+\n)+)(\s*\));", re
.MULTILINE
),
121 '\\1EfiCreateEventLegacyBoot (\\2\\3;'
124 # re.compile("(\W)(PEI_PCI_CFG_PPI)(\W)", re.MULTILINE),
129 ## file cache to avoid circular include in ASL file
130 gIncludedAslFile
= []
132 ## Trim preprocessed source code
134 # Remove extra content made by preprocessor. The preprocessor must enable the
135 # line number generation option when preprocessing.
137 # @param Source File to be trimmed
138 # @param Target File to store the trimmed content
139 # @param Convert If True, convert standard HEX format to MASM format
141 def TrimPreprocessedFile(Source
, Target
, ConvertHex
, TrimLong
):
142 CreateDirectory(os
.path
.dirname(Target
))
144 f
= open (Source
, 'r')
146 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Source
)
149 Lines
= f
.readlines()
152 PreprocessedFile
= ""
154 LineIndexOfOriginalFile
= None
156 LineControlDirectiveFound
= False
157 for Index
in range(len(Lines
)):
160 # Find out the name of files injected by preprocessor from the lines
161 # with Line Control directive
163 MatchList
= gLineControlDirective
.findall(Line
)
165 MatchList
= MatchList
[0]
166 if len(MatchList
) == 2:
167 LineNumber
= int(MatchList
[0], 0)
168 InjectedFile
= MatchList
[1]
169 # The first injetcted file must be the preprocessed file itself
170 if PreprocessedFile
== "":
171 PreprocessedFile
= InjectedFile
172 LineControlDirectiveFound
= True
174 elif PreprocessedFile
== "" or InjectedFile
!= PreprocessedFile
:
177 if LineIndexOfOriginalFile
is None:
179 # Any non-empty lines must be from original preprocessed file.
180 # And this must be the first one.
182 LineIndexOfOriginalFile
= Index
183 EdkLogger
.verbose("Found original file content starting from line %d"
184 % (LineIndexOfOriginalFile
+ 1))
187 Line
= gLongNumberPattern
.sub(r
"\1", Line
)
188 # convert HEX number format if indicated
190 Line
= gHexNumberPattern
.sub(r
"0\2h", Line
)
192 Line
= gHexNumberPattern
.sub(r
"\1\2", Line
)
194 # convert Decimal number format
195 Line
= gDecNumberPattern
.sub(r
"\1", Line
)
197 if LineNumber
is not None:
198 EdkLogger
.verbose("Got line directive: line=%d" % LineNumber
)
199 # in case preprocessor removed some lines, like blank or comment lines
200 if LineNumber
<= len(NewLines
):
202 NewLines
[LineNumber
- 1] = Line
204 if LineNumber
> (len(NewLines
) + 1):
205 for LineIndex
in range(len(NewLines
), LineNumber
-1):
206 NewLines
.append(os
.linesep
)
207 NewLines
.append(Line
)
209 EdkLogger
.verbose("Now we have lines: %d" % len(NewLines
))
211 NewLines
.append(Line
)
213 # in case there's no line directive or linemarker found
214 if (not LineControlDirectiveFound
) and NewLines
== []:
215 MulPatternFlag
= False
216 SinglePatternFlag
= False
218 for Index
in range(len(Lines
)):
220 if MulPatternFlag
== False and gTypedef_MulPattern
.search(Line
) is None:
221 if SinglePatternFlag
== False and gTypedef_SinglePattern
.search(Line
) is None:
222 # remove "#pragram pack" directive
223 if gPragmaPattern
.search(Line
) is None:
224 NewLines
.append(Line
)
226 elif SinglePatternFlag
== False:
227 SinglePatternFlag
= True
228 if Line
.find(";") >= 0:
229 SinglePatternFlag
= False
230 elif MulPatternFlag
== False:
231 # found "typedef struct, typedef union, union, struct", keep its position and set a flag
232 MulPatternFlag
= True
234 # match { and } to find the end of typedef definition
235 if Line
.find("{") >= 0:
237 elif Line
.find("}") >= 0:
240 # "typedef struct, typedef union, union, struct" must end with a ";"
241 if Brace
== 0 and Line
.find(";") >= 0:
242 MulPatternFlag
= False
246 f
= open (Target
, 'wb')
248 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Target
)
249 f
.writelines(NewLines
)
252 ## Trim preprocessed VFR file
254 # Remove extra content made by preprocessor. The preprocessor doesn't need to
255 # enable line number generation option when preprocessing.
257 # @param Source File to be trimmed
258 # @param Target File to store the trimmed content
260 def TrimPreprocessedVfr(Source
, Target
):
261 CreateDirectory(os
.path
.dirname(Target
))
264 f
= open (Source
, 'r')
266 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Source
)
268 Lines
= f
.readlines()
275 for Index
in range(len(Lines
)):
277 # don't trim the lines from "formset" definition to the end of file
278 if Line
.strip() == 'formset':
281 if FoundTypedef
== False and (Line
.find('#line') == 0 or Line
.find('# ') == 0):
282 # empty the line number directive if it's not aomong "typedef struct"
286 if FoundTypedef
== False and gTypedefPattern
.search(Line
) is None:
287 # keep "#pragram pack" directive
288 if gPragmaPattern
.search(Line
) is None:
291 elif FoundTypedef
== False:
292 # found "typedef struct", keept its position and set a flag
296 # match { and } to find the end of typedef definition
297 if Line
.find("{") >= 0:
299 elif Line
.find("}") >= 0:
302 # "typedef struct" must end with a ";"
303 if Brace
== 0 and Line
.find(";") >= 0:
306 # keep all "typedef struct" except to GUID, EFI_PLABEL and PAL_CALL_RETURN
307 if Line
.strip("} ;\r\n") in [TAB_GUID
, "EFI_PLABEL", "PAL_CALL_RETURN"]:
308 for i
in range(TypedefStart
, TypedefEnd
+1):
311 # save all lines trimmed
313 f
= open (Target
, 'w')
315 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Target
)
319 ## Read the content ASL file, including ASL included, recursively
321 # @param Source File to be read
322 # @param Indent Spaces before the Include() statement
323 # @param IncludePathList The list of external include file
324 # @param LocalSearchPath If LocalSearchPath is specified, this path will be searched
325 # first for the included file; otherwise, only the path specified
326 # in the IncludePathList will be searched.
328 def DoInclude(Source
, Indent
='', IncludePathList
=[], LocalSearchPath
=None):
333 # Search LocalSearchPath first if it is specified.
336 SearchPathList
= [LocalSearchPath
] + IncludePathList
338 SearchPathList
= IncludePathList
340 for IncludePath
in SearchPathList
:
341 IncludeFile
= os
.path
.join(IncludePath
, Source
)
342 if os
.path
.isfile(IncludeFile
):
343 F
= open(IncludeFile
, "r")
346 EdkLogger
.error("Trim", "Failed to find include file %s" % Source
)
348 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Source
)
351 # avoid A "include" B and B "include" A
352 IncludeFile
= os
.path
.abspath(os
.path
.normpath(IncludeFile
))
353 if IncludeFile
in gIncludedAslFile
:
354 EdkLogger
.warn("Trim", "Circular include",
355 ExtraData
= "%s -> %s" % (" -> ".join(gIncludedAslFile
), IncludeFile
))
357 gIncludedAslFile
.append(IncludeFile
)
360 LocalSearchPath
= None
361 Result
= gAslIncludePattern
.findall(Line
)
363 Result
= gAslCIncludePattern
.findall(Line
)
364 if len(Result
) == 0 or os
.path
.splitext(Result
[0][1])[1].lower() not in [".asl", ".asi"]:
365 NewFileContent
.append("%s%s" % (Indent
, Line
))
368 # We should first search the local directory if current file are using pattern #include "XXX"
370 if Result
[0][2] == '"':
371 LocalSearchPath
= os
.path
.dirname(IncludeFile
)
372 CurrentIndent
= Indent
+ Result
[0][0]
373 IncludedFile
= Result
[0][1]
374 NewFileContent
.extend(DoInclude(IncludedFile
, CurrentIndent
, IncludePathList
, LocalSearchPath
))
375 NewFileContent
.append("\n")
377 gIncludedAslFile
.pop()
380 return NewFileContent
385 # Replace ASL include statement with the content the included file
387 # @param Source File to be trimmed
388 # @param Target File to store the trimmed content
389 # @param IncludePathFile The file to log the external include path
391 def TrimAslFile(Source
, Target
, IncludePathFile
):
392 CreateDirectory(os
.path
.dirname(Target
))
394 SourceDir
= os
.path
.dirname(Source
)
399 # Add source directory as the first search directory
401 IncludePathList
= [SourceDir
]
404 # If additional include path file is specified, append them all
405 # to the search directory list.
410 for Line
in open(IncludePathFile
, 'r'):
412 if Line
.startswith("/I") or Line
.startswith ("-I"):
413 IncludePathList
.append(Line
[2:].strip())
415 EdkLogger
.warn("Trim", "Invalid include line in include list file.", IncludePathFile
, LineNum
)
417 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=IncludePathFile
)
419 Lines
= DoInclude(Source
, '', IncludePathList
)
422 # Undef MIN and MAX to avoid collision in ASL source code
424 Lines
.insert(0, "#undef MIN\n#undef MAX\n")
426 # save all lines trimmed
428 f
= open (Target
, 'w')
430 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Target
)
435 def GenerateVfrBinSec(ModuleName
, DebugDir
, OutputFile
):
437 if os
.path
.isdir(DebugDir
):
438 for CurrentDir
, Dirs
, Files
in os
.walk(DebugDir
):
439 for FileName
in Files
:
440 Name
, Ext
= os
.path
.splitext(FileName
)
441 if Ext
== '.c' and Name
!= 'AutoGen':
442 VfrNameList
.append (Name
+ 'Bin')
444 VfrNameList
.append (ModuleName
+ 'Strings')
446 EfiFileName
= os
.path
.join(DebugDir
, ModuleName
+ '.efi')
447 MapFileName
= os
.path
.join(DebugDir
, ModuleName
+ '.map')
448 VfrUniOffsetList
= GetVariableOffset(MapFileName
, EfiFileName
, VfrNameList
)
450 if not VfrUniOffsetList
:
454 fInputfile
= open(OutputFile
, "wb+", 0)
456 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, "File open failed for %s" %OutputFile
, None)
458 # Use a instance of BytesIO to cache data
459 fStringIO
= BytesIO('')
461 for Item
in VfrUniOffsetList
:
462 if (Item
[0].find("Strings") != -1):
464 # UNI offset in image.
466 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
468 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
469 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
470 fStringIO
.write(''.join(UniGuid
))
471 UniValue
= pack ('Q', int (Item
[1], 16))
472 fStringIO
.write (UniValue
)
475 # VFR binary offset in image.
477 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
479 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
480 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
481 fStringIO
.write(''.join(VfrGuid
))
483 VfrValue
= pack ('Q', int (Item
[1], 16))
484 fStringIO
.write (VfrValue
)
487 # write data into file.
490 fInputfile
.write (fStringIO
.getvalue())
492 EdkLogger
.error("Trim", FILE_WRITE_FAILURE
, "Write data to file %s failed, please check whether the file been locked or using by other applications." %OutputFile
, None)
497 ## Trim EDK source code file(s)
500 # @param Source File or directory to be trimmed
501 # @param Target File or directory to store the trimmed content
503 def TrimEdkSources(Source
, Target
):
504 if os
.path
.isdir(Source
):
505 for CurrentDir
, Dirs
, Files
in os
.walk(Source
):
511 for FileName
in Files
:
512 Dummy
, Ext
= os
.path
.splitext(FileName
)
513 if Ext
.upper() not in ['.C', '.H']: continue
514 if Target
is None or Target
== '':
516 os
.path
.join(CurrentDir
, FileName
),
517 os
.path
.join(CurrentDir
, FileName
)
521 os
.path
.join(CurrentDir
, FileName
),
522 os
.path
.join(Target
, CurrentDir
[len(Source
)+1:], FileName
)
525 TrimEdkSourceCode(Source
, Target
)
527 ## Trim one EDK source code file
529 # Do following replacement:
531 # (**PeiServices\).PciCfg = <*>;
533 # STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = {
534 # (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
535 # &gEcpPeiPciCfgPpiGuid,
538 # (**PeiServices).InstallPpi (PeiServices, &gEcpPeiPciCfgPpiList);
541 # => PeiLibPciCfgModify (<*>)
543 # gRT->ReportStatusCode (<*>)
544 # => EfiLibReportStatusCode (<*>)
546 # #include <LoadFile\.h>
547 # => #include <FvLoadFile.h>
549 # CreateEvent (EFI_EVENT_SIGNAL_READY_TO_BOOT, <*>)
550 # => EfiCreateEventReadyToBoot (<*>)
552 # CreateEvent (EFI_EVENT_SIGNAL_LEGACY_BOOT, <*>)
553 # => EfiCreateEventLegacyBoot (<*>)
555 # @param Source File to be trimmed
556 # @param Target File to store the trimmed content
558 def TrimEdkSourceCode(Source
, Target
):
559 EdkLogger
.verbose("\t%s -> %s" % (Source
, Target
))
560 CreateDirectory(os
.path
.dirname(Target
))
563 f
= open (Source
, 'rb')
565 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Source
)
571 for Re
, Repl
in gImportCodePatterns
:
573 NewLines
= Re
.sub(Repl
, Lines
)
575 NewLines
= Re
.sub(Repl
, NewLines
)
577 # save all lines if trimmed
578 if Source
== Target
and NewLines
== Lines
:
582 f
= open (Target
, 'wb')
584 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Target
)
589 ## Parse command line options
591 # Using standard Python module optparse to parse command line option of this tool.
593 # @retval Options A optparse.Values object containing the parsed options
594 # @retval InputFile Path of file to be trimmed
598 make_option("-s", "--source-code", dest
="FileType", const
="SourceCode", action
="store_const",
599 help="The input file is preprocessed source code, including C or assembly code"),
600 make_option("-r", "--vfr-file", dest
="FileType", const
="Vfr", action
="store_const",
601 help="The input file is preprocessed VFR file"),
602 make_option("--Vfr-Uni-Offset", dest
="FileType", const
="VfrOffsetBin", action
="store_const",
603 help="The input file is EFI image"),
604 make_option("-a", "--asl-file", dest
="FileType", const
="Asl", action
="store_const",
605 help="The input file is ASL file"),
606 make_option("-8", "--Edk-source-code", dest
="FileType", const
="EdkSourceCode", action
="store_const",
607 help="The input file is source code for Edk to be trimmed for ECP"),
609 make_option("-c", "--convert-hex", dest
="ConvertHex", action
="store_true",
610 help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),
612 make_option("-l", "--trim-long", dest
="TrimLong", action
="store_true",
613 help="Remove postfix of long number"),
614 make_option("-i", "--include-path-file", dest
="IncludePathFile",
615 help="The input file is include path list to search for ASL include file"),
616 make_option("-o", "--output", dest
="OutputFile",
617 help="File to store the trimmed content"),
618 make_option("--ModuleName", dest
="ModuleName", help="The module's BASE_NAME"),
619 make_option("--DebugDir", dest
="DebugDir",
620 help="Debug Output directory to store the output files"),
621 make_option("-v", "--verbose", dest
="LogLevel", action
="store_const", const
=EdkLogger
.VERBOSE
,
622 help="Run verbosely"),
623 make_option("-d", "--debug", dest
="LogLevel", type="int",
624 help="Run with debug information"),
625 make_option("-q", "--quiet", dest
="LogLevel", action
="store_const", const
=EdkLogger
.QUIET
,
627 make_option("-?", action
="help", help="show this help message and exit"),
630 # use clearer usage to override default usage message
631 UsageString
= "%prog [-s|-r|-a|--Vfr-Uni-Offset] [-c] [-v|-d <debug_level>|-q] [-i <include_path_file>] [-o <output_file>] [--ModuleName <ModuleName>] [--DebugDir <DebugDir>] [<input_file>]"
633 Parser
= OptionParser(description
=__copyright__
, version
=__version__
, option_list
=OptionList
, usage
=UsageString
)
634 Parser
.set_defaults(FileType
="Vfr")
635 Parser
.set_defaults(ConvertHex
=False)
636 Parser
.set_defaults(LogLevel
=EdkLogger
.INFO
)
638 Options
, Args
= Parser
.parse_args()
641 if Options
.FileType
== 'VfrOffsetBin':
645 EdkLogger
.error("Trim", OPTION_NOT_SUPPORTED
, ExtraData
=Parser
.get_usage())
647 EdkLogger
.error("Trim", OPTION_MISSING
, ExtraData
=Parser
.get_usage())
649 EdkLogger
.error("Trim", OPTION_NOT_SUPPORTED
, ExtraData
=Parser
.get_usage())
652 return Options
, InputFile
656 # This method mainly dispatch specific methods per the command line options.
657 # If no error found, return zero value so the caller of this tool can know
658 # if it's executed successfully or not.
660 # @retval 0 Tool was successful
661 # @retval 1 Tool failed
665 EdkLogger
.Initialize()
666 CommandOptions
, InputFile
= Options()
667 if CommandOptions
.LogLevel
< EdkLogger
.DEBUG_9
:
668 EdkLogger
.SetLevel(CommandOptions
.LogLevel
+ 1)
670 EdkLogger
.SetLevel(CommandOptions
.LogLevel
)
671 except FatalError
as X
:
675 if CommandOptions
.FileType
== "Vfr":
676 if CommandOptions
.OutputFile
is None:
677 CommandOptions
.OutputFile
= os
.path
.splitext(InputFile
)[0] + '.iii'
678 TrimPreprocessedVfr(InputFile
, CommandOptions
.OutputFile
)
679 elif CommandOptions
.FileType
== "Asl":
680 if CommandOptions
.OutputFile
is None:
681 CommandOptions
.OutputFile
= os
.path
.splitext(InputFile
)[0] + '.iii'
682 TrimAslFile(InputFile
, CommandOptions
.OutputFile
, CommandOptions
.IncludePathFile
)
683 elif CommandOptions
.FileType
== "EdkSourceCode":
684 TrimEdkSources(InputFile
, CommandOptions
.OutputFile
)
685 elif CommandOptions
.FileType
== "VfrOffsetBin":
686 GenerateVfrBinSec(CommandOptions
.ModuleName
, CommandOptions
.DebugDir
, CommandOptions
.OutputFile
)
688 if CommandOptions
.OutputFile
is None:
689 CommandOptions
.OutputFile
= os
.path
.splitext(InputFile
)[0] + '.iii'
690 TrimPreprocessedFile(InputFile
, CommandOptions
.OutputFile
, CommandOptions
.ConvertHex
, CommandOptions
.TrimLong
)
691 except FatalError
as X
:
694 if CommandOptions
is not None and CommandOptions
.LogLevel
<= EdkLogger
.DEBUG_9
:
695 EdkLogger
.quiet("(Python %s on %s) " % (platform
.python_version(), sys
.platform
) + traceback
.format_exc())
703 "Unknown fatal error when trimming [%s]" % InputFile
,
704 ExtraData
="\n(Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!)\n",
707 EdkLogger
.quiet("(Python %s on %s) " % (platform
.python_version(), sys
.platform
) + traceback
.format_exc())
712 if __name__
== '__main__':
714 ## 0-127 is a safe return range, and 1 is a standard default error
715 if r
< 0 or r
> 127: r
= 1