[hackers] [dmenu][RFC][PATCH 4/4] Add the updhist program

From: Silvan Jegen <s.jegen_AT_gmail.com>
Date: Fri, 27 Nov 2015 19:38:32 +0100

This program reads a command (or any character sequence) from stdin and
takes the path to the history file as an argument. The history file should
be empty or contain a list of commands each of which should be followed
by a tab character and a usage count. An example for a line in such a
history file is the following.

st 234

updhist reads a command from stdin, increases its count in the history
file, writes the file out again (overwriting the old one) and then writes
the command to stdout before exiting.
---
 updhist.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)
 create mode 100644 updhist.c
diff --git a/updhist.c b/updhist.c
new file mode 100644
index 0000000..8078b3e
--- /dev/null
+++ b/updhist.c
_AT_@ -0,0 +1,84 @@
+/* See LICENSE file for copyright and license details. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+static void
+usage(void)
+{
+	printf("usage: updhist historyfile\n");
+	exit(0);
+}
+
+static void
+update_hist_file(char* p, char* cmdname, size_t len)
+{
+	FILE *hist = NULL, *nhist = NULL;
+	char *tmpname;
+	char buf[BUFSIZ];
+	int ret, searching = 1;
+	long int count;
+	size_t fnlen;
+
+	if (!(hist = fopen(p, "r")))
+		die("Could not open history file: %s\n", p);
+
+	fnlen = strlen(p);
+	tmpname = malloc(fnlen+5);
+	strcpy(tmpname, p);
+	strcat(tmpname, ".tmp");
+	if (!(nhist = fopen(tmpname, "w")))
+		die("Could not open the history file to write: %s\n", p);
+
+	while (fscanf(hist, "%200s\t%ld", buf, &count) == 2) {
+		if (searching) {
+			searching = strcmp(buf, cmdname);
+			if (searching==0)
+				count++;
+		}
+
+		fprintf(nhist, "%s\t%lu\n", buf, count);
+	}
+	if (searching)
+		fprintf(nhist, "%s\t%d\n", cmdname, 1);
+
+	ret = feof(hist);
+	if (!ret)
+		die("Could not parse history file completely. Exiting.\n");
+
+	fclose(hist);
+	fclose(nhist);
+
+	ret = rename(tmpname, p);
+	if (ret)
+		die("Could not overwrite old history file with the new one. Exiting.\n");
+	free(tmpname);
+}
+
+int
+main(int argc, char *argv[])
+{
+	size_t n, len;
+	char stdinbuf[BUFSIZ];
+
+	if (argc < 2)
+		usage();
+
+	while ((n = fread(stdinbuf, 1, sizeof(stdinbuf), stdin))) {
+		if (fwrite(stdinbuf, 1, n, stdout) == n)
+			continue;
+		fprintf(stderr, "fwrite to stdout did not write all data. Wrote only %lu bytes.\n", n);
+	}
+	fclose(stdout);
+
+	len = strlen(stdinbuf);
+	if (len == 0)
+		return 1;
+
+	stdinbuf[--len] = '\0';
+	update_hist_file(argv[1], stdinbuf, len);
+
+	return 0;
+}
-- 
2.6.2
Received on Fri Nov 27 2015 - 19:38:32 CET

This archive was generated by hypermail 2.3.0 : Fri Nov 27 2015 - 19:48:22 CET