Mercurial > ~dholland > hg > tradcpp > index.cgi
diff files.c @ 6:0601b6e8e53d
checkpoint - can find files
author | David A. Holland |
---|---|
date | Sun, 19 Dec 2010 18:55:51 -0500 (2010-12-19) |
parents | |
children | b8167949474a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/files.c Sun Dec 19 18:55:51 2010 -0500 @@ -0,0 +1,345 @@ +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <err.h> + +#include "array.h" +#include "files.h" + +struct place { + struct seenfile *file; + unsigned line; + unsigned column; +}; + +struct incdir { + const char *name; + bool issystem; +}; + +struct seenfile { + struct place includedfrom; + char *name; + bool fromsystemdir; +}; + +DECLARRAY(incdir); +DECLARRAY(seenfile); +DEFARRAY(incdir, ); +DEFARRAY(seenfile, ); + +static struct incdirarray quotepath, bracketpath; +static struct seenfilearray seenfiles; +static bool overall_failure; + +//////////////////////////////////////////////////////////// +// management + +#define DESTROYALL(T) \ + static \ + void \ + T##array_destroyall(struct T##array *arr) \ + { \ + unsigned i, num; \ + struct T *t; \ + \ + num = T##array_num(arr); \ + for (i=0; i<num; i++) { \ + t = T##array_get(arr, i); \ + T##_destroy(t); \ + } \ + T##array_setsize(arr, 0); \ + } + +static +struct incdir * +incdir_create(const char *name, bool issystem) +{ + struct incdir *id; + + id = domalloc(sizeof(*id)); + id->name = name; + id->issystem = issystem; + return id; +} + +static +void +incdir_destroy(struct incdir *id) +{ + free(id); +} + +static +struct seenfile * +seenfile_create(const struct place *from, char *name, bool fromsystemdir) +{ + struct seenfile *sf; + + sf = domalloc(sizeof(*sf)); + sf->includedfrom = *from; + sf->name = name; + sf->fromsystemdir = fromsystemdir; + return sf; +} + +static +void +seenfile_destroy(struct seenfile *sf) +{ + free(sf->name); + free(sf); +} + +void +files_init(void) +{ + incdirarray_init("epath); + incdirarray_init(&bracketpath); +} + +DESTROYALL(incdir); +DESTROYALL(seenfile); + +void +files_cleanup(void) +{ + seenfilearray_destroyall(&seenfiles); + seenfilearray_cleanup(&seenfiles); + + incdirarray_destroyall("epath); + incdirarray_cleanup("epath); + incdirarray_destroyall(&bracketpath); + incdirarray_cleanup(&bracketpath); +} + +//////////////////////////////////////////////////////////// +// path setup + +void +files_addquotepath(const char *dir, bool issystem) +{ + struct incdir *id; + + id = incdir_create(dir, issystem); + incdirarray_add("epath, id, NULL); +} + +void +files_addbracketpath(const char *dir, bool issystem) +{ + struct incdir *id; + + id = incdir_create(dir, issystem); + incdirarray_add(&bracketpath, id, NULL); +} + +//////////////////////////////////////////////////////////// +// places and complaints + +#define NOWHERE_LINE 0 +#define BUILTIN_LINE 1 +#define COMMANDLINE_LINE 2 + +static struct place scratchplace; +static bool scratchplace_inuse; + +static +bool +place_isnowhere(const struct place *p) +{ + return p->file == NULL && p->line == NOWHERE_LINE; +} + +static +bool +place_isbuiltin(const struct place *p) +{ + return p->file == NULL && p->line == BUILTIN_LINE; +} + +static +bool +place_iscommandline(const struct place *p) +{ + return p->file == NULL && p->line == COMMANDLINE_LINE; +} + +struct place * +place_gettemporary(void) +{ + assert(!scratchplace_inuse); + scratchplace_inuse = true; + return &scratchplace; +} + +void +place_puttemporary(struct place *p) +{ + assert(scratchplace_inuse); + assert(p == &scratchplace); + scratchplace_inuse = false; +} + +void +place_setnowhere(struct place *p) +{ + p->file = NULL; + p->line = NOWHERE_LINE; + p->column = 0; +} + +void +place_setbuiltin(struct place *p, unsigned num) +{ + p->file = NULL; + p->line = BUILTIN_LINE; + p->column = num; +} + +void +place_setcommandline(struct place *p, unsigned column) +{ + p->file = NULL; + p->line = COMMANDLINE_LINE; + p->column = column; +} + +static +void +place_print(const struct place *p) +{ + if (place_iscommandline(p)) { + fprintf(stderr, "<command-line>:1:%u", p->column); + } else if (place_isbuiltin(p)) { + fprintf(stderr, "<built-in>:%u:1", p->column); + } else { + fprintf(stderr, "%s:%u:%u", p->file->name, p->line, p->column); + } +} + +static +void +place_printfrom(const struct place *p) +{ + if (!place_isnowhere(&p->file->includedfrom)) { + place_printfrom(&p->file->includedfrom); + } + fprintf(stderr, "In file included from "); + fprintf(stderr, ":\n"); +} + +void +complain(const struct place *p, const char *fmt, ...) +{ + va_list ap; + + if (!place_isnowhere(&p->file->includedfrom)) { + place_printfrom(&p->file->includedfrom); + } + place_print(p); + fprintf(stderr, ": "); + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +void +complain_fail(void) +{ + overall_failure = true; +} + +bool +complain_failed(void) +{ + return overall_failure; +} + +//////////////////////////////////////////////////////////// +// parsing + +void +file_read(struct seenfile *sf, int fd); + +//////////////////////////////////////////////////////////// +// path search + +static +int +file_tryopen(const char *file) +{ + int fd; + + fd = open(file, O_RDONLY); + if (fd < 0) { + return -1; + } + /* XXX: do we need to do anything here or is this function pointless?*/ + return fd; +} + +static +void +file_search(struct place *place, struct incdirarray *path, const char *name) +{ + unsigned i, num; + struct incdir *id; + struct seenfile *sf; + char *file; + int fd; + + assert(place != NULL); + + num = incdirarray_num(path); + for (i=0; i<num; i++) { + id = incdirarray_get(path, i); + file = dostrdup3(id->name, "/", name); + fd = file_tryopen(file); + if (fd >= 0) { + sf = seenfile_create(place, file, id->issystem); + seenfilearray_add(&seenfiles, sf, NULL); + file_read(sf, fd); + close(fd); + return; + } + free(file); + } + complain(place, "Include file %s not found", name); + complain_fail(); +} + +void +file_readquote(struct place *place, const char *name) +{ + file_search(place, "epath, name); +} + +void +file_readbracket(struct place *place, const char *name) +{ + file_search(place, &bracketpath, name); +} + +void +file_readabsolute(struct place *place, const char *name) +{ + struct seenfile *sf; + int fd; + + assert(place != NULL); + + fd = file_tryopen(name); + if (fd < 0) { + warn("%s", name); + die(); + } + sf = seenfile_create(place, dostrdup(name), false); + seenfilearray_add(&seenfiles, sf, NULL); + file_read(sf, fd); + close(fd); +}