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
|
#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) {
|
void free_filelist(struct filelist * list) {
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
@ -45,19 +107,24 @@ int good(FILE * file) {
|
|||||||
return !feof(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);
|
char temp = fgetc(file);
|
||||||
if (temp == '\n') {
|
if (temp == '\n') {
|
||||||
(*line)++;
|
line++;
|
||||||
*pos = 0;
|
pos = 0;
|
||||||
} else {
|
} else {
|
||||||
(*pos)++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int add_char(char ** str, char c) {
|
int add_char(char ** str, char c) {
|
||||||
if (str == NULL || *str == NULL) {
|
if (str == NULL || *str == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -70,6 +137,7 @@ int add_char(char ** str, char c) {
|
|||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*str = temp;
|
*str = temp;
|
||||||
|
|
||||||
(*str)[len-1] = c;
|
(*str)[len-1] = c;
|
||||||
@ -77,15 +145,20 @@ int add_char(char ** str, char c) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void eval_macro(struct filelist * last, FILE * file) {
|
void eval_macro(struct filelist * last, FILE * file) {
|
||||||
char * name = NULL;
|
char * name = NULL;
|
||||||
strhash_t hash = 0;
|
strhash_t hash = 0;
|
||||||
|
hashtable_iterator_t macro;
|
||||||
|
|
||||||
char current = 0;
|
char current = 0;
|
||||||
|
|
||||||
// read macro name
|
// 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)) {
|
if (!good(file)) {
|
||||||
@ -95,7 +168,7 @@ void eval_macro(struct filelist * last, FILE * file) {
|
|||||||
|
|
||||||
void eval_file(struct filelist * last) {
|
void eval_file(struct filelist * last) {
|
||||||
// open file
|
// open file
|
||||||
FILE * file = fopen(last->path, "r");
|
FILE * file = fopen_count(last->path, "r");
|
||||||
|
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
fprintf(stderr, _("could not open file \"%s\":%s\n"), last->path, strerror(errno));
|
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;
|
char current = 1;
|
||||||
while(good(file)) {
|
while(good(file)) {
|
||||||
current = fgetc(file);
|
current = fgetc_count(file);
|
||||||
|
|
||||||
switch(current) {
|
switch(current) {
|
||||||
case '%':
|
case '%':
|
||||||
// comment, skip line
|
// comment, skip line
|
||||||
do {
|
do {
|
||||||
current = fgetc(file);
|
current = fgetc_count(file);
|
||||||
} while(good(file) && current != '\n');
|
} while(good(file) && current != '\n');
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -121,7 +194,7 @@ void eval_file(struct filelist * last) {
|
|||||||
eval_macro(last, file);
|
eval_macro(last, file);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf(_("unrecognized char! %c\n"), current);
|
printf(_("%d:%d:unrecognized char! %c\n"), line, pos, current);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,6 +249,10 @@ int main(int argc, char ** args) {
|
|||||||
struct filelist list;
|
struct filelist list;
|
||||||
list.next = NULL;
|
list.next = NULL;
|
||||||
list.path = current_file;
|
list.path = current_file;
|
||||||
|
list.macros = malloc(sizeof(macrotable_t));
|
||||||
|
|
||||||
|
macrotable_init(list.macros);
|
||||||
|
macrotable_copy(list.macros, &default_macros);
|
||||||
|
|
||||||
eval_file(&list);
|
eval_file(&list);
|
||||||
free_filelist(list.next);
|
free_filelist(list.next);
|
||||||
|
Loading…
Reference in New Issue
Block a user