]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/UPT/Library/CommentParsing.py
This patch is going to:
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Library / CommentParsing.py
index 5c07f34a7467e8c8947233339c5fb311d8f50ab0..e6d45103f94be2902354d01eac32b5210b316961 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to define comment parsing interface\r
 #\r
-# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
 #\r
 # This program and the accompanying materials are licensed and made available \r
 # under the terms and conditions of the BSD License which accompanies this \r
@@ -32,6 +32,17 @@ from Library.DataType import HEADER_COMMENT_DESCRIPTION
 from Library.DataType import TAB_SPACE_SPLIT\r
 from Library.DataType import TAB_COMMA_SPLIT\r
 from Library.DataType import SUP_MODULE_LIST\r
+from Library.DataType import TAB_VALUE_SPLIT\r
+from Library.DataType import TAB_PCD_VALIDRANGE\r
+from Library.DataType import TAB_PCD_VALIDLIST\r
+from Library.DataType import TAB_PCD_EXPRESSION\r
+from Library.DataType import TAB_PCD_PROMPT\r
+from Library.DataType import TAB_CAPHEX_START\r
+from Library.DataType import TAB_HEX_START\r
+from Library.DataType import PCD_ERR_CODE_MAX_SIZE\r
+from Library.ExpressionValidate import IsValidRangeExpr\r
+from Library.ExpressionValidate import IsValidListExpr\r
+from Library.ExpressionValidate import IsValidLogicalExpr\r
 from Object.POM.CommonObject import TextObject\r
 from Object.POM.CommonObject import PcdErrorObject\r
 import Logger.Log as Logger\r
@@ -47,13 +58,16 @@ from Logger import StringTable as ST
 # @param CommentList:   List of (Comment, LineNumber)\r
 # @param FileName:      FileName of the comment\r
 #\r
-def ParseHeaderCommentSection(CommentList, FileName = None):\r
+def ParseHeaderCommentSection(CommentList, FileName = None, IsBinaryHeader = False):\r
     Abstract = ''\r
     Description = ''\r
     Copyright = ''\r
     License = ''\r
     EndOfLine = "\n"\r
-    STR_HEADER_COMMENT_START = "@file"\r
+    if IsBinaryHeader:\r
+        STR_HEADER_COMMENT_START = "@BinaryHeader"\r
+    else:\r
+        STR_HEADER_COMMENT_START = "@file"\r
     HeaderCommentStage = HEADER_COMMENT_NOT_STARTED\r
     \r
     #\r
@@ -94,7 +108,6 @@ def ParseHeaderCommentSection(CommentList, FileName = None):
                 # in case there is no abstract and description\r
                 #\r
                 if not Comment:\r
-                    Abstract = ''\r
                     HeaderCommentStage = HEADER_COMMENT_DESCRIPTION\r
                 elif _IsCopyrightLine(Comment):\r
                     Result, ErrMsg = _ValidateCopyright(Comment)\r
@@ -134,14 +147,7 @@ def ParseHeaderCommentSection(CommentList, FileName = None):
                 if not Comment and not License:\r
                     continue\r
                 License += Comment + EndOfLine\r
-    \r
-    if not Copyright:\r
-        Logger.Error("\nUPT", FORMAT_INVALID, ST.ERR_COPYRIGHT_MISSING, \\r
-                     FileName)\r
-\r
-    if not License:\r
-        Logger.Error("\nUPT", FORMAT_INVALID, ST.ERR_LICENSE_MISSING, FileName)\r
-                     \r
+                  \r
     return Abstract.strip(), Description.strip(), Copyright.strip(), License.strip()\r
 \r
 ## _IsCopyrightLine\r
@@ -158,7 +164,7 @@ def _IsCopyrightLine (LineContent):
     ReIsCopyrightRe = re.compile(r"""(^|\s)COPYRIGHT *\(""", re.DOTALL)\r
     if ReIsCopyrightRe.search(LineContent):\r
         Result = True\r
-        \r
+\r
     return Result\r
 \r
 ## ParseGenericComment\r
