From owner-freebsd-current@FreeBSD.ORG Mon Jun 30 22:38:13 2003 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 75DF637B401 for ; Mon, 30 Jun 2003 22:38:13 -0700 (PDT) Received: from kientzle.com (h-66-166-149-50.SNVACAID.covad.net [66.166.149.50]) by mx1.FreeBSD.org (Postfix) with ESMTP id 646A44402B for ; Mon, 30 Jun 2003 22:38:10 -0700 (PDT) (envelope-from kientzle@acm.org) Received: from acm.org (big.x.kientzle.com [66.166.149.54] (may be forged)) by kientzle.com (8.12.9/8.12.9) with ESMTP id h615c9tJ005134; Mon, 30 Jun 2003 22:38:09 -0700 (PDT) (envelope-from kientzle@acm.org) Message-ID: <3F011EE1.2010403@acm.org> Date: Mon, 30 Jun 2003 22:40:49 -0700 From: Tim Kientzle User-Agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.0.1) Gecko/20021005 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Marcel Moolenaar References: <20030630222353.GH57432@sunbay.com> <20030630222820.GV70590@roark.gnf.org> <20030630225206.GA57854@ns1.xcllnt.net> <20030630235402.GC70590@roark.gnf.org> <20030701003516.GA3516@dhcp01.pn.xcllnt.net> <3F00FB8A.10607@acm.org> <20030701032617.GA983@athlon.pn.xcllnt.net> Content-Type: multipart/mixed; boundary="------------050009060308070609080104" cc: current@freebsd.org Subject: Re: rescue/ broke cross compiles X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: kientzle@acm.org List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Jul 2003 05:38:13 -0000 This is a multi-part message in MIME format. --------------050009060308070609080104 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit 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. Someone else may have to finish this, as I won't be able to get back to it for a few days. Tim Kientzle --------------050009060308070609080104 Content-Type: text/plain; name="kientzle_shell_buildtools.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="kientzle_shell_buildtools.diff" 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 --------------050009060308070609080104--