]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/Library/ParserValidate.py
BaseTools: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Library / ParserValidate.py
CommitLineData
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 10ParserValidate\r
4234283c
LG
11'''\r
12\r
13import os.path\r
14import re\r
0d2711a6 15import platform\r
4234283c
LG
16\r
17from Library.DataType import MODULE_LIST\r
18from Library.DataType import COMPONENT_TYPE_LIST\r
19from Library.DataType import PCD_USAGE_TYPE_LIST_OF_MODULE\r
20from Library.DataType import TAB_SPACE_SPLIT\r
64285f15 21from Library.StringUtils import GetSplitValueList\r
4234283c
LG
22from Library.ExpressionValidate import IsValidBareCString\r
23from Library.ExpressionValidate import IsValidFeatureFlagExp\r
8145b63e 24from 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
32def __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
46def 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
63def 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
93def 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
101def 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
111def 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
123def 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
135def 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
152def 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
167def 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
184def 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
217def 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
228def 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
280def 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
304def 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
365def 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
381def 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
415def 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
434def 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
452def 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
466def 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
479def 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
498def 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
522def 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
547def 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
561def 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
649def 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
664def 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
677def 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
690def 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
704def 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
722def 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