summaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/bigint.myr14
-rw-r--r--lib/std/bitset.myr2
-rw-r--r--lib/std/blat.myr2
-rw-r--r--lib/std/bld.sub1
-rw-r--r--lib/std/bytealloc.myr39
-rw-r--r--lib/std/dir+plan9.myr2
-rw-r--r--lib/std/fltbits.myr6
-rw-r--r--lib/std/fltfmt.myr17
-rw-r--r--lib/std/fltparse.myr7
-rw-r--r--lib/std/fmt.myr2
-rw-r--r--lib/std/hashfuncs.myr81
-rw-r--r--lib/std/htab.myr8
-rw-r--r--lib/std/listen+plan9.myr175
-rw-r--r--lib/std/listen+posixy.myr34
-rw-r--r--lib/std/mkpath.myr8
-rw-r--r--lib/std/mktemp.myr32
-rw-r--r--lib/std/resolve+posixy.myr2
-rw-r--r--lib/std/slurp.myr2
-rw-r--r--lib/std/syswrap+plan9.myr6
-rw-r--r--lib/std/syswrap+posixy.myr5
-rw-r--r--lib/std/syswrap-ss+plan9.myr2
-rw-r--r--lib/std/test/bitset.myr6
-rw-r--r--lib/std/test/fmt.myr1
-rw-r--r--lib/std/test/hashfuncs.myr123
24 files changed, 484 insertions, 93 deletions
diff --git a/lib/std/bigint.myr b/lib/std/bigint.myr
index 45170dd..129890c 100644
--- a/lib/std/bigint.myr
+++ b/lib/std/bigint.myr
@@ -28,6 +28,7 @@ pkg std =
const bigdup : (a : bigint# -> bigint#)
const bigassign : (d : bigint#, s : bigint# -> bigint#)
const bigmove : (d : bigint#, s : bigint# -> bigint#)
+ const bigsteal : (d : bigint#, s : bigint# -> bigint#)
const bigparse : (s : byte[:] -> option(bigint#))
const bigclear : (a : bigint# -> bigint#)
const bigbfmt : (b : byte[:], a : bigint#, base : int -> size)
@@ -162,6 +163,12 @@ const bigmove = {d, s
-> d
}
+const bigsteal = {d, s
+ bigmove(d, s);
+ bigfree(s)
+ -> d
+}
+
const bigclear = {v
std.slfree(v.dig)
v.sign = 0
@@ -547,7 +554,7 @@ const bigdiv = {a : bigint#, b : bigint# -> bigint#
(q, r) = bigdivmod(a, b)
bigfree(r)
- -> bigmove(a, q)
+ -> bigsteal(a, q)
}
const bigmod = {a : bigint#, b : bigint# -> bigint#
@@ -555,7 +562,7 @@ const bigmod = {a : bigint#, b : bigint# -> bigint#
(q, r) = bigdivmod(a, b)
bigfree(q)
- -> bigmove(a, r)
+ -> bigsteal(a, r)
}
/* a /= b */
@@ -665,6 +672,7 @@ const bigdivmod = {a : bigint#, b : bigint# -> (bigint#, bigint#)
/* undo the biasing for remainder */
bigshri(u, shift)
trim(q)
+ bigfree(v)
-> (trim(q), trim(u))
}
@@ -698,7 +706,7 @@ const bigmodpow = {base, exp, mod
bigmul(base, base)
bigmod(base, mod)
;;
- -> bigmove(base, r)
+ -> bigsteal(base, r)
}
/* returns the number of leading zeros */
diff --git a/lib/std/bitset.myr b/lib/std/bitset.myr
index b173d87..afc66b4 100644
--- a/lib/std/bitset.myr
+++ b/lib/std/bitset.myr
@@ -30,7 +30,7 @@ pkg std =
const bsunion : (a : bitset#, b : bitset# -> void)
const bseq : (a : bitset#, b : bitset# -> bool)
const bsissubset : (a : bitset#, b : bitset# -> bool)
- const bshash : (a : bitset# -> uint32)
+ const bshash : (a : bitset# -> uint64)
type bsiter = struct
idx : size
diff --git a/lib/std/blat.myr b/lib/std/blat.myr
index c0e2b4b..f68f089 100644
--- a/lib/std/blat.myr
+++ b/lib/std/blat.myr
@@ -7,7 +7,7 @@ pkg std =
;;
const blat = {path, buf, perm
- match openmode(path, Ocreat|Owronly, perm)
+ match openmode(path, Ocreat|Owrite, perm)
| `Ok fd: -> fblat(fd, buf)
| `Err e: -> false
;;
diff --git a/lib/std/bld.sub b/lib/std/bld.sub
index b8ce9bc..a834dbb 100644
--- a/lib/std/bld.sub
+++ b/lib/std/bld.sub
@@ -108,6 +108,7 @@ lib std {inc=.} =
env+posixy.myr
errno+plan9.myr
listen+posixy.myr
+ listen+plan9.myr
resolve+plan9.myr
resolve+posixy.myr
wait+plan9.myr
diff --git a/lib/std/bytealloc.myr b/lib/std/bytealloc.myr
index 51c0a34..9b48acc 100644
--- a/lib/std/bytealloc.myr
+++ b/lib/std/bytealloc.myr
@@ -28,7 +28,7 @@ pkg std =
const Zslab = (0 : slab#)
const Zchunk = (0 : chunk#)
-const Slabsz = 4*MiB
+const Slabsz = 512*KiB
const Cachemax = 4
const Bktmax = 128*KiB /* a balance between wasted space and falling back to mmap */
const Pagesz = 4*KiB
@@ -71,7 +71,7 @@ const __init__ = {
}
const startalloctrace = {path
- match openmode(path, Owronly | Ocreat, 0o644)
+ match openmode(path, Owrite | Ocreat, 0o644)
| `Ok fd: tracefd = fd
| `Err e: -> void
;;
@@ -92,7 +92,7 @@ const zbytealloc = {sz
}
const tracealloc = {p, sz
- var stk : void#[13] /* [type, addr, sz, 10 stack slots] */
+ var stk : void#[23] /* [type, addr, sz, 10 stack slots] */
slfill(stk[:], (0 : void#))
stk[0] = (0 : void#)
@@ -123,6 +123,7 @@ const writealloctrace = {sl
const bytealloc = {sz
var bkt, p
+ sz += 8
if sz <= Bktmax
bkt = &buckets[bktnum(sz)]
lock(memlck)
@@ -142,7 +143,12 @@ const bytealloc = {sz
/* frees a blob that is 'sz' bytes long. */
const bytefree = {p, sz
var bkt
+ var v
+ if p == (0 : byte#)
+ -> void
+ ;;
+ v = ((p : size) + sz : uint32#)#
if trace
lock(memlck)
tracefree(p, sz)
@@ -253,7 +259,9 @@ const mkslab = {bkt
s = bkt.cache
bkt.cache = s.next
bkt.ncache--
+ -> s
;;
+
/*
tricky: we need power of two alignment, so we allocate double the
needed size, chop off the unaligned ends, and waste the address
@@ -308,13 +316,12 @@ const bktalloc = {bkt
b = s.freehd
s.freehd = b.next
s.nfree--
- if s.nfree == 0
+ if s.freehd == Zchunk
bkt.slabs = s.next
if s.next != Zslab
s.next.prev = Zslab
;;
;;
-
-> (b : byte#)
}
@@ -337,6 +344,16 @@ const bktfree = {bkt, m
s.prev = Zslab
bkt.slabs = s
elif s.nfree == bkt.nper - 1
+ /* unlink the slab from the list */
+ if s.next != Zslab
+ s.next.prev = s.prev
+ ;;
+ if s.prev != Zslab
+ s.prev.next = s.next
+ ;;
+ if bkt.slabs == s
+ bkt.slabs = s.next
+ ;;
/*
HACK HACK HACK: if we can't unmap, keep an infinite cache per slab size.
We should solve this better somehow.
@@ -345,17 +362,8 @@ const bktfree = {bkt, m
s.next = bkt.cache
s.prev = Zslab
bkt.cache = s
+ bkt.ncache++
else
- /* unlink the slab from the list */
- if s.next != Zslab
- s.next.prev = s.prev
- ;;
- if s.prev != Zslab
- s.prev.next = s.next
- ;;
- if bkt.slabs == s
- bkt.slabs = s.next
- ;;
/* we mapped 2*Slabsz so we could align it,
so we need to unmap the same */
freemem(s.head, Slabsz*2)
@@ -433,3 +441,4 @@ be a power of two.
const mtrunc = {m, align
-> ((m : intptr) & ~((align : intptr) - 1) : byte#)
}
+
diff --git a/lib/std/dir+plan9.myr b/lib/std/dir+plan9.myr
index e363662..82e301f 100644
--- a/lib/std/dir+plan9.myr
+++ b/lib/std/dir+plan9.myr
@@ -26,7 +26,7 @@ const diropen = {p
var fd
var dir
- match open(p, Ordonly)
+ match open(p, Oread)
| `Ok f: fd = f
| `Err e: -> `Err "couldn't open directory"
;;
diff --git a/lib/std/fltbits.myr b/lib/std/fltbits.myr
index f9afd7a..0d7169b 100644
--- a/lib/std/fltbits.myr
+++ b/lib/std/fltbits.myr
@@ -48,12 +48,12 @@ const flt32explode = {flt
bits = flt32bits(flt)
isneg = (bits >> 31) != 0 /* msb is sign bit */
- exp = (bits >> 22) & 0xff /* exp is in bits [23..30] */
- mant = bits & ((1 << 22) - 1) /* msb is in bits [0..22] */
+ exp = (bits >> 23) & 0xff /* exp is in bits [23..30] */
+ mant = bits & ((1 << 23) - 1) /* msb is in bits [0..22] */
/* add back the implicit bit if this is not a denormal */
if exp != 0
- mant |= 1 << 22
+ mant |= 1 << 23
else
exp = 1
;;
diff --git a/lib/std/fltfmt.myr b/lib/std/fltfmt.myr
index 71bb183..9b2e100 100644
--- a/lib/std/fltfmt.myr
+++ b/lib/std/fltfmt.myr
@@ -32,7 +32,7 @@ const flt32bfmt = {sb, val, mode, precision
var isneg, exp, mant
(isneg, mant, exp) = flt32explode(val)
- dragon4(sb, isneg, (mant : int64), (exp - 52 : int64), Fltbias, mode, precision)
+ dragon4(sb, isneg, (mant : int64), (exp - 23 : int64), Fltbias, mode, precision)
}
/*
@@ -52,10 +52,10 @@ const dragon4 = {sb, isneg, f, e, p, mode, cutoff
var k
var a, i
- /* if we have zero for the mantissa, we can return early */
if isneg
sbputs(sb, "-")
;;
+ /* if we have zero for the mantissa, we can return early */
if f == 0
sbputs(sb, "0.0")
-> void
@@ -63,12 +63,11 @@ const dragon4 = {sb, isneg, f, e, p, mode, cutoff
/* initialize */
roundup = false
- r = mkbigint(f)
- r = bigshli(r, max(e - p, 0))
+ u = mkbigint(0)
+ r = bigshli(mkbigint(f), max(e - p, 0))
s = bigshli(mkbigint(1), max(0, -(e - p)))
mm = bigshli(mkbigint(1), max((e - p), 0))
mp = bigdup(mm)
- u = mkbigint(0)
/* fixup: unequal gaps */
t = mkbigint(1)
@@ -224,10 +223,16 @@ const dragon4 = {sb, isneg, f, e, p, mode, cutoff
;;
;;
k--
-
while k >= -1
format(sb, 0, k--)
;;
+
+ bigfree(u)
+ bigfree(r)
+ bigfree(s)
+ bigfree(mm)
+ bigfree(mp)
+
}
const lowdig = {u
diff --git a/lib/std/fltparse.myr b/lib/std/fltparse.myr
index fcc97af..9836d1f 100644
--- a/lib/std/fltparse.myr
+++ b/lib/std/fltparse.myr
@@ -183,8 +183,8 @@ const fallback = {mant, exp, lim
while true
(xprime, rprime) = std.bigdivmod(u, v)
- std.bigmove(x, xprime)
- std.bigmove(r, rprime)
+ std.bigsteal(x, xprime)
+ std.bigsteal(r, rprime)
if k == lim.minexp
if std.biggei(x, lim.minsig) && std.biglei(x, lim.maxsig)
break
@@ -193,7 +193,8 @@ const fallback = {mant, exp, lim
goto done
;;
elif k > lim.maxexp
- -> std.flt64inf()
+ f = std.flt64inf()
+ goto done
;;
if std.biglti(x, lim.minsig)
std.bigmuli(u, 2)
diff --git a/lib/std/fmt.myr b/lib/std/fmt.myr
index 11268e4..08b814d 100644
--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -481,11 +481,13 @@ const intparams = {params
]
opts = parseparams(params, [
+ ("b", true),
("x", false),
("w", true),
("p", true)][:])
for o : opts
match o
+ | ("b", bas): ip.base = getint(bas, "fmt: base must be integer")
| ("x", ""): ip.base = 16
| ("w", wid): ip.padto = getint(wid, "fmt: width must be integer")
| ("p", pad): ip.padfill = decode(pad)
diff --git a/lib/std/hashfuncs.myr b/lib/std/hashfuncs.myr
index 3046377..da47215 100644
--- a/lib/std/hashfuncs.myr
+++ b/lib/std/hashfuncs.myr
@@ -1,30 +1,32 @@
use "alloc"
use "chartype"
use "die"
+use "getint"
use "sleq"
use "slpush"
use "types"
use "utf"
pkg std =
- const strhash : (s : byte[:] -> uint32)
+ const strhash : (s : byte[:] -> uint64)
const streq : (a : byte[:], b : byte[:] -> bool)
- const strcasehash : (s : byte[:] -> uint32)
+ const strcasehash : (s : byte[:] -> uint64)
const strcaseeq : (a : byte[:], b : byte[:] -> bool)
- generic ptrhash : (p : @a# -> uint32)
+ generic ptrhash : (p : @a# -> uint64)
generic ptreq : (a : @a#, b : @a# -> bool)
- generic inthash : (v : @a::(integral,numeric) -> uint32)
+ generic inthash : (v : @a::(integral,numeric) -> uint64)
generic inteq : (a : @a::(integral,numeric), b : @a::(integral,numeric) -> bool)
const murmurhash2 : (data : byte[:], seed : uint32 -> uint32)
+ const siphash24 : (data : byte[:], seed : byte[16] -> uint64)
- generic slhash : (sl : @a[:] -> uint32)
+ generic slhash : (sl : @a[:] -> uint64)
;;
-const Seed = 1234
+const Seed : byte[16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
generic slhash = {data : @a[:]
-> strhash(slbytes(data))
@@ -38,7 +40,7 @@ generic slbytes = {data : @a[:]
}
const strhash = {s
- -> murmurhash2(s, Seed)
+ -> siphash24(s, Seed)
}
const strcaseeq = {a, b
@@ -66,7 +68,7 @@ const strcasehash = {s
(c, s) = std.strstep(s)
std.slpush(&chars, std.tolower(c))
;;
- h = murmurhash2(slbytes(chars), Seed)
+ h = siphash24(slbytes(chars), Seed)
slfree(chars)
-> h
}
@@ -76,10 +78,7 @@ const streq = {a, b
}
generic ptrhash = {p : @a#
- var x
-
- x = (&p : byte#)
- -> murmurhash2(x[0:sizeof(@a#)], Seed)
+ -> inthash((p : intptr))
}
generic ptreq = {a, b
@@ -90,7 +89,7 @@ generic inthash = {v : @a::(integral,numeric)
var p
p = (&v : byte#)
- -> murmurhash2(p[0:sizeof(@a)], Seed)
+ -> siphash24(p[0:sizeof(@a)], Seed)
}
generic inteq = {a, b
@@ -141,3 +140,59 @@ const murmurhash2 = {data, seed
-> h
}
+
+const sipround = {v0, v1, v2, v3 -> (uint64, uint64, uint64, uint64)
+ v0 += v1
+ v1 = (v1 << 13) | (v1 >> 51)
+ v1 ^= v0
+ v0 = (v0 << 32) | (v0 >> 32)
+ v2 += v3
+ v3 = (v3 << 16) | (v3 >> 48)
+ v3 ^= v2
+
+ v2 += v1
+ v1 = (v1 << 17) | (v1 >> 47)
+ v1 ^= v2
+ v2 = (v2 << 32) | (v2 >> 32)
+ v0 += v3
+ v3 = (v3 << 21) | (v3 >> 43)
+ v3 ^= v0
+
+ -> (v0, v1, v2, v3)
+}
+
+const siphash24 = {data, seed
+ var k0, k1, m, v0, v1, v2, v3, w
+ var tail : byte[8] = [0, 0, 0, 0, 0, 0, 0, 0]
+
+ k0 = std.getle64(seed[0:8])
+ k1 = std.getle64(seed[8:16])
+ v0 = k0 ^ 0x736f6d6570736575
+ v1 = k1 ^ 0x646f72616e646f6d
+ v2 = k0 ^ 0x6c7967656e657261
+ v3 = k1 ^ 0x7465646279746573
+ w = (data.len + 8) / 8 - 1
+ for var i = 0; i < w; i++
+ m = std.getle64(data[8 * i:8 * (i + 1)])
+ v3 ^= m
+ (v0, v1, v2, v3) = sipround(v0, v1, v2, v3)
+ (v0, v1, v2, v3) = sipround(v0, v1, v2, v3)
+ v0 ^= m
+ ;;
+ for var i = 0; i < data.len % 8; i++
+ tail[i] = data[8 * w + i]
+ ;;
+ tail[7] = (data.len % 256 : byte)
+ m = std.getle64(tail[:])
+ v3 ^= m
+ (v0, v1, v2, v3) = sipround(v0, v1, v2, v3)
+ (v0, v1, v2, v3) = sipround(v0, v1, v2, v3)
+ v0 ^= m
+
+ v2 ^= 0xff
+ (v0, v1, v2, v3) = sipround(v0, v1, v2, v3)
+ (v0, v1, v2, v3) = sipround(v0, v1, v2, v3)
+ (v0, v1, v2, v3) = sipround(v0, v1, v2, v3)
+ (v0, v1, v2, v3) = sipround(v0, v1, v2, v3)
+ -> v0 ^ v1 ^ v2 ^ v3
+}
diff --git a/lib/std/htab.myr b/lib/std/htab.myr
index ec4ce72..b728124 100644
--- a/lib/std/htab.myr
+++ b/lib/std/htab.myr
@@ -6,19 +6,19 @@ use "types"
pkg std =
type htab(@k, @v) = struct
- hash : (k : @k -> uint32)
+ hash : (k : @k -> uint64)
eq : (a : @k, b : @k -> bool)
nelt : size
ndead : size
keys : @k[:]
vals : @v[:]
- hashes : uint32[:]
+ hashes : uint64[:]
dead : bool[:]
;;
- generic mkht : (h : (k : @k -> uint32), eq : (a : @k, b : @k -> bool) -> htab(@k, @v)#)
- generic htinit : (ht : htab(@k, @v)#, h : (k : @k -> uint32), eq : (a : @k, b : @k -> bool) -> void)
+ generic mkht : (h : (k : @k -> uint64), eq : (a : @k, b : @k -> bool) -> htab(@k, @v)#)
+ generic htinit : (ht : htab(@k, @v)#, h : (k : @k -> uint64), eq : (a : @k, b : @k -> bool) -> void)
generic htfree : (ht : htab(@k, @v)# -> void)
generic htput : (ht : htab(@k, @v)#, k : @k, v : @v -> void)
generic htdel : (ht : htab(@k, @v)#, k : @k -> void)
diff --git a/lib/std/listen+plan9.myr b/lib/std/listen+plan9.myr
new file mode 100644
index 0000000..be82bcf
--- /dev/null
+++ b/lib/std/listen+plan9.myr
@@ -0,0 +1,175 @@
+use sys
+
+use "alloc"
+use "cstrconv"
+use "die"
+use "dirname"
+use "fmt"
+use "mk"
+use "option"
+use "result"
+use "sldup"
+use "strfind"
+use "syswrap"
+use "utf"
+
+
+pkg std =
+ type announce = struct
+ afd : fd
+ lpath : byte[:]
+ netdir : byte[:]
+ ;;
+
+ const announce : (ds : byte[:] -> result(announce#, byte[:]))
+ const aclose : (a : announce# -> void)
+ const accept : (a : announce# -> result(fd, byte[:]))
+;;
+
+const Maxpath = 256
+
+const announce = {ds
+ var a, abuf : byte[Maxpath]
+ var f, fbuf : byte[Maxpath]
+ var nbuf : byte[32]
+ var dir, ctl, n
+
+ /* announce */
+ match translate(ds, abuf[:], fbuf[:])
+ | `Err _: -> `Err "invalid dial string"
+ | `Ok (addr, file):
+ put("addr: {}, file: {}\n", addr, file)
+ a = addr
+ f = file
+ match strrfind(f, "/")
+ | `Some i: dir = i
+ | `None: -> `Err "invalid net dir"
+ ;;
+ ;;
+
+ match open(f, Ordwr)
+ | `Ok fd: ctl = fd
+ | `Err e: -> `Err "could not open ctl fd"
+ ;;
+
+ match read(ctl, nbuf[:])
+ | `Err e: ->`Err "unable to read ctl fd"
+ | `Ok nn:
+ n = fput(ctl, "announce {}", a)
+ if n <= 0
+ close(ctl)
+ -> `Err "writing announce"
+ ;;
+
+ -> `std.Ok mk([
+ .afd=ctl,
+ .lpath = fmt("{}/{}/listen", f[:dir], nbuf[:nn]),
+ .netdir = sldup(f[:dir]),
+ ])
+ ;;
+
+}
+
+const aclose = {a
+ slfree(a.netdir)
+ slfree(a.lpath)
+ close(a.afd)
+ free(a)
+}
+
+const accept = {a -> result(fd, byte[:])
+ var num, numbuf : byte[16]
+ var dat, datbuf : byte[Maxpath]
+ var lfd
+
+ match open(a.lpath, Ordwr)
+ | `Err e: -> `Err "could not open ctl"
+ | `Ok fd: lfd = fd
+ ;;
+
+ match read(lfd, numbuf[:])
+ | `Ok n: num = numbuf[:n]
+ | `Err e: -> `Err "could not accept"
+ ;;
+
+ dat = bfmt(datbuf[:], "{}/{}/data", a.netdir, num)
+ match open(dat, Ordwr)
+ | `Ok fd: -> `Ok fd
+ | `Err e: -> `Err "could not open data fd"
+ ;;
+}
+
+const translate = {ds, addrbuf, filebuf
+ var cs, csbuf : byte[Maxpath]
+ var r, rbuf : byte[Maxpath]
+ var netdir, rest
+ var addr, file
+
+ match strfind(ds, "!")
+ | `None: -> `Err void
+ | `Some sep:
+ if decode(ds[:sep]) == '#' || decode(ds[:sep]) == '/'
+ match strrfind(ds[:sep], "/")
+ | `None: -> `Err void
+ | `Some idx:
+ netdir = ds[:idx]
+ rest = ds[idx+1:]
+ ;;
+ else
+ netdir = "/net"
+ addr = ds
+ ;;
+ ;;
+
+ cs = bfmt(csbuf[:], "{}/cs", netdir)
+ match open(cs, Ordwr)
+ | `Err e: -> identtrans(rest, netdir, addrbuf, filebuf)
+ | `Ok fd:
+ match write(fd, addr)
+ | `Err e:
+ close(fd)
+ -> `Err void
+ | `Ok _:
+ ;;
+
+ seek(fd, 0, Seekset)
+ match read(fd, rbuf[:])
+ | `Err e:
+ close(fd)
+ -> `Err void
+ | `Ok n:
+ r = rbuf[:n]
+ ;;
+ close(fd)
+ ;;
+
+ put("cs returned: {}\n", r)
+ match strfind(r, " ")
+ | `None: -> `Err void
+ | `Some i:
+ addr = bfmt(addrbuf, "{}", r[i+1:])
+ if decode(r) == '/'
+ match strfind(r[:i], "/")
+ | `None: -> `Err void
+ | `Some 0: file = bfmt(filebuf, "{}{}", netdir, r[:i])
+ | `Some n: file = bfmt(filebuf, "{}{}", netdir, r[n+1:])
+ ;;
+ else
+ file = bfmt(filebuf, "{}/{}", netdir, r[:i])
+ ;;
+ ;;
+ -> `Ok (addr, file)
+}
+
+const identtrans = {ds, netdir, addrbuf, filebuf
+ var a, f
+
+ match strfind(ds, "!")
+ | `None:
+ -> `Err void
+ | `Some sep:
+ a = bfmt(addrbuf, "{}", ds[sep + 1:])
+ f = bfmt(filebuf, "{}/{}/clone", netdir, ds[:sep])
+ -> `Ok (a, f)
+ ;;
+}
diff --git a/lib/std/listen+posixy.myr b/lib/std/listen+posixy.myr
index be4456d..49d1054 100644
--- a/lib/std/listen+posixy.myr
+++ b/lib/std/listen+posixy.myr
@@ -5,6 +5,7 @@ use "chartype"
use "dialparse"
use "die"
use "endian"
+use "mk"
use "option"
use "resolve"
use "result"
@@ -16,9 +17,14 @@ use "syswrap"
use "utf"
pkg std =
- const announce : (ds : byte[:] -> result(fd, byte[:]))
- const listen : (sock : fd -> result(fd, byte[:]))
- const accept : (lfd : fd -> result(fd, byte[:]))
+ type announce = struct
+ lfd : fd
+ ;;
+
+ const announce : (ds : byte[:] -> result(announce#, byte[:]))
+ const aclose : (a : announce# -> void)
+
+ const accept : (a : announce# -> result(fd, byte[:]))
;;
const announce = {ds
@@ -31,6 +37,11 @@ const announce = {ds
;;
}
+const aclose = {a
+ close(a.lfd)
+ free(a)
+}
+
const announcesock = {proto, str
var sa4 : sys.sockaddr_in
var sa6 : sys.sockaddr_in6
@@ -80,7 +91,10 @@ const announcesock = {proto, str
if sys.bind(sock, sa, sz) < 0
-> `Err "failed to bind socket"
;;
- -> `Ok (sock : fd)
+ if sys.listen((sock : sys.fd), 10) < 0
+ -> `Err "unable to listen on socket"
+ ;;
+ -> `Ok mk([.lfd=(sock : fd)])
}
const announceunix = {path
@@ -106,23 +120,19 @@ const announceunix = {path
if sys.bind(sock, (&sa : sys.sockaddr#), sizeof(sys.sockaddr_un)) < 0
-> `Err "failed to bind address"
;;
- -> `Ok (sock : fd)
-
-}
-
-const listen = {sock : std.fd -> result(fd, byte[:])
if sys.listen((sock : sys.fd), 10) < 0
-> `Err "unable to listen on socket"
;;
- -> `Ok (sys.dup((sock : sys.fd)) : fd)
+ -> `Ok mk([.lfd=(sock : fd)])
+
}
-const accept = {lfd
+const accept = {a
var sa : sys.sockaddr_storage
var len : sys.size
var fd
- fd = sys.accept((lfd : sys.fd), (0 : sys.sockaddr#), (0 : sys.size#))
+ fd = sys.accept((a.lfd : sys.fd), (0 : sys.sockaddr#), (0 : sys.size#))
if fd < 0
-> `Err "unable to accept socket"
;;
diff --git a/lib/std/mkpath.myr b/lib/std/mkpath.myr
index 61e2a72..22d1d3d 100644
--- a/lib/std/mkpath.myr
+++ b/lib/std/mkpath.myr
@@ -10,9 +10,11 @@ const mkpath = {p
for var i = 0; i < p.len; i++
if p[i] == ('/' : byte) && i != 0
- st = mkdir(p[:i], 0o755)
- if st != 0 && st != Eexist
- -> st
+ if !fexists(p[:i])
+ st = mkdir(p[:i], 0o755)
+ if st != 0
+ -> st
+ ;;
;;
;;
;;
diff --git a/lib/std/mktemp.myr b/lib/std/mktemp.myr
index c5f06c8..bc1bf87 100644
--- a/lib/std/mktemp.myr
+++ b/lib/std/mktemp.myr
@@ -15,6 +15,8 @@ use "types"
pkg std =
const mktemp : (base : byte[:], opt : fdopt, mode : int64 -> std.result((fd, byte[:]), errno))
const mktempat : (dir : byte[:], base : byte[:], opt : fdopt, mode : int64 -> std.result((fd, byte[:]), errno))
+ const mkdtemp : (base : byte[:], mode : int64 -> std.result(byte[:], errno))
+ const mkdtempat : (dir : byte[:], base : byte[:], mode : int64 -> std.result(byte[:], errno))
const mktemppath : (base : byte[:] -> byte[:])
;;
@@ -51,6 +53,36 @@ const mktempat = {tmpdir, base, opt, mode
-> `Err Eexist
}
+const mkdtemp = {base, mode
+ var tmpdir
+
+ match std.getenv("TMPDIR")
+ | `std.Some d: tmpdir = d
+ | `std.None: tmpdir = "/tmp"
+ ;;
+
+ -> mkdtempat(tmpdir, base, mode)
+}
+
+const mkdtempat = {tmpdir, base, mode
+ var path
+
+ for var i = 0; i < Retries; i++
+ path = randpath(tmpdir, base)
+ match std.mkdir(path, mode)
+ | Enone:
+ -> `Ok path
+ | e:
+ if e != Eexist
+ std.slfree(path)
+ -> `Err e
+ ;;
+ ;;
+ std.slfree(path)
+ ;;
+ -> `Err Eexist
+}
+
const mktemppath = {base
var tmpdir, path
diff --git a/lib/std/resolve+posixy.myr b/lib/std/resolve+posixy.myr
index 06250d5..8fa8352 100644
--- a/lib/std/resolve+posixy.myr
+++ b/lib/std/resolve+posixy.myr
@@ -333,7 +333,7 @@ const rquery = {srv, host, id
pfd = [
[.fd=srv, .events=sys.Pollin, .revents=0]
][:]
- r = sys.poll(pfd[:], (std.now() - giveup : int)/1000)
+ r = sys.poll(pfd[:], (giveup - std.now() : int)/1000)
if r < 0
-> `Err `Badconn
elif r == 0
diff --git a/lib/std/slurp.myr b/lib/std/slurp.myr
index a966e4a..8e653f9 100644
--- a/lib/std/slurp.myr
+++ b/lib/std/slurp.myr
@@ -15,7 +15,7 @@ const Bufstart = 4096
const slurp = {path
var sl
- match open(path, Ordonly)
+ match open(path, Oread)
| `Err e: -> `Err e
| `Ok fd:
sl = fslurp(fd)
diff --git a/lib/std/syswrap+plan9.myr b/lib/std/syswrap+plan9.myr
index ddf37ab..9f0ccc9 100644
--- a/lib/std/syswrap+plan9.myr
+++ b/lib/std/syswrap+plan9.myr
@@ -27,8 +27,8 @@ pkg std =
const Failmem : byte# = (-1 : byte#)
- const Ordonly : fdopt = (sys.Ordonly : fdopt)
- const Owronly : fdopt = (sys.Owronly : fdopt)
+ const Oread : fdopt = (sys.Oread : fdopt)
+ const Owrite : fdopt = (sys.Owrite : fdopt)
const Ordwr : fdopt = (sys.Ordwr : fdopt)
const Otrunc : fdopt = (sys.Otrunc : fdopt)
const Ocexec : fdopt = (sys.Ocexec : fdopt)
@@ -198,7 +198,7 @@ const chdir = {path; -> sys.chdir(path) == 0}
const mkdir = {path, mode;
var fd
- fd = sys.create(path, sys.Ordonly, sys.Dmdir | (mode : int))
+ fd = sys.create(path, sys.Oread, sys.Dmdir | (mode : int))
if fd < 0
-> lasterr()
;;
diff --git a/lib/std/syswrap+posixy.myr b/lib/std/syswrap+posixy.myr
index 5766a00..f49f9b8 100644
--- a/lib/std/syswrap+posixy.myr
+++ b/lib/std/syswrap+posixy.myr
@@ -25,12 +25,13 @@ pkg std =
const Seekcur : whence = (sys.Seekcur : whence)
const Seekend : whence = (sys.Seekend : whence)
- const Ordonly : fdopt = (sys.Ordonly : fdopt)
- const Owronly : fdopt = (sys.Owronly : fdopt)
+ const Oread : fdopt = (sys.Ordonly : fdopt)
+ const Owrite : fdopt = (sys.Owronly : fdopt)
const Ordwr : fdopt = (sys.Ordwr : fdopt)
const Ocreat : fdopt = (sys.Ocreat : fdopt)
const Otrunc : fdopt = (sys.Otrunc : fdopt)
const Ocexec : fdopt = (sys.Ocloexec : fdopt)
+ const Oappend : fdopt = (sys.Oappend : fdopt)
const Odir : fdopt = (sys.Odir : fdopt)
/* fd stuff */
diff --git a/lib/std/syswrap-ss+plan9.myr b/lib/std/syswrap-ss+plan9.myr
index 96a2973..58a751a 100644
--- a/lib/std/syswrap-ss+plan9.myr
+++ b/lib/std/syswrap-ss+plan9.myr
@@ -22,7 +22,7 @@ const nanosleep = {nsecs
const bgetcwd = {buf
var fd
- fd = sys.open(".", sys.Ordonly)
+ fd = sys.open(".", sys.Oread)
if fd < 0
-> (fd : errno)
;;
diff --git a/lib/std/test/bitset.myr b/lib/std/test/bitset.myr
index 9112537..6936cba 100644
--- a/lib/std/test/bitset.myr
+++ b/lib/std/test/bitset.myr
@@ -49,11 +49,11 @@ const main = {
}],
[.name="hash", .fn={ctx
var bs = mkset([][:])
- testr.check(ctx, std.bshash(bs) == 2580988821, "wrong hash, got {}", std.bshash(bs))
+ testr.check(ctx, std.bshash(bs) == 0x726fdb47dd0e0e31, "wrong hash, got {}", std.bshash(bs))
std.bsput(bs, 123456)
- testr.check(ctx, std.bshash(bs) == 2020624217, "wrong hash, got {}", std.bshash(bs))
+ testr.check(ctx, std.bshash(bs) == 0x778abc1d7706143b, "wrong hash, got {}", std.bshash(bs))
std.bsdel(bs, 123456)
- testr.check(ctx, std.bshash(bs) == 2580988821, "wrong hash, got {}", std.bshash(bs))
+ testr.check(ctx, std.bshash(bs) == 0x726fdb47dd0e0e31, "wrong hash, got {}", std.bshash(bs))
std.bsfree(bs)
}]
][:])
diff --git a/lib/std/test/fmt.myr b/lib/std/test/fmt.myr
index 67ba2e4..5d0cfa8 100644
--- a/lib/std/test/fmt.myr
+++ b/lib/std/test/fmt.myr
@@ -62,6 +62,7 @@ const builtins = {
check("0x7b", "0x{x}", 123)
check("0.0", "{}", 0.0)
check("0.3", "{}", 0.3)
+ check("0.3", "{}", (0.3 : flt32))
check("1.0", "{}", 1.0)
check("100.0", "{}", 100.0)
check("666.91972", "{}", 666.91972)
diff --git a/lib/std/test/hashfuncs.myr b/lib/std/test/hashfuncs.myr
index d2b1161..f1684f9 100644
--- a/lib/std/test/hashfuncs.myr
+++ b/lib/std/test/hashfuncs.myr
@@ -1,24 +1,113 @@
use std
+use testr
const main = {
- var x, y: int
+ testr.run([
+ [.name="string hash and equality", .fn={ctx
+ testr.check(ctx, std.strhash("abc") == 0x5dbcfa53aa2007a5, "wrong hash\n")
+ testr.check(ctx, std.streq("abc\0def", "abc\0def"), "equal strings not equal\n")
+ testr.check(ctx, !std.streq("abc\0def", "abcdef"), "unequal strings are equal\n")
+ }],
+ [.name="case insensitive hash and equality", .fn={ctx
+ testr.check(ctx, std.strcasehash("abc") == std.strcasehash("AbC"), "wrong case insensitive hash\n")
+ testr.check(ctx, std.strcaseeq("abc", "AbC"), "equal case insensitive strings not equal")
+ testr.check(ctx, !std.strcaseeq("abc", "AbCd"), "unequal case insensitive strings equal")
+ }],
+ [.name="pointer equality", .fn={ctx
+ var x, y: int
+ /* can't sanely test ptrhash; it will change every time */
+ testr.check(ctx, std.ptreq(&x, &x), "equal pointers not equal")
+ testr.check(ctx, !std.ptreq(&x, &y), "unequal pointers are equal")
+ }],
+ [.name="int hash and equality", .fn={ctx
+ testr.check(ctx, std.inthash(123) == 0x5671db246859d5b6, "wrong int hash")
+ testr.check(ctx, std.inteq(123, 123), "equal integers not equal")
+ testr.check(ctx, !std.inteq(123, 456), "unequal integers are equal")
+ }],
+ [.name="murmurhash test", .fn={ctx
+ testr.check(ctx, std.murmurhash2("foobar", 1234) == 2203212445, "wrong murmurhash value")
+ }],
+ [.name="siphash test", .fn={ctx
+ siphashreferencetestvector(ctx)
+ }],
+ ][:])
- std.assert(std.strhash("abc") == 1241861192, "wrong hash\n")
- std.assert(std.streq("abc\0def", "abc\0def"), "equal strings not equal\n")
- std.assert(!std.streq("abc\0def", "abcdef"), "unstrings are equal\n")
-
- std.assert(std.strcasehash("abc") == std.strcasehash("AbC"), "wrong case insensitive hash\n")
- std.assert(std.strcaseeq("abc", "AbC"), "equal case insensitive strings not equal")
- std.assert(!std.strcaseeq("abc", "AbCd"), "unequal case insensitive strings equal")
-
- /* can't sanely test ptrhash; it will change every time */
- std.assert(std.ptreq(&x, &x), "equal pointers not equal")
- std.assert(!std.ptreq(&x, &y), "unequal pointers are equal")
-
- std.assert(std.inthash(123) == 3497506805, "wrong int hash")
- std.assert(std.inteq(123, 123), "equal integers not equal")
- std.assert(!std.inteq(123, 456), "unequal integers are equal")
+}
- std.assert(std.murmurhash2("foobar", 1234) == 2203212445, "wrong murmurhash value")
+const siphashtestvector : byte[8][64] = [
+ [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
+ [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
+ [ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
+ [ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
+ [ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
+ [ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
+ [ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
+ [ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
+ [ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
+ [ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
+ [ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
+ [ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
+ [ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
+ [ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
+ [ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
+ [ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
+ [ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
+ [ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
+ [ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
+ [ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
+ [ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
+ [ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
+ [ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
+ [ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
+ [ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
+ [ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
+ [ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
+ [ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
+ [ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
+ [ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
+ [ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
+ [ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
+ [ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
+ [ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
+ [ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
+ [ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
+ [ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
+ [ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
+ [ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
+ [ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
+ [ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
+ [ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
+ [ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
+ [ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
+ [ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
+ [ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
+ [ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
+ [ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
+ [ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
+ [ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
+ [ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
+ [ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
+ [ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
+ [ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
+ [ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
+ [ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
+ [ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
+ [ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
+ [ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
+ [ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
+ [ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
+ [ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
+ [ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
+ [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ],
+]
+const siphashreferencetestvector = {ctx
+ var key = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
+ var e, h, msg : byte[64]
+ for var i = 0; i < 64; i++
+ msg[i] = i
+ h = std.siphash24(msg[:i], key)
+ e = std.getle64(siphashtestvector[i][:])
+ testr.check(ctx, e == h, "wrong siphash value for entry {}: got {x}\n", i, h)
+ ;;
}