Created
November 29, 2021 15:56
-
-
Save JeffreyVdb/6bcda6e79259b70a460030b664d922ee to your computer and use it in GitHub Desktop.
Prioritize paths
This file contains hidden or 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"); | |
const HashMap = std.HashMap; | |
const Allocator = std.mem.Allocator; | |
const StringHashMap = std.hash_map.StringHashMap; | |
const SinglyLinkedList = std.SinglyLinkedList; | |
pub fn main() !void { | |
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); | |
defer arena.deinit(); | |
const allocator = &arena.allocator; | |
const args = try std.process.argsAlloc(allocator); | |
defer std.process.argsFree(allocator, args); | |
var prioArgs = try readArgsIntoSet(allocator, args[1..]); | |
defer prioArgs.deinit(); | |
const stdout = std.io.getStdOut().writer(); | |
const osPaths = try getOSPaths(allocator); | |
const AL = AppendableLinkedList([]const u8); | |
var prioPaths = AL{}; | |
var windowsPaths = AL{}; | |
var otherPaths = AL{}; | |
var osPathIt = osPaths.first; | |
var dataSize: usize = 0; | |
while (osPathIt) |node| : (osPathIt = node.next) { | |
dataSize += node.data.len + 1; | |
if (prioArgs.getPtr(node.data)) |_| { | |
try prioPaths.append(allocator, node.data); | |
} else if (std.mem.startsWith(u8, node.data, "/mnt/c")) { | |
try windowsPaths.append(allocator, node.data); | |
} else { | |
try otherPaths.append(allocator, node.data); | |
} | |
} | |
const buffer = try allocator.alloc(u8, dataSize); | |
const pathLists = [_]AL{ prioPaths, otherPaths, windowsPaths }; | |
var index: usize = 0; | |
for (pathLists) |lst| { | |
var it = lst.linkedList.first; | |
while (it) |node| : (it = node.next) { | |
const dest = buffer[index..]; | |
std.mem.copy(u8, dest, node.data); | |
dest[node.data.len] = ':'; | |
index += node.data.len + 1; | |
} | |
} | |
_ = try stdout.print("{s}", .{buffer[0 .. buffer.len - 1]}); | |
} | |
fn AppendableLinkedList(comptime T: type) type { | |
return struct { | |
const L = SinglyLinkedList(T); | |
const Self = @This(); | |
linkedList: L = L{}, | |
lastNode: ?*L.Node = null, | |
pub fn append(self: *Self, allocator: *Allocator, v: T) !void { | |
var node = try allocator.create(L.Node); | |
node.data = v; | |
if (self.lastNode) |currentNode| { | |
currentNode.insertAfter(node); | |
} else { | |
self.linkedList.prepend(node); | |
} | |
self.lastNode = node; | |
} | |
}; | |
} | |
fn getOSPaths(allocator: *Allocator) !SinglyLinkedList([]const u8) { | |
const pathEnv = std.os.getenv("PATH").?; | |
const delim = [_]u8{std.fs.path.delimiter}; | |
var pathIter = std.mem.split(pathEnv, delim[0..]); | |
const L = SinglyLinkedList([]const u8); | |
var list = L{}; | |
var lastNode: *L.Node = undefined; | |
if (pathIter.next()) |path| { | |
var firstNode = try allocator.create(L.Node); | |
firstNode.data = path; | |
list.prepend(firstNode); | |
lastNode = firstNode; | |
} | |
while (pathIter.next()) |path| { | |
var newNode = try allocator.create(L.Node); | |
newNode.data = path; | |
lastNode.insertAfter(newNode); | |
lastNode = newNode; | |
} | |
return list; | |
} | |
fn readArgsIntoSet(allocator: *Allocator, args: [][]u8) !StringHashMap(void) { | |
var map = StringHashMap(void).init(allocator); | |
for (args) |arg| { | |
try map.put(arg, .{}); | |
} | |
return map; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment