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