]>
Commit | Line | Data |
---|---|---|
4234283c LG |
1 | ## @file\r |
2 | # This file is used to define comment parsing interface\r | |
3 | #\r | |
64285f15 | 4 | # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r |
4234283c | 5 | #\r |
f7496d71 LG |
6 | # This program and the accompanying materials are licensed and made available\r |
7 | # under the terms and conditions of the BSD License which accompanies this\r | |
8 | # distribution. The full text of the license may be found at\r | |
4234283c LG |
9 | # http://opensource.org/licenses/bsd-license.php\r |
10 | #\r | |
11 | # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
12 | # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
13 | #\r | |
14 | \r | |
15 | '''\r | |
16 | CommentParsing\r | |
17 | '''\r | |
18 | \r | |
19 | ##\r | |
20 | # Import Modules\r | |
21 | #\r | |
22 | import re\r | |
23 | \r | |
64285f15 YZ |
24 | from Library.StringUtils import GetSplitValueList\r |
25 | from Library.StringUtils import CleanString2\r | |
4234283c LG |
26 | from Library.DataType import HEADER_COMMENT_NOT_STARTED\r |
27 | from Library.DataType import TAB_COMMENT_SPLIT\r | |
28 | from Library.DataType import HEADER_COMMENT_LICENSE\r | |
29 | from Library.DataType import HEADER_COMMENT_ABSTRACT\r | |
30 | from Library.DataType import HEADER_COMMENT_COPYRIGHT\r | |
31 | from Library.DataType import HEADER_COMMENT_DESCRIPTION\r | |
32 | from Library.DataType import TAB_SPACE_SPLIT\r | |
33 | from Library.DataType import TAB_COMMA_SPLIT\r | |
34 | from Library.DataType import SUP_MODULE_LIST\r | |
421ccda3 HC |
35 | from Library.DataType import TAB_VALUE_SPLIT\r |
36 | from Library.DataType import TAB_PCD_VALIDRANGE\r | |
37 | from Library.DataType import TAB_PCD_VALIDLIST\r | |
38 | from Library.DataType import TAB_PCD_EXPRESSION\r | |
39 | from Library.DataType import TAB_PCD_PROMPT\r | |
40 | from Library.DataType import TAB_CAPHEX_START\r | |
41 | from Library.DataType import TAB_HEX_START\r | |
42 | from Library.DataType import PCD_ERR_CODE_MAX_SIZE\r | |
43 | from Library.ExpressionValidate import IsValidRangeExpr\r | |
44 | from Library.ExpressionValidate import IsValidListExpr\r | |
45 | from Library.ExpressionValidate import IsValidLogicalExpr\r | |
4234283c LG |
46 | from Object.POM.CommonObject import TextObject\r |
47 | from Object.POM.CommonObject import PcdErrorObject\r | |
48 | import Logger.Log as Logger\r | |
49 | from Logger.ToolError import FORMAT_INVALID\r | |
50 | from Logger.ToolError import FORMAT_NOT_SUPPORTED\r | |
51 | from Logger import StringTable as ST\r | |
52 | \r | |
53 | ## ParseHeaderCommentSection\r | |
54 | #\r | |
55 | # Parse Header comment section lines, extract Abstract, Description, Copyright\r | |
56 | # , License lines\r | |
57 | #\r | |
58 | # @param CommentList: List of (Comment, LineNumber)\r | |
59 | # @param FileName: FileName of the comment\r | |
60 | #\r | |
421ccda3 | 61 | def ParseHeaderCommentSection(CommentList, FileName = None, IsBinaryHeader = False):\r |
4234283c LG |
62 | Abstract = ''\r |
63 | Description = ''\r | |
64 | Copyright = ''\r | |
65 | License = ''\r | |
66 | EndOfLine = "\n"\r | |
421ccda3 HC |
67 | if IsBinaryHeader:\r |
68 | STR_HEADER_COMMENT_START = "@BinaryHeader"\r | |
69 | else:\r | |
70 | STR_HEADER_COMMENT_START = "@file"\r | |
4234283c | 71 | HeaderCommentStage = HEADER_COMMENT_NOT_STARTED\r |
f7496d71 | 72 | \r |
4234283c LG |
73 | #\r |
74 | # first find the last copyright line\r | |
75 | #\r | |
76 | Last = 0\r | |
1b2e0772 | 77 | for Index in range(len(CommentList)-1, 0, -1):\r |
4234283c LG |
78 | Line = CommentList[Index][0]\r |
79 | if _IsCopyrightLine(Line):\r | |
80 | Last = Index\r | |
81 | break\r | |
f7496d71 | 82 | \r |
4234283c LG |
83 | for Item in CommentList:\r |
84 | Line = Item[0]\r | |
85 | LineNo = Item[1]\r | |
f7496d71 | 86 | \r |
4234283c LG |
87 | if not Line.startswith(TAB_COMMENT_SPLIT) and Line:\r |
88 | Logger.Error("\nUPT", FORMAT_INVALID, ST.ERR_INVALID_COMMENT_FORMAT, FileName, Item[1])\r | |
89 | Comment = CleanString2(Line)[1]\r | |
90 | Comment = Comment.strip()\r | |
91 | #\r | |
f7496d71 | 92 | # if there are blank lines between License or Description, keep them as they would be\r |
4234283c LG |
93 | # indication of different block; or in the position that Abstract should be, also keep it\r |
94 | # as it indicates that no abstract\r | |
95 | #\r | |
96 | if not Comment and HeaderCommentStage not in [HEADER_COMMENT_LICENSE, \\r | |
97 | HEADER_COMMENT_DESCRIPTION, HEADER_COMMENT_ABSTRACT]:\r | |
98 | continue\r | |
f7496d71 | 99 | \r |
4234283c LG |
100 | if HeaderCommentStage == HEADER_COMMENT_NOT_STARTED:\r |
101 | if Comment.startswith(STR_HEADER_COMMENT_START):\r | |
102 | HeaderCommentStage = HEADER_COMMENT_ABSTRACT\r | |
103 | else:\r | |
104 | License += Comment + EndOfLine\r | |
105 | else:\r | |
106 | if HeaderCommentStage == HEADER_COMMENT_ABSTRACT:\r | |
107 | #\r | |
108 | # in case there is no abstract and description\r | |
109 | #\r | |
110 | if not Comment:\r | |
4234283c LG |
111 | HeaderCommentStage = HEADER_COMMENT_DESCRIPTION\r |
112 | elif _IsCopyrightLine(Comment):\r | |
113 | Result, ErrMsg = _ValidateCopyright(Comment)\r | |
114 | ValidateCopyright(Result, ST.WRN_INVALID_COPYRIGHT, FileName, LineNo, ErrMsg)\r | |
115 | Copyright += Comment + EndOfLine\r | |
116 | HeaderCommentStage = HEADER_COMMENT_COPYRIGHT\r | |
f7496d71 | 117 | else:\r |
4234283c LG |
118 | Abstract += Comment + EndOfLine\r |
119 | HeaderCommentStage = HEADER_COMMENT_DESCRIPTION\r | |
120 | elif HeaderCommentStage == HEADER_COMMENT_DESCRIPTION:\r | |
121 | #\r | |
122 | # in case there is no description\r | |
f7496d71 | 123 | #\r |
4234283c LG |
124 | if _IsCopyrightLine(Comment):\r |
125 | Result, ErrMsg = _ValidateCopyright(Comment)\r | |
126 | ValidateCopyright(Result, ST.WRN_INVALID_COPYRIGHT, FileName, LineNo, ErrMsg)\r | |
127 | Copyright += Comment + EndOfLine\r | |
128 | HeaderCommentStage = HEADER_COMMENT_COPYRIGHT\r | |
129 | else:\r | |
f7496d71 | 130 | Description += Comment + EndOfLine\r |
4234283c LG |
131 | elif HeaderCommentStage == HEADER_COMMENT_COPYRIGHT:\r |
132 | if _IsCopyrightLine(Comment):\r | |
133 | Result, ErrMsg = _ValidateCopyright(Comment)\r | |
134 | ValidateCopyright(Result, ST.WRN_INVALID_COPYRIGHT, FileName, LineNo, ErrMsg)\r | |
135 | Copyright += Comment + EndOfLine\r | |
136 | else:\r | |
137 | #\r | |
138 | # Contents after copyright line are license, those non-copyright lines in between\r | |
f7496d71 | 139 | # copyright line will be discarded\r |
4234283c LG |
140 | #\r |
141 | if LineNo > Last:\r | |
142 | if License:\r | |
143 | License += EndOfLine\r | |
144 | License += Comment + EndOfLine\r | |
f7496d71 | 145 | HeaderCommentStage = HEADER_COMMENT_LICENSE\r |
4234283c LG |
146 | else:\r |
147 | if not Comment and not License:\r | |
148 | continue\r | |
149 | License += Comment + EndOfLine\r | |
f7496d71 | 150 | \r |
4234283c LG |
151 | return Abstract.strip(), Description.strip(), Copyright.strip(), License.strip()\r |
152 | \r | |
153 | ## _IsCopyrightLine\r | |
f7496d71 LG |
154 | # check whether current line is copyright line, the criteria is whether there is case insensitive keyword "Copyright"\r |
155 | # followed by zero or more white space characters followed by a "(" character\r | |
4234283c LG |
156 | #\r |
157 | # @param LineContent: the line need to be checked\r | |
158 | # @return: True if current line is copyright line, False else\r | |
159 | #\r | |
160 | def _IsCopyrightLine (LineContent):\r | |
161 | LineContent = LineContent.upper()\r | |
162 | Result = False\r | |
f7496d71 | 163 | \r |
4234283c LG |
164 | ReIsCopyrightRe = re.compile(r"""(^|\s)COPYRIGHT *\(""", re.DOTALL)\r |
165 | if ReIsCopyrightRe.search(LineContent):\r | |
166 | Result = True\r | |
421ccda3 | 167 | \r |
4234283c LG |
168 | return Result\r |
169 | \r | |
170 | ## ParseGenericComment\r | |
171 | #\r | |
f7496d71 | 172 | # @param GenericComment: Generic comment list, element of\r |
4234283c LG |
173 | # (CommentLine, LineNum)\r |
174 | # @param ContainerFile: Input value for filename of Dec file\r | |
f7496d71 | 175 | #\r |
4234283c LG |
176 | def ParseGenericComment (GenericComment, ContainerFile=None, SkipTag=None):\r |
177 | if ContainerFile:\r | |
178 | pass\r | |
f7496d71 LG |
179 | HelpTxt = None\r |
180 | HelpStr = ''\r | |
181 | \r | |
4234283c LG |
182 | for Item in GenericComment:\r |
183 | CommentLine = Item[0]\r | |
184 | Comment = CleanString2(CommentLine)[1]\r | |
185 | if SkipTag is not None and Comment.startswith(SkipTag):\r | |
186 | Comment = Comment.replace(SkipTag, '', 1)\r | |
187 | HelpStr += Comment + '\n'\r | |
f7496d71 | 188 | \r |
4234283c LG |
189 | if HelpStr:\r |
190 | HelpTxt = TextObject()\r | |
191 | if HelpStr.endswith('\n') and not HelpStr.endswith('\n\n') and HelpStr != '\n':\r | |
192 | HelpStr = HelpStr[:-1]\r | |
193 | HelpTxt.SetString(HelpStr)\r | |
194 | \r | |
195 | return HelpTxt\r | |
196 | \r | |
421ccda3 HC |
197 | ## ParsePcdErrorCode\r |
198 | #\r | |
f7496d71 | 199 | # @param Value: original ErrorCode value\r |
421ccda3 | 200 | # @param ContainerFile: Input value for filename of Dec file\r |
f7496d71 LG |
201 | # @param LineNum: Line Num\r |
202 | #\r | |
203 | def ParsePcdErrorCode (Value = None, ContainerFile = None, LineNum = None):\r | |
204 | try:\r | |
421ccda3 HC |
205 | if Value.strip().startswith((TAB_HEX_START, TAB_CAPHEX_START)):\r |
206 | Base = 16\r | |
207 | else:\r | |
208 | Base = 10\r | |
1b2e0772 | 209 | ErrorCode = int(Value, Base)\r |
421ccda3 | 210 | if ErrorCode > PCD_ERR_CODE_MAX_SIZE or ErrorCode < 0:\r |
f7496d71 | 211 | Logger.Error('Parser',\r |
421ccda3 HC |
212 | FORMAT_NOT_SUPPORTED,\r |
213 | "The format %s of ErrorCode is not valid, should be UNIT32 type or long type" % Value,\r | |
f7496d71 | 214 | File = ContainerFile,\r |
421ccda3 | 215 | Line = LineNum)\r |
1b2e0772 | 216 | return hex(ErrorCode)\r |
5b0671c1 | 217 | except ValueError as XStr:\r |
421ccda3 HC |
218 | if XStr:\r |
219 | pass\r | |
f7496d71 | 220 | Logger.Error('Parser',\r |
421ccda3 HC |
221 | FORMAT_NOT_SUPPORTED,\r |
222 | "The format %s of ErrorCode is not valid, should be UNIT32 type or long type" % Value,\r | |
f7496d71 | 223 | File = ContainerFile,\r |
421ccda3 | 224 | Line = LineNum)\r |
f7496d71 | 225 | \r |
4234283c LG |
226 | ## ParseDecPcdGenericComment\r |
227 | #\r | |
f7496d71 | 228 | # @param GenericComment: Generic comment list, element of (CommentLine,\r |
4234283c LG |
229 | # LineNum)\r |
230 | # @param ContainerFile: Input value for filename of Dec file\r | |
f7496d71 LG |
231 | #\r |
232 | def ParseDecPcdGenericComment (GenericComment, ContainerFile, TokenSpaceGuidCName, CName, MacroReplaceDict):\r | |
233 | HelpStr = ''\r | |
421ccda3 | 234 | PromptStr = ''\r |
4234283c | 235 | PcdErr = None\r |
421ccda3 HC |
236 | PcdErrList = []\r |
237 | ValidValueNum = 0\r | |
238 | ValidRangeNum = 0\r | |
239 | ExpressionNum = 0\r | |
f7496d71 | 240 | \r |
4234283c LG |
241 | for (CommentLine, LineNum) in GenericComment:\r |
242 | Comment = CleanString2(CommentLine)[1]\r | |
421ccda3 HC |
243 | #\r |
244 | # To replace Macro\r | |
245 | #\r | |
246 | MACRO_PATTERN = '[\t\s]*\$\([A-Z][_A-Z0-9]*\)'\r | |
247 | MatchedStrs = re.findall(MACRO_PATTERN, Comment)\r | |
248 | for MatchedStr in MatchedStrs:\r | |
249 | if MatchedStr:\r | |
250 | Macro = MatchedStr.strip().lstrip('$(').rstrip(')').strip()\r | |
251 | if Macro in MacroReplaceDict:\r | |
f7496d71 | 252 | Comment = Comment.replace(MatchedStr, MacroReplaceDict[Macro])\r |
421ccda3 HC |
253 | if Comment.startswith(TAB_PCD_VALIDRANGE):\r |
254 | if ValidValueNum > 0 or ExpressionNum > 0:\r | |
f7496d71 | 255 | Logger.Error('Parser',\r |
4234283c LG |
256 | FORMAT_NOT_SUPPORTED,\r |
257 | ST.WRN_MULTI_PCD_RANGES,\r | |
f7496d71 | 258 | File = ContainerFile,\r |
4234283c | 259 | Line = LineNum)\r |
421ccda3 | 260 | else:\r |
4234283c | 261 | PcdErr = PcdErrorObject()\r |
421ccda3 HC |
262 | PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName)\r |
263 | PcdErr.SetCName(CName)\r | |
264 | PcdErr.SetFileLine(Comment)\r | |
265 | PcdErr.SetLineNum(LineNum)\r | |
266 | ValidRangeNum += 1\r | |
267 | ValidRange = Comment.replace(TAB_PCD_VALIDRANGE, "", 1).strip()\r | |
268 | Valid, Cause = _CheckRangeExpression(ValidRange)\r | |
269 | if Valid:\r | |
270 | ValueList = ValidRange.split(TAB_VALUE_SPLIT)\r | |
271 | if len(ValueList) > 1:\r | |
272 | PcdErr.SetValidValueRange((TAB_VALUE_SPLIT.join(ValueList[1:])).strip())\r | |
273 | PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum))\r | |
274 | else:\r | |
275 | PcdErr.SetValidValueRange(ValidRange)\r | |
276 | PcdErrList.append(PcdErr)\r | |
277 | else:\r | |
278 | Logger.Error("Parser",\r | |
279 | FORMAT_NOT_SUPPORTED,\r | |
f7496d71 LG |
280 | Cause,\r |
281 | ContainerFile,\r | |
421ccda3 HC |
282 | LineNum)\r |
283 | elif Comment.startswith(TAB_PCD_VALIDLIST):\r | |
284 | if ValidRangeNum > 0 or ExpressionNum > 0:\r | |
f7496d71 | 285 | Logger.Error('Parser',\r |
4234283c LG |
286 | FORMAT_NOT_SUPPORTED,\r |
287 | ST.WRN_MULTI_PCD_RANGES,\r | |
f7496d71 | 288 | File = ContainerFile,\r |
4234283c | 289 | Line = LineNum)\r |
421ccda3 | 290 | elif ValidValueNum > 0:\r |
f7496d71 | 291 | Logger.Error('Parser',\r |
421ccda3 HC |
292 | FORMAT_NOT_SUPPORTED,\r |
293 | ST.WRN_MULTI_PCD_VALIDVALUE,\r | |
f7496d71 | 294 | File = ContainerFile,\r |
421ccda3 HC |
295 | Line = LineNum)\r |
296 | else:\r | |
297 | PcdErr = PcdErrorObject()\r | |
298 | PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName)\r | |
299 | PcdErr.SetCName(CName)\r | |
300 | PcdErr.SetFileLine(Comment)\r | |
301 | PcdErr.SetLineNum(LineNum)\r | |
302 | ValidValueNum += 1\r | |
303 | ValidValueExpr = Comment.replace(TAB_PCD_VALIDLIST, "", 1).strip()\r | |
304 | Valid, Cause = _CheckListExpression(ValidValueExpr)\r | |
305 | if Valid:\r | |
306 | ValidValue = Comment.replace(TAB_PCD_VALIDLIST, "", 1).replace(TAB_COMMA_SPLIT, TAB_SPACE_SPLIT)\r | |
307 | ValueList = ValidValue.split(TAB_VALUE_SPLIT)\r | |
308 | if len(ValueList) > 1:\r | |
309 | PcdErr.SetValidValue((TAB_VALUE_SPLIT.join(ValueList[1:])).strip())\r | |
310 | PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum))\r | |
311 | else:\r | |
312 | PcdErr.SetValidValue(ValidValue)\r | |
313 | PcdErrList.append(PcdErr)\r | |
314 | else:\r | |
315 | Logger.Error("Parser",\r | |
316 | FORMAT_NOT_SUPPORTED,\r | |
f7496d71 LG |
317 | Cause,\r |
318 | ContainerFile,\r | |
421ccda3 HC |
319 | LineNum)\r |
320 | elif Comment.startswith(TAB_PCD_EXPRESSION):\r | |
321 | if ValidRangeNum > 0 or ValidValueNum > 0:\r | |
f7496d71 | 322 | Logger.Error('Parser',\r |
4234283c LG |
323 | FORMAT_NOT_SUPPORTED,\r |
324 | ST.WRN_MULTI_PCD_RANGES,\r | |
f7496d71 | 325 | File = ContainerFile,\r |
4234283c | 326 | Line = LineNum)\r |
421ccda3 | 327 | else:\r |
4234283c | 328 | PcdErr = PcdErrorObject()\r |
421ccda3 HC |
329 | PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName)\r |
330 | PcdErr.SetCName(CName)\r | |
331 | PcdErr.SetFileLine(Comment)\r | |
332 | PcdErr.SetLineNum(LineNum)\r | |
333 | ExpressionNum += 1\r | |
334 | Expression = Comment.replace(TAB_PCD_EXPRESSION, "", 1).strip()\r | |
335 | Valid, Cause = _CheckExpression(Expression)\r | |
336 | if Valid:\r | |
337 | ValueList = Expression.split(TAB_VALUE_SPLIT)\r | |
338 | if len(ValueList) > 1:\r | |
339 | PcdErr.SetExpression((TAB_VALUE_SPLIT.join(ValueList[1:])).strip())\r | |
340 | PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum))\r | |
341 | else:\r | |
342 | PcdErr.SetExpression(Expression)\r | |
343 | PcdErrList.append(PcdErr)\r | |
f7496d71 | 344 | else:\r |
421ccda3 HC |
345 | Logger.Error("Parser",\r |
346 | FORMAT_NOT_SUPPORTED,\r | |
f7496d71 LG |
347 | Cause,\r |
348 | ContainerFile,\r | |
349 | LineNum)\r | |
421ccda3 HC |
350 | elif Comment.startswith(TAB_PCD_PROMPT):\r |
351 | if PromptStr:\r | |
f7496d71 | 352 | Logger.Error('Parser',\r |
421ccda3 HC |
353 | FORMAT_NOT_SUPPORTED,\r |
354 | ST.WRN_MULTI_PCD_PROMPT,\r | |
f7496d71 | 355 | File = ContainerFile,\r |
421ccda3 HC |
356 | Line = LineNum)\r |
357 | PromptStr = Comment.replace(TAB_PCD_PROMPT, "", 1).strip()\r | |
4234283c | 358 | else:\r |
421ccda3 HC |
359 | if Comment:\r |
360 | HelpStr += Comment + '\n'\r | |
f7496d71 | 361 | \r |
4234283c LG |
362 | #\r |
363 | # remove the last EOL if the comment is of format 'FOO\n'\r | |
364 | #\r | |
365 | if HelpStr.endswith('\n'):\r | |
366 | if HelpStr != '\n' and not HelpStr.endswith('\n\n'):\r | |
367 | HelpStr = HelpStr[:-1]\r | |
368 | \r | |
421ccda3 | 369 | return HelpStr, PcdErrList, PromptStr\r |
4234283c LG |
370 | \r |
371 | ## ParseDecPcdTailComment\r | |
372 | #\r | |
373 | # @param TailCommentList: Tail comment list of Pcd, item of format (Comment, LineNum)\r | |
374 | # @param ContainerFile: Input value for filename of Dec file\r | |
375 | # @retVal SupModuleList: The supported module type list detected\r | |
376 | # @retVal HelpStr: The generic help text string detected\r | |
377 | #\r | |
378 | def ParseDecPcdTailComment (TailCommentList, ContainerFile):\r | |
379 | assert(len(TailCommentList) == 1)\r | |
380 | TailComment = TailCommentList[0][0]\r | |
381 | LineNum = TailCommentList[0][1]\r | |
382 | \r | |
383 | Comment = TailComment.lstrip(" #")\r | |
f7496d71 | 384 | \r |
4234283c | 385 | ReFindFirstWordRe = re.compile(r"""^([^ #]*)""", re.DOTALL)\r |
f7496d71 | 386 | \r |
4234283c LG |
387 | #\r |
388 | # get first word and compare with SUP_MODULE_LIST\r | |
389 | #\r | |
390 | MatchObject = ReFindFirstWordRe.match(Comment)\r | |
391 | if not (MatchObject and MatchObject.group(1) in SUP_MODULE_LIST):\r | |
392 | return None, Comment\r | |
393 | \r | |
394 | #\r | |
395 | # parse line, it must have supported module type specified\r | |
396 | #\r | |
397 | if Comment.find(TAB_COMMENT_SPLIT) == -1:\r | |
f7496d71 | 398 | Comment += TAB_COMMENT_SPLIT\r |
4234283c LG |
399 | SupMode, HelpStr = GetSplitValueList(Comment, TAB_COMMENT_SPLIT, 1)\r |
400 | SupModuleList = []\r | |
401 | for Mod in GetSplitValueList(SupMode, TAB_SPACE_SPLIT):\r | |
402 | if not Mod:\r | |
403 | continue\r | |
404 | elif Mod not in SUP_MODULE_LIST:\r | |
405 | Logger.Error("UPT",\r | |
406 | FORMAT_INVALID,\r | |
f7496d71 LG |
407 | ST.WRN_INVALID_MODULE_TYPE%Mod,\r |
408 | ContainerFile,\r | |
4234283c LG |
409 | LineNum)\r |
410 | else:\r | |
411 | SupModuleList.append(Mod)\r | |
412 | \r | |
413 | return SupModuleList, HelpStr\r | |
414 | \r | |
421ccda3 HC |
415 | ## _CheckListExpression\r |
416 | #\r | |
f7496d71 | 417 | # @param Expression: Pcd value list expression\r |
421ccda3 HC |
418 | #\r |
419 | def _CheckListExpression(Expression):\r | |
420 | ListExpr = ''\r | |
421 | if TAB_VALUE_SPLIT in Expression:\r | |
f7496d71 | 422 | ListExpr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:]\r |
421ccda3 HC |
423 | else:\r |
424 | ListExpr = Expression\r | |
f7496d71 | 425 | \r |
421ccda3 HC |
426 | return IsValidListExpr(ListExpr)\r |
427 | \r | |
428 | ## _CheckExpreesion\r | |
429 | #\r | |
430 | # @param Expression: Pcd value expression\r | |
431 | #\r | |
432 | def _CheckExpression(Expression):\r | |
433 | Expr = ''\r | |
434 | if TAB_VALUE_SPLIT in Expression:\r | |
435 | Expr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:]\r | |
436 | else:\r | |
437 | Expr = Expression\r | |
438 | return IsValidLogicalExpr(Expr, True)\r | |
4234283c LG |
439 | \r |
440 | ## _CheckRangeExpression\r | |
441 | #\r | |
442 | # @param Expression: Pcd range expression\r | |
f7496d71 | 443 | #\r |
4234283c | 444 | def _CheckRangeExpression(Expression):\r |
421ccda3 HC |
445 | RangeExpr = ''\r |
446 | if TAB_VALUE_SPLIT in Expression:\r | |
447 | RangeExpr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:]\r | |
448 | else:\r | |
449 | RangeExpr = Expression\r | |
f7496d71 | 450 | \r |
421ccda3 | 451 | return IsValidRangeExpr(RangeExpr)\r |
4234283c LG |
452 | \r |
453 | ## ValidateCopyright\r | |
454 | #\r | |
455 | #\r | |
456 | #\r | |
457 | def ValidateCopyright(Result, ErrType, FileName, LineNo, ErrMsg):\r | |
458 | if not Result:\r | |
f7496d71 | 459 | Logger.Warn("\nUPT", ErrType, FileName, LineNo, ErrMsg)\r |
4234283c LG |
460 | \r |
461 | ## _ValidateCopyright\r | |
462 | #\r | |
463 | # @param Line: Line that contains copyright information, # stripped\r | |
f7496d71 | 464 | #\r |
4234283c LG |
465 | # @retval Result: True if line is conformed to Spec format, False else\r |
466 | # @retval ErrMsg: the detailed error description\r | |
f7496d71 | 467 | #\r |
4234283c LG |
468 | def _ValidateCopyright(Line):\r |
469 | if Line:\r | |
470 | pass\r | |
471 | Result = True\r | |
472 | ErrMsg = ''\r | |
f7496d71 | 473 | \r |
4234283c LG |
474 | return Result, ErrMsg\r |
475 | \r | |
476 | def GenerateTokenList (Comment):\r | |
477 | #\r | |
478 | # Tokenize Comment using '#' and ' ' as token seperators\r | |
479 | #\r | |
f7496d71 | 480 | RelplacedComment = None\r |
4234283c LG |
481 | while Comment != RelplacedComment:\r |
482 | RelplacedComment = Comment\r | |
483 | Comment = Comment.replace('##', '#').replace(' ', ' ').replace(' ', '#').strip('# ')\r | |
484 | return Comment.split('#')\r | |
485 | \r | |
486 | \r | |
487 | #\r | |
488 | # Comment - Comment to parse\r | |
489 | # TypeTokens - A dictionary of type token synonyms\r | |
490 | # RemoveTokens - A list of tokens to remove from help text\r | |
491 | # ParseVariable - True for parsing [Guids]. Otherwise False\r | |
492 | #\r | |
493 | def ParseComment (Comment, UsageTokens, TypeTokens, RemoveTokens, ParseVariable):\r | |
494 | #\r | |
495 | # Initialize return values\r | |
496 | #\r | |
497 | Usage = None\r | |
498 | Type = None\r | |
499 | String = None\r | |
f7496d71 | 500 | \r |
4234283c | 501 | Comment = Comment[0]\r |
f7496d71 LG |
502 | \r |
503 | NumTokens = 2\r | |
4234283c | 504 | if ParseVariable:\r |
f7496d71 LG |
505 | #\r |
506 | # Remove white space around first instance of ':' from Comment if 'Variable'\r | |
4234283c LG |
507 | # is in front of ':' and Variable is the 1st or 2nd token in Comment.\r |
508 | #\r | |
f7496d71 | 509 | List = Comment.split(':', 1)\r |
4234283c LG |
510 | if len(List) > 1:\r |
511 | SubList = GenerateTokenList (List[0].strip())\r | |
512 | if len(SubList) in [1, 2] and SubList[-1] == 'Variable':\r | |
f7496d71 | 513 | if List[1].strip().find('L"') == 0:\r |
4234283c | 514 | Comment = List[0].strip() + ':' + List[1].strip()\r |
f7496d71 LG |
515 | \r |
516 | #\r | |
4234283c | 517 | # Remove first instance of L"<VariableName> from Comment and put into String\r |
f7496d71 | 518 | # if and only if L"<VariableName>" is the 1st token, the 2nd token. Or\r |
4234283c LG |
519 | # L"<VariableName>" is the third token immediately following 'Variable:'.\r |
520 | #\r | |
521 | End = -1\r | |
522 | Start = Comment.find('Variable:L"')\r | |
523 | if Start >= 0:\r | |
524 | String = Comment[Start + 9:]\r | |
525 | End = String[2:].find('"')\r | |
526 | else:\r | |
527 | Start = Comment.find('L"')\r | |
528 | if Start >= 0:\r | |
529 | String = Comment[Start:]\r | |
530 | End = String[2:].find('"')\r | |
531 | if End >= 0:\r | |
532 | SubList = GenerateTokenList (Comment[:Start])\r | |
f7496d71 | 533 | if len(SubList) < 2:\r |
4234283c LG |
534 | Comment = Comment[:Start] + String[End + 3:]\r |
535 | String = String[:End + 3]\r | |
536 | Type = 'Variable'\r | |
f7496d71 LG |
537 | NumTokens = 1\r |
538 | \r | |
4234283c | 539 | #\r |
f7496d71 | 540 | # Initialze HelpText to Comment.\r |
4234283c | 541 | # Content will be remove from HelpText as matching tokens are found\r |
f7496d71 | 542 | #\r |
4234283c | 543 | HelpText = Comment\r |
f7496d71 | 544 | \r |
4234283c LG |
545 | #\r |
546 | # Tokenize Comment using '#' and ' ' as token seperators\r | |
547 | #\r | |
548 | List = GenerateTokenList (Comment)\r | |
f7496d71 | 549 | \r |
4234283c | 550 | #\r |
f7496d71 | 551 | # Search first two tokens for Usage and Type and remove any matching tokens\r |
4234283c LG |
552 | # from HelpText\r |
553 | #\r | |
554 | for Token in List[0:NumTokens]:\r | |
4231a819 | 555 | if Usage is None and Token in UsageTokens:\r |
4234283c LG |
556 | Usage = UsageTokens[Token]\r |
557 | HelpText = HelpText.replace(Token, '')\r | |
4231a819 | 558 | if Usage is not None or not ParseVariable:\r |
4234283c | 559 | for Token in List[0:NumTokens]:\r |
4231a819 | 560 | if Type is None and Token in TypeTokens:\r |
4234283c LG |
561 | Type = TypeTokens[Token]\r |
562 | HelpText = HelpText.replace(Token, '')\r | |
f7496d71 | 563 | if Usage is not None:\r |
4234283c LG |
564 | for Token in List[0:NumTokens]:\r |
565 | if Token in RemoveTokens:\r | |
566 | HelpText = HelpText.replace(Token, '')\r | |
f7496d71 | 567 | \r |
4234283c LG |
568 | #\r |
569 | # If no Usage token is present and set Usage to UNDEFINED\r | |
f7496d71 | 570 | #\r |
4231a819 | 571 | if Usage is None:\r |
4234283c | 572 | Usage = 'UNDEFINED'\r |
f7496d71 | 573 | \r |
4234283c LG |
574 | #\r |
575 | # If no Type token is present and set Type to UNDEFINED\r | |
f7496d71 | 576 | #\r |
4231a819 | 577 | if Type is None:\r |
4234283c | 578 | Type = 'UNDEFINED'\r |
f7496d71 | 579 | \r |
4234283c LG |
580 | #\r |
581 | # If Type is not 'Variable:', then set String to None\r | |
f7496d71 | 582 | #\r |
4234283c | 583 | if Type != 'Variable':\r |
f7496d71 LG |
584 | String = None\r |
585 | \r | |
4234283c LG |
586 | #\r |
587 | # Strip ' ' and '#' from the beginning of HelpText\r | |
f7496d71 | 588 | # If HelpText is an empty string after all parsing is\r |
4234283c | 589 | # complete then set HelpText to None\r |
f7496d71 | 590 | #\r |
4234283c LG |
591 | HelpText = HelpText.lstrip('# ')\r |
592 | if HelpText == '':\r | |
593 | HelpText = None\r | |
f7496d71 | 594 | \r |
4234283c LG |
595 | #\r |
596 | # Return parsing results\r | |
f7496d71 LG |
597 | #\r |
598 | return Usage, Type, String, HelpText\r |