authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-08-05 21:47:08-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-08-05 21:47:08-07:00
logd519ce87dd3c112dbaa087e2ef08514d5253f02a
tree9a75a21f87402147ef245fb37bcc4ea8105f2dee
parente71521335ac656f94892ee049cc4814ecb772b30

preprocessor runs once


6 files changed, 99 insertions(+), 32 deletions(-)

CMakeLists.txt+1
...@@ -23,6 +23,7 @@ include_directories(...@@ -23,6 +23,7 @@ include_directories(
23set(ZIG_SOURCES23set(ZIG_SOURCES
24 "${CMAKE_SOURCE_DIR}/src/main.cpp"24 "${CMAKE_SOURCE_DIR}/src/main.cpp"
25 "${CMAKE_SOURCE_DIR}/src/util.cpp"25 "${CMAKE_SOURCE_DIR}/src/util.cpp"
26 "${CMAKE_SOURCE_DIR}/src/buffer.cpp"
26)27)
2728
28set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")29set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")
src/buffer.cpp created+25
...@@ -0,0 +1,25 @@
1#include "buffer.hpp"
2#include <stdarg.h>
3#include <stdlib.h>
4#include <stdio.h>
5
6Buf *buf_sprintf(const char *format, ...) {
7 va_list ap, ap2;
8 va_start(ap, format);
9 va_copy(ap2, ap);
10
11 int len1 = vsnprintf(nullptr, 0, format, ap);
12 assert(len1 >= 0);
13
14 size_t required_size = len1 + 1;
15
16 Buf *buf = buf_alloc_fixed(len1);
17
18 int len2 = vsnprintf(buf_ptr(buf), required_size, format, ap2);
19 assert(len2 == len1);
20
21 va_end(ap2);
22 va_end(ap);
23
24 return buf;
25}
src/buffer.hpp+26
...@@ -11,11 +11,15 @@...@@ -11,11 +11,15 @@
11#include "list.hpp"11#include "list.hpp"
1212
13#include <assert.h>13#include <assert.h>
14#include <stdint.h>
1415
15struct Buf {16struct Buf {
16 ZigList<char> list;17 ZigList<char> list;
17};18};
1819
20Buf *buf_sprintf(const char *format, ...)
21 __attribute__ ((format (printf, 1, 2)));
22
19static inline int buf_len(Buf *buf) {23static inline int buf_len(Buf *buf) {
20 return buf->list.length - 1;24 return buf->list.length - 1;
21}25}
...@@ -53,6 +57,10 @@ static inline Buf *buf_from_mem(char *ptr, int len) {...@@ -53,6 +57,10 @@ static inline Buf *buf_from_mem(char *ptr, int len) {
53 return buf;57 return buf;
54}58}
5559
60static inline Buf *buf_from_str(char *str) {
61 return buf_from_mem(str, strlen(str));
62}
63
56static inline Buf *buf_slice(Buf *in_buf, int start, int end) {64static inline Buf *buf_slice(Buf *in_buf, int start, int end) {
57 assert(start >= 0);65 assert(start >= 0);
58 assert(end >= 0);66 assert(end >= 0);
...@@ -79,4 +87,22 @@ static inline void buf_append_buf(Buf *buf, Buf *append_buf) {...@@ -79,4 +87,22 @@ static inline void buf_append_buf(Buf *buf, Buf *append_buf) {
79 buf_append_str(buf, buf_ptr(append_buf), buf_len(append_buf));87 buf_append_str(buf, buf_ptr(append_buf), buf_len(append_buf));
80}88}
8189
90// TODO this method needs work
91static inline Buf *buf_dirname(Buf *buf) {
92 if (buf_len(buf) <= 2)
93 zig_panic("TODO buf_dirname small");
94 int last_index = buf_len(buf) - 1;
95 if (buf_ptr(buf)[buf_len(buf) - 1] == '/') {
96 last_index = buf_len(buf) - 2;
97 }
98 for (int i = last_index; i >= 0; i -= 1) {
99 uint8_t c = buf_ptr(buf)[i];
100 if (c == '/') {
101 return buf_slice(buf, 0, i);
102 }
103 }
104 zig_panic("TODO buf_dirname no slash");
105}
106
107
82#endif108#endif
src/main.cpp+47-4
...@@ -25,6 +25,7 @@ static int usage(char *arg0) {...@@ -25,6 +25,7 @@ static int usage(char *arg0) {
25 fprintf(stderr, "Usage: %s --output outfile code.zig\n"25 fprintf(stderr, "Usage: %s --output outfile code.zig\n"
26 "Other options:\n"26 "Other options:\n"
27 "--version print version number and exit\n"27 "--version print version number and exit\n"
28 "-Ipath add path to header include path\n"
28 , arg0);29 , arg0);
29 return EXIT_FAILURE;30 return EXIT_FAILURE;
30}31}
...@@ -377,6 +378,8 @@ struct Preprocess {...@@ -377,6 +378,8 @@ struct Preprocess {
377 Buf *out_buf;378 Buf *out_buf;
378 Buf *in_buf;379 Buf *in_buf;
379 Token *token;380 Token *token;
381 ZigList<char *> *include_paths;
382 Buf *cur_dir_path;
380};383};
381384
382__attribute__ ((format (printf, 2, 3)))385__attribute__ ((format (printf, 2, 3)))
...@@ -395,8 +398,33 @@ enum IncludeState {...@@ -395,8 +398,33 @@ enum IncludeState {
395 IncludeStateQuote,398 IncludeStateQuote,
396};399};
397400
398static void render_include(Preprocess *p, Buf *include_path, char unquote_char) {401static Buf *find_include_file(Preprocess *p, char *dir_path, char *file_path) {
399 fprintf(stderr, "render_include \"%s\" '%c'\n", buf_ptr(include_path), unquote_char);402 Buf *full_path = buf_sprintf("%s/%s", dir_path, file_path);
403
404 FILE *f = fopen(buf_ptr(full_path), "rb");
405 if (!f)
406 return nullptr;
407
408 return fetch_file(f);
409}
410
411static void render_include(Preprocess *p, Buf *target_path, char unquote_char) {
412 if (unquote_char == '"') {
413 Buf *file_contents = find_include_file(p, buf_ptr(p->cur_dir_path), buf_ptr(target_path));
414 if (file_contents) {
415 buf_append_buf(p->out_buf, file_contents);
416 return;
417 }
418 }
419 for (int i = 0; i < p->include_paths->length; i += 1) {
420 char *include_path = p->include_paths->at(i);
421 Buf *file_contents = find_include_file(p, include_path, buf_ptr(target_path));
422 if (file_contents) {
423 buf_append_buf(p->out_buf, file_contents);
424 return;
425 }
426 }
427 preprocess_error(p, "include path \"%s\" not found", buf_ptr(target_path));
400}428}
401429
402static void parse_and_render_include(Preprocess *p, Buf *directive_buf, int pos) {430static void parse_and_render_include(Preprocess *p, Buf *directive_buf, int pos) {
...@@ -469,10 +497,14 @@ static void render_token(Preprocess *p) {...@@ -469,10 +497,14 @@ static void render_token(Preprocess *p) {
469 }497 }
470}498}
471499
472static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens) {500static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens,
501 ZigList<char *> *include_paths, Buf *cur_dir_path)
502{
473 Preprocess p = {0};503 Preprocess p = {0};
474 p.out_buf = buf_alloc();504 p.out_buf = buf_alloc();
475 p.in_buf = in_buf;505 p.in_buf = in_buf;
506 p.include_paths = include_paths;
507 p.cur_dir_path = cur_dir_path;
476 for (int i = 0; i < tokens->length; i += 1) {508 for (int i = 0; i < tokens->length; i += 1) {
477 p.token = &tokens->at(i);509 p.token = &tokens->at(i);
478 render_token(&p);510 render_token(&p);
...@@ -480,10 +512,13 @@ static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens) {...@@ -480,10 +512,13 @@ static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens) {
480 return p.out_buf;512 return p.out_buf;
481}513}
482514
515char cur_dir[1024];
516
483int main(int argc, char **argv) {517int main(int argc, char **argv) {
484 char *arg0 = argv[0];518 char *arg0 = argv[0];
485 char *in_file = NULL;519 char *in_file = NULL;
486 char *out_file = NULL;520 char *out_file = NULL;
521 ZigList<char *> include_paths = {0};
487 for (int i = 1; i < argc; i += 1) {522 for (int i = 1; i < argc; i += 1) {
488 char *arg = argv[i];523 char *arg = argv[i];
489 if (arg[0] == '-' && arg[1] == '-') {524 if (arg[0] == '-' && arg[1] == '-') {
...@@ -500,6 +535,8 @@ int main(int argc, char **argv) {...@@ -500,6 +535,8 @@ int main(int argc, char **argv) {
500 return usage(arg0);535 return usage(arg0);
501 }536 }
502 }537 }
538 } else if (arg[0] == '-' && arg[1] == 'I') {
539 include_paths.append(arg + 2);
503 } else if (!in_file) {540 } else if (!in_file) {
504 in_file = arg;541 in_file = arg;
505 } else {542 } else {
...@@ -511,12 +548,18 @@ int main(int argc, char **argv) {...@@ -511,12 +548,18 @@ int main(int argc, char **argv) {
511 return usage(arg0);548 return usage(arg0);
512549
513 FILE *in_f;550 FILE *in_f;
551 Buf *cur_dir_path;
514 if (strcmp(in_file, "-") == 0) {552 if (strcmp(in_file, "-") == 0) {
515 in_f = stdin;553 in_f = stdin;
554 char *result = getcwd(cur_dir, sizeof(cur_dir));
555 if (!result)
556 zig_panic("unable to get current working directory: %s", strerror(errno));
557 cur_dir_path = buf_from_str(result);
516 } else {558 } else {
517 in_f = fopen(in_file, "rb");559 in_f = fopen(in_file, "rb");
518 if (!in_f)560 if (!in_f)
519 zig_panic("unable to open %s for reading: %s\n", in_file, strerror(errno));561 zig_panic("unable to open %s for reading: %s\n", in_file, strerror(errno));
562 cur_dir_path = buf_dirname(buf_from_str(in_file));
520 }563 }
521564
522 Buf *in_data = fetch_file(in_f);565 Buf *in_data = fetch_file(in_f);
...@@ -528,7 +571,7 @@ int main(int argc, char **argv) {...@@ -528,7 +571,7 @@ int main(int argc, char **argv) {
528 fprintf(stderr, "\nTokens:\n");571 fprintf(stderr, "\nTokens:\n");
529 print_tokens(in_data, tokens);572 print_tokens(in_data, tokens);
530573
531 Buf *preprocessed_source = preprocess(in_data, tokens);574 Buf *preprocessed_source = preprocess(in_data, tokens, &include_paths, cur_dir_path);
532575
533 fprintf(stderr, "\nPreprocessed source:\n%s\n", buf_ptr(preprocessed_source));576 fprintf(stderr, "\nPreprocessed source:\n%s\n", buf_ptr(preprocessed_source));
534577
src/util.cpp-25
...@@ -19,28 +19,3 @@ void zig_panic(const char *format, ...) {...@@ -19,28 +19,3 @@ void zig_panic(const char *format, ...) {
19 va_end(ap);19 va_end(ap);
20 abort();20 abort();
21}21}
22
23char *zig_alloc_sprintf(int *len, const char *format, ...) {
24 va_list ap, ap2;
25 va_start(ap, format);
26 va_copy(ap2, ap);
27
28 int len1 = vsnprintf(nullptr, 0, format, ap);
29 assert(len1 >= 0);
30
31 size_t required_size = len1 + 1;
32 char *mem = allocate<char>(required_size);
33 if (!mem)
34 return nullptr;
35
36 int len2 = vsnprintf(mem, required_size, format, ap2);
37 assert(len2 == len1);
38
39 va_end(ap2);
40 va_end(ap);
41
42 if (len)
43 *len = len1;
44 return mem;
45}
46
src/util.hpp-3
...@@ -41,9 +41,6 @@ static inline T *reallocate_nonzero(T * old, size_t new_count) {...@@ -41,9 +41,6 @@ static inline T *reallocate_nonzero(T * old, size_t new_count) {
41 return ptr;41 return ptr;
42}42}
4343
44char *zig_alloc_sprintf(int *len, const char *format, ...)
45 __attribute__ ((format (printf, 2, 3)));
46
47template <typename T, long n>44template <typename T, long n>
48constexpr long array_length(const T (&)[n]) {45constexpr long array_length(const T (&)[n]) {
49 return n;46 return n;