1## @file
2# This file contained the miscellaneous functions for INF parser
3#
4# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
5#
6# SPDX-License-Identifier: BSD-2-Clause-Patent
7#
8
9'''
10InfParserMisc
11'''
12
13##
14# Import Modules
15#
16import re
17
18
19from Library import DataType as DT
20
21
22from Library.StringUtils import gMACRO_PATTERN
23from Library.StringUtils import ReplaceMacro
24from Object.Parser.InfMisc import ErrorInInf
25from Logger.StringTable import ERR_MARCO_DEFINITION_MISS_ERROR
26
27#
28# Global variable
29#
30
31#
32# Sections can exist in INF file
33#
34gINF_SECTION_DEF = {
35       DT.TAB_UNKNOWN.upper()          : DT.MODEL_UNKNOWN,
36       DT.TAB_HEADER.upper()           : DT.MODEL_META_DATA_FILE_HEADER,
37       DT.TAB_INF_DEFINES.upper()      : DT.MODEL_META_DATA_DEFINE,
38       DT.TAB_BUILD_OPTIONS.upper()    : DT.MODEL_META_DATA_BUILD_OPTION,
39       DT.TAB_LIBRARY_CLASSES.upper()  : DT.MODEL_EFI_LIBRARY_CLASS,
40       DT.TAB_PACKAGES.upper()         : DT.MODEL_META_DATA_PACKAGE,
41       DT.TAB_INF_FIXED_PCD.upper()    : DT.MODEL_PCD_FIXED_AT_BUILD,
42       DT.TAB_INF_PATCH_PCD.upper()    : DT.MODEL_PCD_PATCHABLE_IN_MODULE,
43       DT.TAB_INF_FEATURE_PCD.upper()  : DT.MODEL_PCD_FEATURE_FLAG,
44       DT.TAB_INF_PCD_EX.upper()       : DT.MODEL_PCD_DYNAMIC_EX,
45       DT.TAB_INF_PCD.upper()          : DT.MODEL_PCD_DYNAMIC,
46       DT.TAB_SOURCES.upper()          : DT.MODEL_EFI_SOURCE_FILE,
47       DT.TAB_GUIDS.upper()            : DT.MODEL_EFI_GUID,
48       DT.TAB_PROTOCOLS.upper()        : DT.MODEL_EFI_PROTOCOL,
49       DT.TAB_PPIS.upper()             : DT.MODEL_EFI_PPI,
50       DT.TAB_DEPEX.upper()            : DT.MODEL_EFI_DEPEX,
51       DT.TAB_BINARIES.upper()         : DT.MODEL_EFI_BINARY_FILE,
52       DT.TAB_USER_EXTENSIONS.upper()  : DT.MODEL_META_DATA_USER_EXTENSION
53       #
54       # EDK1 section
55       # TAB_NMAKE.upper()            : MODEL_META_DATA_NMAKE
56       #
57       }
58
59## InfExpandMacro
60#
61# Expand MACRO definition with MACROs defined in [Defines] section and specific section.
62# The MACROs defined in specific section has high priority and will be expanded firstly.
63#
64# @param LineInfo      Contain information of FileName, LineContent, LineNo
65# @param GlobalMacros  MACROs defined in INF [Defines] section
66# @param SectionMacros MACROs defined in INF specific section
67# @param Flag          If the flag set to True, need to skip macros in a quoted string
68#
69def InfExpandMacro(Content, LineInfo, GlobalMacros=None, SectionMacros=None, Flag=False):
70    if GlobalMacros is None:
71        GlobalMacros = {}
72    if SectionMacros is None:
73        SectionMacros = {}
74
75    FileName = LineInfo[0]
76    LineContent = LineInfo[1]
77    LineNo = LineInfo[2]
78
79    # Don't expand macros in comments
80    if LineContent.strip().startswith("#"):
81        return Content
82
83    NewLineInfo = (FileName, LineNo, LineContent)
84
85    #
86    # First, replace MARCOs with value defined in specific section
87    #
88    Content = ReplaceMacro (Content,
89                            SectionMacros,
90                            False,
91                            (LineContent, LineNo),
92                            FileName,
93                            Flag)
94    #
95    # Then replace MARCOs with value defined in [Defines] section
96    #
97    Content = ReplaceMacro (Content,
98                            GlobalMacros,
99                            False,
100                            (LineContent, LineNo),
101                            FileName,
102                            Flag)
103
104    MacroUsed = gMACRO_PATTERN.findall(Content)
105    #
106    # no macro found in String, stop replacing
107    #
108    if len(MacroUsed) == 0:
109        return Content
110    else:
111        for Macro in MacroUsed:
112            gQuotedMacro = re.compile(".*\".*\$\(%s\).*\".*"%(Macro))
113            if not gQuotedMacro.match(Content):
114                #
115                # Still have MACROs can't be expanded.
116                #
117                ErrorInInf (ERR_MARCO_DEFINITION_MISS_ERROR,
118                            LineInfo=NewLineInfo)
119
120    return Content
121
122
123## IsBinaryInf
124#
125# Judge whether the INF file is Binary INF or Common INF
126#
127# @param FileLineList     A list contain all INF file content.
128#
129def IsBinaryInf(FileLineList):
130    if not FileLineList:
131        return False
132
133    ReIsSourcesSection = re.compile("^\s*\[Sources.*\]\s.*$", re.IGNORECASE)
134    ReIsBinarySection = re.compile("^\s*\[Binaries.*\]\s.*$", re.IGNORECASE)
135    BinarySectionFoundFlag = False
136
137    for Line in FileLineList:
138        if ReIsSourcesSection.match(Line):
139            return False
140        if ReIsBinarySection.match(Line):
141            BinarySectionFoundFlag = True
142
143    if BinarySectionFoundFlag:
144        return True
145
146    return False
147
148
149## IsLibInstanceInfo
150#
151# Judge whether the string contain the information of ## @LIB_INSTANCES.
152#
153# @param  String
154#
155# @return Flag
156#
157def IsLibInstanceInfo(String):
158    ReIsLibInstance = re.compile("^\s*##\s*@LIB_INSTANCES\s*$")
159    if ReIsLibInstance.match(String):
160        return True
161    else:
162        return False
163
164
165## IsAsBuildOptionInfo
166#
167# Judge whether the string contain the information of ## @ASBUILD.
168#
169# @param  String
170#
171# @return Flag
172#
173def IsAsBuildOptionInfo(String):
174    ReIsAsBuildInstance = re.compile("^\s*##\s*@AsBuilt\s*$")
175    if ReIsAsBuildInstance.match(String):
176        return True
177    else:
178        return False
179
180
181class InfParserSectionRoot(object):
182    def __init__(self):
183        #
184        # Macros defined in [Define] section are file scope global
185        #
186        self.FileLocalMacros = {}
187
188        #
189        # Current Section Header content.
190        #
191        self.SectionHeaderContent = []
192
193        #
194        # Last time Section Header content.
195        #
196        self.LastSectionHeaderContent = []
197
198        self.FullPath = ''
199
200        self.InfDefSection              = None
201        self.InfBuildOptionSection      = None
202        self.InfLibraryClassSection     = None
203        self.InfPackageSection          = None
204        self.InfPcdSection              = None
205        self.InfSourcesSection          = None
206        self.InfUserExtensionSection    = None
207        self.InfProtocolSection         = None
208        self.InfPpiSection              = None
209        self.InfGuidSection             = None
210        self.InfDepexSection            = None
211        self.InfPeiDepexSection         = None
212        self.InfDxeDepexSection         = None
213        self.InfSmmDepexSection         = None
214        self.InfBinariesSection         = None
215        self.InfHeader                  = None
216        self.InfSpecialCommentSection   = None
217