]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
BaseTools: resolve initialization order errors in VfrFormPkg.h
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrFormPkg.cpp
index db1e4bdd1e2e8c43331178dd0356cbb9c7a11ec9..090ee13ef9da2e1b2402294d4d1908d50e5f8999 100644 (file)
@@ -2,7 +2,7 @@
   \r
   The definition of CFormPkg's member function\r
 \r
-Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -14,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 \r
 #include "stdio.h"\r
+#include "assert.h"\r
 #include "VfrFormPkg.h"\r
 \r
 /*\r
@@ -55,13 +56,13 @@ SPendingAssign::~SPendingAssign (
   )\r
 {\r
   if (mKey != NULL) {\r
-    delete mKey;\r
+    delete[] mKey;\r
   }\r
   mAddr   = NULL;\r
   mLen    = 0;\r
   mLineNo = 0;\r
   if (mMsg != NULL) {\r
-    delete mMsg;\r
+    delete[] mMsg;\r
   }\r
   mNext   = NULL;\r
 }\r
@@ -103,8 +104,13 @@ CFormPkg::CFormPkg (
   SBufferNode *Node;\r
 \r
   mPkgLength           = 0;\r
+  mBufferSize          = 0;\r
   mBufferNodeQueueHead = NULL;\r
+  mBufferNodeQueueTail = NULL;\r
   mCurrBufferNode      = NULL;\r
+  mReadBufferNode      = NULL;\r
+  mReadBufferOffset    = 0;\r
+  PendingAssignList    = NULL;\r
 \r
   Node = new SBufferNode;\r
   if (Node == NULL) {\r
@@ -112,6 +118,7 @@ CFormPkg::CFormPkg (
   }\r
   BufferStart = new CHAR8[BufferSize];\r
   if (BufferStart == NULL) {\r
+    delete Node;\r
     return;\r
   }\r
   BufferEnd   = BufferStart + BufferSize;\r
@@ -669,6 +676,8 @@ CFormPkg::AdjustDynamicInsertOpcode (
 \r
   InserPositionNode  = GetBinBufferNodeForAddr(InserPositionAddr);\r
   InsertOpcodeNode = GetBinBufferNodeForAddr(InsertOpcodeAddr);\r
+  assert (InserPositionNode != NULL);\r
+  assert (InsertOpcodeNode  != NULL);\r
 \r
   if (InserPositionNode == InsertOpcodeNode) {\r
     //\r
@@ -741,6 +750,8 @@ CFormPkg::AdjustDynamicInsertOpcode (
       // Insert the last restore data node.\r
       //\r
       TmpNode = GetNodeBefore (InsertOpcodeNode);\r
+      assert (TmpNode != NULL);\r
+\r
       if (TmpNode == InserPositionNode) {\r
         NewRestoreNodeBegin->mNext = NewRestoreNodeEnd;\r
       } else {\r
@@ -790,6 +801,8 @@ CFormPkg::AdjustDynamicInsertOpcode (
       mBufferNodeQueueTail = NewLastEndNode;\r
     } else if (mBufferNodeQueueTail->mBufferFree - mBufferNodeQueueTail->mBufferStart == 2) {\r
       TmpNode = GetNodeBefore(mBufferNodeQueueTail);\r
+      assert (TmpNode != NULL);\r
+\r
       TmpNode->mNext = NewRestoreNodeBegin;\r
       if (NewRestoreNodeEnd != NULL) {\r
         NewRestoreNodeEnd->mNext = mBufferNodeQueueTail;\r
@@ -818,10 +831,12 @@ CFormPkg::DeclarePendingQuestion (
   CHAR8          FName[MAX_NAME_LEN];\r
   CHAR8          *SName;\r
   CHAR8          *NewStr;\r
-  UINT32         ShrinkSize;\r
+  UINT32         ShrinkSize = 0;\r
   EFI_VFR_RETURN_CODE  ReturnCode;\r
   EFI_VFR_VARSTORE_TYPE VarStoreType  = EFI_VFR_VARSTORE_INVALID;\r
-  EFI_VARSTORE_ID       VarStoreId    = EFI_VARSTORE_ID_INVALID;\r
+  UINT8    LFlags;\r
+  UINT32   MaxValue;\r
+  CIfrGuid *GuidObj = NULL;\r
 \r
   //\r
   // Declare all questions as Numeric in DisableIf True\r
@@ -829,7 +844,7 @@ CFormPkg::DeclarePendingQuestion (
   // DisableIf\r
   CIfrDisableIf DIObj;\r
   DIObj.SetLineNo (LineNo);\r
-  *InsertOpcodeAddr = DIObj.GetObjBinAddr ();\r
+  *InsertOpcodeAddr = DIObj.GetObjBinAddr<CHAR8>();\r
   \r
   //TrueOpcode\r
   CIfrTrue TObj (LineNo);\r
@@ -837,14 +852,8 @@ CFormPkg::DeclarePendingQuestion (
   // Declare Numeric qeustion for each undefined question.\r
   for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
     if (pNode->mFlag == PENDING) {\r
-      CIfrNumeric CNObj;\r
       EFI_VARSTORE_INFO Info; \r
       EFI_QUESTION_ID   QId   = EFI_QUESTION_ID_INVALID;\r
-\r
-      CNObj.SetLineNo (LineNo);\r
-      CNObj.SetPrompt (0x0);\r
-      CNObj.SetHelp (0x0);\r
-\r
       //\r
       // Register this question, assume it is normal question, not date or time question\r
       //\r
@@ -881,7 +890,7 @@ CFormPkg::DeclarePendingQuestion (
       } else {\r
         if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
           ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);\r
-        } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {\r
+        } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER || VarStoreType == EFI_VFR_VARSTORE_BUFFER_BITS) {\r
           VarStr = pNode->mKey;\r
           //convert VarStr with store name to VarStr with structure name\r
           ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (Info.mVarStoreId, &SName);\r
@@ -890,8 +899,8 @@ CFormPkg::DeclarePendingQuestion (
             NewStr[0] = '\0';\r
             strcpy (NewStr, SName);\r
             strcat (NewStr, VarStr + strlen (FName));\r
-            ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
-            delete NewStr;\r
+            ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize, Info.mIsBitVar);\r
+            delete[] NewStr;\r
           }\r
         } else {\r
           ReturnCode = VFR_RETURN_UNSUPPORTED;\r
@@ -901,39 +910,63 @@ CFormPkg::DeclarePendingQuestion (
         gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
         return ReturnCode;\r
       }\r
-\r
-      CNObj.SetQuestionId (QId);\r
-      CNObj.SetVarStoreInfo (&Info);\r
       //\r
-      // Numeric doesn't support BOOLEAN data type. \r
-      // BOOLEAN type has the same data size to UINT8. \r
+      // If the storage is bit fields, create Guid opcode to wrap the numeric opcode.\r
       //\r
-      if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
-        Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
+      if (Info.mIsBitVar) {\r
+        GuidObj = new CIfrGuid(0);\r
+        GuidObj->SetGuid (&gEdkiiIfrBitVarGuid);\r
+        GuidObj->SetLineNo(LineNo);\r
       }\r
-      CNObj.SetFlags (0, Info.mVarType);\r
+\r
+      CIfrNumeric CNObj;\r
+      CNObj.SetLineNo (LineNo);\r
+      CNObj.SetPrompt (0x0);\r
+      CNObj.SetHelp (0x0);\r
+      CNObj.SetQuestionId (QId);\r
+      CNObj.SetVarStoreInfo (&Info);\r
+\r
       //\r
-      // Use maximum value not to limit the vaild value for the undefined question.\r
+      // Set Min/Max/Step Data and flags for the question with bit fields.Min/Max/Step Data are saved as UINT32 type for bit question.\r
       //\r
-      switch (Info.mVarType) {\r
-      case EFI_IFR_TYPE_NUM_SIZE_64:\r
-        CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
-        ShrinkSize = 0;\r
-        break;\r
-      case EFI_IFR_TYPE_NUM_SIZE_32:\r
-        CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
+      if (Info.mIsBitVar) {\r
+        MaxValue = (1 << Info.mVarTotalSize) -1;\r
+        CNObj.SetMinMaxStepData ((UINT32) 0, MaxValue, (UINT32) 0);\r
         ShrinkSize = 12;\r
-        break;\r
-      case EFI_IFR_TYPE_NUM_SIZE_16:\r
-        CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
-        ShrinkSize = 18;\r
-        break;\r
-      case EFI_IFR_TYPE_NUM_SIZE_8:\r
-        CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
-        ShrinkSize = 21;\r
-        break;\r
-      default:\r
-        break;\r
+        LFlags = (EDKII_IFR_NUMERIC_SIZE_BIT & Info.mVarTotalSize);\r
+        CNObj.SetFlagsForBitField (0, LFlags);\r
+      } else {\r
+        //\r
+        // Numeric doesn't support BOOLEAN data type.\r
+        // BOOLEAN type has the same data size to UINT8.\r
+        //\r
+        if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
+          Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
+        }\r
+        CNObj.SetFlags (0, Info.mVarType);\r
+        //\r
+        // Use maximum value not to limit the vaild value for the undefined question.\r
+        //\r
+        switch (Info.mVarType) {\r
+        case EFI_IFR_TYPE_NUM_SIZE_64:\r
+          CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
+          ShrinkSize = 0;\r
+          break;\r
+        case EFI_IFR_TYPE_NUM_SIZE_32:\r
+          CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
+          ShrinkSize = 12;\r
+          break;\r
+        case EFI_IFR_TYPE_NUM_SIZE_16:\r
+          CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
+          ShrinkSize = 18;\r
+          break;\r
+        case EFI_IFR_TYPE_NUM_SIZE_8:\r
+          CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
+          ShrinkSize = 21;\r
+          break;\r
+        default:\r
+          break;\r
+        }\r
       }\r
       CNObj.ShrinkBinSize (ShrinkSize);\r
 \r
@@ -949,8 +982,18 @@ CFormPkg::DeclarePendingQuestion (
       //\r
       // End for Numeric\r
       //\r
-      CIfrEnd CEObj; \r
+      CIfrEnd CEObj;\r
       CEObj.SetLineNo (LineNo);\r
+      //\r
+      // End for Guided opcode\r
+      //\r
+      if (GuidObj != NULL) {\r
+        CIfrEnd CEObjGuid;\r
+        CEObjGuid.SetLineNo (LineNo);\r
+        GuidObj->SetScope(1);\r
+        delete GuidObj;\r
+        GuidObj = NULL;\r
+      }\r
     }\r
   }\r
 \r
@@ -1201,7 +1244,6 @@ CIfrRecordInfoDB::CheckQuestionOpCode (
   case EFI_IFR_TIME_OP:\r
   case EFI_IFR_ORDERED_LIST_OP:\r
   case EFI_IFR_REF_OP:\r
-  case EFI_IFR_RESET_BUTTON_OP:\r
     return TRUE;\r
   default:\r
     return FALSE;\r
@@ -1291,6 +1333,7 @@ CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
   SIfrRecord         *pAdjustNode, *pNodeBeforeAdjust;\r
   SIfrRecord         *pNodeBeforeDynamic;\r
 \r
+  pPreNode            = NULL;\r
   pAdjustNode         = NULL;\r
   pNodeBeforeDynamic  = NULL;\r
   OpcodeOffset        = 0;\r
@@ -1315,7 +1358,7 @@ CIfrRecordInfoDB::IfrAdjustDynamicOpcodeInRecords (
   //\r
   // Check the nodes whether exist.\r
   //\r
-  if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL) {\r
+  if (pNodeBeforeDynamic == NULL || pAdjustNode == NULL || pNodeBeforeAdjust == NULL) {\r
     return FALSE;\r
   }\r
 \r
@@ -1358,7 +1401,7 @@ CIfrRecordInfoDB::IfrUpdateRecordInfoForDynamicOpcode (
   // Base on the original offset info to update the record list.\r
   //\r
   if (!IfrAdjustDynamicOpcodeInRecords(CreateOpcodeAfterParsingVfr)) {\r
-    gCVfrErrorHandle.PrintMsg (0, "Error", "Can not find the adjust offset in the record.");\r
+    gCVfrErrorHandle.PrintMsg (0, (CHAR8 *)"Error", (CHAR8 *)"Can not find the adjust offset in the record.");\r
   }\r
 \r
   //\r
@@ -1403,7 +1446,6 @@ CIfrRecordInfoDB::IfrRecordAdjust (
   EFI_QUESTION_ID    QuestionId;\r
   UINT32             StackCount;\r
   UINT32             QuestionScope;\r
-  UINT32             OpcodeOffset;\r
   CHAR8              ErrorMsg[MAX_STRING_LEN] = {0, };\r
   EFI_VFR_RETURN_CODE  Status;\r
 \r
@@ -1839,6 +1881,7 @@ CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
     // Point to the first expression opcode.\r
     //\r
     pSNode = pDefaultNode->mNext;\r
+    pENode = NULL;\r
     ScopeCount++;\r
     //\r
     // Get opcode number behind the EFI_IFR_DEFAULT_2 until reach its END opcode (including the END opcode of EFI_IFR_DEFAULT_2)\r
@@ -1855,6 +1898,10 @@ CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
       pSNode = pSNode->mNext;\r
       OpcodeCount++;\r
     }\r
+\r
+    assert (pSNode);\r
+    assert (pENode);\r
+\r
     //\r
     // Record the offset of node which need to be adjust, will move the new created default opcode to this offset.\r
     //\r
@@ -1876,8 +1923,9 @@ CIfrRecordInfoDB::IfrCreateDefaultForQuestion (
         while (pSNode != NULL && pSNode->mNext != NULL && OpcodeNumber-- != 0) {\r
           pOpHead = (EFI_IFR_OP_HEADER *) pSNode->mIfrBinBuf;\r
           Obj = new CIfrObj (pOpHead->OpCode, NULL, pSNode->mBinBufLen, FALSE);\r
+          assert (Obj != NULL);\r
           Obj->SetLineNo (pSNode->mLineNo);\r
-          ObjBinBuf = Obj->GetObjBinAddr();\r
+          ObjBinBuf = Obj->GetObjBinAddr<CHAR8>();\r
           memcpy (ObjBinBuf, pSNode->mIfrBinBuf, (UINTN)pSNode->mBinBufLen);\r
           delete Obj;\r
           pSNode = pSNode->mNext;\r
@@ -2378,6 +2426,9 @@ CIfrObj::CIfrObj (
   mObjBinLen   = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
   mObjBinBuf   = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
   mRecordIdx   = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
+  mLineNo      = 0;\r
+\r
+  assert (mObjBinBuf != NULL);\r
 \r
   if (IfrObj != NULL) {\r
     *IfrObj    = mObjBinBuf;\r