]> git.scottworley.com Git - uniqt/commitdiff
Begin
authorScott Worley <scottworley@scottworley.com>
Fri, 15 Sep 2023 00:52:51 +0000 (17:52 -0700)
committerScott Worley <scottworley@scottworley.com>
Fri, 15 Sep 2023 02:46:38 +0000 (19:46 -0700)
Makefile [new file with mode: 0644]
uniqt.c [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..a18dfa6
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,17 @@
+prefix = /usr/local
+bindir = $(prefix)/bin
+INSTALL = install
+
+uniqt:
+
+%: %.c
+       $(CC) -Wall -Wextra -std=c99 -o $@ $^
+
+.PHONY: install
+install: uniqt
+       $(INSTALL) -d $(DESTDIR)$(bindir)
+       $(INSTALL) -m 755 $^ $(DESTDIR)$(bindir)
+
+.PHONY: clean
+clean:
+       -rm uniqt
diff --git a/uniqt.c b/uniqt.c
new file mode 100644 (file)
index 0000000..2b7d229
--- /dev/null
+++ b/uniqt.c
@@ -0,0 +1,84 @@
+#define _POSIX_C_SOURCE 199309L
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+void die(const char *message) {
+  fputs(message, stderr);
+  fputc('\n', stderr);
+  exit(1);
+}
+
+void die_err(const char *message) {
+  perror(message);
+  exit(1);
+}
+
+char *encode_time(time_t t) {
+  struct tm tm;
+  localtime_r(&t, &tm);
+  const size_t size = 20;
+  char *out = (char *)malloc(size);
+  if (strftime(out, size, "%Y %m %d %H %M %S", &tm) != size - 1)
+    die("Couldn't format time");
+  return out;
+}
+
+typedef struct {
+  time_t start, end;
+} time_range_t;
+
+const time_t NULL_TIME = (time_t)-1;
+
+static time_range_t make_time_range(time_t t) { return (time_range_t){t, t}; }
+
+static void extend_time_range(time_range_t *r, time_t t) { r->end = t; }
+
+static char *read_line() {
+  char *line = NULL;
+  int scanf_ret = scanf("%m[^\n]", &line);
+  if (scanf_ret == EOF && ferror(stdin))
+    die_err("Error reading");
+  int newline = getchar();
+  if (newline != EOF && newline != (int)'\n')
+    die("Expected newline");
+  return line;
+}
+
+static void write_line(time_range_t *range, char *line) {
+  if (line == NULL)
+    return;
+  if (printf("%ld %ld %s\n", range->start, range->end, line) < 0)
+    die("Couldn't write");
+}
+
+static int same(char *a, char *b) { return a && b && strcmp(a, b) == 0; }
+
+static void uniqt() {
+  char *current_line = NULL;
+  time_range_t current_time_range = make_time_range(NULL_TIME);
+  for (;;) {
+    char *new_line = read_line();
+    if (new_line == NULL)
+      break;
+    time_t now = time(NULL);
+    if (same(current_line, new_line)) {
+      free(new_line);
+      extend_time_range(&current_time_range, now);
+    } else {
+      write_line(&current_time_range, current_line);
+      free(current_line);
+      current_line = new_line;
+      current_time_range = make_time_range(now);
+    }
+  }
+  write_line(&current_time_range, current_line);
+  free(current_line);
+}
+
+int main() {
+  uniqt();
+  return 0;
+}