implement macro lookup
This commit is contained in:
parent
d5e58616a2
commit
6b020756af
99
main.c
99
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);
|
||||
|
Loading…
Reference in New Issue
Block a user