diff libutil/dbread.c @ 27:ca8a6f95826a

implemented sws-card-lookup and underlying libutil functions
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 16 Mar 2021 23:22:37 +0000
parents
children fa81221ac9b6
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libutil/dbread.c	Tue Mar 16 23:22:37 2021 +0000
@@ -0,0 +1,110 @@
+/*
+ * This module implements functions for reading key=value database files.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include "dbread.h"
+
+static
+parse_read_line(dbs, filename_for_errs, lineno_for_errs)
+	struct dbread_state *dbs;
+	char *filename_for_errs;
+	int lineno_for_errs;
+{
+	unsigned n;
+	char *cp, *np;
+
+	n = 0;
+	for (cp = dbs->linebuf; ; ) {
+		while (isspace(*cp))
+			cp++;
+		if (!*cp)
+			break;
+		if (*cp == '=') {
+inv_syntax:		fprintf(stderr, "%s line %d: invalid syntax\n",
+				filename_for_errs, lineno_for_errs);
+			return(-1);
+		}
+		for (np = cp; ; cp++) {
+			if (*cp == '=')
+				break;
+			if (!*cp || isspace(*cp))
+				goto inv_syntax;
+		}
+		*cp++ = '\0';
+		if (n >= DBREAD_MAX_KV_PAIRS) {
+			fprintf(stderr,
+				"%s line %d: too many key=value pairs\n",
+				filename_for_errs, lineno_for_errs);
+			return(-1);
+		}
+		dbs->kv_pairs[n].key = np;
+		dbs->kv_pairs[n].value = cp;
+		n++;
+		while (*cp && !isspace(*cp))
+			cp++;
+		if (*cp)
+			*cp++ = '\0';
+	}
+	dbs->num_kv_pairs = n;
+	return(0);
+}
+
+char *
+dbread_find_key(dbs, sought_key)
+	struct dbread_state *dbs;
+	char *sought_key;
+{
+	unsigned n;
+
+	for (n = 0; n < dbs->num_kv_pairs; n++)
+		if (!strcasecmp(dbs->kv_pairs[n].key, sought_key))
+			return dbs->kv_pairs[n].value;
+	return 0;
+}
+
+dbread_find_record(filename, dbs, sought_key, sought_value)
+	char *filename, *sought_key, *sought_value;
+	struct dbread_state *dbs;
+{
+	FILE *inf;
+	int lineno;
+	char *cp;
+
+	inf = fopen(filename, "r");
+	if (!inf) {
+		perror(filename);
+		return(-1);
+	}
+	for (lineno = 1; fgets(dbs->linebuf, DBREAD_LINEBUF_SIZE, inf);
+	     lineno++) {
+		if (!index(dbs->linebuf, '\n')) {
+			fprintf(stderr,
+				"%s line %d: too long or missing newline\n",
+				filename, lineno);
+			fclose(inf);
+			return(-1);
+		}
+		if (parse_read_line(dbs, filename, lineno) < 0) {
+			/* error msg already printed */
+			fclose(inf);
+			return(-1);
+		}
+		cp = dbread_find_key(dbs, sought_key);
+		if (!cp)
+			continue;
+		if (strcmp(cp, sought_value))
+			continue;
+		/* found our record: struct dbread_state is our return */
+		fclose(inf);
+		return(0);
+	}
+	fclose(inf);
+	fprintf(stderr, "error: %s=%s not found in %s\n", sought_key,
+		sought_value, filename);
+	return(-1);
+}