commit 777e9a7f0a2e7957e827256a005c0a3a81124a8f
parent bb650a63604a61ec01c02dcc123f9492a56b6fda
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 7 Feb 2022 09:55:37 +0100
Change shitran prefix to sht
Diffstat:
| M | cmake/CMakeLists.txt | | | 64 | ++++++++++++++++++++++++++++++++-------------------------------- |
| D | src/shitran.c | | | 101 | ------------------------------------------------------------------------------- |
| D | src/shitran.h | | | 99 | ------------------------------------------------------------------------------- |
| D | src/shitran_c.h | | | 35 | ----------------------------------- |
| D | src/shitran_isotopologues.c | | | 426 | ------------------------------------------------------------------------------- |
| D | src/shitran_log.c | | | 127 | ------------------------------------------------------------------------------- |
| D | src/shitran_log.h | | | 73 | ------------------------------------------------------------------------- |
| A | src/sht.c | | | 101 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sht.h | | | 99 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sht_c.h | | | 35 | +++++++++++++++++++++++++++++++++++ |
| A | src/sht_isotopologues.c | | | 426 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sht_log.c | | | 127 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/sht_log.h | | | 73 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| D | src/test_shitran.c | | | 74 | -------------------------------------------------------------------------- |
| A | src/test_sht.c | | | 74 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
15 files changed, 967 insertions(+), 967 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -17,10 +17,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
cmake_minimum_required(VERSION 3.1)
-project(shitran C)
+project(sht C)
enable_testing()
-set(SHITRAN_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
+set(SHT_SOURCE_DIR ${PROJECT_SOURCE_DIR}/../src)
option(NO_TEST "Do not build tests" OFF)
################################################################################
@@ -43,41 +43,41 @@ set(VERSION_MINOR 0)
set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
-set(SHITRAN_FILES_SRC
- shitran.c
- shitran_log.c
- shitran_isotopologues.c)
-set(SHITRAN_FILES_INC
- shitran_c.h
- shitran_log.h)
-set(SHITRAN_FILES_INC_API
- shitran.h)
-
-set(SHITRAN_FILES_DOC COPYING README.md)
-
-# Prepend each file in the `SHITRAN_FILES_<SRC|INC>' list by `SHITRAN_SOURCE_DIR'
-rcmake_prepend_path(SHITRAN_FILES_SRC ${SHITRAN_SOURCE_DIR})
-rcmake_prepend_path(SHITRAN_FILES_INC ${SHITRAN_SOURCE_DIR})
-rcmake_prepend_path(SHITRAN_FILES_INC_API ${SHITRAN_SOURCE_DIR})
-rcmake_prepend_path(SHITRAN_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
-
-add_library(shitran SHARED ${SHITRAN_FILES_SRC} ${SHITRAN_FILES_INC} ${SHITRAN_FILES_INC_API})
-target_link_libraries(shitran RSys)
-
-set_target_properties(shitran PROPERTIES
- DEFINE_SYMBOL SHITRAN_SHARED_BUILD
+set(SHT_FILES_SRC
+ sht.c
+ sht_log.c
+ sht_isotopologues.c)
+set(SHT_FILES_INC
+ sht_c.h
+ sht_log.h)
+set(SHT_FILES_INC_API
+ sht.h)
+
+set(SHT_FILES_DOC COPYING README.md)
+
+# Prepend each file in the `SHT_FILES_<SRC|INC>' list by `SHT_SOURCE_DIR'
+rcmake_prepend_path(SHT_FILES_SRC ${SHT_SOURCE_DIR})
+rcmake_prepend_path(SHT_FILES_INC ${SHT_SOURCE_DIR})
+rcmake_prepend_path(SHT_FILES_INC_API ${SHT_SOURCE_DIR})
+rcmake_prepend_path(SHT_FILES_DOC ${PROJECT_SOURCE_DIR}/../)
+
+add_library(sht SHARED ${SHT_FILES_SRC} ${SHT_FILES_INC} ${SHT_FILES_INC_API})
+target_link_libraries(sht RSys)
+
+set_target_properties(sht PROPERTIES
+ DEFINE_SYMBOL SHT_SHARED_BUILD
VERSION ${VERSION}
SOVERSION ${VERSION_MAJOR})
-rcmake_setup_devel(shitran StarHITRAN ${VERSION} star/shitran_version.h)
+rcmake_setup_devel(sht StarHITRAN ${VERSION} star/sht_version.h)
################################################################################
# Add tests
################################################################################
if(NOT NO_TEST)
function(build_test _name)
- add_executable(${_name} ${SHITRAN_SOURCE_DIR}/${_name}.c)
- target_link_libraries(${_name} shitran RSys ${ARGN})
+ add_executable(${_name} ${SHT_SOURCE_DIR}/${_name}.c)
+ target_link_libraries(${_name} sht RSys ${ARGN})
endfunction()
function(new_test _name)
@@ -85,17 +85,17 @@ if(NOT NO_TEST)
add_test(${_name} ${_name})
endfunction()
- new_test(test_shitran)
+ new_test(test_sht)
endif()
################################################################################
# Define output & install directories
################################################################################
-install(TARGETS shitran
+install(TARGETS sht
ARCHIVE DESTINATION bin
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin)
-install(FILES ${SHITRAN_FILES_INC_API} DESTINATION include/star)
-install(FILES ${SHITRAN_FILES_DOC} DESTINATION share/doc/star-hitran)
+install(FILES ${SHT_FILES_INC_API} DESTINATION include/star)
+install(FILES ${SHT_FILES_DOC} DESTINATION share/doc/star-hitran)
diff --git a/src/shitran.c b/src/shitran.c
@@ -1,101 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * 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 "shitran.h"
-#include "shitran_c.h"
-#include "shitran_log.h"
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static INLINE res_T
-check_shitran_create_args(const struct shitran_create_args* args)
-{
- return args ? RES_OK : RES_BAD_ARG;
-}
-
-static void
-release_shitran(ref_T* ref)
-{
- struct shitran* shitran = CONTAINER_OF(ref, struct shitran, ref);
- ASSERT(ref);
- if(shitran->logger == &shitran->logger__) logger_release(&shitran->logger__);
- MEM_RM(shitran->allocator, shitran);
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-shitran_create
- (const struct shitran_create_args* args,
- struct shitran** out_shitran)
-{
- struct mem_allocator* allocator = NULL;
- struct shitran* shitran = NULL;
- res_T res = RES_OK;
-
- if(!out_shitran) { res = RES_BAD_ARG; goto error; }
- res = check_shitran_create_args(args);
- if(res != RES_OK) goto error;
-
- allocator = args->allocator ? args->allocator : &mem_default_allocator;
- shitran = MEM_CALLOC(allocator, 1, sizeof(*shitran));
- if(!shitran) {
- #define ERR_STR "Could not allocate the Star-HITRAN data structure.\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(&shitran->ref);
- shitran->allocator = allocator;
- shitran->verbose = args->verbose;
- if(args->logger) {
- shitran->logger = args->logger;
- } else {
- setup_log_default(shitran);
- }
-
-exit:
- if(out_shitran) *out_shitran = shitran;
- return res;
-error:
- if(shitran) { SHITRAN(ref_put(shitran)); shitran = NULL; }
- goto exit;
-}
-
-res_T
-shitran_ref_get(struct shitran* shitran)
-{
- if(!shitran) return RES_BAD_ARG;
- ref_get(&shitran->ref);
- return RES_OK;
-}
-
-res_T
-shitran_ref_put(struct shitran* shitran)
-{
- if(!shitran) return RES_BAD_ARG;
- ref_put(&shitran->ref, release_shitran);
- return RES_OK;
-}
diff --git a/src/shitran.h b/src/shitran.h
@@ -1,99 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * 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 SHITRAN_H
-#define SHITRAN_H
-
-#include <rsys/rsys.h>
-
-/* Library symbol management */
-#if defined(SHITRAN_SHARED_BUILD) /* Build shared library */
- #define SHITRAN_API extern EXPORT_SYM
-#elif defined(SHITRAN_STATIC) /* Use/build static library */
- #define SHITRAN_API extern LOCAL_SYM
-#else
- #define SHITRAN_API extern IMPORT_SYM
-#endif
-
-/* Helper macro that asserts if the invocation of the sth function `Func'
- * returns an error. One should use this macro on sth function calls for
- * which no explicit error checking is performed */
-#ifndef NDEBUG
- #define SHITRAN(Func) ASSERT(shitran_ ## Func == RES_OK)
-#else
- #define SHITRAN(Func) shitran_ ## Func
-#endif
-
-struct shitran_create_args {
- struct logger* logger; /* May be NULL <=> default logger */
- struct mem_allocator* allocator; /* NULL <=> use default allocator */
- int verbose; /* Verbosity level */
-};
-#define SHITRAN_CREATE_ARGS_DEFAULT__ {NULL, NULL, 0}
-static const struct shitran_create_args SHITRAN_CREATE_ARGS_DEFAULT =
- SHITRAN_CREATE_ARGS_DEFAULT__;
-
-/* Forware declarations */
-struct shitran;
-struct shitran_isotopologues;
-
-BEGIN_DECLS
-
-/*******************************************************************************
- * Device API
- ******************************************************************************/
-SHITRAN_API res_T
-shitran_create
- (const struct shitran_create_args* args,
- struct shitran** shitran);
-
-SHITRAN_API res_T
-shitran_ref_get
- (struct shitran* shitran);
-
-SHITRAN_API res_T
-shitran_ref_put
- (struct shitran* shitran);
-
-/*******************************************************************************
- * Isotopologues API
- ******************************************************************************/
-SHITRAN_API res_T
-shitran_isotopologues_load
- (struct shitran* shitran,
- const char* path,
- struct shitran_isotopologues** isotopologues);
-
-SHITRAN_API res_T
-shitran_isotopologues_load_from_stream
- (struct shitran* shitran,
- FILE* stream,
- const char* stream_name, /* NULL <=> use default stream name */
- struct shitran_isotopologues** isotopologues);
-
-SHITRAN_API res_T
-shitran_isotopologues_ref_get
- (struct shitran_isotopologues* isotopologues);
-
-SHITRAN_API res_T
-shitran_isotopologues_ref_put
- (struct shitran_isotopologues* isotopologues);
-
-END_DECLS
-
-#endif /* SHITRAN_H */
diff --git a/src/shitran_c.h b/src/shitran_c.h
@@ -1,35 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * 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 SHITRAN_C_H
-#define SHITRAN_C_H
-
-#include <rsys/logger.h>
-#include <rsys/ref_count.h>
-
-struct mem_allocator;
-
-struct shitran {
- struct mem_allocator* allocator;
- struct logger* logger;
- struct logger logger__; /* Default logger */
- int verbose;
- ref_T ref;
-};
-
-#endif /* SHITRAN_C_H */
diff --git a/src/shitran_isotopologues.c b/src/shitran_isotopologues.c
@@ -1,426 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * 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 200112L /* strtok_r support */
-
-#include "shitran.h"
-#include "shitran_c.h"
-#include "shitran_log.h"
-
-#include <rsys/cstr.h>
-#include <rsys/dynamic_array.h>
-#include <rsys/hash_table.h>
-#include <rsys/ref_count.h>
-#include <rsys/str.h>
-#include <rsys/text_reader.h>
-
-#include <ctype.h>
-#include <string.h>
-
-struct isotope {
- double abundance;
- double Q; /* At 296 K */
- double gj;
- double molar_mass; /* In g */
- size_t molecule; /* Index of the molecule to which the isotope belongs */
- int id; /* Unique identifier of the isotope */
-};
-
-/* Generate the dynamic array of isotopes */
-#define DARRAY_NAME isotope
-#define DARRAY_DATA struct isotope
-#include <rsys/dynamic_array.h>
-
-struct molecule {
- struct str name;
- size_t isotopes_range[2]; /* Range of the 1st and last regisered isotopes */
- int id; /* Unique identifier of the molecule */
-};
-#define MOLECULE_IS_VALID(Molecule) ((Molecule)->id >= 0)
-
-static INLINE void
-molecule_clear(struct molecule* molecule)
-{
- ASSERT(molecule);
- molecule->isotopes_range[0] = SIZE_MAX;
- molecule->isotopes_range[1] = 0;
- molecule->id = -1;
-}
-
-static INLINE void
-molecule_init(struct mem_allocator* allocator, struct molecule* molecule)
-{
- str_init(allocator, &molecule->name);
- molecule_clear(molecule);
-}
-
-static INLINE void
-molecule_release(struct molecule* molecule)
-{
- str_release(&molecule->name);
-}
-
-static INLINE res_T
-molecule_copy(struct molecule* dst, const struct molecule* src)
-{
- dst->isotopes_range[0] = src->isotopes_range[0];
- dst->isotopes_range[1] = src->isotopes_range[1];
- dst->id = src->id;
- return str_copy(&dst->name, &src->name);
-}
-
-static INLINE res_T
-molecule_copy_and_release(struct molecule* dst, struct molecule* src)
-{
- dst->isotopes_range[0] = src->isotopes_range[0];
- dst->isotopes_range[1] = src->isotopes_range[1];
- dst->id = src->id;
- return str_copy_and_release(&dst->name, &src->name);
-}
-
-/* Generate the dynamic array of molecules */
-#define DARRAY_NAME molecule
-#define DARRAY_DATA struct molecule
-#define DARRAY_FUNCTOR_INIT molecule_init
-#define DARRAY_FUNCTOR_RELEASE molecule_release
-#define DARRAY_FUNCTOR_COPY molecule_copy
-#define DARRAY_FUNCTOR_COPY_AND_RELEASE molecule_copy_and_release
-#include <rsys/dynamic_array.h>
-
-/* Generate the hash table that map a unique identifier to its index */
-#define HTABLE_NAME id2entry
-#define HTABLE_KEY int /* Unique identifier */
-#define HTABLE_DATA size_t /* Index of the corresponding registered data */
-#include <rsys/hash_table.h>
-
-struct shitran_isotopologues {
-
- /* List of molecules and isotopes */
- struct darray_molecule molecules;
- struct darray_isotope isotopes;
-
- /* Map the identifier of a molecule/isotope to its correspond index into
- * their corresponding dynamic arays into which they are registered */
- struct htable_id2entry molid2idx;
- struct htable_id2entry isoid2idx;
-
- struct shitran* shitran;
- ref_T ref;
-};
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static res_T
-create_isotoplogues
- (struct shitran* shitran,
- struct shitran_isotopologues** out_isotopologues)
-{
- struct shitran_isotopologues* isotopologues = NULL;
- res_T res = RES_OK;
- ASSERT(shitran && out_isotopologues);
-
- isotopologues = MEM_CALLOC(shitran->allocator, 1, sizeof(*isotopologues));
- if(!isotopologues) {
- log_err(shitran, "Could not allocate the isotopologues data structure.\n");
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&isotopologues->ref);
- SHITRAN(ref_get(shitran));
- isotopologues->shitran = shitran;
- darray_molecule_init(shitran->allocator, &isotopologues->molecules);
- darray_isotope_init(shitran->allocator, &isotopologues->isotopes);
- htable_id2entry_init(shitran->allocator, &isotopologues->molid2idx);
- htable_id2entry_init(shitran->allocator, &isotopologues->isoid2idx);
-
-exit:
- *out_isotopologues = isotopologues;
- return res;
-error:
- goto exit;
-}
-
-static res_T
-flush_molecule
- (struct shitran_isotopologues* isotopologues,
- struct molecule* molecule, /* Currently parsed molecule */
- struct txtrdr* txtrdr)
-{
- size_t entry = 0;
- res_T res = RES_OK;
- ASSERT(isotopologues && molecule && MOLECULE_IS_VALID(molecule));
-
- /* Fetch _exclusive_ upper bound */
- molecule->isotopes_range[1] = darray_isotope_size_get(&isotopologues->isotopes);
- if(molecule->isotopes_range[0] >= molecule->isotopes_range[1]) {
- log_warn(isotopologues->shitran,
- "%s: the %s molecule does not have any isotopes.\n",
- txtrdr_get_name(txtrdr), str_cget(&molecule->name));
- }
-
- /* Fetch the index of the registered molecule */
- entry = darray_molecule_size_get(&isotopologues->molecules);
-
- /* Storing the molecule */
- res = darray_molecule_push_back(&isotopologues->molecules, molecule);
- if(res != RES_OK) {
- log_err(isotopologues->shitran,
- "%s: error storing the %s molecule -- %s.\n",
- txtrdr_get_name(txtrdr), str_cget(&molecule->name), res_to_cstr(res));
- goto error;
- }
-
- /* Registering the molecule */
- ASSERT(!htable_id2entry_find(&isotopologues->molid2idx, &molecule->id));
- res = htable_id2entry_set(&isotopologues->molid2idx, &molecule->id, &entry);
- if(res != RES_OK) {
- log_err(isotopologues->shitran,
- "%s: error registering the %s molecule -- %s.\n",
- txtrdr_get_name(txtrdr), str_cget(&molecule->name), res_to_cstr(res));
- goto error;
- }
-
- molecule_clear(molecule);
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-static res_T
-parse_molecule
- (struct shitran_isotopologues* isotopologues,
- struct molecule* molecule,
- struct txtrdr* txtrdr)
-{
- char* name = NULL;
- char* id = NULL;
- char* tk = NULL;
- char* tk_ctx = NULL;
- size_t len;
- res_T res = RES_OK;
- ASSERT(molecule && txtrdr);
-
- name = strtok_r(txtrdr_get_line(txtrdr), " \t", &tk_ctx);
- id = strtok_r(NULL, " \t", &tk_ctx);
-
- if(!name) {
- log_err(isotopologues->shitran, "%s:%lu: molecule name is missing.\n",
- txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr));
- res = RES_BAD_ARG;
- goto error;
- }
-
- len = strlen(id);
- if(!id || !len || id[0] != '(' || id[len-1] != ')') {
- log_err(isotopologues->shitran, "%s:%lu: invalid molecule identifier.\n",
- txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr));
- res = RES_BAD_ARG;
- goto error;
- }
-
- id[len-1] = '\0'; /* Rm trailing parenthesis */
- res = cstr_to_int(id+1/*Rm leading parenthesis*/, &molecule->id);
- if(res != RES_OK || !MOLECULE_IS_VALID(molecule)) {
- id[len-1] = ')'; /* Re-add the trailing parenthesis */
- log_err(isotopologues->shitran, "%s:%lu: invalid molecule identifier `%s'.\n",
- txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), id);
- res = RES_BAD_ARG;
- goto error;
- }
-
- tk = strtok_r(NULL, " \t", &tk_ctx);
- if(tk) {
- log_warn(isotopologues->shitran, "%s:%lu: unexpected text `%s'.\n",
- txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk);
- }
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-static res_T
-parse_line
- (struct shitran_isotopologues* isotopologues,
- struct molecule* molecule, /* Currently parsed molecule */
- struct txtrdr* txtrdr)
-{
- const char* line = NULL;
- size_t i;
- res_T res = RES_OK;
- ASSERT(isotopologues && molecule && txtrdr);
-
- line = txtrdr_get_cline(txtrdr);
- ASSERT(line);
- i = strcspn(line, " \t");
- ASSERT(i < strlen(line));
-
- if(isalpha(line[i])) {
- if(MOLECULE_IS_VALID(molecule)) {
- res = flush_molecule(isotopologues, molecule, txtrdr);
- if(res != RES_OK) goto error;
- }
- res = parse_molecule(isotopologues, molecule, txtrdr);
- if(res != RES_OK) goto error;
- } else {
- /* TODO parse the isotope */
- }
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-static res_T
-load_stream
- (struct shitran* shitran,
- FILE* stream,
- const char* name,
- struct shitran_isotopologues** out_isotopologues)
-{
- struct molecule molecule; /* Current molecule */
- struct shitran_isotopologues* isotopologues = NULL;
- struct txtrdr* txtrdr = NULL;
- res_T res = RES_OK;
- ASSERT(shitran && stream && name && out_isotopologues);
-
- molecule_init(shitran->allocator, &molecule);
-
- res = create_isotoplogues(shitran, &isotopologues);
- if(res != RES_OK) goto error;
-
- res = txtrdr_stream(isotopologues->shitran->allocator, stream, name,
- 0/*comment char*/, &txtrdr);
- if(res != RES_OK) {
- log_err(shitran, "%s: error creating the text reader -- %s.\n",
- name, res_to_cstr(res));
- goto error;
- }
-
- #define READ_LINE { \
- res = txtrdr_read_line(txtrdr); \
- if(res != RES_OK) { \
- log_err(shitran, "%s: error reading the line `%lu' -- %s.\n", \
- name, (unsigned long)txtrdr_get_line_num(txtrdr), res_to_cstr(res)); \
- goto error; \
- } \
- } (void)0
-
- /* Skip the 1st line that is a comment line*/
- READ_LINE;
- if(!txtrdr_get_cline(txtrdr)) goto exit;
-
- for(;;) {
- READ_LINE;
-
- if(!txtrdr_get_cline(txtrdr)) break; /* No more parsed line */
- res = parse_line(isotopologues, &molecule, txtrdr);
- if(res != RES_OK) goto error;
- }
- #undef READ_LINE
-
-exit:
- *out_isotopologues = isotopologues;
- molecule_release(&molecule);
- return res;
-error:
- goto exit;
-}
-
-static void
-release_isotopologues(ref_T* ref)
-{
- struct shitran* shitran = NULL;
- struct shitran_isotopologues* isotopologues = CONTAINER_OF
- (ref, struct shitran_isotopologues, ref);
- ASSERT(ref);
- shitran = isotopologues->shitran;
- darray_molecule_release(&isotopologues->molecules);
- darray_isotope_release(&isotopologues->isotopes);
- htable_id2entry_release(&isotopologues->molid2idx);
- htable_id2entry_release(&isotopologues->isoid2idx);
- MEM_RM(shitran->allocator, isotopologues);
- SHITRAN(ref_put(shitran));
-}
-
-/*******************************************************************************
- * Exported functions
- ******************************************************************************/
-res_T
-shitran_isotopologues_load
- (struct shitran* shitran,
- const char* path,
- struct shitran_isotopologues** isotopologues)
-{
- FILE* file = NULL;
- res_T res = RES_OK;
-
- if(!shitran || !path) {
- res = RES_BAD_ARG;
- goto error;
- }
-
- file = fopen(path, "r");
- if(!file) {
- log_err(shitran, "%s: error opening file `%s'.\n", FUNC_NAME, path);
- res = RES_IO_ERR;
- goto error;
- }
-
- res = load_stream(shitran, file, path, isotopologues);
- if(res != RES_OK) goto error;
-
-exit:
- if(file) fclose(file);
- return res;
-error:
- goto exit;
-}
-
-res_T
-shitran_isotopologues_load_from_stream
- (struct shitran* shitran,
- FILE* stream,
- const char* stream_name,
- struct shitran_isotopologues** isotopologues)
-{
- if(!shitran || !stream) return RES_BAD_ARG;
- return load_stream
- (shitran, stream, stream_name ? stream_name : "<stream>", isotopologues);
-}
-
-res_T
-shitran_isotopologues_ref_get(struct shitran_isotopologues* isotopologues)
-{
- if(!isotopologues) return RES_BAD_ARG;
- ref_get(&isotopologues->ref);
- return RES_OK;
-}
-
-res_T
-shitran_isotopologues_ref_put(struct shitran_isotopologues* isotopologues)
-{
- if(!isotopologues) return RES_BAD_ARG;
- ref_put(&isotopologues->ref, release_isotopologues);
- return RES_OK;
-}
diff --git a/src/shitran_log.c b/src/shitran_log.c
@@ -1,127 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * 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 "shitran_c.h"
-#include "shitran_log.h"
-
-#include <rsys/cstr.h>
-#include <rsys/logger.h>
-
-#include <stdarg.h>
-
-/*******************************************************************************
- * Helper functions
- ******************************************************************************/
-static INLINE void
-log_msg
- (const struct shitran* shitran,
- const enum log_type stream,
- const char* msg,
- va_list vargs)
-{
- ASSERT(shitran && msg);
- if(shitran->verbose) {
- res_T res; (void)res;
- res = logger_vprint(shitran->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 shitran* shitran)
-{
- res_T res = RES_OK;
- ASSERT(shitran);
-
- res = logger_init(shitran->allocator, &shitran->logger__);
- if(res != RES_OK) {
- if(shitran->verbose) {
- fprintf(stderr,
- MSG_ERROR_PREFIX
- "Could not setup the default logger for the Star-HITRAN library -- %s.\n",
- res_to_cstr(res));
- }
- goto error;
- }
- logger_set_stream(&shitran->logger__, LOG_OUTPUT, print_info, NULL);
- logger_set_stream(&shitran->logger__, LOG_ERROR, print_err, NULL);
- logger_set_stream(&shitran->logger__, LOG_WARNING, print_warn, NULL);
- shitran->logger = &shitran->logger__;
-
-exit:
- return res;
-error:
- goto exit;
-}
-
-void
-log_info(const struct shitran* shitran, const char* msg, ...)
-{
- va_list vargs_list;
- ASSERT(shitran && msg);
-
- va_start(vargs_list, msg);
- log_msg(shitran, LOG_OUTPUT, msg, vargs_list);
- va_end(vargs_list);
-}
-
-void
-log_err(const struct shitran* shitran, const char* msg, ...)
-{
- va_list vargs_list;
- ASSERT(shitran && msg);
-
- va_start(vargs_list, msg);
- log_msg(shitran, LOG_ERROR, msg, vargs_list);
- va_end(vargs_list);
-}
-
-void
-log_warn(const struct shitran* shitran, const char* msg, ...)
-{
- va_list vargs_list;
- ASSERT(shitran && msg);
-
- va_start(vargs_list, msg);
- log_msg(shitran, LOG_WARNING, msg, vargs_list);
- va_end(vargs_list);
-}
diff --git a/src/shitran_log.h b/src/shitran_log.h
@@ -1,73 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * 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 SHITRAN_LOG_H
-#define SHITRAN_LOG_H
-
-#include <rsys/rsys.h>
-
-#define MSG_INFO_PREFIX "Star-HITRAN:\x1b[1m\x1b[32minfo\x1b[0m: "
-#define MSG_ERROR_PREFIX "Star-HITRAN:\x1b[1m\x1b[31merror\x1b[0m: "
-#define MSG_WARNING_PREFIX "Star-HITRAN:\x1b[1m\x1b[33mwarning\x1b[0m: "
-
-struct shitran;
-struct logger;
-
-extern LOCAL_SYM res_T
-setup_log_default
- (struct shitran* shitran);
-
-/* Conditionally log a message on the LOG_OUTPUT stream of the shitran logger,
- * with respect to its verbose flag */
-extern LOCAL_SYM void
-log_info
- (const struct shitran* shitran,
- const char* msg,
- ...)
-#ifdef COMPILER_GCC
- __attribute((format(printf, 2, 3)))
-#endif
-;
-
-/* Conditionally log a message on the LOG_ERROR stream of the shitran logger,
- * with respect to its verbose flag */
-extern LOCAL_SYM void
-log_err
- (const struct shitran* shitran,
- const char* msg,
- ...)
-#ifdef COMPILER_GCC
- __attribute((format(printf, 2, 3)))
-#endif
-;
-
-/* Conditionally log a message on the LOG_WARNING stream of the shitran logger,
- * with respect to its verbose flag */
-extern LOCAL_SYM void
-log_warn
- (const struct shitran* shitran,
- const char* msg,
- ...)
-#ifdef COMPILER_GCC
- __attribute((format(printf, 2, 3)))
-#endif
-;
-
-
-#endif /* SHITRAN_LOG_H */
-
diff --git a/src/sht.c b/src/sht.c
@@ -0,0 +1,101 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * 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 "sht.h"
+#include "sht_c.h"
+#include "sht_log.h"
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static INLINE res_T
+check_sht_create_args(const struct sht_create_args* args)
+{
+ return args ? RES_OK : RES_BAD_ARG;
+}
+
+static void
+release_sht(ref_T* ref)
+{
+ struct sht* sht = CONTAINER_OF(ref, struct sht, ref);
+ ASSERT(ref);
+ if(sht->logger == &sht->logger__) logger_release(&sht->logger__);
+ MEM_RM(sht->allocator, sht);
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+sht_create
+ (const struct sht_create_args* args,
+ struct sht** out_sht)
+{
+ struct mem_allocator* allocator = NULL;
+ struct sht* sht = NULL;
+ res_T res = RES_OK;
+
+ if(!out_sht) { res = RES_BAD_ARG; goto error; }
+ res = check_sht_create_args(args);
+ if(res != RES_OK) goto error;
+
+ allocator = args->allocator ? args->allocator : &mem_default_allocator;
+ sht = MEM_CALLOC(allocator, 1, sizeof(*sht));
+ if(!sht) {
+ #define ERR_STR "Could not allocate the Star-HITRAN data structure.\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(&sht->ref);
+ sht->allocator = allocator;
+ sht->verbose = args->verbose;
+ if(args->logger) {
+ sht->logger = args->logger;
+ } else {
+ setup_log_default(sht);
+ }
+
+exit:
+ if(out_sht) *out_sht = sht;
+ return res;
+error:
+ if(sht) { SHT(ref_put(sht)); sht = NULL; }
+ goto exit;
+}
+
+res_T
+sht_ref_get(struct sht* sht)
+{
+ if(!sht) return RES_BAD_ARG;
+ ref_get(&sht->ref);
+ return RES_OK;
+}
+
+res_T
+sht_ref_put(struct sht* sht)
+{
+ if(!sht) return RES_BAD_ARG;
+ ref_put(&sht->ref, release_sht);
+ return RES_OK;
+}
diff --git a/src/sht.h b/src/sht.h
@@ -0,0 +1,99 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * 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 SHT_H
+#define SHT_H
+
+#include <rsys/rsys.h>
+
+/* Library symbol management */
+#if defined(SHT_SHARED_BUILD) /* Build shared library */
+ #define SHT_API extern EXPORT_SYM
+#elif defined(SHT_STATIC) /* Use/build static library */
+ #define SHT_API extern LOCAL_SYM
+#else
+ #define SHT_API extern IMPORT_SYM
+#endif
+
+/* Helper macro that asserts if the invocation of the sth function `Func'
+ * returns an error. One should use this macro on sth function calls for
+ * which no explicit error checking is performed */
+#ifndef NDEBUG
+ #define SHT(Func) ASSERT(sht_ ## Func == RES_OK)
+#else
+ #define SHT(Func) sht_ ## Func
+#endif
+
+struct sht_create_args {
+ struct logger* logger; /* May be NULL <=> default logger */
+ struct mem_allocator* allocator; /* NULL <=> use default allocator */
+ int verbose; /* Verbosity level */
+};
+#define SHT_CREATE_ARGS_DEFAULT__ {NULL, NULL, 0}
+static const struct sht_create_args SHT_CREATE_ARGS_DEFAULT =
+ SHT_CREATE_ARGS_DEFAULT__;
+
+/* Forware declarations */
+struct sht;
+struct sht_isotopologues;
+
+BEGIN_DECLS
+
+/*******************************************************************************
+ * Device API
+ ******************************************************************************/
+SHT_API res_T
+sht_create
+ (const struct sht_create_args* args,
+ struct sht** sht);
+
+SHT_API res_T
+sht_ref_get
+ (struct sht* sht);
+
+SHT_API res_T
+sht_ref_put
+ (struct sht* sht);
+
+/*******************************************************************************
+ * Isotopologues API
+ ******************************************************************************/
+SHT_API res_T
+sht_isotopologues_load
+ (struct sht* sht,
+ const char* path,
+ struct sht_isotopologues** isotopologues);
+
+SHT_API res_T
+sht_isotopologues_load_from_stream
+ (struct sht* sht,
+ FILE* stream,
+ const char* stream_name, /* NULL <=> use default stream name */
+ struct sht_isotopologues** isotopologues);
+
+SHT_API res_T
+sht_isotopologues_ref_get
+ (struct sht_isotopologues* isotopologues);
+
+SHT_API res_T
+sht_isotopologues_ref_put
+ (struct sht_isotopologues* isotopologues);
+
+END_DECLS
+
+#endif /* SHT_H */
diff --git a/src/sht_c.h b/src/sht_c.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * 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 SHT_C_H
+#define SHT_C_H
+
+#include <rsys/logger.h>
+#include <rsys/ref_count.h>
+
+struct mem_allocator;
+
+struct sht {
+ struct mem_allocator* allocator;
+ struct logger* logger;
+ struct logger logger__; /* Default logger */
+ int verbose;
+ ref_T ref;
+};
+
+#endif /* SHT_C_H */
diff --git a/src/sht_isotopologues.c b/src/sht_isotopologues.c
@@ -0,0 +1,426 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * 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 200112L /* strtok_r support */
+
+#include "sht.h"
+#include "sht_c.h"
+#include "sht_log.h"
+
+#include <rsys/cstr.h>
+#include <rsys/dynamic_array.h>
+#include <rsys/hash_table.h>
+#include <rsys/ref_count.h>
+#include <rsys/str.h>
+#include <rsys/text_reader.h>
+
+#include <ctype.h>
+#include <string.h>
+
+struct isotope {
+ double abundance;
+ double Q; /* At 296 K */
+ double gj;
+ double molar_mass; /* In g */
+ size_t molecule; /* Index of the molecule to which the isotope belongs */
+ int id; /* Unique identifier of the isotope */
+};
+
+/* Generate the dynamic array of isotopes */
+#define DARRAY_NAME isotope
+#define DARRAY_DATA struct isotope
+#include <rsys/dynamic_array.h>
+
+struct molecule {
+ struct str name;
+ size_t isotopes_range[2]; /* Range of the 1st and last regisered isotopes */
+ int id; /* Unique identifier of the molecule */
+};
+#define MOLECULE_IS_VALID(Molecule) ((Molecule)->id >= 0)
+
+static INLINE void
+molecule_clear(struct molecule* molecule)
+{
+ ASSERT(molecule);
+ molecule->isotopes_range[0] = SIZE_MAX;
+ molecule->isotopes_range[1] = 0;
+ molecule->id = -1;
+}
+
+static INLINE void
+molecule_init(struct mem_allocator* allocator, struct molecule* molecule)
+{
+ str_init(allocator, &molecule->name);
+ molecule_clear(molecule);
+}
+
+static INLINE void
+molecule_release(struct molecule* molecule)
+{
+ str_release(&molecule->name);
+}
+
+static INLINE res_T
+molecule_copy(struct molecule* dst, const struct molecule* src)
+{
+ dst->isotopes_range[0] = src->isotopes_range[0];
+ dst->isotopes_range[1] = src->isotopes_range[1];
+ dst->id = src->id;
+ return str_copy(&dst->name, &src->name);
+}
+
+static INLINE res_T
+molecule_copy_and_release(struct molecule* dst, struct molecule* src)
+{
+ dst->isotopes_range[0] = src->isotopes_range[0];
+ dst->isotopes_range[1] = src->isotopes_range[1];
+ dst->id = src->id;
+ return str_copy_and_release(&dst->name, &src->name);
+}
+
+/* Generate the dynamic array of molecules */
+#define DARRAY_NAME molecule
+#define DARRAY_DATA struct molecule
+#define DARRAY_FUNCTOR_INIT molecule_init
+#define DARRAY_FUNCTOR_RELEASE molecule_release
+#define DARRAY_FUNCTOR_COPY molecule_copy
+#define DARRAY_FUNCTOR_COPY_AND_RELEASE molecule_copy_and_release
+#include <rsys/dynamic_array.h>
+
+/* Generate the hash table that map a unique identifier to its index */
+#define HTABLE_NAME id2entry
+#define HTABLE_KEY int /* Unique identifier */
+#define HTABLE_DATA size_t /* Index of the corresponding registered data */
+#include <rsys/hash_table.h>
+
+struct sht_isotopologues {
+
+ /* List of molecules and isotopes */
+ struct darray_molecule molecules;
+ struct darray_isotope isotopes;
+
+ /* Map the identifier of a molecule/isotope to its correspond index into
+ * their corresponding dynamic arays into which they are registered */
+ struct htable_id2entry molid2idx;
+ struct htable_id2entry isoid2idx;
+
+ struct sht* sht;
+ ref_T ref;
+};
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static res_T
+create_isotoplogues
+ (struct sht* sht,
+ struct sht_isotopologues** out_isotopologues)
+{
+ struct sht_isotopologues* isotopologues = NULL;
+ res_T res = RES_OK;
+ ASSERT(sht && out_isotopologues);
+
+ isotopologues = MEM_CALLOC(sht->allocator, 1, sizeof(*isotopologues));
+ if(!isotopologues) {
+ log_err(sht, "Could not allocate the isotopologues data structure.\n");
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&isotopologues->ref);
+ SHT(ref_get(sht));
+ isotopologues->sht = sht;
+ darray_molecule_init(sht->allocator, &isotopologues->molecules);
+ darray_isotope_init(sht->allocator, &isotopologues->isotopes);
+ htable_id2entry_init(sht->allocator, &isotopologues->molid2idx);
+ htable_id2entry_init(sht->allocator, &isotopologues->isoid2idx);
+
+exit:
+ *out_isotopologues = isotopologues;
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+flush_molecule
+ (struct sht_isotopologues* isotopologues,
+ struct molecule* molecule, /* Currently parsed molecule */
+ struct txtrdr* txtrdr)
+{
+ size_t entry = 0;
+ res_T res = RES_OK;
+ ASSERT(isotopologues && molecule && MOLECULE_IS_VALID(molecule));
+
+ /* Fetch _exclusive_ upper bound */
+ molecule->isotopes_range[1] = darray_isotope_size_get(&isotopologues->isotopes);
+ if(molecule->isotopes_range[0] >= molecule->isotopes_range[1]) {
+ log_warn(isotopologues->sht,
+ "%s: the %s molecule does not have any isotopes.\n",
+ txtrdr_get_name(txtrdr), str_cget(&molecule->name));
+ }
+
+ /* Fetch the index of the registered molecule */
+ entry = darray_molecule_size_get(&isotopologues->molecules);
+
+ /* Storing the molecule */
+ res = darray_molecule_push_back(&isotopologues->molecules, molecule);
+ if(res != RES_OK) {
+ log_err(isotopologues->sht,
+ "%s: error storing the %s molecule -- %s.\n",
+ txtrdr_get_name(txtrdr), str_cget(&molecule->name), res_to_cstr(res));
+ goto error;
+ }
+
+ /* Registering the molecule */
+ ASSERT(!htable_id2entry_find(&isotopologues->molid2idx, &molecule->id));
+ res = htable_id2entry_set(&isotopologues->molid2idx, &molecule->id, &entry);
+ if(res != RES_OK) {
+ log_err(isotopologues->sht,
+ "%s: error registering the %s molecule -- %s.\n",
+ txtrdr_get_name(txtrdr), str_cget(&molecule->name), res_to_cstr(res));
+ goto error;
+ }
+
+ molecule_clear(molecule);
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_molecule
+ (struct sht_isotopologues* isotopologues,
+ struct molecule* molecule,
+ struct txtrdr* txtrdr)
+{
+ char* name = NULL;
+ char* id = NULL;
+ char* tk = NULL;
+ char* tk_ctx = NULL;
+ size_t len;
+ res_T res = RES_OK;
+ ASSERT(molecule && txtrdr);
+
+ name = strtok_r(txtrdr_get_line(txtrdr), " \t", &tk_ctx);
+ id = strtok_r(NULL, " \t", &tk_ctx);
+
+ if(!name) {
+ log_err(isotopologues->sht, "%s:%lu: molecule name is missing.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ len = strlen(id);
+ if(!id || !len || id[0] != '(' || id[len-1] != ')') {
+ log_err(isotopologues->sht, "%s:%lu: invalid molecule identifier.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr));
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ id[len-1] = '\0'; /* Rm trailing parenthesis */
+ res = cstr_to_int(id+1/*Rm leading parenthesis*/, &molecule->id);
+ if(res != RES_OK || !MOLECULE_IS_VALID(molecule)) {
+ id[len-1] = ')'; /* Re-add the trailing parenthesis */
+ log_err(isotopologues->sht, "%s:%lu: invalid molecule identifier `%s'.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), id);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ tk = strtok_r(NULL, " \t", &tk_ctx);
+ if(tk) {
+ log_warn(isotopologues->sht, "%s:%lu: unexpected text `%s'.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk);
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+parse_line
+ (struct sht_isotopologues* isotopologues,
+ struct molecule* molecule, /* Currently parsed molecule */
+ struct txtrdr* txtrdr)
+{
+ const char* line = NULL;
+ size_t i;
+ res_T res = RES_OK;
+ ASSERT(isotopologues && molecule && txtrdr);
+
+ line = txtrdr_get_cline(txtrdr);
+ ASSERT(line);
+ i = strcspn(line, " \t");
+ ASSERT(i < strlen(line));
+
+ if(isalpha(line[i])) {
+ if(MOLECULE_IS_VALID(molecule)) {
+ res = flush_molecule(isotopologues, molecule, txtrdr);
+ if(res != RES_OK) goto error;
+ }
+ res = parse_molecule(isotopologues, molecule, txtrdr);
+ if(res != RES_OK) goto error;
+ } else {
+ /* TODO parse the isotope */
+ }
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+static res_T
+load_stream
+ (struct sht* sht,
+ FILE* stream,
+ const char* name,
+ struct sht_isotopologues** out_isotopologues)
+{
+ struct molecule molecule; /* Current molecule */
+ struct sht_isotopologues* isotopologues = NULL;
+ struct txtrdr* txtrdr = NULL;
+ res_T res = RES_OK;
+ ASSERT(sht && stream && name && out_isotopologues);
+
+ molecule_init(sht->allocator, &molecule);
+
+ res = create_isotoplogues(sht, &isotopologues);
+ if(res != RES_OK) goto error;
+
+ res = txtrdr_stream(isotopologues->sht->allocator, stream, name,
+ 0/*comment char*/, &txtrdr);
+ if(res != RES_OK) {
+ log_err(sht, "%s: error creating the text reader -- %s.\n",
+ name, res_to_cstr(res));
+ goto error;
+ }
+
+ #define READ_LINE { \
+ res = txtrdr_read_line(txtrdr); \
+ if(res != RES_OK) { \
+ log_err(sht, "%s: error reading the line `%lu' -- %s.\n", \
+ name, (unsigned long)txtrdr_get_line_num(txtrdr), res_to_cstr(res)); \
+ goto error; \
+ } \
+ } (void)0
+
+ /* Skip the 1st line that is a comment line*/
+ READ_LINE;
+ if(!txtrdr_get_cline(txtrdr)) goto exit;
+
+ for(;;) {
+ READ_LINE;
+
+ if(!txtrdr_get_cline(txtrdr)) break; /* No more parsed line */
+ res = parse_line(isotopologues, &molecule, txtrdr);
+ if(res != RES_OK) goto error;
+ }
+ #undef READ_LINE
+
+exit:
+ *out_isotopologues = isotopologues;
+ molecule_release(&molecule);
+ return res;
+error:
+ goto exit;
+}
+
+static void
+release_isotopologues(ref_T* ref)
+{
+ struct sht* sht = NULL;
+ struct sht_isotopologues* isotopologues = CONTAINER_OF
+ (ref, struct sht_isotopologues, ref);
+ ASSERT(ref);
+ sht = isotopologues->sht;
+ darray_molecule_release(&isotopologues->molecules);
+ darray_isotope_release(&isotopologues->isotopes);
+ htable_id2entry_release(&isotopologues->molid2idx);
+ htable_id2entry_release(&isotopologues->isoid2idx);
+ MEM_RM(sht->allocator, isotopologues);
+ SHT(ref_put(sht));
+}
+
+/*******************************************************************************
+ * Exported functions
+ ******************************************************************************/
+res_T
+sht_isotopologues_load
+ (struct sht* sht,
+ const char* path,
+ struct sht_isotopologues** isotopologues)
+{
+ FILE* file = NULL;
+ res_T res = RES_OK;
+
+ if(!sht || !path) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ file = fopen(path, "r");
+ if(!file) {
+ log_err(sht, "%s: error opening file `%s'.\n", FUNC_NAME, path);
+ res = RES_IO_ERR;
+ goto error;
+ }
+
+ res = load_stream(sht, file, path, isotopologues);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(file) fclose(file);
+ return res;
+error:
+ goto exit;
+}
+
+res_T
+sht_isotopologues_load_from_stream
+ (struct sht* sht,
+ FILE* stream,
+ const char* stream_name,
+ struct sht_isotopologues** isotopologues)
+{
+ if(!sht || !stream) return RES_BAD_ARG;
+ return load_stream
+ (sht, stream, stream_name ? stream_name : "<stream>", isotopologues);
+}
+
+res_T
+sht_isotopologues_ref_get(struct sht_isotopologues* isotopologues)
+{
+ if(!isotopologues) return RES_BAD_ARG;
+ ref_get(&isotopologues->ref);
+ return RES_OK;
+}
+
+res_T
+sht_isotopologues_ref_put(struct sht_isotopologues* isotopologues)
+{
+ if(!isotopologues) return RES_BAD_ARG;
+ ref_put(&isotopologues->ref, release_isotopologues);
+ return RES_OK;
+}
diff --git a/src/sht_log.c b/src/sht_log.c
@@ -0,0 +1,127 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * 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 "sht_c.h"
+#include "sht_log.h"
+
+#include <rsys/cstr.h>
+#include <rsys/logger.h>
+
+#include <stdarg.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static INLINE void
+log_msg
+ (const struct sht* sht,
+ const enum log_type stream,
+ const char* msg,
+ va_list vargs)
+{
+ ASSERT(sht && msg);
+ if(sht->verbose) {
+ res_T res; (void)res;
+ res = logger_vprint(sht->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 sht* sht)
+{
+ res_T res = RES_OK;
+ ASSERT(sht);
+
+ res = logger_init(sht->allocator, &sht->logger__);
+ if(res != RES_OK) {
+ if(sht->verbose) {
+ fprintf(stderr,
+ MSG_ERROR_PREFIX
+ "Could not setup the default logger for the Star-HITRAN library -- %s.\n",
+ res_to_cstr(res));
+ }
+ goto error;
+ }
+ logger_set_stream(&sht->logger__, LOG_OUTPUT, print_info, NULL);
+ logger_set_stream(&sht->logger__, LOG_ERROR, print_err, NULL);
+ logger_set_stream(&sht->logger__, LOG_WARNING, print_warn, NULL);
+ sht->logger = &sht->logger__;
+
+exit:
+ return res;
+error:
+ goto exit;
+}
+
+void
+log_info(const struct sht* sht, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(sht && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(sht, LOG_OUTPUT, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_err(const struct sht* sht, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(sht && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(sht, LOG_ERROR, msg, vargs_list);
+ va_end(vargs_list);
+}
+
+void
+log_warn(const struct sht* sht, const char* msg, ...)
+{
+ va_list vargs_list;
+ ASSERT(sht && msg);
+
+ va_start(vargs_list, msg);
+ log_msg(sht, LOG_WARNING, msg, vargs_list);
+ va_end(vargs_list);
+}
diff --git a/src/sht_log.h b/src/sht_log.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * 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 SHT_LOG_H
+#define SHT_LOG_H
+
+#include <rsys/rsys.h>
+
+#define MSG_INFO_PREFIX "Star-HITRAN:\x1b[1m\x1b[32minfo\x1b[0m: "
+#define MSG_ERROR_PREFIX "Star-HITRAN:\x1b[1m\x1b[31merror\x1b[0m: "
+#define MSG_WARNING_PREFIX "Star-HITRAN:\x1b[1m\x1b[33mwarning\x1b[0m: "
+
+struct sht;
+struct logger;
+
+extern LOCAL_SYM res_T
+setup_log_default
+ (struct sht* sht);
+
+/* Conditionally log a message on the LOG_OUTPUT stream of the sht logger,
+ * with respect to its verbose flag */
+extern LOCAL_SYM void
+log_info
+ (const struct sht* sht,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+/* Conditionally log a message on the LOG_ERROR stream of the sht logger,
+ * with respect to its verbose flag */
+extern LOCAL_SYM void
+log_err
+ (const struct sht* sht,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+/* Conditionally log a message on the LOG_WARNING stream of the sht logger,
+ * with respect to its verbose flag */
+extern LOCAL_SYM void
+log_warn
+ (const struct sht* sht,
+ const char* msg,
+ ...)
+#ifdef COMPILER_GCC
+ __attribute((format(printf, 2, 3)))
+#endif
+;
+
+
+#endif /* SHT_LOG_H */
+
diff --git a/src/test_shitran.c b/src/test_shitran.c
@@ -1,74 +0,0 @@
-/* Copyright (C) 2022 CNRS - LMD
- * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
- * Copyright (C) 2022 Université Paul Sabatier - IRIT
- * Copyright (C) 2022 Université Paul Sabatier - Laplace
- *
- * 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 "shitran.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 shitran* shitran;
- struct shitran_create_args args = SHITRAN_CREATE_ARGS_DEFAULT;
- (void)argc, (void)argv;
-
- CHK(shitran_create(NULL, &shitran) == RES_BAD_ARG);
- CHK(shitran_create(&args, NULL) == RES_BAD_ARG);
- CHK(shitran_create(&args, &shitran) == RES_OK);
-
- CHK(shitran_ref_get(NULL) == RES_BAD_ARG);
- CHK(shitran_ref_get(shitran) == RES_OK);
- CHK(shitran_ref_put(NULL) == RES_BAD_ARG);
- CHK(shitran_ref_put(shitran) == RES_OK);
- CHK(shitran_ref_put(shitran) == RES_OK);
-
- CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
- args.allocator = &allocator;
- args.verbose = 1;
- CHK(shitran_create(&args, &shitran) == RES_OK);
- CHK(MEM_ALLOCATED_SIZE(&allocator) != 0);
- CHK(shitran_ref_put(shitran) == 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;
- CHK(shitran_create(&args, &shitran) == RES_OK);
- CHK(shitran_ref_put(shitran) == RES_OK);
- args.allocator = NULL;
- CHK(shitran_create(&args, &shitran) == RES_OK);
- CHK(shitran_ref_put(shitran) == RES_OK);
-
- logger_release(&logger);
- CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
- mem_shutdown_proxy_allocator(&allocator);
- CHK(mem_allocated_size() == 0);
- return 0;
-}
diff --git a/src/test_sht.c b/src/test_sht.c
@@ -0,0 +1,74 @@
+/* Copyright (C) 2022 CNRS - LMD
+ * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com)
+ * Copyright (C) 2022 Université Paul Sabatier - IRIT
+ * Copyright (C) 2022 Université Paul Sabatier - Laplace
+ *
+ * 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 "sht.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 sht* sht;
+ struct sht_create_args args = SHT_CREATE_ARGS_DEFAULT;
+ (void)argc, (void)argv;
+
+ CHK(sht_create(NULL, &sht) == RES_BAD_ARG);
+ CHK(sht_create(&args, NULL) == RES_BAD_ARG);
+ CHK(sht_create(&args, &sht) == RES_OK);
+
+ CHK(sht_ref_get(NULL) == RES_BAD_ARG);
+ CHK(sht_ref_get(sht) == RES_OK);
+ CHK(sht_ref_put(NULL) == RES_BAD_ARG);
+ CHK(sht_ref_put(sht) == RES_OK);
+ CHK(sht_ref_put(sht) == RES_OK);
+
+ CHK(mem_init_proxy_allocator(&allocator, &mem_default_allocator) == RES_OK);
+ args.allocator = &allocator;
+ args.verbose = 1;
+ CHK(sht_create(&args, &sht) == RES_OK);
+ CHK(MEM_ALLOCATED_SIZE(&allocator) != 0);
+ CHK(sht_ref_put(sht) == 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;
+ CHK(sht_create(&args, &sht) == RES_OK);
+ CHK(sht_ref_put(sht) == RES_OK);
+ args.allocator = NULL;
+ CHK(sht_create(&args, &sht) == RES_OK);
+ CHK(sht_ref_put(sht) == RES_OK);
+
+ logger_release(&logger);
+ CHK(MEM_ALLOCATED_SIZE(&allocator) == 0);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHK(mem_allocated_size() == 0);
+ return 0;
+}