Lindenii Project Forge
Minor formatting cleanup
export type blob = struct { oid: oid, data: []u8, };
export fn blob_finish(b: blob) void = { free(b.data); };
export type commit = struct { oid: oid, tree: oid, parents: []oid, author: person, committer: person, message: []u8, // other raw headers? };
export fn commit_finish(c: commit) void = { free(c.parents); person_finish(c.author); person_finish(c.committer); free(c.message); };
use bytes; use crypto::sha256; use errors; use strconv; use strings; export type tree = struct { oid: oid, entries: []tree_entry, };
export fn tree_finish(t: tree) void = { for (let entry .. t.entries) { tree_entry_finish(entry); }; free(t.entries); }; export type tree_entry = struct { mode: u32, name: []u8, oid: oid, };
export fn tree_entry_finish(te: tree_entry) void = { free(te.name); }; export fn parse_tree(id: oid, body: []u8) (tree | errors::invalid | strconv::invalid | strconv::overflow | nomem) = { let entries: []tree_entry = []; let i = 0z; for (i < len(body)) { const sp = match (bytes::index(body[i..], ' ')) { case let j: size => yield j; case void => return errors::invalid; }; const mode_b = body[i .. i+sp]; i += sp + 1z; const nul = match (bytes::index(body[i..], 0u8)) { case let j: size => yield j; case void => return errors::invalid; }; const name_b = body[i .. i+nul]; i += nul + 1z; if (i + sha256::SZ > len(body)) return errors::invalid; let child: oid = [0...]; child[..] = body[i .. i+sha256::SZ]; i += sha256::SZ; const mode_s = strings::fromutf8_unsafe(mode_b); const mode = strconv::stou32(mode_s, strconv::base::OCT)?; const name = name_b[..]; append(entries, tree_entry { mode = mode, name = name, oid = child })!; }; return tree { oid = id, entries = entries }; };
export type object = (blob | tree | commit);
export fn object_finish(o: object) void = { match (o) { case let b: blob => blob_finish(b); case let t: tree => tree_finish(t); case let c: commit => commit_finish(c); }; };
export type person = struct { name: []u8, email: []u8, when: i64, ofs: i32, };
export fn person_finish(p: person) void = { free(p.name); free(p.email); };