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)
+ ;;
+
+}