Commit 9eb29e81f9

Andrew Kelley <superjoe30@gmail.com>
2017-02-28 09:07:11
rename CBuf to Buffer0 and some minor std API changes
1 parent 1195994
Changed files (5)
std/cstr.zig
@@ -34,131 +34,142 @@ pub fn toSlice(str: &u8) -> []u8 {
 
 
 /// A buffer that allocates memory and maintains a null byte at the end.
-pub const CBuf = struct {
+pub const Buffer0 = struct {
     list: List(u8),
 
     /// Must deinitialize with deinit.
-    pub fn initEmpty(allocator: &Allocator) -> %CBuf {
-        var self = CBuf {
-            .list = List(u8).init(allocator),
-        };
-        %return self.resize(0);
-        return self;
+    pub fn initEmpty(allocator: &Allocator) -> %Buffer0 {
+        return initSize(allocator, 0);
     }
 
     /// Must deinitialize with deinit.
-    pub fn initFromMem(allocator: &Allocator, m: []const u8) -> %CBuf {
-        var self = CBuf {
-            .list = List(u8).init(allocator),
-        };
-        %return self.resize(m.len);
+    pub fn initFromMem(allocator: &Allocator, m: []const u8) -> %Buffer0 {
+        var self = %return initSize(allocator, m.len);
         mem.copy(u8, self.list.items, m);
         return self;
     }
 
     /// Must deinitialize with deinit.
-    pub fn initFromCStr(allocator: &Allocator, s: &const u8) -> %CBuf {
-        return CBuf.initFromMem(allocator, s[0...strlen(s)]);
+    pub fn initFromCStr(allocator: &Allocator, s: &const u8) -> %Buffer0 {
+        return Buffer0.initFromMem(allocator, s[0...strlen(s)]);
     }
 
     /// Must deinitialize with deinit.
-    pub fn initFromCBuf(cbuf: &const CBuf) -> %CBuf {
-        return CBuf.initFromMem(cbuf.list.allocator, cbuf.list.items[0...cbuf.len()]);
+    pub fn initFromOther(cbuf: &const Buffer0) -> %Buffer0 {
+        return Buffer0.initFromMem(cbuf.list.allocator, cbuf.list.items[0...cbuf.len()]);
     }
 
     /// Must deinitialize with deinit.
-    pub fn initFromSlice(other: &const CBuf, start: usize, end: usize) -> %CBuf {
-        return CBuf.initFromMem(other.list.allocator, other.list.items[start...end]);
+    pub fn initFromSlice(other: &const Buffer0, start: usize, end: usize) -> %Buffer0 {
+        return Buffer0.initFromMem(other.list.allocator, other.list.items[start...end]);
+    }
+
+    /// Must deinitialize with deinit.
+    pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer0 {
+        var self = Buffer0 {
+            .list = List(u8).init(allocator),
+        };
+        %return self.resize(size);
+        return self;
     }
 
-    pub fn deinit(self: &CBuf) {
+    pub fn deinit(self: &Buffer0) {
         self.list.deinit();
     }
 
-    pub fn resize(self: &CBuf, new_len: usize) -> %void {
+    pub fn toSlice(self: &Buffer0) -> []u8 {
+        return self.list.toSlice()[0...self.len()];
+    }
+
+    pub fn toSliceConst(self: &const Buffer0) -> []const u8 {
+        return self.list.toSliceConst()[0...self.len()];
+    }
+
+    pub fn resize(self: &Buffer0, new_len: usize) -> %void {
         %return self.list.resize(new_len + 1);
         self.list.items[self.len()] = 0;
     }
 
-    pub fn len(self: &const CBuf) -> usize {
+    pub fn len(self: &const Buffer0) -> usize {
         return self.list.len - 1;
     }
 
-    pub fn appendMem(self: &CBuf, m: []const u8) -> %void {
+    pub fn appendMem(self: &Buffer0, m: []const u8) -> %void {
         const old_len = self.len();
         %return self.resize(old_len + m.len);
-        mem.copy(u8, self.list.items[old_len...], m);
+        mem.copy(u8, self.list.toSlice()[old_len...], m);
     }
 
-    pub fn appendCStr(self: &CBuf, s: &const u8) -> %void {
+    pub fn appendOther(self: &Buffer0, other: &const Buffer0) -> %void {
+        return self.appendMem(other.toSliceConst());
+    }
+
+    pub fn appendCStr(self: &Buffer0, s: &const u8) -> %void {
         self.appendMem(s[0...strlen(s)])
     }
 
-    pub fn appendChar(self: &CBuf, c: u8) -> %void {
+    pub fn appendByte(self: &Buffer0, byte: u8) -> %void {
         %return self.resize(self.len() + 1);
-        self.list.items[self.len() - 1] = c;
+        self.list.items[self.len() - 1] = byte;
     }
 
-    pub fn eqlMem(self: &const CBuf, m: []const u8) -> bool {
+    pub fn eqlMem(self: &const Buffer0, m: []const u8) -> bool {
         if (self.len() != m.len) return false;
         return mem.cmp(u8, self.list.items[0...m.len], m) == mem.Cmp.Equal;
     }
 
-    pub fn eqlCStr(self: &const CBuf, s: &const u8) -> bool {
+    pub fn eqlCStr(self: &const Buffer0, s: &const u8) -> bool {
         self.eqlMem(s[0...strlen(s)])
     }
 
-    pub fn eqlCBuf(self: &const CBuf, other: &const CBuf) -> bool {
+    pub fn eqlOther(self: &const Buffer0, other: &const Buffer0) -> bool {
         self.eqlMem(other.list.items[0...other.len()])
     }
 
-    pub fn startsWithMem(self: &const CBuf, m: []const u8) -> bool {
+    pub fn startsWithMem(self: &const Buffer0, m: []const u8) -> bool {
         if (self.len() < m.len) return false;
         return mem.cmp(u8, self.list.items[0...m.len], m) == mem.Cmp.Equal;
     }
 
-    pub fn startsWithCBuf(self: &const CBuf, other: &const CBuf) -> bool {
+    pub fn startsWithOther(self: &const Buffer0, other: &const Buffer0) -> bool {
         self.startsWithMem(other.list.items[0...other.len()])
     }
 
-    pub fn startsWithCStr(self: &const CBuf, s: &const u8) -> bool {
+    pub fn startsWithCStr(self: &const Buffer0, s: &const u8) -> bool {
         self.startsWithMem(s[0...strlen(s)])
     }
 };
 
-fn testSimpleCBuf() {
+fn testSimpleBuffer0() {
     @setFnTest(this);
 
-    var buf = %%CBuf.initEmpty(&debug.global_allocator);
+    var buf = %%Buffer0.initEmpty(&debug.global_allocator);
     assert(buf.len() == 0);
     %%buf.appendCStr(c"hello");
-    %%buf.appendChar(' ');
+    %%buf.appendByte(' ');
     %%buf.appendMem("world");
     assert(buf.eqlCStr(c"hello world"));
     assert(buf.eqlMem("hello world"));
+    assert(mem.eql(u8, buf.toSliceConst(), "hello world"));
 
-    var buf2 = %%CBuf.initFromCBuf(&buf);
-    assert(buf.eqlCBuf(&buf2));
+    var buf2 = %%Buffer0.initFromOther(&buf);
+    assert(buf.eqlOther(&buf2));
 
     assert(buf.startsWithMem("hell"));
     assert(buf.startsWithCStr(c"hell"));
 
     %%buf2.resize(4);
-    assert(buf.startsWithCBuf(&buf2));
+    assert(buf.startsWithOther(&buf2));
 }
 
-// TODO do this without globals
-
-fn testCompileTimeStrCmp() {
+fn testCStrFns() {
     @setFnTest(this);
 
-    assert(test_compile_time_str_cmp_result);
+    comptime testCStrFnsImpl();
+    testCStrFnsImpl();
 }
-const test_compile_time_str_cmp_result = (cmp(c"aoeu", c"aoez") == -1);
-
-fn testCompileTimeStrLen() {
-    @setFnTest(this);
 
-    assert(test_comptime_str_len_result);
+fn testCStrFnsImpl() {
+    assert(cmp(c"aoeu", c"aoez") == -1);
+    assert(len(c"123456789") == 9);
 }
-const test_comptime_str_len_result = (len(c"123456789") == 9);
std/debug.zig
@@ -164,7 +164,7 @@ const Die = struct {
     };
 
     fn getAttr(self: &const Die, id: u64) -> ?&const FormValue {
-        for (self.attrs.toSlice()) |*attr| {
+        for (self.attrs.toSliceConst()) |*attr| {
             if (attr.id == id)
                 return &attr.value;
         }
@@ -362,7 +362,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable
 }
 
 fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) -> ?&const AbbrevTableEntry {
-    for (abbrev_table.toSlice()) |*table_entry| {
+    for (abbrev_table.toSliceConst()) |*table_entry| {
         if (table_entry.abbrev_code == abbrev_code)
             return table_entry;
     }
@@ -379,7 +379,7 @@ fn parseDie(in_stream: &io.InStream, abbrev_table: &const AbbrevTable, is_64: bo
         .attrs = List(Die.Attr).init(&global_allocator),
     };
     %return result.attrs.resize(table_entry.attrs.len);
-    for (table_entry.attrs.toSlice()) |attr, i| {
+    for (table_entry.attrs.toSliceConst()) |attr, i| {
         result.attrs.items[i] = Die.Attr {
             .id = attr.attr_id,
             .value = %return parseFormValue(in_stream, attr.form_id, is_64),
std/io.zig
@@ -10,6 +10,7 @@ const debug = @import("debug.zig");
 const assert = debug.assert;
 const os = @import("os.zig");
 const mem = @import("mem.zig");
+const Buffer0 = @import("cstr.zig").Buffer0;
 
 pub const stdin_fileno = 0;
 pub const stdout_fileno = 1;
@@ -486,6 +487,23 @@ pub const InStream = struct {
 
         return usize(stat.size);
     }
+
+    pub fn readAll(is: &InStream, buf: &Buffer0) -> %void {
+        %return buf.resize(buffer_size);
+
+        var actual_buf_len: usize = 0;
+        while (true) {
+            const dest_slice = buf.toSlice()[actual_buf_len...];
+            const bytes_read = %return is.read(dest_slice);
+            actual_buf_len += bytes_read;
+
+            if (bytes_read != dest_slice.len) {
+                return buf.resize(actual_buf_len);
+            }
+
+            %return buf.resize(actual_buf_len + buffer_size);
+        }
+    }
 };
 
 pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {
std/list.zig
@@ -7,6 +7,9 @@ pub fn List(comptime T: type) -> type{
     struct {
         const Self = this;
 
+        /// Use toSlice instead of slicing this directly, because if you don't
+        /// specify the end position of the slice, this will potentially give
+        /// you uninitialized memory.
         items: []T,
         len: usize,
         allocator: &Allocator,
@@ -23,15 +26,17 @@ pub fn List(comptime T: type) -> type{
             l.allocator.free(l.items);
         }
 
-        pub fn toSlice(l: &const Self) -> []const T {
+        pub fn toSlice(l: &Self) -> []T {
+            return l.items[0...l.len];
+        }
+
+        pub fn toSliceConst(l: &const Self) -> []const T {
             return l.items[0...l.len];
         }
 
         pub fn append(l: &Self, item: T) -> %void {
-            const new_length = l.len + 1;
-            %return l.ensureCapacity(new_length);
-            l.items[l.len] = item;
-            l.len = new_length;
+            const new_item_ptr = %return l.addOne();
+            *new_item_ptr = item;
         }
 
         pub fn resize(l: &Self, new_len: usize) -> %void {
@@ -48,6 +53,14 @@ pub fn List(comptime T: type) -> type{
             }
             l.items = %return l.allocator.realloc(T, l.items, better_capacity);
         }
+
+        pub fn addOne(l: &Self) -> %&T {
+            const new_length = l.len + 1;
+            %return l.ensureCapacity(new_length);
+            const result = &l.items[l.len];
+            l.len = new_length;
+            return result;
+        }
     }
 }
 
test/cases/try.zig
@@ -3,6 +3,12 @@ const assert = @import("std").debug.assert;
 fn tryOnErrorUnion() {
     @setFnTest(this);
 
+    tryOnErrorUnionImpl();
+    comptime tryOnErrorUnionImpl();
+
+}
+
+fn tryOnErrorUnionImpl() {
     const x = try (const val = returnsTen()) {
         val + 1
     } else |err| switch (err) {
@@ -12,19 +18,6 @@ fn tryOnErrorUnion() {
     assert(x == 11);
 }
 
-fn tryOnErrorUnionComptime() {
-    @setFnTest(this);
-
-    comptime {
-        const x = try (const val = returnsTen()) {
-            val + 1
-        } else |err| switch (err) {
-            error.ItBroke, error.NoMem => 1,
-            error.CrappedOut => i32(2),
-        };
-        assert(x == 11);
-    }
-}
 error ItBroke;
 error NoMem;
 error CrappedOut;
@@ -57,3 +50,14 @@ fn failIfTrue(ok: bool) -> %void {
         return;
     }
 }
+
+// TODO
+//fn tryThenNotExecutedWithAssignment() {
+//    @setFnTest(this);
+//
+//    try (_ = failIfTrue(true)) {
+//        @unreachable();
+//    } else |err| {
+//        assert(err == error.ItBroke);
+//    }
+//}