## @file
# Trim files preprocessed by compiler
#
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

##
# Import Modules
#
import Common.LongFilePathOs as os
import sys
import re
from io import BytesIO
import codecs
from optparse import OptionParser
from optparse import make_option
from Common.BuildToolError import *
from Common.Misc import *
from Common.DataType import *
from Common.BuildVersion import gBUILD_VERSION
import Common.EdkLogger as EdkLogger
from Common.LongFilePathSupport import OpenLongFilePath as open

# Version and Copyright
__version_number__ = ("0.10" + " " + gBUILD_VERSION)
__version__ = "%prog Version " + __version_number__
__copyright__ = "Copyright (c) 2007-2018, Intel Corporation. All rights reserved."

## Regular expression for matching Line Control directive like "#line xxx"
gLineControlDirective = re.compile(r'^\s*#(?:line)?\s+([0-9]+)\s+"*([^"]*)"')
## Regular expression for matching "typedef struct"
gTypedefPattern = re.compile(r"^\s*typedef\s+struct(\s+\w+)?\s*[{]*$", re.MULTILINE)
## Regular expression for matching "#pragma pack"
gPragmaPattern = re.compile(r"^\s*#pragma\s+pack", re.MULTILINE)
## Regular expression for matching "typedef"
gTypedef_SinglePattern = re.compile(r"^\s*typedef", re.MULTILINE)
## Regular expression for matching "typedef struct, typedef union, struct, union"
gTypedef_MulPattern = re.compile(r"^\s*(typedef)?\s+(struct|union)(\s+\w+)?\s*[{]*$", re.MULTILINE)

#
# The following number pattern match will only match if following criteria is met:
# There is leading non-(alphanumeric or _) character, and no following alphanumeric or _
# as the pattern is greedily match, so it is ok for the gDecNumberPattern or gHexNumberPattern to grab the maximum match
#
## Regular expression for matching HEX number
gHexNumberPattern = re.compile(r"(?<=[^a-zA-Z0-9_])(0[xX])([0-9a-fA-F]+)(U(?=$|[^a-zA-Z0-9_]))?")
## Regular expression for matching decimal number with 'U' postfix
gDecNumberPattern = re.compile(r"(?<=[^a-zA-Z0-9_])([0-9]+)U(?=$|[^a-zA-Z0-9_])")
## Regular expression for matching constant with 'ULL' 'LL' postfix
gLongNumberPattern = re.compile(r"(?<=[^a-zA-Z0-9_])(0[xX][0-9a-fA-F]+|[0-9]+)U?LL(?=$|[^a-zA-Z0-9_])")

## Regular expression for matching "Include ()" in asl file
gAslIncludePattern = re.compile(r"^(\s*)[iI]nclude\s*\(\"?([^\"\(\)]+)\"\)", re.MULTILINE)
## Regular expression for matching C style #include "XXX.asl" in asl file
gAslCIncludePattern = re.compile(r'^(\s*)#include\s*[<"]\s*([-\\/\w.]+)\s*([>"])', re.MULTILINE)
## Regular expression for matching "#pragma once"
gPragmaOncePattern = re.compile(r"^\s*#\s*pragma\s+once\b", re.IGNORECASE)
## Patterns used to convert EDK conventions to EDK2 ECP conventions

## Regular expression for finding header file inclusions
gIncludePattern = re.compile(r"^[ \t]*[%]?[ \t]*include(?:[ \t]*(?:\\(?:\r\n|\r|\n))*[ \t]*)*(?:\(?[\"<]?[ \t]*)([-\w.\\/() \t]+)(?:[ \t]*[\">]?\)?)", re.MULTILINE | re.UNICODE | re.IGNORECASE)


## file cache to avoid circular include in ASL file
gIncludedAslFile = []

