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