authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-10 00:29:49-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-10 00:29:49-04:00
log4787127cf6418f7a819c9d6f07a9046d76e0de65
tree05e2a1d04722ec0a364a5c87278175c27ff7400d
parent6928badd850f9fcebdcc0b13287db2c81d2293c0

partial conversion to post-fix pointer deref using zig fmt


30 files changed, 1620 insertions(+), 1064 deletions(-)

std/atomic/queue.zig+7-5
......@@ -70,7 +70,7 @@ test "std.atomic.queue" {
7070
7171 var queue: Queue(i32) = undefined;
7272 queue.init();
73 var context = Context {
73 var context = Context{
7474 .allocator = a,
7575 .queue = &queue,
7676 .put_sum = 0,
......@@ -81,16 +81,18 @@ test "std.atomic.queue" {
8181
8282 var putters: [put_thread_count]&std.os.Thread = undefined;
8383 for (putters) |*t| {
84 *t = try std.os.spawnThread(&context, startPuts);
84 t.* = try std.os.spawnThread(&context, startPuts);
8585 }
8686 var getters: [put_thread_count]&std.os.Thread = undefined;
8787 for (getters) |*t| {
88 *t = try std.os.spawnThread(&context, startGets);
88 t.* = try std.os.spawnThread(&context, startGets);
8989 }
9090
91 for (putters) |t| t.wait();
91 for (putters) |t|
92 t.wait();
9293 _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
93 for (getters) |t| t.wait();
94 for (getters) |t|
95 t.wait();
9496
9597 std.debug.assert(context.put_sum == context.get_sum);
9698 std.debug.assert(context.get_count == puts_per_thread * put_thread_count);
std/atomic/stack.zig+8-8
......@@ -14,9 +14,7 @@ pub fn Stack(comptime T: type) type {
1414 };
1515
1616 pub fn init() Self {
17 return Self {
18 .root = null,
19 };
17 return Self{ .root = null };
2018 }
2119
2220 /// push operation, but only if you are the first item in the stack. if you did not succeed in
......@@ -75,7 +73,7 @@ test "std.atomic.stack" {
7573 var a = &fixed_buffer_allocator.allocator;
7674
7775 var stack = Stack(i32).init();
78 var context = Context {
76 var context = Context{
7977 .allocator = a,
8078 .stack = &stack,
8179 .put_sum = 0,
......@@ -86,16 +84,18 @@ test "std.atomic.stack" {
8684
8785 var putters: [put_thread_count]&std.os.Thread = undefined;
8886 for (putters) |*t| {
89 *t = try std.os.spawnThread(&context, startPuts);
87 t.* = try std.os.spawnThread(&context, startPuts);
9088 }
9189 var getters: [put_thread_count]&std.os.Thread = undefined;
9290 for (getters) |*t| {
93 *t = try std.os.spawnThread(&context, startGets);
91 t.* = try std.os.spawnThread(&context, startGets);
9492 }
9593
96 for (putters) |t| t.wait();
94 for (putters) |t|
95 t.wait();
9796 _ = @atomicRmw(u8, &context.puts_done, builtin.AtomicRmwOp.Xchg, 1, AtomicOrder.SeqCst);
98 for (getters) |t| t.wait();
97 for (getters) |t|
98 t.wait();
9999
100100 std.debug.assert(context.put_sum == context.get_sum);
101101 std.debug.assert(context.get_count == puts_per_thread * put_thread_count);
std/buffer.zig+3-8
......@@ -31,9 +31,7 @@ pub const Buffer = struct {
3131 /// * ::replaceContentsBuffer
3232 /// * ::resize
3333 pub fn initNull(allocator: &Allocator) Buffer {
34 return Buffer {
35 .list = ArrayList(u8).init(allocator),
36 };
34 return Buffer{ .list = ArrayList(u8).init(allocator) };
3735 }
3836
3937 /// Must deinitialize with deinit.
......@@ -45,9 +43,7 @@ pub const Buffer = struct {
4543 /// allocated with `allocator`.
4644 /// Must deinitialize with deinit.
4745 pub fn fromOwnedSlice(allocator: &Allocator, slice: []u8) Buffer {
48 var self = Buffer {
49 .list = ArrayList(u8).fromOwnedSlice(allocator, slice),
50 };
46 var self = Buffer{ .list = ArrayList(u8).fromOwnedSlice(allocator, slice) };
5147 self.list.append(0);
5248 return self;
5349 }
......@@ -57,11 +53,10 @@ pub const Buffer = struct {
5753 pub fn toOwnedSlice(self: &Buffer) []u8 {
5854 const allocator = self.list.allocator;
5955 const result = allocator.shrink(u8, self.list.items, self.len());
60 *self = initNull(allocator);
56 self.* = initNull(allocator);
6157 return result;
6258 }
6359
64
6560 pub fn deinit(self: &Buffer) void {
6661 self.list.deinit();
6762 }
std/build.zig+86-121
......@@ -82,10 +82,8 @@ pub const Builder = struct {
8282 description: []const u8,
8383 };
8484
85 pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8,
86 cache_root: []const u8) Builder
87 {
88 var self = Builder {
85 pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8, cache_root: []const u8) Builder {
86 var self = Builder{
8987 .zig_exe = zig_exe,
9088 .build_root = build_root,
9189 .cache_root = os.path.relative(allocator, build_root, cache_root) catch unreachable,
......@@ -112,12 +110,12 @@ pub const Builder = struct {
112110 .lib_dir = undefined,
113111 .exe_dir = undefined,
114112 .installed_files = ArrayList([]const u8).init(allocator),
115 .uninstall_tls = TopLevelStep {
113 .uninstall_tls = TopLevelStep{
116114 .step = Step.init("uninstall", allocator, makeUninstall),
117115 .description = "Remove build artifacts from prefix path",
118116 },
119117 .have_uninstall_step = false,
120 .install_tls = TopLevelStep {
118 .install_tls = TopLevelStep{
121119 .step = Step.initNoOp("install", allocator),
122120 .description = "Copy build artifacts to prefix path",
123121 },
......@@ -151,9 +149,7 @@ pub const Builder = struct {
151149 return LibExeObjStep.createObject(self, name, root_src);
152150 }
153151
154 pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8,
155 ver: &const Version) &LibExeObjStep
156 {
152 pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8, ver: &const Version) &LibExeObjStep {
157153 return LibExeObjStep.createSharedLibrary(self, name, root_src, ver);
158154 }
159155
......@@ -163,7 +159,7 @@ pub const Builder = struct {
163159
164160 pub fn addTest(self: &Builder, root_src: []const u8) &TestStep {
165161 const test_step = self.allocator.create(TestStep) catch unreachable;
166 *test_step = TestStep.init(self, root_src);
162 test_step.* = TestStep.init(self, root_src);
167163 return test_step;
168164 }
169165
......@@ -190,33 +186,31 @@ pub const Builder = struct {
190186 }
191187
192188 /// ::argv is copied.
193 pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
194 argv: []const []const u8) &CommandStep
195 {
189 pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap, argv: []const []const u8) &CommandStep {
196190 return CommandStep.create(self, cwd, env_map, argv);
197191 }
198192
199193 pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) &WriteFileStep {
200194 const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
201 *write_file_step = WriteFileStep.init(self, file_path, data);
195 write_file_step.* = WriteFileStep.init(self, file_path, data);
202196 return write_file_step;
203197 }
204198
205199 pub fn addLog(self: &Builder, comptime format: []const u8, args: ...) &LogStep {
206200 const data = self.fmt(format, args);
207201 const log_step = self.allocator.create(LogStep) catch unreachable;
208 *log_step = LogStep.init(self, data);
202 log_step.* = LogStep.init(self, data);
209203 return log_step;
210204 }
211205
212206 pub fn addRemoveDirTree(self: &Builder, dir_path: []const u8) &RemoveDirStep {
213207 const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
214 *remove_dir_step = RemoveDirStep.init(self, dir_path);
208 remove_dir_step.* = RemoveDirStep.init(self, dir_path);
215209 return remove_dir_step;
216210 }
217211
218212 pub fn version(self: &const Builder, major: u32, minor: u32, patch: u32) Version {
219 return Version {
213 return Version{
220214 .major = major,
221215 .minor = minor,
222216 .patch = patch,
......@@ -254,8 +248,7 @@ pub const Builder = struct {
254248 }
255249
256250 pub fn getInstallStep(self: &Builder) &Step {
257 if (self.have_install_step)
258 return &self.install_tls.step;
251 if (self.have_install_step) return &self.install_tls.step;
259252
260253 self.top_level_steps.append(&self.install_tls) catch unreachable;
261254 self.have_install_step = true;
......@@ -263,8 +256,7 @@ pub const Builder = struct {
263256 }
264257
265258 pub fn getUninstallStep(self: &Builder) &Step {
266 if (self.have_uninstall_step)
267 return &self.uninstall_tls.step;
259 if (self.have_uninstall_step) return &self.uninstall_tls.step;
268260
269261 self.top_level_steps.append(&self.uninstall_tls) catch unreachable;
270262 self.have_uninstall_step = true;
......@@ -360,7 +352,7 @@ pub const Builder = struct {
360352
361353 pub fn option(self: &Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
362354 const type_id = comptime typeToEnum(T);
363 const available_option = AvailableOption {
355 const available_option = AvailableOption{
364356 .name = name,
365357 .type_id = type_id,
366358 .description = description,
......@@ -413,7 +405,7 @@ pub const Builder = struct {
413405
414406 pub fn step(self: &Builder, name: []const u8, description: []const u8) &Step {
415407 const step_info = self.allocator.create(TopLevelStep) catch unreachable;
416 *step_info = TopLevelStep {
408 step_info.* = TopLevelStep{
417409 .step = Step.initNoOp(name, self.allocator),
418410 .description = description,
419411 };
......@@ -446,9 +438,9 @@ pub const Builder = struct {
446438 }
447439
448440 pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) bool {
449 if (self.user_input_options.put(name, UserInputOption {
441 if (self.user_input_options.put(name, UserInputOption{
450442 .name = name,
451 .value = UserValue { .Scalar = value },
443 .value = UserValue{ .Scalar = value },
452444 .used = false,
453445 }) catch unreachable) |*prev_value| {
454446 // option already exists
......@@ -458,18 +450,18 @@ pub const Builder = struct {
458450 var list = ArrayList([]const u8).init(self.allocator);
459451 list.append(s) catch unreachable;
460452 list.append(value) catch unreachable;
461 _ = self.user_input_options.put(name, UserInputOption {
453 _ = self.user_input_options.put(name, UserInputOption{
462454 .name = name,
463 .value = UserValue { .List = list },
455 .value = UserValue{ .List = list },
464456 .used = false,
465457 }) catch unreachable;
466458 },
467459 UserValue.List => |*list| {
468460 // append to the list
469461 list.append(value) catch unreachable;
470 _ = self.user_input_options.put(name, UserInputOption {
462 _ = self.user_input_options.put(name, UserInputOption{
471463 .name = name,
472 .value = UserValue { .List = *list },
464 .value = UserValue{ .List = list.* },
473465 .used = false,
474466 }) catch unreachable;
475467 },
......@@ -483,9 +475,9 @@ pub const Builder = struct {
483475 }
484476
485477 pub fn addUserInputFlag(self: &Builder, name: []const u8) bool {
486 if (self.user_input_options.put(name, UserInputOption {
478 if (self.user_input_options.put(name, UserInputOption{
487479 .name = name,
488 .value = UserValue {.Flag = {} },
480 .value = UserValue{ .Flag = {} },
489481 .used = false,
490482 }) catch unreachable) |*prev_value| {
491483 switch (prev_value.value) {
......@@ -556,9 +548,7 @@ pub const Builder = struct {
556548 warn("\n");
557549 }
558550
559 fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
560 argv: []const []const u8) !void
561 {
551 fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap, argv: []const []const u8) !void {
562552 if (self.verbose) {
563553 printCmd(cwd, argv);
564554 }
......@@ -617,7 +607,7 @@ pub const Builder = struct {
617607 self.pushInstalledFile(full_dest_path);
618608
619609 const install_step = self.allocator.create(InstallFileStep) catch unreachable;
620 *install_step = InstallFileStep.init(self, src_path, full_dest_path);
610 install_step.* = InstallFileStep.init(self, src_path, full_dest_path);
621611 return install_step;
622612 }
623613
......@@ -659,25 +649,23 @@ pub const Builder = struct {
659649 if (builtin.environ == builtin.Environ.msvc) {
660650 return "cl.exe";
661651 } else {
662 return os.getEnvVarOwned(self.allocator, "CC") catch |err|
652 return os.getEnvVarOwned(self.allocator, "CC") catch |err|
663653 if (err == error.EnvironmentVariableNotFound)
664654 ([]const u8)("cc")
665655 else
666 debug.panic("Unable to get environment variable: {}", err)
667 ;
656 debug.panic("Unable to get environment variable: {}", err);
668657 }
669658 }
670659
671660 pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 {
672661 // TODO report error for ambiguous situations
673 const exe_extension = (Target { .Native = {}}).exeFileExt();
662 const exe_extension = (Target{ .Native = {} }).exeFileExt();
674663 for (self.search_prefixes.toSliceConst()) |search_prefix| {
675664 for (names) |name| {
676665 if (os.path.isAbsolute(name)) {
677666 return name;
678667 }
679 const full_path = try os.path.join(self.allocator, search_prefix, "bin",
680 self.fmt("{}{}", name, exe_extension));
668 const full_path = try os.path.join(self.allocator, search_prefix, "bin", self.fmt("{}{}", name, exe_extension));
681669 if (os.path.real(self.allocator, full_path)) |real_path| {
682670 return real_path;
683671 } else |_| {
......@@ -761,7 +749,7 @@ pub const Target = union(enum) {
761749 Cross: CrossTarget,
762750
763751 pub fn oFileExt(self: &const Target) []const u8 {
764 const environ = switch (*self) {
752 const environ = switch (self.*) {
765753 Target.Native => builtin.environ,
766754 Target.Cross => |t| t.environ,
767755 };
......@@ -786,7 +774,7 @@ pub const Target = union(enum) {
786774 }
787775
788776 pub fn getOs(self: &const Target) builtin.Os {
789 return switch (*self) {
777 return switch (self.*) {
790778 Target.Native => builtin.os,
791779 Target.Cross => |t| t.os,
792780 };
......@@ -794,7 +782,8 @@ pub const Target = union(enum) {
794782
795783 pub fn isDarwin(self: &const Target) bool {
796784 return switch (self.getOs()) {
797 builtin.Os.ios, builtin.Os.macosx => true,
785 builtin.Os.ios,
786 builtin.Os.macosx => true,
798787 else => false,
799788 };
800789 }
......@@ -860,61 +849,57 @@ pub const LibExeObjStep = struct {
860849 Obj,
861850 };
862851
863 pub fn createSharedLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8,
864 ver: &const Version) &LibExeObjStep
865 {
852 pub fn createSharedLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8, ver: &const Version) &LibExeObjStep {
866853 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
867 *self = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
854 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
868855 return self;
869856 }
870857
871858 pub fn createCSharedLibrary(builder: &Builder, name: []const u8, version: &const Version) &LibExeObjStep {
872859 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
873 *self = initC(builder, name, Kind.Lib, version, false);
860 self.* = initC(builder, name, Kind.Lib, version, false);
874861 return self;
875862 }
876863
877864 pub fn createStaticLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
878865 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
879 *self = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
866 self.* = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
880867 return self;
881868 }
882869
883870 pub fn createCStaticLibrary(builder: &Builder, name: []const u8) &LibExeObjStep {
884871 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
885 *self = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
872 self.* = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
886873 return self;
887874 }
888875
889876 pub fn createObject(builder: &Builder, name: []const u8, root_src: []const u8) &LibExeObjStep {
890877 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
891 *self = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
878 self.* = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
892879 return self;
893880 }
894881
895882 pub fn createCObject(builder: &Builder, name: []const u8, src: []const u8) &LibExeObjStep {
896883 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
897 *self = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
884 self.* = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
898885 self.object_src = src;
899886 return self;
900887 }
901888
902889 pub fn createExecutable(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
903890 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
904 *self = initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0));
891 self.* = initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0));
905892 return self;
906893 }
907894
908895 pub fn createCExecutable(builder: &Builder, name: []const u8) &LibExeObjStep {
909896 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
910 *self = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
897 self.* = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
911898 return self;
912899 }
913900
914 fn initExtraArgs(builder: &Builder, name: []const u8, root_src: ?[]const u8, kind: Kind,
915 static: bool, ver: &const Version) LibExeObjStep
916 {
917 var self = LibExeObjStep {
901 fn initExtraArgs(builder: &Builder, name: []const u8, root_src: ?[]const u8, kind: Kind, static: bool, ver: &const Version) LibExeObjStep {
902 var self = LibExeObjStep{
918903 .strip = false,
919904 .builder = builder,
920905 .verbose_link = false,
......@@ -930,7 +915,7 @@ pub const LibExeObjStep = struct {
930915 .step = Step.init(name, builder.allocator, make),
931916 .output_path = null,
932917 .output_h_path = null,
933 .version = *ver,
918 .version = ver.*,
934919 .out_filename = undefined,
935920 .out_h_filename = builder.fmt("{}.h", name),
936921 .major_only_filename = undefined,
......@@ -953,11 +938,11 @@ pub const LibExeObjStep = struct {
953938 }
954939
955940 fn initC(builder: &Builder, name: []const u8, kind: Kind, version: &const Version, static: bool) LibExeObjStep {
956 var self = LibExeObjStep {
941 var self = LibExeObjStep{
957942 .builder = builder,
958943 .name = name,
959944 .kind = kind,
960 .version = *version,
945 .version = version.*,
961946 .static = static,
962947 .target = Target.Native,
963948 .cflags = ArrayList([]const u8).init(builder.allocator),
......@@ -1005,9 +990,9 @@ pub const LibExeObjStep = struct {
1005990 self.out_filename = self.builder.fmt("lib{}.a", self.name);
1006991 } else {
1007992 switch (self.target.getOs()) {
1008 builtin.Os.ios, builtin.Os.macosx => {
1009 self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib",
1010 self.name, self.version.major, self.version.minor, self.version.patch);
993 builtin.Os.ios,
994 builtin.Os.macosx => {
995 self.out_filename = self.builder.fmt("lib{}.{d}.{d}.{d}.dylib", self.name, self.version.major, self.version.minor, self.version.patch);
1011996 self.major_only_filename = self.builder.fmt("lib{}.{d}.dylib", self.name, self.version.major);
1012997 self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
1013998 },
......@@ -1015,8 +1000,7 @@ pub const LibExeObjStep = struct {
10151000 self.out_filename = self.builder.fmt("{}.dll", self.name);
10161001 },
10171002 else => {
1018 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}",
1019 self.name, self.version.major, self.version.minor, self.version.patch);
1003 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}", self.name, self.version.major, self.version.minor, self.version.patch);
10201004 self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);
10211005 self.name_only_filename = self.builder.fmt("lib{}.so", self.name);
10221006 },
......@@ -1026,16 +1010,12 @@ pub const LibExeObjStep = struct {
10261010 }
10271011 }
10281012
1029 pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os,
1030 target_environ: builtin.Environ) void
1031 {
1032 self.target = Target {
1033 .Cross = CrossTarget {
1034 .arch = target_arch,
1035 .os = target_os,
1036 .environ = target_environ,
1037 }
1038 };
1013 pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os, target_environ: builtin.Environ) void {
1014 self.target = Target{ .Cross = CrossTarget{
1015 .arch = target_arch,
1016 .os = target_os,
1017 .environ = target_environ,
1018 } };
10391019 self.computeOutFileNames();
10401020 }
10411021
......@@ -1159,7 +1139,7 @@ pub const LibExeObjStep = struct {
11591139 pub fn addPackagePath(self: &LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void {
11601140 assert(self.is_zig);
11611141
1162 self.packages.append(Pkg {
1142 self.packages.append(Pkg{
11631143 .name = name,
11641144 .path = pkg_index_path,
11651145 }) catch unreachable;
......@@ -1343,8 +1323,7 @@ pub const LibExeObjStep = struct {
13431323 try builder.spawnChild(zig_args.toSliceConst());
13441324
13451325 if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) {
1346 try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
1347 self.name_only_filename);
1326 try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, self.name_only_filename);
13481327 }
13491328 }
13501329
......@@ -1373,7 +1352,8 @@ pub const LibExeObjStep = struct {
13731352 args.append("ssp-buffer-size=4") catch unreachable;
13741353 }
13751354 },
1376 builtin.Mode.ReleaseFast, builtin.Mode.ReleaseSmall => {
1355 builtin.Mode.ReleaseFast,
1356 builtin.Mode.ReleaseSmall => {
13771357 args.append("-O2") catch unreachable;
13781358 args.append("-fno-stack-protector") catch unreachable;
13791359 },
......@@ -1505,8 +1485,7 @@ pub const LibExeObjStep = struct {
15051485 }
15061486
15071487 if (!is_darwin) {
1508 const rpath_arg = builder.fmt("-Wl,-rpath,{}",
1509 os.path.real(builder.allocator, builder.pathFromRoot(builder.cache_root)) catch unreachable);
1488 const rpath_arg = builder.fmt("-Wl,-rpath,{}", os.path.real(builder.allocator, builder.pathFromRoot(builder.cache_root)) catch unreachable);
15101489 defer builder.allocator.free(rpath_arg);
15111490 cc_args.append(rpath_arg) catch unreachable;
15121491
......@@ -1535,8 +1514,7 @@ pub const LibExeObjStep = struct {
15351514 try builder.spawnChild(cc_args.toSliceConst());
15361515
15371516 if (self.target.wantSharedLibSymLinks()) {
1538 try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
1539 self.name_only_filename);
1517 try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename, self.name_only_filename);
15401518 }
15411519 }
15421520 },
......@@ -1581,8 +1559,7 @@ pub const LibExeObjStep = struct {
15811559 cc_args.append("-o") catch unreachable;
15821560 cc_args.append(output_path) catch unreachable;
15831561
1584 const rpath_arg = builder.fmt("-Wl,-rpath,{}",
1585 os.path.real(builder.allocator, builder.pathFromRoot(builder.cache_root)) catch unreachable);
1562 const rpath_arg = builder.fmt("-Wl,-rpath,{}", os.path.real(builder.allocator, builder.pathFromRoot(builder.cache_root)) catch unreachable);
15861563 defer builder.allocator.free(rpath_arg);
15871564 cc_args.append(rpath_arg) catch unreachable;
15881565
......@@ -1635,7 +1612,7 @@ pub const TestStep = struct {
16351612
16361613 pub fn init(builder: &Builder, root_src: []const u8) TestStep {
16371614 const step_name = builder.fmt("test {}", root_src);
1638 return TestStep {
1615 return TestStep{
16391616 .step = Step.init(step_name, builder.allocator, make),
16401617 .builder = builder,
16411618 .root_src = root_src,
......@@ -1644,7 +1621,7 @@ pub const TestStep = struct {
16441621 .name_prefix = "",
16451622 .filter = null,
16461623 .link_libs = BufSet.init(builder.allocator),
1647 .target = Target { .Native = {} },
1624 .target = Target{ .Native = {} },
16481625 .exec_cmd_args = null,
16491626 .include_dirs = ArrayList([]const u8).init(builder.allocator),
16501627 };
......@@ -1674,16 +1651,12 @@ pub const TestStep = struct {
16741651 self.filter = text;
16751652 }
16761653
1677 pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os,
1678 target_environ: builtin.Environ) void
1679 {
1680 self.target = Target {
1681 .Cross = CrossTarget {
1682 .arch = target_arch,
1683 .os = target_os,
1684 .environ = target_environ,
1685 }
1686 };
1654 pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os, target_environ: builtin.Environ) void {
1655 self.target = Target{ .Cross = CrossTarget{
1656 .arch = target_arch,
1657 .os = target_os,
1658 .environ = target_environ,
1659 } };
16871660 }
16881661
16891662 pub fn setExecCmd(self: &TestStep, args: []const ?[]const u8) void {
......@@ -1789,11 +1762,9 @@ pub const CommandStep = struct {
17891762 env_map: &const BufMap,
17901763
17911764 /// ::argv is copied.
1792 pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
1793 argv: []const []const u8) &CommandStep
1794 {
1765 pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap, argv: []const []const u8) &CommandStep {
17951766 const self = builder.allocator.create(CommandStep) catch unreachable;
1796 *self = CommandStep {
1767 self.* = CommandStep{
17971768 .builder = builder,
17981769 .step = Step.init(argv[0], builder.allocator, make),
17991770 .argv = builder.allocator.alloc([]u8, argv.len) catch unreachable,
......@@ -1828,7 +1799,7 @@ const InstallArtifactStep = struct {
18281799 LibExeObjStep.Kind.Exe => builder.exe_dir,
18291800 LibExeObjStep.Kind.Lib => builder.lib_dir,
18301801 };
1831 *self = Self {
1802 self.* = Self{
18321803 .builder = builder,
18331804 .step = Step.init(builder.fmt("install {}", artifact.step.name), builder.allocator, make),
18341805 .artifact = artifact,
......@@ -1837,10 +1808,8 @@ const InstallArtifactStep = struct {
18371808 self.step.dependOn(&artifact.step);
18381809 builder.pushInstalledFile(self.dest_file);
18391810 if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {
1840 builder.pushInstalledFile(os.path.join(builder.allocator, builder.lib_dir,
1841 artifact.major_only_filename) catch unreachable);
1842 builder.pushInstalledFile(os.path.join(builder.allocator, builder.lib_dir,
1843 artifact.name_only_filename) catch unreachable);
1811 builder.pushInstalledFile(os.path.join(builder.allocator, builder.lib_dir, artifact.major_only_filename) catch unreachable);
1812 builder.pushInstalledFile(os.path.join(builder.allocator, builder.lib_dir, artifact.name_only_filename) catch unreachable);
18441813 }
18451814 return self;
18461815 }
......@@ -1859,8 +1828,7 @@ const InstallArtifactStep = struct {
18591828 };
18601829 try builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode);
18611830 if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {
1862 try doAtomicSymLinks(builder.allocator, self.dest_file,
1863 self.artifact.major_only_filename, self.artifact.name_only_filename);
1831 try doAtomicSymLinks(builder.allocator, self.dest_file, self.artifact.major_only_filename, self.artifact.name_only_filename);
18641832 }
18651833 }
18661834};
......@@ -1872,7 +1840,7 @@ pub const InstallFileStep = struct {
18721840 dest_path: []const u8,
18731841
18741842 pub fn init(builder: &Builder, src_path: []const u8, dest_path: []const u8) InstallFileStep {
1875 return InstallFileStep {
1843 return InstallFileStep{
18761844 .builder = builder,
18771845 .step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make),
18781846 .src_path = src_path,
......@@ -1893,7 +1861,7 @@ pub const WriteFileStep = struct {
18931861 data: []const u8,
18941862
18951863 pub fn init(builder: &Builder, file_path: []const u8, data: []const u8) WriteFileStep {
1896 return WriteFileStep {
1864 return WriteFileStep{
18971865 .builder = builder,
18981866 .step = Step.init(builder.fmt("writefile {}", file_path), builder.allocator, make),
18991867 .file_path = file_path,
......@@ -1922,7 +1890,7 @@ pub const LogStep = struct {
19221890 data: []const u8,
19231891
19241892 pub fn init(builder: &Builder, data: []const u8) LogStep {
1925 return LogStep {
1893 return LogStep{
19261894 .builder = builder,
19271895 .step = Step.init(builder.fmt("log {}", data), builder.allocator, make),
19281896 .data = data,
......@@ -1941,7 +1909,7 @@ pub const RemoveDirStep = struct {
19411909 dir_path: []const u8,
19421910
19431911 pub fn init(builder: &Builder, dir_path: []const u8) RemoveDirStep {
1944 return RemoveDirStep {
1912 return RemoveDirStep{
19451913 .builder = builder,
19461914 .step = Step.init(builder.fmt("RemoveDir {}", dir_path), builder.allocator, make),
19471915 .dir_path = dir_path,
......@@ -1966,8 +1934,8 @@ pub const Step = struct {
19661934 loop_flag: bool,
19671935 done_flag: bool,
19681936
1969 pub fn init(name: []const u8, allocator: &Allocator, makeFn: fn (&Step)error!void) Step {
1970 return Step {
1937 pub fn init(name: []const u8, allocator: &Allocator, makeFn: fn(&Step) error!void) Step {
1938 return Step{
19711939 .name = name,
19721940 .makeFn = makeFn,
19731941 .dependencies = ArrayList(&Step).init(allocator),
......@@ -1980,8 +1948,7 @@ pub const Step = struct {
19801948 }
19811949
19821950 pub fn make(self: &Step) !void {
1983 if (self.done_flag)
1984 return;
1951 if (self.done_flag) return;
19851952
19861953 try self.makeFn(self);
19871954 self.done_flag = true;
......@@ -1994,9 +1961,7 @@ pub const Step = struct {
19941961 fn makeNoOp(self: &Step) error!void {}
19951962};
19961963
1997fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8,
1998 filename_name_only: []const u8) !void
1999{
1964fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8, filename_name_only: []const u8) !void {
20001965 const out_dir = os.path.dirname(output_path);
20011966 const out_basename = os.path.basename(output_path);
20021967 // sym link for libfoo.so.1 to libfoo.so.1.2.3
std/crypto/blake2.zig+470-241
......@@ -6,11 +6,23 @@ const builtin = @import("builtin");
66const htest = @import("test.zig");
77
88const RoundParam = struct {
9 a: usize, b: usize, c: usize, d: usize, x: usize, y: usize,
9 a: usize,
10 b: usize,
11 c: usize,
12 d: usize,
13 x: usize,
14 y: usize,
1015};
1116
1217fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam {
13 return RoundParam { .a = a, .b = b, .c = c, .d = d, .x = x, .y = y, };
18 return RoundParam{
19 .a = a,
20 .b = b,
21 .c = c,
22 .d = d,
23 .x = x,
24 .y = y,
25 };
1426}
1527
1628/////////////////////
......@@ -19,145 +31,153 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam {
1931pub const Blake2s224 = Blake2s(224);
2032pub const Blake2s256 = Blake2s(256);
2133
22fn Blake2s(comptime out_len: usize) type { return struct {
23 const Self = this;
24 const block_size = 64;
25 const digest_size = out_len / 8;
34fn Blake2s(comptime out_len: usize) type {
35 return struct {
36 const Self = this;
37 const block_size = 64;
38 const digest_size = out_len / 8;
39
40 const iv = [8]u32{
41 0x6A09E667,
42 0xBB67AE85,
43 0x3C6EF372,
44 0xA54FF53A,
45 0x510E527F,
46 0x9B05688C,
47 0x1F83D9AB,
48 0x5BE0CD19,
49 };
2650
27 const iv = [8]u32 {
28 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
29 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19,
30 };
51 const sigma = [10][16]u8{
52 []const u8 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
53 []const u8 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
54 []const u8 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
55 []const u8 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
56 []const u8 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
57 []const u8 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
58 []const u8 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
59 []const u8 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
60 []const u8 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
61 []const u8 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
62 };
3163
32 const sigma = [10][16]u8 {
33 []const u8 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
34 []const u8 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
35 []const u8 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
36 []const u8 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
37 []const u8 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
38 []const u8 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
39 []const u8 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
40 []const u8 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
41 []const u8 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
42 []const u8 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
43 };
64 h: [8]u32,
65 t: u64,
66 // Streaming cache
67 buf: [64]u8,
68 buf_len: u8,
4469
45 h: [8]u32,
46 t: u64,
47 // Streaming cache
48 buf: [64]u8,
49 buf_len: u8,
50
51 pub fn init() Self {
52 debug.assert(8 <= out_len and out_len <= 512);
53
54 var s: Self = undefined;
55 s.reset();
56 return s;
57 }
58
59 pub fn reset(d: &Self) void {
60 mem.copy(u32, d.h[0..], iv[0..]);
61
62 // No key plus default parameters
63 d.h[0] ^= 0x01010000 ^ u32(out_len >> 3);
64 d.t = 0;
65 d.buf_len = 0;
66 }
67
68 pub fn hash(b: []const u8, out: []u8) void {
69 var d = Self.init();
70 d.update(b);
71 d.final(out);
72 }
73
74 pub fn update(d: &Self, b: []const u8) void {
75 var off: usize = 0;
76
77 // Partial buffer exists from previous update. Copy into buffer then hash.
78 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
79 off += 64 - d.buf_len;
80 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
81 d.t += 64;
82 d.round(d.buf[0..], false);
83 d.buf_len = 0;
70 pub fn init() Self {
71 debug.assert(8 <= out_len and out_len <= 512);
72
73 var s: Self = undefined;
74 s.reset();
75 return s;
8476 }
8577
86 // Full middle blocks.
87 while (off + 64 <= b.len) : (off += 64) {
88 d.t += 64;
89 d.round(b[off..off + 64], false);
78 pub fn reset(d: &Self) void {
79 mem.copy(u32, d.h[0..], iv[0..]);
80
81 // No key plus default parameters
82 d.h[0] ^= 0x01010000 ^ u32(out_len >> 3);
83 d.t = 0;
84 d.buf_len = 0;
9085 }
9186
92 // Copy any remainder for next pass.
93 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
94 d.buf_len += u8(b[off..].len);
95 }
87 pub fn hash(b: []const u8, out: []u8) void {
88 var d = Self.init();
89 d.update(b);
90 d.final(out);
91 }
9692
97 pub fn final(d: &Self, out: []u8) void {
98 debug.assert(out.len >= out_len / 8);
93 pub fn update(d: &Self, b: []const u8) void {
94 var off: usize = 0;
9995
100 mem.set(u8, d.buf[d.buf_len..], 0);
101 d.t += d.buf_len;
102 d.round(d.buf[0..], true);
96 // Partial buffer exists from previous update. Copy into buffer then hash.
97 if (d.buf_len != 0 and d.buf_len + b.len > 64) {
98 off += 64 - d.buf_len;
99 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
100 d.t += 64;
101 d.round(d.buf[0..], false);
102 d.buf_len = 0;
103 }
103104
104 const rr = d.h[0 .. out_len / 32];
105 // Full middle blocks.
106 while (off + 64 <= b.len) : (off += 64) {
107 d.t += 64;
108 d.round(b[off..off + 64], false);
109 }
105110
106 for (rr) |s, j| {
107 mem.writeInt(out[4*j .. 4*j + 4], s, builtin.Endian.Little);
111 // Copy any remainder for next pass.
112 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
113 d.buf_len += u8(b[off..].len);
108114 }
109 }
110115
111 fn round(d: &Self, b: []const u8, last: bool) void {
112 debug.assert(b.len == 64);
116 pub fn final(d: &Self, out: []u8) void {
117 debug.assert(out.len >= out_len / 8);
113118
114 var m: [16]u32 = undefined;
115 var v: [16]u32 = undefined;
119 mem.set(u8, d.buf[d.buf_len..], 0);
120 d.t += d.buf_len;
121 d.round(d.buf[0..], true);
116122
117 for (m) |*r, i| {
118 *r = mem.readIntLE(u32, b[4*i .. 4*i + 4]);
119 }
123 const rr = d.h[0..out_len / 32];
120124
121 var k: usize = 0;
122 while (k < 8) : (k += 1) {
123 v[k] = d.h[k];
124 v[k+8] = iv[k];
125 for (rr) |s, j| {
126 mem.writeInt(out[4 * j..4 * j + 4], s, builtin.Endian.Little);
127 }
125128 }
126129
127 v[12] ^= @truncate(u32, d.t);
128 v[13] ^= u32(d.t >> 32);
129 if (last) v[14] = ~v[14];
130
131 const rounds = comptime []RoundParam {
132 Rp(0, 4, 8, 12, 0, 1),
133 Rp(1, 5, 9, 13, 2, 3),
134 Rp(2, 6, 10, 14, 4, 5),
135 Rp(3, 7, 11, 15, 6, 7),
136 Rp(0, 5, 10, 15, 8, 9),
137 Rp(1, 6, 11, 12, 10, 11),
138 Rp(2, 7, 8, 13, 12, 13),
139 Rp(3, 4, 9, 14, 14, 15),
140 };
130 fn round(d: &Self, b: []const u8, last: bool) void {
131 debug.assert(b.len == 64);
141132
142 comptime var j: usize = 0;
143 inline while (j < 10) : (j += 1) {
144 inline for (rounds) |r| {
145 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
146 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(16));
147 v[r.c] = v[r.c] +% v[r.d];
148 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(12));
149 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
150 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(8));
151 v[r.c] = v[r.c] +% v[r.d];
152 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(7));
133 var m: [16]u32 = undefined;
134 var v: [16]u32 = undefined;
135
136 for (m) |*r, i| {
137 r.* = mem.readIntLE(u32, b[4 * i..4 * i + 4]);
153138 }
154 }
155139
156 for (d.h) |*r, i| {
157 *r ^= v[i] ^ v[i + 8];
140 var k: usize = 0;
141 while (k < 8) : (k += 1) {
142 v[k] = d.h[k];
143 v[k + 8] = iv[k];
144 }
145
146 v[12] ^= @truncate(u32, d.t);
147 v[13] ^= u32(d.t >> 32);
148 if (last) v[14] = ~v[14];
149
150 const rounds = comptime []RoundParam{
151 Rp(0, 4, 8, 12, 0, 1),
152 Rp(1, 5, 9, 13, 2, 3),
153 Rp(2, 6, 10, 14, 4, 5),
154 Rp(3, 7, 11, 15, 6, 7),
155 Rp(0, 5, 10, 15, 8, 9),
156 Rp(1, 6, 11, 12, 10, 11),
157 Rp(2, 7, 8, 13, 12, 13),
158 Rp(3, 4, 9, 14, 14, 15),
159 };
160
161 comptime var j: usize = 0;
162 inline while (j < 10) : (j += 1) {
163 inline for (rounds) |r| {
164 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
165 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(16));
166 v[r.c] = v[r.c] +% v[r.d];
167 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(12));
168 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
169 v[r.d] = math.rotr(u32, v[r.d] ^ v[r.a], usize(8));
170 v[r.c] = v[r.c] +% v[r.d];
171 v[r.b] = math.rotr(u32, v[r.b] ^ v[r.c], usize(7));
172 }
173 }
174
175 for (d.h) |*r, i| {
176 r.* ^= v[i] ^ v[i + 8];
177 }
158178 }
159 }
160};}
179 };
180}
161181
162182test "blake2s224 single" {
163183 const h1 = "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4";
......@@ -230,7 +250,7 @@ test "blake2s256 streaming" {
230250}
231251
232252test "blake2s256 aligned final" {
233 var block = []u8 {0} ** Blake2s256.block_size;
253 var block = []u8{0} ** Blake2s256.block_size;
234254 var out: [Blake2s256.digest_size]u8 = undefined;
235255
236256 var h = Blake2s256.init();
......@@ -238,154 +258,363 @@ test "blake2s256 aligned final" {
238258 h.final(out[0..]);
239259}
240260
241
242261/////////////////////
243262// Blake2b
244263
245264pub const Blake2b384 = Blake2b(384);
246265pub const Blake2b512 = Blake2b(512);
247266
248fn Blake2b(comptime out_len: usize) type { return struct {
249 const Self = this;
250 const block_size = 128;
251 const digest_size = out_len / 8;
267fn Blake2b(comptime out_len: usize) type {
268 return struct {
269 const Self = this;
270 const block_size = 128;
271 const digest_size = out_len / 8;
272
273 const iv = [8]u64{
274 0x6a09e667f3bcc908,
275 0xbb67ae8584caa73b,
276 0x3c6ef372fe94f82b,
277 0xa54ff53a5f1d36f1,
278 0x510e527fade682d1,
279 0x9b05688c2b3e6c1f,
280 0x1f83d9abfb41bd6b,
281 0x5be0cd19137e2179,
282 };
252283
253 const iv = [8]u64 {
254 0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
255 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
256 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
257 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179,
258 };
284 const sigma = [12][16]u8{
285 []const u8{
286 0,
287 1,
288 2,
289 3,
290 4,
291 5,
292 6,
293 7,
294 8,
295 9,
296 10,
297 11,
298 12,
299 13,
300 14,
301 15,
302 },
303 []const u8{
304 14,
305 10,
306 4,
307 8,
308 9,
309 15,
310 13,
311 6,
312 1,
313 12,
314 0,
315 2,
316 11,
317 7,
318 5,
319 3,
320 },
321 []const u8{
322 11,
323 8,
324 12,
325 0,
326 5,
327 2,
328 15,
329 13,
330 10,
331 14,
332 3,
333 6,
334 7,
335 1,
336 9,
337 4,
338 },
339 []const u8{
340 7,
341 9,
342 3,
343 1,
344 13,
345 12,
346 11,
347 14,
348 2,
349 6,
350 5,
351 10,
352 4,
353 0,
354 15,
355 8,
356 },
357 []const u8{
358 9,
359 0,
360 5,
361 7,
362 2,
363 4,
364 10,
365 15,
366 14,
367 1,
368 11,
369 12,
370 6,
371 8,
372 3,
373 13,
374 },
375 []const u8{
376 2,
377 12,
378 6,
379 10,
380 0,
381 11,
382 8,
383 3,
384 4,
385 13,
386 7,
387 5,
388 15,
389 14,
390 1,
391 9,
392 },
393 []const u8{
394 12,
395 5,
396 1,
397 15,
398 14,
399 13,
400 4,
401 10,
402 0,
403 7,
404 6,
405 3,
406 9,
407 2,
408 8,
409 11,
410 },
411 []const u8{
412 13,
413 11,
414 7,
415 14,
416 12,
417 1,
418 3,
419 9,
420 5,
421 0,
422 15,
423 4,
424 8,
425 6,
426 2,
427 10,
428 },
429 []const u8{
430 6,
431 15,
432 14,
433 9,
434 11,
435 3,
436 0,
437 8,
438 12,
439 2,
440 13,
441 7,
442 1,
443 4,
444 10,
445 5,
446 },
447 []const u8{
448 10,
449 2,
450 8,
451 4,
452 7,
453 6,
454 1,
455 5,
456 15,
457 11,
458 9,
459 14,
460 3,
461 12,
462 13,
463 0,
464 },
465 []const u8{
466 0,
467 1,
468 2,
469 3,
470 4,
471 5,
472 6,
473 7,
474 8,
475 9,
476 10,
477 11,
478 12,
479 13,
480 14,
481 15,
482 },
483 []const u8{
484 14,
485 10,
486 4,
487 8,
488 9,
489 15,
490 13,
491 6,
492 1,
493 12,
494 0,
495 2,
496 11,
497 7,
498 5,
499 3,
500 },
501 };
259502
260 const sigma = [12][16]u8 {
261 []const u8 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
262 []const u8 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
263 []const u8 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
264 []const u8 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
265 []const u8 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
266 []const u8 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
267 []const u8 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
268 []const u8 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
269 []const u8 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
270 []const u8 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
271 []const u8 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
272 []const u8 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
273 };
503 h: [8]u64,
504 t: u128,
505 // Streaming cache
506 buf: [128]u8,
507 buf_len: u8,
274508
275 h: [8]u64,
276 t: u128,
277 // Streaming cache
278 buf: [128]u8,
279 buf_len: u8,
280
281 pub fn init() Self {
282 debug.assert(8 <= out_len and out_len <= 512);
283
284 var s: Self = undefined;
285 s.reset();
286 return s;
287 }
288
289 pub fn reset(d: &Self) void {
290 mem.copy(u64, d.h[0..], iv[0..]);
291
292 // No key plus default parameters
293 d.h[0] ^= 0x01010000 ^ (out_len >> 3);
294 d.t = 0;
295 d.buf_len = 0;
296 }
297
298 pub fn hash(b: []const u8, out: []u8) void {
299 var d = Self.init();
300 d.update(b);
301 d.final(out);
302 }
303
304 pub fn update(d: &Self, b: []const u8) void {
305 var off: usize = 0;
306
307 // Partial buffer exists from previous update. Copy into buffer then hash.
308 if (d.buf_len != 0 and d.buf_len + b.len > 128) {
309 off += 128 - d.buf_len;
310 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
311 d.t += 128;
312 d.round(d.buf[0..], false);
509 pub fn init() Self {
510 debug.assert(8 <= out_len and out_len <= 512);
511
512 var s: Self = undefined;
513 s.reset();
514 return s;
515 }
516
517 pub fn reset(d: &Self) void {
518 mem.copy(u64, d.h[0..], iv[0..]);
519
520 // No key plus default parameters
521 d.h[0] ^= 0x01010000 ^ (out_len >> 3);
522 d.t = 0;
313523 d.buf_len = 0;
314524 }
315525
316 // Full middle blocks.
317 while (off + 128 <= b.len) : (off += 128) {
318 d.t += 128;
319 d.round(b[off..off + 128], false);
526 pub fn hash(b: []const u8, out: []u8) void {
527 var d = Self.init();
528 d.update(b);
529 d.final(out);
320530 }
321531
322 // Copy any remainder for next pass.
323 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
324 d.buf_len += u8(b[off..].len);
325 }
532 pub fn update(d: &Self, b: []const u8) void {
533 var off: usize = 0;
326534
327 pub fn final(d: &Self, out: []u8) void {
328 mem.set(u8, d.buf[d.buf_len..], 0);
329 d.t += d.buf_len;
330 d.round(d.buf[0..], true);
535 // Partial buffer exists from previous update. Copy into buffer then hash.
536 if (d.buf_len != 0 and d.buf_len + b.len > 128) {
537 off += 128 - d.buf_len;
538 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
539 d.t += 128;
540 d.round(d.buf[0..], false);
541 d.buf_len = 0;
542 }
331543
332 const rr = d.h[0 .. out_len / 64];
544 // Full middle blocks.
545 while (off + 128 <= b.len) : (off += 128) {
546 d.t += 128;
547 d.round(b[off..off + 128], false);
548 }
333549
334 for (rr) |s, j| {
335 mem.writeInt(out[8*j .. 8*j + 8], s, builtin.Endian.Little);
550 // Copy any remainder for next pass.
551 mem.copy(u8, d.buf[d.buf_len..], b[off..]);
552 d.buf_len += u8(b[off..].len);
336553 }
337 }
338554
339 fn round(d: &Self, b: []const u8, last: bool) void {
340 debug.assert(b.len == 128);
555 pub fn final(d: &Self, out: []u8) void {
556 mem.set(u8, d.buf[d.buf_len..], 0);
557 d.t += d.buf_len;
558 d.round(d.buf[0..], true);
341559
342 var m: [16]u64 = undefined;
343 var v: [16]u64 = undefined;
560 const rr = d.h[0..out_len / 64];
344561
345 for (m) |*r, i| {
346 *r = mem.readIntLE(u64, b[8*i .. 8*i + 8]);
562 for (rr) |s, j| {
563 mem.writeInt(out[8 * j..8 * j + 8], s, builtin.Endian.Little);
564 }
347565 }
348566
349 var k: usize = 0;
350 while (k < 8) : (k += 1) {
351 v[k] = d.h[k];
352 v[k+8] = iv[k];
353 }
567 fn round(d: &Self, b: []const u8, last: bool) void {
568 debug.assert(b.len == 128);
354569
355 v[12] ^= @truncate(u64, d.t);
356 v[13] ^= u64(d.t >> 64);
357 if (last) v[14] = ~v[14];
358
359 const rounds = comptime []RoundParam {
360 Rp(0, 4, 8, 12, 0, 1),
361 Rp(1, 5, 9, 13, 2, 3),
362 Rp(2, 6, 10, 14, 4, 5),
363 Rp(3, 7, 11, 15, 6, 7),
364 Rp(0, 5, 10, 15, 8, 9),
365 Rp(1, 6, 11, 12, 10, 11),
366 Rp(2, 7, 8, 13, 12, 13),
367 Rp(3, 4, 9, 14, 14, 15),
368 };
570 var m: [16]u64 = undefined;
571 var v: [16]u64 = undefined;
369572
370 comptime var j: usize = 0;
371 inline while (j < 12) : (j += 1) {
372 inline for (rounds) |r| {
373 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
374 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(32));
375 v[r.c] = v[r.c] +% v[r.d];
376 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(24));
377 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
378 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(16));
379 v[r.c] = v[r.c] +% v[r.d];
380 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(63));
573 for (m) |*r, i| {
574 r.* = mem.readIntLE(u64, b[8 * i..8 * i + 8]);
575 }
576
577 var k: usize = 0;
578 while (k < 8) : (k += 1) {
579 v[k] = d.h[k];
580 v[k + 8] = iv[k];
381581 }
382 }
383582
384 for (d.h) |*r, i| {
385 *r ^= v[i] ^ v[i + 8];
583 v[12] ^= @truncate(u64, d.t);
584 v[13] ^= u64(d.t >> 64);
585 if (last) v[14] = ~v[14];
586
587 const rounds = comptime []RoundParam{
588 Rp(0, 4, 8, 12, 0, 1),
589 Rp(1, 5, 9, 13, 2, 3),
590 Rp(2, 6, 10, 14, 4, 5),
591 Rp(3, 7, 11, 15, 6, 7),
592 Rp(0, 5, 10, 15, 8, 9),
593 Rp(1, 6, 11, 12, 10, 11),
594 Rp(2, 7, 8, 13, 12, 13),
595 Rp(3, 4, 9, 14, 14, 15),
596 };
597
598 comptime var j: usize = 0;
599 inline while (j < 12) : (j += 1) {
600 inline for (rounds) |r| {
601 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.x]];
602 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(32));
603 v[r.c] = v[r.c] +% v[r.d];
604 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(24));
605 v[r.a] = v[r.a] +% v[r.b] +% m[sigma[j][r.y]];
606 v[r.d] = math.rotr(u64, v[r.d] ^ v[r.a], usize(16));
607 v[r.c] = v[r.c] +% v[r.d];
608 v[r.b] = math.rotr(u64, v[r.b] ^ v[r.c], usize(63));
609 }
610 }
611
612 for (d.h) |*r, i| {
613 r.* ^= v[i] ^ v[i + 8];
614 }
386615 }
387 }
388};}
616 };
617}
389618
390619test "blake2b384 single" {
391620 const h1 = "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100";
......@@ -458,7 +687,7 @@ test "blake2b512 streaming" {
458687}
459688
460689test "blake2b512 aligned final" {
461 var block = []u8 {0} ** Blake2b512.block_size;
690 var block = []u8{0} ** Blake2b512.block_size;
462691 var out: [Blake2b512.digest_size]u8 = undefined;
463692
464693 var h = Blake2b512.init();
std/crypto/hmac.zig+2-2
......@@ -29,12 +29,12 @@ pub fn Hmac(comptime H: type) type {
2929
3030 var o_key_pad: [H.block_size]u8 = undefined;
3131 for (o_key_pad) |*b, i| {
32 *b = scratch[i] ^ 0x5c;
32 b.* = scratch[i] ^ 0x5c;
3333 }
3434
3535 var i_key_pad: [H.block_size]u8 = undefined;
3636 for (i_key_pad) |*b, i| {
37 *b = scratch[i] ^ 0x36;
37 b.* = scratch[i] ^ 0x36;
3838 }
3939
4040 // HMAC(k, m) = H(o_key_pad | H(i_key_pad | message)) where | is concatenation
std/crypto/sha3.zig+180-101
......@@ -10,148 +10,228 @@ pub const Sha3_256 = Keccak(256, 0x06);
1010pub const Sha3_384 = Keccak(384, 0x06);
1111pub const Sha3_512 = Keccak(512, 0x06);
1212
13fn Keccak(comptime bits: usize, comptime delim: u8) type { return struct {
14 const Self = this;
15 const block_size = 200;
16 const digest_size = bits / 8;
17
18 s: [200]u8,
19 offset: usize,
20 rate: usize,
21
22 pub fn init() Self {
23 var d: Self = undefined;
24 d.reset();
25 return d;
26 }
13fn Keccak(comptime bits: usize, comptime delim: u8) type {
14 return struct {
15 const Self = this;
16 const block_size = 200;
17 const digest_size = bits / 8;
18
19 s: [200]u8,
20 offset: usize,
21 rate: usize,
22
23 pub fn init() Self {
24 var d: Self = undefined;
25 d.reset();
26 return d;
27 }
2728
28 pub fn reset(d: &Self) void {
29 mem.set(u8, d.s[0..], 0);
30 d.offset = 0;
31 d.rate = 200 - (bits / 4);
32 }
29 pub fn reset(d: &Self) void {
30 mem.set(u8, d.s[0..], 0);
31 d.offset = 0;
32 d.rate = 200 - (bits / 4);
33 }
3334
34 pub fn hash(b: []const u8, out: []u8) void {
35 var d = Self.init();
36 d.update(b);
37 d.final(out);
38 }
35 pub fn hash(b: []const u8, out: []u8) void {
36 var d = Self.init();
37 d.update(b);
38 d.final(out);
39 }
3940
40 pub fn update(d: &Self, b: []const u8) void {
41 var ip: usize = 0;
42 var len = b.len;
43 var rate = d.rate - d.offset;
44 var offset = d.offset;
41 pub fn update(d: &Self, b: []const u8) void {
42 var ip: usize = 0;
43 var len = b.len;
44 var rate = d.rate - d.offset;
45 var offset = d.offset;
4546
46 // absorb
47 while (len >= rate) {
48 for (d.s[offset .. offset + rate]) |*r, i|
49 *r ^= b[ip..][i];
47 // absorb
48 while (len >= rate) {
49 for (d.s[offset..offset + rate]) |*r, i|
50 r.* ^= b[ip..][i];
5051
51 keccak_f(1600, d.s[0..]);
52 keccak_f(1600, d.s[0..]);
5253
53 ip += rate;
54 len -= rate;
55 rate = d.rate;
56 offset = 0;
57 }
54 ip += rate;
55 len -= rate;
56 rate = d.rate;
57 offset = 0;
58 }
5859
59 for (d.s[offset .. offset + len]) |*r, i|
60 *r ^= b[ip..][i];
60 for (d.s[offset..offset + len]) |*r, i|
61 r.* ^= b[ip..][i];
6162
62 d.offset = offset + len;
63 }
63 d.offset = offset + len;
64 }
6465
65 pub fn final(d: &Self, out: []u8) void {
66 // padding
67 d.s[d.offset] ^= delim;
68 d.s[d.rate - 1] ^= 0x80;
66 pub fn final(d: &Self, out: []u8) void {
67 // padding
68 d.s[d.offset] ^= delim;
69 d.s[d.rate - 1] ^= 0x80;
6970
70 keccak_f(1600, d.s[0..]);
71 keccak_f(1600, d.s[0..]);
7172
72 // squeeze
73 var op: usize = 0;
74 var len: usize = bits / 8;
73 // squeeze
74 var op: usize = 0;
75 var len: usize = bits / 8;
7576
76 while (len >= d.rate) {
77 mem.copy(u8, out[op..], d.s[0..d.rate]);
78 keccak_f(1600, d.s[0..]);
79 op += d.rate;
80 len -= d.rate;
77 while (len >= d.rate) {
78 mem.copy(u8, out[op..], d.s[0..d.rate]);
79 keccak_f(1600, d.s[0..]);
80 op += d.rate;
81 len -= d.rate;
82 }
83
84 mem.copy(u8, out[op..], d.s[0..len]);
8185 }
86 };
87}
8288
83 mem.copy(u8, out[op..], d.s[0..len]);
84 }
85};}
86
87const RC = []const u64 {
88 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000,
89 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009,
90 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
91 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003,
92 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a,
93 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008,
89const RC = []const u64{
90 0x0000000000000001,
91 0x0000000000008082,
92 0x800000000000808a,
93 0x8000000080008000,
94 0x000000000000808b,
95 0x0000000080000001,
96 0x8000000080008081,
97 0x8000000000008009,
98 0x000000000000008a,
99 0x0000000000000088,
100 0x0000000080008009,
101 0x000000008000000a,
102 0x000000008000808b,
103 0x800000000000008b,
104 0x8000000000008089,
105 0x8000000000008003,
106 0x8000000000008002,
107 0x8000000000000080,
108 0x000000000000800a,
109 0x800000008000000a,
110 0x8000000080008081,
111 0x8000000000008080,
112 0x0000000080000001,
113 0x8000000080008008,
94114};
95115
96const ROTC = []const usize {
97 1, 3, 6, 10, 15, 21, 28, 36,
98 45, 55, 2, 14, 27, 41, 56, 8,
99 25, 43, 62, 18, 39, 61, 20, 44
116const ROTC = []const usize{
117 1,
118 3,
119 6,
120 10,
121 15,
122 21,
123 28,
124 36,
125 45,
126 55,
127 2,
128 14,
129 27,
130 41,
131 56,
132 8,
133 25,
134 43,
135 62,
136 18,
137 39,
138 61,
139 20,
140 44,
100141};
101142
102const PIL = []const usize {
103 10, 7, 11, 17, 18, 3, 5, 16,
104 8, 21, 24, 4, 15, 23, 19, 13,
105 12, 2, 20, 14, 22, 9, 6, 1
143const PIL = []const usize{
144 10,
145 7,
146 11,
147 17,
148 18,
149 3,
150 5,
151 16,
152 8,
153 21,
154 24,
155 4,
156 15,
157 23,
158 19,
159 13,
160 12,
161 2,
162 20,
163 14,
164 22,
165 9,
166 6,
167 1,
106168};
107169
108const M5 = []const usize {
109 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
170const M5 = []const usize{
171 0,
172 1,
173 2,
174 3,
175 4,
176 0,
177 1,
178 2,
179 3,
180 4,
110181};
111182
112183fn keccak_f(comptime F: usize, d: []u8) void {
113184 debug.assert(d.len == F / 8);
114185
115186 const B = F / 25;
116 const no_rounds = comptime x: { break :x 12 + 2 * math.log2(B); };
187 const no_rounds = comptime x: {
188 break :x 12 + 2 * math.log2(B);
189 };
117190
118 var s = []const u64 {0} ** 25;
119 var t = []const u64 {0} ** 1;
120 var c = []const u64 {0} ** 5;
191 var s = []const u64{0} ** 25;
192 var t = []const u64{0} ** 1;
193 var c = []const u64{0} ** 5;
121194
122195 for (s) |*r, i| {
123 *r = mem.readIntLE(u64, d[8*i .. 8*i + 8]);
196 r.* = mem.readIntLE(u64, d[8 * i..8 * i + 8]);
124197 }
125198
126199 comptime var x: usize = 0;
127200 comptime var y: usize = 0;
128201 for (RC[0..no_rounds]) |round| {
129202 // theta
130 x = 0; inline while (x < 5) : (x += 1) {
131 c[x] = s[x] ^ s[x+5] ^ s[x+10] ^ s[x+15] ^ s[x+20];
203 x = 0;
204 inline while (x < 5) : (x += 1) {
205 c[x] = s[x] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20];
132206 }
133 x = 0; inline while (x < 5) : (x += 1) {
134 t[0] = c[M5[x+4]] ^ math.rotl(u64, c[M5[x+1]], usize(1));
135 y = 0; inline while (y < 5) : (y += 1) {
136 s[x + y*5] ^= t[0];
207 x = 0;
208 inline while (x < 5) : (x += 1) {
209 t[0] = c[M5[x + 4]] ^ math.rotl(u64, c[M5[x + 1]], usize(1));
210 y = 0;
211 inline while (y < 5) : (y += 1) {
212 s[x + y * 5] ^= t[0];
137213 }
138214 }
139215
140216 // rho+pi
141217 t[0] = s[1];
142 x = 0; inline while (x < 24) : (x += 1) {
218 x = 0;
219 inline while (x < 24) : (x += 1) {
143220 c[0] = s[PIL[x]];
144221 s[PIL[x]] = math.rotl(u64, t[0], ROTC[x]);
145222 t[0] = c[0];
146223 }
147224
148225 // chi
149 y = 0; inline while (y < 5) : (y += 1) {
150 x = 0; inline while (x < 5) : (x += 1) {
151 c[x] = s[x + y*5];
226 y = 0;
227 inline while (y < 5) : (y += 1) {
228 x = 0;
229 inline while (x < 5) : (x += 1) {
230 c[x] = s[x + y * 5];
152231 }
153 x = 0; inline while (x < 5) : (x += 1) {
154 s[x + y*5] = c[x] ^ (~c[M5[x+1]] & c[M5[x+2]]);
232 x = 0;
233 inline while (x < 5) : (x += 1) {
234 s[x + y * 5] = c[x] ^ (~c[M5[x + 1]] & c[M5[x + 2]]);
155235 }
156236 }
157237
......@@ -160,11 +240,10 @@ fn keccak_f(comptime F: usize, d: []u8) void {
160240 }
161241
162242 for (s) |r, i| {
163 mem.writeInt(d[8*i .. 8*i + 8], r, builtin.Endian.Little);
243 mem.writeInt(d[8 * i..8 * i + 8], r, builtin.Endian.Little);
164244 }
165245}
166246
167
168247test "sha3-224 single" {
169248 htest.assertEqualHash(Sha3_224, "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", "");
170249 htest.assertEqualHash(Sha3_224, "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf", "abc");
......@@ -192,7 +271,7 @@ test "sha3-224 streaming" {
192271}
193272
194273test "sha3-256 single" {
195 htest.assertEqualHash(Sha3_256, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a" , "");
274 htest.assertEqualHash(Sha3_256, "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", "");
196275 htest.assertEqualHash(Sha3_256, "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532", "abc");
197276 htest.assertEqualHash(Sha3_256, "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu");
198277}
......@@ -218,7 +297,7 @@ test "sha3-256 streaming" {
218297}
219298
220299test "sha3-256 aligned final" {
221 var block = []u8 {0} ** Sha3_256.block_size;
300 var block = []u8{0} ** Sha3_256.block_size;
222301 var out: [Sha3_256.digest_size]u8 = undefined;
223302
224303 var h = Sha3_256.init();
......@@ -228,7 +307,7 @@ test "sha3-256 aligned final" {
228307
229308test "sha3-384 single" {
230309 const h1 = "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004";
231 htest.assertEqualHash(Sha3_384, h1 , "");
310 htest.assertEqualHash(Sha3_384, h1, "");
232311 const h2 = "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25";
233312 htest.assertEqualHash(Sha3_384, h2, "abc");
234313 const h3 = "79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7";
......@@ -259,7 +338,7 @@ test "sha3-384 streaming" {
259338
260339test "sha3-512 single" {
261340 const h1 = "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26";
262 htest.assertEqualHash(Sha3_512, h1 , "");
341 htest.assertEqualHash(Sha3_512, h1, "");
263342 const h2 = "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0";
264343 htest.assertEqualHash(Sha3_512, h2, "abc");
265344 const h3 = "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185";
......@@ -289,7 +368,7 @@ test "sha3-512 streaming" {
289368}
290369
291370test "sha3-512 aligned final" {
292 var block = []u8 {0} ** Sha3_512.block_size;
371 var block = []u8{0} ** Sha3_512.block_size;
293372 var out: [Sha3_512.digest_size]u8 = undefined;
294373
295374 var h = Sha3_512.init();
std/event.zig+20-33
......@@ -6,7 +6,7 @@ const mem = std.mem;
66const posix = std.os.posix;
77
88pub const TcpServer = struct {
9 handleRequestFn: async<&mem.Allocator> fn (&TcpServer, &const std.net.Address, &const std.os.File) void,
9 handleRequestFn: async<&mem.Allocator> fn(&TcpServer, &const std.net.Address, &const std.os.File) void,
1010
1111 loop: &Loop,
1212 sockfd: i32,
......@@ -18,13 +18,11 @@ pub const TcpServer = struct {
1818 const PromiseNode = std.LinkedList(promise).Node;
1919
2020 pub fn init(loop: &Loop) !TcpServer {
21 const sockfd = try std.os.posixSocket(posix.AF_INET,
22 posix.SOCK_STREAM|posix.SOCK_CLOEXEC|posix.SOCK_NONBLOCK,
23 posix.PROTO_tcp);
21 const sockfd = try std.os.posixSocket(posix.AF_INET, posix.SOCK_STREAM | posix.SOCK_CLOEXEC | posix.SOCK_NONBLOCK, posix.PROTO_tcp);
2422 errdefer std.os.close(sockfd);
2523
2624 // TODO can't initialize handler coroutine here because we need well defined copy elision
27 return TcpServer {
25 return TcpServer{
2826 .loop = loop,
2927 .sockfd = sockfd,
3028 .accept_coro = null,
......@@ -34,9 +32,7 @@ pub const TcpServer = struct {
3432 };
3533 }
3634
37 pub fn listen(self: &TcpServer, address: &const std.net.Address,
38 handleRequestFn: async<&mem.Allocator> fn (&TcpServer, &const std.net.Address, &const std.os.File)void) !void
39 {
35 pub fn listen(self: &TcpServer, address: &const std.net.Address, handleRequestFn: async<&mem.Allocator> fn(&TcpServer, &const std.net.Address, &const std.os.File) void) !void {
4036 self.handleRequestFn = handleRequestFn;
4137
4238 try std.os.posixBind(self.sockfd, &address.os_addr);
......@@ -48,7 +44,6 @@ pub const TcpServer = struct {
4844
4945 try self.loop.addFd(self.sockfd, ??self.accept_coro);
5046 errdefer self.loop.removeFd(self.sockfd);
51
5247 }
5348
5449 pub fn deinit(self: &TcpServer) void {
......@@ -60,9 +55,7 @@ pub const TcpServer = struct {
6055 pub async fn handler(self: &TcpServer) void {
6156 while (true) {
6257 var accepted_addr: std.net.Address = undefined;
63 if (std.os.posixAccept(self.sockfd, &accepted_addr.os_addr,
64 posix.SOCK_NONBLOCK | posix.SOCK_CLOEXEC)) |accepted_fd|
65 {
58 if (std.os.posixAccept(self.sockfd, &accepted_addr.os_addr, posix.SOCK_NONBLOCK | posix.SOCK_CLOEXEC)) |accepted_fd| {
6659 var socket = std.os.File.openHandle(accepted_fd);
6760 _ = async<self.loop.allocator> self.handleRequestFn(self, accepted_addr, socket) catch |err| switch (err) {
6861 error.OutOfMemory => {
......@@ -110,7 +103,7 @@ pub const Loop = struct {
110103
111104 fn init(allocator: &mem.Allocator) !Loop {
112105 const epollfd = try std.os.linuxEpollCreate(std.os.linux.EPOLL_CLOEXEC);
113 return Loop {
106 return Loop{
114107 .keep_running = true,
115108 .allocator = allocator,
116109 .epollfd = epollfd,
......@@ -118,11 +111,9 @@ pub const Loop = struct {
118111 }
119112
120113 pub fn addFd(self: &Loop, fd: i32, prom: promise) !void {
121 var ev = std.os.linux.epoll_event {
122 .events = std.os.linux.EPOLLIN|std.os.linux.EPOLLOUT|std.os.linux.EPOLLET,
123 .data = std.os.linux.epoll_data {
124 .ptr = @ptrToInt(prom),
125 },
114 var ev = std.os.linux.epoll_event{
115 .events = std.os.linux.EPOLLIN | std.os.linux.EPOLLOUT | std.os.linux.EPOLLET,
116 .data = std.os.linux.epoll_data{ .ptr = @ptrToInt(prom) },
126117 };
127118 try std.os.linuxEpollCtl(self.epollfd, std.os.linux.EPOLL_CTL_ADD, fd, &ev);
128119 }
......@@ -157,9 +148,9 @@ pub const Loop = struct {
157148};
158149
159150pub async fn connect(loop: &Loop, _address: &const std.net.Address) !std.os.File {
160 var address = *_address; // TODO https://github.com/zig-lang/zig/issues/733
151 var address = _address.*; // TODO https://github.com/zig-lang/zig/issues/733
161152
162 const sockfd = try std.os.posixSocket(posix.AF_INET, posix.SOCK_STREAM|posix.SOCK_CLOEXEC|posix.SOCK_NONBLOCK, posix.PROTO_tcp);
153 const sockfd = try std.os.posixSocket(posix.AF_INET, posix.SOCK_STREAM | posix.SOCK_CLOEXEC | posix.SOCK_NONBLOCK, posix.PROTO_tcp);
163154 errdefer std.os.close(sockfd);
164155
165156 try std.os.posixConnectAsync(sockfd, &address.os_addr);
......@@ -179,11 +170,9 @@ test "listen on a port, send bytes, receive bytes" {
179170
180171 const Self = this;
181172
182 async<&mem.Allocator> fn handler(tcp_server: &TcpServer, _addr: &const std.net.Address,
183 _socket: &const std.os.File) void
184 {
173 async<&mem.Allocator> fn handler(tcp_server: &TcpServer, _addr: &const std.net.Address, _socket: &const std.os.File) void {
185174 const self = @fieldParentPtr(Self, "tcp_server", tcp_server);
186 var socket = *_socket; // TODO https://github.com/zig-lang/zig/issues/733
175 var socket = _socket.*; // TODO https://github.com/zig-lang/zig/issues/733
187176 defer socket.close();
188177 const next_handler = async errorableHandler(self, _addr, socket) catch |err| switch (err) {
189178 error.OutOfMemory => @panic("unable to handle connection: out of memory"),
......@@ -191,14 +180,14 @@ test "listen on a port, send bytes, receive bytes" {
191180 (await next_handler) catch |err| {
192181 std.debug.panic("unable to handle connection: {}\n", err);
193182 };
194 suspend |p| { cancel p; }
183 suspend |p| {
184 cancel p;
185 }
195186 }
196187
197 async fn errorableHandler(self: &Self, _addr: &const std.net.Address,
198 _socket: &const std.os.File) !void
199 {
200 const addr = *_addr; // TODO https://github.com/zig-lang/zig/issues/733
201 var socket = *_socket; // TODO https://github.com/zig-lang/zig/issues/733
188 async fn errorableHandler(self: &Self, _addr: &const std.net.Address, _socket: &const std.os.File) !void {
189 const addr = _addr.*; // TODO https://github.com/zig-lang/zig/issues/733
190 var socket = _socket.*; // TODO https://github.com/zig-lang/zig/issues/733
202191
203192 var adapter = std.io.FileOutStream.init(&socket);
204193 var stream = &adapter.stream;
......@@ -210,9 +199,7 @@ test "listen on a port, send bytes, receive bytes" {
210199 const addr = std.net.Address.initIp4(ip4addr, 0);
211200
212201 var loop = try Loop.init(std.debug.global_allocator);
213 var server = MyServer {
214 .tcp_server = try TcpServer.init(&loop),
215 };
202 var server = MyServer{ .tcp_server = try TcpServer.init(&loop) };
216203 defer server.tcp_server.deinit();
217204 try server.tcp_server.listen(addr, MyServer.handler);
218205
std/hash/crc.zig+16-16
......@@ -9,9 +9,9 @@ const std = @import("../index.zig");
99const debug = std.debug;
1010
1111pub const Polynomial = struct {
12 const IEEE = 0xedb88320;
12 const IEEE = 0xedb88320;
1313 const Castagnoli = 0x82f63b78;
14 const Koopman = 0xeb31d82e;
14 const Koopman = 0xeb31d82e;
1515};
1616
1717// IEEE is by far the most common CRC and so is aliased by default.
......@@ -27,20 +27,22 @@ pub fn Crc32WithPoly(comptime poly: u32) type {
2727
2828 for (tables[0]) |*e, i| {
2929 var crc = u32(i);
30 var j: usize = 0; while (j < 8) : (j += 1) {
30 var j: usize = 0;
31 while (j < 8) : (j += 1) {
3132 if (crc & 1 == 1) {
3233 crc = (crc >> 1) ^ poly;
3334 } else {
3435 crc = (crc >> 1);
3536 }
3637 }
37 *e = crc;
38 e.* = crc;
3839 }
3940
4041 var i: usize = 0;
4142 while (i < 256) : (i += 1) {
4243 var crc = tables[0][i];
43 var j: usize = 1; while (j < 8) : (j += 1) {
44 var j: usize = 1;
45 while (j < 8) : (j += 1) {
4446 const index = @truncate(u8, crc);
4547 crc = tables[0][index] ^ (crc >> 8);
4648 tables[j][i] = crc;
......@@ -53,22 +55,21 @@ pub fn Crc32WithPoly(comptime poly: u32) type {
5355 crc: u32,
5456
5557 pub fn init() Self {
56 return Self {
57 .crc = 0xffffffff,
58 };
58 return Self{ .crc = 0xffffffff };
5959 }
6060
6161 pub fn update(self: &Self, input: []const u8) void {
6262 var i: usize = 0;
6363 while (i + 8 <= input.len) : (i += 8) {
64 const p = input[i..i+8];
64 const p = input[i..i + 8];
6565
6666 // Unrolling this way gives ~50Mb/s increase
67 self.crc ^= (u32(p[0]) << 0);
68 self.crc ^= (u32(p[1]) << 8);
67 self.crc ^= (u32(p[0]) << 0);
68 self.crc ^= (u32(p[1]) << 8);
6969 self.crc ^= (u32(p[2]) << 16);
7070 self.crc ^= (u32(p[3]) << 24);
7171
72
7273 self.crc =
7374 lookup_tables[0][p[7]] ^
7475 lookup_tables[1][p[6]] ^
......@@ -123,14 +124,15 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type {
123124
124125 for (table) |*e, i| {
125126 var crc = u32(i * 16);
126 var j: usize = 0; while (j < 8) : (j += 1) {
127 var j: usize = 0;
128 while (j < 8) : (j += 1) {
127129 if (crc & 1 == 1) {
128130 crc = (crc >> 1) ^ poly;
129131 } else {
130132 crc = (crc >> 1);
131133 }
132134 }
133 *e = crc;
135 e.* = crc;
134136 }
135137
136138 break :block table;
......@@ -139,9 +141,7 @@ pub fn Crc32SmallWithPoly(comptime poly: u32) type {
139141 crc: u32,
140142
141143 pub fn init() Self {
142 return Self {
143 .crc = 0xffffffff,
144 };
144 return Self{ .crc = 0xffffffff };
145145 }
146146
147147 pub fn update(self: &Self, input: []const u8) void {
std/hash_map.zig+57-45
......@@ -9,10 +9,7 @@ const builtin = @import("builtin");
99const want_modification_safety = builtin.mode != builtin.Mode.ReleaseFast;
1010const debug_u32 = if (want_modification_safety) u32 else void;
1111
12pub fn HashMap(comptime K: type, comptime V: type,
13 comptime hash: fn(key: K)u32,
14 comptime eql: fn(a: K, b: K)bool) type
15{
12pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K) u32, comptime eql: fn(a: K, b: K) bool) type {
1613 return struct {
1714 entries: []Entry,
1815 size: usize,
......@@ -65,7 +62,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
6562 };
6663
6764 pub fn init(allocator: &Allocator) Self {
68 return Self {
65 return Self{
6966 .entries = []Entry{},
7067 .allocator = allocator,
7168 .size = 0,
......@@ -129,34 +126,36 @@ pub fn HashMap(comptime K: type, comptime V: type,
129126 if (hm.entries.len == 0) return null;
130127 hm.incrementModificationCount();
131128 const start_index = hm.keyToIndex(key);
132 {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
133 const index = (start_index + roll_over) % hm.entries.len;
134 var entry = &hm.entries[index];
135
136 if (!entry.used)
137 return null;
138
139 if (!eql(entry.key, key)) continue;
140
141 while (roll_over < hm.entries.len) : (roll_over += 1) {
142 const next_index = (start_index + roll_over + 1) % hm.entries.len;
143 const next_entry = &hm.entries[next_index];
144 if (!next_entry.used or next_entry.distance_from_start_index == 0) {
145 entry.used = false;
146 hm.size -= 1;
147 return entry;
129 {
130 var roll_over: usize = 0;
131 while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
132 const index = (start_index + roll_over) % hm.entries.len;
133 var entry = &hm.entries[index];
134
135 if (!entry.used) return null;
136
137 if (!eql(entry.key, key)) continue;
138
139 while (roll_over < hm.entries.len) : (roll_over += 1) {
140 const next_index = (start_index + roll_over + 1) % hm.entries.len;
141 const next_entry = &hm.entries[next_index];
142 if (!next_entry.used or next_entry.distance_from_start_index == 0) {
143 entry.used = false;
144 hm.size -= 1;
145 return entry;
146 }
147 entry.* = next_entry.*;
148 entry.distance_from_start_index -= 1;
149 entry = next_entry;
148150 }
149 *entry = *next_entry;
150 entry.distance_from_start_index -= 1;
151 entry = next_entry;
151 unreachable; // shifting everything in the table
152152 }
153 unreachable; // shifting everything in the table
154 }}
153 }
155154 return null;
156155 }
157156
158157 pub fn iterator(hm: &const Self) Iterator {
159 return Iterator {
158 return Iterator{
160159 .hm = hm,
161160 .count = 0,
162161 .index = 0,
......@@ -182,21 +181,23 @@ pub fn HashMap(comptime K: type, comptime V: type,
182181 /// Returns the value that was already there.
183182 fn internalPut(hm: &Self, orig_key: K, orig_value: &const V) ?V {
184183 var key = orig_key;
185 var value = *orig_value;
184 var value = orig_value.*;
186185 const start_index = hm.keyToIndex(key);
187186 var roll_over: usize = 0;
188187 var distance_from_start_index: usize = 0;
189 while (roll_over < hm.entries.len) : ({roll_over += 1; distance_from_start_index += 1;}) {
188 while (roll_over < hm.entries.len) : ({
189 roll_over += 1;
190 distance_from_start_index += 1;
191 }) {
190192 const index = (start_index + roll_over) % hm.entries.len;
191193 const entry = &hm.entries[index];
192194
193195 if (entry.used and !eql(entry.key, key)) {
194196 if (entry.distance_from_start_index < distance_from_start_index) {
195197 // robin hood to the rescue
196 const tmp = *entry;
197 hm.max_distance_from_start_index = math.max(hm.max_distance_from_start_index,
198 distance_from_start_index);
199 *entry = Entry {
198 const tmp = entry.*;
199 hm.max_distance_from_start_index = math.max(hm.max_distance_from_start_index, distance_from_start_index);
200 entry.* = Entry{
200201 .used = true,
201202 .distance_from_start_index = distance_from_start_index,
202203 .key = key,
......@@ -219,7 +220,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
219220 }
220221
221222 hm.max_distance_from_start_index = math.max(distance_from_start_index, hm.max_distance_from_start_index);
222 *entry = Entry {
223 entry.* = Entry{
223224 .used = true,
224225 .distance_from_start_index = distance_from_start_index,
225226 .key = key,
......@@ -232,13 +233,16 @@ pub fn HashMap(comptime K: type, comptime V: type,
232233
233234 fn internalGet(hm: &const Self, key: K) ?&Entry {
234235 const start_index = hm.keyToIndex(key);
235 {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
236 const index = (start_index + roll_over) % hm.entries.len;
237 const entry = &hm.entries[index];
238
239 if (!entry.used) return null;
240 if (eql(entry.key, key)) return entry;
241 }}
236 {
237 var roll_over: usize = 0;
238 while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
239 const index = (start_index + roll_over) % hm.entries.len;
240 const entry = &hm.entries[index];
241
242 if (!entry.used) return null;
243 if (eql(entry.key, key)) return entry;
244 }
245 }
242246 return null;
243247 }
244248
......@@ -282,11 +286,19 @@ test "iterator hash map" {
282286 assert((reset_map.put(2, 22) catch unreachable) == null);
283287 assert((reset_map.put(3, 33) catch unreachable) == null);
284288
285 var keys = []i32 { 1, 2, 3 };
286 var values = []i32 { 11, 22, 33 };
289 var keys = []i32{
290 1,
291 2,
292 3,
293 };
294 var values = []i32{
295 11,
296 22,
297 33,
298 };
287299
288300 var it = reset_map.iterator();
289 var count : usize = 0;
301 var count: usize = 0;
290302 while (it.next()) |next| {
291303 assert(next.key == keys[count]);
292304 assert(next.value == values[count]);
......@@ -305,7 +317,7 @@ test "iterator hash map" {
305317 }
306318
307319 it.reset();
308 var entry = ?? it.next();
320 var entry = ??it.next();
309321 assert(entry.key == keys[0]);
310322 assert(entry.value == values[0]);
311323}
std/json.zig+124-83
......@@ -35,7 +35,7 @@ pub const Token = struct {
3535 };
3636
3737 pub fn init(id: Id, count: usize, offset: u1) Token {
38 return Token {
38 return Token{
3939 .id = id,
4040 .offset = offset,
4141 .string_has_escape = false,
......@@ -45,7 +45,7 @@ pub const Token = struct {
4545 }
4646
4747 pub fn initString(count: usize, has_unicode_escape: bool) Token {
48 return Token {
48 return Token{
4949 .id = Id.String,
5050 .offset = 0,
5151 .string_has_escape = has_unicode_escape,
......@@ -55,7 +55,7 @@ pub const Token = struct {
5555 }
5656
5757 pub fn initNumber(count: usize, number_is_integer: bool) Token {
58 return Token {
58 return Token{
5959 .id = Id.Number,
6060 .offset = 0,
6161 .string_has_escape = false,
......@@ -66,7 +66,7 @@ pub const Token = struct {
6666
6767 // A marker token is a zero-length
6868 pub fn initMarker(id: Id) Token {
69 return Token {
69 return Token{
7070 .id = id,
7171 .offset = 0,
7272 .string_has_escape = false,
......@@ -77,7 +77,7 @@ pub const Token = struct {
7777
7878 // Slice into the underlying input string.
7979 pub fn slice(self: &const Token, input: []const u8, i: usize) []const u8 {
80 return input[i + self.offset - self.count .. i + self.offset];
80 return input[i + self.offset - self.count..i + self.offset];
8181 }
8282};
8383
......@@ -105,8 +105,8 @@ const StreamingJsonParser = struct {
105105 stack: u256,
106106 stack_used: u8,
107107
108 const object_bit = 0;
109 const array_bit = 1;
108 const object_bit = 0;
109 const array_bit = 1;
110110 const max_stack_size = @maxValue(u8);
111111
112112 pub fn init() StreamingJsonParser {
......@@ -120,7 +120,7 @@ const StreamingJsonParser = struct {
120120 p.count = 0;
121121 // Set before ever read in main transition function
122122 p.after_string_state = undefined;
123 p.after_value_state = State.ValueEnd; // handle end of values normally
123 p.after_value_state = State.ValueEnd; // handle end of values normally
124124 p.stack = 0;
125125 p.stack_used = 0;
126126 p.complete = false;
......@@ -181,7 +181,7 @@ const StreamingJsonParser = struct {
181181 }
182182 };
183183
184 pub const Error = error {
184 pub const Error = error{
185185 InvalidTopLevel,
186186 TooManyNestedItems,
187187 TooManyClosingItems,
......@@ -206,8 +206,8 @@ const StreamingJsonParser = struct {
206206 //
207207 // There is currently no error recovery on a bad stream.
208208 pub fn feed(p: &StreamingJsonParser, c: u8, token1: &?Token, token2: &?Token) Error!void {
209 *token1 = null;
210 *token2 = null;
209 token1.* = null;
210 token2.* = null;
211211 p.count += 1;
212212
213213 // unlikely
......@@ -228,7 +228,7 @@ const StreamingJsonParser = struct {
228228 p.state = State.ValueBegin;
229229 p.after_string_state = State.ObjectSeparator;
230230
231 *token = Token.initMarker(Token.Id.ObjectBegin);
231 token.* = Token.initMarker(Token.Id.ObjectBegin);
232232 },
233233 '[' => {
234234 p.stack <<= 1;
......@@ -238,7 +238,7 @@ const StreamingJsonParser = struct {
238238 p.state = State.ValueBegin;
239239 p.after_string_state = State.ValueEnd;
240240
241 *token = Token.initMarker(Token.Id.ArrayBegin);
241 token.* = Token.initMarker(Token.Id.ArrayBegin);
242242 },
243243 '-' => {
244244 p.number_is_integer = true;
......@@ -281,7 +281,10 @@ const StreamingJsonParser = struct {
281281 p.after_value_state = State.TopLevelEnd;
282282 p.count = 0;
283283 },
284 0x09, 0x0A, 0x0D, 0x20 => {
284 0x09,
285 0x0A,
286 0x0D,
287 0x20 => {
285288 // whitespace
286289 },
287290 else => {
......@@ -290,7 +293,10 @@ const StreamingJsonParser = struct {
290293 },
291294
292295 State.TopLevelEnd => switch (c) {
293 0x09, 0x0A, 0x0D, 0x20 => {
296 0x09,
297 0x0A,
298 0x0D,
299 0x20 => {
294300 // whitespace
295301 },
296302 else => {
......@@ -324,7 +330,7 @@ const StreamingJsonParser = struct {
324330 else => {},
325331 }
326332
327 *token = Token.initMarker(Token.Id.ObjectEnd);
333 token.* = Token.initMarker(Token.Id.ObjectEnd);
328334 },
329335 ']' => {
330336 if (p.stack & 1 != array_bit) {
......@@ -348,7 +354,7 @@ const StreamingJsonParser = struct {
348354 else => {},
349355 }
350356
351 *token = Token.initMarker(Token.Id.ArrayEnd);
357 token.* = Token.initMarker(Token.Id.ArrayEnd);
352358 },
353359 '{' => {
354360 if (p.stack_used == max_stack_size) {
......@@ -362,7 +368,7 @@ const StreamingJsonParser = struct {
362368 p.state = State.ValueBegin;
363369 p.after_string_state = State.ObjectSeparator;
364370
365 *token = Token.initMarker(Token.Id.ObjectBegin);
371 token.* = Token.initMarker(Token.Id.ObjectBegin);
366372 },
367373 '[' => {
368374 if (p.stack_used == max_stack_size) {
......@@ -376,7 +382,7 @@ const StreamingJsonParser = struct {
376382 p.state = State.ValueBegin;
377383 p.after_string_state = State.ValueEnd;
378384
379 *token = Token.initMarker(Token.Id.ArrayBegin);
385 token.* = Token.initMarker(Token.Id.ArrayBegin);
380386 },
381387 '-' => {
382388 p.state = State.Number;
......@@ -406,7 +412,10 @@ const StreamingJsonParser = struct {
406412 p.state = State.NullLiteral1;
407413 p.count = 0;
408414 },
409 0x09, 0x0A, 0x0D, 0x20 => {
415 0x09,
416 0x0A,
417 0x0D,
418 0x20 => {
410419 // whitespace
411420 },
412421 else => {
......@@ -428,7 +437,7 @@ const StreamingJsonParser = struct {
428437 p.state = State.ValueBegin;
429438 p.after_string_state = State.ObjectSeparator;
430439
431 *token = Token.initMarker(Token.Id.ObjectBegin);
440 token.* = Token.initMarker(Token.Id.ObjectBegin);
432441 },
433442 '[' => {
434443 if (p.stack_used == max_stack_size) {
......@@ -442,7 +451,7 @@ const StreamingJsonParser = struct {
442451 p.state = State.ValueBegin;
443452 p.after_string_state = State.ValueEnd;
444453
445 *token = Token.initMarker(Token.Id.ArrayBegin);
454 token.* = Token.initMarker(Token.Id.ArrayBegin);
446455 },
447456 '-' => {
448457 p.state = State.Number;
......@@ -472,7 +481,10 @@ const StreamingJsonParser = struct {
472481 p.state = State.NullLiteral1;
473482 p.count = 0;
474483 },
475 0x09, 0x0A, 0x0D, 0x20 => {
484 0x09,
485 0x0A,
486 0x0D,
487 0x20 => {
476488 // whitespace
477489 },
478490 else => {
......@@ -501,7 +513,7 @@ const StreamingJsonParser = struct {
501513 p.state = State.TopLevelEnd;
502514 }
503515
504 *token = Token.initMarker(Token.Id.ArrayEnd);
516 token.* = Token.initMarker(Token.Id.ArrayEnd);
505517 },
506518 '}' => {
507519 if (p.stack_used == 0) {
......@@ -519,9 +531,12 @@ const StreamingJsonParser = struct {
519531 p.state = State.TopLevelEnd;
520532 }
521533
522 *token = Token.initMarker(Token.Id.ObjectEnd);
534 token.* = Token.initMarker(Token.Id.ObjectEnd);
523535 },
524 0x09, 0x0A, 0x0D, 0x20 => {
536 0x09,
537 0x0A,
538 0x0D,
539 0x20 => {
525540 // whitespace
526541 },
527542 else => {
......@@ -534,7 +549,10 @@ const StreamingJsonParser = struct {
534549 p.state = State.ValueBegin;
535550 p.after_string_state = State.ValueEnd;
536551 },
537 0x09, 0x0A, 0x0D, 0x20 => {
552 0x09,
553 0x0A,
554 0x0D,
555 0x20 => {
538556 // whitespace
539557 },
540558 else => {
......@@ -553,12 +571,15 @@ const StreamingJsonParser = struct {
553571 p.complete = true;
554572 }
555573
556 *token = Token.initString(p.count - 1, p.string_has_escape);
574 token.* = Token.initString(p.count - 1, p.string_has_escape);
557575 },
558576 '\\' => {
559577 p.state = State.StringEscapeCharacter;
560578 },
561 0x20, 0x21, 0x23 ... 0x5B, 0x5D ... 0x7F => {
579 0x20,
580 0x21,
581 0x23 ... 0x5B,
582 0x5D ... 0x7F => {
562583 // non-control ascii
563584 },
564585 0xC0 ... 0xDF => {
......@@ -599,7 +620,14 @@ const StreamingJsonParser = struct {
599620 // The current JSONTestSuite tests rely on both of this behaviour being present
600621 // however, so we default to the status quo where both are accepted until this
601622 // is further clarified.
602 '"', '\\', '/', 'b', 'f', 'n', 'r', 't' => {
623 '"',
624 '\\',
625 '/',
626 'b',
627 'f',
628 'n',
629 'r',
630 't' => {
603631 p.string_has_escape = true;
604632 p.state = State.String;
605633 },
......@@ -613,28 +641,36 @@ const StreamingJsonParser = struct {
613641 },
614642
615643 State.StringEscapeHexUnicode4 => switch (c) {
616 '0' ... '9', 'A' ... 'F', 'a' ... 'f' => {
644 '0' ... '9',
645 'A' ... 'F',
646 'a' ... 'f' => {
617647 p.state = State.StringEscapeHexUnicode3;
618648 },
619649 else => return error.InvalidUnicodeHexSymbol,
620650 },
621651
622652 State.StringEscapeHexUnicode3 => switch (c) {
623 '0' ... '9', 'A' ... 'F', 'a' ... 'f' => {
653 '0' ... '9',
654 'A' ... 'F',
655 'a' ... 'f' => {
624656 p.state = State.StringEscapeHexUnicode2;
625657 },
626658 else => return error.InvalidUnicodeHexSymbol,
627659 },
628660
629661 State.StringEscapeHexUnicode2 => switch (c) {
630 '0' ... '9', 'A' ... 'F', 'a' ... 'f' => {
662 '0' ... '9',
663 'A' ... 'F',
664 'a' ... 'f' => {
631665 p.state = State.StringEscapeHexUnicode1;
632666 },
633667 else => return error.InvalidUnicodeHexSymbol,
634668 },
635669
636670 State.StringEscapeHexUnicode1 => switch (c) {
637 '0' ... '9', 'A' ... 'F', 'a' ... 'f' => {
671 '0' ... '9',
672 'A' ... 'F',
673 'a' ... 'f' => {
638674 p.state = State.String;
639675 },
640676 else => return error.InvalidUnicodeHexSymbol,
......@@ -662,13 +698,14 @@ const StreamingJsonParser = struct {
662698 p.number_is_integer = false;
663699 p.state = State.NumberFractionalRequired;
664700 },
665 'e', 'E' => {
701 'e',
702 'E' => {
666703 p.number_is_integer = false;
667704 p.state = State.NumberExponent;
668705 },
669706 else => {
670707 p.state = p.after_value_state;
671 *token = Token.initNumber(p.count, p.number_is_integer);
708 token.* = Token.initNumber(p.count, p.number_is_integer);
672709 return true;
673710 },
674711 }
......@@ -681,7 +718,8 @@ const StreamingJsonParser = struct {
681718 p.number_is_integer = false;
682719 p.state = State.NumberFractionalRequired;
683720 },
684 'e', 'E' => {
721 'e',
722 'E' => {
685723 p.number_is_integer = false;
686724 p.state = State.NumberExponent;
687725 },
......@@ -690,7 +728,7 @@ const StreamingJsonParser = struct {
690728 },
691729 else => {
692730 p.state = p.after_value_state;
693 *token = Token.initNumber(p.count, p.number_is_integer);
731 token.* = Token.initNumber(p.count, p.number_is_integer);
694732 return true;
695733 },
696734 }
......@@ -714,13 +752,14 @@ const StreamingJsonParser = struct {
714752 '0' ... '9' => {
715753 // another digit
716754 },
717 'e', 'E' => {
755 'e',
756 'E' => {
718757 p.number_is_integer = false;
719758 p.state = State.NumberExponent;
720759 },
721760 else => {
722761 p.state = p.after_value_state;
723 *token = Token.initNumber(p.count, p.number_is_integer);
762 token.* = Token.initNumber(p.count, p.number_is_integer);
724763 return true;
725764 },
726765 }
......@@ -729,20 +768,22 @@ const StreamingJsonParser = struct {
729768 State.NumberMaybeExponent => {
730769 p.complete = p.after_value_state == State.TopLevelEnd;
731770 switch (c) {
732 'e', 'E' => {
771 'e',
772 'E' => {
733773 p.number_is_integer = false;
734774 p.state = State.NumberExponent;
735775 },
736776 else => {
737777 p.state = p.after_value_state;
738 *token = Token.initNumber(p.count, p.number_is_integer);
778 token.* = Token.initNumber(p.count, p.number_is_integer);
739779 return true;
740780 },
741781 }
742782 },
743783
744784 State.NumberExponent => switch (c) {
745 '-', '+', => {
785 '-',
786 '+' => {
746787 p.complete = false;
747788 p.state = State.NumberExponentDigitsRequired;
748789 },
......@@ -773,7 +814,7 @@ const StreamingJsonParser = struct {
773814 },
774815 else => {
775816 p.state = p.after_value_state;
776 *token = Token.initNumber(p.count, p.number_is_integer);
817 token.* = Token.initNumber(p.count, p.number_is_integer);
777818 return true;
778819 },
779820 }
......@@ -793,7 +834,7 @@ const StreamingJsonParser = struct {
793834 'e' => {
794835 p.state = p.after_value_state;
795836 p.complete = p.state == State.TopLevelEnd;
796 *token = Token.init(Token.Id.True, p.count + 1, 1);
837 token.* = Token.init(Token.Id.True, p.count + 1, 1);
797838 },
798839 else => {
799840 return error.InvalidLiteral;
......@@ -819,7 +860,7 @@ const StreamingJsonParser = struct {
819860 'e' => {
820861 p.state = p.after_value_state;
821862 p.complete = p.state == State.TopLevelEnd;
822 *token = Token.init(Token.Id.False, p.count + 1, 1);
863 token.* = Token.init(Token.Id.False, p.count + 1, 1);
823864 },
824865 else => {
825866 return error.InvalidLiteral;
......@@ -840,7 +881,7 @@ const StreamingJsonParser = struct {
840881 'l' => {
841882 p.state = p.after_value_state;
842883 p.complete = p.state == State.TopLevelEnd;
843 *token = Token.init(Token.Id.Null, p.count + 1, 1);
884 token.* = Token.init(Token.Id.Null, p.count + 1, 1);
844885 },
845886 else => {
846887 return error.InvalidLiteral;
......@@ -895,7 +936,7 @@ pub const Value = union(enum) {
895936 Object: ObjectMap,
896937
897938 pub fn dump(self: &const Value) void {
898 switch (*self) {
939 switch (self.*) {
899940 Value.Null => {
900941 std.debug.warn("null");
901942 },
......@@ -950,7 +991,7 @@ pub const Value = union(enum) {
950991 }
951992
952993 fn dumpIndentLevel(self: &const Value, indent: usize, level: usize) void {
953 switch (*self) {
994 switch (self.*) {
954995 Value.Null => {
955996 std.debug.warn("null");
956997 },
......@@ -1027,7 +1068,7 @@ const JsonParser = struct {
10271068 };
10281069
10291070 pub fn init(allocator: &Allocator, copy_strings: bool) JsonParser {
1030 return JsonParser {
1071 return JsonParser{
10311072 .allocator = allocator,
10321073 .state = State.Simple,
10331074 .copy_strings = copy_strings,
......@@ -1082,7 +1123,7 @@ const JsonParser = struct {
10821123
10831124 std.debug.assert(p.stack.len == 1);
10841125
1085 return ValueTree {
1126 return ValueTree{
10861127 .arena = arena,
10871128 .root = p.stack.at(0),
10881129 };
......@@ -1115,11 +1156,11 @@ const JsonParser = struct {
11151156
11161157 switch (token.id) {
11171158 Token.Id.ObjectBegin => {
1118 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });
1159 try p.stack.append(Value{ .Object = ObjectMap.init(allocator) });
11191160 p.state = State.ObjectKey;
11201161 },
11211162 Token.Id.ArrayBegin => {
1122 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });
1163 try p.stack.append(Value{ .Array = ArrayList(Value).init(allocator) });
11231164 p.state = State.ArrayValue;
11241165 },
11251166 Token.Id.String => {
......@@ -1133,12 +1174,12 @@ const JsonParser = struct {
11331174 p.state = State.ObjectKey;
11341175 },
11351176 Token.Id.True => {
1136 _ = try object.put(key, Value { .Bool = true });
1177 _ = try object.put(key, Value{ .Bool = true });
11371178 _ = p.stack.pop();
11381179 p.state = State.ObjectKey;
11391180 },
11401181 Token.Id.False => {
1141 _ = try object.put(key, Value { .Bool = false });
1182 _ = try object.put(key, Value{ .Bool = false });
11421183 _ = p.stack.pop();
11431184 p.state = State.ObjectKey;
11441185 },
......@@ -1165,11 +1206,11 @@ const JsonParser = struct {
11651206 try p.pushToParent(value);
11661207 },
11671208 Token.Id.ObjectBegin => {
1168 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });
1209 try p.stack.append(Value{ .Object = ObjectMap.init(allocator) });
11691210 p.state = State.ObjectKey;
11701211 },
11711212 Token.Id.ArrayBegin => {
1172 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });
1213 try p.stack.append(Value{ .Array = ArrayList(Value).init(allocator) });
11731214 p.state = State.ArrayValue;
11741215 },
11751216 Token.Id.String => {
......@@ -1179,10 +1220,10 @@ const JsonParser = struct {
11791220 try array.append(try p.parseNumber(token, input, i));
11801221 },
11811222 Token.Id.True => {
1182 try array.append(Value { .Bool = true });
1223 try array.append(Value{ .Bool = true });
11831224 },
11841225 Token.Id.False => {
1185 try array.append(Value { .Bool = false });
1226 try array.append(Value{ .Bool = false });
11861227 },
11871228 Token.Id.Null => {
11881229 try array.append(Value.Null);
......@@ -1194,11 +1235,11 @@ const JsonParser = struct {
11941235 },
11951236 State.Simple => switch (token.id) {
11961237 Token.Id.ObjectBegin => {
1197 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });
1238 try p.stack.append(Value{ .Object = ObjectMap.init(allocator) });
11981239 p.state = State.ObjectKey;
11991240 },
12001241 Token.Id.ArrayBegin => {
1201 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });
1242 try p.stack.append(Value{ .Array = ArrayList(Value).init(allocator) });
12021243 p.state = State.ArrayValue;
12031244 },
12041245 Token.Id.String => {
......@@ -1208,15 +1249,16 @@ const JsonParser = struct {
12081249 try p.stack.append(try p.parseNumber(token, input, i));
12091250 },
12101251 Token.Id.True => {
1211 try p.stack.append(Value { .Bool = true });
1252 try p.stack.append(Value{ .Bool = true });
12121253 },
12131254 Token.Id.False => {
1214 try p.stack.append(Value { .Bool = false });
1255 try p.stack.append(Value{ .Bool = false });
12151256 },
12161257 Token.Id.Null => {
12171258 try p.stack.append(Value.Null);
12181259 },
1219 Token.Id.ObjectEnd, Token.Id.ArrayEnd => {
1260 Token.Id.ObjectEnd,
1261 Token.Id.ArrayEnd => {
12201262 unreachable;
12211263 },
12221264 },
......@@ -1248,15 +1290,14 @@ const JsonParser = struct {
12481290 // TODO: We don't strictly have to copy values which do not contain any escape
12491291 // characters if flagged with the option.
12501292 const slice = token.slice(input, i);
1251 return Value { .String = try mem.dupe(p.allocator, u8, slice) };
1293 return Value{ .String = try mem.dupe(p.allocator, u8, slice) };
12521294 }
12531295
12541296 fn parseNumber(p: &JsonParser, token: &const Token, input: []const u8, i: usize) !Value {
12551297 return if (token.number_is_integer)
1256 Value { .Integer = try std.fmt.parseInt(i64, token.slice(input, i), 10) }
1298 Value{ .Integer = try std.fmt.parseInt(i64, token.slice(input, i), 10) }
12571299 else
1258 @panic("TODO: fmt.parseFloat not yet implemented")
1259 ;
1300 @panic("TODO: fmt.parseFloat not yet implemented");
12601301 }
12611302};
12621303
......@@ -1267,21 +1308,21 @@ test "json parser dynamic" {
12671308 defer p.deinit();
12681309
12691310 const s =
1270 \\{
1271 \\ "Image": {
1272 \\ "Width": 800,
1273 \\ "Height": 600,
1274 \\ "Title": "View from 15th Floor",
1275 \\ "Thumbnail": {
1276 \\ "Url": "http://www.example.com/image/481989943",
1277 \\ "Height": 125,
1278 \\ "Width": 100
1279 \\ },
1280 \\ "Animated" : false,
1281 \\ "IDs": [116, 943, 234, 38793]
1282 \\ }
1283 \\}
1284 ;
1311 \\{
1312 \\ "Image": {
1313 \\ "Width": 800,
1314 \\ "Height": 600,
1315 \\ "Title": "View from 15th Floor",
1316 \\ "Thumbnail": {
1317 \\ "Url": "http://www.example.com/image/481989943",
1318 \\ "Height": 125,
1319 \\ "Width": 100
1320 \\ },
1321 \\ "Animated" : false,
1322 \\ "IDs": [116, 943, 234, 38793]
1323 \\ }
1324 \\}
1325 ;
12851326
12861327 var tree = try p.parse(s);
12871328 defer tree.deinit();
std/math/acos.zig+7-7
......@@ -16,7 +16,7 @@ pub fn acos(x: var) @typeOf(x) {
1616}
1717
1818fn r32(z: f32) f32 {
19 const pS0 = 1.6666586697e-01;
19 const pS0 = 1.6666586697e-01;
2020 const pS1 = -4.2743422091e-02;
2121 const pS2 = -8.6563630030e-03;
2222 const qS1 = -7.0662963390e-01;
......@@ -74,16 +74,16 @@ fn acos32(x: f32) f32 {
7474}
7575
7676fn r64(z: f64) f64 {
77 const pS0: f64 = 1.66666666666666657415e-01;
77 const pS0: f64 = 1.66666666666666657415e-01;
7878 const pS1: f64 = -3.25565818622400915405e-01;
79 const pS2: f64 = 2.01212532134862925881e-01;
79 const pS2: f64 = 2.01212532134862925881e-01;
8080 const pS3: f64 = -4.00555345006794114027e-02;
81 const pS4: f64 = 7.91534994289814532176e-04;
82 const pS5: f64 = 3.47933107596021167570e-05;
81 const pS4: f64 = 7.91534994289814532176e-04;
82 const pS5: f64 = 3.47933107596021167570e-05;
8383 const qS1: f64 = -2.40339491173441421878e+00;
84 const qS2: f64 = 2.02094576023350569471e+00;
84 const qS2: f64 = 2.02094576023350569471e+00;
8585 const qS3: f64 = -6.88283971605453293030e-01;
86 const qS4: f64 = 7.70381505559019352791e-02;
86 const qS4: f64 = 7.70381505559019352791e-02;
8787
8888 const p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
8989 const q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
std/math/asin.zig+9-9
......@@ -17,7 +17,7 @@ pub fn asin(x: var) @typeOf(x) {
1717}
1818
1919fn r32(z: f32) f32 {
20 const pS0 = 1.6666586697e-01;
20 const pS0 = 1.6666586697e-01;
2121 const pS1 = -4.2743422091e-02;
2222 const pS2 = -8.6563630030e-03;
2323 const qS1 = -7.0662963390e-01;
......@@ -37,9 +37,9 @@ fn asin32(x: f32) f32 {
3737 if (ix >= 0x3F800000) {
3838 // |x| >= 1
3939 if (ix == 0x3F800000) {
40 return x * pio2 + 0x1.0p-120; // asin(+-1) = +-pi/2 with inexact
40 return x * pio2 + 0x1.0p-120; // asin(+-1) = +-pi/2 with inexact
4141 } else {
42 return math.nan(f32); // asin(|x| > 1) is nan
42 return math.nan(f32); // asin(|x| > 1) is nan
4343 }
4444 }
4545
......@@ -66,16 +66,16 @@ fn asin32(x: f32) f32 {
6666}
6767
6868fn r64(z: f64) f64 {
69 const pS0: f64 = 1.66666666666666657415e-01;
69 const pS0: f64 = 1.66666666666666657415e-01;
7070 const pS1: f64 = -3.25565818622400915405e-01;
71 const pS2: f64 = 2.01212532134862925881e-01;
71 const pS2: f64 = 2.01212532134862925881e-01;
7272 const pS3: f64 = -4.00555345006794114027e-02;
73 const pS4: f64 = 7.91534994289814532176e-04;
74 const pS5: f64 = 3.47933107596021167570e-05;
73 const pS4: f64 = 7.91534994289814532176e-04;
74 const pS5: f64 = 3.47933107596021167570e-05;
7575 const qS1: f64 = -2.40339491173441421878e+00;
76 const qS2: f64 = 2.02094576023350569471e+00;
76 const qS2: f64 = 2.02094576023350569471e+00;
7777 const qS3: f64 = -6.88283971605453293030e-01;
78 const qS4: f64 = 7.70381505559019352791e-02;
78 const qS4: f64 = 7.70381505559019352791e-02;
7979
8080 const p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));
8181 const q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));
std/math/atan2.zig+34-32
......@@ -31,7 +31,7 @@ pub fn atan2(comptime T: type, x: T, y: T) T {
3131}
3232
3333fn atan2_32(y: f32, x: f32) f32 {
34 const pi: f32 = 3.1415927410e+00;
34 const pi: f32 = 3.1415927410e+00;
3535 const pi_lo: f32 = -8.7422776573e-08;
3636
3737 if (math.isNan(x) or math.isNan(y)) {
......@@ -53,9 +53,10 @@ fn atan2_32(y: f32, x: f32) f32 {
5353
5454 if (iy == 0) {
5555 switch (m) {
56 0, 1 => return y, // atan(+-0, +...)
57 2 => return pi, // atan(+0, -...)
58 3 => return -pi, // atan(-0, -...)
56 0,
57 1 => return y, // atan(+-0, +...)
58 2 => return pi, // atan(+0, -...)
59 3 => return -pi, // atan(-0, -...)
5960 else => unreachable,
6061 }
6162 }
......@@ -71,18 +72,18 @@ fn atan2_32(y: f32, x: f32) f32 {
7172 if (ix == 0x7F800000) {
7273 if (iy == 0x7F800000) {
7374 switch (m) {
74 0 => return pi / 4, // atan(+inf, +inf)
75 1 => return -pi / 4, // atan(-inf, +inf)
76 2 => return 3*pi / 4, // atan(+inf, -inf)
77 3 => return -3*pi / 4, // atan(-inf, -inf)
75 0 => return pi / 4, // atan(+inf, +inf)
76 1 => return -pi / 4, // atan(-inf, +inf)
77 2 => return 3 * pi / 4, // atan(+inf, -inf)
78 3 => return -3 * pi / 4, // atan(-inf, -inf)
7879 else => unreachable,
7980 }
8081 } else {
8182 switch (m) {
82 0 => return 0.0, // atan(+..., +inf)
83 1 => return -0.0, // atan(-..., +inf)
84 2 => return pi, // atan(+..., -inf)
85 3 => return -pi, // atan(-...f, -inf)
83 0 => return 0.0, // atan(+..., +inf)
84 1 => return -0.0, // atan(-..., +inf)
85 2 => return pi, // atan(+..., -inf)
86 3 => return -pi, // atan(-...f, -inf)
8687 else => unreachable,
8788 }
8889 }
......@@ -107,16 +108,16 @@ fn atan2_32(y: f32, x: f32) f32 {
107108 };
108109
109110 switch (m) {
110 0 => return z, // atan(+, +)
111 1 => return -z, // atan(-, +)
112 2 => return pi - (z - pi_lo), // atan(+, -)
113 3 => return (z - pi_lo) - pi, // atan(-, -)
111 0 => return z, // atan(+, +)
112 1 => return -z, // atan(-, +)
113 2 => return pi - (z - pi_lo), // atan(+, -)
114 3 => return (z - pi_lo) - pi, // atan(-, -)
114115 else => unreachable,
115116 }
116117}
117118
118119fn atan2_64(y: f64, x: f64) f64 {
119 const pi: f64 = 3.1415926535897931160E+00;
120 const pi: f64 = 3.1415926535897931160E+00;
120121 const pi_lo: f64 = 1.2246467991473531772E-16;
121122
122123 if (math.isNan(x) or math.isNan(y)) {
......@@ -143,9 +144,10 @@ fn atan2_64(y: f64, x: f64) f64 {
143144
144145 if (iy | ly == 0) {
145146 switch (m) {
146 0, 1 => return y, // atan(+-0, +...)
147 2 => return pi, // atan(+0, -...)
148 3 => return -pi, // atan(-0, -...)
147 0,
148 1 => return y, // atan(+-0, +...)
149 2 => return pi, // atan(+0, -...)
150 3 => return -pi, // atan(-0, -...)
149151 else => unreachable,
150152 }
151153 }
......@@ -161,18 +163,18 @@ fn atan2_64(y: f64, x: f64) f64 {
161163 if (ix == 0x7FF00000) {
162164 if (iy == 0x7FF00000) {
163165 switch (m) {
164 0 => return pi / 4, // atan(+inf, +inf)
165 1 => return -pi / 4, // atan(-inf, +inf)
166 2 => return 3*pi / 4, // atan(+inf, -inf)
167 3 => return -3*pi / 4, // atan(-inf, -inf)
166 0 => return pi / 4, // atan(+inf, +inf)
167 1 => return -pi / 4, // atan(-inf, +inf)
168 2 => return 3 * pi / 4, // atan(+inf, -inf)
169 3 => return -3 * pi / 4, // atan(-inf, -inf)
168170 else => unreachable,
169171 }
170172 } else {
171173 switch (m) {
172 0 => return 0.0, // atan(+..., +inf)
173 1 => return -0.0, // atan(-..., +inf)
174 2 => return pi, // atan(+..., -inf)
175 3 => return -pi, // atan(-...f, -inf)
174 0 => return 0.0, // atan(+..., +inf)
175 1 => return -0.0, // atan(-..., +inf)
176 2 => return pi, // atan(+..., -inf)
177 3 => return -pi, // atan(-...f, -inf)
176178 else => unreachable,
177179 }
178180 }
......@@ -197,10 +199,10 @@ fn atan2_64(y: f64, x: f64) f64 {
197199 };
198200
199201 switch (m) {
200 0 => return z, // atan(+, +)
201 1 => return -z, // atan(-, +)
202 2 => return pi - (z - pi_lo), // atan(+, -)
203 3 => return (z - pi_lo) - pi, // atan(-, -)
202 0 => return z, // atan(+, +)
203 1 => return -z, // atan(-, +)
204 2 => return pi - (z - pi_lo), // atan(+, -)
205 3 => return (z - pi_lo) - pi, // atan(-, -)
204206 else => unreachable,
205207 }
206208}
std/math/cbrt.zig+5-5
......@@ -58,15 +58,15 @@ fn cbrt32(x: f32) f32 {
5858}
5959
6060fn cbrt64(x: f64) f64 {
61 const B1: u32 = 715094163; // (1023 - 1023 / 3 - 0.03306235651 * 2^20
62 const B2: u32 = 696219795; // (1023 - 1023 / 3 - 54 / 3 - 0.03306235651 * 2^20
61 const B1: u32 = 715094163; // (1023 - 1023 / 3 - 0.03306235651 * 2^20
62 const B2: u32 = 696219795; // (1023 - 1023 / 3 - 54 / 3 - 0.03306235651 * 2^20
6363
6464 // |1 / cbrt(x) - p(x)| < 2^(23.5)
65 const P0: f64 = 1.87595182427177009643;
65 const P0: f64 = 1.87595182427177009643;
6666 const P1: f64 = -1.88497979543377169875;
67 const P2: f64 = 1.621429720105354466140;
67 const P2: f64 = 1.621429720105354466140;
6868 const P3: f64 = -0.758397934778766047437;
69 const P4: f64 = 0.145996192886612446982;
69 const P4: f64 = 0.145996192886612446982;
7070
7171 var u = @bitCast(u64, x);
7272 var hx = u32(u >> 32) & 0x7FFFFFFF;
std/math/ceil.zig+2-2
......@@ -56,7 +56,7 @@ fn ceil64(x: f64) f64 {
5656 const e = (u >> 52) & 0x7FF;
5757 var y: f64 = undefined;
5858
59 if (e >= 0x3FF+52 or x == 0) {
59 if (e >= 0x3FF + 52 or x == 0) {
6060 return x;
6161 }
6262
......@@ -68,7 +68,7 @@ fn ceil64(x: f64) f64 {
6868 y = x + math.f64_toint - math.f64_toint - x;
6969 }
7070
71 if (e <= 0x3FF-1) {
71 if (e <= 0x3FF - 1) {
7272 math.forceEval(y);
7373 if (u >> 63 != 0) {
7474 return -0.0;
std/math/cos.zig+6-6
......@@ -18,20 +18,20 @@ pub fn cos(x: var) @typeOf(x) {
1818}
1919
2020// sin polynomial coefficients
21const S0 = 1.58962301576546568060E-10;
21const S0 = 1.58962301576546568060E-10;
2222const S1 = -2.50507477628578072866E-8;
23const S2 = 2.75573136213857245213E-6;
23const S2 = 2.75573136213857245213E-6;
2424const S3 = -1.98412698295895385996E-4;
25const S4 = 8.33333333332211858878E-3;
25const S4 = 8.33333333332211858878E-3;
2626const S5 = -1.66666666666666307295E-1;
2727
2828// cos polynomial coeffiecients
2929const C0 = -1.13585365213876817300E-11;
30const C1 = 2.08757008419747316778E-9;
30const C1 = 2.08757008419747316778E-9;
3131const C2 = -2.75573141792967388112E-7;
32const C3 = 2.48015872888517045348E-5;
32const C3 = 2.48015872888517045348E-5;
3333const C4 = -1.38888888888730564116E-3;
34const C5 = 4.16666666666665929218E-2;
34const C5 = 4.16666666666665929218E-2;
3535
3636// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
3737//
std/math/floor.zig+2-2
......@@ -57,7 +57,7 @@ fn floor64(x: f64) f64 {
5757 const e = (u >> 52) & 0x7FF;
5858 var y: f64 = undefined;
5959
60 if (e >= 0x3FF+52 or x == 0) {
60 if (e >= 0x3FF + 52 or x == 0) {
6161 return x;
6262 }
6363
......@@ -69,7 +69,7 @@ fn floor64(x: f64) f64 {
6969 y = x + math.f64_toint - math.f64_toint - x;
7070 }
7171
72 if (e <= 0x3FF-1) {
72 if (e <= 0x3FF - 1) {
7373 math.forceEval(y);
7474 if (u >> 63 != 0) {
7575 return -1.0;
std/math/fma.zig+5-2
......@@ -5,7 +5,7 @@ const assert = std.debug.assert;
55pub fn fma(comptime T: type, x: T, y: T, z: T) T {
66 return switch (T) {
77 f32 => fma32(x, y, z),
8 f64 => fma64(x, y ,z),
8 f64 => fma64(x, y, z),
99 else => @compileError("fma not implemented for " ++ @typeName(T)),
1010 };
1111}
......@@ -71,7 +71,10 @@ fn fma64(x: f64, y: f64, z: f64) f64 {
7171 }
7272}
7373
74const dd = struct { hi: f64, lo: f64, };
74const dd = struct {
75 hi: f64,
76 lo: f64,
77};
7578
7679fn dd_add(a: f64, b: f64) dd {
7780 var ret: dd = undefined;
std/math/hypot.zig+4-4
......@@ -39,11 +39,11 @@ fn hypot32(x: f32, y: f32) f32 {
3939 }
4040
4141 var z: f32 = 1.0;
42 if (ux >= (0x7F+60) << 23) {
42 if (ux >= (0x7F + 60) << 23) {
4343 z = 0x1.0p90;
4444 xx *= 0x1.0p-90;
4545 yy *= 0x1.0p-90;
46 } else if (uy < (0x7F-60) << 23) {
46 } else if (uy < (0x7F - 60) << 23) {
4747 z = 0x1.0p-90;
4848 xx *= 0x1.0p-90;
4949 yy *= 0x1.0p-90;
......@@ -57,8 +57,8 @@ fn sq(hi: &f64, lo: &f64, x: f64) void {
5757 const xc = x * split;
5858 const xh = x - xc + xc;
5959 const xl = x - xh;
60 *hi = x * x;
61 *lo = xh * xh - *hi + 2 * xh * xl + xl * xl;
60 hi.* = x * x;
61 lo.* = xh * xh - hi.* + 2 * xh * xl + xl * xl;
6262}
6363
6464fn hypot64(x: f64, y: f64) f64 {
std/math/ln.zig+2-4
......@@ -120,11 +120,9 @@ pub fn ln_64(x_: f64) f64 {
120120 k -= 54;
121121 x *= 0x1.0p54;
122122 hx = u32(@bitCast(u64, ix) >> 32);
123 }
124 else if (hx >= 0x7FF00000) {
123 } else if (hx >= 0x7FF00000) {
125124 return x;
126 }
127 else if (hx == 0x3FF00000 and ix << 32 == 0) {
125 } else if (hx == 0x3FF00000 and ix << 32 == 0) {
128126 return 0;
129127 }
130128
std/math/log10.zig+8-10
......@@ -35,10 +35,10 @@ pub fn log10(x: var) @typeOf(x) {
3535}
3636
3737pub fn log10_32(x_: f32) f32 {
38 const ivln10hi: f32 = 4.3432617188e-01;
39 const ivln10lo: f32 = -3.1689971365e-05;
40 const log10_2hi: f32 = 3.0102920532e-01;
41 const log10_2lo: f32 = 7.9034151668e-07;
38 const ivln10hi: f32 = 4.3432617188e-01;
39 const ivln10lo: f32 = -3.1689971365e-05;
40 const log10_2hi: f32 = 3.0102920532e-01;
41 const log10_2lo: f32 = 7.9034151668e-07;
4242 const Lg1: f32 = 0xaaaaaa.0p-24;
4343 const Lg2: f32 = 0xccce13.0p-25;
4444 const Lg3: f32 = 0x91e9ee.0p-25;
......@@ -95,8 +95,8 @@ pub fn log10_32(x_: f32) f32 {
9595}
9696
9797pub fn log10_64(x_: f64) f64 {
98 const ivln10hi: f64 = 4.34294481878168880939e-01;
99 const ivln10lo: f64 = 2.50829467116452752298e-11;
98 const ivln10hi: f64 = 4.34294481878168880939e-01;
99 const ivln10lo: f64 = 2.50829467116452752298e-11;
100100 const log10_2hi: f64 = 3.01029995663611771306e-01;
101101 const log10_2lo: f64 = 3.69423907715893078616e-13;
102102 const Lg1: f64 = 6.666666666666735130e-01;
......@@ -126,11 +126,9 @@ pub fn log10_64(x_: f64) f64 {
126126 k -= 54;
127127 x *= 0x1.0p54;
128128 hx = u32(@bitCast(u64, x) >> 32);
129 }
130 else if (hx >= 0x7FF00000) {
129 } else if (hx >= 0x7FF00000) {
131130 return x;
132 }
133 else if (hx == 0x3FF00000 and ix << 32 == 0) {
131 } else if (hx == 0x3FF00000 and ix << 32 == 0) {
134132 return 0;
135133 }
136134
std/math/log2.zig+5-2
......@@ -27,7 +27,10 @@ pub fn log2(x: var) @typeOf(x) {
2727 TypeId.IntLiteral => comptime {
2828 var result = 0;
2929 var x_shifted = x;
30 while (b: {x_shifted >>= 1; break :b x_shifted != 0;}) : (result += 1) {}
30 while (b: {
31 x_shifted >>= 1;
32 break :b x_shifted != 0;
33 }) : (result += 1) {}
3134 return result;
3235 },
3336 TypeId.Int => {
......@@ -38,7 +41,7 @@ pub fn log2(x: var) @typeOf(x) {
3841}
3942
4043pub fn log2_32(x_: f32) f32 {
41 const ivln2hi: f32 = 1.4428710938e+00;
44 const ivln2hi: f32 = 1.4428710938e+00;
4245 const ivln2lo: f32 = -1.7605285393e-04;
4346 const Lg1: f32 = 0xaaaaaa.0p-24;
4447 const Lg2: f32 = 0xccce13.0p-25;
std/math/round.zig+4-4
......@@ -24,13 +24,13 @@ fn round32(x_: f32) f32 {
2424 const e = (u >> 23) & 0xFF;
2525 var y: f32 = undefined;
2626
27 if (e >= 0x7F+23) {
27 if (e >= 0x7F + 23) {
2828 return x;
2929 }
3030 if (u >> 31 != 0) {
3131 x = -x;
3232 }
33 if (e < 0x7F-1) {
33 if (e < 0x7F - 1) {
3434 math.forceEval(x + math.f32_toint);
3535 return 0 * @bitCast(f32, u);
3636 }
......@@ -61,13 +61,13 @@ fn round64(x_: f64) f64 {
6161 const e = (u >> 52) & 0x7FF;
6262 var y: f64 = undefined;
6363
64 if (e >= 0x3FF+52) {
64 if (e >= 0x3FF + 52) {
6565 return x;
6666 }
6767 if (u >> 63 != 0) {
6868 x = -x;
6969 }
70 if (e < 0x3ff-1) {
70 if (e < 0x3ff - 1) {
7171 math.forceEval(x + math.f64_toint);
7272 return 0 * @bitCast(f64, u);
7373 }
std/math/sin.zig+6-6
......@@ -19,20 +19,20 @@ pub fn sin(x: var) @typeOf(x) {
1919}
2020
2121// sin polynomial coefficients
22const S0 = 1.58962301576546568060E-10;
22const S0 = 1.58962301576546568060E-10;
2323const S1 = -2.50507477628578072866E-8;
24const S2 = 2.75573136213857245213E-6;
24const S2 = 2.75573136213857245213E-6;
2525const S3 = -1.98412698295895385996E-4;
26const S4 = 8.33333333332211858878E-3;
26const S4 = 8.33333333332211858878E-3;
2727const S5 = -1.66666666666666307295E-1;
2828
2929// cos polynomial coeffiecients
3030const C0 = -1.13585365213876817300E-11;
31const C1 = 2.08757008419747316778E-9;
31const C1 = 2.08757008419747316778E-9;
3232const C2 = -2.75573141792967388112E-7;
33const C3 = 2.48015872888517045348E-5;
33const C3 = 2.48015872888517045348E-5;
3434const C4 = -1.38888888888730564116E-3;
35const C5 = 4.16666666666665929218E-2;
35const C5 = 4.16666666666665929218E-2;
3636
3737// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
3838//
std/math/tan.zig+3-3
......@@ -19,12 +19,12 @@ pub fn tan(x: var) @typeOf(x) {
1919}
2020
2121const Tp0 = -1.30936939181383777646E4;
22const Tp1 = 1.15351664838587416140E6;
22const Tp1 = 1.15351664838587416140E6;
2323const Tp2 = -1.79565251976484877988E7;
2424
25const Tq1 = 1.36812963470692954678E4;
25const Tq1 = 1.36812963470692954678E4;
2626const Tq2 = -1.32089234440210967447E6;
27const Tq3 = 2.50083801823357915839E7;
27const Tq3 = 2.50083801823357915839E7;
2828const Tq4 = -5.38695755929454629881E7;
2929
3030// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
std/net.zig+16-24
......@@ -19,37 +19,29 @@ pub const Address = struct {
1919 os_addr: OsAddress,
2020
2121 pub fn initIp4(ip4: u32, port: u16) Address {
22 return Address {
23 .os_addr = posix.sockaddr {
24 .in = posix.sockaddr_in {
25 .family = posix.AF_INET,
26 .port = std.mem.endianSwapIfLe(u16, port),
27 .addr = ip4,
28 .zero = []u8{0} ** 8,
29 },
30 },
31 };
22 return Address{ .os_addr = posix.sockaddr{ .in = posix.sockaddr_in{
23 .family = posix.AF_INET,
24 .port = std.mem.endianSwapIfLe(u16, port),
25 .addr = ip4,
26 .zero = []u8{0} ** 8,
27 } } };
3228 }
3329
3430 pub fn initIp6(ip6: &const Ip6Addr, port: u16) Address {
35 return Address {
31 return Address{
3632 .family = posix.AF_INET6,
37 .os_addr = posix.sockaddr {
38 .in6 = posix.sockaddr_in6 {
39 .family = posix.AF_INET6,
40 .port = std.mem.endianSwapIfLe(u16, port),
41 .flowinfo = 0,
42 .addr = ip6.addr,
43 .scope_id = ip6.scope_id,
44 },
45 },
33 .os_addr = posix.sockaddr{ .in6 = posix.sockaddr_in6{
34 .family = posix.AF_INET6,
35 .port = std.mem.endianSwapIfLe(u16, port),
36 .flowinfo = 0,
37 .addr = ip6.addr,
38 .scope_id = ip6.scope_id,
39 } },
4640 };
4741 }
4842
4943 pub fn initPosix(addr: &const posix.sockaddr) Address {
50 return Address {
51 .os_addr = *addr,
52 };
44 return Address{ .os_addr = addr.* };
5345 }
5446
5547 pub fn format(self: &const Address, out_stream: var) !void {
......@@ -98,7 +90,7 @@ pub fn parseIp4(buf: []const u8) !u32 {
9890 }
9991 } else {
10092 return error.InvalidCharacter;
101 }
93 }
10294 }
10395 if (index == 3 and saw_any_digits) {
10496 out_ptr[index] = x;
std/os/child_process.zig+101-91
......@@ -49,7 +49,7 @@ pub const ChildProcess = struct {
4949 err_pipe: if (is_windows) void else [2]i32,
5050 llnode: if (is_windows) void else LinkedList(&ChildProcess).Node,
5151
52 pub const SpawnError = error {
52 pub const SpawnError = error{
5353 ProcessFdQuotaExceeded,
5454 Unexpected,
5555 NotDir,
......@@ -88,7 +88,7 @@ pub const ChildProcess = struct {
8888 const child = try allocator.create(ChildProcess);
8989 errdefer allocator.destroy(child);
9090
91 *child = ChildProcess {
91 child.* = ChildProcess{
9292 .allocator = allocator,
9393 .argv = argv,
9494 .pid = undefined,
......@@ -99,8 +99,10 @@ pub const ChildProcess = struct {
9999 .term = null,
100100 .env_map = null,
101101 .cwd = null,
102 .uid = if (is_windows) {} else null,
103 .gid = if (is_windows) {} else null,
102 .uid = if (is_windows) {} else
103 null,
104 .gid = if (is_windows) {} else
105 null,
104106 .stdin = null,
105107 .stdout = null,
106108 .stderr = null,
......@@ -193,9 +195,7 @@ pub const ChildProcess = struct {
193195
194196 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
195197 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
196 pub fn exec(allocator: &mem.Allocator, argv: []const []const u8, cwd: ?[]const u8,
197 env_map: ?&const BufMap, max_output_size: usize) !ExecResult
198 {
198 pub fn exec(allocator: &mem.Allocator, argv: []const []const u8, cwd: ?[]const u8, env_map: ?&const BufMap, max_output_size: usize) !ExecResult {
199199 const child = try ChildProcess.init(argv, allocator);
200200 defer child.deinit();
201201
......@@ -218,7 +218,7 @@ pub const ChildProcess = struct {
218218 try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size);
219219 try stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size);
220220
221 return ExecResult {
221 return ExecResult{
222222 .term = try child.wait(),
223223 .stdout = stdout.toOwnedSlice(),
224224 .stderr = stderr.toOwnedSlice(),
......@@ -255,9 +255,9 @@ pub const ChildProcess = struct {
255255 self.term = (SpawnError!Term)(x: {
256256 var exit_code: windows.DWORD = undefined;
257257 if (windows.GetExitCodeProcess(self.handle, &exit_code) == 0) {
258 break :x Term { .Unknown = 0 };
258 break :x Term{ .Unknown = 0 };
259259 } else {
260 break :x Term { .Exited = @bitCast(i32, exit_code)};
260 break :x Term{ .Exited = @bitCast(i32, exit_code) };
261261 }
262262 });
263263
......@@ -288,9 +288,18 @@ pub const ChildProcess = struct {
288288 }
289289
290290 fn cleanupStreams(self: &ChildProcess) void {
291 if (self.stdin) |*stdin| { stdin.close(); self.stdin = null; }
292 if (self.stdout) |*stdout| { stdout.close(); self.stdout = null; }
293 if (self.stderr) |*stderr| { stderr.close(); self.stderr = null; }
291 if (self.stdin) |*stdin| {
292 stdin.close();
293 self.stdin = null;
294 }
295 if (self.stdout) |*stdout| {
296 stdout.close();
297 self.stdout = null;
298 }
299 if (self.stderr) |*stderr| {
300 stderr.close();
301 self.stderr = null;
302 }
294303 }
295304
296305 fn cleanupAfterWait(self: &ChildProcess, status: i32) !Term {
......@@ -317,25 +326,30 @@ pub const ChildProcess = struct {
317326
318327 fn statusToTerm(status: i32) Term {
319328 return if (posix.WIFEXITED(status))
320 Term { .Exited = posix.WEXITSTATUS(status) }
329 Term{ .Exited = posix.WEXITSTATUS(status) }
321330 else if (posix.WIFSIGNALED(status))
322 Term { .Signal = posix.WTERMSIG(status) }
331 Term{ .Signal = posix.WTERMSIG(status) }
323332 else if (posix.WIFSTOPPED(status))
324 Term { .Stopped = posix.WSTOPSIG(status) }
333 Term{ .Stopped = posix.WSTOPSIG(status) }
325334 else
326 Term { .Unknown = status }
327 ;
335 Term{ .Unknown = status };
328336 }
329337
330338 fn spawnPosix(self: &ChildProcess) !void {
331339 const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined;
332 errdefer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); };
340 errdefer if (self.stdin_behavior == StdIo.Pipe) {
341 destroyPipe(stdin_pipe);
342 };
333343
334344 const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try makePipe() else undefined;
335 errdefer if (self.stdout_behavior == StdIo.Pipe) { destroyPipe(stdout_pipe); };
345 errdefer if (self.stdout_behavior == StdIo.Pipe) {
346 destroyPipe(stdout_pipe);
347 };
336348
337349 const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try makePipe() else undefined;
338 errdefer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); };
350 errdefer if (self.stderr_behavior == StdIo.Pipe) {
351 destroyPipe(stderr_pipe);
352 };
339353
340354 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
341355 const dev_null_fd = if (any_ignore) blk: {
......@@ -346,7 +360,9 @@ pub const ChildProcess = struct {
346360 } else blk: {
347361 break :blk undefined;
348362 };
349 defer { if (any_ignore) os.close(dev_null_fd); }
363 defer {
364 if (any_ignore) os.close(dev_null_fd);
365 }
350366
351367 var env_map_owned: BufMap = undefined;
352368 var we_own_env_map: bool = undefined;
......@@ -358,7 +374,9 @@ pub const ChildProcess = struct {
358374 env_map_owned = try os.getEnvMap(self.allocator);
359375 break :x &env_map_owned;
360376 };
361 defer { if (we_own_env_map) env_map_owned.deinit(); }
377 defer {
378 if (we_own_env_map) env_map_owned.deinit();
379 }
362380
363381 // This pipe is used to communicate errors between the time of fork
364382 // and execve from the child process to the parent process.
......@@ -369,23 +387,21 @@ pub const ChildProcess = struct {
369387 const pid_err = posix.getErrno(pid_result);
370388 if (pid_err > 0) {
371389 return switch (pid_err) {
372 posix.EAGAIN, posix.ENOMEM, posix.ENOSYS => error.SystemResources,
390 posix.EAGAIN,
391 posix.ENOMEM,
392 posix.ENOSYS => error.SystemResources,
373393 else => os.unexpectedErrorPosix(pid_err),
374394 };
375395 }
376396 if (pid_result == 0) {
377397 // we are the child
378398
379 setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch
380 |err| forkChildErrReport(err_pipe[1], err);
381 setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch
382 |err| forkChildErrReport(err_pipe[1], err);
383 setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch
384 |err| forkChildErrReport(err_pipe[1], err);
399 setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
400 setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
401 setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
385402
386403 if (self.cwd) |cwd| {
387 os.changeCurDir(self.allocator, cwd) catch
388 |err| forkChildErrReport(err_pipe[1], err);
404 os.changeCurDir(self.allocator, cwd) catch |err| forkChildErrReport(err_pipe[1], err);
389405 }
390406
391407 if (self.gid) |gid| {
......@@ -396,8 +412,7 @@ pub const ChildProcess = struct {
396412 os.posix_setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
397413 }
398414
399 os.posixExecve(self.argv, env_map, self.allocator) catch
400 |err| forkChildErrReport(err_pipe[1], err);
415 os.posixExecve(self.argv, env_map, self.allocator) catch |err| forkChildErrReport(err_pipe[1], err);
401416 }
402417
403418 // we are the parent
......@@ -423,37 +438,41 @@ pub const ChildProcess = struct {
423438 self.llnode = LinkedList(&ChildProcess).Node.init(self);
424439 self.term = null;
425440
426 if (self.stdin_behavior == StdIo.Pipe) { os.close(stdin_pipe[0]); }
427 if (self.stdout_behavior == StdIo.Pipe) { os.close(stdout_pipe[1]); }
428 if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); }
441 if (self.stdin_behavior == StdIo.Pipe) {
442 os.close(stdin_pipe[0]);
443 }
444 if (self.stdout_behavior == StdIo.Pipe) {
445 os.close(stdout_pipe[1]);
446 }
447 if (self.stderr_behavior == StdIo.Pipe) {
448 os.close(stderr_pipe[1]);
449 }
429450 }
430451
431452 fn spawnWindows(self: &ChildProcess) !void {
432 const saAttr = windows.SECURITY_ATTRIBUTES {
453 const saAttr = windows.SECURITY_ATTRIBUTES{
433454 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
434455 .bInheritHandle = windows.TRUE,
435456 .lpSecurityDescriptor = null,
436457 };
437458
438 const any_ignore = (self.stdin_behavior == StdIo.Ignore or
439 self.stdout_behavior == StdIo.Ignore or
440 self.stderr_behavior == StdIo.Ignore);
459 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
441460
442461 const nul_handle = if (any_ignore) blk: {
443462 const nul_file_path = "NUL";
444463 var fixed_buffer_mem: [nul_file_path.len + 1]u8 = undefined;
445464 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
446 break :blk try os.windowsOpen(&fixed_allocator.allocator, "NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ,
447 windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL);
465 break :blk try os.windowsOpen(&fixed_allocator.allocator, "NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL);
448466 } else blk: {
449467 break :blk undefined;
450468 };
451 defer { if (any_ignore) os.close(nul_handle); }
469 defer {
470 if (any_ignore) os.close(nul_handle);
471 }
452472 if (any_ignore) {
453473 try windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0);
454474 }
455475
456
457476 var g_hChildStd_IN_Rd: ?windows.HANDLE = null;
458477 var g_hChildStd_IN_Wr: ?windows.HANDLE = null;
459478 switch (self.stdin_behavior) {
......@@ -470,7 +489,9 @@ pub const ChildProcess = struct {
470489 g_hChildStd_IN_Rd = null;
471490 },
472491 }
473 errdefer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_IN_Rd, g_hChildStd_IN_Wr); };
492 errdefer if (self.stdin_behavior == StdIo.Pipe) {
493 windowsDestroyPipe(g_hChildStd_IN_Rd, g_hChildStd_IN_Wr);
494 };
474495
475496 var g_hChildStd_OUT_Rd: ?windows.HANDLE = null;
476497 var g_hChildStd_OUT_Wr: ?windows.HANDLE = null;
......@@ -488,7 +509,9 @@ pub const ChildProcess = struct {
488509 g_hChildStd_OUT_Wr = null;
489510 },
490511 }
491 errdefer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_OUT_Rd, g_hChildStd_OUT_Wr); };
512 errdefer if (self.stdin_behavior == StdIo.Pipe) {
513 windowsDestroyPipe(g_hChildStd_OUT_Rd, g_hChildStd_OUT_Wr);
514 };
492515
493516 var g_hChildStd_ERR_Rd: ?windows.HANDLE = null;
494517 var g_hChildStd_ERR_Wr: ?windows.HANDLE = null;
......@@ -506,12 +529,14 @@ pub const ChildProcess = struct {
506529 g_hChildStd_ERR_Wr = null;
507530 },
508531 }
509 errdefer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr); };
532 errdefer if (self.stdin_behavior == StdIo.Pipe) {
533 windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr);
534 };
510535
511536 const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv);
512537 defer self.allocator.free(cmd_line);
513538
514 var siStartInfo = windows.STARTUPINFOA {
539 var siStartInfo = windows.STARTUPINFOA{
515540 .cb = @sizeOf(windows.STARTUPINFOA),
516541 .hStdError = g_hChildStd_ERR_Wr,
517542 .hStdOutput = g_hChildStd_OUT_Wr,
......@@ -534,19 +559,11 @@ pub const ChildProcess = struct {
534559 };
535560 var piProcInfo: windows.PROCESS_INFORMATION = undefined;
536561
537 const cwd_slice = if (self.cwd) |cwd|
538 try cstr.addNullByte(self.allocator, cwd)
539 else
540 null
541 ;
562 const cwd_slice = if (self.cwd) |cwd| try cstr.addNullByte(self.allocator, cwd) else null;
542563 defer if (cwd_slice) |cwd| self.allocator.free(cwd);
543564 const cwd_ptr = if (cwd_slice) |cwd| cwd.ptr else null;
544565
545 const maybe_envp_buf = if (self.env_map) |env_map|
546 try os.createWindowsEnvBlock(self.allocator, env_map)
547 else
548 null
549 ;
566 const maybe_envp_buf = if (self.env_map) |env_map| try os.createWindowsEnvBlock(self.allocator, env_map) else null;
550567 defer if (maybe_envp_buf) |envp_buf| self.allocator.free(envp_buf);
551568 const envp_ptr = if (maybe_envp_buf) |envp_buf| envp_buf.ptr else null;
552569
......@@ -563,11 +580,8 @@ pub const ChildProcess = struct {
563580 };
564581 defer self.allocator.free(app_name);
565582
566 windowsCreateProcess(app_name.ptr, cmd_line.ptr, envp_ptr, cwd_ptr,
567 &siStartInfo, &piProcInfo) catch |no_path_err|
568 {
569 if (no_path_err != error.FileNotFound)
570 return no_path_err;
583 windowsCreateProcess(app_name.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, &siStartInfo, &piProcInfo) catch |no_path_err| {
584 if (no_path_err != error.FileNotFound) return no_path_err;
571585
572586 const PATH = try os.getEnvVarOwned(self.allocator, "PATH");
573587 defer self.allocator.free(PATH);
......@@ -577,9 +591,7 @@ pub const ChildProcess = struct {
577591 const joined_path = try os.path.join(self.allocator, search_path, app_name);
578592 defer self.allocator.free(joined_path);
579593
580 if (windowsCreateProcess(joined_path.ptr, cmd_line.ptr, envp_ptr, cwd_ptr,
581 &siStartInfo, &piProcInfo)) |_|
582 {
594 if (windowsCreateProcess(joined_path.ptr, cmd_line.ptr, envp_ptr, cwd_ptr, &siStartInfo, &piProcInfo)) |_| {
583595 break;
584596 } else |err| if (err == error.FileNotFound) {
585597 continue;
......@@ -609,9 +621,15 @@ pub const ChildProcess = struct {
609621 self.thread_handle = piProcInfo.hThread;
610622 self.term = null;
611623
612 if (self.stdin_behavior == StdIo.Pipe) { os.close(??g_hChildStd_IN_Rd); }
613 if (self.stderr_behavior == StdIo.Pipe) { os.close(??g_hChildStd_ERR_Wr); }
614 if (self.stdout_behavior == StdIo.Pipe) { os.close(??g_hChildStd_OUT_Wr); }
624 if (self.stdin_behavior == StdIo.Pipe) {
625 os.close(??g_hChildStd_IN_Rd);
626 }
627 if (self.stderr_behavior == StdIo.Pipe) {
628 os.close(??g_hChildStd_ERR_Wr);
629 }
630 if (self.stdout_behavior == StdIo.Pipe) {
631 os.close(??g_hChildStd_OUT_Wr);
632 }
615633 }
616634
617635 fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void {
......@@ -622,18 +640,14 @@ pub const ChildProcess = struct {
622640 StdIo.Ignore => try os.posixDup2(dev_null_fd, std_fileno),
623641 }
624642 }
625
626643};
627644
628fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?&u8,
629 lpStartupInfo: &windows.STARTUPINFOA, lpProcessInformation: &windows.PROCESS_INFORMATION) !void
630{
631 if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0,
632 @ptrCast(?&c_void, envp_ptr), cwd_ptr, lpStartupInfo, lpProcessInformation) == 0)
633 {
645fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?&u8, lpStartupInfo: &windows.STARTUPINFOA, lpProcessInformation: &windows.PROCESS_INFORMATION) !void {
646 if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0, @ptrCast(?&c_void, envp_ptr), cwd_ptr, lpStartupInfo, lpProcessInformation) == 0) {
634647 const err = windows.GetLastError();
635648 return switch (err) {
636 windows.ERROR.FILE_NOT_FOUND, windows.ERROR.PATH_NOT_FOUND => error.FileNotFound,
649 windows.ERROR.FILE_NOT_FOUND,
650 windows.ERROR.PATH_NOT_FOUND => error.FileNotFound,
637651 windows.ERROR.INVALID_PARAMETER => unreachable,
638652 windows.ERROR.INVALID_NAME => error.InvalidName,
639653 else => os.unexpectedErrorWindows(err),
......@@ -641,9 +655,6 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?
641655 }
642656}
643657
644
645
646
647658/// Caller must dealloc.
648659/// Guarantees a null byte at result[result.len].
649660fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) ![]u8 {
......@@ -651,8 +662,7 @@ fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8)
651662 defer buf.deinit();
652663
653664 for (argv) |arg, arg_i| {
654 if (arg_i != 0)
655 try buf.appendByte(' ');
665 if (arg_i != 0) try buf.appendByte(' ');
656666 if (mem.indexOfAny(u8, arg, " \t\n\"") == null) {
657667 try buf.append(arg);
658668 continue;
......@@ -686,7 +696,6 @@ fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) void {
686696 if (wr) |h| os.close(h);
687697}
688698
689
690699// TODO: workaround for bug where the `const` from `&const` is dropped when the type is
691700// a namespace field lookup
692701const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;
......@@ -715,8 +724,8 @@ fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const S
715724 try windowsMakePipe(&rd_h, &wr_h, sattr);
716725 errdefer windowsDestroyPipe(rd_h, wr_h);
717726 try windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0);
718 *rd = rd_h;
719 *wr = wr_h;
727 rd.* = rd_h;
728 wr.* = wr_h;
720729}
721730
722731fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) !void {
......@@ -725,8 +734,8 @@ fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const
725734 try windowsMakePipe(&rd_h, &wr_h, sattr);
726735 errdefer windowsDestroyPipe(rd_h, wr_h);
727736 try windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0);
728 *rd = rd_h;
729 *wr = wr_h;
737 rd.* = rd_h;
738 wr.* = wr_h;
730739}
731740
732741fn makePipe() ![2]i32 {
......@@ -734,7 +743,8 @@ fn makePipe() ![2]i32 {
734743 const err = posix.getErrno(posix.pipe(&fds));
735744 if (err > 0) {
736745 return switch (err) {
737 posix.EMFILE, posix.ENFILE => error.SystemResources,
746 posix.EMFILE,
747 posix.ENFILE => error.SystemResources,
738748 else => os.unexpectedErrorPosix(err),
739749 };
740750 }
......@@ -742,8 +752,8 @@ fn makePipe() ![2]i32 {
742752}
743753
744754fn destroyPipe(pipe: &const [2]i32) void {
745 os.close((*pipe)[0]);
746 os.close((*pipe)[1]);
755 os.close((pipe.*)[0]);
756 os.close((pipe.*)[1]);
747757}
748758
749759// Child of fork calls this to report an error to the fork parent.
std/segmented_list.zig+30-24
......@@ -93,7 +93,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
9393
9494 /// Deinitialize with `deinit`
9595 pub fn init(allocator: &Allocator) Self {
96 return Self {
96 return Self{
9797 .allocator = allocator,
9898 .len = 0,
9999 .prealloc_segment = undefined,
......@@ -104,7 +104,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
104104 pub fn deinit(self: &Self) void {
105105 self.freeShelves(ShelfIndex(self.dynamic_segments.len), 0);
106106 self.allocator.free(self.dynamic_segments);
107 *self = undefined;
107 self.* = undefined;
108108 }
109109
110110 pub fn at(self: &Self, i: usize) &T {
......@@ -118,7 +118,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
118118
119119 pub fn push(self: &Self, item: &const T) !void {
120120 const new_item_ptr = try self.addOne();
121 *new_item_ptr = *item;
121 new_item_ptr.* = item.*;
122122 }
123123
124124 pub fn pushMany(self: &Self, items: []const T) !void {
......@@ -128,11 +128,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
128128 }
129129
130130 pub fn pop(self: &Self) ?T {
131 if (self.len == 0)
132 return null;
131 if (self.len == 0) return null;
133132
134133 const index = self.len - 1;
135 const result = *self.uncheckedAt(index);
134 const result = self.uncheckedAt(index).*;
136135 self.len = index;
137136 return result;
138137 }
......@@ -245,8 +244,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
245244 shelf_size: usize,
246245
247246 pub fn next(it: &Iterator) ?&T {
248 if (it.index >= it.list.len)
249 return null;
247 if (it.index >= it.list.len) return null;
250248 if (it.index < prealloc_item_count) {
251249 const ptr = &it.list.prealloc_segment[it.index];
252250 it.index += 1;
......@@ -270,12 +268,10 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
270268 }
271269
272270 pub fn prev(it: &Iterator) ?&T {
273 if (it.index == 0)
274 return null;
271 if (it.index == 0) return null;
275272
276273 it.index -= 1;
277 if (it.index < prealloc_item_count)
278 return &it.list.prealloc_segment[it.index];
274 if (it.index < prealloc_item_count) return &it.list.prealloc_segment[it.index];
279275
280276 if (it.box_index == 0) {
281277 it.shelf_index -= 1;
......@@ -290,7 +286,7 @@ pub fn SegmentedList(comptime T: type, comptime prealloc_item_count: usize) type
290286 };
291287
292288 pub fn iterator(self: &Self, start_index: usize) Iterator {
293 var it = Iterator {
289 var it = Iterator{
294290 .list = self,
295291 .index = start_index,
296292 .shelf_index = undefined,
......@@ -324,25 +320,31 @@ fn testSegmentedList(comptime prealloc: usize, allocator: &Allocator) !void {
324320 var list = SegmentedList(i32, prealloc).init(allocator);
325321 defer list.deinit();
326322
327 {var i: usize = 0; while (i < 100) : (i += 1) {
328 try list.push(i32(i + 1));
329 assert(list.len == i + 1);
330 }}
323 {
324 var i: usize = 0;
325 while (i < 100) : (i += 1) {
326 try list.push(i32(i + 1));
327 assert(list.len == i + 1);
328 }
329 }
331330
332 {var i: usize = 0; while (i < 100) : (i += 1) {
333 assert(*list.at(i) == i32(i + 1));
334 }}
331 {
332 var i: usize = 0;
333 while (i < 100) : (i += 1) {
334 assert(list.at(i).* == i32(i + 1));
335 }
336 }
335337
336338 {
337339 var it = list.iterator(0);
338340 var x: i32 = 0;
339341 while (it.next()) |item| {
340342 x += 1;
341 assert(*item == x);
343 assert(item.* == x);
342344 }
343345 assert(x == 100);
344346 while (it.prev()) |item| : (x -= 1) {
345 assert(*item == x);
347 assert(item.* == x);
346348 }
347349 assert(x == 0);
348350 }
......@@ -350,14 +352,18 @@ fn testSegmentedList(comptime prealloc: usize, allocator: &Allocator) !void {
350352 assert(??list.pop() == 100);
351353 assert(list.len == 99);
352354
353 try list.pushMany([]i32 { 1, 2, 3 });
355 try list.pushMany([]i32{
356 1,
357 2,
358 3,
359 });
354360 assert(list.len == 102);
355361 assert(??list.pop() == 3);
356362 assert(??list.pop() == 2);
357363 assert(??list.pop() == 1);
358364 assert(list.len == 99);
359365
360 try list.pushMany([]const i32 {});
366 try list.pushMany([]const i32{});
361367 assert(list.len == 99);
362368
363369 var i: i32 = 99;
std/sort.zig+398-164
......@@ -5,15 +5,18 @@ const math = std.math;
55const builtin = @import("builtin");
66
77/// Stable in-place sort. O(n) best case, O(pow(n, 2)) worst case. O(1) memory (no allocator required).
8pub fn insertionSort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) void {
9 {var i: usize = 1; while (i < items.len) : (i += 1) {
10 const x = items[i];
11 var j: usize = i;
12 while (j > 0 and lessThan(x, items[j - 1])) : (j -= 1) {
13 items[j] = items[j - 1];
8pub fn insertionSort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool) void {
9 {
10 var i: usize = 1;
11 while (i < items.len) : (i += 1) {
12 const x = items[i];
13 var j: usize = i;
14 while (j > 0 and lessThan(x, items[j - 1])) : (j -= 1) {
15 items[j] = items[j - 1];
16 }
17 items[j] = x;
1418 }
15 items[j] = x;
16 }}
19 }
1720}
1821
1922const Range = struct {
......@@ -21,7 +24,10 @@ const Range = struct {
2124 end: usize,
2225
2326 fn init(start: usize, end: usize) Range {
24 return Range { .start = start, .end = end };
27 return Range{
28 .start = start,
29 .end = end,
30 };
2531 }
2632
2733 fn length(self: &const Range) usize {
......@@ -29,7 +35,6 @@ const Range = struct {
2935 }
3036};
3137
32
3338const Iterator = struct {
3439 size: usize,
3540 power_of_two: usize,
......@@ -42,7 +47,7 @@ const Iterator = struct {
4247 fn init(size2: usize, min_level: usize) Iterator {
4348 const power_of_two = math.floorPowerOfTwo(usize, size2);
4449 const denominator = power_of_two / min_level;
45 return Iterator {
50 return Iterator{
4651 .numerator = 0,
4752 .decimal = 0,
4853 .size = size2,
......@@ -68,7 +73,10 @@ const Iterator = struct {
6873 self.decimal += 1;
6974 }
7075
71 return Range {.start = start, .end = self.decimal};
76 return Range{
77 .start = start,
78 .end = self.decimal,
79 };
7280 }
7381
7482 fn finished(self: &Iterator) bool {
......@@ -100,7 +108,7 @@ const Pull = struct {
100108
101109/// Stable in-place sort. O(n) best case, O(n*log(n)) worst case and average case. O(1) memory (no allocator required).
102110/// Currently implemented as block sort.
103pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) void {
111pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool) void {
104112 // Implementation ported from https://github.com/BonzaiThePenguin/WikiSort/blob/master/WikiSort.c
105113 var cache: [512]T = undefined;
106114
......@@ -123,7 +131,16 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
123131 // http://pages.ripco.net/~jgamble/nw.html
124132 var iterator = Iterator.init(items.len, 4);
125133 while (!iterator.finished()) {
126 var order = []u8{0, 1, 2, 3, 4, 5, 6, 7};
134 var order = []u8{
135 0,
136 1,
137 2,
138 3,
139 4,
140 5,
141 6,
142 7,
143 };
127144 const range = iterator.nextRange();
128145
129146 const sliced_items = items[range.start..];
......@@ -149,56 +166,56 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
149166 swap(T, sliced_items, lessThan, &order, 3, 5);
150167 swap(T, sliced_items, lessThan, &order, 3, 4);
151168 },
152 7 => {
153 swap(T, sliced_items, lessThan, &order, 1, 2);
154 swap(T, sliced_items, lessThan, &order, 3, 4);
155 swap(T, sliced_items, lessThan, &order, 5, 6);
156 swap(T, sliced_items, lessThan, &order, 0, 2);
157 swap(T, sliced_items, lessThan, &order, 3, 5);
158 swap(T, sliced_items, lessThan, &order, 4, 6);
159 swap(T, sliced_items, lessThan, &order, 0, 1);
160 swap(T, sliced_items, lessThan, &order, 4, 5);
161 swap(T, sliced_items, lessThan, &order, 2, 6);
162 swap(T, sliced_items, lessThan, &order, 0, 4);
163 swap(T, sliced_items, lessThan, &order, 1, 5);
164 swap(T, sliced_items, lessThan, &order, 0, 3);
165 swap(T, sliced_items, lessThan, &order, 2, 5);
166 swap(T, sliced_items, lessThan, &order, 1, 3);
167 swap(T, sliced_items, lessThan, &order, 2, 4);
168 swap(T, sliced_items, lessThan, &order, 2, 3);
169 },
170 6 => {
171 swap(T, sliced_items, lessThan, &order, 1, 2);
172 swap(T, sliced_items, lessThan, &order, 4, 5);
173 swap(T, sliced_items, lessThan, &order, 0, 2);
174 swap(T, sliced_items, lessThan, &order, 3, 5);
175 swap(T, sliced_items, lessThan, &order, 0, 1);
176 swap(T, sliced_items, lessThan, &order, 3, 4);
177 swap(T, sliced_items, lessThan, &order, 2, 5);
178 swap(T, sliced_items, lessThan, &order, 0, 3);
179 swap(T, sliced_items, lessThan, &order, 1, 4);
180 swap(T, sliced_items, lessThan, &order, 2, 4);
181 swap(T, sliced_items, lessThan, &order, 1, 3);
182 swap(T, sliced_items, lessThan, &order, 2, 3);
183 },
184 5 => {
185 swap(T, sliced_items, lessThan, &order, 0, 1);
186 swap(T, sliced_items, lessThan, &order, 3, 4);
187 swap(T, sliced_items, lessThan, &order, 2, 4);
188 swap(T, sliced_items, lessThan, &order, 2, 3);
189 swap(T, sliced_items, lessThan, &order, 1, 4);
190 swap(T, sliced_items, lessThan, &order, 0, 3);
191 swap(T, sliced_items, lessThan, &order, 0, 2);
192 swap(T, sliced_items, lessThan, &order, 1, 3);
193 swap(T, sliced_items, lessThan, &order, 1, 2);
194 },
195 4 => {
196 swap(T, sliced_items, lessThan, &order, 0, 1);
197 swap(T, sliced_items, lessThan, &order, 2, 3);
198 swap(T, sliced_items, lessThan, &order, 0, 2);
199 swap(T, sliced_items, lessThan, &order, 1, 3);
200 swap(T, sliced_items, lessThan, &order, 1, 2);
201 },
169 7 => {
170 swap(T, sliced_items, lessThan, &order, 1, 2);
171 swap(T, sliced_items, lessThan, &order, 3, 4);
172 swap(T, sliced_items, lessThan, &order, 5, 6);
173 swap(T, sliced_items, lessThan, &order, 0, 2);
174 swap(T, sliced_items, lessThan, &order, 3, 5);
175 swap(T, sliced_items, lessThan, &order, 4, 6);
176 swap(T, sliced_items, lessThan, &order, 0, 1);
177 swap(T, sliced_items, lessThan, &order, 4, 5);
178 swap(T, sliced_items, lessThan, &order, 2, 6);
179 swap(T, sliced_items, lessThan, &order, 0, 4);
180 swap(T, sliced_items, lessThan, &order, 1, 5);
181 swap(T, sliced_items, lessThan, &order, 0, 3);
182 swap(T, sliced_items, lessThan, &order, 2, 5);
183 swap(T, sliced_items, lessThan, &order, 1, 3);
184 swap(T, sliced_items, lessThan, &order, 2, 4);
185 swap(T, sliced_items, lessThan, &order, 2, 3);
186 },
187 6 => {
188 swap(T, sliced_items, lessThan, &order, 1, 2);
189 swap(T, sliced_items, lessThan, &order, 4, 5);
190 swap(T, sliced_items, lessThan, &order, 0, 2);
191 swap(T, sliced_items, lessThan, &order, 3, 5);
192 swap(T, sliced_items, lessThan, &order, 0, 1);
193 swap(T, sliced_items, lessThan, &order, 3, 4);
194 swap(T, sliced_items, lessThan, &order, 2, 5);
195 swap(T, sliced_items, lessThan, &order, 0, 3);
196 swap(T, sliced_items, lessThan, &order, 1, 4);
197 swap(T, sliced_items, lessThan, &order, 2, 4);
198 swap(T, sliced_items, lessThan, &order, 1, 3);
199 swap(T, sliced_items, lessThan, &order, 2, 3);
200 },
201 5 => {
202 swap(T, sliced_items, lessThan, &order, 0, 1);
203 swap(T, sliced_items, lessThan, &order, 3, 4);
204 swap(T, sliced_items, lessThan, &order, 2, 4);
205 swap(T, sliced_items, lessThan, &order, 2, 3);
206 swap(T, sliced_items, lessThan, &order, 1, 4);
207 swap(T, sliced_items, lessThan, &order, 0, 3);
208 swap(T, sliced_items, lessThan, &order, 0, 2);
209 swap(T, sliced_items, lessThan, &order, 1, 3);
210 swap(T, sliced_items, lessThan, &order, 1, 2);
211 },
212 4 => {
213 swap(T, sliced_items, lessThan, &order, 0, 1);
214 swap(T, sliced_items, lessThan, &order, 2, 3);
215 swap(T, sliced_items, lessThan, &order, 0, 2);
216 swap(T, sliced_items, lessThan, &order, 1, 3);
217 swap(T, sliced_items, lessThan, &order, 1, 2);
218 },
202219 else => {},
203220 }
204221 }
......@@ -273,7 +290,6 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
273290 // we merged two levels at the same time, so we're done with this level already
274291 // (iterator.nextLevel() is called again at the bottom of this outer merge loop)
275292 _ = iterator.nextLevel();
276
277293 } else {
278294 iterator.begin();
279295 while (!iterator.finished()) {
......@@ -303,7 +319,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
303319 // 8. redistribute the two internal buffers back into the items
304320
305321 var block_size: usize = math.sqrt(iterator.length());
306 var buffer_size = iterator.length()/block_size + 1;
322 var buffer_size = iterator.length() / block_size + 1;
307323
308324 // as an optimization, we really only need to pull out the internal buffers once for each level of merges
309325 // after that we can reuse the same buffers over and over, then redistribute it when we're finished with this level
......@@ -316,8 +332,18 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
316332 var start: usize = 0;
317333 var pull_index: usize = 0;
318334 var pull = []Pull{
319 Pull {.from = 0, .to = 0, .count = 0, .range = Range.init(0, 0),},
320 Pull {.from = 0, .to = 0, .count = 0, .range = Range.init(0, 0),},
335 Pull{
336 .from = 0,
337 .to = 0,
338 .count = 0,
339 .range = Range.init(0, 0),
340 },
341 Pull{
342 .from = 0,
343 .to = 0,
344 .count = 0,
345 .range = Range.init(0, 0),
346 },
321347 };
322348
323349 var buffer1 = Range.init(0, 0);
......@@ -355,7 +381,10 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
355381 // these values will be pulled out to the start of A
356382 last = A.start;
357383 count = 1;
358 while (count < find) : ({last = index; count += 1;}) {
384 while (count < find) : ({
385 last = index;
386 count += 1;
387 }) {
359388 index = findLastForward(T, items, items[last], Range.init(last + 1, A.end), lessThan, find - count);
360389 if (index == A.end) break;
361390 }
......@@ -363,7 +392,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
363392
364393 if (count >= buffer_size) {
365394 // keep track of the range within the items where we'll need to "pull out" these values to create the internal buffer
366 pull[pull_index] = Pull {
395 pull[pull_index] = Pull{
367396 .range = Range.init(A.start, B.end),
368397 .count = count,
369398 .from = index,
......@@ -398,7 +427,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
398427 } else if (pull_index == 0 and count > buffer1.length()) {
399428 // keep track of the largest buffer we were able to find
400429 buffer1 = Range.init(A.start, A.start + count);
401 pull[pull_index] = Pull {
430 pull[pull_index] = Pull{
402431 .range = Range.init(A.start, B.end),
403432 .count = count,
404433 .from = index,
......@@ -410,7 +439,10 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
410439 // these values will be pulled out to the end of B
411440 last = B.end - 1;
412441 count = 1;
413 while (count < find) : ({last = index - 1; count += 1;}) {
442 while (count < find) : ({
443 last = index - 1;
444 count += 1;
445 }) {
414446 index = findFirstBackward(T, items, items[last], Range.init(B.start, last), lessThan, find - count);
415447 if (index == B.start) break;
416448 }
......@@ -418,7 +450,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
418450
419451 if (count >= buffer_size) {
420452 // keep track of the range within the items where we'll need to "pull out" these values to create the internal buffe
421 pull[pull_index] = Pull {
453 pull[pull_index] = Pull{
422454 .range = Range.init(A.start, B.end),
423455 .count = count,
424456 .from = index,
......@@ -457,7 +489,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
457489 } else if (pull_index == 0 and count > buffer1.length()) {
458490 // keep track of the largest buffer we were able to find
459491 buffer1 = Range.init(B.end - count, B.end);
460 pull[pull_index] = Pull {
492 pull[pull_index] = Pull{
461493 .range = Range.init(A.start, B.end),
462494 .count = count,
463495 .from = index,
......@@ -496,7 +528,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
496528
497529 // adjust block_size and buffer_size based on the values we were able to pull out
498530 buffer_size = buffer1.length();
499 block_size = iterator.length()/buffer_size + 1;
531 block_size = iterator.length() / buffer_size + 1;
500532
501533 // the first buffer NEEDS to be large enough to tag each of the evenly sized A blocks,
502534 // so this was originally here to test the math for adjusting block_size above
......@@ -547,7 +579,10 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
547579 // swap the first value of each A block with the value in buffer1
548580 var indexA = buffer1.start;
549581 index = firstA.end;
550 while (index < blockA.end) : ({indexA += 1; index += block_size;}) {
582 while (index < blockA.end) : ({
583 indexA += 1;
584 index += block_size;
585 }) {
551586 mem.swap(T, &items[indexA], &items[index]);
552587 }
553588
......@@ -626,9 +661,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
626661
627662 // if there are no more A blocks remaining, this step is finished!
628663 blockA.start += block_size;
629 if (blockA.length() == 0)
630 break;
631
664 if (blockA.length() == 0) break;
632665 } else if (blockB.length() < block_size) {
633666 // move the last B block, which is unevenly sized, to before the remaining A blocks, by using a rotation
634667 // the cache is disabled here since it might contain the contents of the previous A block
......@@ -709,7 +742,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
709742}
710743
711744// merge operation without a buffer
712fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const Range, lessThan: fn(&const T,&const T)bool) void {
745fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const Range, lessThan: fn(&const T, &const T) bool) void {
713746 if (A_arg.length() == 0 or B_arg.length() == 0) return;
714747
715748 // this just repeatedly binary searches into B and rotates A into position.
......@@ -730,8 +763,8 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const
730763 // again, this is NOT a general-purpose solution – it only works well in this case!
731764 // kind of like how the O(n^2) insertion sort is used in some places
732765
733 var A = *A_arg;
734 var B = *B_arg;
766 var A = A_arg.*;
767 var B = B_arg.*;
735768
736769 while (true) {
737770 // find the first place in B where the first item in A needs to be inserted
......@@ -751,7 +784,7 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const
751784}
752785
753786// merge operation using an internal buffer
754fn mergeInternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)bool, buffer: &const Range) void {
787fn mergeInternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T, &const T) bool, buffer: &const Range) void {
755788 // whenever we find a value to add to the final array, swap it with the value that's already in that spot
756789 // when this algorithm is finished, 'buffer' will contain its original contents, but in a different order
757790 var A_count: usize = 0;
......@@ -787,9 +820,9 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s
787820
788821// combine a linear search with a binary search to reduce the number of comparisons in situations
789822// where have some idea as to how many unique values there are and where the next value might be
790fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {
823fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool, unique: usize) usize {
791824 if (range.length() == 0) return range.start;
792 const skip = math.max(range.length()/unique, usize(1));
825 const skip = math.max(range.length() / unique, usize(1));
793826
794827 var index = range.start + skip;
795828 while (lessThan(items[index - 1], value)) : (index += skip) {
......@@ -801,9 +834,9 @@ fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const
801834 return binaryFirst(T, items, value, Range.init(index - skip, index), lessThan);
802835}
803836
804fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {
837fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool, unique: usize) usize {
805838 if (range.length() == 0) return range.start;
806 const skip = math.max(range.length()/unique, usize(1));
839 const skip = math.max(range.length() / unique, usize(1));
807840
808841 var index = range.end - skip;
809842 while (index > range.start and !lessThan(items[index - 1], value)) : (index -= skip) {
......@@ -815,9 +848,9 @@ fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &cons
815848 return binaryFirst(T, items, value, Range.init(index, index + skip), lessThan);
816849}
817850
818fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {
851fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool, unique: usize) usize {
819852 if (range.length() == 0) return range.start;
820 const skip = math.max(range.length()/unique, usize(1));
853 const skip = math.max(range.length() / unique, usize(1));
821854
822855 var index = range.start + skip;
823856 while (!lessThan(value, items[index - 1])) : (index += skip) {
......@@ -829,9 +862,9 @@ fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const
829862 return binaryLast(T, items, value, Range.init(index - skip, index), lessThan);
830863}
831864
832fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {
865fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool, unique: usize) usize {
833866 if (range.length() == 0) return range.start;
834 const skip = math.max(range.length()/unique, usize(1));
867 const skip = math.max(range.length() / unique, usize(1));
835868
836869 var index = range.end - skip;
837870 while (index > range.start and lessThan(value, items[index - 1])) : (index -= skip) {
......@@ -843,12 +876,12 @@ fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const
843876 return binaryLast(T, items, value, Range.init(index, index + skip), lessThan);
844877}
845878
846fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool) usize {
879fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool) usize {
847880 var start = range.start;
848881 var end = range.end - 1;
849882 if (range.start >= range.end) return range.end;
850883 while (start < end) {
851 const mid = start + (end - start)/2;
884 const mid = start + (end - start) / 2;
852885 if (lessThan(items[mid], value)) {
853886 start = mid + 1;
854887 } else {
......@@ -861,12 +894,12 @@ fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Rang
861894 return start;
862895}
863896
864fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool) usize {
897fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T, &const T) bool) usize {
865898 var start = range.start;
866899 var end = range.end - 1;
867900 if (range.start >= range.end) return range.end;
868901 while (start < end) {
869 const mid = start + (end - start)/2;
902 const mid = start + (end - start) / 2;
870903 if (!lessThan(value, items[mid])) {
871904 start = mid + 1;
872905 } else {
......@@ -879,7 +912,7 @@ fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range
879912 return start;
880913}
881914
882fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)bool, into: []T) void {
915fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, lessThan: fn(&const T, &const T) bool, into: []T) void {
883916 var A_index: usize = A.start;
884917 var B_index: usize = B.start;
885918 const A_last = A.end;
......@@ -909,7 +942,7 @@ fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, less
909942 }
910943}
911944
912fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)bool, cache: []T) void {
945fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T, &const T) bool, cache: []T) void {
913946 // A fits into the cache, so use that instead of the internal buffer
914947 var A_index: usize = 0;
915948 var B_index: usize = B.start;
......@@ -937,29 +970,27 @@ fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range,
937970 mem.copy(T, items[insert_index..], cache[A_index..A_last]);
938971}
939972
940fn swap(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool, order: &[8]u8, x: usize, y: usize) void {
941 if (lessThan(items[y], items[x]) or
942 ((*order)[x] > (*order)[y] and !lessThan(items[x], items[y])))
943 {
973fn swap(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool, order: &[8]u8, x: usize, y: usize) void {
974 if (lessThan(items[y], items[x]) or ((order.*)[x] > (order.*)[y] and !lessThan(items[x], items[y]))) {
944975 mem.swap(T, &items[x], &items[y]);
945 mem.swap(u8, &(*order)[x], &(*order)[y]);
976 mem.swap(u8, &(order.*)[x], &(order.*)[y]);
946977 }
947978}
948979
949980fn i32asc(lhs: &const i32, rhs: &const i32) bool {
950 return *lhs < *rhs;
981 return lhs.* < rhs.*;
951982}
952983
953984fn i32desc(lhs: &const i32, rhs: &const i32) bool {
954 return *rhs < *lhs;
985 return rhs.* < lhs.*;
955986}
956987
957988fn u8asc(lhs: &const u8, rhs: &const u8) bool {
958 return *lhs < *rhs;
989 return lhs.* < rhs.*;
959990}
960991
961992fn u8desc(lhs: &const u8, rhs: &const u8) bool {
962 return *rhs < *lhs;
993 return rhs.* < lhs.*;
963994}
964995
965996test "stable sort" {
......@@ -967,44 +998,125 @@ test "stable sort" {
967998 comptime testStableSort();
968999}
9691000fn testStableSort() void {
970 var expected = []IdAndValue {
971 IdAndValue{.id = 0, .value = 0},
972 IdAndValue{.id = 1, .value = 0},
973 IdAndValue{.id = 2, .value = 0},
974 IdAndValue{.id = 0, .value = 1},
975 IdAndValue{.id = 1, .value = 1},
976 IdAndValue{.id = 2, .value = 1},
977 IdAndValue{.id = 0, .value = 2},
978 IdAndValue{.id = 1, .value = 2},
979 IdAndValue{.id = 2, .value = 2},
1001 var expected = []IdAndValue{
1002 IdAndValue{
1003 .id = 0,
1004 .value = 0,
1005 },
1006 IdAndValue{
1007 .id = 1,
1008 .value = 0,
1009 },
1010 IdAndValue{
1011 .id = 2,
1012 .value = 0,
1013 },
1014 IdAndValue{
1015 .id = 0,
1016 .value = 1,
1017 },
1018 IdAndValue{
1019 .id = 1,
1020 .value = 1,
1021 },
1022 IdAndValue{
1023 .id = 2,
1024 .value = 1,
1025 },
1026 IdAndValue{
1027 .id = 0,
1028 .value = 2,
1029 },
1030 IdAndValue{
1031 .id = 1,
1032 .value = 2,
1033 },
1034 IdAndValue{
1035 .id = 2,
1036 .value = 2,
1037 },
9801038 };
981 var cases = [][9]IdAndValue {
982 []IdAndValue {
983 IdAndValue{.id = 0, .value = 0},
984 IdAndValue{.id = 0, .value = 1},
985 IdAndValue{.id = 0, .value = 2},
986 IdAndValue{.id = 1, .value = 0},
987 IdAndValue{.id = 1, .value = 1},
988 IdAndValue{.id = 1, .value = 2},
989 IdAndValue{.id = 2, .value = 0},
990 IdAndValue{.id = 2, .value = 1},
991 IdAndValue{.id = 2, .value = 2},
1039 var cases = [][9]IdAndValue{
1040 []IdAndValue{
1041 IdAndValue{
1042 .id = 0,
1043 .value = 0,
1044 },
1045 IdAndValue{
1046 .id = 0,
1047 .value = 1,
1048 },
1049 IdAndValue{
1050 .id = 0,
1051 .value = 2,
1052 },
1053 IdAndValue{
1054 .id = 1,
1055 .value = 0,
1056 },
1057 IdAndValue{
1058 .id = 1,
1059 .value = 1,
1060 },
1061 IdAndValue{
1062 .id = 1,
1063 .value = 2,
1064 },
1065 IdAndValue{
1066 .id = 2,
1067 .value = 0,
1068 },
1069 IdAndValue{
1070 .id = 2,
1071 .value = 1,
1072 },
1073 IdAndValue{
1074 .id = 2,
1075 .value = 2,
1076 },
9921077 },
993 []IdAndValue {
994 IdAndValue{.id = 0, .value = 2},
995 IdAndValue{.id = 0, .value = 1},
996 IdAndValue{.id = 0, .value = 0},
997 IdAndValue{.id = 1, .value = 2},
998 IdAndValue{.id = 1, .value = 1},
999 IdAndValue{.id = 1, .value = 0},
1000 IdAndValue{.id = 2, .value = 2},
1001 IdAndValue{.id = 2, .value = 1},
1002 IdAndValue{.id = 2, .value = 0},
1078 []IdAndValue{
1079 IdAndValue{
1080 .id = 0,
1081 .value = 2,
1082 },
1083 IdAndValue{
1084 .id = 0,
1085 .value = 1,
1086 },
1087 IdAndValue{
1088 .id = 0,
1089 .value = 0,
1090 },
1091 IdAndValue{
1092 .id = 1,
1093 .value = 2,
1094 },
1095 IdAndValue{
1096 .id = 1,
1097 .value = 1,
1098 },
1099 IdAndValue{
1100 .id = 1,
1101 .value = 0,
1102 },
1103 IdAndValue{
1104 .id = 2,
1105 .value = 2,
1106 },
1107 IdAndValue{
1108 .id = 2,
1109 .value = 1,
1110 },
1111 IdAndValue{
1112 .id = 2,
1113 .value = 0,
1114 },
10031115 },
10041116 };
10051117 for (cases) |*case| {
1006 insertionSort(IdAndValue, (*case)[0..], cmpByValue);
1007 for (*case) |item, i| {
1118 insertionSort(IdAndValue, (case.*)[0..], cmpByValue);
1119 for (case.*) |item, i| {
10081120 assert(item.id == expected[i].id);
10091121 assert(item.value == expected[i].value);
10101122 }
......@@ -1019,13 +1131,31 @@ fn cmpByValue(a: &const IdAndValue, b: &const IdAndValue) bool {
10191131}
10201132
10211133test "std.sort" {
1022 const u8cases = [][]const []const u8 {
1023 [][]const u8{"", ""},
1024 [][]const u8{"a", "a"},
1025 [][]const u8{"az", "az"},
1026 [][]const u8{"za", "az"},
1027 [][]const u8{"asdf", "adfs"},
1028 [][]const u8{"one", "eno"},
1134 const u8cases = [][]const []const u8{
1135 [][]const u8{
1136 "",
1137 "",
1138 },
1139 [][]const u8{
1140 "a",
1141 "a",
1142 },
1143 [][]const u8{
1144 "az",
1145 "az",
1146 },
1147 [][]const u8{
1148 "za",
1149 "az",
1150 },
1151 [][]const u8{
1152 "asdf",
1153 "adfs",
1154 },
1155 [][]const u8{
1156 "one",
1157 "eno",
1158 },
10291159 };
10301160
10311161 for (u8cases) |case| {
......@@ -1036,13 +1166,59 @@ test "std.sort" {
10361166 assert(mem.eql(u8, slice, case[1]));
10371167 }
10381168
1039 const i32cases = [][]const []const i32 {
1040 [][]const i32{[]i32{}, []i32{}},
1041 [][]const i32{[]i32{1}, []i32{1}},
1042 [][]const i32{[]i32{0, 1}, []i32{0, 1}},
1043 [][]const i32{[]i32{1, 0}, []i32{0, 1}},
1044 [][]const i32{[]i32{1, -1, 0}, []i32{-1, 0, 1}},
1045 [][]const i32{[]i32{2, 1, 3}, []i32{1, 2, 3}},
1169 const i32cases = [][]const []const i32{
1170 [][]const i32{
1171 []i32{},
1172 []i32{},
1173 },
1174 [][]const i32{
1175 []i32{1},
1176 []i32{1},
1177 },
1178 [][]const i32{
1179 []i32{
1180 0,
1181 1,
1182 },
1183 []i32{
1184 0,
1185 1,
1186 },
1187 },
1188 [][]const i32{
1189 []i32{
1190 1,
1191 0,
1192 },
1193 []i32{
1194 0,
1195 1,
1196 },
1197 },
1198 [][]const i32{
1199 []i32{
1200 1,
1201 -1,
1202 0,
1203 },
1204 []i32{
1205 -1,
1206 0,
1207 1,
1208 },
1209 },
1210 [][]const i32{
1211 []i32{
1212 2,
1213 1,
1214 3,
1215 },
1216 []i32{
1217 1,
1218 2,
1219 3,
1220 },
1221 },
10461222 };
10471223
10481224 for (i32cases) |case| {
......@@ -1055,13 +1231,59 @@ test "std.sort" {
10551231}
10561232
10571233test "std.sort descending" {
1058 const rev_cases = [][]const []const i32 {
1059 [][]const i32{[]i32{}, []i32{}},
1060 [][]const i32{[]i32{1}, []i32{1}},
1061 [][]const i32{[]i32{0, 1}, []i32{1, 0}},
1062 [][]const i32{[]i32{1, 0}, []i32{1, 0}},
1063 [][]const i32{[]i32{1, -1, 0}, []i32{1, 0, -1}},
1064 [][]const i32{[]i32{2, 1, 3}, []i32{3, 2, 1}},
1234 const rev_cases = [][]const []const i32{
1235 [][]const i32{
1236 []i32{},
1237 []i32{},
1238 },
1239 [][]const i32{
1240 []i32{1},
1241 []i32{1},
1242 },
1243 [][]const i32{
1244 []i32{
1245 0,
1246 1,
1247 },
1248 []i32{
1249 1,
1250 0,
1251 },
1252 },
1253 [][]const i32{
1254 []i32{
1255 1,
1256 0,
1257 },
1258 []i32{
1259 1,
1260 0,
1261 },
1262 },
1263 [][]const i32{
1264 []i32{
1265 1,
1266 -1,
1267 0,
1268 },
1269 []i32{
1270 1,
1271 0,
1272 -1,
1273 },
1274 },
1275 [][]const i32{
1276 []i32{
1277 2,
1278 1,
1279 3,
1280 },
1281 []i32{
1282 3,
1283 2,
1284 1,
1285 },
1286 },
10651287 };
10661288
10671289 for (rev_cases) |case| {
......@@ -1074,10 +1296,22 @@ test "std.sort descending" {
10741296}
10751297
10761298test "another sort case" {
1077 var arr = []i32{ 5, 3, 1, 2, 4 };
1299 var arr = []i32{
1300 5,
1301 3,
1302 1,
1303 2,
1304 4,
1305 };
10781306 sort(i32, arr[0..], i32asc);
10791307
1080 assert(mem.eql(i32, arr, []i32{ 1, 2, 3, 4, 5 }));
1308 assert(mem.eql(i32, arr, []i32{
1309 1,
1310 2,
1311 3,
1312 4,
1313 5,
1314 }));
10811315}
10821316
10831317test "sort fuzz testing" {
......@@ -1112,7 +1346,7 @@ fn fuzzTest(rng: &std.rand.Random) void {
11121346 }
11131347}
11141348
1115pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) T {
1349pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool) T {
11161350 var i: usize = 0;
11171351 var smallest = items[0];
11181352 for (items[1..]) |item| {
......@@ -1123,7 +1357,7 @@ pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const
11231357 return smallest;
11241358}
11251359
1126pub fn max(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) T {
1360pub fn max(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T) bool) T {
11271361 var i: usize = 0;
11281362 var biggest = items[0];
11291363 for (items[1..]) |item| {