ostify/src/main.zig

87 lines
2.7 KiB
Zig

const std = @import("std");
const fs = std.fs;
const mem = std.mem;
const TrackInfo = @import("trackinfo.zig");
const TrackMap = std.StringHashMap(TrackInfo);
fn parse_musicdef(allocator: mem.Allocator, tracks: *TrackMap, file: []const u8) !void {
var lumps = mem.tokenizeSequence(u8, file, "Lump ");
while (lumps.next()) |lump| {
// Parse lump and add it to the tracklist
const info = try TrackInfo.parseLump(allocator, lump);
try tracks.put(try allocator.dupe(u8, info.id), info);
}
}
pub fn main() !void {
// Get allocator
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
defer _ = gpa.deinit();
// Get args
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
if (args.len < 2) {
std.debug.print("Usage: {s} <path to extracted pk3>\n", .{args[0]});
std.process.exit(1);
}
// Extract folder from argv
const folder = args[1];
// Convert folder to absolute
const dir = try fs.cwd().openDir(folder, .{
.iterate = true,
});
// Prepare hashmap for storing song locations
var trackLocations = std.StringHashMap([]const u8).init(allocator);
defer trackLocations.deinit();
var trackInfos = TrackMap.init(allocator);
defer trackInfos.deinit();
var arenaAllocator = std.heap.ArenaAllocator.init(allocator);
defer arenaAllocator.deinit();
const keyAllocator = arenaAllocator.allocator();
// Iter through every file inside the directory (recursive)
var iter = try dir.walk(allocator);
defer iter.deinit();
while (try iter.next()) |entry| {
// Skip non-files
if (entry.kind != fs.File.Kind.file) {
continue;
}
// Remove extension
const extIndex = mem.indexOf(u8, entry.basename, ".");
const filename = if (extIndex) |index| entry.basename[0..index] else entry.basename;
// Check if it's a music definition file (and parse it if so)
if (mem.eql(u8, filename, "MUSICDEF")) {
const filedata = try dir.readFileAlloc(allocator, entry.path, 1048576);
defer allocator.free(filedata);
try parse_musicdef(keyAllocator, &trackInfos, filedata);
} else {
// Save file to hashmap of resolved files
try trackLocations.put(try keyAllocator.dupe(u8, filename), entry.path);
}
}
// Print detected songs
var tracks = trackInfos.valueIterator();
while (tracks.next()) |trackInfo| {
std.debug.print("- [{s}] {?s} ({?s}, {?s})\n", .{
trackInfo.id,
trackInfo.title,
trackInfo.author,
trackInfo.source,
});
}
}