1## @file
2# This file contained the parser for BuildOption 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'''
16InfBuildOptionSectionParser
17'''
18##
19# Import Modules
20#
21from Library import DataType as DT
22from Library import GlobalData
23import Logger.Log as Logger
24from Logger import StringTable as ST
25from Logger.ToolError import FORMAT_INVALID
26from Parser.InfParserMisc import InfExpandMacro
27from Library.Misc import GetSplitValueList
28from Parser.InfParserMisc import IsAsBuildOptionInfo
29from Library.Misc import GetHelpStringByRemoveHashKey
30from Library.ParserValidate import IsValidFamily
31from Library.ParserValidate import IsValidBuildOptionName
32from Parser.InfParserMisc import InfParserSectionRoot
33
34class InfBuildOptionSectionParser(InfParserSectionRoot):
35    ## InfBuildOptionParser
36    #
37    #
38    def InfBuildOptionParser(self, SectionString, InfSectionObject, FileName):
39
40        BuildOptionList = []
41        SectionContent  = ''
42
43        if not GlobalData.gIS_BINARY_INF:
44            ValueList       = []
45            LineNo          = 0
46
47            for Line in SectionString:
48                LineContent = Line[0]
49                LineNo      = Line[1]
50                TailComments = ''
51                ReplaceFlag = False
52
53                if LineContent.strip() == '':
54                    SectionContent += LineContent + DT.END_OF_LINE
55                    continue
56                #
57                # Found Comment
58                #
59                if LineContent.strip().startswith(DT.TAB_COMMENT_SPLIT):
60                    SectionContent += LineContent + DT.END_OF_LINE
61                    continue
62
63                #
64                # Find Tail comment.
65                #
66                if LineContent.find(DT.TAB_COMMENT_SPLIT) > -1:
67                    TailComments = LineContent[LineContent.find(DT.TAB_COMMENT_SPLIT):]
68                    LineContent = LineContent[:LineContent.find(DT.TAB_COMMENT_SPLIT)]
69
70                TokenList = GetSplitValueList(LineContent, DT.TAB_DEQUAL_SPLIT, 1)
71                if len(TokenList) == 2:
72                    #
73                    # "Replace" type build option
74                    #
75                    TokenList.append('True')
76                    ReplaceFlag = True
77                else:
78                    TokenList = GetSplitValueList(LineContent, DT.TAB_EQUAL_SPLIT, 1)
79                    #
80                    # "Append" type build option
81                    #
82                    if len(TokenList) == 2:
83                        TokenList.append('False')
84                    else:
85                        Logger.Error('InfParser',
86                                     FORMAT_INVALID,
87                                     ST.ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID,
88                                     ExtraData=LineContent,
89                                     File=FileName,
90                                     Line=LineNo)
91
92                ValueList[0:len(TokenList)] = TokenList
93
94                #
95                # Replace with [Defines] section Macro
96                #
97                ValueList[0] = InfExpandMacro(ValueList[0], (FileName, LineContent, LineNo),
98                                              self.FileLocalMacros, None)
99                ValueList[1] = InfExpandMacro(ValueList[1], (FileName, LineContent, LineNo),
100                                              self.FileLocalMacros, None, True)
101                EqualString = ''
102                if not ReplaceFlag:
103                    EqualString = ' = '
104                else:
105                    EqualString = ' == '
106
107                SectionContent += ValueList[0] + EqualString + ValueList[1] + TailComments + DT.END_OF_LINE
108
109                Family = GetSplitValueList(ValueList[0], DT.TAB_COLON_SPLIT, 1)
110                if len(Family) == 2:
111                    if not IsValidFamily(Family[0]):
112                        Logger.Error('InfParser',
113                                     FORMAT_INVALID,
114                                     ST.ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID,
115                                     ExtraData=LineContent,
116                                     File=FileName,
117                                     Line=LineNo)
118                    if not IsValidBuildOptionName(Family[1]):
119                        Logger.Error('InfParser',
120                                     FORMAT_INVALID,
121                                     ST.ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID,
122                                     ExtraData=LineContent,
123                                     File=FileName,
124                                     Line=LineNo)
125                if len(Family) == 1:
126                    if not IsValidBuildOptionName(Family[0]):
127                        Logger.Error('InfParser',
128                                     FORMAT_INVALID,
129                                     ST.ERR_INF_PARSER_BUILD_OPTION_FORMAT_INVALID,
130                                     ExtraData=LineContent,
131                                     File=FileName,
132                                     Line=LineNo)
133
134                BuildOptionList.append(ValueList)
135                ValueList = []
136                continue
137        else:
138            BuildOptionList = InfAsBuiltBuildOptionParser(SectionString, FileName)
139
140        #
141        # Current section archs
142        #
143        ArchList = []
144        LastItem = ''
145        for Item in self.LastSectionHeaderContent:
146            LastItem = Item
147            if not (Item[1] == '' or Item[1] == '') and Item[1] not in ArchList:
148                ArchList.append(Item[1])
149                InfSectionObject.SetSupArchList(Item[1])
150
151        InfSectionObject.SetAllContent(SectionContent)
152        if not InfSectionObject.SetBuildOptions(BuildOptionList, ArchList, SectionContent):
153            Logger.Error('InfParser',
154                         FORMAT_INVALID,
155                         ST.ERR_INF_PARSER_MODULE_SECTION_TYPE_ERROR%("[BuilOptions]"),
156                         File=FileName,
157                         Line=LastItem[3])
158
159## InfBuildOptionParser
160#
161#
162def InfAsBuiltBuildOptionParser(SectionString, FileName):
163    BuildOptionList = []
164    #
165    # AsBuild Binary INF file.
166    #
167    AsBuildOptionFlag = False
168    BuildOptionItem = []
169    Count = 0
170    for Line in SectionString:
171        Count += 1
172        LineContent = Line[0]
173        LineNo      = Line[1]
174
175        #
176        # The last line
177        #
178        if len(SectionString) == Count:
179            if LineContent.strip().startswith("##") and AsBuildOptionFlag:
180                BuildOptionList.append(BuildOptionItem)
181                BuildOptionList.append([GetHelpStringByRemoveHashKey(LineContent)])
182            elif LineContent.strip().startswith("#") and AsBuildOptionFlag:
183                BuildOptionInfo = GetHelpStringByRemoveHashKey(LineContent)
184                BuildOptionItem.append(BuildOptionInfo)
185                BuildOptionList.append(BuildOptionItem)
186            else:
187                if len(BuildOptionItem) > 0:
188                    BuildOptionList.append(BuildOptionItem)
189
190            break
191
192        if LineContent.strip() == '':
193            AsBuildOptionFlag = False
194            continue
195
196        if LineContent.strip().startswith("##") and AsBuildOptionFlag:
197            if len(BuildOptionItem) > 0:
198                BuildOptionList.append(BuildOptionItem)
199
200            BuildOptionItem = []
201
202        if not LineContent.strip().startswith("#"):
203            Logger.Error('InfParser',
204                        FORMAT_INVALID,
205                        ST.ERR_BO_CONTATIN_ASBUILD_AND_COMMON,
206                        File=FileName,
207                        Line=LineNo,
208                        ExtraData=LineContent)
209
210        if IsAsBuildOptionInfo(LineContent):
211            AsBuildOptionFlag = True
212            continue
213
214        if AsBuildOptionFlag:
215            BuildOptionInfo = GetHelpStringByRemoveHashKey(LineContent)
216            BuildOptionItem.append(BuildOptionInfo)
217
218    return BuildOptionList