From 56f5fcd2db656be984ec0ccc78af219ec0b3d4ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= <tomasz.wlostowski@cern.ch> Date: Mon, 5 Nov 2018 22:40:26 +0100 Subject: [PATCH] libwr: config parser for Low Phase Noise Calibration (writable & without global vars) NOTE: consider merging with dot-config.c --- userspace/libwr/Makefile | 2 +- userspace/libwr/config-lpcalib.c | 220 ++++++++++++++++++ .../libwr/include/libwr/config-lpcalib.h | 17 ++ 3 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 userspace/libwr/config-lpcalib.c create mode 100644 userspace/libwr/include/libwr/config-lpcalib.h diff --git a/userspace/libwr/Makefile b/userspace/libwr/Makefile index d3ae6145d..037ae9aaf 100644 --- a/userspace/libwr/Makefile +++ b/userspace/libwr/Makefile @@ -6,7 +6,7 @@ OBJS = init.o fpga_io.o util.o pps_gen.o i2c.o shw_io.o i2c_bitbang.o \ i2c_fpga_reg.o pio.o libshw_i2c.o i2c_sfp.o fan.o i2c_io.o hwiu.o \ ptpd_netif.o hal_client.o hal_minirpc.o\ shmem.o rt_client.o \ - dot-config.o wrs-msg.o \ + dot-config.o config-lpcalib.o wrs-msg.o \ mac.o \ timeout.o diff --git a/userspace/libwr/config-lpcalib.c b/userspace/libwr/config-lpcalib.c new file mode 100644 index 000000000..0f21cbd28 --- /dev/null +++ b/userspace/libwr/config-lpcalib.c @@ -0,0 +1,220 @@ +/* + * White Rabbit parser for Low Phase Drift Calibration configuration + * Copyright (C) 2018, CERN. + * + * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch> + * + * Description: re-written parser for configuration file. It allows + * to simultaneously read/write few files. + * + * NOTE: consider merging this with dot-config.c + * + * 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 + * 2 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 <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <libwr/config-lpcalib.h> + +struct key_value +{ + char *comment; + char *key; + char *value; + struct key_value *next; +}; + +struct config_file +{ + struct key_value *head; +}; + +static struct key_value *cfg_find_key(struct config_file *cfg, const char *key, int create) +{ + struct key_value *kv = cfg->head, *kv_prev = cfg->head; + + while (kv) + { + if (kv->key && !strcasecmp(key, kv->key)) + { + return kv; + } + kv_prev = kv; + kv = kv->next; + } + + if (!create) + return NULL; + + if (!cfg->head) + { + cfg->head = malloc(sizeof(struct key_value)); + kv = cfg->head; + } + else + { + kv_prev->next = malloc(sizeof(struct key_value)); + kv = kv_prev->next; + } + + kv->key = strdup(key); + kv->value = NULL; + kv->comment = NULL; + kv->next = NULL; + + return kv; +} + +int cfg_get_int(struct config_file *cfg, const char *key, int *value) +{ + struct key_value *kv = cfg_find_key(cfg, key, 0); + + if (!kv) + return 0; + + *value = atoi(kv->value); + return 1; +} + +struct config_file *cfg_load(const char *filename, int overwrite) +{ + FILE *f = fopen(filename, "rb"); + if (!f) + { + + if (overwrite) + { + struct config_file *cfg = malloc(sizeof(struct config_file)); + + f = fopen(filename, "wb"); + + cfg->head = NULL; + + return cfg; + } + return NULL; + } + + struct config_file *cfg = malloc(sizeof(struct config_file)); + + cfg->head = NULL; + + while (!feof(f)) + { + char str[1024]; + int rv = (int)fgets(str, 1024, f); + int i, pos = -1; + + if (rv == 0) + break; + + for (i = 0; i < strlen(str); i++) + { + if (str[i] == '=' && pos < 0) + pos = i; + if (str[i] == '\n' || str[i] == '\r') + str[i] = 0; + } + + struct key_value *kv = malloc(sizeof(struct key_value)); + if (pos < 0 || strlen(str) == 0 || str[0] == '#') + { + kv->comment = strdup(str); + kv->key = NULL; + kv->value = NULL; + } + else + { + kv->comment = NULL; + kv->key = strndup(str, pos); + kv->value = strdup(str + pos + 1); + kv->next = NULL; + } + + if (!cfg->head) + { + cfg->head = kv; + } + else + { + struct key_value *last = cfg->head; + while (last->next) + last = last->next; + last->next = kv; + } + } + + return cfg; +} + +int cfg_set_int(struct config_file *cfg, const char *key, int value) +{ + struct key_value *kv = cfg_find_key(cfg, key, 1); + + if (!kv) + return 0; + + char buf[1024]; + snprintf(buf, 1024, "%d", value); + + kv->value = strdup(buf); + return 1; +} + +int cfg_save(struct config_file *cfg, const char *filename) +{ + FILE *f = fopen(filename, "wb"); + + if (!f) + { + printf("Can't open '%s' for writing.\n", filename); + return -1; + } + + struct key_value *kv = cfg->head; + + while (kv) + { + if (kv->comment) + fprintf(f, "%s\n", kv->comment); + else + fprintf(f, "%s=%s\n", kv->key, kv->value); + + kv = kv->next; + } + + fclose(f); + return 0; +} + +void cfg_close(struct config_file *cfg) +{ + struct key_value *kv = cfg->head; + + while (kv) + { + if (kv->comment) + free(kv->comment); + if (kv->key) + free(kv->key); + if (kv->value) + free(kv->value); + struct key_value *ptr = kv; + kv = kv->next; + free(ptr); + } +} diff --git a/userspace/libwr/include/libwr/config-lpcalib.h b/userspace/libwr/include/libwr/config-lpcalib.h new file mode 100644 index 000000000..734fc15dc --- /dev/null +++ b/userspace/libwr/include/libwr/config-lpcalib.h @@ -0,0 +1,17 @@ +#ifndef __LIBWR_CONFIG2_H__ +#define __LIBWR_CONFIG2_H__ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +struct config_file; + +int cfg_get_int(struct config_file *cfg, const char *key, int *value); +struct config_file *cfg_load(const char *filename, int overwrite); +int cfg_set_int(struct config_file *cfg, const char *key, int value); +int cfg_save(struct config_file *cfg, const char *filename); +void cfg_free(struct config_file *cfg); + +#endif /* __LIBWR_CONFIG2_H__ */ + -- GitLab