rescue/ broke cross compiles
Tim Kientzle
kientzle at acm.org
Mon Jun 30 22:38:13 PDT 2003
Marcel Moolenaar wrote:
> On Mon, Jun 30, 2003 at 08:10:02PM -0700, Tim Kientzle wrote:
> In general I think that the more portable the build tool, the better.
> If the shell script is not gross or overly ugly compared to the C
> program, then replacing the latter may not be a bad idea.
The attached diff replaces two of the build tools for /bin/sh
with equivalent shell scripts (using grep/sed/awk). I
personally find the awk versions clearer than the C versions.
I apologize that these have not been very well tested, but they
were written in quite a rush. For the most part, the output
of these is exactly the same as that from the C programs.
The few differences look functionally equivalent to me, but
I've not had time to test it very carefully.
The remaining 'mksyntax' also looks pretty easy to replace with
a shell script, at which point, /bin/sh will require no
build-tools target. Then, /rescue will also not need a buld-tools
target (assuming everyone is willing to drop csh from
/rescue).
Unfortunately, it's late, I haven't had dinner, and I have
a lot of paying work piling up. <sigh> Someone else may
have to finish this, as I won't be able to get back to it
for a few days.
Tim Kientzle
-------------- next part --------------
Index: Makefile
===================================================================
RCS file: /usr/cvs/FreeBSD-CVS/src/bin/sh/Makefile,v
retrieving revision 1.40
diff -u -r1.40 Makefile
--- Makefile 2 May 2003 06:26:32 -0000 1.40
+++ Makefile 1 Jul 2003 05:25:08 -0000
@@ -31,7 +31,7 @@
mksyntax mksyntax.o
CLEANFILES+= ${GENSRCS} ${GENHDRS}
-build-tools: mkinit mknodes mksyntax
+build-tools: mksyntax
.ORDER: builtins.c builtins.h
builtins.c builtins.h: mkbuiltins builtins.def
@@ -39,20 +39,18 @@
init.c: mkinit alias.c eval.c exec.c input.c jobs.c options.c parser.c \
redir.c trap.c var.c
- ./mkinit ${.ALLSRC:S/^mkinit$//}
+ sh ${.CURDIR}/mkinit ${.ALLSRC:S/^mkinit$//}
# XXX this is just to stop the default .c rule being used, so that the
# intermediate object has a fixed name.
# XXX we have a default .c rule, but no default .o rule.
.o:
${CC} ${CFLAGS} ${LDFLAGS} ${.IMPSRC} ${LDLIBS} -o ${.TARGET}
-mkinit: mkinit.o
-mknodes: mknodes.o
mksyntax: mksyntax.o
.ORDER: nodes.c nodes.h
nodes.c nodes.h: mknodes nodetypes nodes.c.pat
- ./mknodes ${.CURDIR}/nodetypes ${.CURDIR}/nodes.c.pat
+ sh ${.CURDIR}/mknodes ${.CURDIR}/nodetypes ${.CURDIR}/nodes.c.pat
.ORDER: syntax.c syntax.h
syntax.c syntax.h: mksyntax
--- /dev/null Mon Jun 30 22:15:03 2003
+++ mkinit Mon Jun 30 22:25:04 2003
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+( # to send output to init.c
+
+echo "/*"
+echo " * This file was generated by the mkinit program."
+echo " */"
+echo ""
+echo '#include "shell.h"'
+echo '#include "mystring.h"'
+
+cat $@ | grep '^INCLUDE' | sed -e "s/INCLUDE/#include/"
+
+echo
+echo
+echo
+
+cat $@ | sed -n -e '/^#define/ s/#define //p' | grep -v '\\$' | egrep -v '^[A-Z_]+\(' | awk '{print "#undef ",$1; print "#define",$0; }'
+
+echo
+echo
+
+for f in $@
+do
+ cat $f | sed -n -e '/^MKINIT$/,/^}/ p' -e '/^MKINIT / s/^MKINIT/extern/p' | grep -v '^MKINIT$'
+ echo
+done
+
+echo
+echo
+echo "/*"
+echo " * Initialization code."
+echo " */"
+
+echo
+echo "void"
+echo "init() {"
+
+for f in $@
+do
+ echo " /* from $f: */"
+ cat $f | sed -n -e '/^INIT/,/^}/ p' | sed -e 's/INIT //' | \
+ awk '{print " ",$0;}' OFS=''
+ echo
+done
+
+echo "}"
+
+echo
+echo
+echo
+
+echo "/*"
+echo " * This routine is called when an error or an interrupt occurs in an"
+echo " * interactive shell and control is returned to the main command loop."
+echo " */"
+echo
+echo "void"
+echo "reset() {"
+
+for f in $@
+do
+ echo " /* from $f: */"
+ cat $f | sed -n -e '/^RESET/,/^}/ p' | sed -e 's/RESET //' | \
+ awk '{print " ",$0;}' OFS=''
+ echo
+done
+echo "}"
+
+echo
+echo
+echo
+echo "/*"
+echo " * This routine is called to initialize the shell to run a shell procedure."
+echo " */"
+echo
+echo "void"
+echo "initshellproc() {"
+
+
+for f in $@
+do
+ echo " /* from $f: */"
+ cat $f | sed -n -e '/^SHELLPROC/,/^}/ p' | sed -e 's/SHELLPROC //' | \
+ awk '{print " ",$0;}' OFS=''
+ echo
+done
+echo "}"
+
+
+) > init.c
--- /dev/null Mon Jun 30 22:15:03 2003
+++ mknodes Mon Jun 30 22:20:58 2003
@@ -0,0 +1,227 @@
+#!/bin/sh
+
+NODEFILE=$1
+PATFILE=$2
+
+#
+# The awk scripts are driven by the 'nodetypes' file format,
+# which is basically just a set of C structure definitions.
+#
+# Here's an example entry from nodetypes:
+# NSEMI nbinary
+# type int
+# ch1 nodeptr
+# ch2 nodeptr
+#
+# This says that an 'NSEMI' node uses the 'nbinary' structure;
+# the following lines define the structure. Another example:
+#
+# NWHILE nbinary
+#
+# This says that an 'NWHILE' node uses the 'nbinary' structure,
+# but doesn't define the structure (since it's defined elsewhere).
+# Correlating all of this is much simpler with AWK's associative
+# arrays than with the old C version.
+#
+
+
+###########################################################################
+#
+# Create nodes.c
+#
+###########################################################################
+( # Spawn a subshell to direct output to nodes.c
+
+
+echo "/*"
+echo " * This file was generated by the mknodes program."
+echo " */"
+echo
+
+# Emit first part of pattern file
+cat $PATFILE | sed -ne '1,/%SIZES/p' | grep -v '%SIZES'
+
+# Build nodesize[] array
+echo 'static const short nodesize[26] = {'
+
+cat $NODEFILE | sed -nEe '/^N/ s/^N[A-Z]* (n[a-z]*)[[:>:]].*/ ALIGN(sizeof (struct \1)),/ p'
+
+echo '};'
+
+# Next part of pattern file
+cat $PATFILE | sed -ne '/%SIZES/,/%CALCSIZE/p' \
+ | grep -v '%SIZES' | grep -v '%CALCSIZE'
+
+# Build calcsize function body
+cat $NODEFILE | sed -ne '/^N/,$ p' | sed -e 's/#.*//' | awk '
+ BEGIN { newentry=0;
+ print " if (n == NULL)";
+ print "\t return;"
+ print " funcblocksize += nodesize[n->type];"
+ print " switch (n->type) {"
+ }
+ /^N/ { a=$1; f=$2;
+ cases[f] = cases[f] " " $1;
+ newentry=1;
+ }
+ !/^N/ { if(NF > 1) { # Ignore short lines
+ if(newentry) {
+ types = types " " f;
+ action[f] = "\t break;";
+ newentry = 0;
+ }
+ if($2 == "nodeptr") {
+ action[f] = "\t calcsize(n->" f "." $1 ");\n" action[f];
+ } else if($2 == "nodelist") {
+ action[f] = "\t sizenodelist(n->" f "." $1 ");\n" action[f];
+ } else if($2 == "string") {
+ action[f] = "\t funcstringsize += strlen(n->" f "." $1 ") + 1;\n" action[f];
+ }
+ }
+ }
+ END {
+ ntypes = split(types,typesarr," ");
+ for(nt = 1; nt <= ntypes; ++nt) {
+ f = typesarr[nt];
+ i = split(cases[f],arr," ");
+ for(n = 1; n <= i; ++n)
+ print " case " arr[n] ":";
+ print action[f];
+ }
+ }
+'
+
+echo " };"
+
+# Emit next block of pattern file
+cat $PATFILE | sed -ne '/%CALCSIZE/,/%COPY/p' \
+ | grep -v '%CALCSIZE' | grep -v '%COPY'
+
+# Build copynode function body
+
+cat $NODEFILE | sed -ne '/^N/,$ p' | sed 's/#.*//' | awk '
+ BEGIN { newentry=0;
+ print " if (n == NULL)"
+ print "\t return NULL;"
+ print " new = funcblock;"
+ print " funcblock = (char *)funcblock + nodesize[n->type];"
+ print " switch (n->type) {"
+
+ }
+ /^N/ { a=$1; f=$2;
+ cases[f] = cases[f] " " $1;
+ newentry=1;
+ }
+ !/^N/ { if(NF > 1) {
+ if(newentry) {
+ types = types " " f;
+ action[f] = "\t break;";
+ newentry = 0;
+ }
+ if($1 == "type") {
+ } else if($2 == "nodeptr") {
+ action[f] = "\t new->" f "." $1 " = copynode(n->" f "." $1 ");\n" action[f];
+ } else if($2 == "nodelist") {
+ action[f] = "\t new->" f "." $1 " = copynodelist(n->" f "." $1 ");\n" action[f];
+ } else if($2 == "string") {
+ action[f] = "\t new->" f "." $1 " = nodesavestr(n->" f "." $1 ");\n" action[f];
+ } else if($2 == "temp") {
+ # Nothing
+ } else {
+ action[f] = "\t new->" f "." $1 " = n->" f "." $1 ";\n" action[f];
+ }
+ }
+ }
+ END {
+ ntypes = split(types,typesarr," ");
+ for(nt = 1; nt <= ntypes; ++nt) {
+ f = typesarr[nt];
+ i = split(cases[f],arr," ");
+ for(n = 1; n <= i; ++n)
+ print " case " arr[n] ":";
+ print action[f];
+ }
+ }
+'
+
+echo " };"
+echo " new->type = n->type;"
+
+# Emit final part of pattern file
+cat $PATFILE | sed -ne '/%COPY/,$ p' | grep -v '%COPY'
+
+# End of subshell; here's the promised redirect
+) >nodes.c
+
+
+###########################################################################
+#
+# Create nodes.h
+#
+###########################################################################
+( # Spawn a subshell to direct output to nodes.h
+
+echo "/*"
+echo " * This file was generated by the mknodes program."
+echo " */"
+echo
+
+# Print out enum constants
+cat $NODEFILE | awk 'BEGIN{i=0;} /^N/ { print "#define " $1 " " i; ++i }'
+
+echo
+echo
+echo
+
+# Print out structure definitions
+
+cat $NODEFILE | sed -ne '/^N/,$ p' | sed -e 's/#.*//' | awk '
+ BEGIN { closeold=0; }
+ /^N/ { if(closeold) print "};\n\n"
+ closeold = 0;
+ t = $2;
+ }
+ !/^N/ { if(NF > 1) {
+ if(t) {
+ print "struct " t " {";
+ struct = struct " struct " t " " t ";\n";
+ closeold = 1;
+ t = 0;
+ }
+
+ if($2 == "nodeptr") {
+ print " union node *" $1 ";";
+ } else if($2 == "nodelist") {
+ print " struct nodelist *" $1 ";";
+ } else if($2 == "string") {
+ print " char *" $1 ";";
+ } else if($2 == "temp") {
+ printf " ";
+ for(i = 3; i <= NF; i++) printf " " $i;
+ print ";";
+ } else {
+ print " " $2 " " $1 ";";
+ }
+ }
+ }
+ END {
+ if(closeold) print "};\n\n"
+ print "union node {";
+ print " int type;";
+ print struct "};";
+ }
+'
+
+echo
+echo
+echo "struct nodelist {"
+echo " struct nodelist *next;"
+echo " union node *n;"
+echo "};"
+echo
+echo
+echo "union node *copyfunc(union node *);"
+echo "void freefunc(union node *);"
+
+# End of subshell; here's the promised redirect
+) > nodes.h
More information about the freebsd-current
mailing list