]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseLib/LinkedList.c
MdePkg BaseLib: Fix GCC build break
[mirror_edk2.git] / MdePkg / Library / BaseLib / LinkedList.c
index 8069bd3550fc753a812bc6f11f2adc3049225a3a..f3e57702a641670dfc270b07bdd173190707c19d 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   Linked List Library Functions.\r
 \r
-  Copyright (c) 2006 - 2008, Intel Corporation<BR>\r
-  All rights reserved. This program and the accompanying materials\r
+  Copyright (c) 2006 - 2008, 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
   http://opensource.org/licenses/bsd-license.php\r
   If List is NULL, then ASSERT().\r
   If List->ForwardLink is NULL, then ASSERT().\r
   If List->backLink is NULL, then ASSERT().\r
-  If Node is NULL, then ASSERT();\r
-  If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number\r
-  of nodes in ListHead, including the ListHead node, is greater than or\r
-  equal to PcdMaximumLinkedListLength, then ASSERT().\r
+  If Node is NULL, then ASSERT().\r
+  If PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE and Node \r
+  is in not a member of List, then return FALSE\r
+  If PcdMaximumLinkedListLenth is not zero, and List contains more than\r
+  PcdMaximumLinkedListLenth nodes, then ASSERT().\r
 \r
-  @param  List  A pointer to a node in a linked list.\r
-  @param  Node  A pointer to one nod.\r
+  @param  List              A pointer to a node in a linked list.\r
+  @param  Node              A pointer to a node in a linked list.\r
+  @param  VerifyNodeInList  TRUE if a check should be made to see if Node is a \r
+                            member of List.  FALSE if no membership test should \r
+                            be performed.\r
 \r
-  @retval TRUE   Node is in List\r
-  @retval FALSE  Node isn't in List, or List is invalid\r
+  @retval   TRUE if PcdVerifyNodeInList is FALSE\r
+  @retval   TRUE if DoMembershipCheck is FALSE\r
+  @retval   TRUE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE \r
+            and Node is a member of List.\r
+  @retval   FALSE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE \r
+            and Node is in not a member of List.\r
 \r
 **/\r
 BOOLEAN\r
 EFIAPI\r
-IsNodeInList (\r
-  IN      CONST LIST_ENTRY      *List,\r
-  IN      CONST LIST_ENTRY      *Node\r
+InternalBaseLibIsNodeInList (\r
+  IN CONST LIST_ENTRY  *List,\r
+  IN CONST LIST_ENTRY  *Node,\r
+  IN BOOLEAN           VerifyNodeInList\r
   )\r
 {\r
-  UINTN                         Count;\r
-  CONST LIST_ENTRY              *Ptr;\r
-  BOOLEAN                       Found;\r
+  UINTN             Count;\r
+  CONST LIST_ENTRY  *Ptr;\r
 \r
   //\r
   // Test the validity of List and Node\r
@@ -54,24 +62,54 @@ IsNodeInList (
   ASSERT (List->BackLink != NULL);\r
   ASSERT (Node != NULL);\r
 \r
-  Count = PcdGet32 (PcdMaximumLinkedListLength);\r
+  Count = 0;\r
+  Ptr   = List;\r
 \r
-  Ptr = List;\r
-  do {\r
-    Ptr = Ptr->ForwardLink;\r
-    Count--;\r
-  } while ((Ptr != List) && (Ptr != Node) && (Count > 0));\r
-  Found = (BOOLEAN)(Ptr == Node);\r
+  if (FeaturePcdGet (PcdVerifyNodeInList) && VerifyNodeInList) {\r
+    //\r
+    // Check to see if Node is a member of List.  \r
+    // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength\r
+    //\r
+    do {\r
+      Ptr = Ptr->ForwardLink;\r
+      if (PcdGet32 (PcdMaximumLinkedListLength) > 0) {\r
+        Count++;\r
+        //\r
+        // ASSERT() if the linked list is too long\r
+        //\r
+        ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength));\r
+\r
+        //\r
+        // Return if the linked list is too long\r
+        //\r
+        if (Count >= PcdGet32 (PcdMaximumLinkedListLength)) {\r
+          return (BOOLEAN)(Ptr == Node);\r
+        }\r
+      }\r
+    } while ((Ptr != List) && (Ptr != Node)); \r
+\r
+    if (Ptr != Node) {\r
+      return FALSE;\r
+    }\r
+  }\r
 \r
   if (PcdGet32 (PcdMaximumLinkedListLength) > 0) {\r
-    while ((Count > 0) && (Ptr != List)) {\r
+    //\r
+    // Count the total number of nodes in List.\r
+    // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength\r
+    //\r
+    do {\r
       Ptr = Ptr->ForwardLink;\r
-      Count--;\r
-    }\r
-    ASSERT (Count > 0);\r
+      Count++;\r
+    } while ((Ptr != List) && (Count < PcdGet32 (PcdMaximumLinkedListLength)));\r
+\r
+    //\r
+    // ASSERT() if the linked list is too long\r
+    //\r
+    ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength));\r
   }\r
 \r
