LCOV - code coverage report
Current view: top level - src - sclist.c (source / functions) Hit Total Coverage
Test: mkernel.info Lines: 46 50 92.0 %
Date: 2024-11-24 23:50:19 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /**
       2             :  *    @file  sclist.c
       3             :  *   @brief  Basic single chained generic list
       4             :  *
       5             :  *  @author  François Cerbelle (Fanfan), francois@cerbelle.net
       6             :  *
       7             :  *  @internal
       8             :  *       Created:  15/11/2024
       9             :  *      Revision:  none
      10             :  * Last modified:  2024-11-24 18:18
      11             :  *      Compiler:  gcc
      12             :  *  Organization:  Cerbelle.net
      13             :  *     Copyright:  Copyright (c) 2024, François Cerbelle
      14             :  *
      15             :  *  This source code is released for free distribution under the terms of the
      16             :  *  GNU General Public License as published by the Free Software Foundation.
      17             :  */
      18             : 
      19             : #ifdef HAVE_CONFIG_H
      20             : #include "config.h"
      21             : #endif
      22             : 
      23             : #include "sclist.h"
      24             : 
      25             : #include <stdlib.h>
      26             : #include <stdio.h>
      27             : #include <assert.h>
      28             : 
      29             : /** Private list record structure
      30             :  */
      31             : typedef struct sclistrecord_s {
      32             :     void* value;                                /**< Pointer to value */
      33             :     struct sclistrecord_s* next;                 /**< Next record in the list */
      34             : } sclistrecord_t;
      35             : 
      36             : /** Opaque sclist structure
      37             :  */
      38             : typedef struct sclist_s {
      39             :     sclistrecord_t* first;                       /**< Pointer to the first record */
      40             :     sclistrecord_t* last;                        /**< Pointer to the last record */
      41             : } sclist_t;
      42             : 
      43         191 : sclist_t* sclist_new() {
      44             :     sclist_t* sclist;
      45         191 :     if (NULL==(sclist=malloc(sizeof(struct sclist_s)))) {
      46           0 :         perror("sclist_new OOM");
      47           0 :         abort();
      48             :     }
      49         191 :     sclist->first=NULL;
      50         191 :     sclist->last=NULL;
      51             : 
      52         191 :     return sclist;
      53             : }
      54             : 
      55           6 : void      sclist_del(sclist_t* sclist) {
      56           6 :     assert(sclist);
      57             : 
      58          12 :     while (sclist->first!=NULL) {
      59           6 :         sclistrecord_t* first = sclist->first;
      60           6 :         sclist->first = sclist->first->next;
      61           6 :         free(first);
      62             :     }
      63           6 :     free(sclist);
      64           6 : }
      65             : 
      66         326 : sclistrecord_t* sclist_addrecord(sclist_t* sclist, void* value) {
      67             :     sclistrecord_t* record;
      68             : 
      69         326 :     assert(sclist);
      70             : 
      71             :     /* Create the record record */
      72         326 :     if (NULL==(record=malloc(sizeof(struct sclistrecord_s)))) {
      73           0 :         perror("sclist_addrecord OOM");
      74           0 :         abort();
      75             :     }
      76         326 :     record->value = value;
      77         326 :     record->next = NULL;
      78             : 
      79             :     /* Add to the list */
      80         326 :     if (NULL==sclist->first) {
      81             :         /* First record to be added in an empty list */
      82             :         /* A sentinel record would avoid this test and optimize performances
      83             :          * at the cost of sentinel size RAM consumption */
      84         139 :         sclist->first = record;
      85         139 :         sclist->last = record;
      86             :     } else {
      87             :         /* Add to the end of a non-empty list */
      88         187 :         sclist->last->next = record;
      89         187 :         sclist->last = record;
      90             :     }
      91         326 :     return record;
      92             : }
      93             : 
      94         191 : void      sclist_remrecord(sclist_t* sclist, sclistrecord_t* record) {
      95             :     sclistrecord_t* cur;
      96             :     sclistrecord_t* prev;
      97             : 
      98         191 :     assert(sclist);
      99         191 :     assert(record);
     100             : 
     101         213 :     for (cur=sclist->first, prev=NULL; (cur)&&(cur!=record); prev=cur,cur=cur->next);
     102             : 
     103             :     /* If found */
     104         191 :     if (NULL!=cur) {
     105             :         /* Remove from the chain */
     106         187 :         if (sclist->first==cur)
     107         173 :             sclist->first = cur->next;
     108             :         else
     109          14 :             prev->next = cur->next;
     110             :         /* Update the last pointer if needed */
     111         187 :         if (sclist->last==cur)
     112         103 :             sclist->last = prev;
     113             :     } else {
     114           4 :         fprintf(stderr,"sclist_remrecord record not found.\n");
     115           4 :         abort();
     116             :     }
     117         187 : }
     118             : 
     119         303 : sclistrecord_t* sclist_firstrecord(const sclist_t* sclist) {
     120         303 :     assert(sclist);
     121             : 
     122         303 :     return sclist->first;
     123             : }
     124             : 
     125         405 : sclistrecord_t* sclist_nextrecord(const sclistrecord_t* record) {
     126         405 :     assert(record);
     127             : 
     128         405 :     return record->next;
     129             : }
     130             : 
     131         538 : void*    sclist_getvalue(sclistrecord_t* record) {
     132         538 :     assert(record);
     133             : 
     134         538 :     return record->value;
     135             : }
     136             : /* vim: set tw=80: */

Generated by: LCOV version 1.16