## Trim preprocessed source code
#
# Remove extra content made by preprocessor. The preprocessor must enable the
# line number generation option when preprocessing.
#
# @param  Source    File to be trimmed
# @param  Target    File to store the trimmed content
# @param  Convert   If True, convert standard HEX format to MASM format
#
def TrimPreprocessedFile(Source, Target, ConvertHex, TrimLong, FileFormat):
    CreateDirectory(os.path.dirname(Target))
    try:
        with open(Source, "r") as File:
            Lines = File.readlines()
    except IOError:
        EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source)
    except:
        EdkLogger.error("Trim", AUTOGEN_ERROR, "TrimPreprocessedFile: Error while processing file", File=Source)

    PreprocessedFile = ""
    InjectedFile = ""
    LineIndexOfOriginalFile = None
    NewLines = []
    LineControlDirectiveFound = False
    for Index in range(len(Lines)):
        Line = Lines[Index]
        #
        # Find out the name of files injected by preprocessor from the lines
        # with Line Control directive
        #
        MatchList = gLineControlDirective.findall(Line)
        if MatchList != []:
            MatchList = MatchList[0]
            if len(MatchList) == 2:
                LineNumber = int(MatchList[0], 0)
                InjectedFile = MatchList[1]
                InjectedFile = os.path.normpath(InjectedFile)
                InjectedFile = os.path.normcase(InjectedFile)
                # The first injected file must be the preprocessed file itself
                if PreprocessedFile == "":
                    PreprocessedFile = InjectedFile
                if PreprocessedFile == InjectedFile:
                    # If this is a NASM source file, then keep the current
                    # #line statement replacing #line with NASM syntax %line to
                    # allow source debug to resolve to the NASM source file.
                    if FileFormat == 'NASM':
                        NewLines.append(Line.replace('#line', '%line', 1))
            LineControlDirectiveFound = True
            continue
        elif PreprocessedFile == "" or InjectedFile != PreprocessedFile:
            continue

        if LineIndexOfOriginalFile is None:
            #
            # Any non-empty lines must be from original preprocessed file.
            # And this must be the first one.
            #
            LineIndexOfOriginalFile = Index
            EdkLogger.verbose("Found original file content starting from line %d"
                              % (LineIndexOfOriginalFile + 1))

        if TrimLong:
            Line = gLongNumberPattern.sub(r"\1", Line)
        # convert HEX number format if indicated
        if ConvertHex:
            Line = gHexNumberPattern.sub(r"0\2h", Line)
        else:
            Line = gHexNumberPattern.sub(r"\1\2", Line)

        # convert Decimal number format
        Line = gDecNumberPattern.sub(r"\1", Line)

        if LineNumber is not None:
            EdkLogger.verbose("Got line directive: line=%d" % LineNumber)
            # in case preprocessor removed some lines, like blank or comment lines
            if LineNumber <= len(NewLines):
                # possible?
                NewLines[LineNumber - 1] = Line
            else:
                if LineNumber > (len(NewLines) + 1):
                    for LineIndex in range(len(NewLines), LineNumber-1):
                        NewLines.append(TAB_LINE_BREAK)
                NewLines.append(Line)
            LineNumber = None
            EdkLogger.verbose("Now we have lines: %d" % len(NewLines))
        else:
            NewLines.append(Line)

    # in case there's no line directive or linemarker found
    if (not LineControlDirectiveFound) and NewLines == []:
        MulPatternFlag = False
        SinglePatternFlag = False
        Brace = 0
        for Index in range(len(Lines)):
            Line = Lines[Index]
            if MulPatternFlag == False and gTypedef_MulPattern.search(Line) is None:
                if SinglePatternFlag == False and gTypedef_SinglePattern.search(Line) is None:
                    # remove "#pragram pack" directive
                    if gPragmaPattern.search(Line) is None:
                        NewLines.append(Line)
                    continue
                elif SinglePatternFlag == False:
                    SinglePatternFlag = True
                if Line.find(";") >= 0:
                    SinglePatternFlag = False
            elif MulPatternFlag == False:
                # found "typedef struct, typedef union, union, struct", keep its position and set a flag
                MulPatternFlag = True

            # match { and } to find the end of typedef definition
            if Line.find("{") >= 0:
                Brace += 1
            elif Line.find("}") >= 0:
                Brace -= 1

            # "typedef struct, typedef union, union, struct" must end with a ";"
            if Brace == 0 and Line.find(";") >= 0:
                MulPatternFlag = False

    # save to file
    try:
        with open(Target, 'w') as File:
            File.writelines(NewLines)
    except:
        EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)

