Skip to content

Commit

Permalink
std.zig.render returns bool of whether anything changed
Browse files Browse the repository at this point in the history
zig fmt only renames files and prints to stdout for files which changed
  • Loading branch information
andrewrk committed May 30, 2018
1 parent 15302e8 commit 2c96f19
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 10 deletions.
12 changes: 8 additions & 4 deletions src-self-hosted/main.zig
Expand Up @@ -719,6 +719,9 @@ fn cmdFmt(allocator: &Allocator, args: []const []const u8) !void {
};
defer tree.deinit();

var old_digest: [256]u8 = undefined;
std.crypto.Sha256.hash(source_code, old_digest[0..]);

var error_it = tree.errors.iterator(0);
while (error_it.next()) |parse_error| {
const token = tree.tokens.at(parse_error.loc());
Expand All @@ -745,13 +748,14 @@ fn cmdFmt(allocator: &Allocator, args: []const []const u8) !void {
continue;
}

try stderr.print("{}\n", file_path);

const baf = try io.BufferedAtomicFile.create(allocator, file_path);
defer baf.destroy();

try std.zig.render(allocator, baf.stream(), &tree);
try baf.finish();
const anything_changed = try std.zig.render(allocator, baf.stream(), &tree);
if (anything_changed) {
try stderr.print("{}\n", file_path);
try baf.finish();
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src-self-hosted/module.zig
Expand Up @@ -255,7 +255,7 @@ pub const Module = struct {
const out_stream = &stderr_file_out_stream.stream;

warn("====fmt:====\n");
try std.zig.render(self.allocator, out_stream, &tree);
_ = try std.zig.render(self.allocator, out_stream, &tree);

warn("====ir:====\n");
warn("TODO\n\n");
Expand Down
10 changes: 6 additions & 4 deletions std/zig/parser_test.zig
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -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 => {
Expand Down
54 changes: 53 additions & 1 deletion std/zig/render.zig
Expand Up @@ -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| {
Expand Down

0 comments on commit 2c96f19

Please sign in to comment.