From 1eda7e0fde88ac06eaf595f74157d1e6214c1b3d Mon Sep 17 00:00:00 2001
From: Andrew Kelley
", escaped_source);
+ const tmp_dir_name = "docgen_tmp";
+ try os.makePath(allocator, tmp_dir_name);
+ const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name);
+ const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
+ const tmp_source_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_ext);
+ const tmp_bin_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_bin_ext);
+ try io.writeFile(tmp_source_file_name, trimmed_raw_source, null);
+
+ switch (code.id) {
+ Code.Id.Exe => {
+ {
+ const args = [][]const u8 {zig_exe, "build-exe", tmp_source_file_name, "--output", tmp_bin_file_name};
+ const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
+ switch (result.term) {
+ os.ChildProcess.Term.Exited => |exit_code| {
+ if (exit_code != 0) {
+ warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);
+ for (args) |arg| warn("{} ", arg) else warn("\n");
+ return parseError(tokenizer, code.source_token, "example failed to compile");
+ }
+ },
+ else => {
+ warn("{}\nThe following command crashed:\n", result.stderr);
+ for (args) |arg| warn("{} ", arg) else warn("\n");
+ return parseError(tokenizer, code.source_token, "example failed to compile");
+ },
+ }
+ }
+ const args = [][]const u8 {tmp_bin_file_name};
+ const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
+ switch (result.term) {
+ os.ChildProcess.Term.Exited => |exit_code| {
+ if (exit_code != 0) {
+ warn("The following command exited with code {}:\n", exit_code);
+ for (args) |arg| warn("{} ", arg) else warn("\n");
+ return parseError(tokenizer, code.source_token, "example exited with code {}", exit_code);
+ }
+ },
+ else => {
+ warn("The following command crashed:\n");
+ for (args) |arg| warn("{} ", arg) else warn("\n");
+ return parseError(tokenizer, code.source_token, "example crashed");
+ },
+ }
+ try out.print("{}
\n", code.name, code.name, result.stderr, result.stdout);
+ },
+ Code.Id.Test => {
+ @panic("TODO");
+ },
+ Code.Id.Error => {
+ @panic("TODO");
+ },
+ }
+ },
}
}
diff --git a/doc/langref.html.in b/doc/langref.html.in
index cdbc371511..7b3dc9788c 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -55,28 +55,30 @@
$ zig build-exe {}.zig\n$ ./{}\n{}{}
const std = @import("std");
-pub fn main() -> %void {
+ {#code_begin|exe|hello#}
+const std = @import("std");
+
+pub fn main() -> %void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
try stdout_file.write("Hello, world!\n");
-}
- $ zig build-exe hello.zig
-$ ./hello
-Hello, world!
+}
+ {#code_end#}
Usually you don't want to write to stdout. You want to write to stderr. And you don't care if it fails. It's more like a warning message that you want to emit. For that you can use a simpler API:
-const warn = @import("std").debug.warn;
+ {#code_begin|exe|hello#}
+const warn = @import("std").debug.warn;
-pub fn main() -> %void {
+pub fn main() -> %void {
warn("Hello, world!\n");
-}
+}
+ {#code_end#}
{#see_also|Values|@import|Errors|Root Source File#}
{#header_close#}
{#header_open|Source Encoding#}
diff --git a/std/build.zig b/std/build.zig
index 5d79b00c4f..2b61d4971b 100644
--- a/std/build.zig
+++ b/std/build.zig
@@ -760,7 +760,7 @@ const CrossTarget = struct {
environ: builtin.Environ,
};
-const Target = union(enum) {
+pub const Target = union(enum) {
Native: void,
Cross: CrossTarget,
diff --git a/std/mem.zig b/std/mem.zig
index 2d5b6f7a25..5f6cc0c3e0 100644
--- a/std/mem.zig
+++ b/std/mem.zig
@@ -203,6 +203,20 @@ pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) -> %[]T {
return new_buf;
}
+/// Remove values from the beginning and end of a slice.
+pub fn trim(comptime T: type, slice: []const T, values_to_strip: []const T) -> []const T {
+ var begin: usize = 0;
+ var end: usize = slice.len;
+ while (begin < end and indexOfScalar(T, values_to_strip, slice[begin]) != null) : (begin += 1) {}
+ while (end > begin and indexOfScalar(T, values_to_strip, slice[end - 1]) != null) : (end -= 1) {}
+ return slice[begin..end];
+}
+
+test "mem.trim" {
+ assert(eql(u8, trim(u8, " foo\n ", " \n"), "foo"));
+ assert(eql(u8, trim(u8, "foo", " \n"), "foo"));
+}
+
/// Linear search for the index of a scalar value inside a slice.
pub fn indexOfScalar(comptime T: type, slice: []const T, value: T) -> ?usize {
return indexOfScalarPos(T, slice, 0, value);