## Trim preprocessed VFR file
#
# Remove extra content made by preprocessor. The preprocessor doesn't need to
# enable line number generation option when preprocessing.
#
# @param  Source    File to be trimmed
# @param  Target    File to store the trimmed content
#
def TrimPreprocessedVfr(Source, Target):
    CreateDirectory(os.path.dirname(Target))

    try:
        with open(Source, "r") as File:
            Lines = File.readlines()
    except:
        EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source)
    # read whole file

    FoundTypedef = False
    Brace = 0
    TypedefStart = 0
    TypedefEnd = 0
    for Index in range(len(Lines)):
        Line = Lines[Index]
        # don't trim the lines from "formset" definition to the end of file
        if Line.strip() == 'formset':
            break

        if FoundTypedef == False and (Line.find('#line') == 0 or Line.find('# ') == 0):
            # empty the line number directive if it's not aomong "typedef struct"
            Lines[Index] = "\n"
            continue

        if FoundTypedef == False and gTypedefPattern.search(Line) is None:
            # keep "#pragram pack" directive
            if gPragmaPattern.search(Line) is None:
                Lines[Index] = "\n"
            continue
        elif FoundTypedef == False:
            # found "typedef struct", keept its position and set a flag
            FoundTypedef = True
            TypedefStart = Index

        # match { and } to find the end of typedef definition
        if Line.find("{") >= 0:
            Brace += 1
        elif Line.find("}") >= 0:
            Brace -= 1

        # "typedef struct" must end with a ";"
        if Brace == 0 and Line.find(";") >= 0:
            FoundTypedef = False
            TypedefEnd = Index
            # keep all "typedef struct" except to GUID, EFI_PLABEL and PAL_CALL_RETURN
            if Line.strip("} ;\r\n") in [TAB_GUID, "EFI_PLABEL", "PAL_CALL_RETURN"]:
                for i in range(TypedefStart, TypedefEnd+1):
                    Lines[i] = "\n"

    # save all lines trimmed
    try:
        with open(Target, 'w') as File:
            File.writelines(Lines)
    except:
        EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)

# Create a banner to indicate the start and
# end of the included ASL file. Banner looks like:-
#
#   /*************************************
#   *               @param               *
#   *************************************/
#
# @param Pathname       File pathname to be included in the banner
#
def AddIncludeHeader(Pathname):
    StartLine = "/*" + '*' * (len(Pathname) + 4)
    EndLine = '*' * (len(Pathname) + 4) + "*/"
    Banner = '\n' + StartLine
    Banner += '\n' + ('{0}  {1}  {0}'.format('*', Pathname))
    Banner += '\n' + EndLine + '\n'
    return Banner

