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