| ... | ... | @@ -21,7 +21,6 @@ const assert = std.debug.assert; |
| 21 | 21 | const math = std.math; |
| 22 | 22 | const mem = std.mem; |
| 23 | 23 | const elf = std.elf; |
| 24 | | const unicode = std.unicode; |
| 25 | 24 | const dl = @import("dynamic_library.zig"); |
| 26 | 25 | const MAX_PATH_BYTES = std.fs.MAX_PATH_BYTES; |
| 27 | 26 | |
| ... | ... | @@ -1207,27 +1206,17 @@ pub fn getenvZ(key: [*:0]const u8) ?[]const u8 { |
| 1207 | 1206 | return getenv(mem.spanZ(key)); |
| 1208 | 1207 | } |
| 1209 | 1208 | |
| 1210 | | fn utf16LeAsciiEqlIgnoreCase(a: []const u16, b: []const u16) bool { |
| 1211 | | if (a.len != b.len) return false; |
| 1212 | | var a_it = unicode.Utf16LeIterator.init(a); |
| 1213 | | var b_it = unicode.Utf16LeIterator.init(b); |
| 1214 | | while (a_it.nextCodepoint() catch return false) |a_codepoint| { |
| 1215 | | const b_codepoint = (b_it.nextCodepoint() catch return false) orelse return false; |
| 1216 | | const upper_a = if (a_codepoint >= 97 and a_codepoint <= 122) a_codepoint & 0b11011111 else a_codepoint; |
| 1217 | | const upper_b = if (b_codepoint >= 97 and b_codepoint <= 122) b_codepoint & 0b11011111 else b_codepoint; |
| 1218 | | if (upper_a != upper_b) return false; |
| 1219 | | } |
| 1220 | | return true; |
| 1221 | | } |
| 1222 | | |
| 1223 | 1209 | /// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name. |
| 1224 | 1210 | /// See also `getenv`. |
| 1211 | /// This function first attempts a case-sensitive lookup. If no match is found, and `key` |
| 1212 | /// is ASCII, then it attempts a second case-insensitive lookup. |
| 1225 | 1213 | pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { |
| 1226 | 1214 | if (builtin.os.tag != .windows) { |
| 1227 | 1215 | @compileError("std.os.getenvW is a Windows-only API"); |
| 1228 | 1216 | } |
| 1229 | 1217 | const key_slice = mem.spanZ(key); |
| 1230 | 1218 | const ptr = windows.peb().ProcessParameters.Environment; |
| 1219 | var ascii_match: ?[:0]const u16 = null; |
| 1231 | 1220 | var i: usize = 0; |
| 1232 | 1221 | while (ptr[i] != 0) { |
| 1233 | 1222 | const key_start = i; |
| ... | ... | @@ -1241,11 +1230,22 @@ pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 { |
| 1241 | 1230 | while (ptr[i] != 0) : (i += 1) {} |
| 1242 | 1231 | const this_value = ptr[value_start..i :0]; |
| 1243 | 1232 | |
| 1244 | | if (utf16LeAsciiEqlIgnoreCase(key_slice, this_key)) return this_value; |
| 1233 | if (mem.eql(u16, key_slice, this_key)) return this_value; |
| 1234 | |
| 1235 | ascii_check: { |
| 1236 | if (ascii_match != null) break :ascii_check; |
| 1237 | if (key_slice.len != this_key.len) break :ascii_check; |
| 1238 | for (key_slice) |a_c, key_index| { |
| 1239 | const a = math.cast(u8, a_c) catch break :ascii_check; |
| 1240 | const b = math.cast(u8, this_key[key_index]) catch break :ascii_check; |
| 1241 | if (std.ascii.toLower(a) != std.ascii.toLower(b)) break :ascii_check; |
| 1242 | } |
| 1243 | ascii_match = this_value; |
| 1244 | } |
| 1245 | 1245 | |
| 1246 | 1246 | i += 1; // skip over null byte |
| 1247 | 1247 | } |
| 1248 | | return null; |
| 1248 | return ascii_match; |
| 1249 | 1249 | } |
| 1250 | 1250 | |
| 1251 | 1251 | pub const GetCwdError = error{ |