## Read the content  ASL file, including ASL included, recursively
#
# @param  Source            File to be read
# @param  Indent            Spaces before the Include() statement
# @param  IncludePathList   The list of external include file
# @param  LocalSearchPath   If LocalSearchPath is specified, this path will be searched
#                           first for the included file; otherwise, only the path specified
#                           in the IncludePathList will be searched.
#
def DoInclude(Source, Indent='', IncludePathList=[], LocalSearchPath=None, IncludeFileList = None, filetype=None):
    NewFileContent = []
    if IncludeFileList is None:
        IncludeFileList = []
    try:
        #
        # Search LocalSearchPath first if it is specified.
        #
        if LocalSearchPath:
            SearchPathList = [LocalSearchPath] + IncludePathList
        else:
            SearchPathList = IncludePathList

        for IncludePath in SearchPathList:
            IncludeFile = os.path.join(IncludePath, Source)
            if os.path.isfile(IncludeFile):
                try:
                    with open(IncludeFile, "r") as File:
                        F = File.readlines()
                except Exception:
                    with codecs.open(IncludeFile, "r", encoding='utf-8') as File:
                        F = File.readlines()
                break
        else:
            EdkLogger.error("Trim", FILE_NOT_FOUND, ExtraData="Failed to find include file %s" % Source)
            return []
    except Exception as e:
        if str(e) == str(FILE_NOT_FOUND):
            raise
        else:
            EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source)


    # avoid A "include" B and B "include" A
    IncludeFile = os.path.abspath(os.path.normpath(IncludeFile))
    if IncludeFile in gIncludedAslFile:
        EdkLogger.warn("Trim", "Circular include",
                       ExtraData= "%s -> %s" % (" -> ".join(gIncludedAslFile), IncludeFile))
        return []
    gIncludedAslFile.append(IncludeFile)
    IncludeFileList.append(IncludeFile.strip())
    for Line in F:
        LocalSearchPath = None
        if filetype == "ASL":
            Result = gAslIncludePattern.findall(Line)
            if len(Result) == 0:
                Result = gAslCIncludePattern.findall(Line)
                if len(Result) == 0 or os.path.splitext(Result[0][1])[1].lower() not in [".asl", ".asi"]:
                    if gPragmaOncePattern.match(Line):
                        continue
                    NewFileContent.append("%s%s" % (Indent, Line))
                    continue
                #
                # We should first search the local directory if current file are using pattern #include "XXX"
                #
                if Result[0][2] == '"':
                    LocalSearchPath = os.path.dirname(IncludeFile)
            CurrentIndent = Indent + Result[0][0]
            IncludedFile = Result[0][1]
            NewFileContent.append(AddIncludeHeader(IncludedFile+" --START"))
            NewFileContent.extend(DoInclude(IncludedFile, CurrentIndent, IncludePathList, LocalSearchPath,IncludeFileList,filetype))
            NewFileContent.append(AddIncludeHeader(IncludedFile+" --END"))
            NewFileContent.append("\n")
        elif filetype == "ASM":
            Result = gIncludePattern.findall(Line)
            if len(Result) == 0:
                NewFileContent.append("%s%s" % (Indent, Line))
                continue

            IncludedFile = Result[0]

            IncludedFile = IncludedFile.strip()
            IncludedFile = os.path.normpath(IncludedFile)
            NewFileContent.append(AddIncludeHeader(IncludedFile+" --START"))
            NewFileContent.extend(DoInclude(IncludedFile, '', IncludePathList, LocalSearchPath,IncludeFileList,filetype))
            NewFileContent.append(AddIncludeHeader(IncludedFile+" --END"))
            NewFileContent.append("\n")

    gIncludedAslFile.pop()

    return NewFileContent


## Trim ASL file
#
# Replace ASL include statement with the content the included file
#
# @param  Source          File to be trimmed
# @param  Target          File to store the trimmed content
# @param  IncludePathFile The file to log the external include path
#
def TrimAslFile(Source, Target, IncludePathFile,AslDeps = False):
    CreateDirectory(os.path.dirname(Target))

    SourceDir = os.path.dirname(Source)
    if SourceDir == '':
        SourceDir = '.'

    #
    # Add source directory as the first search directory
    #
    IncludePathList = [SourceDir]

    #
    # If additional include path file is specified, append them all
    # to the search directory list.
    #
    if IncludePathFile:
        try:
            LineNum = 0
            with open(IncludePathFile, 'r') as File:
                FileLines = File.readlines()
            for Line in FileLines:
                LineNum += 1
                if Line.startswith("/I") or Line.startswith ("-I"):
                    IncludePathList.append(Line[2:].strip())
                else:
                    EdkLogger.warn("Trim", "Invalid include line in include list file.", IncludePathFile, LineNum)
        except:
            EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=IncludePathFile)
    AslIncludes = []
    Lines = DoInclude(Source, '', IncludePathList,IncludeFileList=AslIncludes,filetype='ASL')
    AslIncludes = [item for item in AslIncludes if item !=Source]
    SaveFileOnChange(os.path.join(os.path.dirname(Target),os.path.basename(Source))+".trim.deps", " \\\n".join([Source+":"] +AslIncludes),False)

    #
    # Undef MIN and MAX to avoid collision in ASL source code
    #
    Lines.insert(0, "#undef MIN\n#undef MAX\n")

    # save all lines trimmed
    try:
        with open(Target, 'w') as File:
            File.writelines(Lines)
    except:
        EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)

