commit eb3c0123f187e0ef6696c8f1d74994fe5c162e74
Author: Charlie Stanton <charlie@shtanton.xyz>
Date: Wed, 17 Aug 2022 12:45:19 +0100
Initial commit
Implements version 0.1.0 of roundrobin
Diffstat:
3 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+bin
diff --git a/Makefile b/Makefile
@@ -0,0 +1,9 @@
+PROGRAMS=roundrobin
+BINARIES=$(patsubst %, bin/%, $(PROGRAMS))
+
+all: $(BINARIES)
+
+bin/%: src/%.c
+ $(CC) $(CFLAGS) $^ -o $@
+
+.PHONY: all
diff --git a/src/roundrobin.c b/src/roundrobin.c
@@ -0,0 +1,101 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+struct {
+ size_t length;
+ size_t capacity;
+ FILE **writers;
+} outputs;
+
+void append_output(FILE *writer) {
+ if (outputs.length >= outputs.capacity) {
+ outputs.capacity *= 2;
+ outputs.writers = realloc(outputs.writers, outputs.capacity * sizeof(FILE **));
+ if (outputs.writers == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ exit(1);
+ }
+ }
+ outputs.writers[outputs.length++] = writer;
+}
+
+int main(int argc, char *argv[]) {
+ int c;
+ size_t output_index = 0;
+ char separator = '\n';
+ FILE *writer;
+
+ outputs.length = 0;
+ outputs.capacity = 4;
+ outputs.writers = malloc(4 * sizeof(FILE **));
+ if (outputs.writers == NULL) {
+ fprintf(stderr, "Out of memory\n");
+ return 1;
+ }
+
+ if (argc <= 1) {
+ fprintf(stderr, "Missing output files\n");
+ return 1;
+ }
+
+ size_t i;
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] != '-') {
+ fprintf(stderr, "Expected flag, found: \"%s\"\n", argv[i]);
+ return 1;
+ }
+
+ if (argv[i][1] != '\0' && argv[i][2] != '\0') {
+ fprintf(stderr, "Invalid flag: \"%s\"", argv[i]);
+ return 1;
+ }
+
+ switch (argv[i][1]) {
+ case 'e':
+ if (++i >= argc) {
+ fprintf(stderr, "Missing file after -f\n");
+ return 1;
+ }
+ writer = popen(argv[i], "w");
+ if (writer == NULL) {
+ fprintf(stderr, "Error running command: %s\n", argv[i]);
+ return 1;
+ }
+ append_output(writer);
+ break;
+ case 'f':
+ if (++i >= argc) {
+ fprintf(stderr, "Missing file after -f\n");
+ return 1;
+ }
+ writer = fopen(argv[i], "w");
+ if (writer == NULL) {
+ fprintf(stderr, "Error opening file %s\n", argv[i]);
+ return 1;
+ }
+ append_output(writer);
+ break;
+ default:
+ fprintf(stderr, "Invalid flag: \"%s\"\n", argv[i]);
+ return 1;
+ }
+ }
+
+ for (;;) {
+ c = getchar();
+ if (c == EOF) {
+ break;
+ }
+
+ if (fputc(c, outputs.writers[output_index]) == EOF) {
+ fprintf(stderr, "Error writing to output %lu\n", output_index);
+ return 1;
+ }
+
+ if (c == separator) {
+ fflush(outputs.writers[output_index]);
+ output_index++;
+ output_index %= outputs.length;
+ }
+ }
+}