diff --git a/CMakeLists.txt b/CMakeLists.txt index cf0f41dd0..502eef605 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,6 +194,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/test_runner_libc.zig" DESTINATION "${ZIG_ install(FILES "${CMAKE_SOURCE_DIR}/std/test_runner_nolibc.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/io.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/os.zig" DESTINATION "${ZIG_STD_DEST}") +install(FILES "${CMAKE_SOURCE_DIR}/std/str.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/linux.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/errno.zig" DESTINATION "${ZIG_STD_DEST}") install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}") diff --git a/example/cat/main.zig b/example/cat/main.zig index 97e04b6ea..7b2a2c0d3 100644 --- a/example/cat/main.zig +++ b/example/cat/main.zig @@ -1,4 +1,6 @@ -use @import("std"); +const std = @import("std"); +const io = std.io; +const str = std.str; // TODO var args printing @@ -6,7 +8,7 @@ pub fn main(args: [][]u8) -> %void { const exe = args[0]; var catted_anything = false; for (args[1...]) |arg| { - if (str_eql(arg, "-")) { + if (str.eql(arg, "-")) { catted_anything = true; cat_stream(io.stdin) %% |err| return err; } else if (arg[0] == '-') { diff --git a/std/bootstrap.zig b/std/bootstrap.zig index 849567e3c..f381311b0 100644 --- a/std/bootstrap.zig +++ b/std/bootstrap.zig @@ -2,6 +2,7 @@ const root = @import("@root"); const linux = @import("linux.zig"); +const str = @import("str.zig"); const want_start_symbol = switch(@compile_var("os")) { linux => true, @@ -29,19 +30,11 @@ export fn _start() -> unreachable { call_main_and_exit() } -fn strlen(ptr: &const u8) -> isize { - var count: isize = 0; - while (ptr[count] != 0) { - count += 1; - } - return count; -} - fn call_main() -> %void { var args: [argc][]u8 = undefined; for (args) |arg, i| { const ptr = argv[i]; - args[i] = ptr[0...strlen(ptr)]; + args[i] = ptr[0...str.len(ptr)]; } return root.main(args); } diff --git a/std/index.zig b/std/index.zig index a7bcfc446..e5a77be1f 100644 --- a/std/index.zig +++ b/std/index.zig @@ -2,24 +2,9 @@ pub const Rand = @import("rand.zig").Rand; pub const io = @import("io.zig"); pub const os = @import("os.zig"); pub const math = @import("math.zig"); +pub const str = @import("str.zig"); pub fn assert(b: bool) { if (!b) unreachable{} } -pub const str_eql = slice_eql(u8); - -pub fn slice_eql(T: type)(a: []const T, b: []const T) -> bool { - if (a.len != b.len) return false; - for (a) |item, index| { - if (b[index] != item) return false; - } - return true; -} - -#attribute("test") -fn string_equality() { - assert(str_eql("abcd", "abcd")); - assert(!str_eql("abcdef", "abZdef")); - assert(!str_eql("abcdefg", "abcdef")); -} diff --git a/std/io.zig b/std/io.zig index f579db6cd..07a480f09 100644 --- a/std/io.zig +++ b/std/io.zig @@ -207,13 +207,6 @@ pub struct InStream { } } -#attribute("cold") -pub fn abort() -> unreachable { - linux.raise(linux.SIGABRT); - linux.raise(linux.SIGKILL); - while (true) {} -} - pub error InvalidChar; pub error Overflow; diff --git a/std/os.zig b/std/os.zig index 5e0ee4878..8771e48bb 100644 --- a/std/os.zig +++ b/std/os.zig @@ -26,3 +26,11 @@ pub fn get_random_bytes(buf: []u8) -> %void { else => unreachable{}, } } + +#attribute("cold") +pub fn abort() -> unreachable { + linux.raise(linux.SIGABRT); + linux.raise(linux.SIGKILL); + while (true) {} +} + diff --git a/std/str.zig b/std/str.zig new file mode 100644 index 000000000..7df0c5658 --- /dev/null +++ b/std/str.zig @@ -0,0 +1,34 @@ +const assert = @import("index.zig").assert; + +pub fn len(ptr: &const u8) -> isize { + var count: isize = 0; + while (ptr[count] != 0) { + count += 1; + } + return count; +} + +pub fn from_c_const(str: &const u8) -> []const u8 { + return str[0...len(str)]; +} + +pub fn from_c(str: &u8) -> []u8 { + return str[0...len(str)]; +} + +pub const eql = slice_eql(u8); + +pub fn slice_eql(T: type)(a: []const T, b: []const T) -> bool { + if (a.len != b.len) return false; + for (a) |item, index| { + if (b[index] != item) return false; + } + return true; +} + +#attribute("test") +fn string_equality() { + assert(eql("abcd", "abcd")); + assert(!eql("abcdef", "abZdef")); + assert(!eql("abcdefg", "abcdef")); +} diff --git a/test/self_hosted.zig b/test/self_hosted.zig index 1ab673db1..bfc43a322 100644 --- a/test/self_hosted.zig +++ b/test/self_hosted.zig @@ -1,5 +1,7 @@ // test std library -use @import("std"); +const std = @import("std"); +const assert = std.assert; +const str = std.str; #attribute("test") fn empty_function() {} @@ -701,8 +703,8 @@ three)AOEU"; one two) three)"; - assert(str_eql(s1, s2)); - assert(str_eql(s3, s2)); + assert(str.eql(s1, s2)); + assert(str.eql(s3, s2)); } @@ -760,7 +762,7 @@ fn accepts_string(foo: []u8) { } #attribute("test") fn hex_escape() { - assert(str_eql("\x68\x65\x6c\x6c\x6f", "hello")); + assert(str.eql("\x68\x65\x6c\x6c\x6f", "hello")); } @@ -768,8 +770,8 @@ error AnError; error ALongerErrorName; #attribute("test") fn error_name_string() { - assert(str_eql(@err_name(error.AnError), "AnError")); - assert(str_eql(@err_name(error.ALongerErrorName), "ALongerErrorName")); + assert(str.eql(@err_name(error.AnError), "AnError")); + assert(str.eql(@err_name(error.ALongerErrorName), "ALongerErrorName")); } @@ -1069,12 +1071,12 @@ fn overflow_intrinsics() { #attribute("test") fn nested_arrays() { const array_of_strings = [][]u8 {"hello", "this", "is", "my", "thing"}; - for (array_of_strings) |str, i| { - if (i == 0) assert(str_eql(str, "hello")); - if (i == 1) assert(str_eql(str, "this")); - if (i == 2) assert(str_eql(str, "is")); - if (i == 3) assert(str_eql(str, "my")); - if (i == 4) assert(str_eql(str, "thing")); + for (array_of_strings) |s, i| { + if (i == 0) assert(str.eql(s, "hello")); + if (i == 1) assert(str.eql(s, "this")); + if (i == 2) assert(str.eql(s, "is")); + if (i == 3) assert(str.eql(s, "my")); + if (i == 4) assert(str.eql(s, "thing")); } } @@ -1088,7 +1090,7 @@ fn int_to_ptr_cast() { #attribute("test") fn string_concatenation() { - assert(str_eql("OK" ++ " IT " ++ "WORKED", "OK IT WORKED")); + assert(str.eql("OK" ++ " IT " ++ "WORKED", "OK IT WORKED")); } #attribute("test") @@ -1185,8 +1187,8 @@ fn test_pointer_to_void_return_type_2() -> &void { #attribute("test") fn call_result_of_if_else_expression() { - assert(str_eql(f2(true), "a")); - assert(str_eql(f2(false), "b")); + assert(str.eql(f2(true), "a")); + assert(str.eql(f2(false), "b")); } fn f2(x: bool) -> []u8 { return (if (x) f_a else f_b)();