Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ziglang/zig
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b4e42042cf27
Choose a base ref
...
head repository: ziglang/zig
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 987e0f5acb4b
Choose a head ref
  • 7 commits
  • 6 files changed
  • 1 contributor

Commits on Oct 9, 2017

  1. better support table

    andrewrk committed Oct 9, 2017
    Copy the full SHA
    968ff38 View commit details
  2. Copy the full SHA
    08ee69d View commit details
  3. Copy the full SHA
    dcf5c90 View commit details
  4. Copy the full SHA
    e15e1e0 View commit details
  5. Copy the full SHA
    7cfab2f View commit details
  6. Copy the full SHA
    9d5f15f View commit details
  7. Copy the full SHA
    987e0f5 View commit details
Showing with 822 additions and 109 deletions.
  1. +40 −4 README.md
  2. +2 −2 std/build.zig
  3. +37 −20 std/mem.zig
  4. +48 −12 std/os/index.zig
  5. +691 −70 std/os/path.zig
  6. +4 −1 std/os/windows/index.zig
44 changes: 40 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -43,14 +43,50 @@ clarity.
* Cross-compiling is a primary use case.
* In addition to creating executables, creating a C library is a primary use
case. You can export an auto-generated .h file.
* Standard library supports Operating System abstractions for:
* `x86_64` `linux`
* `x86_64` `macos`
* Support for all popular operating systems and architectures is planned.
* For OS development, Zig supports all architectures that LLVM does. All the
standard library that does not depend on an OS is available to you in
freestanding mode.

### Support Table

Freestanding means that you do not directly interact with the OS
or you are writing your own OS.

Note that if you use libc or other libraries to interact with the OS,
that counts as "freestanding" for the purposes of this table.

| | freestanding | linux | macosx | windows | other |
|-------------|--------------|---------|---------|---------|---------|
|i386 | OK | planned | OK | OK | planned |
|x86_64 | OK | OK | OK | OK | planned |
|arm | OK | planned | planned | N/A | planned |
|aarch64 | OK | planned | planned | planned | planned |
|avr | OK | planned | planned | N/A | planned |
|bpf | OK | planned | planned | N/A | planned |
|hexagon | OK | planned | planned | N/A | planned |
|mips | OK | planned | planned | N/A | planned |
|msp430 | OK | planned | planned | N/A | planned |
|nios2 | OK | planned | planned | N/A | planned |
|powerpc | OK | planned | planned | N/A | planned |
|r600 | OK | planned | planned | N/A | planned |
|amdgcn | OK | planned | planned | N/A | planned |
|riscv | OK | planned | planned | N/A | planned |
|sparc | OK | planned | planned | N/A | planned |
|s390x | OK | planned | planned | N/A | planned |
|tce | OK | planned | planned | N/A | planned |
|thumb | OK | planned | planned | N/A | planned |
|xcore | OK | planned | planned | N/A | planned |
|nvptx | OK | planned | planned | N/A | planned |
|le | OK | planned | planned | N/A | planned |
|amdil | OK | planned | planned | N/A | planned |
|hsail | OK | planned | planned | N/A | planned |
|spir | OK | planned | planned | N/A | planned |
|kalimba | OK | planned | planned | N/A | planned |
|shave | OK | planned | planned | N/A | planned |
|lanai | OK | planned | planned | N/A | planned |
|wasm | OK | N/A | N/A | N/A | N/A |
|renderscript | OK | N/A | N/A | N/A | N/A |

## Community

