authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-13 17:13:10-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-12-13 17:13:10-05:00
logfff6e471259071d9ad8466bcdb0ce42c9d7a90d4
tree84c5b8ce41886b3740970e76506050c82a718183
parent457f03e37d368bcc470fb690778d880fd1878082
signature Commit is signed but in an unrecognized format.

fixups


2 files changed, 40 insertions(+), 47 deletions(-)

std/buf_map.zig+27-9
......@@ -16,7 +16,7 @@ pub const BufMap = struct {
1616 return self;
1717 }
1818
19 pub fn deinit(self: *const BufMap) void {
19 pub fn deinit(self: *BufMap) void {
2020 var it = self.hash_map.iterator();
2121 while (true) {
2222 const entry = it.next() orelse break;
......@@ -27,16 +27,34 @@ pub const BufMap = struct {
2727 self.hash_map.deinit();
2828 }
2929
30 /// Same as `set` but the key and value become owned by the BufMap rather
31 /// than being copied.
32 /// If `setMove` fails, the ownership of key and value does not transfer.
33 pub fn setMove(self: *BufMap, key: []u8, value: []u8) !void {
34 const get_or_put = try self.hash_map.getOrPut(key);
35 if (get_or_put.found_existing) {
36 self.free(get_or_put.kv.key);
37 get_or_put.kv.key = key;
38 }
39 get_or_put.kv.value = value;
40 }
41
42 /// `key` and `value` are copied into the BufMap.
3043 pub fn set(self: *BufMap, key: []const u8, value: []const u8) !void {
31 self.delete(key);
32 const key_copy = try self.copy(key);
33 errdefer self.free(key_copy);
3444 const value_copy = try self.copy(value);
3545 errdefer self.free(value_copy);
36 _ = try self.hash_map.put(key_copy, value_copy);
46 // Avoid copying key if it already exists
47 const get_or_put = try self.hash_map.getOrPut(key);
48 if (!get_or_put.found_existing) {
49 get_or_put.kv.key = self.copy(key) catch |err| {
50 _ = self.hash_map.remove(key);
51 return err;
52 };
53 }
54 get_or_put.kv.value = value_copy;
3755 }
3856
39 pub fn get(self: *const BufMap, key: []const u8) ?[]const u8 {
57 pub fn get(self: BufMap, key: []const u8) ?[]const u8 {
4058 const entry = self.hash_map.get(key) orelse return null;
4159 return entry.value;
4260 }
......@@ -47,7 +65,7 @@ pub const BufMap = struct {
4765 self.free(entry.value);
4866 }
4967
50 pub fn count(self: *const BufMap) usize {
68 pub fn count(self: BufMap) usize {
5169 return self.hash_map.count();
5270 }
5371
......@@ -55,11 +73,11 @@ pub const BufMap = struct {
5573 return self.hash_map.iterator();
5674 }
5775
58 fn free(self: *const BufMap, value: []const u8) void {
76 fn free(self: BufMap, value: []const u8) void {
5977 self.hash_map.allocator.free(value);
6078 }
6179
62 fn copy(self: *const BufMap, value: []const u8) ![]const u8 {
80 fn copy(self: BufMap, value: []const u8) ![]u8 {
6381 return mem.dupe(self.hash_map.allocator, u8, value);
6482 }
6583};
std/os/index.zig+13-38
......@@ -705,54 +705,28 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
705705 const ptr = windows.GetEnvironmentStringsW() orelse return error.OutOfMemory;
706706 defer assert(windows.FreeEnvironmentStringsW(ptr) != 0);
707707
708 var buf: [100]u8 = undefined;
709
710708 var i: usize = 0;
711709 while (true) {
712710 if (ptr[i] == 0) return result;
713711
714712 const key_start = i;
715 var fallocator = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator;
716713
717714 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
718
719 const key_slice = ptr[key_start..i];
720 var key: []u8 = undefined;
721 var heap_key = false;
722
723 key = std.unicode.utf16leToUtf8Alloc(fallocator, key_slice) catch undefined;
724
725 if (key.len == 0) {
726 key = try std.unicode.utf16leToUtf8Alloc(allocator, key_slice);
727 heap_key = true;
728 }
715 const key_w = ptr[key_start..i];
716 const key = try std.unicode.utf16leToUtf8Alloc(allocator, key_w);
717 errdefer allocator.free(key);
729718
730719 if (ptr[i] == '=') i += 1;
731720
732721 const value_start = i;
733722 while (ptr[i] != 0) : (i += 1) {}
734
735 const value_slice = ptr[value_start..i];
736 var value: []u8 = undefined;
737 var heap_value = false;
738
739 value = std.unicode.utf16leToUtf8Alloc(fallocator, value_slice) catch undefined;
740
741 if (value.len == 0) {
742 value = try std.unicode.utf16leToUtf8Alloc(allocator, value_slice);
743 heap_value = true;
744 }
723 const value_w = ptr[value_start..i];
724 const value = try std.unicode.utf16leToUtf8Alloc(allocator, value_w);
725 errdefer allocator.free(value);
745726
746727 i += 1; // skip over null byte
747728
748 try result.set(key, value);
749
750 if (heap_key) {
751 allocator.free(key);
752 }
753 if (heap_value) {
754 allocator.free(value);
755 }
729 try result.setMove(key, value);
756730 }
757731 } else {
758732 for (posix_environ_raw) |ptr| {
......@@ -795,9 +769,6 @@ pub fn getEnvPosix(key: []const u8) ?[]const u8 {
795769pub const GetEnvVarOwnedError = error{
796770 OutOfMemory,
797771 EnvironmentVariableNotFound,
798 DanglingSurrogateHalf,
799 ExpectedSecondSurrogateHalf,
800 UnexpectedSecondSurrogateHalf,
801772
802773 /// See https://github.com/ziglang/zig/issues/1774
803774 InvalidUtf8,
......@@ -833,7 +804,12 @@ pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwned
833804 continue;
834805 }
835806
836 return try std.unicode.utf16leToUtf8Alloc(allocator, buf);
807 return std.unicode.utf16leToUtf8Alloc(allocator, buf) catch |err| switch (err) {
808 error.DanglingSurrogateHalf => return error.InvalidUtf8,
809 error.ExpectedSecondSurrogateHalf => return error.InvalidUtf8,
810 error.UnexpectedSecondSurrogateHalf => return error.InvalidUtf8,
811 error.OutOfMemory => return error.OutOfMemory,
812 };
837813 }
838814 } else {
839815 const result = getEnvPosix(key) orelse return error.EnvironmentVariableNotFound;
......@@ -846,7 +822,6 @@ test "os.getEnvVarOwned" {
846822 debug.assertError(getEnvVarOwned(ga, "BADENV"), error.EnvironmentVariableNotFound);
847823}
848824
849
850825/// Caller must free the returned memory.
851826pub fn getCwdAlloc(allocator: *Allocator) ![]u8 {
852827 var buf: [MAX_PATH_BYTES]u8 = undefined;