shithub: mc

Download patch

ref: 340cbfe1d94aa8065191eac10aec2dbe3922c100
parent: cf94e8f3c050f869d11a985f7ac4a4d9a477a9e4
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Jun 18 14:02:09 EDT 2015

Fix and enable all fmt tests.

--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -321,7 +321,7 @@
 		match typedesc(desc)
 		| `Tybyte:
 			s_val = vanext(ap)
-			sbputs(sb, s_val)
+			strfmt(sb, s_val, params)
 		| _:
 			sbputs(sb, "slice[:]")
 		;;
@@ -349,12 +349,6 @@
 	;;
 }
 
-type intparams = struct
-	base	: size
-	padto	: size
-	padfill	: char
-;;
-
 const getparams = {fmt
 	var i
 
@@ -368,9 +362,15 @@
 	-> (fmt[:i], fmt[i+1:])
 }
 
+type intparams = struct
+	base	: size
+	padto	: size
+	padfill	: char
+;;
 
 const intparams = {params
 	var ip : intparams
+	var opts
 
 	ip = [
 		.base = 10,
@@ -378,29 +378,55 @@
 		.padto = 0
 	]
 
-	var pl = parseparams(params, [
+	opts = parseparams(params, [
 		("x", false),
 		("w", true),
 		("p", true)][:])
-	for p in pl
-		match p
+	for o in opts
+		match o
 		| ("x", ""):	ip.base = 16
-		| ("w", wid):	
-			/* would use get(), but that's a dep loop */
-			match std.intparse(wid)
-			| `Some w:	ip.padto = w;
-			| `None:	die("width was not number")
-			;;
-		| ("p", pad):
-			std.assert(pad.len == 1, "pad takes one character")
-			ip.padfill = decode(pad)
-		| _:
+		| ("w", wid):	ip.padto = getint(wid, "fmt: width must be integer")
+		| ("p", pad):	ip.padfill = decode(pad)
+		| _:	std.die("unreachable")
 		;;
 	;;
-	std.slfree(pl)
+	std.assert(ip.padto >= 0, "pad must be >= 0")
+	std.slfree(opts)
 	-> ip
 }
 
+const strfmt = {sb, str, params
+	var opts
+	var w, p, i
+	
+	p = ' '
+	w = 0
+	opts = parseparams(params, [
+		("w", true),
+		("p", true)][:])
+	for o in opts
+		match o
+		| ("w", wid):	w = getint(wid, "fmt: width must be integer")
+		| ("p", pad):	p = decode(pad)
+		| _:	std.die("unreachable")
+		;;
+	;;
+	std.assert(p >= 0, "pad must be >= 0")
+	std.slfree(opts)
+	for i = 0; i < w - graphemewidth(str); i++
+		sbputc(sb, p)
+	;;
+	sbputs(sb, str)
+}
+
+/*
+Hah. like we're going to put in the work to actually
+count graphemes.
+*/
+const graphemewidth = {str
+	-> str.len
+}
+
 const digitchars = [
 	'0','1','2','3','4',
 	'5','6','7','8','9',
@@ -466,3 +492,11 @@
 	-> len
 }
 
+
+/* would use std.get(), but that's a dependency loop */
+const getint = {s, msg
+	match std.intparse(s)
+	| `Some w:	-> w;
+	| `None:	die(msg)
+	;;
+}
--- a/libstd/test/fmt.myr
+++ b/libstd/test/fmt.myr
@@ -12,12 +12,10 @@
 }
 
 const main = {
-	/* FIXME: make these equivalents tested.
-	check("      abcd", "%10s", "abcd")
-	check("00000bdcae", "%010s", "bdcae")
-	check("abcdefghijkl", "%010s", "abcdefghijkl")
-	check("a", "%01s", "a")
-	*/
+	check("      abcd", "{w=10}", "abcd")
+	check("00000bdcae", "{p=0,w=10}", "bdcae")
+	check("abcdefghijkl", "{p=0,w=10}", "abcdefghijkl")
+	check("a", "{w=0,p=1}", "a")
 	check("        10", "{w=10}", 10)
 	check("0000000010", "{p=0,w=10}", 10)
 	check("4294967295", "{p=0,w=10}", -1 castto(uint))