aboutsummaryrefslogtreecommitdiff
path: root/std
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2018-05-30 14:55:59 -0400
committerAndrew Kelley <superjoe30@gmail.com>2018-05-30 14:58:27 -0400
commit2c96f19fd3ed312e5cb0ac8006b73e73abf4a98d (patch)
treed3d21091ba024a1b2c6c560727d21c833c8286bd /std
parent15302e84a45a04cfe94a8842318f02a608055962 (diff)
downloadzig-2c96f19fd3ed312e5cb0ac8006b73e73abf4a98d.tar.gz
zig-2c96f19fd3ed312e5cb0ac8006b73e73abf4a98d.zip
std.zig.render returns bool of whether anything changed
zig fmt only renames files and prints to stdout for files which changed
Diffstat (limited to 'std')
-rw-r--r--std/zig/parser_test.zig10
-rw-r--r--std/zig/render.zig54
2 files changed, 59 insertions, 5 deletions
diff --git a/std/zig/parser_test.zig b/std/zig/parser_test.zig
index 75ba9e61d7..eee6b12767 100644
--- a/std/zig/parser_test.zig
+++ b/std/zig/parser_test.zig
@@ -1792,7 +1792,7 @@ const io = std.io;
var fixed_buffer_mem: [100 * 1024]u8 = undefined;
-fn testParse(source: []const u8, allocator: &mem.Allocator) ![]u8 {
+fn testParse(source: []const u8, allocator: &mem.Allocator, changes_expected: bool) ![]u8 {
var stderr_file = try io.getStdErr();
var stderr = &io.FileOutStream.init(&stderr_file).stream;
@@ -1829,16 +1829,18 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) ![]u8 {
errdefer buffer.deinit();
var buffer_out_stream = io.BufferOutStream.init(&buffer);
- try std.zig.render(allocator, &buffer_out_stream.stream, &tree);
+ const anything_changed = try std.zig.render(allocator, &buffer_out_stream.stream, &tree);
+ std.debug.assert(anything_changed == changes_expected);
return buffer.toOwnedSlice();
}
fn testTransform(source: []const u8, expected_source: []const u8) !void {
+ const changes_expected = source.ptr != expected_source.ptr;
const needed_alloc_count = x: {
// Try it once with unlimited memory, make sure it works
var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize));
- const result_source = try testParse(source, &failing_allocator.allocator);
+ const result_source = try testParse(source, &failing_allocator.allocator, changes_expected);
if (!mem.eql(u8, result_source, expected_source)) {
warn("\n====== expected this output: =========\n");
warn("{}", expected_source);
@@ -1855,7 +1857,7 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
while (fail_index < needed_alloc_count) : (fail_index += 1) {
var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, fail_index);
- if (testParse(source, &failing_allocator.allocator)) |_| {
+ if (testParse(source, &failing_allocator.allocator, changes_expected)) |_| {
return error.NondeterministicMemoryUsage;
} else |err| switch (err) {
error.OutOfMemory => {
diff --git a/std/zig/render.zig b/std/zig/render.zig
index e3bf5fe38e..657fcae8bb 100644
--- a/std/zig/render.zig
+++ b/std/zig/render.zig
@@ -12,9 +12,61 @@ pub const Error = error{
OutOfMemory,
};
-pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf(stream).Child.Error || Error)!void {
+/// Returns whether anything changed
+pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf(stream).Child.Error || Error)!bool {
comptime assert(@typeId(@typeOf(stream)) == builtin.TypeId.Pointer);
+ var anything_changed: bool = false;
+
+ // make a passthrough stream that checks whether something changed
+ const MyStream = struct {
+ const MyStream = this;
+ const StreamError = @typeOf(stream).Child.Error;
+ const Stream = std.io.OutStream(StreamError);
+
+ anything_changed_ptr: &bool,
+ child_stream: @typeOf(stream),
+ stream: Stream,
+ source_index: usize,
+ source: []const u8,
+
+ fn write(iface_stream: &Stream, bytes: []const u8) StreamError!void {
+ const self = @fieldParentPtr(MyStream, "stream", iface_stream);
+
+ if (!self.anything_changed_ptr.*) {
+ const end = self.source_index + bytes.len;
+ if (end > self.source.len) {
+ self.anything_changed_ptr.* = true;
+ } else {
+ const src_slice = self.source[self.source_index..end];
+ self.source_index += bytes.len;
+ if (!mem.eql(u8, bytes, src_slice)) {
+ self.anything_changed_ptr.* = true;
+ }
+ }
+ }
+
+ try self.child_stream.write(bytes);
+ }
+ };
+ var my_stream = MyStream{
+ .stream = MyStream.Stream{ .writeFn = MyStream.write },
+ .child_stream = stream,
+ .anything_changed_ptr = &anything_changed,
+ .source_index = 0,
+ .source = tree.source,
+ };
+
+ try renderRoot(allocator, &my_stream.stream, tree);
+
+ return anything_changed;
+}
+
+fn renderRoot(
+ allocator: &mem.Allocator,
+ stream: var,
+ tree: &ast.Tree,
+) (@typeOf(stream).Child.Error || Error)!void {
// render all the line comments at the beginning of the file
var tok_it = tree.tokens.iterator(0);
while (tok_it.next()) |token| {