shithub: mc

Download patch

ref: da1de51de2edb383cc26a1b726df4cfc9328e1c7
parent: 8bd18e2d1caef67781ae69d761bdfca8d2bcf41d
parent: ea7fb6cca6d0fbe0f4f3f3ef269d97e76c488c27
author: Ori Bernstein <[email protected]>
date: Thu Dec 12 11:44:11 EST 2013

Merge branch 'master' of git+ssh://git.eigenstate.org/git/ori/mc

--- a/6/isel.c
+++ b/6/isel.c
@@ -353,22 +353,8 @@
 
 static void blit(Isel *s, Loc *to, Loc *from, size_t dstoff, size_t srcoff, size_t sz)
 {
-    AsmOp op;
     Loc *sp, *dp, *len; /* pointers to src, dst */
 
-    if (sz % 8 == 0) {
-        sz /= 8;
-        op = Irepmovsq;
-    } else if (sz % 4 == 0) {
-        sz /= 4;
-        op = Irepmovsl;
-    } else if (sz % 2 == 0) {
-        sz /= 2;
-        op = Irepmovsw;
-    } else {
-        op = Irepmovsb;
-    }
-
     len = loclit(sz, ModeQ);
     sp = inr(s, from);
     dp = inr(s, to);
@@ -385,7 +371,7 @@
         g(s, Ilea, locmem(dstoff, dp, NULL, ModeQ), locphysreg(Rrdi), NULL);
     else
         g(s, Imov, dp, locphysreg(Rrdi), NULL);
-    g(s, op, NULL);
+    g(s, Irepmovsb, NULL);
 }
 
 static Loc *gencall(Isel *s, Node *n)
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -11,8 +11,8 @@
     fmt.myr \
     hashfuncs.myr \
     htab.myr \
-    ipaddr.myr \
     intparse.myr \
+    ipparse.myr \
     now.myr \
     option.myr \
     optparse.myr \
@@ -23,7 +23,10 @@
     sldup.myr \
     sleq.myr \
     sljoin.myr \
+    slpush.myr \
     slurp.myr \
+    strsplit.myr \
+    strstrip.myr \
     strcmp.myr \
     sys.myr \
     types.myr \
--- a/libstd/alloc.myr
+++ b/libstd/alloc.myr
@@ -118,7 +118,7 @@
 
 	/* if the slice wouldn't change buckets, we don't need to realloc. */
 	if samebucket(sl.len * sizeof(@a), len * sizeof(@a))
