home *** CD-ROM | disk | FTP | other *** search
- #! /bin/sh
- # ----------------------------------------------------------------
- # FILE
- # inherits.sh
- #
- # DESCRIPTION
- # shell script which generates tags.h and inh.c
- # and $TREE/$OD/lib/H/slots, which is used by Gen_creator.sh
- # later on during the node function generation process.
- #
- # NOTES
- #
- # IDENTIFICATION
- # $Header: /private/postgres/src/lib/Gen/RCS/inherits.sh,v 1.11 1991/04/28 09:16:09 cimarron Exp $
- # ----------------------------------------------------------------
- TMPDIR=${TMPDIR-/tmp}
- INHFILE=$TMPDIR/inh.$$
- TAGFILE=$TREE/$OD/lib/H/tags.h
- TAGTEMP=$TREE/$OD/lib/H/tags.temp
- SLOTFILE=$TREE/$OD/lib/H/slots
- OUTFILE=inh.c
-
- # ----------------
- # collect nodefiles
- # ----------------
- NODEFILES=''
- x=1
- numargs=$#
- while test $x -le $numargs ; do
- NODEFILES="$NODEFILES $1"
- x=`expr $x + 1`
- shift
- done
-
- # ----------------
- # generate the initial inheritance graph
- # ----------------
- egrep -h '^class' $NODEFILES | \
- sed \
- -e 's/^class (\([A-Za-z]*\))/\1/' \
- -e 's/ public (\([A-Za-z]*\))/ \1/' \
- -e 's/[ {}]*$//' > $INHFILE
-
- # ----------------
- # generate tags.h from the inheritance graph
- # ----------------
- cat > $TAGTEMP << 'EOF'
- /* ----------------------------------------------------------------
- * FILE
- * tags.h
- *
- * DESCRIPTION
- * node tag header file - generated by the inherits.sh
- * script from the contents of the nodes files.
- *
- * NOTES
- *
- * IDENTIFICATION
- * $Header: /private/postgres/src/lib/Gen/RCS/inherits.sh,v 1.11 1991/04/28 09:16:09 cimarron Exp $
- * ----------------------------------------------------------------
- */
-
- EOF
- awk 'BEGIN { i = -1 }\
- { printf("#define T_%s %d\n", $1, ++i) }' $INHFILE >> $TAGTEMP
-
- # ----------------
- # now extract slot names from node files and generate slots.temp
- # ----------------
- rm -f $SLOTFILE
- cat $NODEFILES | \
- egrep -v '(^#|^[ /]*\*|typedef|extern|Defs)' | \
- sed -e 's/;//' \
- -e '/\/\*/,/\*\//D' \
- -e 's/ / /g' \
- -e 's/ */ /g' \
- -e 's/\\//' | \
- awk '
- # ----------------
- # ORS and OFS are the output field and record separators
- # nc is the number of "class"es we have scanned
- # inside is a variable set to 1 when we are scanning the
- # contents of a class definition.
- # ----------------
- BEGIN {
- ORS = " ";
- OFS = "";
- nc = 0;
- inside = 0;
- }
-
- # ----------------
- # first search for the "class" tag. once found
- # extract class information into the classes[] array.
- # i is the slot number of the next slot we scan..
- # ----------------
- /class /,/{/ {
- class = substr($2,2,length($2)-2);
- classes[ nc++ ] = class;
- i = 1;
- inside = 1;
- }
-
- # ----------------
- # process the contents of the class definition
- #
- # decl[ class 0 ] contains the number of slots + 1
- # decl[ class x ] contains the slot name for slot x
- # whole[ class x ] contains the entire declaration for slot x
- # parents[ class ] contains the parent class names
- # ----------------
- /{/,/}/ {
- if (inside == 0)
- next;
-
- if ($1 ~ /{/)
- next;
-
- if ($1 ~ /}/) {
- decl[ class 0 ] = i;
- i = 1;
- inside = 0;
- next;
- }
-
- if ($1 ~ /inherits/) {
- parent = substr($1,10,length($1)-10);
- parents[ class ] = parent;
-
- if (parent != "Node") {
- ndecs = decl[ parent 0 ];
- for (j=1; j<ndecs; j++) {
- whole[ class i] = whole[ parent j ];
- decl[ class i++ ] = decl[ parent j ];
- }
- }
- next;
- }
-
- if ($1 ~ /struct/) {
- whole[ class i ] = $0;
- decl[ class i++ ] = substr($3,2,length($3)-1);
- next;
- }
-
- if ($1 !~ /inherits/ && $1 !~ /struct/ && $1 !~ /class/) {
- whole[ class i ] = $0;
- decl[ class i++ ] = $2;
- }
- }
-
- # ----------------
- # all nodes have been scanned, now write node slot information.
- # the output format is:
- #
- # {
- # number-of-slots class
- # slot-name: slot-declaration
- # slot-name: slot-declaration
- # ...
- # }
- #
- # example:
- #
- # {
- # 7 Plan
- # cost: Cost cost
- # fragment: Index fragment
- # state: struct EState *state
- # qptargetlist: List qptargetlist
- # qpqual: List qpqual
- # lefttree: struct Plan *lefttree
- # righttree: struct Plan *righttree
- # }
- #
- # ----------------
- END {
- decl[ class 0 ] = i;
-
- for (j=0; j<nc; j++) {
- class = classes[ j ];
- ndecs = decl[ class 0 ];
- if (class != "Node") {
- print "\n{";
- print "\n" ndecs-1 " " class;
- for (i=1; i<ndecs; i++) {
- print "\n" decl[ class i ] ":" \
- whole[ class i ];
- }
- print "\n}";
- print "\n";
- }
- }
- print "\n";
- }
- ' > $SLOTFILE
-
- # ----------------
- # now generate inh.c
- # ----------------
- cat > $OUTFILE << 'EOF'
- /* ----------------------------------------------------------------
- * FILE
- * inh.c
- *
- * DESCRIPTION
- * node inheritance graph file - generated by the inherits.sh
- * script from the contents of the nodes files.
- *
- * NOTES
- * NodeIsType() now uses a lookup table instead of doing a
- * tree walk. The first time you ask for a node's type, we
- * walk the tree and initialize the corresponding entries in
- * the table. Subsequent calls go directly to the table.
- *
- * IDENTIFICATION
- * $Header: /private/postgres/src/lib/Gen/RCS/inherits.sh,v 1.11 1991/04/28 09:16:09 cimarron Exp $
- * ----------------------------------------------------------------
- */
-
- #include "tmp/c.h"
- #include "nodes/pg_lisp.h"
- #include "nodes/nodes.h"
- #include "nodes/primnodes.h"
- #include "nodes/execnodes.h"
- #include "nodes/relation.h"
- #include "nodes/plannodes.h"
- #include "nodes/mnodes.h"
- EOF
-
- echo '#include' \"$TAGFILE\" >> $OUTFILE
- cat >> $OUTFILE << 'EOF'
-
- struct nodeinfo {
- char *ni_name;
- TypeId ni_id;
- TypeId ni_parent;
- Size ni_size;
- };
- struct nodeinfo _NodeInfo[] = {
- EOF
-
- awk '{ if ($2 == "") { $2 = "Node" };\
- printf(" { \"%s\", T_%s, T_%s, sizeof(struct _%s) },\n", $1, $1, $2, $1) }' \
- $INHFILE >> $OUTFILE
- cat >> $OUTFILE << 'EOF'
- { "INVALID", 0, 0, 0 }
- };
-
- #define _NClasses (lengthof(_NodeInfo) - 1)
- #define _NClassBytes ((_NClasses / 8) + 1)
-
- TypeId _InvalidTypeId = (TypeId) _NClasses;
- bits8 _NodeClassArray[_NClasses][_NClassBytes];
- bits8 _NodeBitMask[] = { 1<<0, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7 };
-
- bool _NodeInfoTrace = false;
-
- /* ----------------
- * InitNodeArray initializes our node's inheritance table.
- * ----------------
- */
- void
- InitNodeArray(i)
- register TypeId i;
- {
- register TypeId j;
- register int q;
- register int r;
-
- /* ----------------
- * base clause for recursion: initializing the root node
- * ----------------
- */
- if (i == T_Node) {
- _NodeClassArray[i][0] = 1<<0;
- return;
- }
-
- /* ----------------
- * recursive initialization: initialize our parent, if necessary
- * ----------------
- */
- j = _NodeInfo[i].ni_parent;
- if (_NodeClassArray[j][0] == 0)
- InitNodeArray(j);
-
- /* ----------------
- * now initialize ourself by copying our parent's bitmask and
- * setting our own bit.
- * ----------------
- */
- for (q=0; q<_NClassBytes; q++)
- _NodeClassArray[i][q] = _NodeClassArray[j][q];
-
- q = i / 8; r = i % 8;
- _NodeClassArray[i][q] |= _NodeBitMask[r];
- }
-
- /* ----------------
- * NodeIsType
- *
- * determine if (thisNode) is of type (tag) or is a subclass
- * of type (tag). We do this by consulting the master
- * node class array bitmap: look in the row corresponding
- * to (thisNode)'s type. Now look at the bit in the position
- * indicated by (tag). If this is set, then (thisNode) is
- * of type (tag), otherwise it's not.
- *
- * The table is initialized on demand. If nobody ever asks
- * about a given class, then we never initialize that class's
- * information...
- * ----------------
- */
- bool
- NodeIsType(thisNode, tag)
- Node thisNode;
- register TypeId tag;
- {
- register TypeId i;
- register int q;
- register int r;
-
- Assert(NodeIsValid(thisNode));
-
- i = NodeType(thisNode);
- Assert(TypeIdIsValid(i));
- Assert(TypeIdIsValid(tag));
-
- if (_NodeClassArray[i][0] == 0)
- InitNodeArray(i);
-
- q = tag / 8; r = tag % 8;
- return (bool)
- (_NodeClassArray[i][q] & _NodeBitMask[r]);
- }
-
- void
- Dump_NodeInfo()
- {
- register TypeId i;
-
- printf("%16.16s%16.16s%16.16s\n",
- "NODE NAME:", "NODE TAG:", "PARENT NODE:");
-
- for (i = 0; i < _InvalidTypeId; ++i)
- printf("%16.16s%16.1d%16.16s\n",
- _NodeInfo[i].ni_name,
- _NodeInfo[i].ni_id,
- _NodeInfo[_NodeInfo[i].ni_parent].ni_name);
- }
-
- EOF
- rm -f $INHFILE
-
- # ----------------
- # finally, compare the new tagfile with the old.
- #
- # if the tagfile has changed, then it means that
- # cinterface.a has to be remade because its tag #defines
- # are different.
- # ----------------
- if [ -r $TAGFILE ]; then
- if cmp -s $TAGFILE $TAGTEMP ; then
- echo "tags.h unchanged";
- else
- mv $TAGTEMP $TAGFILE;
- echo "tags.h has changed; remake cinterface.a";
- fi
- else
- mv $TAGTEMP $TAGFILE;
- fi
-
- # ----------------
- # all done
- # ----------------
- exit 0
-