## Trim ASM file
#
# Output ASM include statement with the content the included file
#
# @param  Source          File to be trimmed
# @param  Target          File to store the trimmed content
# @param  IncludePathFile The file to log the external include path
#
def TrimAsmFile(Source, Target, IncludePathFile):
    CreateDirectory(os.path.dirname(Target))

    SourceDir = os.path.dirname(Source)
    if SourceDir == '':
        SourceDir = '.'

    #
    # Add source directory as the first search directory
    #
    IncludePathList = [SourceDir]
    #
    # If additional include path file is specified, append them all
    # to the search directory list.
    #
    if IncludePathFile:
        try:
            LineNum = 0
            with open(IncludePathFile, 'r') as File:
                FileLines = File.readlines()
            for Line in FileLines:
                LineNum += 1
                if Line.startswith("/I") or Line.startswith ("-I"):
                    IncludePathList.append(Line[2:].strip())
                else:
                    EdkLogger.warn("Trim", "Invalid include line in include list file.", IncludePathFile, LineNum)
        except:
            EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=IncludePathFile)
    AsmIncludes = []
    Lines = DoInclude(Source, '', IncludePathList,IncludeFileList=AsmIncludes,filetype='ASM')
    AsmIncludes = [item for item in AsmIncludes if item != Source]
    if AsmIncludes:
        SaveFileOnChange(os.path.join(os.path.dirname(Target),os.path.basename(Source))+".trim.deps", " \\\n".join([Source+":"] +AsmIncludes),False)
    # save all lines trimmed
    try:
        with open(Target, 'w') as File:
            File.writelines(Lines)
    except:
        EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)

def GenerateVfrBinSec(ModuleName, DebugDir, OutputFile):
    VfrNameList = []
    if os.path.isdir(DebugDir):
        for CurrentDir, Dirs, Files in os.walk(DebugDir):
            for FileName in Files:
                Name, Ext = os.path.splitext(FileName)
                if Ext == '.c' and Name != 'AutoGen':
                    VfrNameList.append (Name + 'Bin')

    VfrNameList.append (ModuleName + 'Strings')

    EfiFileName = os.path.join(DebugDir, ModuleName + '.efi')
    MapFileName = os.path.join(DebugDir, ModuleName + '.map')
    VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrNameList)

    if not VfrUniOffsetList:
        return

    try:
        fInputfile = open(OutputFile, "wb+")
    except:
        EdkLogger.error("Trim", FILE_OPEN_FAILURE, "File open failed for %s" %OutputFile, None)

    # Use a instance of BytesIO to cache data
    fStringIO = BytesIO()

    for Item in VfrUniOffsetList:
        if (Item[0].find("Strings") != -1):
            #
            # UNI offset in image.
            # GUID + Offset
            # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
            #
            UniGuid = b'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f'
            fStringIO.write(UniGuid)
            UniValue = pack ('Q', int (Item[1], 16))
            fStringIO.write (UniValue)
        else:
            #
            # VFR binary offset in image.
            # GUID + Offset
            # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
            #
            VfrGuid = b'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2'
            fStringIO.write(VfrGuid)
            type (Item[1])
            VfrValue = pack ('Q', int (Item[1], 16))
            fStringIO.write (VfrValue)

    #
    # write data into file.
    #
    try :
        fInputfile.write (fStringIO.getvalue())
    except:
        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)

    fStringIO.close ()
    fInputfile.close ()


