LCOV - code coverage report
Current view: top level - lib - list.c (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 22 31 71.0 %
Date: 2023-04-18 16:19:03 Functions: 4 5 80.0 %

          Line data    Source code
       1             : /*
       2             :  * list - double linked list routines
       3             :  * Author: Rusty Russell <rusty@rustcorp.com.au>
       4             :  *
       5             :  * The list header contains routines for manipulating double linked lists.
       6             :  * It defines two types: struct list_head used for anchoring lists, and
       7             :  * struct list_node which is usually embedded in the structure which is placed
       8             :  * in the list.
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the
      12             :  * "Software"), to deal in the Software without restriction, including
      13             :  * without limitation the rights to use, copy, modify, merge, publish,
      14             :  * distribute, sublicense, and/or sell copies of the Software, and to permit
      15             :  * persons to whom the Software is furnished to do so, subject to the
      16             :  * following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      23             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      24             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      25             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
      26             :  * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
      27             :  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      28             :  */
      29             : 
      30             : #include <stdio.h>
      31             : #include <stdlib.h>
      32             : 
      33             : #include "list.h"
      34             : 
      35             : #ifndef NDEBUG
      36             : static struct list_node poison_node_1 = {.next = (void *)0xdeadbeef,
      37             :                                          .prev = (void *)0xbebacafe};
      38             : static struct list_node poison_node_2 = {.next = (void *)0xbebacafe,
      39             :                                          .prev = (void *)0xdeadbeef};
      40             : 
      41         796 : void list_poison_node(struct list_node *node)
      42             : {
      43         796 :     node->prev = &poison_node_1;
      44         796 :     node->next = &poison_node_2;
      45         796 : }
      46             : 
      47        5010 : static bool is_poisoned(const struct list_node *node)
      48             : {
      49        5010 :     assert(poison_node_1.next == poison_node_2.prev);
      50        5010 :     assert(poison_node_1.prev == poison_node_2.next);
      51        5010 :     assert(poison_node_1.next == (void *)0xdeadbeef);
      52        5010 :     assert(poison_node_1.prev == (void *)0xbebacafe);
      53             : 
      54       10020 :     return (node->prev == &poison_node_1 || node->prev == &poison_node_2) ||
      55        5010 :            (node->next == &poison_node_1 || node->next == &poison_node_2);
      56             : }
      57             : 
      58           0 : static void *corrupt(const char *abortstr,
      59             :                      const struct list_node *head,
      60             :                      const struct list_node *node,
      61             :                      unsigned int count)
      62             : {
      63           0 :     if (abortstr) {
      64           0 :         fprintf(stderr, "%s: prev corrupt in node %p (%u) of %p\n", abortstr,
      65             :                 node, count, head);
      66           0 :         abort();
      67             :     }
      68           0 :     return NULL;
      69             : }
      70             : #endif
      71             : 
      72        5010 : struct list_node *list_check_node(const struct list_node *node,
      73             :                                   const char *abortstr)
      74             : {
      75             : #ifndef NDEBUG
      76             :     const struct list_node *p, *n;
      77        5010 :     unsigned int count = 0;
      78             : 
      79        5010 :     if (is_poisoned(node))
      80           0 :         return corrupt(abortstr, node, node, 0);
      81             : 
      82        8075 :     for (p = node, n = node->next; n != node; p = n, n = n->next) {
      83        3065 :         count++;
      84        3065 :         if (n->prev != p)
      85           0 :             return corrupt(abortstr, node, n, count);
      86             :     }
      87             :     /* Check prev on head node. */
      88        5010 :     if (node->prev != p)
      89           0 :         return corrupt(abortstr, node, node, 0);
      90             : #else
      91             :     (void)abortstr;
      92             : #endif
      93             : 
      94        5010 :     return (struct list_node *)node;
      95             : }
      96             : 
      97        4214 : struct list_head *list_check(const struct list_head *h, const char *abortstr)
      98             : {
      99        4214 :     if (!list_check_node(&h->n, abortstr))
     100           0 :         return NULL;
     101        4214 :     return (struct list_head *)h;
     102             : }

Generated by: LCOV version 1.15-2-gb9d6727