shithub: mc

Download patch

ref: ac965251351332f405c9e5390e00d436fa467ff4
parent: e024022f35c31fa7f9dd85eaeb6719c57d817aba
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Jun 7 05:27:06 EDT 2015

Add support for custom formatting.

--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -215,13 +215,13 @@
 			/* format specifiers */
 			match c
 			| 's':
-				(s_val, ap) = vanext(ap)
+				s_val = vanext(&ap)
 				n += strfmt(buf[n:], s_val, padto, padfill)
 			| 't':
-				(t_val, ap) = vanext(ap)
+				t_val = vanext(&ap)
 				n += boolfmt(buf[n:], t_val, padto, padfill)
 			| 'f':
-				(f_val, ap) = vanext(ap)
+				f_val = vanext(&ap)
 				b = buf[n:]
 				sb = mkbufsb(b)
 				flt64bfmt(sb, f_val, 0, b.len)
@@ -228,7 +228,7 @@
 				n += sb.len
 				strfmt(buf[n:], sbfin(sb), 0, ' ')
 			| 'F':
-				(F_val, ap) = vanext(ap)
+				F_val = vanext(&ap)
 				b = buf[n:]
 				sb = mkbufsb(b)
 				flt64bfmt(sb, F_val castto(flt64), 0, b.len)
@@ -237,45 +237,45 @@
 			/* format integers */
 			| 'b':
 				if signed
-					(b_val, ap) = vanext(ap)
+					b_val = vanext(&ap)
 					n += intfmt(buf[n:], b_val, base, signed, padto, padfill)
 				else
-					(ub_val, ap) = vanext(ap)
+					ub_val = vanext(&ap)
 					n += intfmt(buf[n:], ub_val, base, signed, padto, padfill)
 				;;
 			| 'w':
 				if signed
-					(w_val, ap) = vanext(ap)
+					w_val = vanext(&ap)
 					n += intfmt(buf[n:], w_val, base, signed, padto, padfill)
 				else
-					(uw_val, ap) = vanext(ap)
+					uw_val = vanext(&ap)
 					n += intfmt(buf[n:], uw_val, base, signed, padto, padfill)
 				;;
 			| 'i':
 				if signed
-					(i_val, ap) = vanext(ap)
+					i_val = vanext(&ap)
 					n += intfmt(buf[n:], i_val, base, signed, padto, padfill)
 				else
-					(ui_val, ap) = vanext(ap)
+					ui_val = vanext(&ap)
 					n += intfmt(buf[n:], ui_val, base, signed, padto, padfill)
 				;;
 			| 'l':
 				if signed
-					(l_val, ap) = vanext(ap)
+					l_val = vanext(&ap)
 					n += intfmt(buf[n:], l_val, base, signed, padto, padfill)
 				else
-					(ul_val, ap) = vanext(ap)
+					ul_val = vanext(&ap)
 					n += intfmt(buf[n:], ul_val, base, signed, padto, padfill)
 				;;
 
 			| 'z':
-				(z_val, ap) = vanext(ap)
+				z_val = vanext(&ap)
 				n += intfmt(buf[n:], z_val castto(int64), base, signed, padto, padfill)
 			| 'p':
-				(p_val, ap) = vanext(ap)
+				p_val = vanext(&ap)
 				n += intfmt(buf[n:], p_val castto(int64), 16, false, padto, padfill)
 			| 'c':
-				(c_val, ap) = vanext(ap)
+				c_val = vanext(&ap)
 				n += encode(buf[n:], c_val)
 			| '%':
 				n += encode(buf[n:], '%')
--- a/libstd/fmt2.myr
+++ b/libstd/fmt2.myr
@@ -3,7 +3,10 @@
 use "die.use"
 use "extremum.use"
 use "fltfmt.use"
+use "htab.use"
+use "hashfuncs.use"
 use "introspect.use"
+use "option.use"
 use "strbuf.use"
 use "syswrap-ss.use"
 use "syswrap.use"
@@ -17,25 +20,44 @@
 	/* write to fd */
 	const f2put	: (fmt : byte[:], args : ... -> size)
 	const f2fput	: (fd : fd, fmt : byte[:], args : ... -> size)
