rnsl

Load a list of strings expanded by the shell
git clone git://git.meso-star.fr/rnsl.git
Log | Files | Refs | README | LICENSE

commit 16b610f08c6f8d74d044eaad6340cd08d79293f2
parent ed0a7d248ea758e70561ff9171fbe595d45e4100
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri,  9 Sep 2022 12:40:15 +0200

Implement de device API

Diffstat:
Acmake/CMakeLists.txt | 122+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/rnfl.c | 110+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/rnfl.h | 91+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/rnfl_c.h | 35+++++++++++++++++++++++++++++++++++
Asrc/rnfl_log.c | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/rnfl_log.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/test_rnfl.c | 76++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 636 insertions(+), 0 deletions(-)

diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt @@ -0,0 +1,122 @@ +# Copyright (C) 2022 Centre National de la Recherche Scientifique +# Copyright (C) 2022 Institut de Physique du Globe de Paris +# Copyright (C) 2022 |Méso|Star> (contact@meso-star.com) +# Copyright (C) 2022 Université de Reims Champagne-Ardenne +# Copyright (C) 2022 Université de Versaille Saint-Quentin +# Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr) +# +# 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(rnfl C) +enable_testing() + +set(RNFL_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.13 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 0) +set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) + +set(RNFL_FILES_SRC + rnfl.c + rnfl_log.c) +set(RNFL_FILES_INC + rnfl_c.h + rnfl_log.h) +set(RNFL_FILES_INC_API + rnfl.h) + +set(RNFL_FILES_DOC COPYING README.md) + +# Prepend each file in the `RNFL_FILES_<SRC|INC>' list by `RNFL_SOURCE_DIR' +rcmake_prepend_path(RNFL_FILES_SRC ${RNFL_SOURCE_DIR}) +rcmake_prepend_path(RNFL_FILES_INC ${RNFL_SOURCE_DIR}) +rcmake_prepend_path(RNFL_FILES_INC_API ${RNFL_SOURCE_DIR}) +rcmake_prepend_path(RNFL_FILES_DOC ${PROJECT_SOURCE_DIR}/../) + +add_library(rnfl SHARED ${RNFL_FILES_SRC} ${RNFL_FILES_INC} ${RNFL_FILES_INC_API}) +target_link_libraries(rnfl RSys) + +if(CMAKE_COMPILER_IS_GNUCC) + target_link_libraries(rnfl m) +endif() + +set_target_properties(rnfl PROPERTIES + DEFINE_SYMBOL RNFL_SHARED_BUILD + VERSION ${VERSION} + SOVERSION ${VERSION_MAJOR}) + +rcmake_setup_devel(rnfl StarCK ${VERSION} rad-net/rnfl_version.h) + +################################################################################ +# Add tests +################################################################################ +if(NOT NO_TEST) + function(new_test _name) + add_executable(${_name} ${RNFL_SOURCE_DIR}/${_name}.c) + target_link_libraries(${_name} rnfl RSys ${ARGN}) + add_test(${_name} ${_name}) + endfunction() + + new_test(test_rnfl) + # new_test(test_rnfl_load) +endif() + +################################################################################ +# Man page +############################################################################### +#find_program(SCDOC NAMES scdoc) +#if(NOT SCDOC) +# message(WARNING +# "The `scdoc' program is missing. " +# "The Star-CK man page cannot be generated.") +#else() +# set(_src ${PROJECT_SOURCE_DIR}/../doc/rnfl.5.scd) +# add_custom_command( +# OUTPUT rnfl.5 +# COMMAND ${SCDOC} < ${_src} > rnfl.5 +# DEPENDS ${_src} +# WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} +# COMMENT "Buid ROFF man page rnfl.5" +# VERBATIM) +# add_custom_target(man-roff ALL DEPENDS rnfl.5) +# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/rnfl.5 DESTINATION share/man/man5) +#endif() + +################################################################################ +# Define output & install directories +################################################################################ +install(TARGETS rnfl + ARCHIVE DESTINATION bin + LIBRARY DESTINATION lib + RUNTIME DESTINATION bin) +install(FILES ${RNFL_FILES_INC_API} DESTINATION include/rad-net) +install(FILES ${RNFL_FILES_DOC} DESTINATION share/doc/rnfl) diff --git a/src/rnfl.c b/src/rnfl.c @@ -0,0 +1,110 @@ +/* Copyright (C) 2022 Centre National de la Recherche Scientifique + * Copyright (C) 2022 Institut de Physique du Globe de Paris + * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022 Université de Reims Champagne-Ardenne + * Copyright (C) 2022 Université de Versaille Saint-Quentin + * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr) + * + * 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 "rnfl.h" +#include "rnfl_c.h" +#include "rnfl_log.h" + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE res_T +check_rnfl_create_args(const struct rnfl_create_args* args) +{ + /* Nothing to check. Only return RES_BAD_ARG if args is NULL */ + return args ? RES_OK : RES_BAD_ARG; +} + +static void +release_rnfl(ref_T* ref) +{ + struct rnfl* rnfl; + ASSERT(ref); + rnfl = CONTAINER_OF(ref, struct rnfl, ref); + if(rnfl->logger == &rnfl->logger__) logger_release(&rnfl->logger__); + MEM_RM(rnfl->allocator, rnfl); +} + +/******************************************************************************* + * Exported functions + ******************************************************************************/ +res_T +rnfl_create + (const struct rnfl_create_args* args, + struct rnfl** out_rnfl) +{ + struct rnfl* rnfl = NULL; + struct mem_allocator* allocator = NULL; + res_T res = RES_OK; + + if(!out_rnfl) { res = RES_BAD_ARG; goto error; } + res = check_rnfl_create_args(args); + if(res != RES_OK) goto error; + + allocator = args->allocator ? args->allocator : &mem_default_allocator; + rnfl = MEM_CALLOC(allocator, 1, sizeof(*rnfl)); + if(!rnfl) { + if(args->verbose) { + #define ERR_STR "Could not allocate the Rad-Net File List 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(&rnfl->ref); + rnfl->allocator = allocator; + rnfl->verbose = args->verbose; + if(args->logger) { + rnfl->logger = args->logger; + } else { + setup_log_default(rnfl); + } + +exit: + if(out_rnfl) *out_rnfl = rnfl; + return res; +error: + if(rnfl) { + RNFL(ref_put(rnfl)); + rnfl = NULL; + } + goto exit; +} + +res_T +rnfl_ref_get(struct rnfl* rnfl) +{ + if(!rnfl) return RES_BAD_ARG; + ref_get(&rnfl->ref); + return RES_OK; +} + +res_T +rnfl_ref_put(struct rnfl* rnfl) +{ + if(!rnfl) return RES_BAD_ARG; + ref_put(&rnfl->ref, release_rnfl); + return RES_OK; +} diff --git a/src/rnfl.h b/src/rnfl.h @@ -0,0 +1,91 @@ +/* Copyright (C) 2022 Centre National de la Recherche Scientifique + * Copyright (C) 2022 Institut de Physique du Globe de Paris + * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022 Université de Reims Champagne-Ardenne + * Copyright (C) 2022 Université de Versaille Saint-Quentin + * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr) + * + * 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 RNFL_H +#define RNFL_H + +#include <rsys/rsys.h> + +/* Library symbol management */ +#if defined(RNFL_SHARED_BUILD) /* Build shared library */ + #define RNFL_API extern EXPORT_SYM +#elif defined(RNFL_STATIC) /* Use/build static library */ + #define RNFL_API extern LOCAL_SYM +#else /* Use shared library */ + #define RNFL_API extern IMPORT_SYM +#endif + +/* Helper macro that asserts if the invocation of the rnfl function `Func' + * returns an error. One should use this macro on suvm function calls for + * which no explicit error checking is performed */ +#ifndef NDEBUG + #define RNFL(Func) ASSERT(rnfl_ ## Func == RES_OK) +#else + #define RNFL(Func) rnfl_ ## Func +#endif + +struct rnfl_create_args { + struct logger* logger; /* May be NULL <=> default logger */ + struct mem_allocator* allocator; /* NULL <=> use default allocator */ + int verbose; /* Verbosity level */ +}; +#define RNFL_CREATE_ARGS_DEFAULT__ {NULL, NULL, 0} +static const struct rnfl_create_args RNFL_CREATE_ARGS_DEFAULT = + RNFL_CREATE_ARGS_DEFAULT__; + +/* Forward declaration of external data types */ +struct logger; +struct mem_allocator; + +/* Forward declaration of opaque data types */ +struct rnfl; + +BEGIN_DECLS + +/******************************************************************************* + * API of the Rad-Net file list + ******************************************************************************/ +RNFL_API res_T +rnfl_create + (const struct rnfl_create_args* args, + struct rnfl** rnfl); + +RNFL_API res_T +rnfl_ref_get + (struct rnfl* rnfl); + +RNFL_API res_T +rnfl_ref_put + (struct rnfl* rnfl); + +RNFL_API res_T +rnfl_load + (struct rnfl* rnfl, + const char* filename); + +RNFL_API res_T +rnfl_load_stream + (struct rnfl* rnfl, + FILE* stream, + const char* stream_name); + +END_DECLS + +#endif /* RNFL_H */ diff --git a/src/rnfl_c.h b/src/rnfl_c.h @@ -0,0 +1,35 @@ +/* Copyright (C) 2022 Centre National de la Recherche Scientifique + * Copyright (C) 2022 Institut de Physique du Globe de Paris + * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022 Université de Reims Champagne-Ardenne + * Copyright (C) 2022 Université de Versaille Saint-Quentin + * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr) + * + * 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 RNFL_C_H +#define RNFL_C_H + +#include <rsys/logger.h> +#include <rsys/ref_count.h> + +struct rnfl { + struct mem_allocator* allocator; + struct logger* logger; + struct logger logger__; + int verbose; /* Verbosity level */ + ref_T ref; +}; + +#endif /* RNFL_C_H */ diff --git a/src/rnfl_log.c b/src/rnfl_log.c @@ -0,0 +1,129 @@ +/* Copyright (C) 2022 Centre National de la Recherche Scientifique + * Copyright (C) 2022 Institut de Physique du Globe de Paris + * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022 Université de Reims Champagne-Ardenne + * Copyright (C) 2022 Université de Versaille Saint-Quentin + * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr) + * + * 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 "rnfl_c.h" +#include "rnfl_log.h" + +#include <rsys/cstr.h> +#include <rsys/logger.h> + +#include <stdarg.h> + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE void +log_msg + (const struct rnfl* fl, + const enum log_type stream, + const char* msg, + va_list vargs) +{ + ASSERT(fl && msg); + if(fl->verbose) { + res_T res; (void)res; + res = logger_vprint(fl->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 rnfl* fl) +{ + res_T res = RES_OK; + ASSERT(fl); + + res = logger_init(fl->allocator, &fl->logger__); + if(res != RES_OK) { + if(fl->verbose) { + fprintf(stderr, + MSG_ERROR_PREFIX + "Could not setup the default logger -- %s.\n", + res_to_cstr(res)); + } + goto error; + } + logger_set_stream(&fl->logger__, LOG_OUTPUT, print_info, NULL); + logger_set_stream(&fl->logger__, LOG_ERROR, print_err, NULL); + logger_set_stream(&fl->logger__, LOG_WARNING, print_warn, NULL); + fl->logger = &fl->logger__; + +exit: + return res; +error: + goto exit; +} + +void +log_info(const struct rnfl* fl, const char* msg, ...) +{ + va_list vargs_list; + ASSERT(fl && msg); + + va_start(vargs_list, msg); + log_msg(fl, LOG_OUTPUT, msg, vargs_list); + va_end(vargs_list); +} + +void +log_err(const struct rnfl* fl, const char* msg, ...) +{ + va_list vargs_list; + ASSERT(fl && msg); + + va_start(vargs_list, msg); + log_msg(fl, LOG_ERROR, msg, vargs_list); + va_end(vargs_list); +} + +void +log_warn(const struct rnfl* fl, const char* msg, ...) +{ + va_list vargs_list; + ASSERT(fl && msg); + + va_start(vargs_list, msg); + log_msg(fl, LOG_WARNING, msg, vargs_list); + va_end(vargs_list); +} diff --git a/src/rnfl_log.h b/src/rnfl_log.h @@ -0,0 +1,73 @@ +/* Copyright (C) 2022 Centre National de la Recherche Scientifique + * Copyright (C) 2022 Institut de Physique du Globe de Paris + * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022 Université de Reims Champagne-Ardenne + * Copyright (C) 2022 Université de Versaille Saint-Quentin + * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr) + * + * 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 RNFL_LOG_H +#define RNFL_LOG_H + +#include <rsys/rsys.h> + +#define MSG_INFO_PREFIX "RNFL:\x1b[1m\x1b[32minfo\x1b[0m: " +#define MSG_ERROR_PREFIX "RNFL:\x1b[1m\x1b[31merror\x1b[0m: " +#define MSG_WARNING_PREFIX "RNFL:\x1b[1m\x1b[33mwarning\x1b[0m: " + +struct rnfl; +struct logger; + +extern LOCAL_SYM res_T +setup_log_default + (struct rnfl* rnfl); + +/* Conditionally log a message on the LOG_OUTPUT stream of the rnfl logger, + * with respect to its verbose flag */ +extern LOCAL_SYM void +log_info + (const struct rnfl* rnfl, + const char* msg, + ...) +#ifdef COMPILER_GCC + __attribute((format(printf, 2, 3))) +#endif +; + +/* Conditionally log a message on the LOG_ERROR stream of the rnfl logger, + * with respect to its verbose flag */ +extern LOCAL_SYM void +log_err + (const struct rnfl* rnfl, + const char* msg, + ...) +#ifdef COMPILER_GCC + __attribute((format(printf, 2, 3))) +#endif +; + +/* Conditionally log a message on the LOG_WARNING stream of the rnfl logger, + * with respect to its verbose flag */ +extern LOCAL_SYM void +log_warn + (const struct rnfl* rnfl, + const char* msg, + ...) +#ifdef COMPILER_GCC + __attribute((format(printf, 2, 3))) +#endif +; + +#endif /* RNFL_LOG_H */ diff --git a/src/test_rnfl.c b/src/test_rnfl.c @@ -0,0 +1,76 @@ +/* Copyright (C) 2022 Centre National de la Recherche Scientifique + * Copyright (C) 2022 Institut de Physique du Globe de Paris + * Copyright (C) 2022 |Méso|Star> (contact@meso-star.com) + * Copyright (C) 2022 Université de Reims Champagne-Ardenne + * Copyright (C) 2022 Université de Versaille Saint-Quentin + * Copyright (C) 2022 Université Paul Sabatier (contact@laplace.univ-tlse.fr) + * + * 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 "rnfl.h" + +#include <rsys/logger.h> + +static void +log_stream(const char* msg, void* ctx) +{ + ASSERT(msg); + (void)msg, (void)ctx; + printf("%s\n", msg); +} + +int +main(int argc, char** argv) +{ + struct mem_allocator allocator; + struct logger logger; + struct rnfl_create_args args = RNFL_CREATE_ARGS_DEFAULT; + struct rnfl* rnfl; + (void)argc, (void)argv; + + CHK(rnfl_create(NULL, &rnfl) == RES_BAD_ARG); + CHK(rnfl_create(&args, NULL) == RES_BAD_ARG); + CHK(rnfl_create(&args, &rnfl) == RES_OK); + + CHK(rnfl_ref_get(NULL) == RES_BAD_ARG); + CHK(rnfl_ref_get(rnfl) == RES_OK); + CHK(rnfl_ref_put(NULL) == RES_BAD_ARG); + CHK(rnfl_ref_put(rnfl) == RES_OK); + CHK(rnfl_ref_put(rnfl) == RES_OK); + + CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK); + args.allocator = &allocator; + args.verbose = 1; + CHK(rnfl_create(&args, &rnfl) == RES_OK); + CHK(rnfl_ref_put(rnfl) == RES_OK); + + CHK(logger_init(&allocator, &logger) == RES_OK); + logger_set_stream(&logger, LOG_OUTPUT, log_stream, NULL); + logger_set_stream(&logger, LOG_ERROR, log_stream, NULL); + logger_set_stream(&logger, LOG_WARNING, log_stream, NULL); + + args.logger = &logger; + args.verbose = 0; + CHK(rnfl_create(&args, &rnfl) == RES_OK); + CHK(rnfl_ref_put(rnfl) == RES_OK); + args.allocator = NULL; + CHK(rnfl_create(&args, &rnfl) == RES_OK); + CHK(rnfl_ref_put(rnfl) == RES_OK); + + logger_release(&logger); + mem_shutdown_proxy_allocator(&allocator); + CHK(mem_allocated_size() == 0); + return 0; +} +