Lindenii Project Forge
Warning: Due to various recent migrations, viewing non-HEAD refs may be broken.
/git/ident.ha (raw)
use bytes;
use errors;
use strings;
use strconv;
// Author/committer identity and its associated timestamp
// and timezone offset.
export type ident = struct {
name: []u8,
email: []u8,
when: i64,
ofs: i32,
};
// Frees resources associated with an [[ident]].
export fn ident_finish(p: ident) void = {
free(p.name);
free(p.email);
};
// Parses an [[ident]] from its canonical byte-slice representation.
fn parse_ident(
line: []u8,
) (ident | errors::invalid | strconv::invalid | strconv::overflow | nomem) = {
let mlt = bytes::index(line, '<');
if (mlt is void) {
return errors::invalid;
};
let lt = mlt: size;
let mgt_rel = bytes::index(line[lt + 1z..], '>');
if (mgt_rel is void) {
return errors::invalid;
};
let gt_rel = mgt_rel: size;
const gt = lt + 1z + gt_rel;
const name_b = line[..lt];
const email_b = line[lt + 1z .. gt];
let rest = line[gt + 1z..];
if (len(rest) == 0 || rest[0] != ' ') {
return errors::invalid;
};
rest = rest[1..];
let msp = bytes::index(rest, ' ');
if (msp is void) {
return errors::invalid;
};
let sp = msp: size;
const when_s = strings::fromutf8_unsafe(rest[..sp]);
const tz_b = rest[sp + 1z..];
if (len(tz_b) < 5) {
return errors::invalid;
};
const when = strconv::stoi64(when_s)?;
let sign: i32 = 1;
if (tz_b[0] == '-') {
sign = -1;
};
const hh = strconv::stou32(strings::fromutf8_unsafe(tz_b[1..3]), strconv::base::DEC)?;
const mm = strconv::stou32(strings::fromutf8_unsafe(tz_b[3..5]), strconv::base::DEC)?;
const mins: i32 = (hh: i32) * 60 + (mm: i32);
const ofs: i32 = sign * mins;
let name = alloc(name_b...)?;
let email = alloc(email_b...)?;
return ident { name = name, email = email, when = when, ofs = ofs };
};