ziggy stuff happened
This commit is contained in:
parent
57824afd87
commit
ff715db029
2 changed files with 112 additions and 6 deletions
48
src/main.zig
48
src/main.zig
|
@ -1,10 +1,25 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const fs = std.fs;
|
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 {
|
pub fn main() !void {
|
||||||
// Get allocator
|
// Get allocator
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
|
||||||
// Get args
|
// Get args
|
||||||
const args = try std.process.argsAlloc(allocator);
|
const args = try std.process.argsAlloc(allocator);
|
||||||
|
@ -19,12 +34,21 @@ pub fn main() !void {
|
||||||
const folder = args[1];
|
const folder = args[1];
|
||||||
|
|
||||||
// Convert folder to absolute
|
// Convert folder to absolute
|
||||||
const dir = try fs.cwd().openDir(folder, .{ .iterate = true });
|
const dir = try fs.cwd().openDir(folder, .{
|
||||||
|
.iterate = true,
|
||||||
|
});
|
||||||
|
|
||||||
// Prepare hashmap for storing song locations
|
// Prepare hashmap for storing song locations
|
||||||
var trackLocations = std.StringHashMap([]const u8).init(allocator);
|
var trackLocations = std.StringHashMap([]const u8).init(allocator);
|
||||||
defer trackLocations.deinit();
|
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)
|
// Iter through every file inside the directory (recursive)
|
||||||
var iter = try dir.walk(allocator);
|
var iter = try dir.walk(allocator);
|
||||||
defer iter.deinit();
|
defer iter.deinit();
|
||||||
|
@ -35,16 +59,28 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove extension
|
// Remove extension
|
||||||
const extIndex = std.mem.indexOf(u8, entry.basename, ".");
|
const extIndex = mem.indexOf(u8, entry.basename, ".");
|
||||||
const filename = if (extIndex) |index| entry.basename[0..index] else 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)
|
// Check if it's a music definition file (and parse it if so)
|
||||||
if (std.mem.eql(u8, filename, "MUSICDEF")) {
|
if (mem.eql(u8, filename, "MUSICDEF")) {
|
||||||
//TODO
|
const filedata = try dir.readFileAlloc(allocator, entry.path, 1048576);
|
||||||
|
defer allocator.free(filedata);
|
||||||
|
try parse_musicdef(keyAllocator, &trackInfos, filedata);
|
||||||
} else {
|
} else {
|
||||||
// Save file to hashmap of resolved files
|
// Save file to hashmap of resolved files
|
||||||
try trackLocations.put(filename, entry.path);
|
try trackLocations.put(try keyAllocator.dupe(u8, filename), entry.path);
|
||||||
}
|
}
|
||||||
std.debug.print("- {s}\n", .{filename});
|
}
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
70
src/trackinfo.zig
Normal file
70
src/trackinfo.zig
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const mem = std.mem;
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
const InfoKey = enum {
|
||||||
|
Title,
|
||||||
|
Author,
|
||||||
|
Source,
|
||||||
|
OriginalComposers,
|
||||||
|
};
|
||||||
|
|
||||||
|
const source_original = "Dr. Robotnik's Ring Racers";
|
||||||
|
|
||||||
|
allocator: mem.Allocator,
|
||||||
|
id: []const u8,
|
||||||
|
title: ?[]const u8,
|
||||||
|
author: ?[]const u8,
|
||||||
|
source: ?[]const u8,
|
||||||
|
originalComposers: ?[]const u8,
|
||||||
|
is_original: bool,
|
||||||
|
|
||||||
|
pub fn parseLump(allocator: mem.Allocator, lump: []const u8) !Self {
|
||||||
|
// Get lines
|
||||||
|
var lines = mem.tokenize(u8, lump, "\n");
|
||||||
|
|
||||||
|
// Next line is the ID, we need that ASAP!
|
||||||
|
const id = mem.trim(u8, lines.next().?, " \r");
|
||||||
|
var info = Self{
|
||||||
|
.allocator = allocator,
|
||||||
|
.id = try allocator.dupe(u8, id),
|
||||||
|
.title = null,
|
||||||
|
.author = null,
|
||||||
|
.source = null,
|
||||||
|
.originalComposers = null,
|
||||||
|
.is_original = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Read rest of lump and assign to fields in struct
|
||||||
|
while (lines.next()) |line| {
|
||||||
|
const sep = mem.indexOf(u8, line, "=");
|
||||||
|
if (sep) |sepIndex| {
|
||||||
|
const key = mem.trim(u8, line[0..sepIndex], " \r");
|
||||||
|
const val = mem.trim(u8, line[sepIndex + 1 ..], " \r");
|
||||||
|
const ownedVal = try allocator.dupe(u8, val);
|
||||||
|
const infoKey = std.meta.stringToEnum(InfoKey, key) orelse continue;
|
||||||
|
switch (infoKey) {
|
||||||
|
.Title => info.title = ownedVal,
|
||||||
|
.Author => info.author = ownedVal,
|
||||||
|
.Source => info.source = ownedVal,
|
||||||
|
.OriginalComposers => info.originalComposers = ownedVal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if it's an original work
|
||||||
|
if (info.source) |source| {
|
||||||
|
info.is_original = mem.eql(u8, source, source_original);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: Self) void {
|
||||||
|
self.allocator.free(self.id);
|
||||||
|
if (self.title) |ptr| self.allocator.free(ptr);
|
||||||
|
if (self.author) |ptr| self.allocator.free(ptr);
|
||||||
|
if (self.source) |ptr| self.allocator.free(ptr);
|
||||||
|
if (self.title) |ptr| self.allocator.free(ptr);
|
||||||
|
if (self.originalComposers) |ptr| self.allocator.free(ptr);
|
||||||
|
}
|
Loading…
Reference in a new issue