commit 15f4fa8ba124fed78581f87258e96bef55db7539
parent 16122bf99ac305d84f4ec94dfe37c100f06c06f7
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 14 Mar 2022 16:16:07 +0100
Implement the Star-Mesh library
It is actually a fork of the Star-Tetrahedra library that becomes
depracated.
Diffstat:
| A | cmake/CMakeLists.txt | | | 118 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/smsh.c | | | 289 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/smsh.h | | | 125 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/smsh_c.h | | | 45 | +++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/smsh_log.c | | | 124 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/smsh_log.h | | | 69 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 770 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -0,0 +1,118 @@
+# Copyright (C) 2020, 2021 |Meso|Star> (contact@meso-star.com)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+cmake_minimum_required(VERSION 3.1)
+project(smsh C)
+enable_testing()
+
+set(SMSH_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
+option(NO_TEST "Do not build tests" OFF)
+
+################################################################################
+# Check dependencies
+################################################################################
+find_package(RCMake 0.4 REQUIRED)
+find_package(RSys 0.10 REQUIRED)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${RCMAKE_SOURCE_DIR})
+include(rcmake)
+include(rcmake_runtime)
+
+include_directories(${RSys_INCLUDE_DIR})
+
+################################################################################
+# Configure and define targets
+################################################################################
+set(VERSION_MAJOR 0)
+set(VERSION_MINOR 0)
+set(VERSION_PATCH 1)
+set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
+
+set(SMSH_FILES_SRC
+ smsh.c
+ smsh_log.c)
+set(SMSH_FILES_INC
+ smsh_c.h
+ smsh_log.h)
+set(SMSH_FILES_INC_API
+ smsh.h)
+
+set(SMSH_FILES_DOC COPYING README.md)
+
+# Prepend each file in the `SMSH_FILES_<SRC|INC>' list by `SMSH_SOURCE_DIR'
+rcmake_prepend_path(SMSH_FILES_SRC ${SMSH_SOURCE_DIR})
+rcmake_prepend_path(SMSH_FILES_INC ${SMSH_SOURCE_DIR})
+rcmake_prepend_path(SMSH_FILES_INC_API ${SMSH_SOURCE_DIR})
+rcmake_prepend_path(SMSH_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
+
+add_library(smsh SHARED ${SMSH_FILES_SRC} ${SMSH_FILES_INC} ${SMSH_FILES_INC_API})
+target_link_libraries(smsh RSys)
+
+set_target_properties(smsh PROPERTIES
+ DEFINE_SYMBOL SMSH_SHARED_BUILD
+ VERSION ${VERSION}
+ SOVERSION ${VERSION_MAJOR})
+
+rcmake_setup_devel(smsh StarMesh ${VERSION} star/smsh_version.h)
+
+################################################################################
+# Add tests
+################################################################################
+if(NOT NO_TEST)
+ function(build_test _name)
+ add_executable(${_name} ${SMSH_SOURCE_DIR}/${_name}.c)
+ target_link_libraries(${_name} smsh RSys ${ARGN})
+ endfunction()
+
+ function(new_test _name)
+ build_test(${_name} ${ARGN})
+ add_test(${_name} ${_name})
+ endfunction()
+
+ #new_test(test_smsh)
+ #new_test(test_smsh_load)
+endif()
+
+################################################################################
+# Man page
+###############################################################################
+find_program(SCDOC NAMES scdoc)
+if(NOT SCDOC)
+ message(WARNING
+ "The `scdoc' program is missing. "
+ "The Star-Mesh man page cannot be generated.")
+else()
+ set(_src ${PROJECT_SOURCE_DIR}/../doc/smsh.5.scd)
+ add_custom_command(
+ OUTPUT smsh.5
+ COMMAND ${SCDOC} < ${_src} > smsh.5
+ DEPENDS ${_src}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Buid ROFF man page smsh.5"
+ VERBATIM)
+ add_custom_target(man-roff ALL DEPENDS smsh.5)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/smsh.5 DESTINATION share/man/man5)
+endif()
+
+################################################################################
+# Define output & install directories
+################################################################################
+install(TARGETS smsh
+ ARCHIVE DESTINATION bin
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin)
+install(FILES ${SMSH_FILES_INC_API} DESTINATION include/star)
+install(FILES ${SMSH_FILES_DOC} DESTINATION share/doc/star-mesh)
+
diff --git a/src/smsh.c b/src/smsh.c
@@ -0,0 +1,289 @@
+/* Copyright (C) 2020, 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#define _POSIX_C_SOURCE 200809L /* mmap support */
+#define _DEFAULT_SOURCE 1 /* MAP_POPULATE support */
+#define _BSD_SOURCE 1 /* MAP_POPULATE for glibc < 2.19 */
+
+#include "smsh.h"
+#include "smsh_c.h"
+#include "smsh_log.h"
+
+#include <rsys/mem_allocator.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/mman.h> /* mmap */
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static INLINE res_T
+check_smsh_create_args(const struct smsh_create_args* args)
+{
+ /* Nothing to check. Only return RES_BAD_ARG if args is NULL */
+ return args ? RES_OK : RES_BAD_ARG;
+}
+
+static void
+reset_smsh(struct smsh* smsh)
+{
+ ASSERT(smsh);
+ smsh->nnodes = 0;
+ smsh->ncells = 0;
+ smsh->pagesize = 0;
+ if(smsh->nodes) munmap(smsh->nodes, smsh->map_len_nodes);
+ if(smsh->cells) munmap(smsh->cells, smsh->map_len_cells);
+ smsh->nodes = NULL;
+ smsh->cells = NULL;
+ smsh->map_len_nodes = 0;
+ smsh->map_len_cells = 0;
+}
+
+static res_T
+map_data
+ (struct smsh* smsh,
+ const char* stream_name,
+ const int fd, /* File descriptor */
+ const size_t filesz, /* Overall filesize */
+ const char* data_name,
+ const off_t offset, /* Offset of the data into file */
+ const size_t map_len,
+ void** out_map) /* Lenght of the data to map */
+{
+ void* map = NULL;
+ res_T res = RES_OK;
+ ASSERT(smsh && stream_name && filesz && data_name && map_len && out_map);
+ ASSERT(IS_ALIGNED((size_t)offset, (size_t)smsh->pagesize));
+
+ if((size_t)offset + map_len > filesz) {
+ log_err(smsh, "%s: the %s to load exceed the file size.\n",
+ stream_name, data_name);
+ res = RES_IO_ERR;
+ goto error;
+ }
+
+ map = mmap(NULL, map_len, PROT_READ, MAP_PRIVATE|MAP_POPULATE, fd, offset);
+ if(map == MAP_FAILED) {
+ log_err(smsh, "%s: could not map the %s -- %s.\n",
+ stream_name, data_name, strerror(errno));
+ res = RES_IO_ERR;
+ goto error;
+ }
+
+exit:
+ *out_map = map;
+ return res;
+error:
+ if(map == MAP_FAILED) map = NULL;
+ goto exit;
+}
+
+static res_T
+load_stream(struct smsh* smsh, FILE* stream, const char* stream_name)
+{
+ off_t pos_offset;
+ off_t ids_offset;
+ size_t filesz;
+ res_T res = RES_OK;
+ ASSERT(smsh && stream && stream_name);
+
+ reset_smsh(smsh);
+
+ /* Read file header */
+ #define READ(Var, N, Name) { \
+ if(fread((Var), sizeof(*(Var)), (N), stream) != (N)) { \
+ log_err(smsh, "%s: could not read the %s.\n", stream_name, (Name)); \
+ res = RES_IO_ERR; \
+ goto error; \
+ } \
+ } (void)0
+ READ(&smsh->pagesize, 1, "page size");
+ READ(&smsh->nnodes, 1, "number of nodes");
+ READ(&smsh->ncells, 1, "number of cells");
+ READ(&smsh->dnode, 1, "node dimension");
+ READ(&smsh->dcell, 1, "cell dimension");
+ #undef READ
+
+ if(!IS_ALIGNED(smsh->pagesize, smsh->pagesize_os)) {
+ log_err(smsh,
+ "%s: invalid page size %li. The page size attribute must be aligned on "
+ "the page size of the operating system (%lu).\n",
+ stream_name, smsh->pagesize, (unsigned long)smsh->pagesize_os);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ /* Compute the length in bytes of the data to map */
+ smsh->map_len_nodes = smsh->nnodes * sizeof(double) * smsh->dnode;
+ smsh->map_len_cells = smsh->ncells * sizeof(uint64_t) * smsh->dcell;
+ smsh->map_len_nodes = ALIGN_SIZE(smsh->map_len_nodes, (size_t)smsh->pagesize);
+ smsh->map_len_cells = ALIGN_SIZE(smsh->map_len_cells, (size_t)smsh->pagesize);
+
+ /* Find the offsets of the positions/indices data into the stream */
+ pos_offset = (off_t)ALIGN_SIZE((uint64_t)ftell(stream), smsh->pagesize);
+ ids_offset = (off_t)((size_t)pos_offset + smsh->map_len_nodes);
+
+ /* Retrieve the overall filesize */
+ fseek(stream, 0, SEEK_END);
+ filesz = (size_t)ftell(stream);
+
+ /* Map the nodes */
+ res = map_data(smsh, stream_name, fileno(stream), filesz, "nodes",
+ pos_offset, smsh->map_len_nodes, (void**)&smsh->nodes);
+ if(res != RES_OK) goto error;
+
+ /* Map the cells */
+ res = map_data(smsh, stream_name, fileno(stream), filesz, "cells",
+ ids_offset, smsh->map_len_cells, (void**)&smsh->cells);
+ if(res != RES_OK) goto error;
+
+exit:
+ return res;
+error:
+ reset_smsh(smsh);
+ goto exit;
+}
+
+static void
+release_smsh(ref_T* ref)
+{
+ struct smsh* smsh;
+ ASSERT(ref);
+ smsh = CONTAINER_OF(ref, struct smsh, ref);
+ reset_smsh(smsh);
+ if(smsh->logger == &smsh->logger__) logger_release(&smsh->logger__);
+ MEM_RM(smsh->allocator, smsh);
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+smsh_create
+ (const struct smsh_create_args* args,
+ struct smsh** out_smsh)
+{
+ struct smsh* smsh = NULL;
+ struct mem_allocator* allocator = NULL;
+ res_T res = RES_OK;
+
+ if(!out_smsh) { res = RES_BAD_ARG; goto error; }
+ res = check_smsh_create_args(args);
+ if(res != RES_OK) goto error;
+
+ allocator = args->allocator ? args->allocator : &mem_default_allocator;
+ smsh = MEM_CALLOC(allocator, 1, sizeof(*smsh));
+ if(!smsh) {
+ if(args->verbose) {
+ #define ERR_STR "Could not allocate the Star-Mesh device.\n"
+ if(args->logger) {
+ logger_print(args->logger, LOG_ERROR, ERR_STR);
+ } else {
+ fprintf(stderr, MSG_ERROR_PREFIX ERR_STR);
+ }
+ #undef ERR_STR
+ }
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&smsh->ref);
+ smsh->allocator = allocator;
+ smsh->verbose = args->verbose;
+ smsh->pagesize_os = (size_t)sysconf(_SC_PAGESIZE);
+ if(args->logger) {
+ smsh->logger = args->logger;
+ } else {
+ setup_log_default(smsh);
+ }
+
+exit:
+ if(out_smsh) *out_smsh = smsh;
+ return res;
+error:
+ if(smsh) {
+ SMSH(ref_put(smsh));
+ smsh = NULL;
+ }
+ goto exit;
+}
+
+res_T
+smsh_ref_get(struct smsh* smsh)
+{
+ if(!smsh) return RES_BAD_ARG;
+ ref_get(&smsh->ref);
+ return RES_OK;
+}
+
+res_T
+smsh_ref_put(struct smsh* smsh)
+{
+ if(!smsh) return RES_BAD_ARG;
+ ref_put(&smsh->ref, release_smsh);
+ return RES_OK;
+}
+
+
+res_T
+smsh_load(struct smsh* smsh, const char* path)
+{
+ FILE* file = NULL;
+ res_T res = RES_OK;
+
+ if(!smsh || !path) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ file = fopen(path, "r");
+ if(!file) {
+ log_err(smsh, "%s: error opening file `%s'.\n", FUNC_NAME, path);
+ res = RES_IO_ERR;
+ goto error;
+ }
+
+ res = load_stream(smsh, file, path);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(file) fclose(file);
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+smsh_load_stream
+ (struct smsh* smsh,
+ FILE* stream,
+ const char* stream_name)
+{
+ if(!smsh || !stream) return RES_BAD_ARG;
+ return load_stream(smsh, stream, stream_name ? stream_name : "<stream>");
+}
+
+res_T
+smsh_get_desc(const struct smsh* smsh, struct smsh_desc* desc)
+{
+ if(!smsh || !desc) return RES_BAD_ARG;
+ desc->nodes = smsh->nodes;
+ desc->cells = smsh->cells;
+ desc->nnodes = smsh->nnodes;
+ desc->ncells = smsh->ncells;
+ desc->dnode = smsh->dnode;
+ desc->dcell = smsh->dcell;
+ return RES_OK;
+}
diff --git a/src/smsh.h b/src/smsh.h
@@ -0,0 +1,125 @@
+/* Copyright (C) 2020, 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redismshbute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is dismshbuted in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SMSH_H
+#define SMSH_H
+
+#include <rsys/rsys.h>
+
+/* Library symbol management */
+#if defined(SMSH_SHARED_BUILD) /* Build shared library */
+ #define SMSH_API extern EXPORT_SYM
+#elif defined(SMSH_STATIC) /* Use/build static library */
+ #define SMSH_API extern LOCAL_SYM
+#else /* Use shared library */
+ #define SMSH_API extern IMPORT_SYM
+#endif
+
+/* Helper macro that asserts if the invocation of the smsh function `Func'
+ * returns an error. One should use this macro on smsh function calls for
+ * which no explicit error checking is performed */
+#ifndef NDEBUG
+ #define SMSH(Func) ASSERT(smsh_ ## Func == RES_OK)
+#else
+ #define SMSH(Func) smsh_ ## Func
+#endif
+
+/* Forward declaration of external data types */
+struct logger;
+struct mem_allocator;
+
+struct smsh_create_args {
+ struct logger* logger; /* May be NULL <=> default logger */
+ struct mem_allocator* allocator; /* NULL <=> use default allocator */
+ int verbose; /* Verbosity level */
+};
+#define SMSH_CREATE_ARGS_DEFAULT__ {NULL, NULL, 0}
+static const struct smsh_create_args SMSH_CREATE_ARGS_DEFAULT =
+ SMSH_CREATE_ARGS_DEFAULT__;
+
+struct smsh_desc {
+ const double* nodes; /* List of double[3] */
+ const uint64_t* cells; /* List of uint64_t[4] */
+ size_t nnodes;
+ size_t ncells;
+ unsigned dnode; /* Dimension of a node */
+ unsigned dcell; /* Dimension of a cell */
+};
+#define SMSH_DESC_NULL__ {NULL, NULL, 0, 0, 0, 0}
+static const struct smsh_desc SMSH_DESC_NULL = SMSH_DESC_NULL__;
+
+/* Forward declaration of opaque data types */
+struct smsh;
+
+BEGIN_DECLS
+
+/*******************************************************************************
+ * STri API
+ ******************************************************************************/
+SMSH_API res_T
+smsh_create
+ (const struct smsh_create_args* args,
+ struct smsh** smsh);
+
+SMSH_API res_T
+smsh_ref_get
+ (struct smsh* smsh);
+
+SMSH_API res_T
+smsh_ref_put
+ (struct smsh* smsh);
+
+SMSH_API res_T
+smsh_load
+ (struct smsh* smsh,
+ const char* path);
+
+SMSH_API res_T
+smsh_load_stream
+ (struct smsh* smsh,
+ FILE* stream,
+ const char* stream_name); /* NULL <=> use default stream name */
+
+SMSH_API res_T
+smsh_get_desc
+ (const struct smsh* smsh,
+ struct smsh_desc* desc);
+
+static INLINE const double*
+smsh_desc_get_node
+ (const struct smsh_desc* desc,
+ const size_t inode)
+{
+ ASSERT(desc && inode < desc->nnodes);
+ return desc->nodes + inode*desc->dnode;
+}
+
+static INLINE const uint64_t*
+smsh_desc_get_cell
+ (const struct smsh_desc* desc,
+ const size_t icell)
+{
+ const uint64_t* cell;
+ ASSERT(desc && icell < desc->ncells);
+ cell = desc->cells + icell*desc->dcell;
+#ifndef NDEBUG
+ {unsigned i; FOR_EACH(i, 0, desc->dcell) ASSERT(cell[i] < desc->nnodes);}
+#endif
+ return cell;
+}
+
+END_DECLS
+
+#endif /* SMSH_H */
diff --git a/src/smsh_c.h b/src/smsh_c.h
@@ -0,0 +1,45 @@
+/* Copyright (C) 2020, 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SMSH_C_H
+#define SMSH_C_H
+
+#include <rsys/logger.h>
+#include <rsys/ref_count.h>
+
+struct mem_allocator;
+
+struct smsh {
+ uint64_t pagesize;
+ uint64_t nnodes;
+ uint64_t ncells;
+ unsigned dnode;
+ unsigned dcell;
+
+ double* nodes;
+ uint64_t* cells;
+ size_t map_len_nodes;
+ size_t map_len_cells;
+
+ size_t pagesize_os;
+
+ struct mem_allocator* allocator;
+ struct logger* logger;
+ struct logger logger__; /* Default logger */
+ int verbose;
+ ref_T ref;
+};
+
+#endif /* SMSH_C_H */
diff --git a/src/smsh_log.c b/src/smsh_log.c
@@ -0,0 +1,124 @@
+/* Copyright (C) 2020, 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "smsh_c.h"
+#include "smsh_log.h"
+
+#include <rsys/cstr.h>
+#include <rsys/logger.h>
+
+#include <stdarg.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static INLINE void
+log_msg
+ (const struct smsh* smsh,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
+{
+ ASSERT(smsh && msg);
+ if(smsh->verbose) {
+ res_T res; (void)res;
+ res = logger_vprint(smsh->logger, stream, msg, vargs);
+ ASSERT(res == RES_OK);
+ }
+}
+
+static void
+print_info(const char* msg, void* ctx)
+{
+ (void)ctx;
+ fprintf(stderr, MSG_INFO_PREFIX"%s", msg);
+}
+
+static void
+print_err(const char* msg, void* ctx)
+{
+ (void)ctx;
+ fprintf(stderr, MSG_ERROR_PREFIX"%s", msg);
+}
+
+static void
+print_warn(const char* msg, void* ctx)
+{
+ (void)ctx;
+ fprintf(stderr, MSG_WARNING_PREFIX"%s", msg);
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+setup_log_default(struct smsh* smsh)
+{
+ res_T res = RES_OK;
+ ASSERT(smsh);
+
+ res = logger_init(smsh->allocator, &smsh->logger__);
+ if(res != RES_OK) {
+ if(smsh->verbose) {
+ fprintf(stderr,
+ MSG_ERROR_PREFIX
+ "Could not setup the Star-Mesh default logger -- %s.\n",
+ res_to_cstr(res));
+ }
+ goto error;
+ }
+ logger_set_stream(&smsh->logger__, LOG_OUTPUT, print_info, NULL);
+ logger_set_stream(&smsh->logger__, LOG_ERROR, print_err, NULL);
+ logger_set_stream(&smsh->logger__, LOG_WARNING, print_warn, NULL);
+ smsh->logger = &smsh->logger__;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+void
+log_info(const struct smsh* smsh, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(smsh && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(smsh, LOG_OUTPUT, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_err(const struct smsh* smsh, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(smsh && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(smsh, LOG_ERROR, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_warn(const struct smsh* smsh, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(smsh && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(smsh, LOG_WARNING, msg, vargs_list);
+ va_end(vargs_list);
+}
diff --git a/src/smsh_log.h b/src/smsh_log.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 2020, 2021 |Meso|Star> (contact@meso-star.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SMSH_LOG_H
+#define SMSH_LOG_H
+
+#include <rsys/rsys.h>
+
+#define MSG_INFO_PREFIX "Star-Mesh:\x1b[1m\x1b[32minfo\x1b[0m: "
+#define MSG_ERROR_PREFIX "Star-Mesh:\x1b[1m\x1b[31merror\x1b[0m: "
+#define MSG_WARNING_PREFIX "Star-Mesh:\x1b[1m\x1b[33mwarning\x1b[0m: "
+
+struct smsh;
+struct logger;
+
+extern LOCAL_SYM res_T
+setup_log_default
+ (struct smsh* smsh);
+
+/* Conditionally log a message on the LOG_OUTPUT stream of the smsh logger,
+ * with respect to its verbose flag */
+extern LOCAL_SYM void
+log_info
+ (const struct smsh* smsh,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+/* Conditionally log a message on the LOG_ERROR stream of the smsh logger,
+ * with respect to its verbose flag */
+extern LOCAL_SYM void
+log_err
+ (const struct smsh* smsh,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+/* Conditionally log a message on the LOG_WARNING stream of the smsh logger,
+ * with respect to its verbose flag */
+extern LOCAL_SYM void
+log_warn
+ (const struct smsh* smsh,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+#endif /* SMSH_LOG_H */
+