shithub: mc

ref: ed2bcb605e43881ebe854040f1e3e6f918ed9b26
dir: /lib/std/fmtfuncs.myr/

View raw version
use "alloc"
use "bigint"
use "bitset"
use "fmt"
use "introspect"
use "strbuf"
use "varargs"
use "ipparse"

pkg std =
;;

const __init__ = {
	var bigint : bigint#
	var bitset : bitset#
	var ipaddr : netaddr

	bigint = mkbigint(0)
	bitset = mkbs()
	fmtinstall(typeof(bigint), bigfmt)
	fmtinstall(typeof(bitset), bsfmt)
	fmtinstall(typeof(ipaddr), ipfmt)
	bigfree(bigint)
	bsfree(bitset)
}

const bigfmt = {sb, ap, opts
	var a, n, buf

	a = vanext(ap)
 	/*
	allocate a buffer guaranteed to be big enough.
	that's 
		2 + floor(nbits/(log_2(10)))
	or
		2 + a.dig.len * 32/3.32...
	or
		2 + a.dig.len * 10
	plus one for the - sign.
	*/
	buf = slalloc(3 + a.dig.len * 10)
	n = bigbfmt(buf, a, 10)
	sbputs(sb, buf[:n])
	slfree(buf)
}

const bsfmt = {sb, ap, opts
	var bs, sep

	bs = vanext(ap)
	sep = ""
	sbputs(sb, "bitset{")
	for var i = 0; i < bsmax(bs); i++
		if bshas(bs, i)
			sbfmt(sb, sep)
			sbfmt(sb, "{}", i)
			sep = ", "
		;;
	;;
	sbputs(sb, "}")
}

const ipfmt = {sb, ap, opts
	var ip : netaddr
	var sep = "" 

	ip = std.vanext(ap)
	match ip
	| `Ipv4 a:
		std.put("{}.{}.{}.{}", a[0], a[1], a[2], a[3])
	| `Ipv6 a:	
		sep = ""
		for var i = 0; i < 16; i += 2
			std.put("{}{w=2,p=0,x}{w=2,p=0,x}", sep, a[i+0], a[i+1])
			sep = ":"
		;;
	;;
}