mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 15:42:49 +00:00
af536ac343
* remove setFnTest builtin * add test "name" { ... } syntax * remove --check-unused argument. functions are always lazy now.
172 lines
4.8 KiB
Zig
172 lines
4.8 KiB
Zig
const List = @import("list.zig").List;
|
|
const mem = @import("mem.zig");
|
|
const Allocator = mem.Allocator;
|
|
const debug = @import("debug.zig");
|
|
const assert = debug.assert;
|
|
|
|
const strlen = len;
|
|
|
|
pub fn len(ptr: &const u8) -> usize {
|
|
var count: usize = 0;
|
|
while (ptr[count] != 0; count += 1) {}
|
|
return count;
|
|
}
|
|
|
|
pub fn cmp(a: &const u8, b: &const u8) -> i8 {
|
|
var index: usize = 0;
|
|
while (a[index] == b[index] && a[index] != 0; index += 1) {}
|
|
if (a[index] > b[index]) {
|
|
return 1;
|
|
} else if (a[index] < b[index]) {
|
|
return -1;
|
|
} else {
|
|
return 0;
|
|
};
|
|
}
|
|
|
|
pub fn toSliceConst(str: &const u8) -> []const u8 {
|
|
return str[0...strlen(str)];
|
|
}
|
|
|
|
pub fn toSlice(str: &u8) -> []u8 {
|
|
return str[0...strlen(str)];
|
|
}
|
|
|
|
|
|
/// A buffer that allocates memory and maintains a null byte at the end.
|
|
pub const Buffer0 = struct {
|
|
list: List(u8),
|
|
|
|
/// Must deinitialize with deinit.
|
|
pub fn initEmpty(allocator: &Allocator) -> %Buffer0 {
|
|
return initSize(allocator, 0);
|
|
}
|
|
|
|
/// Must deinitialize with deinit.
|
|
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) -> %Buffer0 {
|
|
return Buffer0.initFromMem(allocator, s[0...strlen(s)]);
|
|
}
|
|
|
|
/// Must deinitialize with deinit.
|
|
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 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: &Buffer0) {
|
|
self.list.deinit();
|
|
}
|
|
|
|
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 Buffer0) -> usize {
|
|
return self.list.len - 1;
|
|
}
|
|
|
|
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.toSlice()[old_len...], m);
|
|
}
|
|
|
|
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 appendByte(self: &Buffer0, byte: u8) -> %void {
|
|
%return self.resize(self.len() + 1);
|
|
self.list.items[self.len() - 1] = byte;
|
|
}
|
|
|
|
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 Buffer0, s: &const u8) -> bool {
|
|
self.eqlMem(s[0...strlen(s)])
|
|
}
|
|
|
|
pub fn eqlOther(self: &const Buffer0, other: &const Buffer0) -> bool {
|
|
self.eqlMem(other.list.items[0...other.len()])
|
|
}
|
|
|
|
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 startsWithOther(self: &const Buffer0, other: &const Buffer0) -> bool {
|
|
self.startsWithMem(other.list.items[0...other.len()])
|
|
}
|
|
|
|
pub fn startsWithCStr(self: &const Buffer0, s: &const u8) -> bool {
|
|
self.startsWithMem(s[0...strlen(s)])
|
|
}
|
|
};
|
|
|
|
test "simple Buffer0" {
|
|
var buf = %%Buffer0.initEmpty(&debug.global_allocator);
|
|
assert(buf.len() == 0);
|
|
%%buf.appendCStr(c"hello");
|
|
%%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 = %%Buffer0.initFromOther(&buf);
|
|
assert(buf.eqlOther(&buf2));
|
|
|
|
assert(buf.startsWithMem("hell"));
|
|
assert(buf.startsWithCStr(c"hell"));
|
|
|
|
%%buf2.resize(4);
|
|
assert(buf.startsWithOther(&buf2));
|
|
}
|
|
|
|
test "cstr fns" {
|
|
comptime testCStrFnsImpl();
|
|
testCStrFnsImpl();
|
|
}
|
|
|
|
fn testCStrFnsImpl() {
|
|
assert(cmp(c"aoeu", c"aoez") == -1);
|
|
assert(len(c"123456789") == 9);
|
|
}
|