Last active
April 9, 2019 14:14
-
-
Save ljmccarthy/ef3e4e828a940812ae9d23f4d3713053 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const std = @import("std"); | |
use std.os.windows; | |
pub extern "kernel32" stdcallcc fn GetCommandLineW() LPWSTR; | |
pub extern "kernel32" stdcallcc fn LocalFree(hMem: *c_void) ?*c_void; | |
pub extern "shell32" stdcallcc fn CommandLineToArgvW(lpCmdLine: LPCWSTR, out_pNumArgs: *c_int) ?[*]LPWSTR; | |
pub const ArgIteratorWindows = struct { | |
index: usize, | |
count: usize, | |
raw: ?[*]LPWSTR, | |
pub const NextError = @typeOf(std.unicode.utf16leToUtf8Alloc).ReturnType.ErrorSet; | |
pub fn init() ArgIteratorWindows { | |
return initWithCmdLine(GetCommandLineW()); | |
} | |
pub fn initWithCmdLine(cmd_line: [*]const u16) ArgIteratorWindows { | |
var num_args: c_int = undefined; | |
var raw = CommandLineToArgvW(GetCommandLineW(), &num_args); | |
return ArgIteratorWindows{ | |
.index = 0, | |
.count = @intCast(usize, num_args), | |
.raw = raw, | |
}; | |
} | |
pub fn deinit(self: *ArgIteratorWindows) void { | |
if (self.raw != null) { | |
_ = LocalFree(@ptrCast(*c_void, self.raw)); | |
} | |
} | |
/// You must free the returned memory when done. | |
pub fn next(self: *ArgIteratorWindows, allocator: *std.mem.Allocator) ?(NextError![]u8) { | |
if (self.raw == null) { | |
return null; // error.OutOfMemory; | |
} | |
if (self.index == self.count) { | |
return null; | |
} | |
const arg = std.mem.toSlice(u16, self.raw.?[self.index]); | |
self.index += 1; | |
return std.unicode.utf16leToUtf8Alloc(allocator, arg); | |
} | |
pub fn skip(self: *ArgIteratorWindows) bool { | |
if (self.index == self.count) return false; | |
self.index += 1; | |
return true; | |
} | |
}; | |
fn printArgs(allocator: *std.mem.Allocator) !void { | |
const stdout = try std.io.getStdOut(); | |
var argsIter = ArgIteratorWindows.init(); | |
defer argsIter.deinit(); | |
while (argsIter.next(allocator)) |argOrError| { | |
var arg = try argOrError; | |
defer allocator.free(arg); | |
try stdout.write(arg); | |
try stdout.write("\n"); | |
} | |
} | |
pub fn main() !void { | |
var direct_allocator = std.heap.DirectAllocator.init(); | |
defer direct_allocator.deinit(); | |
var arena = std.heap.ArenaAllocator.init(&direct_allocator.allocator); | |
defer arena.deinit(); | |
try printArgs(&arena.allocator); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment