commit b08677ff273884b5c1feeceb0c9c1d1c00d72d13
parent 980632e7d47e5e8b4c213de9303c22357e8b28ce
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 28 Feb 2020 09:10:28 +0100
Write the create/ref_<get|put> funcs and add a CMakeLists.txt file
Diffstat:
| A | cmake/CMakeLists.txt | | | 96 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/mrumtl.c | | | 176 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 272 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -0,0 +1,96 @@
+# Copyright (C) 2020 |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 2.8)
+project(mrumtl C)
+enable_testing()
+
+set(MRUMTL_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.9 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(MRUMTL_FILES_SRC mrumtl.c)
+set(MRUMTL_FILES_INC )
+set(MRUMTL_FILES_INC_API mrumtl.h)
+set(MRUMTL_FILES_DOC COPYING README.md)
+
+# Prepend each file in the `MRUMTL_FILES_<SRC|INC>' list by `MRUMTL_SOURCE_DIR'
+rcmake_prepend_path(MRUMTL_FILES_SRC ${MRUMTL_SOURCE_DIR})
+rcmake_prepend_path(MRUMTL_FILES_INC ${MRUMTL_SOURCE_DIR})
+rcmake_prepend_path(MRUMTL_FILES_INC_API ${MRUMTL_SOURCE_DIR})
+rcmake_prepend_path(MRUMTL_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
+
+add_library(mrumtl SHARED ${MRUMTL_FILES_SRC} ${MRUMTL_FILES_INC} ${MRUMTL_FILES_INC_API})
+target_link_libraries(mrumtl RSys)
+
+#if(CMAKE_COMPILER_IS_GNUCC)
+# target_link_libraries(htgop m)
+#endif()
+
+set_target_properties(mrumtl PROPERTIES
+ DEFINE_SYMBOL MRUMTL_SHARED_BUILD
+ VERSION ${VERSION}
+ SOVERSION ${VERSION_MAJOR})
+
+rcmake_setup_devel(mrumtl MRUMTL ${VERSION} modradurb/mrumtl_version.h)
+
+################################################################################
+# Add tests
+################################################################################
+if(NOT NO_TEST)
+ function(build_test _name)
+ add_executable(${_name}
+ ${MRUMTL_SOURCE_DIR}/${_name}.c)
+ target_link_libraries(${_name} mrumtl RSys)
+ endfunction()
+
+ function(new_test _name)
+ build_test(${_name})
+ add_test(${_name} ${_name})
+ endfunction()
+
+ # TODO add tests
+
+endif()
+
+################################################################################
+# Define output & install directories
+################################################################################
+install(TARGETS mrumtl
+ ARCHIVE DESTINATION bin
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin)
+install(FILES ${MRUMTL_FILES_INC_API} DESTINATION include/modradurb)
+install(FILES ${MRUMTL_FILES_DOC} DESTINATION share/doc/mrumtl)
+
diff --git a/src/mrumtl.c b/src/mrumtl.c
@@ -0,0 +1,176 @@
+/* Copyright (C) 2020 |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 "mrumtl.h"
+
+#include <rsys/logger.h>
+#include <rsys/mem_allocator.h>
+#include <rsys/ref_count.h>
+
+struct mrumtl {
+ int verbose;
+ struct logger* logger;
+ struct logger logger__;
+ struct mem_allocator* allocator;
+ ref_T ref;
+};
+
+#define MSG_INFO_PREFIX "MRUMTL:\x1b[1m\x1b[32minfo\x1b[0m: "
+#define MSG_ERROR_PREFIX "MRUMTL:\x1b[1m\x1b[31merror\x1b[0m: "
+#define MSG_WARNING_PREFIX "MRUMTL:\x1b[1m\x1b[33mwarning\x1b[0m: "
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+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);
+}
+
+static res_T
+setup_default_logger(struct mem_allocator* allocator, struct logger* logger)
+{
+ res_T res = RES_OK;
+ ASSERT(logger);
+ res = logger_init(allocator, logger);
+ if(res != RES_OK) return res;
+ logger_set_stream(logger, LOG_OUTPUT, print_info, NULL);
+ logger_set_stream(logger, LOG_ERROR, print_err, NULL);
+ logger_set_stream(logger, LOG_WARNING, print_warn, NULL);
+ return RES_OK;
+}
+
+static INLINE void
+log_msg
+ (const struct mrumtl* mrumtl,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
+{
+ ASSERT(mrumtl && msg);
+ if(mrumtl->verbose) {
+ res_T res; (void)res;
+ res = logger_vprint(mrumtl->logger, stream, msg, vargs);
+ ASSERT(res == RES_OK);
+ }
+}
+
+static void
+release_mrumtl(ref_T* ref)
+{
+ struct mrumtl* mrumtl;
+ ASSERT(ref);
+ mrumtl = CONTAINER_OF(ref, struct mrumtl, ref);
+
+ /* First release the programs that uses the libs array */
+ if(mrumtl->logger == &mrumtl->logger__) logger_release(&mrumtl->logger__);
+ MEM_RM(mrumtl->allocator, mrumtl);
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+mrumtl_create
+ (struct logger* logger, /* NULL <=> use default logger */
+ struct mem_allocator* mem_allocator,
+ const int verbose, /* Verbosity level */
+ struct mrumtl** out_mrumtl)
+{
+ struct mrumtl* mrumtl = NULL;
+ struct mem_allocator* allocator = NULL;
+ res_T res = RES_OK;
+
+ if(!out_mrumtl) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ allocator = mem_allocator ? mem_allocator : &mem_default_allocator;
+ mrumtl = MEM_CALLOC(allocator, 1, sizeof(*mrumtl));
+ if(!mrumtl) {
+ if(verbose) {
+ #define ERR_STR "Could not allocate the MRUMTL handler.\n"
+ if(logger) {
+ logger_print(logger, LOG_ERROR, ERR_STR);
+ } else {
+ fprintf(stderr, MSG_ERROR_PREFIX ERR_STR);
+ }
+ #undef ERR_STR
+ }
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&mrumtl->ref);
+ mrumtl->allocator = allocator;
+ mrumtl->verbose = verbose;
+
+ if(logger) {
+ mrumtl->logger = logger;
+ } else {
+ res = setup_default_logger(mrumtl->allocator, &mrumtl->logger__);
+ if(res != RES_OK) {
+ if(verbose) {
+ fprintf(stderr, MSG_ERROR_PREFIX
+ "Could not setup the MRUMTL logger.\n");
+ }
+ goto error;
+ }
+ mrumtl->logger = &mrumtl->logger__;
+ }
+
+exit:
+ if(out_mrumtl) *out_mrumtl = mrumtl;
+ return res;
+error:
+ if(mrumtl) {
+ MRUMTL(ref_put(mrumtl));
+ mrumtl = NULL;
+ }
+ goto exit;
+}
+
+res_T
+mrumtl_ref_get(struct mrumtl* mrumtl)
+{
+ if(!mrumtl) return RES_BAD_ARG;
+ ref_get(&mrumtl->ref);
+ return RES_OK;
+}
+
+res_T
+mrumtl_ref_put(struct mrumtl* mrumtl)
+{
+ if(!mrumtl) return RES_BAD_ARG;
+ ref_put(&mrumtl->ref, release_mrumtl);
+ return RES_OK;
+}
+