From b4a4427b61eaa570f53ea7fbc232aa9cbf60b35f Mon Sep 17 00:00:00 2001 From: lufia Date: Sun, 19 May 2019 22:54:51 +0900 Subject: [PATCH] [WIP]add files to generate mkfiles on Plan 9 --- gen-mkfile.sh | 283 ++++++++++++++++++++++++++++++++++++++++++++++++++ plan9/defs | 14 +++ 2 files changed, 297 insertions(+) create mode 100644 gen-mkfile.sh create mode 100644 plan9/defs diff --git a/gen-mkfile.sh b/gen-mkfile.sh new file mode 100644 index 0000000000..8124ba571c --- /dev/null +++ b/gen-mkfile.sh @@ -0,0 +1,283 @@ +#!/bin/sh +# usage: gen-mkfiles.sh {lib|bin|include} Makefile.am +set -e + +if [ $# -ne 3 -a $# -ne 2 ]; then + echo "usage: $0 {lib|bin|include} Makefile.am" >&2 + exit 2 +fi + +target=$1 +wdir=`dirname $2` +recipe=`basename $2` + +cd $wdir +d=`git rev-parse --show-cdup`. +top_srcdir=`echo $d | sed 's!/\.$!!'` + +# Plan 9 isn't having /dev/stderr, instead it has /fd/2. +stderr=/dev/stderr +if [ -w /fd/2 ]; then + stderr=/fd/2 +fi + +# filename: current filename +# lineno: current line number of filename +# vars: variables defined in Makefile.am +# defs: variables defined in plan9/defs; these will appear in -D flag too +# ifblock: booleans of nested if-statement; will reverse an value when enter to else +# ifpos: index of last ifblock +awk <$recipe ' +BEGIN { + stderr = "'"$stderr"'" + target = "'"$target"'" + vars["top_srcdir"] = "'"$top_srcdir"'" + loaddefs(getvar("top_srcdir") "/plan9/defs") +} + +function loaddefs(file) { + while((getline s 0) + defs[s] = 1 + close(file) +} + +function fatal(msg) { + printf "%s:%d %s\n", filename, lineno, msg >stderr + exit(1) +} +function assign(name, op, value) { + if(op != "=" && op != "+=") + fatal(sprintf("unknown operator: %s %s %s", name, op, value)) + if(op == "=") + delete vars[name] + if(value == "") + return + + if(vars[name] == "") + vars[name] = value + else + vars[name] = vars[name] SUBSEP value +} +function expand(s, v) { + while(match(s, /\$\([a-zA-Z0-9_]+\)/)){ + v = substr(s, RSTART+2, RLENGTH-3) + s = substr(s, 1, RSTART-1) vars[v] substr(s, RSTART+RLENGTH) + } + return s +} +function getvar(name) { + return expand(vars[name]) +} +function getarray(name, a) { + return split(getvar(name), a, SUBSEP) +} +function iftrue( i,r) { + r = 1 + for(i = 1; i <= ifpos; i++) + r = r && ifblock[i] + return r +} +function eval(tokens, n, v,i) { + if(n == 2 && tokens[1] == "if"){ + ifpos++ + v = tokens[2] + if(v ~ /^!/){ + v = substr(v, 2) + ifblock[ifpos] = !(v in defs) + }else + ifblock[ifpos] = v in defs + }else if(n == 1 && tokens[1] == "else"){ + ifblock[ifpos] = !ifblock[ifpos] + }else if(n == 1 && tokens[1] == "endif"){ + ifpos-- + } + if(!iftrue()) + return + + if(n >= 2 && tokens[2] == "=" || tokens[2] == "+="){ + for(i = 3; i <= n; i++) + assign(tokens[1], tokens[2], tokens[i]) + return + } + if(n == 2 && tokens[1] == "include") + evalfile(expand(tokens[2])) +} + +# evalfile cannot handle nested include directive referenced with relative path. +function evalfile(file, s,a,i,n) { + while((getline s 0){ + n = split(s, a) + filename = file + lineno = ++i + eval(a, n) + } + close(file) +} +{ for(i = 1; i <= NF; i++) + a[i] = $i + filename = FILENAME + lineno = FNR + eval(a, NF) + next +} + +function aname(file) { + sub(/\.la$/, ".a", file) + return file +} +function varname(file, name) { + gsub(/\./, "_", file) + return file "_" name +} +function getarrayof(file, name, a, v) { + v = varname(file, name) + return getarray(v, a) +} +function merge(a, a1, n1, a2, n2, x,n,i) { + for(i = 1; i <= n1; i++) + x[a1[i]] = 1 + for(i = 1; i <= n2; i++) + x[a2[i]] = 1 + for(i in x) + a[++n] = i + return n +} +function append(a, n, name, a1,n1) { + n1 = getarray(name, a1) + return merge(a, a, n, a1, n1) +} +function join(a, bp, ep, i,s) { + for(i = bp; i <= ep; i++){ + if(s != "") + s = s " " + s = s a[i] + } + return s +} +function dirname(path, a,n) { + n = split(path, a, "/") + return join(a, 1, n-1) +} +function dirnames(a, n, r, i,x,s) { + for(i = 1; i <= n; i++){ + s = dirname(a[i]) + x[s] = 1 + } + n = 0 + for(s in x) + r[++n] = s + return n +} +function filter(a, n, path, r, i,u,s) { + gsub(/\/+$/, "", path) + for(i = 1; i <= n; i++){ + s = dirname(a[i]) + if(s != path) + continue + if(path == "") + r[++u] = a[i] + else + r[++u] = substr(a[i], length(s)+2) + } + return u +} + +function collect(m, name, a, n,i,l,x) { + n = getarrayof(m, name, a) + l = getarrayof(m, "LIBADD", x) + for(i = 1; i <= l; i++) + n = append(a, n, varname(x[i], name)) + return n +} + +END { + if(target == "include"){ + # TODO(lufia) + key = "include_HEADERS" + exit(0) + } + if(target == "lib") + key = "lib_LTLIBRARIES" + else if(target == "bin") + key = "bin_PROGRAMS" + else + fatal(sprintf("invalid target: %s", target)) + m = getvar(key) + nc = collect(m, "SOURCES", cfiles) + nh = getarray("noinst_HEADERS", hfiles) + ndir = dirnames(cfiles, nc, dirs) + root = vars["top_srcdir"] + for(i = 1; i <= ndir; i++){ + wfile = combine(dirs[i], "mkfile") + mkfilehdr(wfile) + + s = relative(dirs[i]) + vars["top_srcdir"] = combine(s, root) + n = filter(cfiles, nc, dirs[i], a) + qsort(a, 1, n) + print "CFILES=\\" >>wfile + for(j = 1; j <= n; j++) + printf "\t%s\\\n", a[j] >>wfile + print "" >>wfile + print "OFILES=${CFILES:%.c=%.$O}" >>wfile + n = filter(hfiles, nh, dirs[i], a) + if(n > 0){ + qsort(a, 1, n) + print "HFILES=\\" >>wfile + for(j = 1; j <= n; j++) + printf "\t%s\\\n", a[j] >>wfile + print "" >>wfile + } + + if(target == "lib") + printf "LIB=/$objtype/lib/ape/%s\n", aname(m) >>wfile + else if(target == "bin") + printf "BIN=/$objtype/bin/%s\n", m >>wfile + print "" >>wfile + + print ">wfile + close(wfile) + } +} + +function mkfilehdr(wfile, a,n,i,name) { + print "wfile + #printf "<%s/mkfile.proto\n", getvar("top_srcdir") + print "" >>wfile + print "CFLAGS=$CFLAGS -c\\" >>wfile + for(name in defs) + a[++n] = "-D" name + n = append(a, n, "AM_CFLAGS") + n = append(a, n, "AM_CPPFLAGS") + qsort(a, 1, n) + for(i = 1; i <= n; i++) + printf "\t%s\\\n", a[i] >>wfile + print "" >>wfile +} +function relative(path) { + gsub(/[^\/]+/, "..", path) + return path +} +function combine(p, q) { + if(p == "" || p == ".") + return q + return sprintf("%s/%s", p, q) +} +function swap(a, i, j, v) { + v = a[i] + a[i] = a[j] + a[j] = v +} +function qsort(a, l, r, last,i) { + if(l >= r) + return + swap(a, l, int((l+r)/2)) + last = l + for(i = l+1; i <= r; i++) + if(a[i] < a[l]) + swap(a, ++last, i) + swap(a, l, last) + qsort(a, l, last-1) + qsort(a, last+1, r) +} +' diff --git a/plan9/defs b/plan9/defs new file mode 100644 index 0000000000..ef729c6aa6 --- /dev/null +++ b/plan9/defs @@ -0,0 +1,14 @@ +HOST_PLAN9 +Plan9 +_POSIX_SOURCE +_PLAN9_SOURCE +_BSD_EXTENSION +_SUSV2_SOURCE +_RESEARCH_SOURCE +_REENTRANT_SOURCE +HAVE_ARC4RANDOM_BUF +HAVE_GETENTROPY +HAVE_SOCK_OPTS +HAVE_STRCASECMP +HAVE_GETPAGESIZE +HAVE_GETPROGNAME