aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ankarström <john@ankarstrom.se>2020-11-10 21:21:20 +0100
committerJohn Ankarström <john@ankarstrom.se>2020-11-10 21:21:20 +0100
commit89304337fba2cda5a823bbfd724a5bc572ea34dd (patch)
tree7722fb8647873135986fe2530181e03753f8e868
downloadrf-89304337fba2cda5a823bbfd724a5bc572ea34dd.tar.gz
first commit
-rw-r--r--rf.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/rf.c b/rf.c
new file mode 100644
index 0000000..6067373
--- /dev/null
+++ b/rf.c
@@ -0,0 +1,120 @@
+#include <ctype.h>
+#include <err.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define DEFMAX 300
+
+struct ref {
+ char *a;
+ char *y;
+ char *t;
+ char *q;
+ char *d;
+ char *c;
+ char *p;
+ char *w;
+};
+
+char format_extra[DEFMAX+1];
+char format_full[DEFMAX+1];
+char format_list[DEFMAX+1];
+int refs_s;
+struct ref *refs;
+
+void record(char *dest) {
+ char c;
+ int i;
+ i = 0;
+ while (read(STDIN_FILENO, &c, 1) != 0 && isspace(c))
+ ;
+ while (read(STDIN_FILENO, &c, 1) != 0)
+ dest[i++] = c;
+ dest[i] = '\0';
+}
+
+int main() {
+ char c, *buf, last[4];
+ int i, buf_s, ref_i;
+
+ buf_s = 200;
+ buf = malloc((buf_s+1) * sizeof(char));
+ if (buf == NULL) err(1, "malloc");
+
+#define reset(n) do { \
+ strncpy(last, " ", 4); \
+ i =- n; \
+ buf[i] = '\0'; \
+} while (0)
+
+ i = 0;
+ ref_i = -1;
+
+next:
+ while (read(STDIN_FILENO, &c, 1) != 0) {
+ if (strncmp(last, "\n.F", 3) != 0)
+ goto ref;
+
+ /* record format def */
+ switch (last[4]) {
+ case 'f':
+ record(format_full);
+ break;
+ case 'x':
+ record(format_extra);
+ break;
+ case 'l':
+ record(format_list);
+ break;
+ default:
+ goto add;
+ }
+ reset(3);
+ goto next;
+
+ref:
+ if (strncmp(last, "\n.R", 3) != 0)
+ goto add;
+
+ /* record reference def */
+ switch(last[4]) {
+ case 'a':
+ reset(3);
+ if (ref_i+1 > refs_s) {
+ refs_s += 10;
+ refs = realloc(refs, refs_s*sizeof(struct ref));
+ if (refs == NULL) err(1, "realloc");
+ }
+ ref_i++;
+ refs[ref_i].a = malloc((DEFMAX+1) * sizeof(char));
+ if (refs[ref_i].a == NULL) err(1, "malloc");
+ record(refs[ref_i].a);
+ break;
+ case 'y':
+ break;
+ default:
+ goto add;
+ }
+ reset(3);
+ goto next;
+
+add:
+ /* add to buffer */
+ if (i+1 > buf_s) {
+ buf_s += 100;
+ buf = realloc(buf, (buf_s+1) * sizeof(char));
+ if (buf == NULL) err(1, "realloc");
+ }
+ buf[i++] = c;
+
+ /* keep track of last 4 characters */
+ if (i <= 4) last[i] = c;
+ else {
+ memmove(last, last+1, 3);
+ last[3] = c;
+ }
+ }
+}