star-meteo

Time varying meteorological data
git clone git://git.meso-star.fr/star-meteo.git
Log | Files | Refs | README | LICENSE

commit 18f8bd5d5e3743e6d2f1925a1bc785c7427c0527
parent 15692dff7628ad536dea68e4465d81a4d5322bd9
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Fri, 16 May 2025 09:21:21 +0200

Add the smeteo utility

Loads a smeteo file and prints information about it. It checks both the
loading procedure and the validity of the loaded data with regard to the
smeteo file format.

Diffstat:
MMakefile | 34+++++++++++++++++++++++++++++++---
Msrc/smeteo.h | 4++--
Asrc/smeteo_main.c | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 189 insertions(+), 5 deletions(-)

diff --git a/Makefile b/Makefile @@ -23,7 +23,7 @@ LIBNAME_SHARED = libsmeteo.so LIBNAME = $(LIBNAME_$(LIB_TYPE)) default: library -all: default tests +all: default tests util ################################################################################ # Library @@ -68,6 +68,32 @@ libsmsh.o: $(OBJ) $(CC) $(CFLAGS_LIB) -c $< -o $@ ################################################################################ +# utils +################################################################################ +UTIL_SRC = src/smeteo_main.c +UTIL_OBJ = $(UTIL_SRC:.c=.o) +UTIL_DEP = $(UTIL_SRC:.c=.d) + +PKG_CONFIG_LOCAL = PKG_CONFIG_PATH="./:$${PKG_CONFIG_PATH}" $(PKG_CONFIG) +INCS_UTIL = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --cflags rsys smeteo-local) +LIBS_UTIL = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --libs rsys smeteo-local) + +CFLAGS_UTIL = $(CFLAGS_EXE) $(INCS_UTIL) +LDFLAGS_UTIL = $(LDFLAGS_EXE) $(LIBS_UTIL) + +util: library $(UTIL_DEP) + @$(MAKE) -fMakefile -f"$(UTIL_DEP)" smeteo + +smeteo: config.mk smeteo-local.pc $(UTIL_OBJ) + $(CC) $(CFLAGS_UTIL) -o $@ $(UTIL_OBJ) $(LDFLAGS_UTIL) + +$(UTIL_DEP): config.mk smeteo-local.pc + @$(CC) $(CFLAGS_UTIL) -MM -MT "$(@:.d=.o) $@" $(@:.d=.c) -MF $@ + +$(UTIL_OBJ): config.mk smeteo-local.pc + $(CC) $(CFLAGS_UTIL) -c $(@:.o=.c) -o $@ + +################################################################################ # Miscellaneous ################################################################################ pkg: @@ -84,7 +110,7 @@ smeteo-local.pc: smeteo.pc.in -e 's#@RSYS_VERSION@#$(RSYS_VERSION)#g'\ smeteo.pc.in > $@ -install: library pkg +install: library util pkg install() { mode="$$1"; prefix="$$2"; shift 2; \ mkdir -p "$${prefix}"; \ cp "$$@" "$${prefix}"; \ @@ -93,12 +119,14 @@ install: library pkg install 755 "$(DESTDIR)$(LIBPREFIX)" $(LIBNAME); \ install 644 "$(DESTDIR)$(LIBPREFIX)/pkgconfig" smeteo.pc; \ install 644 "$(DESTDIR)$(INCPREFIX)/star" src/smeteo.h; \ + install 755 "$(DESTDIR)$(BINPREFIX)/" smeteo; \ install 644 "$(DESTDIR)$(PREFIX)/share/doc/star-meteo" COPYING README.md uninstall: rm -f "$(DESTDIR)$(LIBPREFIX)/$(LIBNAME)" rm -f "$(DESTDIR)$(LIBPREFIX)/pkgconfig/smeteo.pc" rm -f "$(DESTDIR)$(INCPREFIX)/star/smeteo.h" + rm -f "$(DESTDIR)$(BINPREFIX)/smeteo" rm -f "$(DESTDIR)$(PREFIX)/share/doc/star-meteo/COPYING" rm -f "$(DESTDIR)$(PREFIX)/share/doc/star-meteo/README.md" @@ -107,6 +135,7 @@ lint: clean: clean_test rm -f $(DEP) $(OBJ) $(LIBNAME) + rm -f $(UTIL_DEP) $(UTIL_OBJ) smeteo rm -f .config libsmeteo.o smeteo.pc smeteo-local.pc ################################################################################ @@ -117,7 +146,6 @@ TEST_OBJ = $(TEST_SRC:.c=.o) TEST_DEP = $(TEST_SRC:.c=.d) TEST_TGT = $(TEST_SRC:.c=.t) -PKG_CONFIG_LOCAL = PKG_CONFIG_PATH="./:$${PKG_CONFIG_PATH}" $(PKG_CONFIG) INCS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --cflags rsys smeteo-local.pc) LIBS_TEST = $$($(PKG_CONFIG_LOCAL) $(PCFLAGS) --libs rsys smeteo-local.pc) diff --git a/src/smeteo.h b/src/smeteo.h @@ -57,7 +57,7 @@ struct smeteo_desc { const struct smeteo_entry* entries; size_t nentries; }; -#define SMETEO_DESC_NULL__ {NULL, NULL, 0} +#define SMETEO_DESC_NULL__ {NULL,NULL,0} static const struct smeteo_desc SMETEO_DESC_NULL = SMETEO_DESC_NULL__; struct smeteo_create_args { @@ -65,7 +65,7 @@ struct smeteo_create_args { struct mem_allocator* allocator; /* NULL <=> use default allocator */ int verbose; /* Verbosity level */ }; -#define SMETEO_CREATE_ARGS_DEFAULT__ {NULL, NULL, 0} +#define SMETEO_CREATE_ARGS_DEFAULT__ {NULL,NULL,0} static const struct smeteo_create_args SMETEO_CREATE_ARGS_DEFAULT = SMETEO_CREATE_ARGS_DEFAULT__; diff --git a/src/smeteo_main.c b/src/smeteo_main.c @@ -0,0 +1,156 @@ +/* Copyright (C) 2025 |Méso|Star> (contact@meso-star.com) + * + * This program is free software: you can redismeteobute 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 dismeteobuted 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 /* getopt support */ + +#include "smeteo.h" + +#include <rsys/mem_allocator.h> + +#include <stdio.h> +#include <unistd.h> /* getopt */ + +struct args { + const char* filename; /* Path toward the file storing meteo data */ + int verbose; /* Verbosity level */ + int quit; +}; +static const struct args ARGS_DEFAULT = {NULL, 0, 0}; + +struct cmd { + struct args args; + struct smeteo* smeteo; +}; +static const struct cmd CMD_NULL = {0}; + +/******************************************************************************* + * Helper functions + ******************************************************************************/ +static INLINE void +usage(FILE* stream) +{ + fprintf(stream, "usage: smeteo [-hv] [file]\n"); +} + +static res_T +args_init(struct args* args, int argc, char** argv) +{ + int opt = 0; + res_T res = RES_OK; + + *args = ARGS_DEFAULT; + + while((opt = getopt(argc, argv, "hv")) != -1) { + switch(opt) { + case 'h': + usage(stdout); + args->quit = 1; + goto exit; + case 'v': args->verbose += (args->verbose < 3); break; + default: res = RES_BAD_ARG; + } + if(res != RES_OK) goto error; + } + + args->filename = optind < argc ? argv[optind] : NULL; + +exit: + return res; +error: + usage(stderr); + goto exit; +} + +static INLINE void +cmd_release(struct cmd* cmd) +{ + if(cmd->smeteo) SMETEO(ref_put(cmd->smeteo)); +} + +static res_T +cmd_init(struct cmd* cmd, const struct args* args) +{ + struct smeteo_create_args smeteo_args = SMETEO_CREATE_ARGS_DEFAULT; + res_T res = RES_OK; + ASSERT(cmd && args); + + cmd->args = *args; + + smeteo_args.verbose = args->verbose; + res = smeteo_create(&smeteo_args, &cmd->smeteo); + if(res != RES_OK) goto error; + +exit: + return res; +error: + cmd_release(cmd); + goto exit; +} + +static INLINE void +print_info(struct cmd* cmd) +{ + struct smeteo_desc desc = SMETEO_DESC_NULL; + ASSERT(cmd); + + SMETEO(get_desc(cmd->smeteo, &desc)); + printf("%lu %s\n", desc.nentries, desc.filename); +} + +static res_T +cmd_run(struct cmd* cmd) +{ + res_T res = RES_OK; + ASSERT(cmd); + + if(cmd->args.filename) { + res = smeteo_load(cmd->smeteo, cmd->args.filename); + } else { + res = smeteo_load_stream(cmd->smeteo, stdin, "stdin"); + } + if(res != RES_OK) goto error; + + print_info(cmd); + +exit: + return res; +error: + goto exit; +} + +/******************************************************************************* + * The program + ******************************************************************************/ +int +main(int argc, char** argv) +{ + struct args args = ARGS_DEFAULT; + struct cmd cmd = CMD_NULL; + int err = 0; + res_T res = RES_OK; + + if((res = args_init(&args, argc, argv)) != RES_OK) goto error; + if(args.quit) goto exit; + + if((res = cmd_init(&cmd, &args)) != RES_OK) goto error; + if((res = cmd_run(&cmd)) != RES_OK) goto error; +exit: + cmd_release(&cmd); + CHK(mem_allocated_size() == 0); + return err; +error: + err = 1; + goto exit; +}