-		-> sl
+		-> (sl castto(@a#))[:len]
 	;;
 
 	new = slalloc(len)
--- /dev/null
+++ b/libstd/ipparse.myr
@@ -1,0 +1,45 @@
+use "types.use"
+use "intparse.use"
+use "option.use"
+
+ /* FIXME: needed for decls which should be pulled in as hidden */
+use "strcmp.use"
+use "utf.use"
+use "fmt.use"
+
+pkg std =
+	const ip4parse	: (ip : byte[:] -> option(byte[4]))
+	const ip6parse	: (ip : byte[:] -> option(byte[16]))
+;;
+
+const ip4parse = {ip
+	var addr
+	var last : size
+	var x : option(int32)
+	var val : int32 /* need int32 to check for overflow */
+	var i
+	var j : size
+
+	i = 0
+	for j = 0; j < ip.len; j++
+		if ip[j] == '.' castto(byte)
+			put("seg[%z..%z] = %s\n", last, j, ip[last:j])
+			val = intparsebase(ip[last:j], 10)
+			if val < 0 || val > 255
+				-> `None
+			;;
+			addr[i++] = val castto(byte)
+			last = j + 1
+		;;
+	;;
+			put("seg[%z..%z] = %s\n", last, j, ip[last:j])
+	val = intparsebase(ip[last:j], 10)
+	if val < 0 || val > 255
+		-> `None
+	;;
+	addr[i] = val castto(byte)
+	if j != ip.len
+		-> `None
+	;;
+	-> `Some addr
+}
--- a/libstd/resolve.myr
+++ b/libstd/resolve.myr
@@ -3,7 +3,11 @@
 use "endian.use"
 use "error.use"
 use "fmt.use"
+use "option.use"
 use "slcp.use"
+use "slurp.use"
+use "strsplit.use"
+use "strstrip.use"
 use "sys.use"
 use "types.use"
 
@@ -12,37 +16,65 @@
 		`Badhost
 		`Badsrv
 		`Badquery
+		`Badresp
 	;;
 
+	type netaddr = union
+		`Ipv4	byte[4]
+		`Ipv6	byte[16]
+	;;
+
 	type hostinfo = struct
-		flags	: uint32
 		fam	: sockfam
 		stype	: socktype
+		ttl	: uint32
+		addr	: netaddr
+	/*
 		proto	: uint32
+		flags	: uint32
 		addr	: sockaddr[:]
 		canon	: byte[:]
 		next	: hostinfo#
+	*/
 	;;
 
-	const resolve	: (host : byte[:]	-> hostinfo#)
+	const resolve	: (host : byte[:]	-> error(hostinfo[:], resolveerr))
 ;;
 
-type dnshdr = struct
-	id	: uint16
-	/* {qr:1|op:4|aa:1|tc:1|rd:1|ra:1|z:3|rcode:4} */
-	flags	: uint16  
-	qdcnt	: uint16
-	ancnt	: uint16
-	nscnt	: uint16
-	arcnt	: uint16
-;;
+const Hostfile = "/etc/hosts"
 
 const resolve = {host : byte[:]
-	var hinf
+	match hostfind(host)
+	| `Some h:	-> h
+	| `None: 	-> dnsresolve(host)
+	;;
+}
 
-	hinf = zalloc()
-	dnsresolve(host)
-	-> hinf
+const hostfind = {host
+	-> `None
+	/*
+	var hdat
+	var lines
+	var ip
+	var hn
+	var str
+	var i
+
+	match slurp(Hostfile)
+	| `Success h:	hdat = h
+	| `Failure m:	-> `None
+	;;
+
+	lines = strsplit(hdat, "\n")
+	for i = 0; i < lines.len; i++
+		lines[i] = strstrip(lines[i])
+		(ip, str) = nextword(lines)
+		(hn, str) = nextword(str)
+		if streq(hn, host)
+			-> parseip(ip)
+		;;
+	;;
+	*/
 }
 
 const dnsresolve = {host : byte[:]
@@ -55,10 +87,7 @@
 	if (nsrv = dnsconnect()) < 0
 		-> `Failure (`Badsrv)
 	;;
-	if !dnsquery(nsrv, host)
-		-> `Failure (`Badquery)
-	;;
-	-> `Success true
+	-> dnsquery(nsrv, host)
 }
 
 const dnsconnect = {
@@ -71,7 +100,8 @@
 		put("Warning: Failed to open socket: %l\n", s)
 		-> -1
 	;;
-	/* hardcode Google DNS for now */
+	/* hardcode Google DNS for now.
+	FIXME: parse /etc/resolv.conf */
 	sa.fam = Afinet
 	sa.port = hosttonet(53) /* port 53 */
 	sa.addr = [8,8,8,8]	/* 8.8.8.8 */
@@ -84,10 +114,13 @@
 }
 
 const dnsquery = {srv, host
-	tquery(srv, host)
-	rquery(srv)
-	put("Unimplemented query: srv=%z, host=%s\n", srv, host)
-	-> false
+	var id
+	var r
+
+	id = tquery(srv, host)
+	r = rquery(srv, id)
+	put("Got hosts. Returning\n")
+	-> r
 }
 
 const Qr : uint16 = 1 << 0
@@ -96,14 +129,15 @@
 const Rd : uint16 = 1 << 7
 const Ra : uint16 = 1 << 8
 
-var nextid = 42
+var nextid : uint16 = 42
 const tquery = {srv, host
 	var pkt : byte[512] /* big enough */
 	var off : size
 
+	put("Sending request for %s\n", host)
 	/* header */
 	off = 0
-	off += pack16(pkt[:], off, nextid++)	/* id */
+	off += pack16(pkt[:], off, nextid)	/* id */
 	off += pack16(pkt[:], off, Ra)	/* flags */
 	off += pack16(pkt[:], off, 1)	/* qdcount */
 	off += pack16(pkt[:], off, 0)	/* ancount */
@@ -115,11 +149,11 @@
 	off += pack16(pkt[:], off, 0x1) /* qtype: a record */
 	off += pack16(pkt[:], off, 0x1) /* qclass: inet4 */
 
-	write(1, pkt[:off])
 	write(srv, pkt[:off])
+	-> nextid++
 }
 
-const rquery = {srv
+const rquery = {srv, id
 	var pktbuf : byte[1024]
 	var pkt
 	var n
@@ -130,10 +164,56 @@
 		put("Warning: Failed to read from %z: %i\n", srv, n)
 	;;
 	pkt = pktbuf[:n]
+	put("Got response:\n");
 	dumpresponse(pkt)
+	-> hosts(pkt, id)
 }
 
+const hosts = {pkt, id : uint16
+	var off
+	var v
+	var q
+	var a
+	var i
+	var hinf : hostinfo[:]
 
+	off = 0
+	/* parse header */
+	(v, off) = unpack16(pkt, off)	/* id */
+	if v != id
+		-> `Failure (`Badresp)
+	;;
+	put("Unpacking flags")
+	(v, off) = unpack16(pkt, off)	/* flags */
+	(q, off) = unpack16(pkt, off)	/* qdcount */
+	(a, off) = unpack16(pkt, off)	/* ancount */
+	(v, off) = unpack16(pkt, off)	/* nscount */
+	(v, off) = unpack16(pkt, off)	/* arcount */
+
+	/* skip past query records */
+	for i = 0; i < q; i++
+		put("Skipping query record")
+		off = skipname(pkt, off)	/* name */
+		(v, off) = unpack16(pkt, off)	/* type */
+		(v, off) = unpack16(pkt, off)	/* class */
+	;;
+
+	/* parse answer records */
+	hinf = slalloc(a castto(size))
+	for i = 0; i < a; i++
+		off = skipname(pkt, off)	/* name */
+		(v, off) = unpack16(pkt, off)	/* type */
+		(v, off) = unpack16(pkt, off)	/* class */
+		(hinf[i].ttl, off) = unpack32(pkt, off)	/* ttl */
+		(v, off) = unpack16(pkt, off)	/* rdatalen */
+		/* the thing we're interested in: our IP address */
+		hinf[i].addr = `Ipv4 [pkt[off], pkt[off+1], pkt[off+2], pkt[off+3]]
+		off += 4;
+	;;
+	-> `Success hinf
+}
+
+
 const dumpresponse = {pkt
 	var nquery
 	var nans
@@ -141,13 +221,8 @@
 	var v
 	var i
 
-	put("packet size = %z\n", pkt.len)
 	(v, off) = unpack16(pkt, 0)
-	put("hdr.id = %w\n", v)
 	(v, off) = unpack16(pkt, off)
-	put("hdr.rawflag = %i\n", (((v castto(uint32)) & 0xf000) >> 12))
-	put("hdr.flag = [Qr = %t, Aa = %t, Tc = %t, Rd = %t, Ra = %t]\n", (v&Qr) == 0, (v&Aa) == 0, (v&Tc) == 0, (v&Rd)==0, (v&Ra)==0)
-	put("hdr.rcode = %w\n", (v >> 11) & 0xf)
 	(nquery, off) = unpack16(pkt, off)
 	put("hdr.qdcount = %w\n", nquery)
 	(nans, off) = unpack16(pkt, off)
@@ -203,6 +278,21 @@
 	-> off
 }
 
+const skipname = {pkt, off
+	var sz
+
+	for sz = pkt[off] castto(size); sz != 0; sz = pkt[off] castto(size)
+		/* ptr is 2 bytes */
+		if sz & 0xC0 == 0xC0
+			-> off + 2
+		else
+			off += sz + 1
+		;;
+	;;
+	-> off + 1
+}
+
+
 const printname = {pkt, off
 	var sz
 
@@ -231,6 +321,16 @@
 	v = (buf[off] castto(uint16)) << 8
 	v |= (buf[off + 1] castto(uint16))
 	-> (v, off+sizeof(uint16))
+}
+
+const unpack32 = {buf, off
+	var v
+
+	v = (buf[off] castto(uint32)) << 24
+	v |= (buf[off+1] castto(uint32)) << 32
+	v |= (buf[off+2] castto(uint32)) << 8
+	v |= (buf[off+3] castto(uint32))
+	-> (v, off+sizeof(uint32))
 }
 
 const packname = {buf, off : size, host
--- /dev/null
+++ b/libstd/strsplit.myr
@@ -1,0 +1,29 @@
+use "alloc.use"
+use "die.use"
+use "extremum.use"
+use "fmt.use"
+use "slpush.use"
+use "sys.use"
+use "types.use"
+
+pkg std =
+	const strsplit	: (s : byte[:], delim : byte[:] -> byte[:][:])
+;;
+
+const strsplit = {s, delim
+	var i
+	var last
+	var sp
+
+	sp = [][:]
+	last = 0
+	assert(delim.len == 1, "FIXME: We should support strings as delimiters")
+	for i = 0; i < s.len; i++
+		if s[i] == delim[0]
+			sp = slpush(sp, s[last:i])
+			last = i + 1
+		;;
+	;;
+	-> sp
+}
+
--- /dev/null
+++ b/libstd/strstrip.myr
@@ -1,0 +1,44 @@
+use "types.use"
+use "utf.use"
+use "chartype.use"
+
+pkg std =
+	const strstrip	: (str : byte[:] -> byte[:])
+	const strfstrip	: (str : byte[:] -> byte[:])
+	const strrstrip	: (str : byte[:] -> byte[:])
+;;
+
+/* strip blanks from both head and tail of str */
+const strstrip = {str
+	-> strrstrip(strfstrip(str))
+}
+
+/* strip forward on str */
+const strfstrip = {str
+	var c
+	
+	for c = decode(str); isblank(c); c = decode(str)
+		str = str[charlen(c):]
+	;;
+	-> str
+
+}
+
+/* strip reverse on str */
+const strrstrip = {str
+	var i
+	var end
+
+	/* scan backwards for start of utf8 char */
+	end = 0
+	for i = str.len; i != 0; i--
+		if str[i] & 0x80 == 0
+			if !isspace(decode(str[i-1:]))
+				goto donestrip
+			;;
+			end = i - 1
+		;;
+	;;
+:donestrip
+	-> str[:end]
+}
--- a/mi/df.c
+++ b/mi/df.c
@@ -13,7 +13,28 @@
 #include "parse.h"
 #include "opt.h"
 
+/*
+static void nodeuse(Node *n, Bitset *bs)
+{
+}
+
+static void nodedef(Node *n, Bitset *bs)
+{
+}
+
+static void bbuse(Bb *bb, Bitset *bs)
+{
+}
+
+static void bbdef(Bb *bb, Bitset *bs)
+{
+}
+*/
+
 void flow(Cfg *cfg)
 {
 }
 
+void checkret(Cfg *cfg)
+{
+}
--- a/mi/opt.h
+++ b/mi/opt.h
@@ -3,6 +3,8 @@
 
 struct  Cfg {
     Bb **bb;
+    Bb *start;
+    Bb *end;
     size_t nbb;
 
     /* for building bb */
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -479,7 +479,7 @@
 
 size_t max(size_t a, size_t b);
 size_t min(size_t a, size_t b);
-size_t align(size_t sz, size_t align);
+size_t align(size_t sz, size_t a);
 
 /* suffix replacement */
 char *swapsuffix(char *buf, size_t sz, char *s, char *suf, char *swap);
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -526,7 +526,7 @@
             continue;
         if (c == '.')
             isfloat = 1;
-        else if (hexval(c) > base)
+        else if (hexval(c) < 0 || hexval(c) > base)
             fatal(line, "Integer digit '%c' outside of base %d", c, base);
     }
 
--- a/parse/util.c
+++ b/parse/util.c
@@ -375,8 +375,11 @@
         return b;
 }
 
-size_t align(size_t sz, size_t align)
+size_t align(size_t sz, size_t a)
 {
-    return (sz + align - 1) & ~(align - 1);
+    /* align to 0 just returns sz */
+    if (a == 0)
+        return sz;
+    return (sz + a - 1) & ~(a - 1);
 }
 
--- /dev/null
+++ b/test/data/strsplit-expected
@@ -1,0 +1,4 @@
+a
+b
+c
+d
--- /dev/null
+++ b/test/data/strstrip-expected
@@ -1,0 +1,15 @@
+"abc"
+"abc  "
+"  abc"
+--
+"世界"
+"世界  "
+"  世界"
+--
+""
+""
+""
+--
+""
+""
+""
--- a/test/match-badtypes.myr
+++ b/test/match-badtypes.myr
@@ -7,9 +7,7 @@
 */
 const foo = {
 	match 123
-	"asdf":	123
-		;;
-	234:	888
-		;;
+	|"asdf":	123
+	|234567:	888
 	;;
 }
--- a/test/matchmixed.myr
+++ b/test/matchmixed.myr
@@ -7,8 +7,8 @@
 
 const main = {
 	match "asdf"
-	`A:	std.put("Got a\n");;
-	`B:	std.put("Got b\n");;
+	| `A:	std.put("Got a\n")
+	| `B:	std.put("Got b\n")
 	;;
 	-> 42
 }
--- /dev/null
+++ b/test/strsplit.myr
@@ -1,0 +1,12 @@
+use std
+
+const main = {
+	var i
+	var sp
+
+	sp = std.strsplit("a,b,c,d", ",")
+	for i = 0; i < sp.len; i++
+		std.put("%s\n", sp[i])
+	;;
+	-> 0
+}
--- /dev/null
+++ b/test/strstrip.myr
@@ -1,0 +1,23 @@
+use std
+
+const main = {
+	std.put("\"%s\"\n", std.strstrip("  abc  "))
+	std.put("\"%s\"\n", std.strfstrip("  abc  "))
+	std.put("\"%s\"\n", std.strrstrip("  abc  "))
+
+	std.put("--\n")
+	std.put("\"%s\"\n", std.strstrip("  世界  "))
+	std.put("\"%s\"\n", std.strfstrip("  世界  "))
+	std.put("\"%s\"\n", std.strrstrip("  世界  "))
+
+	std.put("--\n")
+	std.put("\"%s\"\n", std.strstrip("    "))
+	std.put("\"%s\"\n", std.strfstrip("    "))
+	std.put("\"%s\"\n", std.strrstrip("    "))
+
+	std.put("--\n")
+	std.put("\"%s\"\n", std.strstrip(""))
+	std.put("\"%s\"\n", std.strfstrip(""))
+	std.put("\"%s\"\n", std.strrstrip(""))
+	-> 0
+}
--- a/test/tests
+++ b/test/tests
@@ -105,6 +105,8 @@
 B encodechar	P	1世界äa
 B strtab	C
 B catfile	C
+B strstrip	C
+B strsplit	C
 # B local-labels	E	10 ## BUGGERED
 F declmismatch
 F infermismatch