From 874c46705a0c8592d621de90cc01d36c5b0b18af Mon Sep 17 00:00:00 2001 From: nirenjan Date: Mon, 9 Aug 2021 22:16:30 -0700 Subject: [PATCH] Add config save routines --- daemon/Makefile.am | 1 + daemon/x52d_config.c | 15 ++++ daemon/x52d_config.h | 5 +- daemon/x52d_config_dump.c | 162 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 daemon/x52d_config_dump.c diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 9fd989f..479a37c 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -9,6 +9,7 @@ bin_PROGRAMS += x52d x52d_SOURCES = \ daemon/x52d_main.c \ daemon/x52d_config_parser.c \ + daemon/x52d_config_dump.c \ daemon/x52d_config.c \ daemon/x52d_device.c \ daemon/x52d_clock.c \ diff --git a/daemon/x52d_config.c b/daemon/x52d_config.c index 193e837..7d9e12f 100644 --- a/daemon/x52d_config.c +++ b/daemon/x52d_config.c @@ -40,6 +40,21 @@ void x52d_config_load(const char *cfg_file) } } +void x52d_config_save(const char *cfg_file) +{ + int rc; + + if (cfg_file == NULL) { + cfg_file = X52D_SYS_CFG_FILE; + } + + rc = x52d_config_save_file(&x52d_config, cfg_file); + if (rc != 0) { + PINELOG_ERROR(_("Error %d saving configuration file: %s"), + rc, strerror(rc)); + } +} + /* Callback stubs * TODO: Remove the ones below when their implementation is complete */ diff --git a/daemon/x52d_config.h b/daemon/x52d_config.h index 416a72f..ac4975a 100644 --- a/daemon/x52d_config.h +++ b/daemon/x52d_config.h @@ -35,7 +35,7 @@ struct x52d_config { // the length in the following declaration. libx52_led_state leds[21]; - uint16_t brightness[2]; + int brightness[2]; bool clutch_enabled; bool clutch_latched; @@ -83,4 +83,7 @@ void x52d_config_clear_overrides(void); void x52d_config_load(const char *cfg_file); void x52d_config_apply(void); +int x52d_config_save_file(struct x52d_config *cfg, const char *cfg_file); +void x52d_config_save(const char *cfg_file); + #endif // !defined X52D_CONFIG_H diff --git a/daemon/x52d_config_dump.c b/daemon/x52d_config_dump.c new file mode 100644 index 0000000..7569233 --- /dev/null +++ b/daemon/x52d_config_dump.c @@ -0,0 +1,162 @@ +/* + * Saitek X52 Pro MFD & LED driver - Configuration dumper + * + * Copyright (C) 2021 Nirenjan Krishnan (nirenjan@nirenjan.org) + * + * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 + */ + +#include "config.h" +#include +#include +#include +#include +#include +#include + +#include "pinelog.h" +#include "libx52.h" +#include "x52d_config.h" +#include "x52d_const.h" + +static char *current_section = NULL; + +// Print the current section to the file +static void print_section(FILE *cfg, const char *section) +{ + if (current_section == NULL || strcasecmp(current_section, section)) { + if (current_section != NULL) { + free(current_section); + } + + current_section = strdup(section); + PINELOG_TRACE("Printing section header %s", section); + + fprintf(cfg, "[%s]\n", section); + } +} + +// Create a pointer "name" of type "type", which stores the value of the +// corresponding element within the config struct. +#define CONFIG_PTR(type, name) type name = (type)((uintptr_t)cfg + offset) + +// Check if the parameters are all valid +#define CHECK_PARAMS() do { if (cfg == NULL || section == NULL || key == NULL) { return EINVAL; } } while(0) + +static int bool_dumper(FILE *file, const char *section, const char *key, const struct x52d_config *cfg, size_t offset) +{ + CONFIG_PTR(bool *, config); + CHECK_PARAMS(); + + print_section(file, section); + PINELOG_TRACE("Printing bool value %s.%s from offset %lu value = %d", + section, key, offset, *config); + fprintf(file, "%s = %s\n", key, *config ? "true" : "false"); + + return 0; +} + +static int string_dumper(FILE *file, const char *section, const char *key, struct x52d_config *cfg, size_t offset) +{ + CONFIG_PTR(char *, config); + CHECK_PARAMS(); + + print_section(file, section); + PINELOG_TRACE("Printing string value %s.%s from offset %lu value = %s", + section, key, offset, config); + fprintf(file, "%s = %s\n", key, config); + + return 0; +} + +static int int_dumper(FILE *file, const char *section, const char *key, struct x52d_config *cfg, size_t offset) +{ + CONFIG_PTR(int *, config); + CHECK_PARAMS(); + + print_section(file, section); + PINELOG_TRACE("Printing int value %s.%s from offset %lu value = %d", + section, key, offset, *config); + fprintf(file, "%s = %d\n", key, *config); + + return 0; +} + +static int led_dumper(FILE *file, const char *section, const char *key, struct x52d_config *cfg, size_t offset) +{ + CONFIG_PTR(libx52_led_state *, config); + CHECK_PARAMS(); + + print_section(file, section); + PINELOG_TRACE("Printing led value %s.%s from offset %lu value = %d", + section, key, offset, *config); + fprintf(file, "%s = %s\n", key, libx52_led_state_to_str(*config)); + + return 0; +} + +static int clock_format_dumper(FILE *file, const char *section, const char *key, struct x52d_config *cfg, size_t offset) +{ + CONFIG_PTR(libx52_clock_format *, config); + CHECK_PARAMS(); + + print_section(file, section); + PINELOG_TRACE("Printing clock format value %s.%s from offset %lu value = %d", + section, key, offset, *config); + fprintf(file, "%s = %s\n", key, libx52_clock_format_to_str(*config)); + + return 0; +} + +static int date_format_dumper(FILE *file, const char *section, const char *key, struct x52d_config *cfg, size_t offset) +{ + CONFIG_PTR(libx52_date_format *, config); + CHECK_PARAMS(); + + print_section(file, section); + PINELOG_TRACE("Printing date format value %s.%s from offset %lu value = %d", + section, key, offset, *config); + fprintf(file, "%s = %s\n", key, libx52_date_format_to_str(*config)); + + return 0; +} + +#undef CHECK_PARAMS +#undef CONFIG_PTR + +int x52d_config_save_file(struct x52d_config *cfg, const char *cfg_file) +{ + int rc; + FILE *cfg_fp; + if (cfg == NULL || cfg_file == NULL) { + return EINVAL; + } + + if (current_section) { + free(current_section); + } + current_section = NULL; + + cfg_fp = fopen(cfg_file, "w"); + if (cfg_fp == NULL) { + rc = errno; + PINELOG_ERROR(_("Unable to save config file %s - code %d: %s"), + cfg_file, rc, strerror(rc)); + return rc; + } + + PINELOG_TRACE("Saving configuration to file %s", cfg_file); + #define CFG(section, key, name, type, def) do { \ + PINELOG_TRACE("Dumping " #section "." #key " to file %s", cfg_file); \ + rc = type ## _dumper(cfg_fp, #section, #key, cfg, offsetof(struct x52d_config, name)); \ + if (rc) { \ + PINELOG_ERROR(_("Failed to dump %s.%s to config file %s - code %d: %s"), \ + #section, #key, cfg_file, rc, strerror(rc)); \ + return rc; \ + } \ + } while (0); + #include "x52d_config.def" + + return 0; +} +