]>
Commit | Line | Data |
---|---|---|
4234283c | 1 | ## @file ParserValidate.py\r |
421ccda3 | 2 | # Functions for parser validation\r |
4234283c | 3 | #\r |
64285f15 | 4 | # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r |
4234283c | 5 | #\r |
2e351cbe | 6 | # SPDX-License-Identifier: BSD-2-Clause-Patent\r |
4234283c LG |
7 | #\r |
8 | \r | |
9 | '''\r | |
fb0b35e0 | 10 | ParserValidate\r |
4234283c LG |
11 | '''\r |
12 | \r | |
13 | import os.path\r | |
14 | import re\r | |
0d2711a6 | 15 | import platform\r |
4234283c LG |
16 | \r |
17 | from Library.DataType import MODULE_LIST\r | |
18 | from Library.DataType import COMPONENT_TYPE_LIST\r | |
19 | from Library.DataType import PCD_USAGE_TYPE_LIST_OF_MODULE\r | |
20 | from Library.DataType import TAB_SPACE_SPLIT\r | |
64285f15 | 21 | from Library.StringUtils import GetSplitValueList\r |
4234283c LG |
22 | from Library.ExpressionValidate import IsValidBareCString\r |
23 | from Library.ExpressionValidate import IsValidFeatureFlagExp\r | |
8145b63e | 24 | from Common.MultipleWorkspace import MultipleWorkspace as mws\r |
4234283c LG |
25 | \r |
26 | ## __HexDigit() method\r | |
27 | #\r | |
28 | # Whether char input is a Hex data bit\r | |
29 | #\r | |
30 | # @param TempChar: The char to test\r | |
31 | #\r | |
32 | def __HexDigit(TempChar):\r | |
33 | if (TempChar >= 'a' and TempChar <= 'f') or \\r | |
34 | (TempChar >= 'A' and TempChar <= 'F') \\r | |
35 | or (TempChar >= '0' and TempChar <= '9'):\r | |
36 | return True\r | |
37 | else:\r | |
38 | return False\r | |
f7496d71 | 39 | \r |
4234283c LG |
40 | ## IsValidHex() method\r |
41 | #\r | |
42 | # Whether char input is a Hex data.\r | |
43 | #\r | |
44 | # @param TempChar: The char to test\r | |
45 | #\r | |
46 | def IsValidHex(HexStr):\r | |
47 | if not HexStr.upper().startswith("0X"):\r | |
48 | return False\r | |
49 | CharList = [c for c in HexStr[2:] if not __HexDigit(c)]\r | |
50 | if len(CharList) == 0:\r | |
51 | return True\r | |
52 | else:\r | |
53 | return False\r | |
54 | \r | |
55 | ## Judge the input string is valid bool type or not.\r | |
f7496d71 | 56 | #\r |
4234283c LG |
57 | # <TRUE> ::= {"TRUE"} {"true"} {"True"} {"0x1"} {"0x01"}\r |
58 | # <FALSE> ::= {"FALSE"} {"false"} {"False"} {"0x0"} {"0x00"}\r | |
59 | # <BoolType> ::= {<TRUE>} {<FALSE>}\r | |
60 | #\r | |
61 | # @param BoolString: A string contained the value need to be judged.\r | |
62 | #\r | |
63 | def IsValidBoolType(BoolString):\r | |
64 | #\r | |
fb0b35e0 | 65 | # Valid True\r |
4234283c LG |
66 | #\r |
67 | if BoolString == 'TRUE' or \\r | |
68 | BoolString == 'True' or \\r | |
69 | BoolString == 'true' or \\r | |
70 | BoolString == '0x1' or \\r | |
71 | BoolString == '0x01':\r | |
72 | return True\r | |
73 | #\r | |
74 | # Valid False\r | |
75 | #\r | |
76 | elif BoolString == 'FALSE' or \\r | |
77 | BoolString == 'False' or \\r | |
78 | BoolString == 'false' or \\r | |
79 | BoolString == '0x0' or \\r | |
80 | BoolString == '0x00':\r | |
81 | return True\r | |
82 | #\r | |
83 | # Invalid bool type\r | |
84 | #\r | |
85 | else:\r | |
86 | return False\r | |
f7496d71 LG |
87 | \r |
88 | ## Is Valid Module Type List or not\r | |
89 | #\r | |
90 | # @param ModuleTypeList: A list contain ModuleType strings need to be\r | |
4234283c LG |
91 | # judged.\r |
92 | #\r | |
93 | def IsValidInfMoudleTypeList(ModuleTypeList):\r | |
94 | for ModuleType in ModuleTypeList:\r | |
95 | return IsValidInfMoudleType(ModuleType)\r | |
96 | \r | |
f7496d71 LG |
97 | ## Is Valid Module Type or not\r |
98 | #\r | |
4234283c LG |
99 | # @param ModuleType: A string contain ModuleType need to be judged.\r |
100 | #\r | |
101 | def IsValidInfMoudleType(ModuleType):\r | |
102 | if ModuleType in MODULE_LIST:\r | |
103 | return True\r | |
104 | else:\r | |
105 | return False\r | |
106 | \r | |
f7496d71 LG |
107 | ## Is Valid Component Type or not\r |
108 | #\r | |
4234283c LG |
109 | # @param ComponentType: A string contain ComponentType need to be judged.\r |
110 | #\r | |
111 | def IsValidInfComponentType(ComponentType):\r | |
112 | if ComponentType.upper() in COMPONENT_TYPE_LIST:\r | |
113 | return True\r | |
114 | else:\r | |
115 | return False\r | |
116 | \r | |
117 | \r | |
118 | ## Is valid Tool Family or not\r | |
119 | #\r | |
120 | # @param ToolFamily: A string contain Tool Family need to be judged.\r | |
fb0b35e0 | 121 | # Family := [A-Z]([a-zA-Z0-9])*\r |
4234283c LG |
122 | #\r |
123 | def IsValidToolFamily(ToolFamily):\r | |
fb0b35e0 AC |
124 | ReIsValidFamily = re.compile(r"^[A-Z]+[A-Za-z0-9]{0,}$", re.DOTALL)\r |
125 | if ReIsValidFamily.match(ToolFamily) is None:\r | |
4234283c LG |
126 | return False\r |
127 | return True\r | |
128 | \r | |
129 | ## Is valid Tool TagName or not\r | |
130 | #\r | |
131 | # The TagName sample is MYTOOLS and VS2005.\r | |
132 | #\r | |
133 | # @param TagName: A string contain Tool TagName need to be judged.\r | |
134 | #\r | |
135 | def IsValidToolTagName(TagName):\r | |
136 | if TagName.strip() == '':\r | |
137 | return True\r | |
138 | if TagName.strip() == '*':\r | |
139 | return True\r | |
140 | if not IsValidWord(TagName):\r | |
141 | return False\r | |
142 | return True\r | |
143 | \r | |
144 | ## Is valid arch or not\r | |
f7496d71 | 145 | #\r |
4234283c LG |
146 | # @param Arch The arch string need to be validated\r |
147 | # <OA> ::= (a-zA-Z)(A-Za-z0-9){0,}\r | |
148 | # <arch> ::= {"IA32"} {"X64"} {"IPF"} {"EBC"} {<OA>}\r | |
149 | # {"common"}\r | |
150 | # @param Arch: Input arch\r | |
f7496d71 | 151 | #\r |
4234283c LG |
152 | def IsValidArch(Arch):\r |
153 | if Arch == 'common':\r | |
154 | return True\r | |
fb0b35e0 AC |
155 | ReIsValidArch = re.compile(r"^[a-zA-Z]+[a-zA-Z0-9]{0,}$", re.DOTALL)\r |
156 | if ReIsValidArch.match(Arch) is None:\r | |
4234283c LG |
157 | return False\r |
158 | return True\r | |
159 | \r | |
160 | ## Is valid family or not\r | |
f7496d71 | 161 | #\r |
4234283c LG |
162 | # <Family> ::= {"MSFT"} {"GCC"} {"INTEL"} {<Usr>} {"*"}\r |
163 | # <Usr> ::= [A-Z][A-Za-z0-9]{0,}\r | |
164 | #\r | |
165 | # @param family: The family string need to be validated\r | |
f7496d71 | 166 | #\r |
4234283c LG |
167 | def IsValidFamily(Family):\r |
168 | Family = Family.strip()\r | |
169 | if Family == '*':\r | |
170 | return True\r | |
f7496d71 | 171 | \r |
4234283c LG |
172 | if Family == '':\r |
173 | return True\r | |
f7496d71 | 174 | \r |
4234283c | 175 | ReIsValidFamily = re.compile(r"^[A-Z]+[A-Za-z0-9]{0,}$", re.DOTALL)\r |
4231a819 | 176 | if ReIsValidFamily.match(Family) is None:\r |
4234283c LG |
177 | return False\r |
178 | return True\r | |
179 | \r | |
180 | ## Is valid build option name or not\r | |
f7496d71 | 181 | #\r |
4234283c LG |
182 | # @param BuildOptionName: The BuildOptionName string need to be validated\r |
183 | #\r | |
184 | def IsValidBuildOptionName(BuildOptionName):\r | |
185 | if not BuildOptionName:\r | |
186 | return False\r | |
f7496d71 | 187 | \r |
4234283c | 188 | ToolOptionList = GetSplitValueList(BuildOptionName, '_', 4)\r |
f7496d71 | 189 | \r |
4234283c LG |
190 | if len(ToolOptionList) != 5:\r |
191 | return False\r | |
f7496d71 | 192 | \r |
4234283c LG |
193 | ReIsValidBuildOption1 = re.compile(r"^\s*(\*)|([A-Z][a-zA-Z0-9]*)$")\r |
194 | ReIsValidBuildOption2 = re.compile(r"^\s*(\*)|([a-zA-Z][a-zA-Z0-9]*)$")\r | |
f7496d71 | 195 | \r |
4231a819 | 196 | if ReIsValidBuildOption1.match(ToolOptionList[0]) is None:\r |
4234283c | 197 | return False\r |
f7496d71 | 198 | \r |
4231a819 | 199 | if ReIsValidBuildOption1.match(ToolOptionList[1]) is None:\r |
4234283c | 200 | return False\r |
f7496d71 | 201 | \r |
4231a819 | 202 | if ReIsValidBuildOption2.match(ToolOptionList[2]) is None:\r |
4234283c | 203 | return False\r |
f7496d71 | 204 | \r |
4234283c LG |
205 | if ToolOptionList[3] == "*" and ToolOptionList[4] not in ['FAMILY', 'DLL', 'DPATH']:\r |
206 | return False\r | |
f7496d71 | 207 | \r |
4234283c | 208 | return True\r |
f7496d71 | 209 | \r |
4234283c LG |
210 | ## IsValidToken\r |
211 | #\r | |
212 | # Check if pattern string matches total token\r | |
213 | #\r | |
214 | # @param ReString: regular string\r | |
215 | # @param Token: Token to be matched\r | |
216 | #\r | |
217 | def IsValidToken(ReString, Token):\r | |
218 | Match = re.compile(ReString).match(Token)\r | |
219 | return Match and Match.start() == 0 and Match.end() == len(Token)\r | |
220 | \r | |
221 | ## IsValidPath\r | |
222 | #\r | |
223 | # Check if path exist\r | |
224 | #\r | |
225 | # @param Path: Absolute path or relative path to be checked\r | |
226 | # @param Root: Root path\r | |
227 | #\r | |
228 | def IsValidPath(Path, Root):\r | |
229 | Path = Path.strip()\r | |
230 | OrigPath = Path.replace('\\', '/')\r | |
f7496d71 | 231 | \r |
4234283c LG |
232 | Path = os.path.normpath(Path).replace('\\', '/')\r |
233 | Root = os.path.normpath(Root).replace('\\', '/')\r | |
fb0f8067 | 234 | FullPath = mws.join(Root, Path)\r |
f7496d71 | 235 | \r |
4234283c LG |
236 | if not os.path.exists(FullPath):\r |
237 | return False\r | |
f7496d71 | 238 | \r |
4234283c LG |
239 | #\r |
240 | # If Path is absolute path.\r | |
241 | # It should be in Root.\r | |
242 | #\r | |
243 | if os.path.isabs(Path):\r | |
244 | if not Path.startswith(Root):\r | |
245 | return False\r | |
246 | return True\r | |
247 | \r | |
248 | #\r | |
249 | # Check illegal character\r | |
250 | #\r | |
251 | for Rel in ['/', './', '../']:\r | |
252 | if OrigPath.startswith(Rel):\r | |
253 | return False\r | |
254 | for Rel in ['//', '/./', '/../']:\r | |
255 | if Rel in OrigPath:\r | |
256 | return False\r | |
257 | for Rel in ['/.', '/..', '/']:\r | |
258 | if OrigPath.endswith(Rel):\r | |
259 | return False\r | |
f7496d71 | 260 | \r |
4234283c | 261 | Path = Path.rstrip('/')\r |
f7496d71 | 262 | \r |
4234283c LG |
263 | #\r |
264 | # Check relative path\r | |
265 | #\r | |
266 | for Word in Path.split('/'):\r | |
267 | if not IsValidWord(Word):\r | |
268 | return False\r | |
f7496d71 | 269 | \r |
4234283c LG |
270 | return True\r |
271 | \r | |
272 | ## IsValidInstallPath\r | |
273 | #\r | |
274 | # Check if an install path valid or not.\r | |
275 | #\r | |
276 | # Absolute path or path starts with '.' or path contains '..' are invalid.\r | |
277 | #\r | |
278 | # @param Path: path to be checked\r | |
279 | #\r | |
280 | def IsValidInstallPath(Path):\r | |
0d2711a6 LG |
281 | if platform.platform().find("Windows") >= 0:\r |
282 | if os.path.isabs(Path):\r | |
283 | return False\r | |
284 | else:\r | |
9508d0fa | 285 | if Path[1:2] == ':':\r |
0d2711a6 LG |
286 | return False\r |
287 | if os.path.isabs(Path):\r | |
288 | return False\r | |
4234283c LG |
289 | if Path.startswith('.'):\r |
290 | return False\r | |
f7496d71 | 291 | \r |
4234283c LG |
292 | if Path.find('..') != -1:\r |
293 | return False\r | |
f7496d71 | 294 | \r |
4234283c | 295 | return True\r |
f7496d71 | 296 | \r |
4234283c LG |
297 | \r |
298 | ## IsValidCFormatGuid\r | |
299 | #\r | |
300 | # Check if GUID format has the from of {8,4,4,{2,2,2,2,2,2,2,2}}\r | |
301 | #\r | |
302 | # @param Guid: Guid to be checked\r | |
303 | #\r | |
304 | def IsValidCFormatGuid(Guid):\r | |
305 | #\r | |
f7496d71 | 306 | # Valid: { 0xf0b11735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38,\r |
4234283c | 307 | # 0xaf, 0x48, 0xce }}\r |
f7496d71 | 308 | # Invalid: { 0xf0b11735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38,\r |
4234283c | 309 | # 0xaf, 0x48, 0xce }} 0x123\r |
f7496d71 | 310 | # Invalid: { 0xf0b1 1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38,\r |
4234283c LG |
311 | # 0xaf, 0x48, 0xce }}\r |
312 | #\r | |
f7496d71 | 313 | List = ['{', 10, ',', 6, ',', 6, ',{', 4, ',', 4, ',', 4,\r |
4234283c LG |
314 | ',', 4, ',', 4, ',', 4, ',', 4, ',', 4, '}}']\r |
315 | Index = 0\r | |
316 | Value = ''\r | |
317 | SepValue = ''\r | |
318 | for Char in Guid:\r | |
319 | if Char not in '{},\t ':\r | |
320 | Value += Char\r | |
321 | continue\r | |
322 | if Value:\r | |
323 | try:\r | |
324 | #\r | |
325 | # Index may out of bound\r | |
326 | #\r | |
327 | if not SepValue or SepValue != List[Index]:\r | |
328 | return False\r | |
329 | Index += 1\r | |
330 | SepValue = ''\r | |
331 | \r | |
332 | if not Value.startswith('0x') and not Value.startswith('0X'):\r | |
333 | return False\r | |
f7496d71 | 334 | \r |
4234283c LG |
335 | #\r |
336 | # Index may out of bound\r | |
337 | #\r | |
0d1f5b2b | 338 | if not isinstance(List[Index], type(1)) or \\r |
4234283c LG |
339 | len(Value) > List[Index] or len(Value) < 3:\r |
340 | return False\r | |
f7496d71 | 341 | \r |
4234283c LG |
342 | #\r |
343 | # Check if string can be converted to integer\r | |
344 | # Throw exception if not\r | |
345 | #\r | |
346 | int(Value, 16)\r | |
347 | except BaseException:\r | |
348 | #\r | |
349 | # Exception caught means invalid format\r | |
350 | #\r | |
351 | return False\r | |
352 | Value = ''\r | |
353 | Index += 1\r | |
354 | if Char in '{},':\r | |
355 | SepValue += Char\r | |
356 | \r | |
357 | return SepValue == '}}' and Value == ''\r | |
358 | \r | |
359 | ## IsValidPcdType\r | |
360 | #\r | |
361 | # Check whether the PCD type is valid\r | |
362 | #\r | |
363 | # @param PcdTypeString: The PcdType string need to be checked.\r | |
f7496d71 | 364 | #\r |
4234283c LG |
365 | def IsValidPcdType(PcdTypeString):\r |
366 | if PcdTypeString.upper() in PCD_USAGE_TYPE_LIST_OF_MODULE:\r | |
367 | return True\r | |
368 | else:\r | |
369 | return False\r | |
f7496d71 | 370 | \r |
4234283c LG |
371 | ## IsValidWord\r |
372 | #\r | |
373 | # Check whether the word is valid.\r | |
f7496d71 LG |
374 | # <Word> ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with\r |
375 | # optional\r | |
376 | # dash "-" and/or underscore "_" characters. No whitespace\r | |
4234283c | 377 | # characters are permitted.\r |
f7496d71 | 378 | #\r |
4234283c | 379 | # @param Word: The word string need to be checked.\r |
f7496d71 | 380 | #\r |
4234283c LG |
381 | def IsValidWord(Word):\r |
382 | if not Word:\r | |
383 | return False\r | |
384 | #\r | |
385 | # The first char should be alpha, _ or Digit.\r | |
386 | #\r | |
387 | if not Word[0].isalnum() and \\r | |
388 | not Word[0] == '_' and \\r | |
389 | not Word[0].isdigit():\r | |
390 | return False\r | |
f7496d71 | 391 | \r |
4234283c | 392 | LastChar = ''\r |
f7496d71 | 393 | for Char in Word[1:]:\r |
4234283c LG |
394 | if (not Char.isalpha()) and \\r |
395 | (not Char.isdigit()) and \\r | |
396 | Char != '-' and \\r | |
397 | Char != '_' and \\r | |
398 | Char != '.':\r | |
399 | return False\r | |
400 | if Char == '.' and LastChar == '.':\r | |
401 | return False\r | |
402 | LastChar = Char\r | |
f7496d71 | 403 | \r |
4234283c LG |
404 | return True\r |
405 | \r | |
406 | \r | |
407 | ## IsValidSimpleWord\r | |
408 | #\r | |
409 | # Check whether the SimpleWord is valid.\r | |
f7496d71 | 410 | # <SimpleWord> ::= (a-zA-Z0-9)(a-zA-Z0-9_-){0,}\r |
4234283c | 411 | # A word that cannot contain a period character.\r |
f7496d71 | 412 | #\r |
4234283c | 413 | # @param Word: The word string need to be checked.\r |
f7496d71 | 414 | #\r |
4234283c LG |
415 | def IsValidSimpleWord(Word):\r |
416 | ReIsValidSimpleWord = \\r | |
417 | re.compile(r"^[0-9A-Za-z][0-9A-Za-z\-_]*$", re.DOTALL)\r | |
418 | Word = Word.strip()\r | |
419 | if not Word:\r | |
420 | return False\r | |
f7496d71 | 421 | \r |
4234283c LG |
422 | if not ReIsValidSimpleWord.match(Word):\r |
423 | return False\r | |
f7496d71 | 424 | \r |
4234283c LG |
425 | return True\r |
426 | \r | |
427 | ## IsValidDecVersion\r | |
428 | #\r | |
429 | # Check whether the decimal version is valid.\r | |
430 | # <DecVersion> ::= (0-9){1,} ["." (0-9){1,}]\r | |
f7496d71 | 431 | #\r |
4234283c | 432 | # @param Word: The word string need to be checked.\r |
f7496d71 | 433 | #\r |
4234283c LG |
434 | def IsValidDecVersion(Word):\r |
435 | if Word.find('.') > -1:\r | |
436 | ReIsValidDecVersion = re.compile(r"[0-9]+\.?[0-9]+$")\r | |
437 | else:\r | |
438 | ReIsValidDecVersion = re.compile(r"[0-9]+$")\r | |
4231a819 | 439 | if ReIsValidDecVersion.match(Word) is None:\r |
f7496d71 | 440 | return False\r |
4234283c | 441 | return True\r |
f7496d71 | 442 | \r |
4234283c LG |
443 | ## IsValidHexVersion\r |
444 | #\r | |
445 | # Check whether the hex version is valid.\r | |
446 | # <HexVersion> ::= "0x" <Major> <Minor>\r | |
447 | # <Major> ::= <HexDigit>{4}\r | |
448 | # <Minor> ::= <HexDigit>{4}\r | |
f7496d71 | 449 | #\r |
4234283c | 450 | # @param Word: The word string need to be checked.\r |
f7496d71 | 451 | #\r |
4234283c LG |
452 | def IsValidHexVersion(Word):\r |
453 | ReIsValidHexVersion = re.compile(r"[0][xX][0-9A-Fa-f]{8}$", re.DOTALL)\r | |
4231a819 | 454 | if ReIsValidHexVersion.match(Word) is None:\r |
4234283c | 455 | return False\r |
f7496d71 | 456 | \r |
4234283c LG |
457 | return True\r |
458 | \r | |
459 | ## IsValidBuildNumber\r | |
460 | #\r | |
461 | # Check whether the BUILD_NUMBER is valid.\r | |
462 | # ["BUILD_NUMBER" "=" <Integer>{1,4} <EOL>]\r | |
f7496d71 | 463 | #\r |
4234283c | 464 | # @param Word: The BUILD_NUMBER string need to be checked.\r |
f7496d71 | 465 | #\r |
4234283c LG |
466 | def IsValidBuildNumber(Word):\r |
467 | ReIsValieBuildNumber = re.compile(r"[0-9]{1,4}$", re.DOTALL)\r | |
4231a819 | 468 | if ReIsValieBuildNumber.match(Word) is None:\r |
4234283c | 469 | return False\r |
f7496d71 | 470 | \r |
4234283c LG |
471 | return True\r |
472 | \r | |
473 | ## IsValidDepex\r | |
474 | #\r | |
475 | # Check whether the Depex is valid.\r | |
f7496d71 | 476 | #\r |
4234283c | 477 | # @param Word: The Depex string need to be checked.\r |
f7496d71 | 478 | #\r |
4234283c LG |
479 | def IsValidDepex(Word):\r |
480 | Index = Word.upper().find("PUSH")\r | |
481 | if Index > -1:\r | |
482 | return IsValidCFormatGuid(Word[Index+4:].strip())\r | |
483 | \r | |
484 | ReIsValidCName = re.compile(r"^[A-Za-z_][0-9A-Za-z_\s\.]*$", re.DOTALL)\r | |
4231a819 | 485 | if ReIsValidCName.match(Word) is None:\r |
4234283c | 486 | return False\r |
f7496d71 | 487 | \r |
4234283c LG |
488 | return True\r |
489 | \r | |
490 | ## IsValidNormalizedString\r | |
491 | #\r | |
f7496d71 | 492 | # Check\r |
4234283c LG |
493 | # <NormalizedString> ::= <DblQuote> [{<Word>} {<Space>}]{1,} <DblQuote>\r |
494 | # <Space> ::= 0x20\r | |
495 | #\r | |
496 | # @param String: string to be checked\r | |
497 | #\r | |
498 | def IsValidNormalizedString(String):\r | |
499 | if String == '':\r | |
500 | return True\r | |
f7496d71 | 501 | \r |
4234283c LG |
502 | for Char in String:\r |
503 | if Char == '\t':\r | |
504 | return False\r | |
f7496d71 | 505 | \r |
4234283c | 506 | StringList = GetSplitValueList(String, TAB_SPACE_SPLIT)\r |
f7496d71 | 507 | \r |
4234283c LG |
508 | for Item in StringList:\r |
509 | if not Item:\r | |
510 | continue\r | |
511 | if not IsValidWord(Item):\r | |
512 | return False\r | |
f7496d71 | 513 | \r |
4234283c LG |
514 | return True\r |
515 | \r | |
516 | ## IsValidIdString\r | |
517 | #\r | |
518 | # Check whether the IdString is valid.\r | |
f7496d71 | 519 | #\r |
4234283c | 520 | # @param IdString: The IdString need to be checked.\r |
f7496d71 | 521 | #\r |
4234283c LG |
522 | def IsValidIdString(String):\r |
523 | if IsValidSimpleWord(String.strip()):\r | |
524 | return True\r | |
f7496d71 | 525 | \r |
4234283c LG |
526 | if String.strip().startswith('"') and \\r |
527 | String.strip().endswith('"'):\r | |
528 | String = String[1:-1]\r | |
529 | if String.strip() == "":\r | |
530 | return True\r | |
531 | if IsValidNormalizedString(String):\r | |
532 | return True\r | |
f7496d71 | 533 | \r |
4234283c LG |
534 | return False\r |
535 | \r | |
536 | ## IsValidVersionString\r | |
537 | #\r | |
538 | # Check whether the VersionString is valid.\r | |
539 | # <AsciiString> ::= [ [<WhiteSpace>]{0,} [<AsciiChars>]{0,} ] {0,}\r | |
540 | # <WhiteSpace> ::= {<Tab>} {<Space>}\r | |
541 | # <Tab> ::= 0x09\r | |
542 | # <Space> ::= 0x20\r | |
f7496d71 LG |
543 | # <AsciiChars> ::= (0x21 - 0x7E)\r |
544 | #\r | |
4234283c | 545 | # @param VersionString: The VersionString need to be checked.\r |
f7496d71 | 546 | #\r |
4234283c LG |
547 | def IsValidVersionString(VersionString):\r |
548 | VersionString = VersionString.strip()\r | |
549 | for Char in VersionString:\r | |
550 | if not (Char >= 0x21 and Char <= 0x7E):\r | |
551 | return False\r | |
f7496d71 | 552 | \r |
4234283c LG |
553 | return True\r |
554 | \r | |
555 | ## IsValidPcdValue\r | |
556 | #\r | |
557 | # Check whether the PcdValue is valid.\r | |
f7496d71 | 558 | #\r |
4234283c | 559 | # @param VersionString: The PcdValue need to be checked.\r |
f7496d71 | 560 | #\r |
4234283c LG |
561 | def IsValidPcdValue(PcdValue):\r |
562 | for Char in PcdValue:\r | |
563 | if Char == '\n' or Char == '\t' or Char == '\f':\r | |
564 | return False\r | |
f7496d71 | 565 | \r |
4234283c LG |
566 | #\r |
567 | # <Boolean>\r | |
568 | #\r | |
569 | if IsValidFeatureFlagExp(PcdValue, True)[0]:\r | |
570 | return True\r | |
f7496d71 | 571 | \r |
4234283c LG |
572 | #\r |
573 | # <Number> ::= {<Integer>} {<HexNumber>}\r | |
574 | # <Integer> ::= {(0-9)} {(1-9)(0-9){1,}}\r | |
575 | # <HexNumber> ::= "0x" <HexDigit>{1,}\r | |
576 | # <HexDigit> ::= (a-fA-F0-9)\r | |
f7496d71 | 577 | #\r |
4234283c LG |
578 | if IsValidHex(PcdValue):\r |
579 | return True\r | |
f7496d71 | 580 | \r |
421ccda3 | 581 | ReIsValidIntegerSingle = re.compile(r"^\s*[0-9]\s*$", re.DOTALL)\r |
4231a819 | 582 | if ReIsValidIntegerSingle.match(PcdValue) is not None:\r |
4234283c | 583 | return True\r |
f7496d71 LG |
584 | \r |
585 | ReIsValidIntegerMulti = re.compile(r"^\s*[1-9][0-9]+\s*$", re.DOTALL)\r | |
4231a819 | 586 | if ReIsValidIntegerMulti.match(PcdValue) is not None:\r |
4234283c | 587 | return True\r |
f7496d71 | 588 | \r |
4234283c LG |
589 | #\r |
590 | # <StringVal> ::= {<StringType>} {<Array>} {"$(" <MACRO> ")"}\r | |
591 | # <StringType> ::= {<UnicodeString>} {<CString>}\r | |
592 | #\r | |
593 | ReIsValidStringType = re.compile(r"^\s*[\"L].*[\"]\s*$")\r | |
594 | if ReIsValidStringType.match(PcdValue):\r | |
595 | IsTrue = False\r | |
596 | if PcdValue.strip().startswith('L\"'):\r | |
597 | StringValue = PcdValue.strip().lstrip('L\"').rstrip('\"')\r | |
598 | if IsValidBareCString(StringValue):\r | |
599 | IsTrue = True\r | |
600 | elif PcdValue.strip().startswith('\"'):\r | |
601 | StringValue = PcdValue.strip().lstrip('\"').rstrip('\"')\r | |
602 | if IsValidBareCString(StringValue):\r | |
603 | IsTrue = True\r | |
604 | if IsTrue:\r | |
605 | return IsTrue\r | |
f7496d71 | 606 | \r |
4234283c LG |
607 | #\r |
608 | # <Array> ::= {<CArray>} {<NList>} {<CFormatGUID>}\r | |
609 | # <CArray> ::= "{" [<NList>] <CArray>{0,} "}"\r | |
610 | # <NList> ::= <HexByte> ["," <HexByte>]{0,}\r | |
611 | # <HexDigit> ::= (a-fA-F0-9)\r | |
612 | # <HexByte> ::= "0x" <HexDigit>{1,2}\r | |
613 | #\r | |
614 | if IsValidCFormatGuid(PcdValue):\r | |
615 | return True\r | |
f7496d71 | 616 | \r |
4234283c LG |
617 | ReIsValidByteHex = re.compile(r"^\s*0x[0-9a-fA-F]{1,2}\s*$", re.DOTALL)\r |
618 | if PcdValue.strip().startswith('{') and PcdValue.strip().endswith('}') :\r | |
619 | StringValue = PcdValue.strip().lstrip('{').rstrip('}')\r | |
620 | ValueList = StringValue.split(',')\r | |
621 | AllValidFlag = True\r | |
f7496d71 | 622 | for ValueItem in ValueList:\r |
4234283c LG |
623 | if not ReIsValidByteHex.match(ValueItem.strip()):\r |
624 | AllValidFlag = False\r | |
f7496d71 | 625 | \r |
4234283c LG |
626 | if AllValidFlag:\r |
627 | return True\r | |
f7496d71 LG |
628 | \r |
629 | #\r | |
4234283c LG |
630 | # NList\r |
631 | #\r | |
632 | AllValidFlag = True\r | |
633 | ValueList = PcdValue.split(',')\r | |
f7496d71 | 634 | for ValueItem in ValueList:\r |
4234283c LG |
635 | if not ReIsValidByteHex.match(ValueItem.strip()):\r |
636 | AllValidFlag = False\r | |
f7496d71 | 637 | \r |
4234283c LG |
638 | if AllValidFlag:\r |
639 | return True\r | |
f7496d71 | 640 | \r |
4234283c LG |
641 | return False\r |
642 | \r | |
643 | ## IsValidCVariableName\r | |
644 | #\r | |
645 | # Check whether the PcdValue is valid.\r | |
f7496d71 | 646 | #\r |
4234283c | 647 | # @param VersionString: The PcdValue need to be checked.\r |
f7496d71 | 648 | #\r |
4234283c LG |
649 | def IsValidCVariableName(CName):\r |
650 | ReIsValidCName = re.compile(r"^[A-Za-z_][0-9A-Za-z_]*$", re.DOTALL)\r | |
4231a819 | 651 | if ReIsValidCName.match(CName) is None:\r |
4234283c | 652 | return False\r |
f7496d71 | 653 | \r |
4234283c LG |
654 | return True\r |
655 | \r | |
656 | ## IsValidIdentifier\r | |
657 | #\r | |
658 | # <Identifier> ::= <NonDigit> <Chars>{0,}\r | |
659 | # <Chars> ::= (a-zA-Z0-9_)\r | |
660 | # <NonDigit> ::= (a-zA-Z_)\r | |
661 | #\r | |
662 | # @param Ident: identifier to be checked\r | |
663 | #\r | |
664 | def IsValidIdentifier(Ident):\r | |
665 | ReIdent = re.compile(r"^[A-Za-z_][0-9A-Za-z_]*$", re.DOTALL)\r | |
4231a819 | 666 | if ReIdent.match(Ident) is None:\r |
4234283c | 667 | return False\r |
f7496d71 | 668 | \r |
4234283c LG |
669 | return True\r |
670 | \r | |
671 | ## IsValidDecVersionVal\r | |
672 | #\r | |
673 | # {(0-9){1,} "." (0-99)}\r | |
674 | #\r | |
675 | # @param Ver: version to be checked\r | |
676 | #\r | |
677 | def IsValidDecVersionVal(Ver):\r | |
678 | ReVersion = re.compile(r"[0-9]+(\.[0-9]{1,2})$")\r | |
f7496d71 | 679 | \r |
4231a819 | 680 | if ReVersion.match(Ver) is None:\r |
4234283c | 681 | return False\r |
f7496d71 | 682 | \r |
4234283c LG |
683 | return True\r |
684 | \r | |
685 | \r | |
686 | ## IsValidLibName\r | |
687 | #\r | |
688 | # (A-Z)(a-zA-Z0-9){0,} and could not be "NULL"\r | |
689 | #\r | |
690 | def IsValidLibName(LibName):\r | |
691 | if LibName == 'NULL':\r | |
692 | return False\r | |
693 | ReLibName = re.compile("^[A-Z]+[a-zA-Z0-9]*$")\r | |
694 | if not ReLibName.match(LibName):\r | |
695 | return False\r | |
f7496d71 | 696 | \r |
4234283c LG |
697 | return True\r |
698 | \r | |
699 | # IsValidUserId\r | |
700 | #\r | |
701 | # <UserId> ::= (a-zA-Z)(a-zA-Z0-9_.){0,}\r | |
702 | # Words that contain period "." must be encapsulated in double quotation marks.\r | |
703 | #\r | |
704 | def IsValidUserId(UserId):\r | |
705 | UserId = UserId.strip()\r | |
706 | Quoted = False\r | |
707 | if UserId.startswith('"') and UserId.endswith('"'):\r | |
708 | Quoted = True\r | |
709 | UserId = UserId[1:-1]\r | |
710 | if not UserId or not UserId[0].isalpha():\r | |
711 | return False\r | |
712 | for Char in UserId[1:]:\r | |
713 | if not Char.isalnum() and not Char in '_.':\r | |
714 | return False\r | |
715 | if Char == '.' and not Quoted:\r | |
716 | return False\r | |
717 | return True\r | |
718 | \r | |
fe90f483 HC |
719 | #\r |
720 | # Check if a UTF16-LE file has a BOM header\r | |
721 | #\r | |
722 | def CheckUTF16FileHeader(File):\r | |
723 | FileIn = open(File, 'rb').read(2)\r | |
174a9d3c | 724 | if FileIn != b'\xff\xfe':\r |
fe90f483 HC |
725 | return False\r |
726 | \r | |
727 | return True\r |