LCOV - code coverage report
Current view: top level - src - sclist.c (source / functions) Hit Total Coverage
Test: mkernel.info Lines: 47 51 92.2 %
Date: 2024-12-05 21:00:54 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-29 17:58
      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         233 : sclist_t* sclist_new() {
      44             :     sclist_t* sclist;
      45         233 :     if (NULL==(sclist=malloc(sizeof(struct sclist_s)))) {
      46           0 :         perror("sclist_new OOM");
      47           0 :         abort();
      48             :     }
      49         233 :     sclist->first=NULL;
      50         233 :     sclist->last=NULL;
      51             : 
      52         233 :     return sclist;
      53             : }
      54             : 
      55         164 : void      sclist_del(sclist_t* sclist) {
      56         164 :     assert(sclist);
      57             : 
      58         173 :     while (sclist->first!=NULL) {
      59           9 :         sclistrecord_t* first = sclist->first;
      60           9 :         sclist->first = sclist->first->next;
      61           9 :         free(first);
      62             :     }
      63         164 :     free(sclist);
      64         164 : }
      65             : 
      66         352 : sclistrecord_t* sclist_addrecord(sclist_t* sclist, void* value) {
      67             :     sclistrecord_t* record;
      68             : 
      69         352 :     assert(sclist);
      70             : 
      71             :     /* Create the record record */
      72         352 :     if (NULL==(record=malloc(sizeof(struct sclistrecord_s)))) {
      73           0 :         perror("sclist_addrecord OOM");
      74           0 :         abort();
      75             :     }
      76         352 :     record->value = value;
      77         352 :     record->next = NULL;
      78             : 
      79             :     /* Add to the list */
      80         352 :     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         158 :         sclist->first = record;
      85         158 :         sclist->last = record;
      86             :     } else {
      87             :         /* Add to the end of a non-empty list */
      88         194 :         sclist->last->next = record;
      89         194 :         sclist->last = record;
      90             :     }
      91         352 :     return record;
      92             : }
      93             : 
      94         223 : sclist_t* sclist_remrecord(sclist_t* sclist, sclistrecord_t* record) {
      95             :     sclistrecord_t* cur;
      96             :     sclistrecord_t* prev;
      97             : 
      98         223 :     assert(sclist);
      99         223 :     assert(record);
     100             : 
     101         256 :     for (cur=sclist->first, prev=NULL; (cur)&&(cur!=record); prev=cur,cur=cur->next);
     102             : 
     103             :     /* If found */
     104         223 :     if (NULL!=cur) {
     105             :         /* Remove from the chain */
     106         215 :         if (sclist->first==cur)
     107         200 :             sclist->first = cur->next;
     108             :         else
     109          15 :             prev->next = cur->next;
     110             :         /* Update the last pointer if needed */
     111         215 :         if (sclist->last==cur)
     112         125 :             sclist->last = prev;
     113         215 :         free(cur);
     114         215 :         return sclist;
     115             :     } else {
     116           8 :         fprintf(stderr,"ERROR: sclist_remrecord record not found.\n");
     117           8 :         return NULL;
     118             :     }
     119             : }
     120             : 
     121         372 : sclistrecord_t* sclist_firstrecord(const sclist_t* sclist) {
     122         372 :     assert(sclist);
     123             : 
     124         372 :     return sclist->first;
     125             : }
     126             : 
     127         456 : sclistrecord_t* sclist_nextrecord(const sclistrecord_t* record) {
     128         456 :     assert(record);
     129             : 
     130         456 :     return record->next;
     131             : }
     132             : 
     133         586 : void*    sclist_getvalue(sclistrecord_t* record) {
     134         586 :     assert(record);
     135             : 
     136         586 :     return record->value;
     137             : }
     138             : /* vim: set tw=80: */

Generated by: LCOV version 1.16