From 4234283c3acb8c35014acc1546621fbc2621b095 Mon Sep 17 00:00:00 2001 From: lgao4 Date: Fri, 26 Aug 2011 07:46:26 +0000 Subject: Sync BaseTools Branch (version r2271) to EDKII main trunk. BaseTool Branch: https://edk2-buildtools.svn.sourceforge.net/svnroot/edk2-buildtools/branches/Releases/BaseTools_r2100 Signed-off-by: lgao4 Reviewed-by: hchen30 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12214 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Source/Python/UPT/Library/ParserValidate.py | 717 +++++++++++++++++++++ 1 file changed, 717 insertions(+) create mode 100644 BaseTools/Source/Python/UPT/Library/ParserValidate.py (limited to 'BaseTools/Source/Python/UPT/Library/ParserValidate.py') diff --git a/BaseTools/Source/Python/UPT/Library/ParserValidate.py b/BaseTools/Source/Python/UPT/Library/ParserValidate.py new file mode 100644 index 0000000000..d6b9a096c7 --- /dev/null +++ b/BaseTools/Source/Python/UPT/Library/ParserValidate.py @@ -0,0 +1,717 @@ +## @file ParserValidate.py +# +# Copyright (c) 2011, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials are licensed and made available +# under the terms and conditions of the BSD License which accompanies this +# distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# + +''' +PaserValidate +''' + +import os.path +import re + +from Library.DataType import MODULE_LIST +from Library.DataType import COMPONENT_TYPE_LIST +from Library.DataType import PCD_USAGE_TYPE_LIST_OF_MODULE +from Library.DataType import TAB_SPACE_SPLIT +from Library.String import GetSplitValueList +from Library.ExpressionValidate import IsValidBareCString +from Library.ExpressionValidate import IsValidFeatureFlagExp + +## __HexDigit() method +# +# Whether char input is a Hex data bit +# +# @param TempChar: The char to test +# +def __HexDigit(TempChar): + if (TempChar >= 'a' and TempChar <= 'f') or \ + (TempChar >= 'A' and TempChar <= 'F') \ + or (TempChar >= '0' and TempChar <= '9'): + return True + else: + return False + +## IsValidHex() method +# +# Whether char input is a Hex data. +# +# @param TempChar: The char to test +# +def IsValidHex(HexStr): + if not HexStr.upper().startswith("0X"): + return False + CharList = [c for c in HexStr[2:] if not __HexDigit(c)] + if len(CharList) == 0: + return True + else: + return False + +## Judge the input string is valid bool type or not. +# +# ::= {"TRUE"} {"true"} {"True"} {"0x1"} {"0x01"} +# ::= {"FALSE"} {"false"} {"False"} {"0x0"} {"0x00"} +# ::= {} {} +# +# @param BoolString: A string contained the value need to be judged. +# +def IsValidBoolType(BoolString): + # + # Valid Ture + # + if BoolString == 'TRUE' or \ + BoolString == 'True' or \ + BoolString == 'true' or \ + BoolString == '0x1' or \ + BoolString == '0x01': + return True + # + # Valid False + # + elif BoolString == 'FALSE' or \ + BoolString == 'False' or \ + BoolString == 'false' or \ + BoolString == '0x0' or \ + BoolString == '0x00': + return True + # + # Invalid bool type + # + else: + return False + +## Is Valid Module Type List or not +# +# @param ModuleTypeList: A list contain ModuleType strings need to be +# judged. +# +def IsValidInfMoudleTypeList(ModuleTypeList): + for ModuleType in ModuleTypeList: + return IsValidInfMoudleType(ModuleType) + +## Is Valid Module Type or not +# +# @param ModuleType: A string contain ModuleType need to be judged. +# +def IsValidInfMoudleType(ModuleType): + if ModuleType in MODULE_LIST: + return True + else: + return False + +## Is Valid Component Type or not +# +# @param ComponentType: A string contain ComponentType need to be judged. +# +def IsValidInfComponentType(ComponentType): + if ComponentType.upper() in COMPONENT_TYPE_LIST: + return True + else: + return False + + +## Is valid Tool Family or not +# +# @param ToolFamily: A string contain Tool Family need to be judged. +# Famlily := [A-Z]([a-zA-Z0-9])* +# +def IsValidToolFamily(ToolFamily): + ReIsValieFamily = re.compile(r"^[A-Z]+[A-Za-z0-9]{0,}$", re.DOTALL) + if ReIsValieFamily.match(ToolFamily) == None: + return False + return True + +## Is valid Tool TagName or not +# +# The TagName sample is MYTOOLS and VS2005. +# +# @param TagName: A string contain Tool TagName need to be judged. +# +def IsValidToolTagName(TagName): + if TagName.strip() == '': + return True + if TagName.strip() == '*': + return True + if not IsValidWord(TagName): + return False + return True + +## Is valid arch or not +# +# @param Arch The arch string need to be validated +# ::= (a-zA-Z)(A-Za-z0-9){0,} +# ::= {"IA32"} {"X64"} {"IPF"} {"EBC"} {} +# {"common"} +# @param Arch: Input arch +# +def IsValidArch(Arch): + if Arch == 'common': + return True + ReIsValieArch = re.compile(r"^[a-zA-Z]+[a-zA-Z0-9]{0,}$", re.DOTALL) + if ReIsValieArch.match(Arch) == None: + return False + return True + +## Is valid family or not +# +# ::= {"MSFT"} {"GCC"} {"INTEL"} {} {"*"} +# ::= [A-Z][A-Za-z0-9]{0,} +# +# @param family: The family string need to be validated +# +def IsValidFamily(Family): + Family = Family.strip() + if Family == '*': + return True + + if Family == '': + return True + + ReIsValidFamily = re.compile(r"^[A-Z]+[A-Za-z0-9]{0,}$", re.DOTALL) + if ReIsValidFamily.match(Family) == None: + return False + return True + +## Is valid build option name or not +# +# @param BuildOptionName: The BuildOptionName string need to be validated +# +def IsValidBuildOptionName(BuildOptionName): + if not BuildOptionName: + return False + + ToolOptionList = GetSplitValueList(BuildOptionName, '_', 4) + + if len(ToolOptionList) != 5: + return False + + ReIsValidBuildOption1 = re.compile(r"^\s*(\*)|([A-Z][a-zA-Z0-9]*)$") + ReIsValidBuildOption2 = re.compile(r"^\s*(\*)|([a-zA-Z][a-zA-Z0-9]*)$") + + if ReIsValidBuildOption1.match(ToolOptionList[0]) == None: + return False + + if ReIsValidBuildOption1.match(ToolOptionList[1]) == None: + return False + + if ReIsValidBuildOption2.match(ToolOptionList[2]) == None: + return False + + if ToolOptionList[3] == "*" and ToolOptionList[4] not in ['FAMILY', 'DLL', 'DPATH']: + return False + + return True + +## IsValidToken +# +# Check if pattern string matches total token +# +# @param ReString: regular string +# @param Token: Token to be matched +# +def IsValidToken(ReString, Token): + Match = re.compile(ReString).match(Token) + return Match and Match.start() == 0 and Match.end() == len(Token) + +## IsValidPath +# +# Check if path exist +# +# @param Path: Absolute path or relative path to be checked +# @param Root: Root path +# +def IsValidPath(Path, Root): + Path = Path.strip() + OrigPath = Path.replace('\\', '/') + + Path = os.path.normpath(Path).replace('\\', '/') + Root = os.path.normpath(Root).replace('\\', '/') + FullPath = os.path.normpath(os.path.join(Root, Path)).replace('\\', '/') + + if not os.path.exists(FullPath): + return False + + # + # If Path is absolute path. + # It should be in Root. + # + if os.path.isabs(Path): + if not Path.startswith(Root): + return False + return True + + # + # Check illegal character + # + for Rel in ['/', './', '../']: + if OrigPath.startswith(Rel): + return False + for Rel in ['//', '/./', '/../']: + if Rel in OrigPath: + return False + for Rel in ['/.', '/..', '/']: + if OrigPath.endswith(Rel): + return False + + Path = Path.rstrip('/') + + # + # Check relative path + # + for Word in Path.split('/'): + if not IsValidWord(Word): + return False + + return True + +## IsValidInstallPath +# +# Check if an install path valid or not. +# +# Absolute path or path starts with '.' or path contains '..' are invalid. +# +# @param Path: path to be checked +# +def IsValidInstallPath(Path): + if os.path.isabs(Path): + return False + + if Path.startswith('.'): + return False + + if Path.find('..') != -1: + return False + + return True + + +## IsValidCFormatGuid +# +# Check if GUID format has the from of {8,4,4,{2,2,2,2,2,2,2,2}} +# +# @param Guid: Guid to be checked +# +def IsValidCFormatGuid(Guid): + # + # Valid: { 0xf0b11735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, + # 0xaf, 0x48, 0xce }} + # Invalid: { 0xf0b11735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, + # 0xaf, 0x48, 0xce }} 0x123 + # Invalid: { 0xf0b1 1735, 0x87a0, 0x4193, {0xb2, 0x66, 0x53, 0x8c, 0x38, + # 0xaf, 0x48, 0xce }} + # + List = ['{', 10, ',', 6, ',', 6, ',{', 4, ',', 4, ',', 4, + ',', 4, ',', 4, ',', 4, ',', 4, ',', 4, '}}'] + Index = 0 + Value = '' + SepValue = '' + for Char in Guid: + if Char not in '{},\t ': + Value += Char + continue + if Value: + try: + # + # Index may out of bound + # + if not SepValue or SepValue != List[Index]: + return False + Index += 1 + SepValue = '' + + if not Value.startswith('0x') and not Value.startswith('0X'): + return False + + # + # Index may out of bound + # + if type(List[Index]) != type(1) or \ + len(Value) > List[Index] or len(Value) < 3: + return False + + # + # Check if string can be converted to integer + # Throw exception if not + # + int(Value, 16) + except BaseException: + # + # Exception caught means invalid format + # + return False + Value = '' + Index += 1 + if Char in '{},': + SepValue += Char + + return SepValue == '}}' and Value == '' + +## IsValidPcdType +# +# Check whether the PCD type is valid +# +# @param PcdTypeString: The PcdType string need to be checked. +# +def IsValidPcdType(PcdTypeString): + if PcdTypeString.upper() in PCD_USAGE_TYPE_LIST_OF_MODULE: + return True + else: + return False + +## IsValidWord +# +# Check whether the word is valid. +# ::= (a-zA-Z0-9_)(a-zA-Z0-9_-){0,} Alphanumeric characters with +# optional +# dash "-" and/or underscore "_" characters. No whitespace +# characters are permitted. +# +# @param Word: The word string need to be checked. +# +def IsValidWord(Word): + if not Word: + return False + # + # The first char should be alpha, _ or Digit. + # + if not Word[0].isalnum() and \ + not Word[0] == '_' and \ + not Word[0].isdigit(): + return False + + LastChar = '' + for Char in Word[1:]: + if (not Char.isalpha()) and \ + (not Char.isdigit()) and \ + Char != '-' and \ + Char != '_' and \ + Char != '.': + return False + if Char == '.' and LastChar == '.': + return False + LastChar = Char + + return True + + +## IsValidSimpleWord +# +# Check whether the SimpleWord is valid. +# ::= (a-zA-Z0-9)(a-zA-Z0-9_-){0,} +# A word that cannot contain a period character. +# +# @param Word: The word string need to be checked. +# +def IsValidSimpleWord(Word): + ReIsValidSimpleWord = \ + re.compile(r"^[0-9A-Za-z][0-9A-Za-z\-_]*$", re.DOTALL) + Word = Word.strip() + if not Word: + return False + + if not ReIsValidSimpleWord.match(Word): + return False + + return True + +## IsValidDecVersion +# +# Check whether the decimal version is valid. +# ::= (0-9){1,} ["." (0-9){1,}] +# +# @param Word: The word string need to be checked. +# +def IsValidDecVersion(Word): + if Word.find('.') > -1: + ReIsValidDecVersion = re.compile(r"[0-9]+\.?[0-9]+$") + else: + ReIsValidDecVersion = re.compile(r"[0-9]+$") + if ReIsValidDecVersion.match(Word) == None: + return False + return True + +## IsValidHexVersion +# +# Check whether the hex version is valid. +# ::= "0x" +# ::= {4} +# ::= {4} +# +# @param Word: The word string need to be checked. +# +def IsValidHexVersion(Word): + ReIsValidHexVersion = re.compile(r"[0][xX][0-9A-Fa-f]{8}$", re.DOTALL) + if ReIsValidHexVersion.match(Word) == None: + return False + + return True + +## IsValidBuildNumber +# +# Check whether the BUILD_NUMBER is valid. +# ["BUILD_NUMBER" "=" {1,4} ] +# +# @param Word: The BUILD_NUMBER string need to be checked. +# +def IsValidBuildNumber(Word): + ReIsValieBuildNumber = re.compile(r"[0-9]{1,4}$", re.DOTALL) + if ReIsValieBuildNumber.match(Word) == None: + return False + + return True + +## IsValidDepex +# +# Check whether the Depex is valid. +# +# @param Word: The Depex string need to be checked. +# +def IsValidDepex(Word): + Index = Word.upper().find("PUSH") + if Index > -1: + return IsValidCFormatGuid(Word[Index+4:].strip()) + + ReIsValidCName = re.compile(r"^[A-Za-z_][0-9A-Za-z_\s\.]*$", re.DOTALL) + if ReIsValidCName.match(Word) == None: + return False + + return True + +## IsValidNormalizedString +# +# Check +# ::= [{} {}]{1,} +# ::= 0x20 +# +# @param String: string to be checked +# +def IsValidNormalizedString(String): + if String == '': + return True + + for Char in String: + if Char == '\t': + return False + + StringList = GetSplitValueList(String, TAB_SPACE_SPLIT) + + for Item in StringList: + if not Item: + continue + if not IsValidWord(Item): + return False + + return True + +## IsValidIdString +# +# Check whether the IdString is valid. +# +# @param IdString: The IdString need to be checked. +# +def IsValidIdString(String): + if IsValidSimpleWord(String.strip()): + return True + + if String.strip().startswith('"') and \ + String.strip().endswith('"'): + String = String[1:-1] + if String.strip() == "": + return True + if IsValidNormalizedString(String): + return True + + return False + +## IsValidVersionString +# +# Check whether the VersionString is valid. +# ::= [ []{0,} []{0,} ] {0,} +# ::= {} {} +# ::= 0x09 +# ::= 0x20 +# ::= (0x21 - 0x7E) +# +# @param VersionString: The VersionString need to be checked. +# +def IsValidVersionString(VersionString): + VersionString = VersionString.strip() + for Char in VersionString: + if not (Char >= 0x21 and Char <= 0x7E): + return False + + return True + +## IsValidPcdValue +# +# Check whether the PcdValue is valid. +# +# @param VersionString: The PcdValue need to be checked. +# +def IsValidPcdValue(PcdValue): + for Char in PcdValue: + if Char == '\n' or Char == '\t' or Char == '\f': + return False + + # + # + # + if IsValidFeatureFlagExp(PcdValue, True)[0]: + return True + + # + # ::= {} {} + # ::= {(0-9)} {(1-9)(0-9){1,}} + # ::= "0x" {1,} + # ::= (a-fA-F0-9) + # + if IsValidHex(PcdValue): + return True + + ReIsValidIntegerSingle = re.compile(r"^\s*[0-9]\s*$", re.DOTALL) + if ReIsValidIntegerSingle.match(PcdValue) != None: + return True + + ReIsValidIntegerMulti = re.compile(r"^\s*[1-9][0-9]+\s*$", re.DOTALL) + if ReIsValidIntegerMulti.match(PcdValue) != None: + return True + + + # + # ::= {} {} {"$(" ")"} + # ::= {} {} + # + ReIsValidStringType = re.compile(r"^\s*[\"L].*[\"]\s*$") + if ReIsValidStringType.match(PcdValue): + IsTrue = False + if PcdValue.strip().startswith('L\"'): + StringValue = PcdValue.strip().lstrip('L\"').rstrip('\"') + if IsValidBareCString(StringValue): + IsTrue = True + elif PcdValue.strip().startswith('\"'): + StringValue = PcdValue.strip().lstrip('\"').rstrip('\"') + if IsValidBareCString(StringValue): + IsTrue = True + if IsTrue: + return IsTrue + + # + # ::= {} {} {} + # ::= "{" [] {0,} "}" + # ::= ["," ]{0,} + # ::= (a-fA-F0-9) + # ::= "0x" {1,2} + # + if IsValidCFormatGuid(PcdValue): + return True + + ReIsValidByteHex = re.compile(r"^\s*0x[0-9a-fA-F]{1,2}\s*$", re.DOTALL) + if PcdValue.strip().startswith('{') and PcdValue.strip().endswith('}') : + StringValue = PcdValue.strip().lstrip('{').rstrip('}') + ValueList = StringValue.split(',') + AllValidFlag = True + for ValueItem in ValueList: + if not ReIsValidByteHex.match(ValueItem.strip()): + AllValidFlag = False + + if AllValidFlag: + return True + + # + # NList + # + AllValidFlag = True + ValueList = PcdValue.split(',') + for ValueItem in ValueList: + if not ReIsValidByteHex.match(ValueItem.strip()): + AllValidFlag = False + + if AllValidFlag: + return True + + return False + +## IsValidCVariableName +# +# Check whether the PcdValue is valid. +# +# @param VersionString: The PcdValue need to be checked. +# +def IsValidCVariableName(CName): + ReIsValidCName = re.compile(r"^[A-Za-z_][0-9A-Za-z_]*$", re.DOTALL) + if ReIsValidCName.match(CName) == None: + return False + + return True + +## IsValidIdentifier +# +# ::= {0,} +# ::= (a-zA-Z0-9_) +# ::= (a-zA-Z_) +# +# @param Ident: identifier to be checked +# +def IsValidIdentifier(Ident): + ReIdent = re.compile(r"^[A-Za-z_][0-9A-Za-z_]*$", re.DOTALL) + if ReIdent.match(Ident) == None: + return False + + return True + +## IsValidDecVersionVal +# +# {(0-9){1,} "." (0-99)} +# +# @param Ver: version to be checked +# +def IsValidDecVersionVal(Ver): + ReVersion = re.compile(r"[0-9]+(\.[0-9]{1,2})$") + + if ReVersion.match(Ver) == None: + return False + + return True + + +## IsValidLibName +# +# (A-Z)(a-zA-Z0-9){0,} and could not be "NULL" +# +def IsValidLibName(LibName): + if LibName == 'NULL': + return False + ReLibName = re.compile("^[A-Z]+[a-zA-Z0-9]*$") + if not ReLibName.match(LibName): + return False + + return True + +# IsValidUserId +# +# ::= (a-zA-Z)(a-zA-Z0-9_.){0,} +# Words that contain period "." must be encapsulated in double quotation marks. +# +def IsValidUserId(UserId): + UserId = UserId.strip() + Quoted = False + if UserId.startswith('"') and UserId.endswith('"'): + Quoted = True + UserId = UserId[1:-1] + if not UserId or not UserId[0].isalpha(): + return False + for Char in UserId[1:]: + if not Char.isalnum() and not Char in '_.': + return False + if Char == '.' and not Quoted: + return False + return True + -- cgit v1.2.3