mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-09 15:19:07 +00:00
preprocessor runs once
This commit is contained in:
parent
e71521335a
commit
d519ce87dd
6 changed files with 99 additions and 32 deletions
|
|
@ -23,6 +23,7 @@ include_directories(
|
||||||
set(ZIG_SOURCES
|
set(ZIG_SOURCES
|
||||||
"${CMAKE_SOURCE_DIR}/src/main.cpp"
|
"${CMAKE_SOURCE_DIR}/src/main.cpp"
|
||||||
"${CMAKE_SOURCE_DIR}/src/util.cpp"
|
"${CMAKE_SOURCE_DIR}/src/util.cpp"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/buffer.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")
|
set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")
|
||||||
|
|
|
||||||
25
src/buffer.cpp
Normal file
25
src/buffer.cpp
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#include "buffer.hpp"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
Buf *buf_sprintf(const char *format, ...) {
|
||||||
|
va_list ap, ap2;
|
||||||
|
va_start(ap, format);
|
||||||
|
va_copy(ap2, ap);
|
||||||
|
|
||||||
|
int len1 = vsnprintf(nullptr, 0, format, ap);
|
||||||
|
assert(len1 >= 0);
|
||||||
|
|
||||||
|
size_t required_size = len1 + 1;
|
||||||
|
|
||||||
|
Buf *buf = buf_alloc_fixed(len1);
|
||||||
|
|
||||||
|
int len2 = vsnprintf(buf_ptr(buf), required_size, format, ap2);
|
||||||
|
assert(len2 == len1);
|
||||||
|
|
||||||
|
va_end(ap2);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
@ -11,11 +11,15 @@
|
||||||
#include "list.hpp"
|
#include "list.hpp"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
struct Buf {
|
struct Buf {
|
||||||
ZigList<char> list;
|
ZigList<char> list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Buf *buf_sprintf(const char *format, ...)
|
||||||
|
__attribute__ ((format (printf, 1, 2)));
|
||||||
|
|
||||||
static inline int buf_len(Buf *buf) {
|
static inline int buf_len(Buf *buf) {
|
||||||
return buf->list.length - 1;
|
return buf->list.length - 1;
|
||||||
}
|
}
|
||||||
|
|
@ -53,6 +57,10 @@ static inline Buf *buf_from_mem(char *ptr, int len) {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline Buf *buf_from_str(char *str) {
|
||||||
|
return buf_from_mem(str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
static inline Buf *buf_slice(Buf *in_buf, int start, int end) {
|
static inline Buf *buf_slice(Buf *in_buf, int start, int end) {
|
||||||
assert(start >= 0);
|
assert(start >= 0);
|
||||||
assert(end >= 0);
|
assert(end >= 0);
|
||||||
|
|
@ -79,4 +87,22 @@ static inline void buf_append_buf(Buf *buf, Buf *append_buf) {
|
||||||
buf_append_str(buf, buf_ptr(append_buf), buf_len(append_buf));
|
buf_append_str(buf, buf_ptr(append_buf), buf_len(append_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO this method needs work
|
||||||
|
static inline Buf *buf_dirname(Buf *buf) {
|
||||||
|
if (buf_len(buf) <= 2)
|
||||||
|
zig_panic("TODO buf_dirname small");
|
||||||
|
int last_index = buf_len(buf) - 1;
|
||||||
|
if (buf_ptr(buf)[buf_len(buf) - 1] == '/') {
|
||||||
|
last_index = buf_len(buf) - 2;
|
||||||
|
}
|
||||||
|
for (int i = last_index; i >= 0; i -= 1) {
|
||||||
|
uint8_t c = buf_ptr(buf)[i];
|
||||||
|
if (c == '/') {
|
||||||
|
return buf_slice(buf, 0, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zig_panic("TODO buf_dirname no slash");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
51
src/main.cpp
51
src/main.cpp
|
|
@ -25,6 +25,7 @@ static int usage(char *arg0) {
|
||||||
fprintf(stderr, "Usage: %s --output outfile code.zig\n"
|
fprintf(stderr, "Usage: %s --output outfile code.zig\n"
|
||||||
"Other options:\n"
|
"Other options:\n"
|
||||||
"--version print version number and exit\n"
|
"--version print version number and exit\n"
|
||||||
|
"-Ipath add path to header include path\n"
|
||||||
, arg0);
|
, arg0);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
@ -377,6 +378,8 @@ struct Preprocess {
|
||||||
Buf *out_buf;
|
Buf *out_buf;
|
||||||
Buf *in_buf;
|
Buf *in_buf;
|
||||||
Token *token;
|
Token *token;
|
||||||
|
ZigList<char *> *include_paths;
|
||||||
|
Buf *cur_dir_path;
|
||||||
};
|
};
|
||||||
|
|
||||||
__attribute__ ((format (printf, 2, 3)))
|
__attribute__ ((format (printf, 2, 3)))
|
||||||
|
|
@ -395,8 +398,33 @@ enum IncludeState {
|
||||||
IncludeStateQuote,
|
IncludeStateQuote,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void render_include(Preprocess *p, Buf *include_path, char unquote_char) {
|
static Buf *find_include_file(Preprocess *p, char *dir_path, char *file_path) {
|
||||||
fprintf(stderr, "render_include \"%s\" '%c'\n", buf_ptr(include_path), unquote_char);
|
Buf *full_path = buf_sprintf("%s/%s", dir_path, file_path);
|
||||||
|
|
||||||
|
FILE *f = fopen(buf_ptr(full_path), "rb");
|
||||||
|
if (!f)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return fetch_file(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void render_include(Preprocess *p, Buf *target_path, char unquote_char) {
|
||||||
|
if (unquote_char == '"') {
|
||||||
|
Buf *file_contents = find_include_file(p, buf_ptr(p->cur_dir_path), buf_ptr(target_path));
|
||||||
|
if (file_contents) {
|
||||||
|
buf_append_buf(p->out_buf, file_contents);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < p->include_paths->length; i += 1) {
|
||||||
|
char *include_path = p->include_paths->at(i);
|
||||||
|
Buf *file_contents = find_include_file(p, include_path, buf_ptr(target_path));
|
||||||
|
if (file_contents) {
|
||||||
|
buf_append_buf(p->out_buf, file_contents);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
preprocess_error(p, "include path \"%s\" not found", buf_ptr(target_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_and_render_include(Preprocess *p, Buf *directive_buf, int pos) {
|
static void parse_and_render_include(Preprocess *p, Buf *directive_buf, int pos) {
|
||||||
|
|
@ -469,10 +497,14 @@ static void render_token(Preprocess *p) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens) {
|
static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens,
|
||||||
|
ZigList<char *> *include_paths, Buf *cur_dir_path)
|
||||||
|
{
|
||||||
Preprocess p = {0};
|
Preprocess p = {0};
|
||||||
p.out_buf = buf_alloc();
|
p.out_buf = buf_alloc();
|
||||||
p.in_buf = in_buf;
|
p.in_buf = in_buf;
|
||||||
|
p.include_paths = include_paths;
|
||||||
|
p.cur_dir_path = cur_dir_path;
|
||||||
for (int i = 0; i < tokens->length; i += 1) {
|
for (int i = 0; i < tokens->length; i += 1) {
|
||||||
p.token = &tokens->at(i);
|
p.token = &tokens->at(i);
|
||||||
render_token(&p);
|
render_token(&p);
|
||||||
|
|
@ -480,10 +512,13 @@ static Buf *preprocess(Buf *in_buf, ZigList<Token> *tokens) {
|
||||||
return p.out_buf;
|
return p.out_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char cur_dir[1024];
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
char *arg0 = argv[0];
|
char *arg0 = argv[0];
|
||||||
char *in_file = NULL;
|
char *in_file = NULL;
|
||||||
char *out_file = NULL;
|
char *out_file = NULL;
|
||||||
|
ZigList<char *> include_paths = {0};
|
||||||
for (int i = 1; i < argc; i += 1) {
|
for (int i = 1; i < argc; i += 1) {
|
||||||
char *arg = argv[i];
|
char *arg = argv[i];
|
||||||
if (arg[0] == '-' && arg[1] == '-') {
|
if (arg[0] == '-' && arg[1] == '-') {
|
||||||
|
|
@ -500,6 +535,8 @@ int main(int argc, char **argv) {
|
||||||
return usage(arg0);
|
return usage(arg0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (arg[0] == '-' && arg[1] == 'I') {
|
||||||
|
include_paths.append(arg + 2);
|
||||||
} else if (!in_file) {
|
} else if (!in_file) {
|
||||||
in_file = arg;
|
in_file = arg;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -511,12 +548,18 @@ int main(int argc, char **argv) {
|
||||||
return usage(arg0);
|
return usage(arg0);
|
||||||
|
|
||||||
FILE *in_f;
|
FILE *in_f;
|
||||||
|
Buf *cur_dir_path;
|
||||||
if (strcmp(in_file, "-") == 0) {
|
if (strcmp(in_file, "-") == 0) {
|
||||||
in_f = stdin;
|
in_f = stdin;
|
||||||
|
char *result = getcwd(cur_dir, sizeof(cur_dir));
|
||||||
|
if (!result)
|
||||||
|
zig_panic("unable to get current working directory: %s", strerror(errno));
|
||||||
|
cur_dir_path = buf_from_str(result);
|
||||||
} else {
|
} else {
|
||||||
in_f = fopen(in_file, "rb");
|
in_f = fopen(in_file, "rb");
|
||||||
if (!in_f)
|
if (!in_f)
|
||||||
zig_panic("unable to open %s for reading: %s\n", in_file, strerror(errno));
|
zig_panic("unable to open %s for reading: %s\n", in_file, strerror(errno));
|
||||||
|
cur_dir_path = buf_dirname(buf_from_str(in_file));
|
||||||
}
|
}
|
||||||
|
|
||||||
Buf *in_data = fetch_file(in_f);
|
Buf *in_data = fetch_file(in_f);
|
||||||
|
|
@ -528,7 +571,7 @@ int main(int argc, char **argv) {
|
||||||
fprintf(stderr, "\nTokens:\n");
|
fprintf(stderr, "\nTokens:\n");
|
||||||
print_tokens(in_data, tokens);
|
print_tokens(in_data, tokens);
|
||||||
|
|
||||||
Buf *preprocessed_source = preprocess(in_data, tokens);
|
Buf *preprocessed_source = preprocess(in_data, tokens, &include_paths, cur_dir_path);
|
||||||
|
|
||||||
fprintf(stderr, "\nPreprocessed source:\n%s\n", buf_ptr(preprocessed_source));
|
fprintf(stderr, "\nPreprocessed source:\n%s\n", buf_ptr(preprocessed_source));
|
||||||
|
|
||||||
|
|
|
||||||
25
src/util.cpp
25
src/util.cpp
|
|
@ -19,28 +19,3 @@ void zig_panic(const char *format, ...) {
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
char *zig_alloc_sprintf(int *len, const char *format, ...) {
|
|
||||||
va_list ap, ap2;
|
|
||||||
va_start(ap, format);
|
|
||||||
va_copy(ap2, ap);
|
|
||||||
|
|
||||||
int len1 = vsnprintf(nullptr, 0, format, ap);
|
|
||||||
assert(len1 >= 0);
|
|
||||||
|
|
||||||
size_t required_size = len1 + 1;
|
|
||||||
char *mem = allocate<char>(required_size);
|
|
||||||
if (!mem)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
int len2 = vsnprintf(mem, required_size, format, ap2);
|
|
||||||
assert(len2 == len1);
|
|
||||||
|
|
||||||
va_end(ap2);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (len)
|
|
||||||
*len = len1;
|
|
||||||
return mem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,6 @@ static inline T *reallocate_nonzero(T * old, size_t new_count) {
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *zig_alloc_sprintf(int *len, const char *format, ...)
|
|
||||||
__attribute__ ((format (printf, 2, 3)));
|
|
||||||
|
|
||||||
template <typename T, long n>
|
template <typename T, long n>
|
||||||
constexpr long array_length(const T (&)[n]) {
|
constexpr long array_length(const T (&)[n]) {
|
||||||
return n;
|
return n;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue