mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
add parseh tests
This commit is contained in:
parent
474340a003
commit
f1c5d3d3a1
@ -14,3 +14,6 @@ Update the C integer types to be the correct size for the target.
|
||||
|
||||
Add the conditional compilation code for the page size global. It is hardcoded
|
||||
for each target.
|
||||
|
||||
Make sure that parseh sends the correct command line parameters to libclang for
|
||||
the given target.
|
||||
|
||||
@ -672,7 +672,7 @@ static void render_node(AstRender *ar, AstNode *node) {
|
||||
}
|
||||
|
||||
ar->indent -= ar->indent_size;
|
||||
fprintf(ar->f, "}\n");
|
||||
fprintf(ar->f, "}");
|
||||
break;
|
||||
}
|
||||
case NodeTypeStructField:
|
||||
|
||||
@ -397,6 +397,9 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
|
||||
if (!enum_def) {
|
||||
// this is a type that we can point to but that's it, same as `struct Foo;`.
|
||||
add_typedef_node(c, type_name, create_symbol_node(c, "u8"));
|
||||
AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name),
|
||||
create_symbol_node(c, buf_ptr(type_name)));
|
||||
c->aliases.append(alias_node);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -404,7 +407,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
|
||||
buf_init_from_buf(&node->data.struct_decl.name, type_name);
|
||||
|
||||
node->data.struct_decl.kind = ContainerKindEnum;
|
||||
node->data.struct_decl.visib_mod = c->visib_mod;
|
||||
node->data.struct_decl.visib_mod = VisibModExport;
|
||||
node->data.struct_decl.directives = create_empty_directives(c);
|
||||
|
||||
ZigList<AstNode *> var_decls = {0};
|
||||
@ -465,6 +468,43 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
|
||||
|
||||
}
|
||||
|
||||
static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
|
||||
Buf bare_name = BUF_INIT;
|
||||
buf_init_from_str(&bare_name, decl_name(record_decl));
|
||||
|
||||
Buf *type_name = buf_alloc();
|
||||
buf_appendf(type_name, "struct_%s", buf_ptr(&bare_name));
|
||||
|
||||
if (c->type_table.maybe_get(type_name)) {
|
||||
// we've already seen it
|
||||
return;
|
||||
}
|
||||
|
||||
RecordDecl *record_def = record_decl->getDefinition();
|
||||
if (!record_def) {
|
||||
// this is a type that we can point to but that's it, such as `struct Foo;`.
|
||||
add_typedef_node(c, type_name, create_symbol_node(c, "u8"));
|
||||
AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name),
|
||||
create_symbol_node(c, buf_ptr(type_name)));
|
||||
c->aliases.append(alias_node);
|
||||
return;
|
||||
}
|
||||
|
||||
emit_warning(c, record_decl, "skipping record %s, TODO", buf_ptr(&bare_name));
|
||||
|
||||
/*
|
||||
AstNode *node = create_node(c, NodeTypeStructDecl);
|
||||
buf_init_from_buf(&node->data.struct_decl.name, type_name);
|
||||
|
||||
node->data.struct_decl.kind = ContainerKindStruct;
|
||||
node->data.struct_decl.visib_mod = VisibModExport;
|
||||
node->data.struct_decl.directives = create_empty_directives(c);
|
||||
|
||||
normalize_parent_ptrs(node);
|
||||
c->root->data.root.top_level_decls.append(node);
|
||||
*/
|
||||
}
|
||||
|
||||
static bool decl_visitor(void *context, const Decl *decl) {
|
||||
Context *c = (Context*)context;
|
||||
|
||||
@ -478,6 +518,9 @@ static bool decl_visitor(void *context, const Decl *decl) {
|
||||
case Decl::Enum:
|
||||
visit_enum_decl(c, static_cast<const EnumDecl *>(decl));
|
||||
break;
|
||||
case Decl::Record:
|
||||
visit_record_decl(c, static_cast<const RecordDecl *>(decl));
|
||||
break;
|
||||
default:
|
||||
emit_warning(c, decl, "ignoring %s decl\n", decl->getDeclKindName());
|
||||
}
|
||||
|
||||
@ -24,10 +24,12 @@ struct TestCase {
|
||||
ZigList<const char *> compile_errors;
|
||||
ZigList<const char *> compiler_args;
|
||||
ZigList<const char *> program_args;
|
||||
bool is_parseh;
|
||||
};
|
||||
|
||||
static ZigList<TestCase*> test_cases = {0};
|
||||
static const char *tmp_source_path = ".tmp_source.zig";
|
||||
static const char *tmp_h_path = ".tmp_header.h";
|
||||
static const char *tmp_exe_path = "./.tmp_exe";
|
||||
static const char *zig_exe = "./zig";
|
||||
|
||||
@ -94,6 +96,24 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source
|
||||
return test_case;
|
||||
}
|
||||
|
||||
static TestCase *add_parseh_case(const char *case_name, const char *source, const char *output) {
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->case_name = case_name;
|
||||
test_case->output = output;
|
||||
test_case->is_parseh = true;
|
||||
|
||||
test_case->source_files.resize(1);
|
||||
test_case->source_files.at(0).relative_path = tmp_h_path;
|
||||
test_case->source_files.at(0).source_code = source;
|
||||
|
||||
test_case->compiler_args.append("parseh");
|
||||
test_case->compiler_args.append(tmp_h_path);
|
||||
test_case->compiler_args.append("--c-import-warnings");
|
||||
|
||||
test_cases.append(test_case);
|
||||
return test_case;
|
||||
}
|
||||
|
||||
static void add_compiling_test_cases(void) {
|
||||
add_simple_case("hello world with libc", R"SOURCE(
|
||||
#link("c")
|
||||
@ -1771,6 +1791,39 @@ const x = 2 == 2.0;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void add_parseh_test_cases(void) {
|
||||
add_parseh_case("simple data types", R"SOURCE(
|
||||
#include <stdint.h>
|
||||
int foo(char a, unsigned char b, signed char c);
|
||||
void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
|
||||
void baz(int8_t a, int16_t b, int32_t c, int64_t d);
|
||||
)SOURCE", R"OUTPUT(pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;
|
||||
pub extern fn bar(a: u8, b: u16, c: u32, d: u64);
|
||||
pub extern fn baz(a: i8, b: i16, c: i32, d: i64);)OUTPUT");
|
||||
|
||||
add_parseh_case("noreturn attribute", R"SOURCE(
|
||||
void foo(void) __attribute__((noreturn));
|
||||
)SOURCE", R"OUTPUT(pub extern fn foo() -> unreachable;)OUTPUT");
|
||||
|
||||
add_parseh_case("enums", R"SOURCE(
|
||||
enum Foo {
|
||||
FooA,
|
||||
FooB,
|
||||
Foo1,
|
||||
};
|
||||
)SOURCE", R"OUTPUT(export enum enum_Foo {
|
||||
A,
|
||||
B,
|
||||
_1,
|
||||
}
|
||||
pub const FooA = enum_Foo.A;
|
||||
pub const FooB = enum_Foo.B;
|
||||
pub const Foo1 = enum_Foo._1;
|
||||
pub const Foo = enum_Foo;)OUTPUT");
|
||||
}
|
||||
|
||||
static void print_compiler_invocation(TestCase *test_case) {
|
||||
printf("%s", zig_exe);
|
||||
for (int i = 0; i < test_case->compiler_args.length; i += 1) {
|
||||
@ -1822,36 +1875,55 @@ static void run_test(TestCase *test_case) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Buf program_stderr = BUF_INIT;
|
||||
Buf program_stdout = BUF_INIT;
|
||||
os_exec_process(tmp_exe_path, test_case->program_args, &return_code, &program_stderr, &program_stdout);
|
||||
|
||||
if (return_code != 0) {
|
||||
printf("\nProgram exited with return code %d:\n", return_code);
|
||||
print_compiler_invocation(test_case);
|
||||
printf("%s", tmp_exe_path);
|
||||
for (int i = 0; i < test_case->program_args.length; i += 1) {
|
||||
printf(" %s", test_case->program_args.at(i));
|
||||
if (test_case->is_parseh) {
|
||||
if (buf_len(&zig_stderr) > 0) {
|
||||
printf("\nparseh emitted warnings:\n");
|
||||
print_compiler_invocation(test_case);
|
||||
printf("%s\n", buf_ptr(&zig_stderr));
|
||||
exit(1);
|
||||
}
|
||||
printf("\n");
|
||||
printf("%s\n", buf_ptr(&program_stderr));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!buf_eql_str(&program_stdout, test_case->output)) {
|
||||
printf("\n");
|
||||
print_compiler_invocation(test_case);
|
||||
printf("%s", tmp_exe_path);
|
||||
for (int i = 0; i < test_case->program_args.length; i += 1) {
|
||||
printf(" %s", test_case->program_args.at(i));
|
||||
if (!strstr(buf_ptr(&zig_stdout), test_case->output)) {
|
||||
printf("\n");
|
||||
printf("========= Expected this output: =========\n");
|
||||
printf("%s\n", test_case->output);
|
||||
printf("================================================\n");
|
||||
print_compiler_invocation(test_case);
|
||||
printf("%s\n", buf_ptr(&zig_stdout));
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
Buf program_stderr = BUF_INIT;
|
||||
Buf program_stdout = BUF_INIT;
|
||||
os_exec_process(tmp_exe_path, test_case->program_args, &return_code, &program_stderr, &program_stdout);
|
||||
|
||||
if (return_code != 0) {
|
||||
printf("\nProgram exited with return code %d:\n", return_code);
|
||||
print_compiler_invocation(test_case);
|
||||
printf("%s", tmp_exe_path);
|
||||
for (int i = 0; i < test_case->program_args.length; i += 1) {
|
||||
printf(" %s", test_case->program_args.at(i));
|
||||
}
|
||||
printf("\n");
|
||||
printf("%s\n", buf_ptr(&program_stderr));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!buf_eql_str(&program_stdout, test_case->output)) {
|
||||
printf("\n");
|
||||
print_compiler_invocation(test_case);
|
||||
printf("%s", tmp_exe_path);
|
||||
for (int i = 0; i < test_case->program_args.length; i += 1) {
|
||||
printf(" %s", test_case->program_args.at(i));
|
||||
}
|
||||
printf("\n");
|
||||
printf("==== Test failed. Expected output: ====\n");
|
||||
printf("%s\n", test_case->output);
|
||||
printf("========= Actual output: ==============\n");
|
||||
printf("%s\n", buf_ptr(&program_stdout));
|
||||
printf("=======================================\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("\n");
|
||||
printf("==== Test failed. Expected output: ====\n");
|
||||
printf("%s\n", test_case->output);
|
||||
printf("========= Actual output: ==============\n");
|
||||
printf("%s\n", buf_ptr(&program_stdout));
|
||||
printf("=======================================\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < test_case->source_files.length; i += 1) {
|
||||
@ -1881,6 +1953,7 @@ static void run_all_tests(bool reverse) {
|
||||
|
||||
static void cleanup(void) {
|
||||
remove(tmp_source_path);
|
||||
remove(tmp_h_path);
|
||||
remove(tmp_exe_path);
|
||||
}
|
||||
|
||||
@ -1900,6 +1973,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
add_compiling_test_cases();
|
||||
add_compile_failure_test_cases();
|
||||
add_parseh_test_cases();
|
||||
run_all_tests(reverse);
|
||||
cleanup();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user