-	const f2putv	: (fmt : byte[:], ap : valist -> size)
-	const f2fputv	: (fd : fd, fmt : byte[:], ap : valist -> size)
+	const f2putv	: (fmt : byte[:], ap : valist# -> size)
+	const f2fputv	: (fd : fd, fmt : byte[:], ap : valist# -> size)
 
 	/* write to buffer */
 	const f2fmt	: (fmt : byte[:], args : ... -> byte[:])
-	const f2fmtv	: (fmt : byte[:], ap : valist -> byte[:])
+	const f2fmtv	: (fmt : byte[:], ap : valist# -> byte[:])
 	const f2bfmt	: (buf : byte[:], fmt : byte[:], args : ... -> byte[:])
-	const f2bfmtv	: (buf : byte[:], fmt : byte[:], ap : valist -> byte[:])
+	const f2bfmtv	: (buf : byte[:], fmt : byte[:], ap : valist# -> byte[:])
 
 	/* write to strbuf */
 	const f2sbfmt	: (buf : strbuf#, fmt : byte[:], args : ... -> size)
-	const f2sbfmtv	: (buf : strbuf#, fmt : byte[:], ap : valist -> size)
+	const f2sbfmtv	: (buf : strbuf#, fmt : byte[:], ap : valist# -> size)
 
+	/* add a formatter function */
+	const f2fmtinstall	: (ty : byte[:], \
+		fn : (sb : strbuf#, ap : valist#, opts : byte[:] -> void) \
+		-> void)
+
 	$noret const f2fatal	: (fmt : byte[:], args : ... -> void)
-	$noret const f2fatalv	: (fmt : byte[:], ap : valist -> void)
+	$noret const f2fatalv	: (fmt : byte[:], ap : valist# -> void)
 ;;
 
+var fmtmapinited : bool = false
+var fmtmap : htab(byte[:], (sb : strbuf#, ap : valist#, opts : byte[:] -> void))#
+
+const f2fmtinstall = {ty, fn
+	if !fmtmapinited
+		fmtmapinited = true
+		fmtmap = mkht(strhash, streq)
+	;;
+	htput(fmtmap, ty, fn)
+}
+
 const f2put = {fmt, args
-	-> f2fputv(1, fmt, vastart(&args))
+	var ap
+
+	ap = vastart(&args)
+	-> f2fputv(1, fmt, &ap)
 }
 
 const f2putv = {fmt, ap
@@ -43,7 +65,10 @@
 }
 
 const f2fput = {fd, fmt, args
-	-> f2fputv(fd, fmt, vastart(&args))
+	var ap
+
+	ap = vastart(&args)
+	-> f2fputv(fd, fmt, &ap)
 }
 
 const f2fputv = {fd, fmt, ap
@@ -56,7 +81,10 @@
 }
 
 const f2fmt = {fmt, args
-	-> f2fmtv(fmt, vastart(&args))
+	var ap
+
+	ap = vastart(&args)
+	-> f2fmtv(fmt, &ap)
 }
 
 const f2fmtv = {fmt, ap
@@ -68,7 +96,10 @@
 }
 
 const f2bfmt = {buf, fmt, args
-	-> f2bfmtv(buf, fmt, vastart(&args))
+	var ap
+
+	ap = vastart(&args)
+	-> f2bfmtv(buf, fmt, &ap)
 }
 
 const f2bfmtv = {buf, fmt, ap
@@ -80,15 +111,22 @@
 }
 
 const f2sbfmt = {sb, fmt, args
-	-> f2sbfmtv(sb, fmt, vastart(&args))
+	var ap
+
+	ap = vastart(&args)
+	-> f2sbfmtv(sb, fmt, &ap)
 }
 
 const f2sbfmtv = {sb, fmt, ap -> size
-	var c, params
+	var c, params, ty
 	var nfmt, nparams
 
 	nparams = ap.tc.nelt
 	nfmt = 0
+	if !fmtmapinited
+		fmtmapinited = true
+		fmtmap = mkht(strhash, streq)
+	;;
 	while fmt.len != 0
 		(c, fmt) = striter(fmt)
 		match c
@@ -108,8 +146,13 @@
 				die("too few params for fmt\n")
 			;;
 
-			ap = fallbackfmt(sb, params, vatype(ap), ap)
-
+			ty = vatype(ap)
+			match htget(fmtmap, ty)
+			| `Some func:
+				func(sb, ap, params)
+			| `None:
+				fallbackfmt(sb, params, ty, ap)
+			;;
 		| chr:
 			sbputc(sb, chr)
 		;;
@@ -121,7 +164,7 @@
 	-> sb.len
 }
 
-const fallbackfmt = {sb, params, tyenc, ap
+const fallbackfmt = {sb, params, tyenc, ap : valist# -> void
 	/* value types */
 	var t_val : bool
 	var b_val : int8, ub_val : uint8
@@ -145,7 +188,7 @@
 	| `Tyvoid:
 		sbputs(sb, "void")
 	| `Tybool:
-		(t_val, ap) = vanext(ap)
+		t_val = vanext(ap)
 		if t_val
 			sbputs(sb ,"true")
 		else
@@ -152,53 +195,53 @@
 			sbputs(sb, "false")
 		;;
 	| `Tychar:
-		(c_val, ap) = vanext(ap)
+		c_val = vanext(ap)
 		sbputc(sb, c_val)
 	| `Tyint8:
-		(b_val, ap) = vanext(ap)
+		b_val = vanext(ap)
 		intfmt(sb, intparams(params), true, b_val)
 	| `Tyint16:
-		(w_val, ap) = vanext(ap)
+		w_val = vanext(ap)
 		intfmt(sb, intparams(params), true, w_val)
 	| `Tyint:
-		(i_val, ap) = vanext(ap)
+		i_val = vanext(ap)
 		intfmt(sb, intparams(params), true, i_val)
 	| `Tyint32:
-		(i_val, ap) = vanext(ap)
+		i_val = vanext(ap)
 		intfmt(sb, intparams(params), true, i_val)
 	| `Tyint64:
-		(l_val, ap) = vanext(ap)
+		l_val = vanext(ap)
 		intfmt(sb, intparams(params), true, l_val)
 	| `Tylong:
-		(l_val, ap) = vanext(ap)
+		l_val = vanext(ap)
 		intfmt(sb, intparams(params), true, l_val)
 
 	| `Tybyte:
-		(ub_val, ap) = vanext(ap)
+		ub_val = vanext(ap)
 		intfmt(sb, intparams(params), false, ub_val)
 	| `Tyuint8:
-		(ub_val, ap) = vanext(ap)
+		ub_val = vanext(ap)
 		intfmt(sb, intparams(params), false, ub_val)
 	| `Tyuint16:
-		(w_val, ap) = vanext(ap)
+		w_val = vanext(ap)
 		intfmt(sb, intparams(params), false, uw_val)
 	| `Tyuint:
-		(i_val, ap) = vanext(ap)
+		i_val = vanext(ap)
 		intfmt(sb, intparams(params), false, ui_val)
 	| `Tyuint32:
-		(i_val, ap) = vanext(ap)
+		i_val = vanext(ap)
 		intfmt(sb, intparams(params), false, ui_val)
 	| `Tyuint64:
-		(l_val, ap) = vanext(ap)
+		l_val = vanext(ap)
 		intfmt(sb, intparams(params), false, ul_val)
 	| `Tyulong:
-		(l_val, ap) = vanext(ap)
+		l_val = vanext(ap)
 		intfmt(sb, intparams(params), false, ul_val)
 	| `Tyflt32:
-		(f32_val, ap) = vanext(ap)
+		f32_val = vanext(ap)
 		flt32bfmt(sb, f32_val, MNormal, 0)
 	| `Tyflt64:
-		(f64_val, ap) = vanext(ap)
+		f64_val = vanext(ap)
 		flt64bfmt(sb, f64_val, MNormal, 0)
 	| `Tyvalist:
 		sbputs(sb, "...")
@@ -205,7 +248,7 @@
 
 	/* compound types */
 	| `Typtr desc:
-		(p_val, ap) = vanext(ap)
+		p_val = vanext(ap)
 		sbputs(sb, "0x")
 		intfmt(sb, \
 			[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
@@ -213,13 +256,13 @@
 	| `Tyslice desc:
 		match typedesc(desc)
 		| `Tybyte:
-			(s_val, ap) = vanext(ap)
+			s_val = vanext(ap)
 			sbputs(sb, s_val)
 		| _:
 			sbputs(sb, "slice[:]")
 		;;
 	| `Tyfunc tc:
-		(p_val, ap) = vanext(ap)
+		p_val = vanext(ap)
 		sbputs(sb, "func{")
 		intfmt(sb, \
 			[.base=16, .padto=2*sizeof(void#), .padfill='0'], \
@@ -235,9 +278,8 @@
 	| `Tyunion namecursor:
 		sbputs(sb, "struct")
 	| `Tyname (name, desc):
-		ap = fallbackfmt(sb, params, desc, ap)
+		fallbackfmt(sb, params, desc, ap)
 	;;
-	-> ap
 }
 
 type intparams = struct
--- a/libstd/varargs.myr
+++ b/libstd/varargs.myr
@@ -7,9 +7,9 @@
 	type valist
 
 	const vastart	: (args : ...# -> valist)
-	const vatype	: (ap : valist -> byte[:])
-	const vaskip	: (ap : valist -> byte[:])
-	generic vanext	: (ap : valist -> (@a, valist))
+	const vatype	: (ap : valist# -> byte[:])
+	const vaskip	: (ap : valist# -> byte[:])
+	generic vanext	: (ap : valist# -> @a)
 ;;
 
 type valist = struct
@@ -55,7 +55,7 @@
 	-> tcpeek(&ap.tc)
 }
 
-generic vanext = {ap -> (@a, valist)
+generic vanext = {ap -> @a
 	var v : @a
 	var align
 	var p
@@ -83,5 +83,5 @@
 
 	/* only move on after we read through the value */
 	ap.args = ((p castto(intptr)) + sizeof(@a)) castto(byte#)
-	-> (v, ap)
+	-> v
 }