1## @file
2# This file contained the parser for define sections in INF file
3#
4# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
5#
6# SPDX-License-Identifier: BSD-2-Clause-Patent
7#
8
9'''
10InfDefineSectionParser
11'''
12##
13# Import Modules
14#
15import re
16
17from Library import DataType as DT
18from Library import GlobalData
19from Library.Parsing import MacroParser
20from Library.Misc import GetSplitValueList
21from Library.ParserValidate import IsValidArch
22from Object.Parser.InfCommonObject import InfLineCommentObject
23from Object.Parser.InfDefineObject import InfDefMember
24from Parser.InfParserMisc import InfExpandMacro
25from Object.Parser.InfMisc import ErrorInInf
26from Logger import StringTable as ST
27from Parser.InfParserMisc import InfParserSectionRoot
28
29## __GetValidateArchList
30#
31#
32def GetValidateArchList(LineContent):
33
34    TempArch = ''
35    ArchList = []
36    ValidateAcrhPatten = re.compile(r"^\s*#\s*VALID_ARCHITECTURES\s*=\s*.*$", re.DOTALL)
37
38    if ValidateAcrhPatten.match(LineContent):
39        TempArch = GetSplitValueList(LineContent, DT.TAB_EQUAL_SPLIT, 1)[1]
40
41        TempArch = GetSplitValueList(TempArch, '(', 1)[0]
42
43        ArchList = re.split('\s+', TempArch)
44        NewArchList = []
45        for Arch in ArchList:
46            if IsValidArch(Arch):
47                NewArchList.append(Arch)
48
49        ArchList = NewArchList
50
51    return ArchList
52
53class InfDefinSectionParser(InfParserSectionRoot):
54    def InfDefineParser(self, SectionString, InfSectionObject, FileName, SectionComment):
55
56        if SectionComment:
57            pass
58        #
59        # Parser Defines section content and fill self._ContentList dict.
60        #
61        StillCommentFalg  = False
62        HeaderComments = []
63        SectionContent = ''
64        ArchList       = []
65        _ContentList   = []
66        _ValueList     = []
67        #
68        # Add WORKSPACE to global Marco dict.
69        #
70        self.FileLocalMacros['WORKSPACE'] = GlobalData.gWORKSPACE
71
72        for Line in SectionString:
73            LineContent = Line[0]
74            LineNo      = Line[1]
75            TailComments   = ''
76            LineComment    = None
77
78            LineInfo       = ['', -1, '']
79            LineInfo[0]    = FileName
80            LineInfo[1]    = LineNo
81            LineInfo[2]    = LineContent
82
83            if LineContent.strip() == '':
84                continue
85            #
86            # The first time encountered VALIDATE_ARCHITECHERS will be considered as support arch list.
87            #
88            if not ArchList:
89                ArchList = GetValidateArchList(LineContent)
90
91            #
92            # Parser Comment
93            #
94            if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
95                #
96                # Last line is comments, and this line go on.
97                #
98                if StillCommentFalg:
99                    HeaderComments.append(Line)
100                    SectionContent += LineContent + DT.END_OF_LINE
101                    continue
102                #
103                # First time encounter comment
104                #
105                else:
106                    #
107                    # Clear original data
108                    #
109                    HeaderComments = []
110                    HeaderComments.append(Line)
111                    StillCommentFalg = True
112                    SectionContent += LineContent + DT.END_OF_LINE
113                    continue
114            else:
115                StillCommentFalg = False
116
117            if len(HeaderComments) >= 1:
118                LineComment = InfLineCommentObject()
119                LineCommentContent = ''
120                for Item in HeaderComments:
121                    LineCommentContent += Item[0] + DT.END_OF_LINE
122                LineComment.SetHeaderComments(LineCommentContent)
123
124            #
125            # Find Tail comment.
126            #
127            if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
128                TailComments = LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):]
129                LineContent = LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
130                if LineComment is None:
131                    LineComment = InfLineCommentObject()
132                LineComment.SetTailComments(TailComments)
133
134            #
135            # Find Macro
136            #
137            Name, Value = MacroParser((LineContent, LineNo),
138                                      FileName,
139                                      DT.MODEL_META_DATA_HEADER,
140                                      self.FileLocalMacros)
141            if Name is not None:
142                self.FileLocalMacros[Name] = Value
143                continue
144
145            #
146            # Replace with [Defines] section Macro
147            #
148            LineContent = InfExpandMacro(LineContent,
149                                         (FileName, LineContent, LineNo),
150                                         self.FileLocalMacros,
151                                         None, True)
152
153            SectionContent += LineContent + DT.END_OF_LINE
154
155            TokenList = GetSplitValueList(LineContent, DT.TAB_EQUAL_SPLIT, 1)
156            if len(TokenList) < 2:
157                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE,
158                           LineInfo=LineInfo)
159            _ValueList[0:len(TokenList)] = TokenList
160            if not _ValueList[0]:
161                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_NAME,
162                           LineInfo=LineInfo)
163            if not _ValueList[1]:
164                ErrorInInf(ST.ERR_INF_PARSER_DEFINE_ITEM_NO_VALUE,
165                           LineInfo=LineInfo)
166
167            Name, Value = _ValueList[0], _ValueList[1]
168
169            InfDefMemberObj = InfDefMember(Name, Value)
170            if (LineComment is not None):
171                InfDefMemberObj.Comments.SetHeaderComments(LineComment.GetHeaderComments())
172                InfDefMemberObj.Comments.SetTailComments(LineComment.GetTailComments())
173
174            InfDefMemberObj.CurrentLine.SetFileName(self.FullPath)
175            InfDefMemberObj.CurrentLine.SetLineString(LineContent)
176            InfDefMemberObj.CurrentLine.SetLineNo(LineNo)
177
178            _ContentList.append(InfDefMemberObj)
179            HeaderComments = []
180            TailComments = ''
181
182        #
183        # Current Define section archs
184        #
185        if not ArchList:
186            ArchList = ['COMMON']
187
188        InfSectionObject.SetAllContent(SectionContent)
189
190        InfSectionObject.SetDefines(_ContentList, Arch=ArchList)
191
192