implement macro lookup

This commit is contained in:
Julian Daube 2017-10-25 20:42:33 +02:00
parent d5e58616a2
commit 6b020756af

99
main.c
View File

@ -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);