| author | |
| committer | |
| log | 0a868dacdd31b7d5c529a332da718683477a2505 |
| tree | a5d91a35d7f66b78c26110923eda548e52eb6258 |
| parent | 852eb272bf895ee6fc242e298e31d666caa9d0df |
Signed-off-by: Eric Joldasov <bratishkaerik@getgoogleoff.me>12 files changed, 38 insertions(+), 116 deletions(-)
lib/c.zig+5-1| ... | ... | @@ -153,7 +153,11 @@ test "strncat" { |
| 153 | 153 | } |
| 154 | 154 | |
| 155 | 155 | fn strcmp(s1: [*:0]const u8, s2: [*:0]const u8) callconv(.C) c_int { |
| 156 | return std.cstr.cmp(s1, s2); | |
| 156 | return switch (std.mem.orderZ(u8, s1, s2)) { | |
| 157 | .lt => -1, | |
| 158 | .eq => 0, | |
| 159 | .gt => 1, | |
| 160 | }; | |
| 157 | 161 | } |
| 158 | 162 | |
| 159 | 163 | fn strlen(s: [*:0]const u8) callconv(.C) usize { |
lib/std/child_process.zig-1| ... | ... | @@ -1,6 +1,5 @@ |
| 1 | 1 | const std = @import("std.zig"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | const cstr = std.cstr; | |
| 4 | 3 | const unicode = std.unicode; |
| 5 | 4 | const io = std.io; |
| 6 | 5 | const fs = std.fs; |
lib/std/cstr.zig+3-100| ... | ... | @@ -1,100 +1,3 @@ |
| 1 | const std = @import("std.zig"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | const debug = std.debug; | |
| 4 | const mem = std.mem; | |
| 5 | const testing = std.testing; | |
| 6 | ||
| 7 | pub const line_sep = switch (builtin.os.tag) { | |
| 8 | .windows => "\r\n", | |
| 9 | else => "\n", | |
| 10 | }; | |
| 11 | ||
| 12 | pub fn cmp(a: [*:0]const u8, b: [*:0]const u8) i8 { | |
| 13 | var index: usize = 0; | |
| 14 | while (a[index] == b[index] and a[index] != 0) : (index += 1) {} | |
| 15 | if (a[index] > b[index]) { | |
| 16 | return 1; | |
| 17 | } else if (a[index] < b[index]) { | |
| 18 | return -1; | |
| 19 | } else { | |
| 20 | return 0; | |
| 21 | } | |
| 22 | } | |
| 23 | ||
| 24 | test "cstr fns" { | |
| 25 | try comptime testCStrFnsImpl(); | |
| 26 | try testCStrFnsImpl(); | |
| 27 | } | |
| 28 | ||
| 29 | fn testCStrFnsImpl() !void { | |
| 30 | try testing.expect(cmp("aoeu", "aoez") == -1); | |
| 31 | } | |
| 32 | ||
| 33 | /// Returns a mutable, null-terminated slice with the same length as `slice`. | |
| 34 | /// Caller owns the returned memory. | |
| 35 | pub fn addNullByte(allocator: mem.Allocator, slice: []const u8) ![:0]u8 { | |
| 36 | const result = try allocator.alloc(u8, slice.len + 1); | |
| 37 | @memcpy(result[0..slice.len], slice); | |
| 38 | result[slice.len] = 0; | |
| 39 | return result[0..slice.len :0]; | |
| 40 | } | |
| 41 | ||
| 42 | test "addNullByte" { | |
| 43 | const slice = try addNullByte(std.testing.allocator, "hello"[0..4]); | |
| 44 | defer std.testing.allocator.free(slice); | |
| 45 | try testing.expect(slice.len == 4); | |
| 46 | try testing.expect(slice[4] == 0); | |
| 47 | } | |
| 48 | ||
| 49 | pub const NullTerminated2DArray = struct { | |
| 50 | allocator: mem.Allocator, | |
| 51 | byte_count: usize, | |
| 52 | ptr: ?[*:null]?[*:0]u8, | |
| 53 | ||
| 54 | /// Takes N lists of strings, concatenates the lists together, and adds a null terminator | |
| 55 | /// Caller must deinit result | |
| 56 | pub fn fromSlices(allocator: mem.Allocator, slices: []const []const []const u8) !NullTerminated2DArray { | |
| 57 | var new_len: usize = 1; // 1 for the list null | |
| 58 | var byte_count: usize = 0; | |
| 59 | for (slices) |slice| { | |
| 60 | new_len += slice.len; | |
| 61 | for (slice) |inner| { | |
| 62 | byte_count += inner.len; | |
| 63 | } | |
| 64 | byte_count += slice.len; // for the null terminators of inner | |
| 65 | } | |
| 66 | ||
| 67 | const index_size = @sizeOf(usize) * new_len; // size of the ptrs | |
| 68 | byte_count += index_size; | |
| 69 | ||
| 70 | const buf = try allocator.alignedAlloc(u8, @alignOf(?*u8), byte_count); | |
| 71 | errdefer allocator.free(buf); | |
| 72 | ||
| 73 | var write_index = index_size; | |
| 74 | const index_buf = mem.bytesAsSlice(?[*]u8, buf); | |
| 75 | ||
| 76 | var i: usize = 0; | |
| 77 | for (slices) |slice| { | |
| 78 | for (slice) |inner| { | |
| 79 | index_buf[i] = buf.ptr + write_index; | |
| 80 | i += 1; | |
| 81 | @memcpy(buf[write_index..][0..inner.len], inner); | |
| 82 | write_index += inner.len; | |
| 83 | buf[write_index] = 0; | |
| 84 | write_index += 1; | |
| 85 | } | |
| 86 | } | |
| 87 | index_buf[i] = null; | |
| 88 | ||
| 89 | return NullTerminated2DArray{ | |
| 90 | .allocator = allocator, | |
| 91 | .byte_count = byte_count, | |
| 92 | .ptr = @as(?[*:null]?[*:0]u8, @ptrCast(buf.ptr)), | |
| 93 | }; | |
| 94 | } | |
| 95 | ||
| 96 | pub fn deinit(self: *NullTerminated2DArray) void { | |
| 97 | const buf = @as([*]u8, @ptrCast(self.ptr)); | |
| 98 | self.allocator.free(buf[0..self.byte_count]); | |
| 99 | } | |
| 100 | }; | |
| 1 | pub const line_sep = @compileError("deprecated; choose correct end-of-line sequence of characters by yourself instead"); | |
| 2 | pub const cmp = @compileError("deprecated; use `std.mem.orderZ` instead"); | |
| 3 | pub const addNullByte = @compileError("deprecated; use `allocator.dupeZ(u8, stuff)` instead"); |
lib/std/mem.zig+13-1| ... | ... | @@ -607,12 +607,24 @@ pub fn order(comptime T: type, lhs: []const T, rhs: []const T) math.Order { |
| 607 | 607 | return math.order(lhs.len, rhs.len); |
| 608 | 608 | } |
| 609 | 609 | |
| 610 | test "order" { | |
| 610 | /// Compares two many-item pointers with NUL-termination lexicographically. | |
| 611 | pub fn orderZ(comptime T: type, lhs: [*:0]const T, rhs: [*:0]const T) math.Order { | |
| 612 | var i: usize = 0; | |
| 613 | while (lhs[i] == rhs[i] and lhs[i] != 0) : (i += 1) {} | |
| 614 | return math.order(lhs[i], rhs[i]); | |
| 615 | } | |
| 616 | ||
| 617 | test "order and orderZ" { | |
| 611 | 618 | try testing.expect(order(u8, "abcd", "bee") == .lt); |
| 619 | try testing.expect(orderZ(u8, "abcd", "bee") == .lt); | |
| 612 | 620 | try testing.expect(order(u8, "abc", "abc") == .eq); |
| 621 | try testing.expect(orderZ(u8, "abc", "abc") == .eq); | |
| 613 | 622 | try testing.expect(order(u8, "abc", "abc0") == .lt); |
| 623 | try testing.expect(orderZ(u8, "abc", "abc0") == .lt); | |
| 614 | 624 | try testing.expect(order(u8, "", "") == .eq); |
| 625 | try testing.expect(orderZ(u8, "", "") == .eq); | |
| 615 | 626 | try testing.expect(order(u8, "", "a") == .lt); |
| 627 | try testing.expect(orderZ(u8, "", "a") == .lt); | |
| 616 | 628 | } |
| 617 | 629 | |
| 618 | 630 | /// Returns true if lhs < rhs, false otherwise |
lib/std/net.zig+2-2| ... | ... | @@ -783,7 +783,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) Get |
| 783 | 783 | errdefer result.deinit(); |
| 784 | 784 | |
| 785 | 785 | if (builtin.target.os.tag == .windows) { |
| 786 | const name_c = try std.cstr.addNullByte(allocator, name); | |
| 786 | const name_c = try allocator.dupeZ(u8, name); | |
| 787 | 787 | defer allocator.free(name_c); |
| 788 | 788 | |
| 789 | 789 | const port_c = try std.fmt.allocPrintZ(allocator, "{}", .{port}); |
| ... | ... | @@ -855,7 +855,7 @@ pub fn getAddressList(allocator: mem.Allocator, name: []const u8, port: u16) Get |
| 855 | 855 | } |
| 856 | 856 | |
| 857 | 857 | if (builtin.link_libc) { |
| 858 | const name_c = try std.cstr.addNullByte(allocator, name); | |
| 858 | const name_c = try allocator.dupeZ(u8, name); | |
| 859 | 859 | defer allocator.free(name_c); |
| 860 | 860 | |
| 861 | 861 | const port_c = try std.fmt.allocPrintZ(allocator, "{}", .{port}); |
lib/std/zig/c_builtins.zig+5-1| ... | ... | @@ -126,7 +126,11 @@ pub inline fn __builtin_strlen(s: [*c]const u8) usize { |
| 126 | 126 | return std.mem.sliceTo(s, 0).len; |
| 127 | 127 | } |
| 128 | 128 | pub inline fn __builtin_strcmp(s1: [*c]const u8, s2: [*c]const u8) c_int { |
| 129 | return @as(c_int, std.cstr.cmp(s1, s2)); | |
| 129 | return switch (std.mem.orderZ(u8, s1, s2)) { | |
| 130 | .lt => -1, | |
| 131 | .eq => 0, | |
| 132 | .gt => 1, | |
| 133 | }; | |
| 130 | 134 | } |
| 131 | 135 | |
| 132 | 136 | pub inline fn __builtin_object_size(ptr: ?*const anyopaque, ty: c_int) usize { |
src/Compilation.zig+1-1| ... | ... | @@ -5066,7 +5066,7 @@ fn parseLldStderr(comp: *Compilation, comptime prefix: []const u8, stderr: []con |
| 5066 | 5066 | defer context_lines.deinit(); |
| 5067 | 5067 | |
| 5068 | 5068 | var current_err: ?*LldError = null; |
| 5069 | var lines = mem.splitSequence(u8, stderr, std.cstr.line_sep); | |
| 5069 | var lines = mem.splitSequence(u8, stderr, if (builtin.os.tag == .windows) "\r\n" else "\n"); | |
| 5070 | 5070 | while (lines.next()) |line| { |
| 5071 | 5071 | if (mem.startsWith(u8, line, prefix ++ ":")) { |
| 5072 | 5072 | if (current_err) |err| { |
src/codegen/c/type.zig+1-2| ... | ... | @@ -1,5 +1,4 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | const cstr = std.cstr; | |
| 3 | 2 | const mem = std.mem; |
| 4 | 3 | const Allocator = mem.Allocator; |
| 5 | 4 | const assert = std.debug.assert; |
| ... | ... | @@ -1025,7 +1024,7 @@ pub const CType = extern union { |
| 1025 | 1024 | for (lhs_data, rhs_data) |lhs_field, rhs_field| { |
| 1026 | 1025 | if (!ctx.eqlIndex(lhs_field.type, rhs_field.type)) return false; |
| 1027 | 1026 | if (lhs_field.alignas.@"align" != rhs_field.alignas.@"align") return false; |
| 1028 | if (cstr.cmp(lhs_field.name, rhs_field.name) != 0) return false; | |
| 1027 | if (std.mem.orderZ(u8, lhs_field.name, rhs_field.name) != .eq) return false; | |
| 1029 | 1028 | } |
| 1030 | 1029 | return true; |
| 1031 | 1030 | }, |
test/behavior/basic.zig+1-1| ... | ... | @@ -647,7 +647,7 @@ test "multiline string literal is null terminated" { |
| 647 | 647 | \\three |
| 648 | 648 | ; |
| 649 | 649 | const s2 = "one\ntwo)\nthree"; |
| 650 | try expect(std.cstr.cmp(s1, s2) == 0); | |
| 650 | try expect(std.mem.orderZ(u8, s1, s2) == .eq); | |
| 651 | 651 | } |
| 652 | 652 | |
| 653 | 653 | test "string escapes" { |
test/cbe.zig+5-4| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const Cases = @import("src/Cases.zig"); |
| 3 | const nl = if (@import("builtin").os.tag == .windows) "\r\n" else "\n"; | |
| 3 | 4 | |
| 4 | 5 | // These tests should work with all platforms, but we're using linux_x64 for |
| 5 | 6 | // now for consistency. Will be expanded eventually. |
| ... | ... | @@ -19,7 +20,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 19 | 20 | \\ _ = puts("hello world!"); |
| 20 | 21 | \\ return 0; |
| 21 | 22 | \\} |
| 22 | , "hello world!" ++ std.cstr.line_sep); | |
| 23 | , "hello world!" ++ nl); | |
| 23 | 24 | |
| 24 | 25 | // Now change the message only |
| 25 | 26 | case.addCompareOutput( |
| ... | ... | @@ -28,7 +29,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 28 | 29 | \\ _ = puts("yo"); |
| 29 | 30 | \\ return 0; |
| 30 | 31 | \\} |
| 31 | , "yo" ++ std.cstr.line_sep); | |
| 32 | , "yo" ++ nl); | |
| 32 | 33 | |
| 33 | 34 | // Add an unused Decl |
| 34 | 35 | case.addCompareOutput( |
| ... | ... | @@ -38,7 +39,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 38 | 39 | \\ return 0; |
| 39 | 40 | \\} |
| 40 | 41 | \\fn unused() void {} |
| 41 | , "yo!" ++ std.cstr.line_sep); | |
| 42 | , "yo!" ++ nl); | |
| 42 | 43 | |
| 43 | 44 | // Comptime return type and calling convention expected. |
| 44 | 45 | case.addError( |
| ... | ... | @@ -67,7 +68,7 @@ pub fn addCases(ctx: *Cases) !void { |
| 67 | 68 | \\ _ = printf("Hello, %s!\n", "world"); |
| 68 | 69 | \\ return 0; |
| 69 | 70 | \\} |
| 70 | , "Hello, world!" ++ std.cstr.line_sep); | |
| 71 | , "Hello, world!" ++ nl); | |
| 71 | 72 | } |
| 72 | 73 | |
| 73 | 74 | { |
test/compare_output.zig+1-1| ... | ... | @@ -15,7 +15,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { |
| 15 | 15 | \\ _ = c.puts("Hello, world!"); |
| 16 | 16 | \\ return 0; |
| 17 | 17 | \\} |
| 18 | , "Hello, world!" ++ std.cstr.line_sep); | |
| 18 | , "Hello, world!" ++ if (@import("builtin").os.tag == .windows) "\r\n" else "\n"); | |
| 19 | 19 | |
| 20 | 20 | cases.add("hello world without libc", |
| 21 | 21 | \\const io = @import("std").io; |
test/run_translated_c.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const tests = @import("tests.zig"); |
| 3 | const nl = std.cstr.line_sep; | |
| 3 | const nl = if (@import("builtin").os.tag == .windows) "\r\n" else "\n"; | |
| 4 | 4 | |
| 5 | 5 | pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 6 | 6 | cases.add("dereference address of", |