@@ -188,6 +194,37 @@ def ParseGenericComment (GenericComment, ContainerFile=None, SkipTag=None):
 \r
     return HelpTxt\r
 \r
+## ParsePcdErrorCode\r
+#\r
+# @param Value: original ErrorCode value \r
+# @param ContainerFile: Input value for filename of Dec file\r
+# @param LineNum: Line Num \r
+# \r
+def ParsePcdErrorCode (Value = None, ContainerFile = None, LineNum = None):      \r
+    try: \r
+        if Value.strip().startswith((TAB_HEX_START, TAB_CAPHEX_START)):\r
+            Base = 16\r
+        else:\r
+            Base = 10\r
+        ErrorCode = long(Value, Base)\r
+        if ErrorCode > PCD_ERR_CODE_MAX_SIZE or ErrorCode < 0:\r
+            Logger.Error('Parser', \r
+                        FORMAT_NOT_SUPPORTED,\r
+                        "The format %s of ErrorCode is not valid, should be UNIT32 type or long type" % Value,\r
+                        File = ContainerFile, \r
+                        Line = LineNum)\r
+        #\r
+        # To delete the tailing 'L'\r
+        #\r
+        return hex(ErrorCode)[:-1]\r
+    except ValueError, XStr:\r
+        if XStr:\r
+            pass\r
+        Logger.Error('Parser', \r
+                    FORMAT_NOT_SUPPORTED,\r
+                    "The format %s of ErrorCode is not valid, should be UNIT32 type or long type" % Value,\r
+                    File = ContainerFile, \r
+                    Line = LineNum)\r
     \r
 ## ParseDecPcdGenericComment\r
 #\r
@@ -195,46 +232,135 @@ def ParseGenericComment (GenericComment, ContainerFile=None, SkipTag=None):
 #                         LineNum)\r
 # @param ContainerFile:  Input value for filename of Dec file\r
 # \r
-def ParseDecPcdGenericComment (GenericComment, ContainerFile):       \r
+def ParseDecPcdGenericComment (GenericComment, ContainerFile, TokenSpaceGuidCName, CName, MacroReplaceDict):       \r
     HelpStr = '' \r
+    PromptStr = ''\r
     PcdErr = None\r
+    PcdErrList = []\r
+    ValidValueNum = 0\r
+    ValidRangeNum = 0\r
+    ExpressionNum = 0\r
         \r
     for (CommentLine, LineNum) in GenericComment:\r
         Comment = CleanString2(CommentLine)[1]\r
-        if Comment.startswith("@ValidRange"):\r
-            if PcdErr:\r
+        #\r
+        # To replace Macro\r
+        #\r
+        MACRO_PATTERN = '[\t\s]*\$\([A-Z][_A-Z0-9]*\)'\r
+        MatchedStrs =  re.findall(MACRO_PATTERN, Comment)\r
+        for MatchedStr in MatchedStrs:\r
+            if MatchedStr:\r
+                Macro = MatchedStr.strip().lstrip('$(').rstrip(')').strip()\r
+                if Macro in MacroReplaceDict:\r
+                    Comment = Comment.replace(MatchedStr, MacroReplaceDict[Macro])    \r
+        if Comment.startswith(TAB_PCD_VALIDRANGE):\r
+            if ValidValueNum > 0 or ExpressionNum > 0:\r
                 Logger.Error('Parser', \r
                              FORMAT_NOT_SUPPORTED,\r
                              ST.WRN_MULTI_PCD_RANGES,\r
                              File = ContainerFile, \r
                              Line = LineNum)\r
-            ValidRange = Comment.replace("@ValidRange", "", 1)\r
-            if _CheckRangeExpression(ValidRange):\r
+            else:\r
                 PcdErr = PcdErrorObject()\r
