Skip to content

Commit 2c96f19

Browse files
committed
std.zig.render returns bool of whether anything changed
zig fmt only renames files and prints to stdout for files which changed
1 parent 15302e8 commit 2c96f19

File tree

4 files changed

+68
-10
lines changed

4 files changed

+68
-10
lines changed

src-self-hosted/main.zig

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,9 @@ fn cmdFmt(allocator: &Allocator, args: []const []const u8) !void {
719719
};
720720
defer tree.deinit();
721721

722+
var old_digest: [256]u8 = undefined;
723+
std.crypto.Sha256.hash(source_code, old_digest[0..]);
724+
722725
var error_it = tree.errors.iterator(0);
723726
while (error_it.next()) |parse_error| {
724727
const token = tree.tokens.at(parse_error.loc());
@@ -745,13 +748,14 @@ fn cmdFmt(allocator: &Allocator, args: []const []const u8) !void {
745748
continue;
746749
}
747750

748-
try stderr.print("{}\n", file_path);
749-
750751
const baf = try io.BufferedAtomicFile.create(allocator, file_path);
751752
defer baf.destroy();
752753

753-
try std.zig.render(allocator, baf.stream(), &tree);
754-
try baf.finish();
754+
const anything_changed = try std.zig.render(allocator, baf.stream(), &tree);
755+
if (anything_changed) {
756+
try stderr.print("{}\n", file_path);
757+
try baf.finish();
758+
}
755759
}
756760
}
757761

src-self-hosted/module.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ pub const Module = struct {
255255
const out_stream = &stderr_file_out_stream.stream;
256256

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

260260
warn("====ir:====\n");
261261
warn("TODO\n\n");

std/zig/parser_test.zig

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,7 +1792,7 @@ const io = std.io;
17921792

17931793
var fixed_buffer_mem: [100 * 1024]u8 = undefined;
17941794

1795-
fn testParse(source: []const u8, allocator: &mem.Allocator) ![]u8 {
1795+
fn testParse(source: []const u8, allocator: &mem.Allocator, changes_expected: bool) ![]u8 {
17961796
var stderr_file = try io.getStdErr();
17971797
var stderr = &io.FileOutStream.init(&stderr_file).stream;
17981798

@@ -1829,16 +1829,18 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) ![]u8 {
18291829
errdefer buffer.deinit();
18301830

18311831
var buffer_out_stream = io.BufferOutStream.init(&buffer);
1832-
try std.zig.render(allocator, &buffer_out_stream.stream, &tree);
1832+
const anything_changed = try std.zig.render(allocator, &buffer_out_stream.stream, &tree);
1833+
std.debug.assert(anything_changed == changes_expected);
18331834
return buffer.toOwnedSlice();
18341835
}
18351836

18361837
fn testTransform(source: []const u8, expected_source: []const u8) !void {
1838+
const changes_expected = source.ptr != expected_source.ptr;
18371839
const needed_alloc_count = x: {
18381840
// Try it once with unlimited memory, make sure it works
18391841
var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
18401842
var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize));
1841-
const result_source = try testParse(source, &failing_allocator.allocator);
1843+
const result_source = try testParse(source, &failing_allocator.allocator, changes_expected);
18421844
if (!mem.eql(u8, result_source, expected_source)) {
18431845
warn("\n====== expected this output: =========\n");
18441846
warn("{}", expected_source);
@@ -1855,7 +1857,7 @@ fn testTransform(source: []const u8, expected_source: []const u8) !void {
18551857
while (fail_index < needed_alloc_count) : (fail_index += 1) {
18561858
var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
18571859
var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, fail_index);
1858-
if (testParse(source, &failing_allocator.allocator)) |_| {
1860+
if (testParse(source, &failing_allocator.allocator, changes_expected)) |_| {
18591861
return error.NondeterministicMemoryUsage;
18601862
} else |err| switch (err) {
18611863
error.OutOfMemory => {

std/zig/render.zig

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,61 @@ pub const Error = error{
1212
OutOfMemory,
1313
};
1414

15-
pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf(stream).Child.Error || Error)!void {
15+
/// Returns whether anything changed
16+
pub fn render(allocator: &mem.Allocator, stream: var, tree: &ast.Tree) (@typeOf(stream).Child.Error || Error)!bool {
1617
comptime assert(@typeId(@typeOf(stream)) == builtin.TypeId.Pointer);
1718

19+
var anything_changed: bool = false;
20+
21+
// make a passthrough stream that checks whether something changed
22+
const MyStream = struct {
23+
const MyStream = this;
24+
const StreamError = @typeOf(stream).Child.Error;
25+
const Stream = std.io.OutStream(StreamError);
26+
27+
anything_changed_ptr: &bool,
28+
child_stream: @typeOf(stream),
29+
stream: Stream,
30+
source_index: usize,
31+
source: []const u8,
32+
33+
fn write(iface_stream: &Stream, bytes: []const u8) StreamError!void {
34+
const self = @fieldParentPtr(MyStream, "stream", iface_stream);
35+
36+
if (!self.anything_changed_ptr.*) {
37+
const end = self.source_index + bytes.len;
38+
if (end > self.source.len) {
39+
self.anything_changed_ptr.* = true;
40+
} else {
41+
const src_slice = self.source[self.source_index..end];
42+
self.source_index += bytes.len;
43+
if (!mem.eql(u8, bytes, src_slice)) {
44+
self.anything_changed_ptr.* = true;
45+
}
46+
}
47+
}
48+
49+
try self.child_stream.write(bytes);
50+
}
51+
};
52+
var my_stream = MyStream{
53+
.stream = MyStream.Stream{ .writeFn = MyStream.write },
54+
.child_stream = stream,
55+
.anything_changed_ptr = &anything_changed,
56+
.source_index = 0,
57+
.source = tree.source,
58+
};
59+
60+
try renderRoot(allocator, &my_stream.stream, tree);
61+
62+
return anything_changed;
63+
}
64+
65+
fn renderRoot(
66+
allocator: &mem.Allocator,
67+
stream: var,
68+
tree: &ast.Tree,
69+
) (@typeOf(stream).Child.Error || Error)!void {
1870
// render all the line comments at the beginning of the file
1971
var tok_it = tree.tokens.iterator(0);
2072
while (tok_it.next()) |token| {

0 commit comments

Comments
 (0)