authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-01 02:29:21-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-12-01 02:29:21-07:00
logdfb6682089ad758b7ba72733778a9aa8c544c164
treec86a7a8bff35db1188a4b644a715caff6a5be92c
parent58e375d0a1423c04f4d3faabe4d84bfc11028d56

add test for bad import


9 files changed, 75 insertions(+), 13 deletions(-)

example/multiple_files/main.zig+1-1
......@@ -1,4 +1,4 @@
1export executable "test";
1export executable "test-multiple-files";
22
33use "libc.zig";
44use "foo.zig";
src/analyze.cpp+1-1
......@@ -11,7 +11,7 @@
1111#include "zig_llvm.hpp"
1212#include "os.hpp"
1313
14static void add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
14void add_node_error(CodeGen *g, AstNode *node, Buf *msg) {
1515 ErrorMsg *err = allocate<ErrorMsg>(1);
1616 err->line_start = node->line;
1717 err->column_start = node->column;
src/analyze.hpp+3
......@@ -9,7 +9,10 @@
99#define ZIG_ANALYZE_HPP
1010
1111struct CodeGen;
12struct AstNode;
13struct Buf;
1214
1315void semantic_analyze(CodeGen *g);
16void add_node_error(CodeGen *g, AstNode *node, Buf *msg);
1417
1518#endif
src/codegen.cpp+6-1
......@@ -669,6 +669,7 @@ static void init(CodeGen *g, Buf *source_path) {
669669}
670670
671671static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *source_code) {
672 int err;
672673 Buf full_path = BUF_INIT;
673674 os_path_join(g->root_source_dir, source_path, &full_path);
674675
......@@ -736,7 +737,11 @@ static ImportTableEntry *codegen_add_code(CodeGen *g, Buf *source_path, Buf *sou
736737 Buf full_path = BUF_INIT;
737738 os_path_join(g->root_source_dir, &top_level_decl->data.use.path, &full_path);
738739 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 }
740745 codegen_add_code(g, &top_level_decl->data.use.path, import_code);
741746 }
742747 }
src/error.cpp+6
......@@ -6,6 +6,12 @@ const char *err_str(int err) {
66 case ErrorNoMem: return "out of memory";
77 case ErrorInvalidFormat: return "invalid format";
88 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";
915 }
1016 return "(invalid error)";
1117}
src/error.hpp+6
......@@ -13,6 +13,12 @@ enum Error {
1313 ErrorNoMem,
1414 ErrorInvalidFormat,
1515 ErrorSemanticAnalyzeFail,
16 ErrorAccess,
17 ErrorInterrupted,
18 ErrorSystemResources,
19 ErrorFileNotFound,
20 ErrorFileSystem,
21 ErrorFileTooBig,
1622};
1723
1824const char *err_str(int err);
src/os.cpp+48-8
......@@ -7,6 +7,7 @@
77
88#include "os.hpp"
99#include "util.hpp"
10#include "error.hpp"
1011
1112#include <unistd.h>
1213#include <errno.h>
......@@ -143,26 +144,65 @@ void os_write_file(Buf *full_path, Buf *contents) {
143144int os_fetch_file(FILE *f, Buf *out_contents) {
144145 int fd = fileno(f);
145146 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 }
148163 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 }
151167 int size = (int)big_size;
152168
153169 buf_resize(out_contents, size);
154170 ssize_t ret = read(fd, buf_ptr(out_contents), size);
155171
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 }
158183
159184 return 0;
160185}
161186
162187int os_fetch_file_path(Buf *full_path, Buf *out_contents) {
163188 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 }
166206 int result = os_fetch_file(f, out_contents);
167207 fclose(f);
168208 return result;
src/util.hpp-2
......@@ -16,8 +16,6 @@
1616
1717#define BREAKPOINT __asm("int $0x03")
1818
19static const int COMPILE_FAILED_ERR_CODE = 10; // chosen with a random number generator
20
2119void zig_panic(const char *format, ...)
2220 __attribute__((cold))
2321 __attribute__ ((noreturn))
test/run_tests.cpp+4
......@@ -249,6 +249,10 @@ fn b() {}
249249#version("aoeu")
250250export executable "test";
251251 )SOURCE", 1, ".tmp_source.zig:2:1: error: invalid version string");
252
253 add_compile_fail_case("bad import", R"SOURCE(
254use "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");
252256}
253257
254258static void print_compiler_invokation(TestCase *test_case, Buf *zig_stderr) {