From ec306ef31fdf4af6eb6951bb2bbc4c37c7eadc3d Mon Sep 17 00:00:00 2001 From: Jesse McDonald Date: Sun, 22 Nov 2009 22:41:27 -0600 Subject: [PATCH] Adjust indirect form (#i"path") to be relative to the current file. --- reader.c | 48 ++++++++++++++++++++++++++++++++------ reader.h | 5 +++- rosella.c | 70 ++++++++++++++++++++++++++----------------------------- 3 files changed, 78 insertions(+), 45 deletions(-) diff --git a/reader.c b/reader.c index 25db31a..23a43fa 100644 --- a/reader.c +++ b/reader.c @@ -1,3 +1,10 @@ +#define _XOPEN_SOURCE 500 + +#include +#include +#include +#include + #include #include #include @@ -47,7 +54,7 @@ static value_t patch_placeholders(reader_state_t *state, value_t v); static void tree_replace(value_t *in, value_t oldval, value_t newval); -value_t read_value(FILE *f) +value_t read_value_from_file(FILE *f) { reader_state_t state; value_t result; @@ -72,6 +79,38 @@ value_t read_value(FILE *f) return result; } +value_t read_value_from_path(const char *path) +{ + FILE *f = fopen(path, "r"); + const char *last_slash; + value_t v; + int dirfd; + + release_assert(f != NULL); + + dirfd = open(".", O_RDONLY); + release_assert(dirfd >= 0); + + last_slash = strrchr(path, '/'); + + if (last_slash) + { + size_t bytes = last_slash - path; + char *dirname = (char*)malloc(bytes+1); + memcpy(dirname, path, bytes); + dirname[bytes] = '\0'; + chdir(dirname); + } + + v = read_value_from_file(f); + fchdir(dirfd); + close(dirfd); + + fclose(f); + + return v; +} + static value_t read_one_value(reader_state_t *state) { skip_whitespace(state); @@ -676,13 +715,8 @@ static value_t read_placeholder(reader_state_t *state) static value_t read_indirect(value_t path) { char *name = value_to_string(path); - FILE *f = fopen(name, "r"); - value_t v; + value_t v = read_value_from_path(name); free(name); - - release_assert(f != NULL); - v = read_value(f); - fclose(f); return v; } diff --git a/reader.h b/reader.h index 3acf57e..751cf61 100644 --- a/reader.h +++ b/reader.h @@ -1,9 +1,12 @@ #ifndef READER_H_bc8f9bf546e3914a72851703b38326d2 #define READER_H_bc8f9bf546e3914a72851703b38326d2 +#include + #include "gc.h" -value_t read_value(FILE *f); +value_t read_value_from_file(FILE *f); +value_t read_value_from_path(const char *path); #endif /* vim:set sw=2 expandtab: */ diff --git a/rosella.c b/rosella.c index dced4b4..c14393c 100644 --- a/rosella.c +++ b/rosella.c @@ -37,56 +37,52 @@ int main(int argc, char **argv) interpreter_init(); io_builtin_init(); - if (argc < 2 || (strcmp(argv[1], "-k") == 0)) + if (argc < 2 || (strcmp(argv[1], "-t") == 0) || (strcmp(argv[1], "--test") == 0)) { test_builtins(); test_weak_boxes_and_wills(); - if (argc > 1) - test_reader(); - test_garbage_collection(argc > 1); + test_garbage_collection(false); + } + else if ((strcmp(argv[1], "-b") == 0) || (strcmp(argv[1], "--burn-in") == 0)) + { + test_garbage_collection(true); + } + else if ((strcmp(argv[1], "-r") == 0) || (strcmp(argv[1], "--reader") == 0)) + { + test_reader(); } else { - FILE *f = fopen(argv[1], "r"); + gc_root_t argv_root; + value_t program; + value_t results; - if (f) + register_gc_root(&argv_root, NIL); + + /* Construct list backward, so that we don't have to reverse it. */ + for (int i = argc - 1; i >= 2; --i) { - gc_root_t argv_root; - value_t program; - value_t results; + value_t temp = string_to_value(argv[i]); + argv_root.value = cons(temp, argv_root.value); + } + + program = read_value_from_path(argv[1]); - register_gc_root(&argv_root, NIL); + unregister_gc_root(&argv_root); + results = run_interpreter(program, argv_root.value); - /* Construct list backward, so that we don't have to reverse it. */ - for (int i = argc - 1; i >= 2; --i) - { - value_t temp = string_to_value(argv[i]); - argv_root.value = cons(temp, argv_root.value); - } - - program = read_value(f); - fclose(f); - - unregister_gc_root(&argv_root); - results = run_interpreter(program, argv_root.value); - - for (value_t result = results; !is_nil(result); result = _CDR(result)) - { - print_value(CAR(result)); - nl(); - } + for (value_t result = results; !is_nil(result); result = _CDR(result)) + { + print_value(CAR(result)); + nl(); + } #if 0 - nl(); - fflush(stdout); + nl(); + fflush(stdout); - fprint_gc_stats(stderr); + fprint_gc_stats(stderr); #endif - } - else - { - perror(argv[1]); - } } return 0; @@ -206,7 +202,7 @@ static void test_reader(void) fputs("> ", stdout); fflush(stdout); - v = read_value(stdin); + v = read_value_from_file(stdin); print_value(v); nl(); nl();