#include #include #include #include #include "read.h" #include "strbst.h" #include "nodelink.h" #include "ll.h" 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); } 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 } char* empty(void) { // "" with a freeable memory address char* str = malloc(sizeof(char)); *str = 0; return str; } char* line(FILE* file) { // gets a line from file char* link = NULL; size_t n = 0; getline(&link, &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; } } link* insorget(strbst* tgt, char* name) { link* get = query(tgt, name); if (!get) { get = newlink(newnode()); insbst(tgt, name, get); } return get; } link* addbstlink(strbst* tree, char* name, node* to) { link* l = newlink(to); insbst(tree, name, l); return l; } char* resolvell(llnode* head, size_t* sz) { llnode* tail = head->next; head->next = NULL; char *out, *pos; pos = out = malloc(sizeof(char)*(*sz+1)); out[*sz] = 0; *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, name, 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, &sz); 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; }