#include #include #include #include #include "read.h" #include "strbst.h" #include "nodelink.h" #include "ll.h" static void consumespaces(FILE* file) { // used to consume spaces in an item ("- list item" -> "list item") int c; while ( ( c = fgetc(file) ) != EOF && c == ' ' ); ungetc(c, file); } static void wsclean(char* txt, size_t sz){ // "string\n \n" -> "string" size_t i; for (i = sz; i > 0; i--) { // start at end [i-1] and dec // break on non-nl, non-space char if (txt[i-1] != ' ' && txt[i-1] != '\n') break; } txt[i] = 0; // finish string } static char* empty(void) { // "" with a freeable memory address char* str = malloc(sizeof(char)); *str = 0; return str; } static char* getline(size_t* n, FILE* file) { size_t sz = 100; *n = 0; int c; char* out = malloc(sizeof(char)*100); while ( (c = fgetc(file)) != EOF ) { if (*n == sz) out = realloc(out, sizeof(char) * (sz *= 2)); out[*n] = c; (*n)++; if (c == '\n') break; } out[(*n)] = 0; //(*n)++; return realloc(out, sizeof(char) * (*n+1) ); } static char* line(FILE* file) { // gets a line from file size_t n; char* link = getline(&n, file); // getline stores a line of size n in link wsclean(link, n); // removes trailing whitespace if (*link == '\n') { // empty line treated as "" free(link); char* out = empty(); // DEBGUGU return out; } else { // else return obtained return link; } } static link* insorget(strbst* tgt, char* name) { link* get = query(tgt, name); if (!get) { get = newlink(newnode()); insbst(tgt, name, get); } return get; } static link* addbstlink(strbst* tree, char* name, node* to) { link* l = newlink(to); insbst(tree, name, l); return l; } static char* resolvell(llnode* tail, size_t sz) { 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->str); free(tmp); } return out; } node* readfile(char* name) { FILE* read = fopen(name, "r"); node *root, *cur; cur = root = newnode(); link* curl = addbstlink(root->links, "root", root); llnode start; start.next = NULL; // empty desc isn't undefined llnode *head, *tail; head = tail = &start; size_t sz = 0; int c; while ( ( c = fgetc(read) ) != EOF ) { if (c == ':' || c == '-') { curl->desc = resolvell(head->next, sz); head->next = NULL; tail = head; sz = 0; consumespaces(read); } switch (c) { case ':': curl = insorget(root->links, line(read)); cur = curl->to; break; case '-': ; char* lname = line(read); node* at = insorget(root->links, lname)->to; curl = addbstlink(cur->links, lname, at); break; default: ungetc(c, read); case '.': tail = appendll(tail, line(read)); sz += strlen(tail->str); break; } } fclose(read); return root; }