authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-01-02 12:29:37+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-02 17:12:58-07:00
log5b981b1be7b387a3f51d60b8642064e6642b956c
treea969e1d6c6dfb6e3aab168bfa09e17f4bf3d7a51
parent608a73efb12df43fbc136c4439558f87a063dc31

Remove some unwanted changes

Leftovers after a long rebase.

7 files changed, 3 insertions(+), 860 deletions(-)

build.zig-189
...@@ -359,195 +359,6 @@ pub fn build(b: *Builder) !void {...@@ -359,195 +359,6 @@ pub fn build(b: *Builder) !void {
359 test_step.dependOn(docs_step);359 test_step.dependOn(docs_step);
360}360}
361361
362fn dependOnLib(b: *Builder, lib_exe_obj: anytype, dep: LibraryDep) void {
363 for (dep.libdirs.items) |lib_dir| {
364 lib_exe_obj.addLibPath(lib_dir);
365 }
366 const lib_dir = fs.path.join(
367 b.allocator,
368 &[_][]const u8{ dep.prefix, "lib" },
369 ) catch unreachable;
370 for (dep.system_libs.items) |lib| {
371 const static_bare_name = if (mem.eql(u8, lib, "curses"))
372 @as([]const u8, "libncurses.a")
373 else
374 b.fmt("lib{s}.a", .{lib});
375 const static_lib_name = fs.path.join(
376 b.allocator,
377 &[_][]const u8{ lib_dir, static_bare_name },
378 ) catch unreachable;
379 const have_static = fileExists(static_lib_name) catch unreachable;
380 if (have_static) {
381 lib_exe_obj.addObjectFile(static_lib_name);
382 } else {
383 lib_exe_obj.linkSystemLibrary(lib);
384 }
385 }
386 for (dep.libs.items) |lib| {
387 lib_exe_obj.addObjectFile(lib);
388 }
389 for (dep.includes.items) |include_path| {
390 lib_exe_obj.addIncludeDir(include_path);
391 }
392}
393
394fn fileExists(filename: []const u8) !bool {
395 fs.cwd().access(filename, .{}) catch |err| switch (err) {
396 error.FileNotFound => return false,
397 else => return err,
398 };
399 return true;
400}
401
402fn addCppLib(b: *Builder, lib_exe_obj: anytype, cmake_binary_dir: []const u8, lib_name: []const u8) void {
403 lib_exe_obj.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{
404 cmake_binary_dir,
405 "zigcpp",
406 b.fmt("{s}{s}{s}", .{ lib_exe_obj.target.libPrefix(), lib_name, lib_exe_obj.target.staticLibSuffix() }),
407 }) catch unreachable);
408}
409
410const LibraryDep = struct {
411 prefix: []const u8,
412 libdirs: ArrayList([]const u8),
413 libs: ArrayList([]const u8),
414 system_libs: ArrayList([]const u8),
415 includes: ArrayList([]const u8),
416};
417
418fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
419 const shared_mode = try b.exec(&[_][]const u8{ llvm_config_exe, "--shared-mode" });
420 const is_static = mem.startsWith(u8, shared_mode, "static");
421 const libs_output = if (is_static)
422 try b.exec(&[_][]const u8{
423 llvm_config_exe,
424 "--libfiles",
425 "--system-libs",
426 })
427 else
428 try b.exec(&[_][]const u8{
429 llvm_config_exe,
430 "--libs",
431 });
432 const includes_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--includedir" });
433 const libdir_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--libdir" });
434 const prefix_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--prefix" });
435
436 var result = LibraryDep{
437 .prefix = mem.tokenize(prefix_output, " \r\n").next().?,
438 .libs = ArrayList([]const u8).init(b.allocator),
439 .system_libs = ArrayList([]const u8).init(b.allocator),
440 .includes = ArrayList([]const u8).init(b.allocator),
441 .libdirs = ArrayList([]const u8).init(b.allocator),
442 };
443 {
444 var it = mem.tokenize(libs_output, " \r\n");
445 while (it.next()) |lib_arg| {
446 if (mem.startsWith(u8, lib_arg, "-l")) {
447 try result.system_libs.append(lib_arg[2..]);
448 } else {
449 if (fs.path.isAbsolute(lib_arg)) {
450 try result.libs.append(lib_arg);
451 } else {
452 var lib_arg_copy = lib_arg;
453 if (mem.endsWith(u8, lib_arg, ".lib")) {
454 lib_arg_copy = lib_arg[0 .. lib_arg.len - 4];
455 }
456 try result.system_libs.append(lib_arg_copy);
457 }
458 }
459 }
460 }
461 {
462 var it = mem.tokenize(includes_output, " \r\n");
463 while (it.next()) |include_arg| {
464 if (mem.startsWith(u8, include_arg, "-I")) {
465 try result.includes.append(include_arg[2..]);
466 } else {
467 try result.includes.append(include_arg);
468 }
469 }
470 }
471 {
472 var it = mem.tokenize(libdir_output, " \r\n");
473 while (it.next()) |libdir| {
474 if (mem.startsWith(u8, libdir, "-L")) {
475 try result.libdirs.append(libdir[2..]);
476 } else {
477 try result.libdirs.append(libdir);
478 }
479 }
480 }
481 return result;
482}
483
484fn configureStage2(b: *Builder, exe: anytype, ctx: Context, need_cpp_includes: bool) !void {
485 exe.addIncludeDir("src");
486 exe.addIncludeDir(ctx.cmake_binary_dir);
487 addCppLib(b, exe, ctx.cmake_binary_dir, "zigcpp");
488 assert(ctx.lld_include_dir.len != 0);
489 exe.addIncludeDir(ctx.lld_include_dir);
490 {
491 var it = mem.tokenize(ctx.lld_libraries, ";");
492 while (it.next()) |lib| {
493 exe.addObjectFile(lib);
494 }
495 }
496 {
497 var it = mem.tokenize(ctx.clang_libraries, ";");
498 while (it.next()) |lib| {
499 exe.addObjectFile(lib);
500 }
501 }
502 dependOnLib(b, exe, ctx.llvm);
503
504 // Boy, it sure would be nice to simply linkSystemLibrary("c++") and rely on zig's
505 // ability to provide libc++ right? Well thanks to C++ not having a stable ABI this
506 // will cause linker errors. It would work in the situation when `zig cc` is used to
507 // build LLVM, Clang, and LLD, however when depending on them as system libraries, system
508 // libc++ must be used.
509 const cross_compile = false; // TODO
510 if (cross_compile) {
511 // In this case we assume that zig cc was used to build the LLVM, Clang, LLD dependencies.
512 exe.linkSystemLibrary("c++");
513 } else {
514 if (exe.target.getOsTag() == .linux) {
515 // First we try to static link against gcc libstdc++. If that doesn't work,
516 // we fall back to -lc++ and cross our fingers.
517 addCxxKnownPath(b, ctx, exe, "libstdc++.a", "", need_cpp_includes) catch |err| switch (err) {
518 error.RequiredLibraryNotFound => {
519 exe.linkSystemLibrary("c++");
520 },
521 else => |e| return e,
522 };
523
524 exe.linkSystemLibrary("pthread");
525 } else if (exe.target.isFreeBSD()) {
526 try addCxxKnownPath(b, ctx, exe, "libc++.a", null, need_cpp_includes);
527 exe.linkSystemLibrary("pthread");
528 } else if (exe.target.isDarwin()) {
529 if (addCxxKnownPath(b, ctx, exe, "libgcc_eh.a", "", need_cpp_includes)) {
530 // Compiler is GCC.
531 try addCxxKnownPath(b, ctx, exe, "libstdc++.a", null, need_cpp_includes);
532 exe.linkSystemLibrary("pthread");
533 // TODO LLD cannot perform this link.
534 // Set ZIG_SYSTEM_LINKER_HACK env var to use system linker ld instead.
535 // See https://github.com/ziglang/zig/issues/1535
536 } else |err| switch (err) {
537 error.RequiredLibraryNotFound => {
538 // System compiler, not gcc.
539 exe.linkSystemLibrary("c++");
540 },
541 else => |e| return e,
542 }
543 }
544
545 if (ctx.dia_guids_lib.len != 0) {
546 exe.addObjectFile(ctx.dia_guids_lib);
547 }
548 }
549}
550
551fn addCxxKnownPath(362fn addCxxKnownPath(
552 b: *Builder,363 b: *Builder,
553 ctx: CMakeConfig,364 ctx: CMakeConfig,
lib/std/array_list_sentineled.zig deleted-229
...@@ -1,229 +0,0 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2020 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6const std = @import("std.zig");
7const debug = std.debug;
8const mem = std.mem;
9const Allocator = mem.Allocator;
10const assert = debug.assert;
11const testing = std.testing;
12const ArrayList = std.ArrayList;
13
14/// A contiguous, growable list of items in memory, with a sentinel after them.
15/// The sentinel is maintained when appending, resizing, etc.
16/// If you do not need a sentinel, consider using `ArrayList` instead.
17pub fn ArrayListSentineled(comptime T: type, comptime sentinel: T) type {
18 return struct {
19 list: ArrayList(T),
20
21 const Self = @This();
22
23 /// Must deinitialize with deinit.
24 pub fn init(allocator: *Allocator, m: []const T) !Self {
25 var self = try initSize(allocator, m.len);
26 mem.copy(T, self.list.items, m);
27 return self;
28 }
29
30 /// Initialize memory to size bytes of undefined values.
31 /// Must deinitialize with deinit.
32 pub fn initSize(allocator: *Allocator, size: usize) !Self {
33 var self = initNull(allocator);
34 try self.resize(size);
35 return self;
36 }
37
38 /// Initialize with capacity to hold at least num bytes.
39 /// Must deinitialize with deinit.
40 pub fn initCapacity(allocator: *Allocator, num: usize) !Self {
41 var self = Self{ .list = try ArrayList(T).initCapacity(allocator, num + 1) };
42 self.list.appendAssumeCapacity(sentinel);
43 return self;
44 }
45
46 /// Must deinitialize with deinit.
47 /// None of the other operations are valid until you do one of these:
48 /// * `replaceContents`
49 /// * `resize`
50 pub fn initNull(allocator: *Allocator) Self {
51 return Self{ .list = ArrayList(T).init(allocator) };
52 }
53
54 /// Must deinitialize with deinit.
55 pub fn initFromBuffer(buffer: Self) !Self {
56 return Self.init(buffer.list.allocator, buffer.span());
57 }
58
59 /// Takes ownership of the passed in slice. The slice must have been
60 /// allocated with `allocator`.
61 /// Must deinitialize with deinit.
62 pub fn fromOwnedSlice(allocator: *Allocator, slice: []T) !Self {
63 var self = Self{ .list = ArrayList(T).fromOwnedSlice(allocator, slice) };
64 try self.list.append(sentinel);
65 return self;
66 }
67
68 /// The caller owns the returned memory. The list becomes null and is safe to `deinit`.
69 pub fn toOwnedSlice(self: *Self) [:sentinel]T {
70 const allocator = self.list.allocator;
71 const result = self.list.toOwnedSlice();
72 self.* = initNull(allocator);
73 return result[0 .. result.len - 1 :sentinel];
74 }
75
76 /// Only works when `T` is `u8`.
77 pub fn allocPrint(allocator: *Allocator, comptime format: []const u8, args: anytype) !Self {
78 const size = std.math.cast(usize, std.fmt.count(format, args)) catch |err| switch (err) {
79 error.Overflow => return error.OutOfMemory,
80 };
81 var self = try Self.initSize(allocator, size);
82 assert((std.fmt.bufPrint(self.list.items, format, args) catch unreachable).len == size);
83 return self;
84 }
85
86 pub fn deinit(self: *Self) void {
87 self.list.deinit();
88 }
89
90 pub fn span(self: anytype) @TypeOf(self.list.items[0..:sentinel]) {
91 return self.list.items[0..self.len() :sentinel];
92 }
93
94 pub fn shrink(self: *Self, new_len: usize) void {
95 assert(new_len <= self.len());
96 self.list.shrink(new_len + 1);
97 self.list.items[self.len()] = sentinel;
98 }
99
100 pub fn resize(self: *Self, new_len: usize) !void {
101 try self.list.resize(new_len + 1);
102 self.list.items[self.len()] = sentinel;
103 }
104
105 pub fn isNull(self: Self) bool {
106 return self.list.items.len == 0;
107 }
108
109 pub fn len(self: Self) usize {
110 return self.list.items.len - 1;
111 }
112
113 pub fn capacity(self: Self) usize {
114 return if (self.list.capacity > 0)
115 self.list.capacity - 1
116 else
117 0;
118 }
119
120 pub fn appendSlice(self: *Self, m: []const T) !void {
121 const old_len = self.len();
122 try self.resize(old_len + m.len);
123 mem.copy(T, self.list.items[old_len..], m);
124 }
125
126 pub fn append(self: *Self, byte: T) !void {
127 const old_len = self.len();
128 try self.resize(old_len + 1);
129 self.list.items[old_len] = byte;
130 }
131
132 pub fn eql(self: Self, m: []const T) bool {
133 return mem.eql(T, self.span(), m);
134 }
135
136 pub fn startsWith(self: Self, m: []const T) bool {
137 if (self.len() < m.len) return false;
138 return mem.eql(T, self.list.items[0..m.len], m);
139 }
140
141 pub fn endsWith(self: Self, m: []const T) bool {
142 const l = self.len();
143 if (l < m.len) return false;
144 const start = l - m.len;
145 return mem.eql(T, self.list.items[start..l], m);
146 }
147
148 pub fn replaceContents(self: *Self, m: []const T) !void {
149 try self.resize(m.len);
150 mem.copy(T, self.list.items, m);
151 }
152
153 /// Initializes an OutStream which will append to the list.
154 /// This function may be called only when `T` is `u8`.
155 pub fn outStream(self: *Self) std.io.OutStream(*Self, error{OutOfMemory}, appendWrite) {
156 return .{ .context = self };
157 }
158
159 /// Same as `append` except it returns the number of bytes written, which is always the same
160 /// as `m.len`. The purpose of this function existing is to match `std.io.OutStream` API.
161 /// This function may be called only when `T` is `u8`.
162 pub fn appendWrite(self: *Self, m: []const u8) !usize {
163 try self.appendSlice(m);
164 return m.len;
165 }
166 };
167}
168
169test "simple" {
170 var buf = try ArrayListSentineled(u8, 0).init(testing.allocator, "");
171 defer buf.deinit();
172
173 testing.expect(buf.len() == 0);
174 try buf.appendSlice("hello");
175 try buf.appendSlice(" ");
176 try buf.appendSlice("world");
177 testing.expect(buf.eql("hello world"));
178 testing.expect(mem.eql(u8, mem.spanZ(buf.span().ptr), buf.span()));
179
180 var buf2 = try ArrayListSentineled(u8, 0).initFromBuffer(buf);
181 defer buf2.deinit();
182 testing.expect(buf.eql(buf2.span()));
183
184 testing.expect(buf.startsWith("hell"));
185 testing.expect(buf.endsWith("orld"));
186
187 try buf2.resize(4);
188 testing.expect(buf.startsWith(buf2.span()));
189}
190
191test "initSize" {
192 var buf = try ArrayListSentineled(u8, 0).initSize(testing.allocator, 3);
193 defer buf.deinit();
194 testing.expect(buf.len() == 3);
195 try buf.appendSlice("hello");
196 testing.expect(mem.eql(u8, buf.span()[3..], "hello"));
197}
198
199test "initCapacity" {
200 var buf = try ArrayListSentineled(u8, 0).initCapacity(testing.allocator, 10);
201 defer buf.deinit();
202 testing.expect(buf.len() == 0);
203 testing.expect(buf.capacity() >= 10);
204 const old_cap = buf.capacity();
205 try buf.appendSlice("hello");
206 testing.expect(buf.len() == 5);
207 testing.expect(buf.capacity() == old_cap);
208 testing.expect(mem.eql(u8, buf.span(), "hello"));
209}
210
211test "print" {
212 var buf = try ArrayListSentineled(u8, 0).init(testing.allocator, "");
213 defer buf.deinit();
214
215 try buf.outStream().print("Hello {d} the {s}", .{ 2, "world" });
216 testing.expect(buf.eql("Hello 2 the world"));
217}
218
219test "outStream" {
220 var buffer = try ArrayListSentineled(u8, 0).initSize(testing.allocator, 0);
221 defer buffer.deinit();
222 const buf_stream = buffer.outStream();
223
224 const x: i32 = 42;
225 const y: i32 = 1234;
226 try buf_stream.print("x: {}\ny: {}\n", .{ x, y });
227
228 testing.expect(mem.eql(u8, buffer.span(), "x: 42\ny: 1234\n"));
229}
lib/std/progress.zig deleted-310
...@@ -1,310 +0,0 @@
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2015-2020 Zig Contributors
3// This file is part of [zig](https://ziglang.org/), which is MIT licensed.
4// The MIT license requires this copyright notice to be included in all copies
5// and substantial portions of the software.
6const std = @import("std");
7const windows = std.os.windows;
8const testing = std.testing;
9const assert = std.debug.assert;
10
11/// This API is non-allocating and non-fallible. The tradeoff is that users of
12/// this API must provide the storage for each `Progress.Node`.
13/// Initialize the struct directly, overriding these fields as desired:
14/// * `refresh_rate_ms`
15/// * `initial_delay_ms`
16pub const Progress = struct {
17 /// `null` if the current node (and its children) should
18 /// not print on update()
19 terminal: ?std.fs.File = undefined,
20
21 /// Whether the terminal supports ANSI escape codes.
22 supports_ansi_escape_codes: bool = false,
23
24 root: Node = undefined,
25
26 /// Keeps track of how much time has passed since the beginning.
27 /// Used to compare with `initial_delay_ms` and `refresh_rate_ms`.
28 timer: std.time.Timer = undefined,
29
30 /// When the previous refresh was written to the terminal.
31 /// Used to compare with `refresh_rate_ms`.
32 prev_refresh_timestamp: u64 = undefined,
33
34 /// This buffer represents the maximum number of bytes written to the terminal
35 /// with each refresh.
36 output_buffer: [100]u8 = undefined,
37
38 /// How many nanoseconds between writing updates to the terminal.
39 refresh_rate_ns: u64 = 50 * std.time.ns_per_ms,
40
41 /// How many nanoseconds to keep the output hidden
42 initial_delay_ns: u64 = 500 * std.time.ns_per_ms,
43
44 done: bool = true,
45
46 /// Keeps track of how many columns in the terminal have been output, so that
47 /// we can move the cursor back later.
48 columns_written: usize = undefined,
49
50 /// Represents one unit of progress. Each node can have children nodes, or
51 /// one can use integers with `update`.
52 pub const Node = struct {
53 context: *Progress,
54 parent: ?*Node,
55 completed_items: usize,
56 name: []const u8,
57 recently_updated_child: ?*Node = null,
58
59 /// This field may be updated freely.
60 estimated_total_items: ?usize,
61
62 /// Create a new child progress node.
63 /// Call `Node.end` when done.
64 /// TODO solve https://github.com/ziglang/zig/issues/2765 and then change this
65 /// API to set `self.parent.recently_updated_child` with the return value.
66 /// Until that is fixed you probably want to call `activate` on the return value.
67 pub fn start(self: *Node, name: []const u8, estimated_total_items: ?usize) Node {
68 return Node{
69 .context = self.context,
70 .parent = self,
71 .completed_items = 0,
72 .name = name,
73 .estimated_total_items = estimated_total_items,
74 };
75 }
76
77 /// This is the same as calling `start` and then `end` on the returned `Node`.
78 pub fn completeOne(self: *Node) void {
79 if (self.parent) |parent| parent.recently_updated_child = self;
80 self.completed_items += 1;
81 self.context.maybeRefresh();
82 }
83
84 pub fn end(self: *Node) void {
85 self.context.maybeRefresh();
86 if (self.parent) |parent| {
87 if (parent.recently_updated_child) |parent_child| {
88 if (parent_child == self) {
89 parent.recently_updated_child = null;
90 }
91 }
92 parent.completeOne();
93 } else {
94 self.context.done = true;
95 self.context.refresh();
96 }
97 }
98
99 /// Tell the parent node that this node is actively being worked on.
100 pub fn activate(self: *Node) void {
101 if (self.parent) |parent| parent.recently_updated_child = self;
102 }
103 };
104
105 /// Create a new progress node.
106 /// Call `Node.end` when done.
107 /// TODO solve https://github.com/ziglang/zig/issues/2765 and then change this
108 /// API to return Progress rather than accept it as a parameter.
109 pub fn start(self: *Progress, name: []const u8, estimated_total_items: ?usize) !*Node {
110 const stderr = std.io.getStdErr();
111 self.terminal = null;
112 if (stderr.supportsAnsiEscapeCodes()) {
113 self.terminal = stderr;
114 self.supports_ansi_escape_codes = true;
115 } else if (std.builtin.os.tag == .windows and stderr.isTty()) {
116 self.terminal = stderr;
117 }
118 self.root = Node{
119 .context = self,
120 .parent = null,
121 .completed_items = 0,
122 .name = name,
123 .estimated_total_items = estimated_total_items,
124 };
125 self.columns_written = 0;
126 self.prev_refresh_timestamp = 0;
127 self.timer = try std.time.Timer.start();
128 self.done = false;
129 return &self.root;
130 }
131
132 /// Updates the terminal if enough time has passed since last update.
133 pub fn maybeRefresh(self: *Progress) void {
134 const now = self.timer.read();
135 if (now < self.initial_delay_ns) return;
136 if (now - self.prev_refresh_timestamp < self.refresh_rate_ns) return;
137 self.refresh();
138 }
139
140 /// Updates the terminal and resets `self.next_refresh_timestamp`.
141 pub fn refresh(self: *Progress) void {
142 const file = self.terminal orelse return;
143
144 const prev_columns_written = self.columns_written;
145 var end: usize = 0;
146 if (self.columns_written > 0) {
147 // restore the cursor position by moving the cursor
148 // `columns_written` cells to the left, then clear the rest of the
149 // line
150 if (self.supports_ansi_escape_codes) {
151 end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[{d}D", .{self.columns_written}) catch unreachable).len;
152 end += (std.fmt.bufPrint(self.output_buffer[end..], "\x1b[0K", .{}) catch unreachable).len;
153 } else if (std.builtin.os.tag == .windows) winapi: {
154 var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined;
155 if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE)
156 unreachable;
157
158 var cursor_pos = windows.COORD{
159 .X = info.dwCursorPosition.X - @intCast(windows.SHORT, self.columns_written),
160 .Y = info.dwCursorPosition.Y,
161 };
162
163 if (cursor_pos.X < 0)
164 cursor_pos.X = 0;
165
166 const fill_chars = @intCast(windows.DWORD, info.dwSize.X - cursor_pos.X);
167
168 var written: windows.DWORD = undefined;
169 if (windows.kernel32.FillConsoleOutputAttribute(
170 file.handle,
171 info.wAttributes,
172 fill_chars,
173 cursor_pos,
174 &written,
175 ) != windows.TRUE) {
176 // Stop trying to write to this file.
177 self.terminal = null;
178 break :winapi;
179 }
180 if (windows.kernel32.FillConsoleOutputCharacterA(
181 file.handle,
182 ' ',
183 fill_chars,
184 cursor_pos,
185 &written,
186 ) != windows.TRUE) unreachable;
187
188 if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE)
189 unreachable;
190 } else unreachable;
191
192 self.columns_written = 0;
193 }
194
195 if (!self.done) {
196 var need_ellipse = false;
197 var maybe_node: ?*Node = &self.root;
198 while (maybe_node) |node| {
199 if (need_ellipse) {
200 self.bufWrite(&end, "... ", .{});
201 }
202 need_ellipse = false;
203 if (node.name.len != 0 or node.estimated_total_items != null) {
204 if (node.name.len != 0) {
205 self.bufWrite(&end, "{s}", .{node.name});
206 need_ellipse = true;
207 }
208 if (node.estimated_total_items) |total| {
209 if (need_ellipse) self.bufWrite(&end, " ", .{});
210 self.bufWrite(&end, "[{d}/{d}] ", .{ node.completed_items + 1, total });
211 need_ellipse = false;
212 } else if (node.completed_items != 0) {
213 if (need_ellipse) self.bufWrite(&end, " ", .{});
214 self.bufWrite(&end, "[{d}] ", .{node.completed_items + 1});
215 need_ellipse = false;
216 }
217 }
218 maybe_node = node.recently_updated_child;
219 }
220 if (need_ellipse) {
221 self.bufWrite(&end, "... ", .{});
222 }
223 }
224
225 _ = file.write(self.output_buffer[0..end]) catch |e| {
226 // Stop trying to write to this file once it errors.
227 self.terminal = null;
228 };
229 self.prev_refresh_timestamp = self.timer.read();
230 }
231
232 pub fn log(self: *Progress, comptime format: []const u8, args: anytype) void {
233 const file = self.terminal orelse return;
234 self.refresh();
235 file.outStream().print(format, args) catch {
236 self.terminal = null;
237 return;
238 };
239 self.columns_written = 0;
240 }
241
242 fn bufWrite(self: *Progress, end: *usize, comptime format: []const u8, args: anytype) void {
243 if (std.fmt.bufPrint(self.output_buffer[end.*..], format, args)) |written| {
244 const amt = written.len;
245 end.* += amt;
246 self.columns_written += amt;
247 } else |err| switch (err) {
248 error.NoSpaceLeft => {
249 self.columns_written += self.output_buffer.len - end.*;
250 end.* = self.output_buffer.len;
251 },
252 }
253 const bytes_needed_for_esc_codes_at_end = if (std.builtin.os.tag == .windows) 0 else 11;
254 const max_end = self.output_buffer.len - bytes_needed_for_esc_codes_at_end;
255 if (end.* > max_end) {
256 const suffix = "... ";
257 self.columns_written = self.columns_written - (end.* - max_end) + suffix.len;
258 std.mem.copy(u8, self.output_buffer[max_end..], suffix);
259 end.* = max_end + suffix.len;
260 }
261 }
262};
263
264test "basic functionality" {
265 var disable = true;
266 if (disable) {
267 // This test is disabled because it uses time.sleep() and is therefore slow. It also
268 // prints bogus progress data to stderr.
269 return error.SkipZigTest;
270 }
271 var progress = Progress{};
272 const root_node = try progress.start("", 100);
273 defer root_node.end();
274
275 const sub_task_names = [_][]const u8{
276 "reticulating splines",
277 "adjusting shoes",
278 "climbing towers",
279 "pouring juice",
280 };
281 var next_sub_task: usize = 0;
282
283 var i: usize = 0;
284 while (i < 100) : (i += 1) {
285 var node = root_node.start(sub_task_names[next_sub_task], 5);
286 node.activate();
287 next_sub_task = (next_sub_task + 1) % sub_task_names.len;
288
289 node.completeOne();
290 std.time.sleep(5 * std.time.ns_per_ms);
291 node.completeOne();
292 node.completeOne();
293 std.time.sleep(5 * std.time.ns_per_ms);
294 node.completeOne();
295 node.completeOne();
296 std.time.sleep(5 * std.time.ns_per_ms);
297
298 node.end();
299
300 std.time.sleep(5 * std.time.ns_per_ms);
301 }
302 {
303 var node = root_node.start("this is a really long name designed to activate the truncation code. let's find out if it works", null);
304 node.activate();
305 std.time.sleep(10 * std.time.ns_per_ms);
306 progress.refresh();
307 std.time.sleep(10 * std.time.ns_per_ms);
308 node.end();
309 }
310}
src/codegen/c.zig+2-3
...@@ -481,9 +481,8 @@ fn genBinOp(ctx: *Context, file: *C, inst: *Inst.BinOp, operator: []const u8) !?...@@ -481,9 +481,8 @@ fn genBinOp(ctx: *Context, file: *C, inst: *Inst.BinOp, operator: []const u8) !?
481 const rhs = try ctx.resolveInst(inst.rhs);481 const rhs = try ctx.resolveInst(inst.rhs);
482 const writer = file.main.writer();482 const writer = file.main.writer();
483 const name = try ctx.name();483 const name = try ctx.name();
484 try writer.writeAll(indentation ++ "const ");484 try renderTypeAndName(ctx, writer, inst.base.ty, name, .Const);
485 try renderType(ctx, writer, inst.base.ty);485 try writer.print(" = {s} {s} {s};\n", .{ lhs, operator, rhs });
486 try writer.print(" {s} = {s} " ++ operator ++ " {s};\n", .{ name, lhs, rhs });
487 return name;486 return name;
488}487}
489488
src/codegen/llvm.zig deleted-125
...@@ -1,125 +0,0 @@
1const std = @import("std");
2const Allocator = std.mem.Allocator;
3
4pub fn targetTriple(allocator: *Allocator, target: std.Target) ![]u8 {
5 const llvm_arch = switch (target.cpu.arch) {
6 .arm => "arm",
7 .armeb => "armeb",
8 .aarch64 => "aarch64",
9 .aarch64_be => "aarch64_be",
10 .aarch64_32 => "aarch64_32",
11 .arc => "arc",
12 .avr => "avr",
13 .bpfel => "bpfel",
14 .bpfeb => "bpfeb",
15 .hexagon => "hexagon",
16 .mips => "mips",
17 .mipsel => "mipsel",
18 .mips64 => "mips64",
19 .mips64el => "mips64el",
20 .msp430 => "msp430",
21 .powerpc => "powerpc",
22 .powerpc64 => "powerpc64",
23 .powerpc64le => "powerpc64le",
24 .r600 => "r600",
25 .amdgcn => "amdgcn",
26 .riscv32 => "riscv32",
27 .riscv64 => "riscv64",
28 .sparc => "sparc",
29 .sparcv9 => "sparcv9",
30 .sparcel => "sparcel",
31 .s390x => "s390x",
32 .tce => "tce",
33 .tcele => "tcele",
34 .thumb => "thumb",
35 .thumbeb => "thumbeb",
36 .i386 => "i386",
37 .x86_64 => "x86_64",
38 .xcore => "xcore",
39 .nvptx => "nvptx",
40 .nvptx64 => "nvptx64",
41 .le32 => "le32",
42 .le64 => "le64",
43 .amdil => "amdil",
44 .amdil64 => "amdil64",
45 .hsail => "hsail",
46 .hsail64 => "hsail64",
47 .spir => "spir",
48 .spir64 => "spir64",
49 .kalimba => "kalimba",
50 .shave => "shave",
51 .lanai => "lanai",
52 .wasm32 => "wasm32",
53 .wasm64 => "wasm64",
54 .renderscript32 => "renderscript32",
55 .renderscript64 => "renderscript64",
56 .ve => "ve",
57 .spu_2 => return error.LLVMBackendDoesNotSupportSPUMarkII,
58 };
59 // TODO Add a sub-arch for some architectures depending on CPU features.
60
61 const llvm_os = switch (target.os.tag) {
62 .freestanding => "unknown",
63 .ananas => "ananas",
64 .cloudabi => "cloudabi",
65 .dragonfly => "dragonfly",
66 .freebsd => "freebsd",
67 .fuchsia => "fuchsia",
68 .ios => "ios",
69 .kfreebsd => "kfreebsd",
70 .linux => "linux",
71 .lv2 => "lv2",
72 .macos => "macosx",
73 .netbsd => "netbsd",
74 .openbsd => "openbsd",
75 .solaris => "solaris",
76 .windows => "windows",
77 .haiku => "haiku",
78 .minix => "minix",
79 .rtems => "rtems",
80 .nacl => "nacl",
81 .cnk => "cnk",
82 .aix => "aix",
83 .cuda => "cuda",
84 .nvcl => "nvcl",
85 .amdhsa => "amdhsa",
86 .ps4 => "ps4",
87 .elfiamcu => "elfiamcu",
88 .tvos => "tvos",
89 .watchos => "watchos",
90 .mesa3d => "mesa3d",
91 .contiki => "contiki",
92 .amdpal => "amdpal",
93 .hermit => "hermit",
94 .hurd => "hurd",
95 .wasi => "wasi",
96 .emscripten => "emscripten",
97 .uefi => "windows",
98 .other => "unknown",
99 };
100
101 const llvm_abi = switch (target.abi) {
102 .none => "unknown",
103 .gnu => "gnu",
104 .gnuabin32 => "gnuabin32",
105 .gnuabi64 => "gnuabi64",
106 .gnueabi => "gnueabi",
107 .gnueabihf => "gnueabihf",
108 .gnux32 => "gnux32",
109 .code16 => "code16",
110 .eabi => "eabi",
111 .eabihf => "eabihf",
112 .android => "android",
113 .musl => "musl",
114 .musleabi => "musleabi",
115 .musleabihf => "musleabihf",
116 .msvc => "msvc",
117 .itanium => "itanium",
118 .cygnus => "cygnus",
119 .coreclr => "coreclr",
120 .simulator => "simulator",
121 .macabi => "macabi",
122 };
123
124 return std.fmt.allocPrint(allocator, "{s}-unknown-{s}-{s}", .{ llvm_arch, llvm_os, llvm_abi });
125}
src/link/C.zig-3
...@@ -111,9 +111,6 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {...@@ -111,9 +111,6 @@ pub fn flushModule(self: *C, comp: *Compilation) !void {
111 if (self.header.buf.items.len > 0) {111 if (self.header.buf.items.len > 0) {
112 try writer.writeByte('\n');112 try writer.writeByte('\n');
113 }113 }
114 if (self.header.items.len > 0) {
115 try writer.print("{s}\n", .{self.header.items});
116 }
117 if (self.constants.items.len > 0) {114 if (self.constants.items.len > 0) {
118 try writer.print("{s}\n", .{self.constants.items});115 try writer.print("{s}\n", .{self.constants.items});
119 }116 }
src/llvm_backend.zig+1-1
...@@ -132,7 +132,7 @@ pub fn targetTriple(allocator: *Allocator, target: std.Target) ![:0]u8 {...@@ -132,7 +132,7 @@ pub fn targetTriple(allocator: *Allocator, target: std.Target) ![:0]u8 {
132 .macabi => "macabi",132 .macabi => "macabi",
133 };133 };
134134
135 return std.fmt.allocPrintZ(allocator, "{}-unknown-{}-{}", .{ llvm_arch, llvm_os, llvm_abi });135 return std.fmt.allocPrintZ(allocator, "{s}-unknown-{s}-{s}", .{ llvm_arch, llvm_os, llvm_abi });
136}136}
137137
138pub const LLVMIRModule = struct {138pub const LLVMIRModule = struct {