-  return Found;\r
+  return TRUE;\r
 }\r
 \r
 /**\r
@@ -136,8 +174,8 @@ InsertHeadList (
   //\r
   // ASSERT List not too long and Entry is not one of the nodes of List\r
   //\r
-  ASSERT (!IsNodeInList (ListHead, Entry));\r
-\r
+  ASSERT (InternalBaseLibIsNodeInList (ListHead, Entry, FALSE));\r
+  \r
   Entry->ForwardLink = ListHead->ForwardLink;\r
   Entry->BackLink = ListHead;\r
   Entry->ForwardLink->BackLink = Entry;\r
@@ -177,8 +215,8 @@ InsertTailList (
   //\r
   // ASSERT List not too long and Entry is not one of the nodes of List\r
   //\r
-  ASSERT (!IsNodeInList (ListHead, Entry));\r
-\r
+  ASSERT (InternalBaseLibIsNodeInList (ListHead, Entry, FALSE));\r
+  \r
   Entry->ForwardLink = ListHead;\r
   Entry->BackLink = ListHead->BackLink;\r
   Entry->BackLink->ForwardLink = Entry;\r
@@ -215,7 +253,7 @@ GetFirstNode (
   //\r
   // ASSERT List not too long\r
   //\r
-  ASSERT (IsNodeInList (List, List));\r
+  ASSERT (InternalBaseLibIsNodeInList (List, List, FALSE));\r
 \r
   return List->ForwardLink;\r
 }\r
@@ -233,13 +271,12 @@ GetFirstNode (
   InitializeListHead(), then ASSERT().\r
   If PcdMaximumLinkedListLenth is not zero, and List contains more than\r
   PcdMaximumLinkedListLenth nodes, then ASSERT().\r
-  If Node is not a node in List, then ASSERT().\r
+  If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
 \r
   @param  List  A pointer to the head node of a doubly linked list.\r
   @param  Node  A pointer to a node in the doubly linked list.\r
 \r
-  @return Pointer to the next node if one exists. Otherwise a null value which\r
-          is actually List is returned.\r
+  @return Pointer to the next node if one exists. Otherwise List is returned.\r
 \r
 **/\r
 LIST_ENTRY *\r
@@ -252,11 +289,47 @@ GetNextNode (
   //\r
   // ASSERT List not too long and Node is one of the nodes of List\r
   //\r
-  ASSERT (IsNodeInList (List, Node));\r
+  ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));\r
 \r
   return Node->ForwardLink;\r
 }\r
 \r
