rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

logger.h (3348B)


      1 /* Copyright (C) 2013-2023, 2025 Vincent Forest (vaplv@free.fr)
      2  *
      3  * The RSys library is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published
      5  * by the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * The RSys library is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License
     14  * along with the RSys library. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #ifndef LOGGER_H
     17 #define LOGGER_H
     18 
     19 #include "dynamic_array_char.h"
     20 #include "list.h"
     21 #include "mem_allocator.h"
     22 #include "mutex.h"
     23 
     24 #include <stdarg.h>
     25 
     26 #define LOGGER_DEFAULT ((struct logger*)(int64_t)0xC0DE)
     27 
     28 enum log_type {
     29   LOG_OUTPUT,
     30   LOG_ERROR,
     31   LOG_WARNING,
     32   LOG_TYPES_COUNT__
     33 };
     34 
     35 struct logger {
     36   /* Internal data */
     37   struct {
     38     void (*writer)(const char* msg, void* ctx);
     39     void* ctx;
     40   } streams[LOG_TYPES_COUNT__];
     41   struct mutex* mutex;
     42   struct mem_allocator* allocator;
     43   struct darray_char buffer;
     44 };
     45 
     46 static INLINE void
     47 logger_release(struct logger* logger)
     48 {
     49   ASSERT(logger);
     50   darray_char_release(&logger->buffer);
     51   if(logger->mutex) mutex_destroy(logger->mutex);
     52 }
     53 
     54 static INLINE res_T
     55 logger_init
     56   (struct mem_allocator* allocator, /* May be NULL <=> default allocator */
     57    struct logger* logger)
     58 {
     59   int i;
     60   res_T res = RES_OK;
     61   ASSERT(logger);
     62 
     63   memset(logger, 0, sizeof(struct logger));
     64   logger->allocator = allocator ? allocator : &mem_default_allocator;
     65   FOR_EACH(i, 0, LOG_TYPES_COUNT__) logger->streams[i].writer = NULL;
     66 
     67   darray_char_init(logger->allocator, &logger->buffer);
     68   res = darray_char_resize(&logger->buffer, 256);
     69   if(res != RES_OK) goto error;
     70 
     71   logger->mutex = mutex_create();
     72   if(!logger->mutex) {
     73     res = RES_MEM_ERR;
     74     goto error;
     75   }
     76 
     77 exit:
     78   return res;
     79 error:
     80   logger_release(logger);
     81   goto exit;
     82 }
     83 
     84 static INLINE void
     85 logger_clear(struct logger* logger)
     86 {
     87   int i;
     88   ASSERT(logger);
     89   FOR_EACH(i, 0, LOG_TYPES_COUNT__) logger->streams[i].writer = NULL;
     90 }
     91 
     92 static INLINE void
     93 logger_set_stream
     94   (struct logger* logger,
     95    const enum log_type type,
     96    void (*writer)(const char* msg, void* ctx), /* May be NULL */
     97    void* ctx) /* May be NULL */
     98 {
     99   ASSERT(logger && (unsigned)type < LOG_TYPES_COUNT__);
    100   mutex_lock(logger->mutex);
    101   logger->streams[type].writer = writer;
    102   logger->streams[type].ctx = ctx;
    103   mutex_unlock(logger->mutex);
    104 }
    105 
    106 static FINLINE char
    107 logger_has_stream
    108   (struct logger* logger,
    109    const enum log_type type)
    110 {
    111   char b;
    112   ASSERT(logger && (unsigned)type < LOG_TYPES_COUNT__);
    113   mutex_lock(logger->mutex);
    114   b = logger->streams[type].writer != NULL;
    115   mutex_unlock(logger->mutex);
    116   return b;
    117 }
    118 
    119 BEGIN_DECLS
    120 
    121 RSYS_API res_T
    122 logger_print
    123   (struct logger* logger,
    124    const enum log_type type,
    125    const char* log,
    126    ... )
    127 #ifdef COMPILER_GCC
    128   __attribute((format(printf, 3, 4)))
    129 #endif
    130 ;
    131 
    132 /* The value of vargs is undefined after the call of logger_vprint */
    133 RSYS_API res_T
    134 logger_vprint
    135   (struct logger* logger,
    136    const enum log_type type,
    137    const char* log,
    138    va_list vargs);
    139 
    140 END_DECLS
    141 
    142 #endif /* LOGGER_H */