shithub: mc

Download patch

ref: 68b11241dc9da7153cfcae2218c11e0b1b545d88
parent: ec0c5068657881478c4c4959dd072e463ffd493f
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Dec 28 19:10:27 EST 2014

Slightly more sophisticated system filtering.

--- a/Makefile
+++ b/Makefile
@@ -5,6 +5,7 @@
 	clean.myr \
 	config.myr \
 	deps.myr \
+	fsel.myr \
 	install.myr \
 	main.myr \
 	opts.myr \
--- a/bldfile
+++ b/bldfile
@@ -3,7 +3,11 @@
 	build.myr
 	clean.myr
 	config.myr
+	config+posixy.myr
+	config+plan9.myr
+	config+posixy-x64.myr
 	deps.myr
+	fsel.myr
 	install.myr
 	main.myr
 	opts.myr
--- /dev/null
+++ b/fsel.myr
@@ -1,0 +1,104 @@
+use std
+
+use "opts.use"
+
+pkg bld =
+	type fsel = struct
+		filematch	: std.htab(byte[:], int)#
+		filebest	: std.htab(byte[:], byte[:])#
+		sysattrs	: std.htab(byte[:], bool)#
+	;;
+
+	const mkfsel	: (-> fsel#)
+	const fseladd	: (fsel : fsel#, file : byte[:] -> void)
+	const fselfin	: (fsel : fsel# -> byte[:][:])
+;;
+
+const mkfsel = {
+	var fsel
+
+	fsel = std.alloc()
+	fsel.filematch = std.mkht(std.strhash, std.streq)
+	fsel.filebest = std.mkht(std.strhash, std.streq)
+	fsel.sysattrs = std.mkht(std.strhash, std.streq)
+	addsysattrs(fsel.sysattrs)
+	-> fsel
+}
+
+const fseladd = {fsel, f
+	var basename, attrs
+	var nmatch, curbest
+	var attrlist
+
+	match std.strfind(f, "+")
+	| `std.Some i:
+		basename = f[:i]
+		match std.strrfind(f[i+1:], ".")
+		| `std.Some j:	attrs = f[i+1:][:j]
+		| `std.None:	std.fatal(1, "unrecognized type for file %s\n", f)
+		;;
+	| `std.None:
+		match std.strrfind(f, ".")
+		| `std.None:	std.fatal(1, "unrecognized type for file %s\n", f)
+		| `std.Some i:
+			basename = f[:i]
+			attrs = ""
+		;;
+	;;
+
+	nmatch = 0
+	attrlist = std.strsplit(attrs, "-")
+	for a in attrlist
+		if std.hthas(fsel.sysattrs, a)
+			nmatch++
+		else
+			nmatch = -1
+			break
+		;;
+	;;
+	std.slfree(attrlist)
+	curbest = std.htgetv(fsel.filematch, basename, -1)
+	if curbest < nmatch
+		std.htput(fsel.filematch, basename, nmatch)
+		std.htput(fsel.filebest, basename, f)
+	;;
+}
+
+const fselfin = {fsel
+	var keys, nmatch, ret
+
+	keys = std.htkeys(fsel.filematch)
+	ret = [][:]
+	for k in keys
+		nmatch = std.htgetv(fsel.filematch, k, -1)
+		if nmatch == -1
+			std.fatal(1, "no applicable file for '%s'\n", k)
+		;;
+		ret = std.slpush(ret, std.htgetv(fsel.filebest, k, ""))
+	;;
+	std.htfree(fsel.filematch)
+	std.htfree(fsel.filebest)
+	std.htfree(fsel.sysattrs)
+	-> ret
+}
+
+const addsysattrs = {sa
+	var attrs
+	match opt_sys
+	| "freebsd":	attrs = ["freebsd", "posixy"][:]
+	| "linux":	attrs = ["linux", "posixy"][:]
+	| "plan9":	attrs = ["plan9"][:]
+	| unknown:	std.fatal(1, "unknown system %s\n", unknown)
+	;;
+	for a in attrs
+		std.htput(sa, a, true)
+	;;
+
+	match opt_arch
+	| "x64":	attrs = ["x64"][:]
+	| unknown:	std.fatal(1, "unknown arch %s\n", unknown)
+	;;
+	for a in attrs
+		std.htput(sa, a, true)
+	;;
+}
--- a/parse.myr
+++ b/parse.myr
@@ -3,6 +3,7 @@
 use "types.use"
 use "util.use"
 use "opts.use"
+use "fsel.use"
 
 pkg bld =
 	const parse	: (p : parser#	-> bool)
@@ -73,8 +74,9 @@
 	| name attrlist = inputlist ';;'
 */
 const myrtarget = {p, targ
-	var name, inputs, libdeps, attrs
 	var ldscript, runtime, inst, incpath
+	var name, inputs, libdeps, attrs
+	var fsel
 
 	match word(p)
 	| `std.Some n:	name = n
@@ -98,13 +100,12 @@
 
 	match inputlist(p)
 	| `std.Some (wl, libs): 
-		inputs = [][:]
+		fsel = mkfsel()
 		libdeps = libs
 		for w in wl
-			if isplatform(w)
-				inputs = std.slpush(inputs, w)
-			;;
+			fseladd(fsel, w)
 		;;
+		inputs = fselfin(fsel)
 		std.slfree(wl)
 	| `std.None: failparse(p, "expected list of file names after '%s %s'\n", targ, name)
 	;;
--- a/util.myr
+++ b/util.myr
@@ -10,7 +10,6 @@
 	const swapsuffix	: (f : byte[:], suff : byte[:], newsuff : byte[:] -> byte[:])
 	const srcswapsuffix	: (f : byte[:], newsuff : byte[:] -> byte[:])
 	const strlistfree	: (sl : byte[:][:] -> void)
-	const isplatform	: (src : byte[:] -> bool)
 ;;
 
 const run = {cmd, dir
@@ -100,16 +99,6 @@
 	else
 		std.fatal(1, "unrecognized source %s\n", src)
 	;;
-}
-
-const isplatform = {src
-	var base, platf, suff
-
-	(base, platf, suff) = srcsplit(src)
-	-> platf.len == 0 || \
-		std.sleq(platf, sysarchstr) ||  \
-		std.sleq(platf, sysstr) ||  \
-		std.sleq(platf, archstr)
 }
 
 const strlistfree = {sl