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-23 15:59:17 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-16 16:27
      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             : #include "sclist.h"
      20             : 
      21             : #include <stdlib.h>
      22             : #include <stdio.h>
      23             : #include <assert.h>
      24             : 
      25             : /** Private list record structure
      26             :  */
      27             : typedef struct sclistrecord_s {
      28             :     void* value;                                /**< Pointer to value */
      29             :     struct sclistrecord_s* next;                 /**< Next record in the list */
      30             : } sclistrecord_t;
      31             : 
      32             : /** Opaque sclist structure
      33             :  */
      34             : typedef struct sclist_s {
      35             :     sclistrecord_t* first;                       /**< Pointer to the first record */
      36             :     sclistrecord_t* last;                        /**< Pointer to the last record */
      37             : } sclist_t;
      38             : 
      39          61 : sclist_t* sclist_new() {
      40             :     sclist_t* sclist;
      41          61 :     if (NULL==(sclist=malloc(sizeof(struct sclist_s)))) {
      42           0 :         perror("sclist_new OOM");
      43           0 :         abort();
      44             :     }
      45          61 :     sclist->first=NULL;
      46          61 :     sclist->last=NULL;
      47             : 
      48          61 :     return sclist;
      49             : }
      50             : 
      51           6 : void      sclist_del(sclist_t* sclist) {
      52           6 :     assert(sclist);
      53             : 
      54          12 :     while (sclist->first!=NULL) {
      55           6 :         sclistrecord_t* first = sclist->first;
      56           6 :         sclist->first = sclist->first->next;
      57           6 :         free(first);
      58             :     }
      59           6 :     free(sclist);
      60           6 : }
      61             : 
      62         146 : sclistrecord_t* sclist_addrecord(sclist_t* sclist, void* value) {
      63             :     sclistrecord_t* record;
      64             : 
      65         146 :     assert(sclist);
      66             : 
      67             :     /* Create the record record */
      68         146 :     if (NULL==(record=malloc(sizeof(struct sclistrecord_s)))) {
      69           0 :         perror("sclist_addrecord OOM");
      70           0 :         abort();
      71             :     }
      72         146 :     record->value = value;
      73         146 :     record->next = NULL;
      74             : 
      75             :     /* Add to the list */
      76         146 :     if (NULL==sclist->first) {
      77             :         /* First record to be added in an empty list */
      78             :         /* A sentinel record would avoid this test and optimize performances
      79             :          * at the cost of sentinel size RAM consumption */
      80          44 :         sclist->first = record;
      81          44 :         sclist->last = record;
      82             :     } else {
      83             :         /* Add to the end of a non-empty list */
      84         102 :         sclist->last->next = record;
      85         102 :         sclist->last = record;
      86             :     }
      87         146 :     return record;
      88             : }
      89             : 
      90          26 : void      sclist_remrecord(sclist_t* sclist, sclistrecord_t* record) {
      91             :     sclistrecord_t* cur;
      92             :     sclistrecord_t* prev;
      93             : 
      94          26 :     assert(sclist);
      95          26 :     assert(record);
      96             : 
      97          39 :     for (cur=sclist->first, prev=NULL; (cur)&&(cur!=record); prev=cur,cur=cur->next);
      98             : 
      99             :     /* If found */
     100          26 :     if (NULL!=cur) {
     101             :         /* Remove from the chain */
     102          22 :         if (sclist->first==cur)
     103          14 :             sclist->first = cur->next;
     104             :         else
     105           8 :             prev->next = cur->next;
     106             :         /* Update the last pointer if needed */
     107          22 :         if (sclist->last==cur)
     108          16 :             sclist->last = prev;
     109             :     } else {
     110           4 :         fprintf(stderr,"sclist_remrecord record not found.\n");
     111           4 :         abort();
     112             :     }
     113          22 : }
     114             : 
     115         116 : sclistrecord_t* sclist_firstrecord(const sclist_t* sclist) {
     116         116 :     assert(sclist);
     117             : 
     118         116 :     return sclist->first;
     119             : }
     120             : 
     121         162 : sclistrecord_t* sclist_nextrecord(const sclistrecord_t* record) {
     122         162 :     assert(record);
     123             : 
     124         162 :     return record->next;
     125             : }
     126             : 
     127         191 : void*    sclist_getvalue(sclistrecord_t* record) {
     128         191 :     assert(record);
     129             : 
     130         191 :     return record->value;
     131             : }
     132             : /* vim: set tw=80: */

Generated by: LCOV version 1.16