star-hitran

Load line-by-line data from the HITRAN database
git clone git://git.meso-star.com/star-hitran.git
Log | Files | Refs | README | LICENSE

commit 31f5415ad97b4553a015099dc634a63bbe1b8d9f
parent 0d1212b9bba3dfa7589772b0beca126530e1a852
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 26 Jun 2026 16:20:07 +0200

Merge branch 'release_0.1'

Diffstat:
MREADME.md | 7+++++++
Mconfig.mk | 2+-
Msrc/shtr.h | 6++++--
Msrc/shtr_isotope_metadata.c | 42+++++++++++++++++++++++++++---------------
Msrc/test_shtr_isotope_metadata.c | 18++++++++++++++++++
Msrc/test_shtr_molecule_id.c | 6++++++
6 files changed, 63 insertions(+), 18 deletions(-)

diff --git a/README.md b/README.md @@ -19,6 +19,13 @@ Edit config.mk as needed, then run: ## Release notes +### Version 0.1 + +- Add support for the molecules `H3+`, `CH3`, `S2`, `COFCl`, `HONO`, and + `ClNO2`. +- Fix a library crash that occurred when the metadata list contained + unrecognized molecules. + ### Version 0.0 - Initial version of the library for loading metadata and spectroscopic diff --git a/config.mk b/config.mk @@ -1,4 +1,4 @@ -VERSION = 0.0 +VERSION = 0.1 PREFIX = /usr/local BINPREFIX = $(PREFIX)/bin diff --git a/src/shtr.h b/src/shtr.h @@ -60,7 +60,8 @@ enum shtr_molecule_id { SHTR_HOBr, SHTR_C2H4, SHTR_CH3OH, SHTR_CH3Br, SHTR_CH3CN, SHTR_CF4, SHTR_C4H2, SHTR_HC3N, SHTR_H2, SHTR_CS, SHTR_SO3, SHTR_C2N2, SHTR_COCl2, SHTR_SO, SHTR_CH3F, SHTR_GeH4, SHTR_CS2, SHTR_CH3I, - SHTR_NF3, + SHTR_NF3, SHTR_H3plus, SHTR_CH3, SHTR_S2, SHTR_COFCl, SHTR_HONO, + SHTR_ClNO2, SHTR_MAX_MOLECULE_COUNT }; @@ -78,7 +79,8 @@ static const char* SHTR_MOLECULE_CSTR__[SHTR_MAX_MOLECULE_COUNT] = { "HOBr", "C2H4", "CH3OH", "CH3Br", "CH3CN", "CF4", "C4H2", "HC3N", "H2", "CS", "SO3", "C2N2", "COCl2", "SO", "CH3F", "GeH4", "CS2", "CH3I", - "NF3" + "NF3", "H3+", "CH3", "S2", "COFCl", "HONO", + "ClNO2" }; static INLINE const char* diff --git a/src/shtr_isotope_metadata.c b/src/shtr_isotope_metadata.c @@ -46,7 +46,8 @@ struct molecule { size_t isotopes_range[2]; /* Range of the [1st and last[ isotopes */ int id; /* Unique identifier of the molecule */ }; -#define MOLECULE_IS_VALID(Molecule) ((Molecule)->id >= 0) +#define MOLECULE_IS_VALID(Molecule) \ + (((Molecule)->id > 0) && ((Molecule)->id < SHTR_MAX_MOLECULE_COUNT)) static INLINE void molecule_clear(struct molecule* molecule) @@ -155,7 +156,6 @@ flush_molecule { size_t nisotopes = 0; size_t ientry = SIZE_MAX; - size_t* pimolecule = NULL; res_T res = RES_OK; ASSERT(metadata && molecule && MOLECULE_IS_VALID(molecule)); @@ -195,16 +195,9 @@ flush_molecule /* Register the molecule */ if(metadata->molid2idx[molecule->id] >= 0) { - const struct molecule* molecule2 = NULL; - molecule2 = darray_molecule_cdata_get(&metadata->molecules) + *pimolecule; - ERROR(metadata->shtr, - "%s: cannot register the %s molecule. " - "The %s molecule has the same identifier %i.\n", - txtrdr_get_name(txtrdr), - str_cget(&molecule->name), - str_cget(&molecule2->name), - molecule->id); - res = RES_OK; + ERROR(metadata->shtr, "%s: the molecule %s appears several times.\n", + txtrdr_get_name(txtrdr), str_cget(&molecule->name)); + res = RES_BAD_ARG; goto error; } ASSERT((size_t)((int)ientry) == ientry); @@ -246,7 +239,7 @@ parse_molecule res = str_set(&molecule->name, name); if(res != RES_OK) { ERROR(metadata->shtr, - "%s:%lu: error seting the molecule name `%s' -- %s.\n", + "%s:%lu: error setting the molecule name `%s' -- %s.\n", txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), name, res_to_cstr(res)); goto error; @@ -263,14 +256,33 @@ parse_molecule 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)) { + if(res != RES_OK) { id[len-1] = ')'; /* Re-add the trailing parenthesis */ - ERROR(metadata->shtr, "%s:%lu: invalid molecule identifier `%s'.\n", + ERROR(metadata->shtr, + "%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; } + if(!MOLECULE_IS_VALID(molecule)) { + ERROR(metadata->shtr, + "%s:%lu: the `%s (%d)' molecule is not supported.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + name, molecule->id); + res = RES_BAD_ARG; + goto error; + } + + if(strcmp(name, shtr_molecule_cstr(molecule->id))) { + ERROR(metadata->shtr, + "%s:%li: the molecule %d is named `%s' instead of `%s'.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + molecule->id, name, shtr_molecule_cstr(molecule->id)); + res = RES_BAD_ARG; + goto error; + } + tk = strtok_r(NULL, " \t", &tk_ctx); if(tk) { WARN(metadata->shtr, "%s:%lu: unexpected text `%s'.\n", diff --git a/src/test_shtr_isotope_metadata.c b/src/test_shtr_isotope_metadata.c @@ -559,6 +559,24 @@ test_load_failures(struct shtr* shtr) rewind(fp); CHK(shtr_isotope_metadata_load_stream(shtr, fp, NULL, &mdata) == RES_MEM_ERR); CHK(fclose(fp) == 0); + + /* Duplicate molecule */ + CHK(fp = tmpfile()); + fprintf(fp, "Molecule # Iso Abundance Q(296K) gj Molar Mass(g)\n"); + molecule_print(fp, &H2O); + molecule_print(fp, &H2O); + rewind(fp); + CHK(shtr_isotope_metadata_load_stream(shtr, fp, NULL, &mdata) == RES_BAD_ARG); + CHK(fclose(fp) == 0); + + /* Invalid molecule name */ + CHK(fp = tmpfile()); + fprintf(fp, "Comment line\n"); + fprintf(fp, "H_2O (1)\n"); + isotope_print(fp, &H2O_isotopes[0]); + rewind(fp); + CHK(shtr_isotope_metadata_load_stream(shtr, fp, NULL, &mdata) == RES_BAD_ARG); + CHK(fclose(fp) == 0); } static void diff --git a/src/test_shtr_molecule_id.c b/src/test_shtr_molecule_id.c @@ -79,6 +79,12 @@ id2cstr(const enum shtr_molecule_id id) case SHTR_CS2: cstr = "CS2"; break; case SHTR_CH3I: cstr = "CH3I"; break; case SHTR_NF3: cstr = "NF3"; break; + case SHTR_H3plus: cstr = "H3+"; break; + case SHTR_CH3: cstr = "CH3"; break; + case SHTR_S2: cstr = "S2"; break; + case SHTR_COFCl: cstr = "COFCl"; break; + case SHTR_HONO: cstr = "HONO"; break; + case SHTR_ClNO2: cstr = "ClNO2"; break; default: FATAL("Unreachable code\n"); break; } return cstr;