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-2018, 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 InjectedFile
= os
.path
.normpath(InjectedFile
)
170 InjectedFile
= os
.path
.normcase(InjectedFile
)
171 # The first injetcted file must be the preprocessed file itself
172 if PreprocessedFile
== "":
173 PreprocessedFile
= InjectedFile
174 LineControlDirectiveFound
= True
176 elif PreprocessedFile
== "" or InjectedFile
!= PreprocessedFile
:
179 if LineIndexOfOriginalFile
is None:
181 # Any non-empty lines must be from original preprocessed file.
182 # And this must be the first one.
184 LineIndexOfOriginalFile
= Index
185 EdkLogger
.verbose("Found original file content starting from line %d"
186 % (LineIndexOfOriginalFile
+ 1))
189 Line
= gLongNumberPattern
.sub(r
"\1", Line
)
190 # convert HEX number format if indicated
192 Line
= gHexNumberPattern
.sub(r
"0\2h", Line
)
194 Line
= gHexNumberPattern
.sub(r
"\1\2", Line
)
196 # convert Decimal number format
197 Line
= gDecNumberPattern
.sub(r
"\1", Line
)
199 if LineNumber
is not None:
200 EdkLogger
.verbose("Got line directive: line=%d" % LineNumber
)
201 # in case preprocessor removed some lines, like blank or comment lines
202 if LineNumber
<= len(NewLines
):
204 NewLines
[LineNumber
- 1] = Line
206 if LineNumber
> (len(NewLines
) + 1):
207 for LineIndex
in range(len(NewLines
), LineNumber
-1):
208 NewLines
.append(os
.linesep
)
209 NewLines
.append(Line
)
211 EdkLogger
.verbose("Now we have lines: %d" % len(NewLines
))
213 NewLines
.append(Line
)
215 # in case there's no line directive or linemarker found
216 if (not LineControlDirectiveFound
) and NewLines
== []:
217 MulPatternFlag
= False
218 SinglePatternFlag
= False
220 for Index
in range(len(Lines
)):
222 if MulPatternFlag
== False and gTypedef_MulPattern
.search(Line
) is None:
223 if SinglePatternFlag
== False and gTypedef_SinglePattern
.search(Line
) is None:
224 # remove "#pragram pack" directive
225 if gPragmaPattern
.search(Line
) is None:
226 NewLines
.append(Line
)
228 elif SinglePatternFlag
== False:
229 SinglePatternFlag
= True
230 if Line
.find(";") >= 0:
231 SinglePatternFlag
= False
232 elif MulPatternFlag
== False:
233 # found "typedef struct, typedef union, union, struct", keep its position and set a flag
234 MulPatternFlag
= True
236 # match { and } to find the end of typedef definition
237 if Line
.find("{") >= 0:
239 elif Line
.find("}") >= 0:
242 # "typedef struct, typedef union, union, struct" must end with a ";"
243 if Brace
== 0 and Line
.find(";") >= 0:
244 MulPatternFlag
= False
248 f
= open (Target
, 'w')
250 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Target
)
251 f
.writelines(NewLines
)
254 ## Trim preprocessed VFR file
256 # Remove extra content made by preprocessor. The preprocessor doesn't need to
257 # enable line number generation option when preprocessing.
259 # @param Source File to be trimmed
260 # @param Target File to store the trimmed content
262 def TrimPreprocessedVfr(Source
, Target
):
263 CreateDirectory(os
.path
.dirname(Target
))
266 f
= open (Source
, 'r')
268 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Source
)
270 Lines
= f
.readlines()
277 for Index
in range(len(Lines
)):
279 # don't trim the lines from "formset" definition to the end of file
280 if Line
.strip() == 'formset':
283 if FoundTypedef
== False and (Line
.find('#line') == 0 or Line
.find('# ') == 0):
284 # empty the line number directive if it's not aomong "typedef struct"
288 if FoundTypedef
== False and gTypedefPattern
.search(Line
) is None:
289 # keep "#pragram pack" directive
290 if gPragmaPattern
.search(Line
) is None:
293 elif FoundTypedef
== False:
294 # found "typedef struct", keept its position and set a flag
298 # match { and } to find the end of typedef definition
299 if Line
.find("{") >= 0:
301 elif Line
.find("}") >= 0:
304 # "typedef struct" must end with a ";"
305 if Brace
== 0 and Line
.find(";") >= 0:
308 # keep all "typedef struct" except to GUID, EFI_PLABEL and PAL_CALL_RETURN
309 if Line
.strip("} ;\r\n") in [TAB_GUID
, "EFI_PLABEL", "PAL_CALL_RETURN"]:
310 for i
in range(TypedefStart
, TypedefEnd
+1):
313 # save all lines trimmed
315 f
= open (Target
, 'w')
317 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Target
)
321 ## Read the content ASL file, including ASL included, recursively
323 # @param Source File to be read
324 # @param Indent Spaces before the Include() statement
325 # @param IncludePathList The list of external include file
326 # @param LocalSearchPath If LocalSearchPath is specified, this path will be searched
327 # first for the included file; otherwise, only the path specified
328 # in the IncludePathList will be searched.
330 def DoInclude(Source
, Indent
='', IncludePathList
=[], LocalSearchPath
=None):
335 # Search LocalSearchPath first if it is specified.
338 SearchPathList
= [LocalSearchPath
] + IncludePathList
340 SearchPathList
= IncludePathList
342 for IncludePath
in SearchPathList
:
343 IncludeFile
= os
.path
.join(IncludePath
, Source
)
344 if os
.path
.isfile(IncludeFile
):
345 F
= open(IncludeFile
, "r")
348 EdkLogger
.error("Trim", "Failed to find include file %s" % Source
)
350 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Source
)
353 # avoid A "include" B and B "include" A
354 IncludeFile
= os
.path
.abspath(os
.path
.normpath(IncludeFile
))
355 if IncludeFile
in gIncludedAslFile
:
356 EdkLogger
.warn("Trim", "Circular include",
357 ExtraData
= "%s -> %s" % (" -> ".join(gIncludedAslFile
), IncludeFile
))
359 gIncludedAslFile
.append(IncludeFile
)
362 LocalSearchPath
= None
363 Result
= gAslIncludePattern
.findall(Line
)
365 Result
= gAslCIncludePattern
.findall(Line
)
366 if len(Result
) == 0 or os
.path
.splitext(Result
[0][1])[1].lower() not in [".asl", ".asi"]:
367 NewFileContent
.append("%s%s" % (Indent
, Line
))
370 # We should first search the local directory if current file are using pattern #include "XXX"
372 if Result
[0][2] == '"':
373 LocalSearchPath
= os
.path
.dirname(IncludeFile
)
374 CurrentIndent
= Indent
+ Result
[0][0]
375 IncludedFile
= Result
[0][1]
376 NewFileContent
.extend(DoInclude(IncludedFile
, CurrentIndent
, IncludePathList
, LocalSearchPath
))
377 NewFileContent
.append("\n")
379 gIncludedAslFile
.pop()
382 return NewFileContent
387 # Replace ASL include statement with the content the included file
389 # @param Source File to be trimmed
390 # @param Target File to store the trimmed content
391 # @param IncludePathFile The file to log the external include path
393 def TrimAslFile(Source
, Target
, IncludePathFile
):
394 CreateDirectory(os
.path
.dirname(Target
))
396 SourceDir
= os
.path
.dirname(Source
)
401 # Add source directory as the first search directory
403 IncludePathList
= [SourceDir
]
406 # If additional include path file is specified, append them all
407 # to the search directory list.
412 for Line
in open(IncludePathFile
, 'r'):
414 if Line
.startswith("/I") or Line
.startswith ("-I"):
415 IncludePathList
.append(Line
[2:].strip())
417 EdkLogger
.warn("Trim", "Invalid include line in include list file.", IncludePathFile
, LineNum
)
419 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=IncludePathFile
)
421 Lines
= DoInclude(Source
, '', IncludePathList
)
424 # Undef MIN and MAX to avoid collision in ASL source code
426 Lines
.insert(0, "#undef MIN\n#undef MAX\n")
428 # save all lines trimmed
430 f
= open (Target
, 'w')
432 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Target
)
437 def GenerateVfrBinSec(ModuleName
, DebugDir
, OutputFile
):
439 if os
.path
.isdir(DebugDir
):
440 for CurrentDir
, Dirs
, Files
in os
.walk(DebugDir
):
441 for FileName
in Files
:
442 Name
, Ext
= os
.path
.splitext(FileName
)
443 if Ext
== '.c' and Name
!= 'AutoGen':
444 VfrNameList
.append (Name
+ 'Bin')
446 VfrNameList
.append (ModuleName
+ 'Strings')
448 EfiFileName
= os
.path
.join(DebugDir
, ModuleName
+ '.efi')
449 MapFileName
= os
.path
.join(DebugDir
, ModuleName
+ '.map')
450 VfrUniOffsetList
= GetVariableOffset(MapFileName
, EfiFileName
, VfrNameList
)
452 if not VfrUniOffsetList
:
456 fInputfile
= open(OutputFile
, "wb+", 0)
458 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, "File open failed for %s" %OutputFile
, None)
460 # Use a instance of BytesIO to cache data
461 fStringIO
= BytesIO()
463 for Item
in VfrUniOffsetList
:
464 if (Item
[0].find("Strings") != -1):
466 # UNI offset in image.
468 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
470 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
471 fStringIO
.write(bytes(UniGuid
))
472 UniValue
= pack ('Q', int (Item
[1], 16))
473 fStringIO
.write (UniValue
)
476 # VFR binary offset in image.
478 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
480 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
481 fStringIO
.write(bytes(VfrGuid
))
482 VfrValue
= pack ('Q', int (Item
[1], 16))
483 fStringIO
.write (VfrValue
)
486 # write data into file.
489 fInputfile
.write (fStringIO
.getvalue())
491 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)
496 ## Trim EDK source code file(s)
499 # @param Source File or directory to be trimmed
500 # @param Target File or directory to store the trimmed content
502 def TrimEdkSources(Source
, Target
):
503 if os
.path
.isdir(Source
):
504 for CurrentDir
, Dirs
, Files
in os
.walk(Source
):
510 for FileName
in Files
:
511 Dummy
, Ext
= os
.path
.splitext(FileName
)
512 if Ext
.upper() not in ['.C', '.H']: continue
513 if Target
is None or Target
== '':
515 os
.path
.join(CurrentDir
, FileName
),
516 os
.path
.join(CurrentDir
, FileName
)
520 os
.path
.join(CurrentDir
, FileName
),
521 os
.path
.join(Target
, CurrentDir
[len(Source
)+1:], FileName
)
524 TrimEdkSourceCode(Source
, Target
)
526 ## Trim one EDK source code file
528 # Do following replacement:
530 # (**PeiServices\).PciCfg = <*>;
532 # STATIC EFI_PEI_PPI_DESCRIPTOR gEcpPeiPciCfgPpiList = {
533 # (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
534 # &gEcpPeiPciCfgPpiGuid,
537 # (**PeiServices).InstallPpi (PeiServices, &gEcpPeiPciCfgPpiList);
540 # => PeiLibPciCfgModify (<*>)
542 # gRT->ReportStatusCode (<*>)
543 # => EfiLibReportStatusCode (<*>)
545 # #include <LoadFile\.h>
546 # => #include <FvLoadFile.h>
548 # CreateEvent (EFI_EVENT_SIGNAL_READY_TO_BOOT, <*>)
549 # => EfiCreateEventReadyToBoot (<*>)
551 # CreateEvent (EFI_EVENT_SIGNAL_LEGACY_BOOT, <*>)
552 # => EfiCreateEventLegacyBoot (<*>)
554 # @param Source File to be trimmed
555 # @param Target File to store the trimmed content
557 def TrimEdkSourceCode(Source
, Target
):
558 EdkLogger
.verbose("\t%s -> %s" % (Source
, Target
))
559 CreateDirectory(os
.path
.dirname(Target
))
562 f
= open (Source
, 'r')
564 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Source
)
570 for Re
, Repl
in gImportCodePatterns
:
572 NewLines
= Re
.sub(Repl
, Lines
)
574 NewLines
= Re
.sub(Repl
, NewLines
)
576 # save all lines if trimmed
577 if Source
== Target
and NewLines
== Lines
:
581 f
= open (Target
, 'w')
583 EdkLogger
.error("Trim", FILE_OPEN_FAILURE
, ExtraData
=Target
)
588 ## Parse command line options
590 # Using standard Python module optparse to parse command line option of this tool.
592 # @retval Options A optparse.Values object containing the parsed options
593 # @retval InputFile Path of file to be trimmed
597 make_option("-s", "--source-code", dest
="FileType", const
="SourceCode", action
="store_const",
598 help="The input file is preprocessed source code, including C or assembly code"),
599 make_option("-r", "--vfr-file", dest
="FileType", const
="Vfr", action
="store_const",
600 help="The input file is preprocessed VFR file"),
601 make_option("--Vfr-Uni-Offset", dest
="FileType", const
="VfrOffsetBin", action
="store_const",
602 help="The input file is EFI image"),
603 make_option("-a", "--asl-file", dest
="FileType", const
="Asl", action
="store_const",
604 help="The input file is ASL file"),
605 make_option("-8", "--Edk-source-code", dest
="FileType", const
="EdkSourceCode", action
="store_const",
606 help="The input file is source code for Edk to be trimmed for ECP"),
608 make_option("-c", "--convert-hex", dest
="ConvertHex", action
="store_true",
609 help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),
611 make_option("-l", "--trim-long", dest
="TrimLong", action
="store_true",
612 help="Remove postfix of long number"),
613 make_option("-i", "--include-path-file", dest
="IncludePathFile",
614 help="The input file is include path list to search for ASL include file"),
615 make_option("-o", "--output", dest
="OutputFile",
616 help="File to store the trimmed content"),
617 make_option("--ModuleName", dest
="ModuleName", help="The module's BASE_NAME"),
618 make_option("--DebugDir", dest
="DebugDir",
619 help="Debug Output directory to store the output files"),
620 make_option("-v", "--verbose", dest
="LogLevel", action
="store_const", const
=EdkLogger
.VERBOSE
,
621 help="Run verbosely"),
622 make_option("-d", "--debug", dest
="LogLevel", type="int",
623 help="Run with debug information"),
624 make_option("-q", "--quiet", dest
="LogLevel", action
="store_const", const
=EdkLogger
.QUIET
,
626 make_option("-?", action
="help", help="show this help message and exit"),
629 # use clearer usage to override default usage message
630 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>]"
632 Parser
= OptionParser(description
=__copyright__
, version
=__version__
, option_list
=OptionList
, usage
=UsageString
)
633 Parser
.set_defaults(FileType
="Vfr")
634 Parser
.set_defaults(ConvertHex
=False)
635 Parser
.set_defaults(LogLevel
=EdkLogger
.INFO
)
637 Options
, Args
= Parser
.parse_args()
640 if Options
.FileType
== 'VfrOffsetBin':
644 EdkLogger
.error("Trim", OPTION_NOT_SUPPORTED
, ExtraData
=Parser
.get_usage())
646 EdkLogger
.error("Trim", OPTION_MISSING
, ExtraData
=Parser
.get_usage())
648 EdkLogger
.error("Trim", OPTION_NOT_SUPPORTED
, ExtraData
=Parser
.get_usage())
651 return Options
, InputFile
655 # This method mainly dispatch specific methods per the command line options.
656 # If no error found, return zero value so the caller of this tool can know
657 # if it's executed successfully or not.
659 # @retval 0 Tool was successful
660 # @retval 1 Tool failed
664 EdkLogger
.Initialize()
665 CommandOptions
, InputFile
= Options()
666 if CommandOptions
.LogLevel
< EdkLogger
.DEBUG_9
:
667 EdkLogger
.SetLevel(CommandOptions
.LogLevel
+ 1)
669 EdkLogger
.SetLevel(CommandOptions
.LogLevel
)
670 except FatalError
as X
:
674 if CommandOptions
.FileType
== "Vfr":
675 if CommandOptions
.OutputFile
is None:
676 CommandOptions
.OutputFile
= os
.path
.splitext(InputFile
)[0] + '.iii'
677 TrimPreprocessedVfr(InputFile
, CommandOptions
.OutputFile
)
678 elif CommandOptions
.FileType
== "Asl":
679 if CommandOptions
.OutputFile
is None:
680 CommandOptions
.OutputFile
= os
.path
.splitext(InputFile
)[0] + '.iii'
681 TrimAslFile(InputFile
, CommandOptions
.OutputFile
, CommandOptions
.IncludePathFile
)
682 elif CommandOptions
.FileType
== "EdkSourceCode":
683 TrimEdkSources(InputFile
, CommandOptions
.OutputFile
)
684 elif CommandOptions
.FileType
== "VfrOffsetBin":
685 GenerateVfrBinSec(CommandOptions
.ModuleName
, CommandOptions
.DebugDir
, CommandOptions
.OutputFile
)
687 if CommandOptions
.OutputFile
is None:
688 CommandOptions
.OutputFile
= os
.path
.splitext(InputFile
)[0] + '.iii'
689 TrimPreprocessedFile(InputFile
, CommandOptions
.OutputFile
, CommandOptions
.ConvertHex
, CommandOptions
.TrimLong
)
690 except FatalError
as X
:
693 if CommandOptions
is not None and CommandOptions
.LogLevel
<= EdkLogger
.DEBUG_9
:
694 EdkLogger
.quiet("(Python %s on %s) " % (platform
.python_version(), sys
.platform
) + traceback
.format_exc())
702 "Unknown fatal error when trimming [%s]" % InputFile
,
703 ExtraData
="\n(Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!)\n",
706 EdkLogger
.quiet("(Python %s on %s) " % (platform
.python_version(), sys
.platform
) + traceback
.format_exc())
711 if __name__
== '__main__':
713 ## 0-127 is a safe return range, and 1 is a standard default error
714 if r
< 0 or r
> 127: r
= 1