shithub: mc

Download patch

ref: 6ae90fe67572c8feeee655abeb80d1e32aa587bd
parent: d3cad93205eb0f2e2dbbead396c2a976face45ba
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Oct 15 09:15:41 EDT 2015

Add case insensitive comparison functions.

--- a/lib/std/cmp.myr
+++ b/lib/std/cmp.myr
@@ -1,5 +1,7 @@
 use "extremum.use"
 use "types.use"
+use "utf.use"
+use "chartype.use"
 
 pkg std =
 	type order = union
@@ -11,8 +13,11 @@
 	generic numcmp	: (a : @a, b : @a -> order)
 	const strcmp	: (a : byte[:], b : byte[:] -> order)
 	const strncmp	: (a : byte[:], b : byte[:], n : size -> order)
+	const strcasecmp	: (a : byte[:], b : byte[:] -> order)
 ;;
 
+extern const put : (str : byte[:], args : ... -> int64)
+
 generic numcmp = {a, b
 	if a < b
 		-> `Before
@@ -42,7 +47,6 @@
 	else
 		-> `Equal
 	;;
-		
 }
 
 const strncmp = {a, b, n
@@ -49,5 +53,30 @@
 	a = a[:min(a.len, n)]
 	b = b[:min(b.len, n)]
 	-> strcmp(a, b)
+}
+
+
+const strcasecmp = {a, b
+	var ca, cb
+
+	while a.len > 0 && b.len > 0
+		(ca, a) = std.striter(a)
+		(cb, b) = std.striter(b)
+		ca = toupper(ca)
+		cb = toupper(cb)
+		std.put("{}, {}\n", ca, cb)
+		if ca < cb
+			-> `Before
+		elif ca > cb
+			-> `After
+		;;
+	;;
+	if a.len < b.len
+		-> `Before
+	elif a.len > b.len
+		-> `After
+	else
+		-> `Equal
+	;;
 }
 
--- a/lib/std/dial+posixy.myr
+++ b/lib/std/dial+posixy.myr
@@ -80,8 +80,6 @@
 		-> `Fail "missing proto"
 	elif host.len == 0
 		-> `Fail "missing host"
-	elif port.len == 0
-		-> `Fail "missing port"
 	;;
 
 	if sleq(proto, "net")
@@ -89,8 +87,14 @@
 	elif sleq(proto, "unix")
 		-> `Fail "net unix proto not yet supported\n"
 	elif sleq(proto, "tcp")
+		if port.len == 0
+			-> `Fail "missing port"
+		;;
 		socktype = sys.Sockstream
 	elif sleq(proto, "udp")
+		if port.len == 0
+			-> `Fail "missing port"
+		;;
 		socktype = sys.Sockdgram
 	;;
 
--- a/lib/std/hashfuncs.myr
+++ b/lib/std/hashfuncs.myr
@@ -68,7 +68,6 @@
 	h = murmurhash2(slbytes(chars), Seed)
 	slfree(chars)
 	-> h
-
 }
 
 const streq = {a, b
--- /dev/null
+++ b/lib/std/test/cmp.myr
@@ -1,0 +1,38 @@
+use std
+
+const main = {
+	expect(std.strcmp, "foo", "bar", `std.After)
+	expect(std.strcmp, "foo", "foo", `std.Equal)
+	expect(std.strcmp, "foo", "foos", `std.Before)
+	expect(std.strcmp, "Foo", "foos", `std.Before)
+
+	expect(std.strcasecmp, "FOo", "bar", `std.After)
+	expect(std.strcasecmp, "FOo", "Bar", `std.After)
+	expect(std.strcasecmp, "FOo", "FUCK", `std.Before)
+	expect(std.strcasecmp, "FOo", "fuck", `std.Before)
+	expect(std.strcasecmp, "FOo", "foo", `std.Equal)
+	expect(std.strcasecmp, "FOo", "foos", `std.Before)
+
+	expect(std.strcasecmp, "FOo", "bar", `std.After)
+	expect(std.strcasecmp, "FOo", "foo", `std.Equal)
+	expect(std.strcasecmp, "FOo", "foos", `std.Before)
+
+	expect(std.strcasecmp, "Γειά σας", "γειά σας", `std.Equal)
+	expect(std.strcasecmp, "γειά σας", "γειά σας", `std.Equal)
+	expect(std.strcasecmp, "γειά σας", "Γειά σας", `std.Equal)
+	expect(std.strcasecmp, "γειά", "Γειά σας", `std.Before)
+}
+
+const expect = {fn, a, b, e
+	var val
+
+	val = fn(a, b)
+	match (val, e)
+	| (`std.Before, `std.Before):	/* nothing */
+	| (`std.After, `std.After):	/* nothing */
+	| (`std.Equal, `std.Equal):	/* nothing */
+	| _:
+		std.fatal("cmp {}, {}: expected {}, got {}\n", a, b, e, val)
+	;;
+
+}