+/**\r
+  Retrieves the previous node of a doubly linked list.\r
\r
+  Returns the node of a doubly linked list that precedes Node.  \r
+  List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()\r
+  or InitializeListHead().  If List is empty, then List is returned.\r
\r
+  If List is NULL, then ASSERT().\r
+  If Node is NULL, then ASSERT().\r
+  If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or \r
+  InitializeListHead(), then ASSERT().\r
+  If PcdMaximumLinkedListLenth is not zero, and List contains more than\r
+  PcdMaximumLinkedListLenth nodes, then ASSERT().\r
+  If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
\r
+  @param  List  A pointer to the head node of a doubly linked list.\r
+  @param  Node  A pointer to a node in the doubly linked list.\r
\r
+  @return Pointer to the previous node if one exists. Otherwise List is returned.\r
\r
+**/\r
+LIST_ENTRY *\r
+EFIAPI\r
+GetPreviousNode (\r
+  IN      CONST LIST_ENTRY          *List,\r
+  IN      CONST LIST_ENTRY          *Node\r
+  )\r
+{\r
+  //\r
+  // ASSERT List not too long and Node is one of the nodes of List\r
+  //\r
+  ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));\r
\r
+  return Node->BackLink;\r
+}\r
+\r
 /**\r
   Checks to see if a doubly linked list is empty or not.\r
 \r
@@ -285,8 +358,8 @@ IsListEmpty (
   //\r
   // ASSERT List not too long\r
   //\r
-  ASSERT (IsNodeInList (ListHead, ListHead));\r
-\r
+  ASSERT (InternalBaseLibIsNodeInList (ListHead, ListHead, FALSE));\r
+  \r
   return (BOOLEAN)(ListHead->ForwardLink == ListHead);\r
 }\r
 \r
@@ -306,7 +379,8 @@ IsListEmpty (
   If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
   in List, including the List node, is greater than or equal to\r
   PcdMaximumLinkedListLength, then ASSERT().\r
-  If Node is not a node in List and Node is not equal to List, then ASSERT().\r
+  If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not \r
+  equal to List, then ASSERT().\r
 \r
   @param  List  A pointer to the head node of a doubly linked list.\r
   @param  Node  A pointer to a node in the doubly linked list.\r
@@ -325,8 +399,8 @@ IsNull (
   //\r
   // ASSERT List not too long and Node is one of the nodes of List\r
   //\r
-  ASSERT (IsNodeInList (List, Node));\r
-\r
+  ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));\r
+  \r
   return (BOOLEAN)(Node == List);\r
 }\r
 \r
@@ -344,7 +418,7 @@ IsNull (
   If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r
   in List, including the List node, is greater than or equal to\r
   PcdMaximumLinkedListLength, then ASSERT().\r
-  If Node is not a node in List, then ASSERT().\r
+  If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
 \r
   @param  List  A pointer to the head node of a doubly linked list.\r
   @param  Node  A pointer to a node in the doubly linked list.\r
@@ -363,8 +437,8 @@ IsNodeAtEnd (
   //\r
   // ASSERT List not too long and Node is one of the nodes of List\r
   //\r
-  ASSERT (IsNodeInList (List, Node));\r
-\r
+  ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));\r
+  \r
   return (BOOLEAN)(!IsNull (List, Node) && List->BackLink == Node);\r
 }\r
 \r
@@ -381,7 +455,8 @@ IsNodeAtEnd (
 \r
   If FirstEntry is NULL, then ASSERT().\r
   If SecondEntry is NULL, then ASSERT().\r
-  If SecondEntry and FirstEntry are not in the same linked list, then ASSERT().\r
+  If PcdVerifyNodeInList is TRUE and SecondEntry and FirstEntry are not in the \r
+  same linked list, then ASSERT().\r
   If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r
   linked list containing the FirstEntry and SecondEntry nodes, including\r
   the FirstEntry and SecondEntry nodes, is greater than or equal to\r
@@ -409,8 +484,8 @@ SwapListEntries (
   //\r
   // ASSERT Entry1 and Entry2 are in the same linked list\r
   //\r
-  ASSERT (IsNodeInList (FirstEntry, SecondEntry));\r
-\r
+  ASSERT (InternalBaseLibIsNodeInList (FirstEntry, SecondEntry, TRUE));\r
+  \r
   //\r
   // Ptr is the node pointed to by FirstEntry->ForwardLink\r
   //\r
@@ -468,7 +543,7 @@ RemoveEntryList (
   )\r
 {\r
   ASSERT (!IsListEmpty (Entry));\r
-\r
+  \r
   Entry->ForwardLink->BackLink = Entry->BackLink;\r
   Entry->BackLink->ForwardLink = Entry->ForwardLink;\r
   return Entry->ForwardLink;\r