* IRC: `#zig` on Freenode.
4 changes: 2 additions & 2 deletions std/build.zig
Original file line number Diff line number Diff line change
@@ -309,7 +309,7 @@ pub const Builder = struct {

fn processNixOSEnvVars(self: &Builder) {
if (os.getEnv("NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
var it = mem.split(nix_cflags_compile, ' ');
var it = mem.split(nix_cflags_compile, " ");
while (true) {
const word = it.next() ?? break;
if (mem.eql(u8, word, "-isystem")) {
@@ -325,7 +325,7 @@ pub const Builder = struct {
}
}
if (os.getEnv("NIX_LDFLAGS")) |nix_ldflags| {
var it = mem.split(nix_ldflags, ' ');
var it = mem.split(nix_ldflags, " ");
while (true) {
const word = it.next() ?? break;
if (mem.eql(u8, word, "-rpath")) {
57 changes: 37 additions & 20 deletions std/mem.zig
Original file line number Diff line number Diff line change
@@ -216,20 +216,28 @@ pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) -> %[]T {

/// Linear search for the index of a scalar value inside a slice.
pub fn indexOfScalar(comptime T: type, slice: []const T, value: T) -> ?usize {
for (slice) |item, i| {
if (item == value) {
return indexOfScalarPos(T, slice, 0, value);
}

pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) -> ?usize {
var i: usize = start_index;
while (i < slice.len) : (i += 1) {
if (slice[i] == value)
return i;
}
}
return null;
}

// TODO boyer-moore algorithm
pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) -> ?usize {
return indexOfPos(T, haystack, 0, needle);
}

// TODO boyer-moore algorithm
pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, needle: []const T) -> ?usize {
if (needle.len > haystack.len)
return null;

var i: usize = 0;
var i: usize = start_index;
const end = haystack.len - needle.len;
while (i <= end) : (i += 1) {
if (eql(T, haystack[i .. i + needle.len], needle))
@@ -303,20 +311,20 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) -> bool {
return eql(u8, a, b);
}

/// Returns an iterator that iterates over the slices of ::s that are not
/// the byte ::c.
/// split(" abc def ghi ")
/// Returns an iterator that iterates over the slices of `buffer` that are not
/// any of the bytes in `split_bytes`.
/// split(" abc def ghi ", " ")
/// Will return slices for "abc", "def", "ghi", null, in that order.
pub fn split(s: []const u8, c: u8) -> SplitIterator {
pub fn split(buffer: []const u8, split_bytes: []const u8) -> SplitIterator {
SplitIterator {
.index = 0,
.s = s,
.c = c,
.buffer = buffer,
.split_bytes = split_bytes,
}
}

test "mem.split" {
var it = split(" abc def ghi ", ' ');
var it = split(" abc def ghi ", " ");
assert(eql(u8, ??it.next(), "abc"));
assert(eql(u8, ??it.next(), "def"));
assert(eql(u8, ??it.next(), "ghi"));
@@ -328,31 +336,40 @@ pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) -> b
}

const SplitIterator = struct {
s: []const u8,
c: u8,
buffer: []const u8,
split_bytes: []const u8,
index: usize,

pub fn next(self: &SplitIterator) -> ?[]const u8 {
// move to beginning of token
while (self.index < self.s.len and self.s[self.index] == self.c) : (self.index += 1) {}
while (self.index < self.buffer.len and self.isSplitByte(self.buffer[self.index])) : (self.index += 1) {}
const start = self.index;
if (start == self.s.len) {
if (start == self.buffer.len) {
return null;
}

// move to end of token
while (self.index < self.s.len and self.s[self.index] != self.c) : (self.index += 1) {}
while (self.index < self.buffer.len and !self.isSplitByte(self.buffer[self.index])) : (self.index += 1) {}
const end = self.index;

return self.s[start..end];
return self.buffer[start..end];
}

/// Returns a slice of the remaining bytes. Does not affect iterator state.
pub fn rest(self: &const SplitIterator) -> []const u8 {
// move to beginning of token
var index: usize = self.index;
while (index < self.s.len and self.s[index] == self.c) : (index += 1) {}
return self.s[index..];
while (index < self.buffer.len and self.isSplitByte(self.buffer[index])) : (index += 1) {}
return self.buffer[index..];
}

fn isSplitByte(self: &const SplitIterator, byte: u8) -> bool {
for (self.split_bytes) |split_byte| {
if (byte == split_byte) {
return true;
}
}
return false;
}
};

60 changes: 48 additions & 12 deletions std/os/index.zig
Original file line number Diff line number Diff line change
@@ -384,7 +384,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
// +1 for the null terminating byte
const path_buf = %return allocator.alloc(u8, PATH.len + exe_path.len + 2);
defer allocator.free(path_buf);
var it = mem.split(PATH, ':');
var it = mem.split(PATH, ":");
var seen_eacces = false;
var err: usize = undefined;
while (it.next()) |search_path| {
@@ -474,18 +474,41 @@ pub const args = struct {

/// Caller must free the returned memory.
pub fn getCwd(allocator: &Allocator) -> %[]u8 {
var buf = %return allocator.alloc(u8, 1024);
%defer allocator.free(buf);
while (true) {
const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len));
if (err == posix.ERANGE) {
buf = %return allocator.realloc(u8, buf, buf.len * 2);
continue;
} else if (err > 0) {
return error.Unexpected;
}
switch (builtin.os) {
Os.windows => {
var buf = %return allocator.alloc(u8, 256);
%defer allocator.free(buf);

while (true) {
const result = windows.GetCurrentDirectoryA(windows.WORD(buf.len), buf.ptr);

if (result == 0) {
return error.Unexpected;
}

if (result > buf.len) {
buf = %return allocator.realloc(u8, buf, result);
continue;
}

return buf[0..result];
}
},
else => {
var buf = %return allocator.alloc(u8, 1024);
%defer allocator.free(buf);
while (true) {
const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len));
if (err == posix.ERANGE) {
buf = %return allocator.realloc(u8, buf, buf.len * 2);
continue;
} else if (err > 0) {
return error.Unexpected;
}

return cstr.toSlice(buf.ptr);
return cstr.toSlice(buf.ptr);
}
},
}
}

@@ -1033,3 +1056,16 @@ pub fn posix_setregid(rgid: u32, egid: u32) -> %void {
else => error.Unexpected,
};
}

test "std.os" {
_ = @import("child_process.zig");
_ = @import("darwin_errno.zig");
_ = @import("darwin.zig");
_ = @import("get_user_id.zig");
_ = @import("linux_errno.zig");
//_ = @import("linux_i386.zig");
_ = @import("linux_x86_64.zig");
_ = @import("linux.zig");
_ = @import("path.zig");
_ = @import("windows/index.zig");
}
Loading