| author | |
| committer | |
| log | dfb6682089ad758b7ba72733778a9aa8c544c164 |
| tree | c86a7a8bff35db1188a4b644a715caff6a5be92c |
| parent | 58e375d0a1423c04f4d3faabe4d84bfc11028d56 |
9 files changed, 75 insertions(+), 13 deletions(-)
example/multiple_files/main.zig+1-1| ... | ... | @@ -1,4 +1,4 @@ |
| 1 | export executable "test"; | |
| 1 | export executable "test-multiple-files"; | |
| 2 | 2 | |
| 3 | 3 | use "libc.zig"; |
| 4 | 4 | use "foo.zig"; |
src/analyze.cpp+1-1| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | #include "zig_llvm.hpp" |
| 12 | 12 | #include "os.hpp" |
| 13 | 13 | |
| 14 | static void add_node_error(CodeGen *g, AstNode *node, Buf *msg) { | |
| 14 | void add_node_error(CodeGen *g, AstNode *node, Buf *msg) { | |
| 15 | 15 | ErrorMsg *err = allocate<ErrorMsg>(1); |
| 16 | 16 | err->line_start = node->line; |
| 17 | 17 | err->column_start = node->column; |
src/analyze.hpp+3| ... | ... | @@ -9,7 +9,10 @@ |
| 9 | 9 | #define ZIG_ANALYZE_HPP |
| 10 | 10 | |
| 11 | 11 | struct CodeGen; |
| 12 | struct AstNode; | |
| 13 | struct Buf; | |
| 12 | 14 | |
| 13 | 15 | void semantic_analyze(CodeGen *g); |
| 16 | void add_node_error(CodeGen *g, AstNode *node, Buf *msg); | |
| 14 | 17 | |
| 15 | 18 | #endif |
src/codegen.cpp+6-1| ... | ... | @@ -669,6 +669,7 @@ static void init(CodeGen *g, Buf *source_path) { |
| 669 | 669 | } |
| 670 | 670 | |
| 671 | 671 | static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *source_code) { |
| 672 | int err; | |
| 672 | 673 | Buf full_path = BUF_INIT; |
| 673 | 674 | os_path_join(g->root_source_dir, source_path, &full_path); |
| 674 | 675 | |
| ... | ... | @@ -736,7 +737,11 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *sou |
| 736 | 737 | Buf full_path = BUF_INIT; |
| 737 | 738 | os_path_join(g->root_source_dir, &top_level_decl->data.use.path, &full_path); |
| 738 | 739 | Buf *import_code = buf_alloc(); |
| 739 | os_fetch_file_path(&full_path, import_code); | |
| 740 | if ((err = os_fetch_file_path(&full_path, import_code))) { | |
| 741 | add_node_error(g, top_level_decl, | |
| 742 | buf_sprintf("unable to open \"%s\": %s", buf_ptr(&full_path), err_str(err))); | |
| 743 | break; | |
| 744 | } | |
| 740 | 745 | codegen_add_code(g, &top_level_decl->data.use.path, import_code); |
| 741 | 746 | } |
| 742 | 747 | } |
src/error.cpp+6| ... | ... | @@ -6,6 +6,12 @@ const char *err_str(int err) { |
| 6 | 6 | case ErrorNoMem: return "out of memory"; |
| 7 | 7 | case ErrorInvalidFormat: return "invalid format"; |
| 8 | 8 | case ErrorSemanticAnalyzeFail: return "semantic analyze failed"; |
| 9 | case ErrorAccess: return "access denied"; | |
| 10 | case ErrorInterrupted: return "interrupted"; | |
| 11 | case ErrorSystemResources: return "lack of system resources"; | |
| 12 | case ErrorFileNotFound: return "file not found"; | |
| 13 | case ErrorFileSystem: return "file system error"; | |
| 14 | case ErrorFileTooBig: return "file too big"; | |
| 9 | 15 | } |
| 10 | 16 | return "(invalid error)"; |
| 11 | 17 | } |
src/error.hpp+6| ... | ... | @@ -13,6 +13,12 @@ enum Error { |
| 13 | 13 | ErrorNoMem, |
| 14 | 14 | ErrorInvalidFormat, |
| 15 | 15 | ErrorSemanticAnalyzeFail, |
| 16 | ErrorAccess, | |
| 17 | ErrorInterrupted, | |
| 18 | ErrorSystemResources, | |
| 19 | ErrorFileNotFound, | |
| 20 | ErrorFileSystem, | |
| 21 | ErrorFileTooBig, | |
| 16 | 22 | }; |
| 17 | 23 | |
| 18 | 24 | const char *err_str(int err); |
src/os.cpp+48-8| ... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 | |
| 8 | 8 | #include "os.hpp" |
| 9 | 9 | #include "util.hpp" |
| 10 | #include "error.hpp" | |
| 10 | 11 | |
| 11 | 12 | #include <unistd.h> |
| 12 | 13 | #include <errno.h> |
| ... | ... | @@ -143,26 +144,65 @@ void os_write_file(Buf *full_path, Buf *contents) { |
| 143 | 144 | int os_fetch_file(FILE *f, Buf *out_contents) { |
| 144 | 145 | int fd = fileno(f); |
| 145 | 146 | struct stat st; |
| 146 | if (fstat(fd, &st)) | |
| 147 | zig_panic("unable to stat file: %s", strerror(errno)); | |
| 147 | if (fstat(fd, &st)) { | |
| 148 | switch (errno) { | |
| 149 | case EACCES: | |
| 150 | return ErrorAccess; | |
| 151 | case ENOENT: | |
| 152 | return ErrorFileNotFound; | |
| 153 | case ENOMEM: | |
| 154 | return ErrorSystemResources; | |
| 155 | case EINTR: | |
| 156 | return ErrorInterrupted; | |
| 157 | case EINVAL: | |
| 158 | zig_unreachable(); | |
| 159 | default: | |
| 160 | return ErrorFileSystem; | |
| 161 | } | |
| 162 | } | |
| 148 | 163 | off_t big_size = st.st_size; |
| 149 | if (big_size > INT_MAX) | |
| 150 | zig_panic("file too big"); | |
| 164 | if (big_size > INT_MAX) { | |
| 165 | return ErrorFileTooBig; | |
| 166 | } | |
| 151 | 167 | int size = (int)big_size; |
| 152 | 168 | |
| 153 | 169 | buf_resize(out_contents, size); |
| 154 | 170 | ssize_t ret = read(fd, buf_ptr(out_contents), size); |
| 155 | 171 | |
| 156 | if (ret != size) | |
| 157 | zig_panic("unable to read file: %s", strerror(errno)); | |
| 172 | if (ret != size) { | |
| 173 | switch (errno) { | |
| 174 | case EINTR: | |
| 175 | return ErrorInterrupted; | |
| 176 | case EINVAL: | |
| 177 | case EISDIR: | |
| 178 | zig_unreachable(); | |
| 179 | default: | |
| 180 | return ErrorFileSystem; | |
| 181 | } | |
| 182 | } | |
| 158 | 183 | |
| 159 | 184 | return 0; |
| 160 | 185 | } |
| 161 | 186 | |
| 162 | 187 | int os_fetch_file_path(Buf *full_path, Buf *out_contents) { |
| 163 | 188 | FILE *f = fopen(buf_ptr(full_path), "rb"); |
| 164 | if (!f) | |
| 165 | zig_panic("unable to open %s: %s\n", buf_ptr(full_path), strerror(errno)); | |
| 189 | if (!f) { | |
| 190 | switch (errno) { | |
| 191 | case EACCES: | |
| 192 | return ErrorAccess; | |
| 193 | case EINTR: | |
| 194 | return ErrorInterrupted; | |
| 195 | case EINVAL: | |
| 196 | zig_unreachable(); | |
| 197 | case ENFILE: | |
| 198 | case ENOMEM: | |
| 199 | return ErrorSystemResources; | |
| 200 | case ENOENT: | |
| 201 | return ErrorFileNotFound; | |
| 202 | default: | |
| 203 | return ErrorFileSystem; | |
| 204 | } | |
| 205 | } | |
| 166 | 206 | int result = os_fetch_file(f, out_contents); |
| 167 | 207 | fclose(f); |
| 168 | 208 | return result; |
src/util.hpp-2| ... | ... | @@ -16,8 +16,6 @@ |
| 16 | 16 | |
| 17 | 17 | #define BREAKPOINT __asm("int $0x03") |
| 18 | 18 | |
| 19 | static const int COMPILE_FAILED_ERR_CODE = 10; // chosen with a random number generator | |
| 20 | ||
| 21 | 19 | void zig_panic(const char *format, ...) |
| 22 | 20 | __attribute__((cold)) |
| 23 | 21 | __attribute__ ((noreturn)) |
test/run_tests.cpp+4| ... | ... | @@ -249,6 +249,10 @@ fn b() {} |
| 249 | 249 | #version("aoeu") |
| 250 | 250 | export executable "test"; |
| 251 | 251 | )SOURCE", 1, ".tmp_source.zig:2:1: error: invalid version string"); |
| 252 | ||
| 253 | add_compile_fail_case("bad import", R"SOURCE( | |
| 254 | use "bogus-does-not-exist.zig"; | |
| 255 | )SOURCE", 1, ".tmp_source.zig:2:1: error: unable to open \"./bogus-does-not-exist.zig\": file not found"); | |
| 252 | 256 | } |
| 253 | 257 | |
| 254 | 258 | static void print_compiler_invokation(TestCase *test_case, Buf *zig_stderr) { |