## Parse command line options
#
# Using standard Python module optparse to parse command line option of this tool.
#
# @retval Options   A optparse.Values object containing the parsed options
# @retval InputFile Path of file to be trimmed
#
def Options():
    OptionList = [
        make_option("-s", "--source-code", dest="FileType", const="SourceCode", action="store_const",
                          help="The input file is preprocessed source code, including C or assembly code"),
        make_option("-f", "--source-code-format", dest="FileFormat", type="choice", choices=["NASM","NONE"], default="NONE",
                          help="The format of the input file(NASM)"),
        make_option("-r", "--vfr-file", dest="FileType", const="Vfr", action="store_const",
                          help="The input file is preprocessed VFR file"),
        make_option("--Vfr-Uni-Offset", dest="FileType", const="VfrOffsetBin", action="store_const",
                          help="The input file is EFI image"),
        make_option("--asl-deps", dest="AslDeps", const="True", action="store_const",
                          help="Generate Asl dependent files."),
        make_option("-a", "--asl-file", dest="FileType", const="Asl", action="store_const",
                          help="The input file is ASL file"),
        make_option( "--asm-file", dest="FileType", const="Asm", action="store_const",
                          help="The input file is asm file"),
        make_option("-c", "--convert-hex", dest="ConvertHex", action="store_true",
                          help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),

        make_option("-l", "--trim-long", dest="TrimLong", action="store_true",
                          help="Remove postfix of long number"),
        make_option("-i", "--include-path-file", dest="IncludePathFile",
                          help="The input file is include path list to search for ASL include file"),
        make_option("-o", "--output", dest="OutputFile",
                          help="File to store the trimmed content"),
        make_option("--ModuleName", dest="ModuleName", help="The module's BASE_NAME"),
        make_option("--DebugDir", dest="DebugDir",
                          help="Debug Output directory to store the output files"),
        make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE,
                          help="Run verbosely"),
        make_option("-d", "--debug", dest="LogLevel", type="int",
                          help="Run with debug information"),
        make_option("-q", "--quiet", dest="LogLevel", action="store_const", const=EdkLogger.QUIET,
                          help="Run quietly"),
        make_option("-?", action="help", help="show this help message and exit"),
    ]

    # use clearer usage to override default usage message
    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>]"

    Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString)
    Parser.set_defaults(FileType="Vfr")
    Parser.set_defaults(ConvertHex=False)
    Parser.set_defaults(LogLevel=EdkLogger.INFO)

    Options, Args = Parser.parse_args()

    # error check
    if Options.FileType == 'VfrOffsetBin':
        if len(Args) == 0:
            return Options, ''
        elif len(Args) > 1:
            EdkLogger.error("Trim", OPTION_NOT_SUPPORTED, ExtraData=Parser.get_usage())
    if len(Args) == 0:
        EdkLogger.error("Trim", OPTION_MISSING, ExtraData=Parser.get_usage())
    if len(Args) > 1:
        EdkLogger.error("Trim", OPTION_NOT_SUPPORTED, ExtraData=Parser.get_usage())

    InputFile = Args[0]
    return Options, InputFile

## Entrance method
#
# This method mainly dispatch specific methods per the command line options.
# If no error found, return zero value so the caller of this tool can know
# if it's executed successfully or not.
#
# @retval 0     Tool was successful
# @retval 1     Tool failed
#
def Main():
    try:
        EdkLogger.Initialize()
        CommandOptions, InputFile = Options()
        if CommandOptions.LogLevel < EdkLogger.DEBUG_9:
            EdkLogger.SetLevel(CommandOptions.LogLevel + 1)
        else:
            EdkLogger.SetLevel(CommandOptions.LogLevel)
    except FatalError as X:
        return 1

    try:
        if CommandOptions.FileType == "Vfr":
            if CommandOptions.OutputFile is None:
                CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
            TrimPreprocessedVfr(InputFile, CommandOptions.OutputFile)
        elif CommandOptions.FileType == "Asl":
            if CommandOptions.OutputFile is None:
                CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
            TrimAslFile(InputFile, CommandOptions.OutputFile, CommandOptions.IncludePathFile,CommandOptions.AslDeps)
        elif CommandOptions.FileType == "VfrOffsetBin":
            GenerateVfrBinSec(CommandOptions.ModuleName, CommandOptions.DebugDir, CommandOptions.OutputFile)
        elif CommandOptions.FileType == "Asm":
            TrimAsmFile(InputFile, CommandOptions.OutputFile, CommandOptions.IncludePathFile)
        else :
            if CommandOptions.OutputFile is None:
                CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
            TrimPreprocessedFile(InputFile, CommandOptions.OutputFile, CommandOptions.ConvertHex, CommandOptions.TrimLong, CommandOptions.FileFormat)
    except FatalError as X:
        import platform
        import traceback
        if CommandOptions is not None and CommandOptions.LogLevel <= EdkLogger.DEBUG_9:
            EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
        return 1
    except:
        import traceback
        import platform
        EdkLogger.error(
                    "\nTrim",
                    CODE_ERROR,
                    "Unknown fatal error when trimming [%s]" % InputFile,
                    ExtraData="\n(Please send email to %s for help, attaching following call stack trace!)\n" % MSG_EDKII_MAIL_ADDR,
                    RaiseError=False
                    )
        EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
        return 1

    return 0

if __name__ == '__main__':
    r = Main()
    ## 0-127 is a safe return range, and 1 is a standard default error
    if r < 0 or r > 127: r = 1
    sys.exit(r)

