shithub: mc

Download patch

ref: 062038c04a1cb9b7b161b670c5a3a948aaed42d1
parent: a07a52d75ed87ab92e5985f553a41d8bbff11d24
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Jul 13 20:18:49 EDT 2015

Add support for system tags.

--- a/mbld/bld.sub
+++ b/mbld/bld.sub
@@ -5,11 +5,11 @@
 	config.myr	# config, as generated by the ./configure script
 	config+plan9-x64.myr	# config, as hardcoded for Plan 9
 	deps.myr
-	fsel.myr
 	install.myr
 	main.myr
 	opts.myr
 	parse.myr
+	syssel.myr
 	test.myr
         types.myr
 	util.myr
@@ -24,4 +24,3 @@
 ;;
 
 man = mbld.1;;
-
--- a/mbld/fsel.myr
+++ b/mbld/fsel.myr
@@ -7,17 +7,18 @@
 		file	: byte[:]
 		line	: int
 		targ	: byte[:]
-		sysattrs	: std.htab(byte[:], bool)#
+
+		_sysattrs	: std.htab(byte[:], bool)#
 		_match	: std.htab(byte[:], int)#
 		_best	: std.htab(byte[:], @a)#
 	;;
 
-	const mkfsel	: (f : byte[:], line : int, targ : byte[:] -> syssel(byte[:])#)
-	const fseladd	: (fsel : syssel(byte[:])#, file : byte[:] -> void)
-	const fselfin	: (fsel : syssel(byte[:])# -> byte[:][:])
+	generic mksyssel	: (f : byte[:], line : int, targ : byte[:] -> syssel(byte[:])#)
+	generic sysseladd	: (fsel : syssel(byte[:])#, file : byte[:] -> void)
+	generic sysselfin	: (fsel : syssel(byte[:])# -> byte[:][:])
 ;;
 
-const mkfsel = {file, line, targ
+generic mksyssel = {file, line, targ
 	var fsel
 
 	fsel = std.mk([
@@ -24,31 +25,32 @@
 		.file = file,
 		.line = line,
 		.targ = targ,
+
 		._match = std.mkht(std.strhash, std.streq),
 		._best = std.mkht(std.strhash, std.streq),
-		.sysattrs = std.mkht(std.strhash, std.streq),
+		._sysattrs = std.mkht(std.strhash, std.streq),
 	])
-	addsysattrs(fsel.sysattrs)
+	addsysattrs(fsel._sysattrs)
 	-> fsel
 }
 
-const fseladd = {fsel, f
+generic sysseladd = {fsel, f
 	var basename, attrs
 	var nmatch, curbest
-	var attrlist
+	var attrlist, i
 
 	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.Some idx:
+		basename = f[:idx]
+		match std.strrfind(f[idx+1:], ".")
+		| `std.Some j:	attrs = f[idx+1:][:j]
 		| `std.None:	std.fatal("unrecognized type for file {}\n", f)
 		;;
 	| `std.None:
 		match std.strrfind(f, ".")
 		| `std.None:	std.fatal("unrecognized type for file {}\n", f)
-		| `std.Some i:
-			basename = f[:i]
+		| `std.Some idx:
+			basename = f[:idx]
 			attrs = ""
 		;;
 	;;
@@ -55,8 +57,8 @@
 
 	nmatch = 0
 	attrlist = std.strsplit(attrs, "-")
-	for a in attrlist
-		if std.hthas(fsel.sysattrs, a)
+	for i = 0; i < attrlist.len; i++
+		if std.hthas(fsel._sysattrs, attrlist[i])
 			nmatch++
 		else
 			nmatch = -1
@@ -71,7 +73,7 @@
 	;;
 }
 
-const fselfin = {fsel
+generic sysselfin = {fsel
 	var keys, nmatch, ret
 
 	keys = std.htkeys(fsel._match)
@@ -85,7 +87,7 @@
 	;;
 	std.htfree(fsel._match)
 	std.htfree(fsel._best)
-	std.htfree(fsel.sysattrs)
+	std.htfree(fsel._sysattrs)
 	-> ret
 }
 
--- a/mbld/parse.myr
+++ b/mbld/parse.myr
@@ -3,7 +3,7 @@
 use "types.use"
 use "util.use"
 use "opts.use"
-use "fsel.use"
+use "syssel.use"
 
 pkg bld =
 	const load	: (b : build# -> bool)
@@ -20,11 +20,23 @@
 
 	/* extracted data for further parsing */
 	subdirs	: byte[:][:]
+	targsel	: syssel((byte[:], targ))#
 ;;
 
 const load = {b
-	var ok
-	ok = loadall(b, b.bldfile, "")
+	var ok, sel
+	var targs
+
+	sel = mksyssel("mbld", 0, "mbld")
+	ok = loadall(b, b.bldfile, "", sel)
+
+	targs = sysselfin(sel)
+	for (name, targ) in targs
+		b.all = std.slpush(b.all, name)
+		std.htput(b.targs, name, targ)
+	;;
+	std.slfree(targs)
+
 	if ok
 		ok = sortdeps(b)
 	;;
@@ -31,12 +43,12 @@
 	-> ok
 }
 
-const loadall = {b, path, dir
+const loadall = {b, path, dir, sel
 	var p : parser#
 	var subbld, subproj, ok
 	var curbase
 
-	p = mkparser(path, dir, b.basedir)
+	p = mkparser(path, dir, b.basedir, sel)
 	ok = bld.parse(b, p, "")
 	for sub in p.subdirs
 		subbld = std.pathcat(sub, "bld.sub")
@@ -46,7 +58,7 @@
 		build root.
 		*/
 		if std.fexists(subbld)
-			loadall(b, subbld, sub)
+			loadall(b, subbld, sub, sel)
 		/*
 		bld.proj reroots the project -- @/
 		is relative to the most recent bld.proj
@@ -55,7 +67,7 @@
 		elif std.fexists(sub)
 			curbase = b.basedir
 			b.basedir = sub
-			loadall(b, subproj, sub)
+			loadall(b, subproj, sub, sel)
 			b.basedir = curbase
 		else
 			std.fatal("could not open {} or {} \n", subbld, subproj)
@@ -67,6 +79,24 @@
 	-> ok
 }
 
+const mkparser = {path, dir, basedir, sel
+	var p
+
+	p = std.mk([
+		.line = 1,
+		.fname = std.sldup(path),
+		.fdir = std.sldup(dir),
+		.basedir = std.sldup(basedir),
+		.targsel = sel,
+	])
+	match std.slurp(path)
+	| `std.Ok d:	p.data = d
+	| `std.Fail _:	std.fatal("could not open '{}'\n", path)
+	;;
+	p.rest = p.data
+	-> p
+}
+
 const sortdeps = {b
 	var looped
 	var marked
@@ -111,22 +141,6 @@
 	;;
 }
 
-const mkparser = {path, dir, basedir
-	var p
-
-	p = std.zalloc()
-	p.line = 1
-	p.fname = std.sldup(path)
-	p.fdir = std.sldup(dir)
-	p.basedir = std.sldup(basedir)
-	match std.slurp(path)
-	| `std.Ok d:	p.data = d
-	| `std.Fail _:	std.fatal("could not open '{}'\n", path)
-	;;
-	p.rest = p.data
-	-> p
-}
-
 const freeparser = {p
 	std.slfree(p.fname)
 	std.slfree(p.fdir)
@@ -181,7 +195,7 @@
 const bintarget = {b, p
 	var t
 	t = myrtarget(p, "bin")
-	addtarg(p, b, t.name, `Bin t)
+	addtarg(p, b, t.name, t.systags, `Bin t)
 }
 
 /* libtarget: myrtarget */
@@ -189,7 +203,7 @@
 	var t
 	t = myrtarget(p, "lib")
 	t.islib = true
-	addtarg(p, b, t.name, `Lib t)
+	addtarg(p, b, t.name, t.systags, `Lib t)
 }
 
 /* testtarget: myrtarget */
@@ -196,7 +210,7 @@
 const testtarget = {b, p
 	var t
 	t = myrtarget(p, "test")
-	addtarg(p, b, t.name, `Test t)
+	addtarg(p, b, t.name, t.systags, `Test t)
 }
 
 /* mantarget: anontarget */
@@ -207,7 +221,7 @@
 		.dir=std.sldup(p.fdir),
 		.pages=anontarget(p, "man")
 	])
-	addtarg(p, b, "__man__", `Man targ)
+	addtarg(p, b, "__man__", [][:], `Man targ)
 }
 
 /* subtarget : anontarget */
@@ -263,11 +277,12 @@
 
 	durable = false
 	deplist = [][:]
+	systags = [][:]
 	for elt in attrs
 		match elt
 		| ("durable", ""):	durable = true
 		| ("dep", depname):	deplist = std.slpush(deplist, depname)
-		| ("sys", tags):	systags = std.slpush(systags, tags)
+		| ("sys", tag):	systags = std.slpush(systags, tag)
 		| (attr, ""):
 			failparse(p, "attribute {} not valid on {} targets\n", attr, cmd)
 		| (attr, val):
@@ -285,10 +300,10 @@
 	])
 	for o in outlist
 		if iscmd
-			addtarg(p, b, o, `Cmd gt)
+			addtarg(p, b, o, gt.systags, `Cmd gt)
 		else
 			std.htput(b.gensrc, o, gt)
-			addtarg(p, b, o, `Gen gt)
+			addtarg(p, b, o, gt.systags, `Gen gt)
 		;;
 	;;
 }
@@ -324,12 +339,12 @@
 
 	match inputlist(p)
 	| `std.Some (wl, libs): 
-		fsel = mkfsel(p.fname, p.line, targ)
+		fsel = mksyssel(p.fname, p.line, targ)
 		libdeps = libs
 		for w in wl
-			fseladd(fsel, w)
+			sysseladd(fsel, w)
 		;;
-		inputs = fselfin(fsel)
+		inputs = sysselfin(fsel)
 		std.slfree(wl)
 	| `std.None: failparse(p, "expected list of file names after '{} {}'\n", targ, name)
 	;;
@@ -343,6 +358,7 @@
 	ldscript = ""
 	runtime = ""
 	incpath = [][:]
+	systags = [][:]
 	for elt in attrs
 		match elt
 		| ("ldscript", lds):	ldscript = std.sldup(lds)
@@ -349,7 +365,7 @@
 		| ("runtime", rt):	runtime = std.sldup(rt)
 		| ("inc", path):	incpath = std.slpush(incpath, std.sldup(path))
 		| ("noinst", ""):	inst = false
-		| ("sys", tags):	systags = std.slpush(systags, tags)
+		| ("sys", tag):	systags = std.slpush(systags, tag)
 		| (invalid, _):
 			std.fatal("{}: got invalid attr '{}'\n", targ, invalid)
 		;;
@@ -591,15 +607,11 @@
 	-> c
 }
 
-const addtarg = {p, b, name, targ
+const addtarg = {p, b, name, systags, targ
 	var tn
 
 	tn = std.fmt("{}:{}", p.fdir, name)
-	if std.hthas(b.targs, tn)
-		failparse(p, "duplicate target {}\n", tn)
-	;;
-	b.all = std.slpush(b.all, tn)
-	std.htput(b.targs, tn, targ)
+	sysseladdlist(p.targsel, tn, systags, (tn, targ))
 }
 
 const libpath = {p, libpath