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:
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;
+}