-                PcdErr.SetValidValueRange(ValidRange)\r
-        elif Comment.startswith("@ValidList"):\r
-            if PcdErr:\r
+                PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName)\r
+                PcdErr.SetCName(CName)\r
+                PcdErr.SetFileLine(Comment)\r
+                PcdErr.SetLineNum(LineNum)\r
+                ValidRangeNum += 1\r
+            ValidRange = Comment.replace(TAB_PCD_VALIDRANGE, "", 1).strip()\r
+            Valid, Cause = _CheckRangeExpression(ValidRange)\r
+            if Valid:\r
+                ValueList = ValidRange.split(TAB_VALUE_SPLIT)\r
+                if len(ValueList) > 1:\r
+                    PcdErr.SetValidValueRange((TAB_VALUE_SPLIT.join(ValueList[1:])).strip())\r
+                    PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum))\r
+                else:\r
+                    PcdErr.SetValidValueRange(ValidRange)\r
+                PcdErrList.append(PcdErr)\r
+            else:\r
+                Logger.Error("Parser",\r
+                         FORMAT_NOT_SUPPORTED,\r
+                         Cause, \r
+                         ContainerFile, \r
+                         LineNum)\r
+        elif Comment.startswith(TAB_PCD_VALIDLIST):\r
+            if ValidRangeNum > 0 or ExpressionNum > 0:\r
                 Logger.Error('Parser', \r
                              FORMAT_NOT_SUPPORTED,\r
                              ST.WRN_MULTI_PCD_RANGES,\r
                              File = ContainerFile, \r
                              Line = LineNum)\r
-            ValidValue = Comment.replace("@ValidList", "", 1).replace(TAB_COMMA_SPLIT, TAB_SPACE_SPLIT)\r
-            PcdErr = PcdErrorObject()\r
-            PcdErr.SetValidValue(ValidValue)\r
-        elif Comment.startswith("@Expression"):\r
-            if PcdErr:\r
+            elif ValidValueNum > 0:\r
+                Logger.Error('Parser', \r
+                             FORMAT_NOT_SUPPORTED,\r
+                             ST.WRN_MULTI_PCD_VALIDVALUE,\r
+                             File = ContainerFile, \r
+                             Line = LineNum)\r
+            else:\r
+                PcdErr = PcdErrorObject()\r
+                PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName)\r
+                PcdErr.SetCName(CName)\r
+                PcdErr.SetFileLine(Comment)\r
+                PcdErr.SetLineNum(LineNum)\r
+                ValidValueNum += 1\r
+                ValidValueExpr = Comment.replace(TAB_PCD_VALIDLIST, "", 1).strip()\r
+            Valid, Cause = _CheckListExpression(ValidValueExpr)\r
+            if Valid:\r
+                ValidValue = Comment.replace(TAB_PCD_VALIDLIST, "", 1).replace(TAB_COMMA_SPLIT, TAB_SPACE_SPLIT)\r
+                ValueList = ValidValue.split(TAB_VALUE_SPLIT)\r
+                if len(ValueList) > 1:\r
+                    PcdErr.SetValidValue((TAB_VALUE_SPLIT.join(ValueList[1:])).strip())\r
+                    PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum))\r
+                else:\r
+                    PcdErr.SetValidValue(ValidValue)\r
+                PcdErrList.append(PcdErr)\r
+            else:\r
+                Logger.Error("Parser",\r
+                         FORMAT_NOT_SUPPORTED,\r
+                         Cause, \r
+                         ContainerFile, \r
+                         LineNum)\r
+        elif Comment.startswith(TAB_PCD_EXPRESSION):\r
+            if ValidRangeNum > 0 or ValidValueNum > 0:\r
                 Logger.Error('Parser', \r
                              FORMAT_NOT_SUPPORTED,\r
                              ST.WRN_MULTI_PCD_RANGES,\r
                              File = ContainerFile, \r
                              Line = LineNum)\r
-            Expression = Comment.replace("@Expression", "", 1)\r
-            if _CheckRangeExpression(Expression):\r
+            else:\r
                 PcdErr = PcdErrorObject()\r
