From 6b020756affef2e917ab5663522844ef27da56aa Mon Sep 17 00:00:00 2001 From: Julian Daube Date: Wed, 25 Oct 2017 20:42:33 +0200 Subject: [PATCH] implement macro lookup --- main.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index 010afd8..9e3d29d 100644 --- a/main.c +++ b/main.c @@ -6,7 +6,69 @@ #define _(x) x +struct macro { + char * name; +}; +void *copy_macro(void * macro) { + struct macro * temp = (struct macro*)(macro), + * new = malloc(sizeof(struct macro)); + + new->name = strdup(temp->name); + return (void*)(new); +} + +void free_macro(void * macro) { + struct macro * temp = (struct macro*)(macro); + + free(temp->name); + free(temp); +} + + +typedef struct hashtable macrotable_t; + +// init default macros empty +macrotable_t default_macros = {}; + +void build_default_macros() { + // default macros currently implemented: + // if + // lstinputlisting + // include + // input + // includegraphics + // graphicspath + hashtable_clear(&default_macros); +} + +void macrotable_init(macrotable_t * table) { + hashtable_init(table); + table->dealloc_data = free_macro; +} + +void macrotable_copy(macrotable_t * to, macrotable_t * from) { + if (!to || !from) { + return; + } + + hashtable_iterator_t it = hashtable_next(from, NULL); + struct entry newEntry; + + for(; it != hashtable_end(from); it = hashtable_next(from, it)) { + // insert it into to + newEntry = *it; + newEntry.data = copy_macro(newEntry.data); + + hashtable_add(to, newEntry); + } +} + +struct filelist { + struct filelist * next; + char * path; + struct hashtable * macros; +}; void free_filelist(struct filelist * list) { if (list == NULL) { @@ -45,19 +107,24 @@ int good(FILE * file) { return !feof(file); } -char fgetc_count(FILE *file, int * line, int * pos) { +volatile int line = 0, pos = 0; +FILE * fopen_count(const char * path, const char * flags) { + line = pos = 0; + return fopen(path, flags); +} + +char fgetc_count(FILE *file) { char temp = fgetc(file); if (temp == '\n') { - (*line)++; - *pos = 0; + line++; + pos = 0; } else { - (*pos)++; + pos++; } return temp; } - int add_char(char ** str, char c) { if (str == NULL || *str == NULL) { return 0; @@ -70,6 +137,7 @@ int add_char(char ** str, char c) { errno = ENOMEM; return -1; } + *str = temp; (*str)[len-1] = c; @@ -77,15 +145,20 @@ int add_char(char ** str, char c) { return 0; } + + void eval_macro(struct filelist * last, FILE * file) { char * name = NULL; strhash_t hash = 0; + hashtable_iterator_t macro; char current = 0; // read macro name - while(good(file) && current != '\\') { - + while(good(file) && current != '\\' && macro == hashtable_end(last->macros)) { + hash = strhash_add(hash, current); + // try to find macro in table + macro = hashtable_get_hash(last->macros, hash); } if (!good(file)) { @@ -95,7 +168,7 @@ void eval_macro(struct filelist * last, FILE * file) { void eval_file(struct filelist * last) { // open file - FILE * file = fopen(last->path, "r"); + FILE * file = fopen_count(last->path, "r"); if (file == NULL) { fprintf(stderr, _("could not open file \"%s\":%s\n"), last->path, strerror(errno)); @@ -106,13 +179,13 @@ void eval_file(struct filelist * last) { char current = 1; while(good(file)) { - current = fgetc(file); + current = fgetc_count(file); switch(current) { case '%': // comment, skip line do { - current = fgetc(file); + current = fgetc_count(file); } while(good(file) && current != '\n'); break; @@ -121,7 +194,7 @@ void eval_file(struct filelist * last) { eval_macro(last, file); break; default: - printf(_("unrecognized char! %c\n"), current); + printf(_("%d:%d:unrecognized char! %c\n"), line, pos, current); break; } } @@ -176,6 +249,10 @@ int main(int argc, char ** args) { struct filelist list; list.next = NULL; list.path = current_file; + list.macros = malloc(sizeof(macrotable_t)); + + macrotable_init(list.macros); + macrotable_copy(list.macros, &default_macros); eval_file(&list); free_filelist(list.next);