summaryrefslogtreecommitdiffstats
path: root/common/eurephia_cfgfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/eurephia_cfgfile.c')
-rw-r--r--common/eurephia_cfgfile.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/common/eurephia_cfgfile.c b/common/eurephia_cfgfile.c
new file mode 100644
index 0000000..ac47ee7
--- /dev/null
+++ b/common/eurephia_cfgfile.c
@@ -0,0 +1,152 @@
+/* eurephia_cfgfile.c
+ *
+ * Simple generic ini-style config file parser
+ *
+ * GPLv2 only - Copyright (C) 2011
+ * David Sommerseth <dazo@users.sourceforge.net>
+ *
+ * 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; version 2
+ * of the License.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/**
+ * @file eurephia_cfgfile.c
+ * @author David Sommerseth <dazo@users.sourceforge.net>
+ * @date 2011-07-23
+ *
+ * @brief A simple, generic ini-style config file parser
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <eurephia_nullsafe.h>
+#include <eurephia_context.h>
+#include <eurephia_log.h>
+#include <eurephia_values.h>
+
+
+/**
+ * Parse one single configuration line into a eurephiaVALUES key/value
+ * pair. It will also ignore comment lines, and also remove the
+ * comments on the line of the configuration line so that only the
+ * key/value information is extracted.
+ *
+ * @param line Input configuration line
+ *
+ * @return eurephiaVALUES pointer containing the parsed result. On
+ * error or if no valid config line was found, NULL is returned.
+ */
+static inline eurephiaVALUES *parse_config_line(eurephiaCTX *ctx, const char *line) {
+ char *cp = NULL, *key = NULL, *val = NULL, *ptr = NULL;
+ eurephiaVALUES *ret = NULL;
+
+ if( *line == '#' ) {
+ return NULL;
+ }
+
+ cp = strdup(line);
+ key = cp;
+ val = strpbrk(cp, "=");
+ if( val == NULL ) {
+ free_nullsafe(NULL, cp);
+ return NULL;
+ }
+ *val = '\0'; val++;
+
+ // Discard comments at the end of a line
+ if( (ptr = strpbrk(val, "#")) != NULL ) {
+ *ptr = '\0';
+ }
+
+ // Left trim
+ while( ((*key == 0x20) || (*key == 0x0A) || (*key == 0x0D)) ) {
+ key++;
+ }
+ while( ((*val == 0x20) || (*val == 0x0A) || (*val == 0x0D)) ) {
+ val++;
+ }
+
+ // Right trim
+ ptr = key + strlen_nullsafe(key) - 1;
+ while( ((*ptr == 0x20) || (*ptr == 0x0A) || (*ptr == 0x0D)) && (ptr > key) ) {
+ ptr--;
+ }
+ ptr++;
+ *ptr = '\0';
+
+ ptr = val + strlen_nullsafe(val) - 1;
+ while( ((*ptr == 0x20) || (*ptr == 0x0A) || (*ptr == 0x0D)) && (ptr > val) ) {
+ ptr--;
+ }
+ ptr++;
+ *ptr = '\0';
+
+ // Put key/value into a eurephiaVALUES struct and return it
+ ret = eCreate_value_space(ctx, 20);
+ ret->key = strdup(key);
+ ret->val = strdup(val);
+
+ free_nullsafe(ctx, cp);
+ return ret;
+}
+
+
+/**
+ * Parses a complete config file and puts it into an eurephiaVALUES
+ * key/value stack
+ *
+ * @param fname Complete file name with full path to the configuration
+ * file to parse
+ *
+ * @return Returns a pointer to an eurephiaVALUES stack containing the
+ * configuration on success, otherwise NULL.
+ */
+eurephiaVALUES *ecfg_ReadConfig(eurephiaCTX *ctx, const char *fname)
+{
+ FILE *fp = NULL;
+ char *buf = NULL;
+ eurephiaVALUES *cfg = NULL;
+ struct stat fi;
+
+ if( stat(fname, &fi) == -1 ) {
+ eurephia_log(ctx, LOG_CRITICAL, 0,
+ "Could not open the config file: %s\n", fname);
+ return NULL;
+ }
+
+ if( (fp = fopen(fname, "r")) == NULL ) {
+ eurephia_log(ctx, LOG_CRITICAL, 0,
+ "Could not open the config file: %s\n", fname);
+ return NULL;
+ }
+
+ buf = (char *) malloc_nullsafe(ctx, fi.st_size+2);
+
+ cfg = eCreate_value_space(ctx, 20);
+ while( fgets(buf, fi.st_size, fp) != NULL ) {
+ eurephiaVALUES *prm = parse_config_line(ctx, buf);
+ if( prm != NULL ) {
+ eAdd_valuestruct(ctx, cfg, prm);
+ }
+ };
+ free_nullsafe(ctx, buf);
+ fclose(fp); fp = NULL;
+
+ return cfg;
+}
+