Merge remote-tracking branch 'origin/master' into llvm6
commit
df89291d1c
|
@ -3,9 +3,9 @@ const io = std.io;
|
|||
const mem = std.mem;
|
||||
const os = std.os;
|
||||
const warn = std.debug.warn;
|
||||
const allocator = std.debug.global_allocator;
|
||||
|
||||
pub fn main() -> %void {
|
||||
const allocator = &std.debug.global_allocator;
|
||||
var args_it = os.args();
|
||||
const exe = %return unwrapArg(??args_it.next(allocator));
|
||||
var catted_anything = false;
|
||||
|
|
|
@ -1508,13 +1508,9 @@ struct CodeGen {
|
|||
bool linker_rdynamic;
|
||||
const char *linker_script;
|
||||
|
||||
// The function definitions this module includes. There must be a corresponding
|
||||
// fn_protos entry.
|
||||
// The function definitions this module includes.
|
||||
ZigList<FnTableEntry *> fn_defs;
|
||||
size_t fn_defs_index;
|
||||
// The function prototypes this module includes. In the case of external declarations,
|
||||
// there will not be a corresponding fn_defs entry.
|
||||
ZigList<FnTableEntry *> fn_protos;
|
||||
ZigList<TldVar *> global_vars;
|
||||
|
||||
OutType out_type;
|
||||
|
|
|
@ -2121,8 +2121,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
|
|||
}
|
||||
|
||||
if (!fn_table_entry->type_entry->data.fn.is_generic) {
|
||||
g->fn_protos.append(fn_table_entry);
|
||||
|
||||
if (fn_def_node)
|
||||
g->fn_defs.append(fn_table_entry);
|
||||
|
||||
|
@ -2162,7 +2160,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
|
|||
fn_table_entry->body_node = source_node->data.test_decl.body;
|
||||
fn_table_entry->is_test = true;
|
||||
|
||||
g->fn_protos.append(fn_table_entry);
|
||||
g->fn_defs.append(fn_table_entry);
|
||||
g->test_fns.append(fn_table_entry);
|
||||
|
||||
|
|
|
@ -408,6 +408,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
|
|||
LLVMValueRef existing_llvm_fn = LLVMGetNamedFunction(g->module, buf_ptr(symbol_name));
|
||||
if (existing_llvm_fn) {
|
||||
fn_table_entry->llvm_value = LLVMConstBitCast(existing_llvm_fn, LLVMPointerType(fn_llvm_type, 0));
|
||||
return fn_table_entry->llvm_value;
|
||||
} else {
|
||||
fn_table_entry->llvm_value = LLVMAddFunction(g->module, buf_ptr(symbol_name), fn_llvm_type);
|
||||
}
|
||||
|
@ -493,6 +494,49 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
|
|||
// use the ABI alignment, which is fine.
|
||||
}
|
||||
|
||||
if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) {
|
||||
// nothing to do
|
||||
} else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer ||
|
||||
fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdFn)
|
||||
{
|
||||
addLLVMAttr(fn_table_entry->llvm_value, 0, "nonnull");
|
||||
} else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) &&
|
||||
calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc))
|
||||
{
|
||||
addLLVMArgAttr(fn_table_entry->llvm_value, 0, "sret");
|
||||
addLLVMArgAttr(fn_table_entry->llvm_value, 0, "nonnull");
|
||||
}
|
||||
|
||||
|
||||
// set parameter attributes
|
||||
for (size_t param_i = 0; param_i < fn_type->data.fn.fn_type_id.param_count; param_i += 1) {
|
||||
FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i];
|
||||
size_t gen_index = gen_info->gen_index;
|
||||
bool is_byval = gen_info->is_byval;
|
||||
|
||||
if (gen_index == SIZE_MAX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FnTypeParamInfo *param_info = &fn_type->data.fn.fn_type_id.param_info[param_i];
|
||||
|
||||
TypeTableEntry *param_type = gen_info->type;
|
||||
if (param_info->is_noalias) {
|
||||
addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "noalias");
|
||||
}
|
||||
if ((param_type->id == TypeTableEntryIdPointer && param_type->data.pointer.is_const) || is_byval) {
|
||||
addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "readonly");
|
||||
}
|
||||
if (param_type->id == TypeTableEntryIdPointer) {
|
||||
addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "nonnull");
|
||||
}
|
||||
// Note: byval is disabled on windows due to an LLVM bug:
|
||||
// https://github.com/zig-lang/zig/issues/536
|
||||
if (is_byval && g->zig_target.os != ZigLLVM_Win32) {
|
||||
addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)gen_index, "byval");
|
||||
}
|
||||
}
|
||||
|
||||
return fn_table_entry->llvm_value;
|
||||
}
|
||||
|
||||
|
@ -4297,59 +4341,6 @@ static void do_code_gen(CodeGen *g) {
|
|||
var->value_ref = global_value;
|
||||
}
|
||||
|
||||
// Generate function prototypes
|
||||
for (size_t fn_proto_i = 0; fn_proto_i < g->fn_protos.length; fn_proto_i += 1) {
|
||||
FnTableEntry *fn_table_entry = g->fn_protos.at(fn_proto_i);
|
||||
|
||||
TypeTableEntry *fn_type = fn_table_entry->type_entry;
|
||||
FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id;
|
||||
|
||||
LLVMValueRef fn_val = fn_llvm_value(g, fn_table_entry);
|
||||
|
||||
if (!type_has_bits(fn_type->data.fn.fn_type_id.return_type)) {
|
||||
// nothing to do
|
||||
} else if (fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdPointer ||
|
||||
fn_type->data.fn.fn_type_id.return_type->id == TypeTableEntryIdFn)
|
||||
{
|
||||
addLLVMAttr(fn_val, 0, "nonnull");
|
||||
} else if (handle_is_ptr(fn_type->data.fn.fn_type_id.return_type) &&
|
||||
calling_convention_does_first_arg_return(fn_type->data.fn.fn_type_id.cc))
|
||||
{
|
||||
addLLVMArgAttr(fn_val, 0, "sret");
|
||||
addLLVMArgAttr(fn_val, 0, "nonnull");
|
||||
}
|
||||
|
||||
|
||||
// set parameter attributes
|
||||
for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) {
|
||||
FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i];
|
||||
size_t gen_index = gen_info->gen_index;
|
||||
bool is_byval = gen_info->is_byval;
|
||||
|
||||
if (gen_index == SIZE_MAX) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FnTypeParamInfo *param_info = &fn_type_id->param_info[param_i];
|
||||
|
||||
TypeTableEntry *param_type = gen_info->type;
|
||||
if (param_info->is_noalias) {
|
||||
addLLVMArgAttr(fn_val, (unsigned)gen_index, "noalias");
|
||||
}
|
||||
if ((param_type->id == TypeTableEntryIdPointer && param_type->data.pointer.is_const) || is_byval) {
|
||||
addLLVMArgAttr(fn_val, (unsigned)gen_index, "readonly");
|
||||
}
|
||||
if (param_type->id == TypeTableEntryIdPointer) {
|
||||
addLLVMArgAttr(fn_val, (unsigned)gen_index, "nonnull");
|
||||
}
|
||||
// Note: byval is disabled on windows due to an LLVM bug:
|
||||
// https://github.com/zig-lang/zig/issues/536
|
||||
if (is_byval && g->zig_target.os != ZigLLVM_Win32) {
|
||||
addLLVMArgAttr(fn_val, (unsigned)gen_index, "byval");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate function definitions.
|
||||
for (size_t fn_i = 0; fn_i < g->fn_defs.length; fn_i += 1) {
|
||||
FnTableEntry *fn_table_entry = g->fn_defs.at(fn_i);
|
||||
|
|
|
@ -10584,7 +10584,6 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal
|
|||
impl_fn->analyzed_executable.source_node = call_instruction->base.source_node;
|
||||
impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec;
|
||||
|
||||
ira->codegen->fn_protos.append(impl_fn);
|
||||
ira->codegen->fn_defs.append(impl_fn);
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ pub fn ArrayList(comptime T: type) -> type{
|
|||
}
|
||||
|
||||
test "basic ArrayList test" {
|
||||
var list = ArrayList(i32).init(&debug.global_allocator);
|
||||
var list = ArrayList(i32).init(debug.global_allocator);
|
||||
defer list.deinit();
|
||||
|
||||
{var i: usize = 0; while (i < 10) : (i += 1) {
|
||||
|
|
|
@ -135,7 +135,7 @@ pub const Buffer = struct {
|
|||
test "simple Buffer" {
|
||||
const cstr = @import("cstr.zig");
|
||||
|
||||
var buf = %%Buffer.init(&debug.global_allocator, "");
|
||||
var buf = %%Buffer.init(debug.global_allocator, "");
|
||||
assert(buf.len() == 0);
|
||||
%%buf.append("hello");
|
||||
%%buf.appendByte(' ');
|
||||
|
|
|
@ -6,26 +6,28 @@ pub const _errno = __error;
|
|||
|
||||
/// Renamed to Stat to not conflict with the stat function.
|
||||
pub const Stat = extern struct {
|
||||
dev: u32,
|
||||
dev: i32,
|
||||
mode: u16,
|
||||
nlink: u16,
|
||||
ino: u64,
|
||||
uid: u32,
|
||||
gid: u32,
|
||||
rdev: u64,
|
||||
|
||||
atim: timespec,
|
||||
mtim: timespec,
|
||||
ctim: timespec,
|
||||
|
||||
size: u64,
|
||||
blocks: u64,
|
||||
blksize: u32,
|
||||
rdev: i32,
|
||||
atime: usize,
|
||||
atimensec: usize,
|
||||
mtime: usize,
|
||||
mtimensec: usize,
|
||||
ctime: usize,
|
||||
ctimensec: usize,
|
||||
birthtime: usize,
|
||||
birthtimensec: usize,
|
||||
size: i64,
|
||||
blocks: i64,
|
||||
blksize: i32,
|
||||
flags: u32,
|
||||
gen: u32,
|
||||
lspare: i32,
|
||||
qspare: [2]u64,
|
||||
|
||||
qspare: [2]i64,
|
||||
};
|
||||
|
||||
pub const timespec = extern struct {
|
||||
|
|
|
@ -14,6 +14,7 @@ pub extern "c" fn exit(code: c_int) -> noreturn;
|
|||
pub extern "c" fn isatty(fd: c_int) -> c_int;
|
||||
pub extern "c" fn close(fd: c_int) -> c_int;
|
||||
pub extern "c" fn fstat(fd: c_int, buf: &Stat) -> c_int;
|
||||
pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: &Stat) -> c_int;
|
||||
pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) -> isize;
|
||||
pub extern "c" fn open(path: &const u8, oflag: c_int, ...) -> c_int;
|
||||
pub extern "c" fn raise(sig: c_int) -> c_int;
|
||||
|
|
|
@ -38,7 +38,7 @@ fn getStderrStream() -> %&io.OutStream {
|
|||
/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
|
||||
pub fn dumpStackTrace() {
|
||||
const stderr = getStderrStream() %% return;
|
||||
writeStackTrace(stderr, &global_allocator, stderr_file.isTty(), 1) %% return;
|
||||
writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) %% return;
|
||||
}
|
||||
|
||||
/// This function invokes undefined behavior when `ok` is `false`.
|
||||
|
@ -86,7 +86,7 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn {
|
|||
|
||||
const stderr = getStderrStream() %% os.abort();
|
||||
stderr.print(format ++ "\n", args) %% os.abort();
|
||||
writeStackTrace(stderr, &global_allocator, stderr_file.isTty(), 1) %% os.abort();
|
||||
writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) %% os.abort();
|
||||
|
||||
os.abort();
|
||||
}
|
||||
|
@ -967,7 +967,8 @@ fn readILeb128(in_stream: &io.InStream) -> %i64 {
|
|||
}
|
||||
}
|
||||
|
||||
pub var global_allocator = mem.Allocator {
|
||||
pub const global_allocator = &global_allocator_state;
|
||||
var global_allocator_state = mem.Allocator {
|
||||
.allocFn = globalAlloc,
|
||||
.reallocFn = globalRealloc,
|
||||
.freeFn = globalFree,
|
||||
|
|
|
@ -232,7 +232,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
|
|||
}
|
||||
|
||||
test "basicHashMapTest" {
|
||||
var map = HashMap(i32, i32, hash_i32, eql_i32).init(&debug.global_allocator);
|
||||
var map = HashMap(i32, i32, hash_i32, eql_i32).init(debug.global_allocator);
|
||||
defer map.deinit();
|
||||
|
||||
assert(%%map.put(1, 11) == null);
|
||||
|
|
39
std/io.zig
39
std/io.zig
|
@ -20,6 +20,12 @@ const fmt = std.fmt;
|
|||
const is_posix = builtin.os != builtin.Os.windows;
|
||||
const is_windows = builtin.os == builtin.Os.windows;
|
||||
|
||||
test "import io tests" {
|
||||
comptime {
|
||||
_ = @import("io_test.zig");
|
||||
}
|
||||
}
|
||||
|
||||
/// The function received invalid input at runtime. An Invalid error means a
|
||||
/// bug in the program that called the function.
|
||||
error Invalid;
|
||||
|
@ -247,17 +253,32 @@ pub const File = struct {
|
|||
}
|
||||
|
||||
pub fn getEndPos(self: &File) -> %usize {
|
||||
var stat: system.Stat = undefined;
|
||||
const err = system.getErrno(system.fstat(self.handle, &stat));
|
||||
if (err > 0) {
|
||||
return switch (err) {
|
||||
system.EBADF => error.BadFd,
|
||||
system.ENOMEM => error.OutOfMemory,
|
||||
else => os.unexpectedErrorPosix(err),
|
||||
if (is_posix) {
|
||||
var stat: system.Stat = undefined;
|
||||
const err = system.getErrno(system.fstat(self.handle, &stat));
|
||||
if (err > 0) {
|
||||
return switch (err) {
|
||||
system.EBADF => error.BadFd,
|
||||
system.ENOMEM => error.OutOfMemory,
|
||||
else => os.unexpectedErrorPosix(err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usize(stat.size);
|
||||
return usize(stat.size);
|
||||
} else if (is_windows) {
|
||||
var file_size: system.LARGE_INTEGER = undefined;
|
||||
if (system.GetFileSizeEx(self.handle, &file_size) == 0) {
|
||||
const err = system.GetLastError();
|
||||
return switch (err) {
|
||||
else => os.unexpectedErrorWindows(err),
|
||||
};
|
||||
}
|
||||
if (file_size < 0)
|
||||
return error.Overflow;
|
||||
return math.cast(usize, u64(file_size));
|
||||
} else {
|
||||
unreachable;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(self: &File, buffer: []u8) -> %usize {
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
const std = @import("index.zig");
|
||||
const io = std.io;
|
||||
const allocator = std.debug.global_allocator;
|
||||
const Rand = std.rand.Rand;
|
||||
const assert = std.debug.assert;
|
||||
const mem = std.mem;
|
||||
const os = std.os;
|
||||
|
||||
test "write a file, read it, then delete it" {
|
||||
var data: [1024]u8 = undefined;
|
||||
var rng = Rand.init(1234);
|
||||
rng.fillBytes(data[0..]);
|
||||
const tmp_file_name = "temp_test_file.txt";
|
||||
{
|
||||
var file = %%io.File.openWrite(tmp_file_name, allocator);
|
||||
defer file.close();
|
||||
|
||||
var file_out_stream = io.FileOutStream.init(&file);
|
||||
var buf_stream = io.BufferedOutStream.init(&file_out_stream.stream);
|
||||
const st = &buf_stream.stream;
|
||||
%%st.print("begin");
|
||||
%%st.write(data[0..]);
|
||||
%%st.print("end");
|
||||
%%buf_stream.flush();
|
||||
}
|
||||
{
|
||||
var file = %%io.File.openRead(tmp_file_name, allocator);
|
||||
defer file.close();
|
||||
|
||||
const file_size = %%file.getEndPos();
|
||||
const expected_file_size = "begin".len + data.len + "end".len;
|
||||
assert(file_size == expected_file_size);
|
||||
|
||||
var file_in_stream = io.FileInStream.init(&file);
|
||||
var buf_stream = io.BufferedInStream.init(&file_in_stream.stream);
|
||||
const st = &buf_stream.stream;
|
||||
const contents = %%st.readAllAlloc(allocator, 2 * 1024);
|
||||
defer allocator.free(contents);
|
||||
|
||||
assert(mem.eql(u8, contents[0.."begin".len], "begin"));
|
||||
assert(mem.eql(u8, contents["begin".len..contents.len - "end".len], data));
|
||||
assert(mem.eql(u8, contents[contents.len - "end".len ..], "end"));
|
||||
}
|
||||
%%os.deleteFile(allocator, tmp_file_name);
|
||||
}
|
|
@ -195,7 +195,7 @@ pub fn LinkedList(comptime T: type) -> type {
|
|||
}
|
||||
|
||||
test "basic linked list test" {
|
||||
const allocator = &debug.global_allocator;
|
||||
const allocator = debug.global_allocator;
|
||||
var list = LinkedList(u32).init();
|
||||
|
||||
var one = %%list.createNode(1, allocator);
|
||||
|
|
|
@ -331,8 +331,8 @@ pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 {
|
|||
}
|
||||
|
||||
test "mem.join" {
|
||||
assert(eql(u8, %%join(&debug.global_allocator, ',', "a", "b", "c"), "a,b,c"));
|
||||
assert(eql(u8, %%join(&debug.global_allocator, ',', "a"), "a"));
|
||||
assert(eql(u8, %%join(debug.global_allocator, ',', "a", "b", "c"), "a,b,c"));
|
||||
assert(eql(u8, %%join(debug.global_allocator, ',', "a"), "a"));
|
||||
}
|
||||
|
||||
test "testStringEquality" {
|
||||
|
|
|
@ -129,7 +129,7 @@ pub fn isatty(fd: i32) -> bool {
|
|||
}
|
||||
|
||||
pub fn fstat(fd: i32, buf: &c.Stat) -> usize {
|
||||
errnoWrap(c.fstat(fd, buf))
|
||||
errnoWrap(c.@"fstat$INODE64"(fd, buf))
|
||||
}
|
||||
|
||||
pub fn lseek(fd: i32, offset: isize, whence: c_int) -> usize {
|
||||
|
|
|
@ -562,7 +562,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 {
|
|||
|
||||
test "os.getCwd" {
|
||||
// at least call it so it gets compiled
|
||||
_ = getCwd(&debug.global_allocator);
|
||||
_ = getCwd(debug.global_allocator);
|
||||
}
|
||||
|
||||
pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {
|
||||
|
@ -1432,10 +1432,10 @@ test "windows arg parsing" {
|
|||
fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const u8) {
|
||||
var it = ArgIteratorWindows.initWithCmdLine(input_cmd_line);
|
||||
for (expected_args) |expected_arg| {
|
||||
const arg = %%??it.next(&debug.global_allocator);
|
||||
const arg = %%??it.next(debug.global_allocator);
|
||||
assert(mem.eql(u8, arg, expected_arg));
|
||||
}
|
||||
assert(it.next(&debug.global_allocator) == null);
|
||||
assert(it.next(debug.global_allocator) == null);
|
||||
}
|
||||
|
||||
test "std.os" {
|
||||
|
@ -1500,4 +1500,3 @@ pub fn isTty(handle: FileHandle) -> bool {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,23 +41,23 @@ pub fn joinPosix(allocator: &Allocator, paths: ...) -> %[]u8 {
|
|||
}
|
||||
|
||||
test "os.path.join" {
|
||||
assert(mem.eql(u8, %%joinWindows(&debug.global_allocator, "c:\\a\\b", "c"), "c:\\a\\b\\c"));
|
||||
assert(mem.eql(u8, %%joinWindows(&debug.global_allocator, "c:\\a\\b\\", "c"), "c:\\a\\b\\c"));
|
||||
assert(mem.eql(u8, %%joinWindows(debug.global_allocator, "c:\\a\\b", "c"), "c:\\a\\b\\c"));
|
||||
assert(mem.eql(u8, %%joinWindows(debug.global_allocator, "c:\\a\\b\\", "c"), "c:\\a\\b\\c"));
|
||||
|
||||
assert(mem.eql(u8, %%joinWindows(&debug.global_allocator, "c:\\", "a", "b\\", "c"), "c:\\a\\b\\c"));
|
||||
assert(mem.eql(u8, %%joinWindows(&debug.global_allocator, "c:\\a\\", "b\\", "c"), "c:\\a\\b\\c"));
|
||||
assert(mem.eql(u8, %%joinWindows(debug.global_allocator, "c:\\", "a", "b\\", "c"), "c:\\a\\b\\c"));
|
||||
assert(mem.eql(u8, %%joinWindows(debug.global_allocator, "c:\\a\\", "b\\", "c"), "c:\\a\\b\\c"));
|
||||
|
||||
assert(mem.eql(u8, %%joinWindows(&debug.global_allocator,
|
||||
assert(mem.eql(u8, %%joinWindows(debug.global_allocator,
|
||||
"c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std", "io.zig"),
|
||||
"c:\\home\\andy\\dev\\zig\\build\\lib\\zig\\std\\io.zig"));
|
||||
|
||||
assert(mem.eql(u8, %%joinPosix(&debug.global_allocator, "/a/b", "c"), "/a/b/c"));
|
||||
assert(mem.eql(u8, %%joinPosix(&debug.global_allocator, "/a/b/", "c"), "/a/b/c"));
|
||||
assert(mem.eql(u8, %%joinPosix(debug.global_allocator, "/a/b", "c"), "/a/b/c"));
|
||||
assert(mem.eql(u8, %%joinPosix(debug.global_allocator, "/a/b/", "c"), "/a/b/c"));
|
||||
|
||||
assert(mem.eql(u8, %%joinPosix(&debug.global_allocator, "/", "a", "b/", "c"), "/a/b/c"));
|
||||
assert(mem.eql(u8, %%joinPosix(&debug.global_allocator, "/a/", "b/", "c"), "/a/b/c"));
|
||||
assert(mem.eql(u8, %%joinPosix(debug.global_allocator, "/", "a", "b/", "c"), "/a/b/c"));
|
||||
assert(mem.eql(u8, %%joinPosix(debug.global_allocator, "/a/", "b/", "c"), "/a/b/c"));
|
||||
|
||||
assert(mem.eql(u8, %%joinPosix(&debug.global_allocator, "/home/andy/dev/zig/build/lib/zig/std", "io.zig"),
|
||||
assert(mem.eql(u8, %%joinPosix(debug.global_allocator, "/home/andy/dev/zig/build/lib/zig/std", "io.zig"),
|
||||
"/home/andy/dev/zig/build/lib/zig/std/io.zig"));
|
||||
}
|
||||
|
||||
|
@ -453,7 +453,7 @@ pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {
|
|||
}
|
||||
|
||||
test "os.path.resolve" {
|
||||
const cwd = %%os.getCwd(&debug.global_allocator);
|
||||
const cwd = %%os.getCwd(debug.global_allocator);
|
||||
if (is_windows) {
|
||||
assert(mem.eql(u8, testResolveWindows([][]const u8{"."}), cwd));
|
||||
} else {
|
||||
|
@ -492,11 +492,11 @@ test "os.path.resolvePosix" {
|
|||
}
|
||||
|
||||
fn testResolveWindows(paths: []const []const u8) -> []u8 {
|
||||
return %%resolveWindows(&debug.global_allocator, paths);
|
||||
return %%resolveWindows(debug.global_allocator, paths);
|
||||
}
|
||||
|
||||
fn testResolvePosix(paths: []const []const u8) -> []u8 {
|
||||
return %%resolvePosix(&debug.global_allocator, paths);
|
||||
return %%resolvePosix(debug.global_allocator, paths);
|
||||
}
|
||||
|
||||
pub fn dirname(path: []const u8) -> []const u8 {
|
||||
|
@ -899,12 +899,12 @@ test "os.path.relative" {
|
|||
}
|
||||
|
||||
fn testRelativePosix(from: []const u8, to: []const u8, expected_output: []const u8) {
|
||||
const result = %%relativePosix(&debug.global_allocator, from, to);
|
||||
const result = %%relativePosix(debug.global_allocator, from, to);
|
||||
assert(mem.eql(u8, result, expected_output));
|
||||
}
|
||||
|
||||
fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []const u8) {
|
||||
const result = %%relativeWindows(&debug.global_allocator, from, to);
|
||||
const result = %%relativeWindows(debug.global_allocator, from, to);
|
||||
assert(mem.eql(u8, result, expected_output));
|
||||
}
|
||||
|
||||
|
@ -1022,5 +1022,5 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
|
|||
|
||||
test "os.path.real" {
|
||||
// at least call it so it gets compiled
|
||||
_ = real(&debug.global_allocator, "some_path");
|
||||
_ = real(debug.global_allocator, "some_path");
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuf
|
|||
|
||||
pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: &DWORD) -> BOOL;
|
||||
|
||||
pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: &LARGE_INTEGER) -> BOOL;
|
||||
|
||||
pub extern "kernel32" stdcallcc fn GetLastError() -> DWORD;
|
||||
|
||||
pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(in_hFile: HANDLE,
|
||||
|
@ -115,6 +117,7 @@ pub const ULONG_PTR = usize;
|
|||
pub const UNICODE = false;
|
||||
pub const WCHAR = u16;
|
||||
pub const WORD = u16;
|
||||
pub const LARGE_INTEGER = i64;
|
||||
|
||||
pub const TRUE = 1;
|
||||
pub const FALSE = 0;
|
||||
|
|
Loading…
Reference in New Issue