-                PcdErr.SetExpression(Expression)\r
+                PcdErr.SetTokenSpaceGuidCName(TokenSpaceGuidCName)\r
+                PcdErr.SetCName(CName)\r
+                PcdErr.SetFileLine(Comment)\r
+                PcdErr.SetLineNum(LineNum)\r
+                ExpressionNum += 1\r
+            Expression = Comment.replace(TAB_PCD_EXPRESSION, "", 1).strip()\r
+            Valid, Cause = _CheckExpression(Expression)\r
+            if Valid:\r
+                ValueList = Expression.split(TAB_VALUE_SPLIT)\r
+                if len(ValueList) > 1:\r
+                    PcdErr.SetExpression((TAB_VALUE_SPLIT.join(ValueList[1:])).strip())\r
+                    PcdErr.SetErrorNumber(ParsePcdErrorCode(ValueList[0], ContainerFile, LineNum))\r
+                else:\r
+                    PcdErr.SetExpression(Expression)\r
+                PcdErrList.append(PcdErr)\r
+            else:        \r
+                Logger.Error("Parser",\r
+                         FORMAT_NOT_SUPPORTED,\r
+                         Cause, \r
+                         ContainerFile, \r
+                         LineNum)                \r
+        elif Comment.startswith(TAB_PCD_PROMPT):\r
+            if PromptStr:\r
+                Logger.Error('Parser', \r
+                             FORMAT_NOT_SUPPORTED,\r
+                             ST.WRN_MULTI_PCD_PROMPT,\r
+                             File = ContainerFile, \r
+                             Line = LineNum)\r
+            PromptStr = Comment.replace(TAB_PCD_PROMPT, "", 1).strip()\r
         else:\r
-            HelpStr += Comment + '\n'\r
+            if Comment:\r
+                HelpStr += Comment + '\n'\r
     \r
     #\r
     # remove the last EOL if the comment is of format 'FOO\n'\r
@@ -243,7 +369,7 @@ def ParseDecPcdGenericComment (GenericComment, ContainerFile):
         if HelpStr != '\n' and not HelpStr.endswith('\n\n'):\r
             HelpStr = HelpStr[:-1]\r
 \r
-    return HelpStr, PcdErr\r
+    return HelpStr, PcdErrList, PromptStr\r
 \r
 ## ParseDecPcdTailComment\r
 #\r
@@ -289,18 +415,43 @@ def ParseDecPcdTailComment (TailCommentList, ContainerFile):
 \r
     return SupModuleList, HelpStr\r
 \r
+## _CheckListExpression\r
+#\r
+# @param Expression: Pcd value list expression \r
+#\r
+def _CheckListExpression(Expression):\r
+    ListExpr = ''\r
+    if TAB_VALUE_SPLIT in Expression:\r
+        ListExpr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:] \r
+    else:\r
+        ListExpr = Expression\r
+        \r
+    return IsValidListExpr(ListExpr)\r
+\r
+## _CheckExpreesion\r
+#\r
+# @param Expression: Pcd value expression\r
+#\r
+def _CheckExpression(Expression):\r
+    Expr = ''\r
+    if TAB_VALUE_SPLIT in Expression:\r
+        Expr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:]\r
+    else:\r
+        Expr = Expression\r
+    return IsValidLogicalExpr(Expr, True)\r
 \r
 ## _CheckRangeExpression\r
 #\r
 # @param Expression:    Pcd range expression\r
 #          \r
 def _CheckRangeExpression(Expression):\r
-    #\r
-    # check grammar for Pcd range expression is not required yet\r
-    #\r
-    if Expression:\r
-        pass\r
-    return True\r
+    RangeExpr = ''\r
+    if TAB_VALUE_SPLIT in Expression:\r
+        RangeExpr = Expression[Expression.find(TAB_VALUE_SPLIT)+1:]\r
+    else:\r
+        RangeExpr = Expression\r
+        \r
+    return IsValidRangeExpr(RangeExpr)\r
 \r
 ## ValidateCopyright\r
 #\r
@@ -349,7 +500,6 @@ def ParseComment (Comment, UsageTokens, TypeTokens, RemoveTokens, ParseVariable)
     Usage = None\r
     Type = None\r
     String = None\r
-    HelpText = None\r
     \r
     Comment = Comment[0]\r
     \r