ref: c62a377b27f8259a9270d95d02e8acbca21c2ac9
dir: /fmt.myr/
use "die.use" use "sys.use" use "types.use" use "utf.use" pkg std = const bfmt : (buf : byte[,], fmt : byte[,], args:... -> size) const put : (fmt : byte[,], args:... -> size) ;; const put = {fmt, args var buf : byte[2048] var n n = bfmt(buf[0,2048], fmt, args) write(1, buf[0,n]) -> n } const bfmt = {buf, fmt, args var c var n var ap var i_val; var s_val; n = 0 ap = &args castto(byte*) while fmt.len (c, fmt) = striter(fmt) if c == '%' (c, fmt) = striter(fmt) match c 's': ap = align(ap, sizeof(void*)) s_val = *(ap castto(byte[,]*)) n += strfmt(buf[n, buf.len], s_val) ap = add(ap, sizeof(byte[,])) ;; /* format integers */ 'b': ap = align(ap, sizeof(int8)); i_val = *(ap castto(int8*)) castto(int64) n += intfmt(buf[n, buf.len], i_val, 10) ap = add(ap, sizeof(int8)) ;; /* 'w': ap = align(ap, sizeof(int16)); i_val = *(ap castto(int16*)) castto(int64) n += intfmt(buf[n, buf.len], i_val, 10) ap = add(ap, sizeof(int16)) ;; */ 'i': ap = align(ap, sizeof(int32)); i_val = *(ap castto(int32*)) castto(int64) n += intfmt(buf[n, buf.len], i_val, 10) ap = add(ap, sizeof(int32)) ;; 'l': ap = align(ap, sizeof(int64)); i_val = *(ap castto(int64*)) n += intfmt(buf[n, buf.len], i_val, 10) ap = add(ap, sizeof(int64)) ;; 'p': ap = align(ap, sizeof(byte*)); i_val = *(ap castto(int64*)) strfmt(buf[n,buf.len], "0x") n += intfmt(buf[n, buf.len], i_val, 16) ap = add(ap, sizeof(byte*)) ;; ;; else n += encode(buf[n,buf.len], c) ;; ;; -> n } const strfmt = {buf, str var i for i = 0; i < min(str.len, buf.len); i++ buf[i] = str[i] ;; -> i } const intfmt = {buf, val, base var digits = [ '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' ] var b : char[32] var i var j var n n = 0 i = 0 if val < 0 b[i] = '-' i++ ;; while val != 0 b[i] = digits[val % base] val /= base i++ ;; n = 0 for j = i-1; j >= 0; j-- n += encode(buf[n,buf.len], b[j]) ;; -> n } const min = {a : size, b : size if a < b -> a else -> b ;; } const align = {p, align var v v = p castto(intptr) v = (v + align - 1) & ~(align - 1) -> v castto(byte*) } const add = {p, sz -> ((p castto(intptr)) + sz) castto(byte*) }