aboutsummaryrefslogtreecommitdiff
path: root/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'read.c')
-rw-r--r--read.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/read.c b/read.c
new file mode 100644
index 0000000..e896863
--- /dev/null
+++ b/read.c
@@ -0,0 +1,114 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "read.h"
+#include "strbst.h"
+#include "nodelink.h"
+#include "ll.h"
+
+void consumespaces(FILE* file) {
+ int c;
+ while ( ( c = fgetc(file) ) != EOF && c != ' ' );
+ ungetc(c, file);
+}
+
+void wsclean(char* str, size_t sz) { //
+ bool nl = false;
+ if (str[sz] == '\n') {
+ sz--;
+ nl = true;
+ }
+ size_t i;
+ for (i = sz-1; i >= 0 && str[i] == ' '; i--);
+ if (nl) {
+ str[i+1] = '\n';
+ str[i+2] = 0;
+ } else {
+ str[i+1] = 0;
+ }
+
+}
+
+char* empty(void) {
+ char* str = malloc(sizeof(char));
+ *str = 0;
+ return str;
+}
+
+char* line(FILE* file) {
+ char* link = NULL;
+ size_t n;
+ getline(&link, &n, file);
+ wsclean(link, n);
+ if (*link == '\n') {
+ free(link);
+ link = empty();
+ }
+ return link;
+}
+
+link* insorget(strbst* tgt, char* name) {
+ link* get = query(tgt, name);
+ if (!(*get)) {
+ get = newlink(newnode());
+ insbst(tgt, name, get);
+ }
+ return get;
+}
+
+char* getdesc(FILE* file) {
+ int c;
+ size_t sz;
+ llnode *head, *tail;
+ head = tail = appendll(NULL, NULL);
+ while ( (c = getc()) != EOF && c != ':' && c != '-' ) {
+ tail = tail->next = appendll(tail, line());
+ sz += strlen(tail->str); // this should be traced but I haven't
+ }
+ if (c != EOF) ungetc(c, file);
+ tail = head->next; free(head);
+ char *out, *pos;
+ pos = out = malloc(sizeof(char)*(sz+1)); out[sz] = 0;
+ while (tail != NULL) {
+ size_t len = strlen(tail->str);
+ memcpy(pos, tail->str, len);
+ pos += len;
+ llnode* tmp = tail;
+ tail = tail->next;
+ free(tmp); free(tmp->str);
+ }
+ return pos;
+}
+
+node* readfile(char* name) {
+ FILE* read = fopen(name, "r");
+ node *root, *cur;
+ cur = root = newnode();
+ link* curl = insbst(root->links, name, root);
+ // getline
+ while ( ( int c = fgetc(read) ) != EOF ) {
+ switch (c) {
+ case ':':
+ consumespaces(file);
+ curl = insorget(root->links, line());
+ cur = curl->to;
+ break;
+
+ case '-':
+ consumespaces(file);
+ char* lname = line();
+ curl = insbst(cur->links, lname,
+ insorget(root->links, lname)->to);
+ break;
+
+ default:
+ ungetc(c, read);
+ curl->desc = getdesc();
+ break;
+ }
+ }
+ fclose(read);
+ return root;
+}