[comp.soft-sys.andrew] enhancements

grogers@SNIDELY.CS.UIUC.EDU (Greg Rogers) (01/15/90)

Here are the context diffs for several modifications that I have made to
the ATK that I thought you might be interested in.  These are not bug
fixes but enhancements.

The diffs are against Andrew version 3 as distributed with X11R4, patchlevel 1.

(My first 7 fixes have already been sent to info-andrew-bugs.)

8 - adds SetLineStyle to the graphic, xgraphic, and view classes.
	This method pretty much matches the Xlib command.

9 - modifications to the dvi2disp.c font map table to match the fonts on
	the ibm 3812 page printer.

10 - lpair, bpair - promoted DoFullUpdate and ResetDimensions from static
	functions to methods.  I needed to override these for some reason,
	but I didn't need to modify the methods that call them.

	My feeling is that there should not be any static functions, especially
	ones that perform useful operations like DoFullUpdate.  The use of
	static functions eventually leads to unnecessary code duplication.
	The modifications to bpair where to remove the ResetDimensions function
	since it was exactly the same as lpair's (so is ComputeSizes, but
	I just did what I needed to do.)

11 - scroll - didn't implement DesiredSize and the inherited method did
	nothing.  This prevented size negotiation between my top level view
	and bottom level view because a scroll view was between the two.
	After I did this I realized that I could (should) have just subclassed
	scroll.  Oh well....

12 - class - I modified the class preprocessor so that I could override the
	default Destroy method.  This is necessary to support objects that
	allow multiple references and do reference counting.  Unfortunately
	I didn't make it a method, I just prevent class from generating
	it if the .ch file specifies one.

	I was VERY disappointed when I discovered that Destroy was not
	a method of the class class as described in class/doc/Class.doc
	and class/doc/class.chng.  

Greg Rogers
University of Illinois at Urbana-Champaign
Department of Computer Science
1304 W. Springfield Ave.
Urbana, IL 61801

grogers@cs.uiuc.edu


#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	8
#	9
#	10
#	11
#	12
# This archive created: Mon Jan 15 01:37:27 1990
export PATH; PATH=/bin:$PATH
if test -f '8'
then
	echo shar: will not over-write existing file "'8'"
else
cat << \SHAR_EOF > '8'
*** ./atk/basics/x/xgraphic.ch.orig	Sun Jan 14 18:00:35 1990
--- ./atk/basics/x/xgraphic.ch	Sun Jan 14 18:03:32 1990
***************
*** 66,71 ****
--- 66,72 ----
      ClearClippingRect();
  
      SetLineWidth(short NewLineWidth);
+     SetLineStyle(int NewLineStyle, int NewCapStyle, int NewJoinStyle );
  
      SetTransferMode(short NewTransferMode);
  
*** ./atk/basics/x/xgraphic.c.orig	Sun Jan 14 18:00:25 1990
--- ./atk/basics/x/xgraphic.c	Sun Jan 14 18:02:43 1990
***************
*** 1366,1371 ****
--- 1366,1390 ----
  		GCLineWidth,&tempGC);
  }
  
+ void
+ xgraphic__SetLineStyle(self, NewLineStyle, NewCapStyle, NewJoinStyle )
+     struct xgraphic * self;
+     int NewLineStyle, NewCapStyle, NewJoinStyle;
+ {
+     XGCValues tempGC;
+ 
+     self->header.graphic.lineStyle = NewLineStyle;
+     self->header.graphic.capStyle  = NewCapStyle;
+     self->header.graphic.joinStyle = NewJoinStyle;
+     tempGC.line_style = NewLineStyle;
+     tempGC.cap_style  = NewCapStyle;
+     tempGC.join_style = NewJoinStyle;
+ 
+     XChangeGC(xgraphic_XDisplay(self),
+ 	xgraphic_XGC(self),
+ 	GCLineStyle | GCCapStyle | GCJoinStyle, &tempGC);
+ }
+ 
  
  void xgraphic__SetTransferMode(self,NewTransferMode)
  struct xgraphic * self;
*** ./atk/basics/common/graphic.ch.orig	Sun Jan 14 18:04:34 1990
--- ./atk/basics/common/graphic.ch	Sun Jan 14 18:11:26 1990
***************
*** 30,36 ****
--- 30,56 ----
  #define graphic_BETWEENTOPANDBOTTOM	 0100
  #define graphic_BETWEENTOPANDBASELINE	 0200
  
+ /* LineStyle */
  
+ #define graphic_LineSolid	0
+ #define graphic_LineOnOffDash	1
+ #define graphic_LineDoubleDash	2
+ 
+ /* capStyle */
+ 
+ #define graphic_CapNotLast	0
+ #define graphic_CapButt		1
+ #define graphic_CapRound	2
+ #define graphic_CapProjecting	3
+ 
+ /* joinStyle */
+ 
+ #define graphic_JoinMiter	0
+ #define graphic_JoinRound	1
+ #define graphic_JoinBevel	2
+ 
+ 
+ 
  class graphic : observable[observe] {
  methods:
      MoveToPt(struct point * Pt);
***************
*** 124,129 ****
--- 144,152 ----
      SetLineWidth(short NewLineWidth);
      GetLineWidth() returns short;
  
+     SetLineStyle(int NewLineStyle, int NewCapStyle, int NewJoinStyle );
+     GetLineStyle(int *lineStyle, int *capStyle, int *joinStyle );
+ 
      SetTransferMode(short NewTransferMode);
      GetTransferMode() returns short;
  
***************
*** 180,185 ****
--- 203,209 ----
      short  spaceShim;
      short  transferMode;	    /* ALU function for bitblit */
      short  lineWidth;		    /* How thick to make outlines */
+     int lineStyle, capStyle, joinStyle;
      struct rectangle * clippingRect; /* Rects for clipping */
      struct point    currentPoint;	    /* Start of drawing operations */
      boolean internalFont;	     /* internal fontdescriptor */
*** ./atk/basics/common/graphic.c.orig	Sun Jan 14 18:04:40 1990
--- ./atk/basics/common/graphic.c	Sun Jan 14 18:08:59 1990
***************
*** 576,586 ****
--- 576,589 ----
  {
      struct point * tempPt;
      short tempLineWidth, tempTMode;
+     int tempLineStyle, tempCapStyle, tempJoinStyle;
  
      /* Slow, but correct -- instead of filling a rectangle, we should
        probably draw a one pixel long, one pixel wide line. */
      graphic_GetCurrentPt(self,&tempPt);
      tempLineWidth = graphic_GetLineWidth(self);
+     graphic_GetLineStyle( self, &tempLineStyle, &tempCapStyle, &tempJoinStyle);
+ 
      tempTMode = graphic_GetTransferMode(self);
  
      if (NewValue==TRUE)
***************
*** 591,599 ****
--- 594,605 ----
  
      graphic_MoveTo(self,XPos,YPos);
      graphic_SetLineWidth(self,1);
+     graphic_SetLineStyle( self, 0, 1, 0);
      graphic_DrawLineTo(self,XPos,YPos); /* yep, this draws one dot in wm */
  
      graphic_MoveToPt(self,&tempPt);
+     graphic_SetLineStyle( self, tempLineStyle, tempCapStyle, tempJoinStyle);
+ 
      graphic_SetLineWidth(self,tempLineWidth);
      graphic_SetTransferMode(self,tempTMode);
  
***************
*** 726,731 ****
--- 732,758 ----
      return self->lineWidth;
  }
  
+ void
+ graphic__SetLineStyle(self, NewLineStyle, NewCapStyle, NewJoinStyle)
+     struct graphic * self;
+     short NewLineStyle, NewCapStyle, NewJoinStyle;
+ {
+     self->lineStyle = NewLineStyle;
+     self->capStyle  = NewCapStyle;
+     self->joinStyle = NewJoinStyle;
+ }
+ 
+ void
+ graphic__GetLineStyle(self, lineStyle, capStyle, joinStyle)
+     struct graphic * self;
+     int *lineStyle, *capStyle, *joinStyle;
+ {
+     *lineStyle = self->lineStyle;
+     *capStyle  = self->capStyle;
+     *joinStyle = self->joinStyle;
+ }
+ 
+ 
  void graphic__SetTransferMode(self,NewTransferMode)
  struct graphic * self;
  short NewTransferMode;
***************
*** 1006,1011 ****
--- 1033,1042 ----
      self->spaceShim = 0;
      self->transferMode = graphic_COPY;
      self->lineWidth = 1;
+     self->lineStyle = 0;
+     self->capStyle  = 1;
+     self->joinStyle = 0;
+ 
      self->clippingRect = (struct rectangle * ) NULL;
      point_SetPt(&self->currentPoint,0,0);
  
*** ./atk/basics/common/view.ch.orig	Sun Jan 14 18:11:53 1990
--- ./atk/basics/common/view.ch	Sun Jan 14 23:11:08 1990
***************
*** 58,63 ****
--- 58,83 ----
  #define view_BETWEENTOPANDBOTTOM	 0100
  #define view_BETWEENTOPANDBASELINE	 0200
  
+ 
+ /* LineStyle */
+ 
+ #define view_LineSolid	0
+ #define view_LineOnOffDash	1
+ #define view_LineDoubleDash	2
+ 
+ /* capStyle */
+ 
+ #define view_CapNotLast	0
+ #define view_CapButt		1
+ #define view_CapRound	2
+ #define view_CapProjecting	3
+ 
+ /* joinStyle */
+ 
+ #define view_JoinMiter	0
+ #define view_JoinRound	1
+ #define view_JoinBevel	2
+ 
  /* Error codes for the description procedure */
  enum view_DescriberErrs {
      view_NoDescribeError,
***************
*** 215,220 ****
--- 235,243 ----
  
      SetLineWidth(NewLineWidth) (graphic_SetLineWidth((self)->drawable, (NewLineWidth)))
      GetLineWidth() (graphic_GetLineWidth((self)->drawable))
+ 
+     SetLineStyle(NewLineStyle,NewCapStyle,NewJoinStyle) (graphic_SetLineStyle((self)->drawable,(NewLineStyle),(NewCapStyle),(NewJoinStyle)))
+     GetLineStyle(lineStyle,capStyle,joinStyle) (graphic_GetLineStyle((self)->drawable),(lineStyle),(capStyle),(joinStyle))
  
      SetTransferMode(NewTransferMode) (graphic_SetTransferMode((self)->drawable,(NewTransferMode)))
      GetTransferMode() (graphic_GetTransferMode((self)->drawable))
SHAR_EOF
fi # end of overwriting check
if test -f '9'
then
	echo shar: will not over-write existing file "'9'"
else
cat << \SHAR_EOF > '9'
*** ./atk/preview/dvi2disp.c.orig	Wed Nov 22 11:24:22 1989
--- ./atk/preview/dvi2disp.c	Sat Jan 13 22:50:27 1990
***************
*** 546,558 ****
  			  switch (name[1])  {
  			      case 'R':
  				  break;
! 			      case 'O':
  			          value += Italic;
  				  break;
  			      case 'B':
  			          value += Bold;
  				  break;
! 			      case 'D':
  			          value += BoldItalic;
  				  break;
  			  }
--- 546,558 ----
  			  switch (name[1])  {
  			      case 'R':
  				  break;
! 			      case 'I':
  			          value += Italic;
  				  break;
  			      case 'B':
  			          value += Bold;
  				  break;
! 			      case 'Y':
  			          value += BoldItalic;
  				  break;
  			  }
SHAR_EOF
fi # end of overwriting check
if test -f '10'
then
	echo shar: will not over-write existing file "'10'"
else
cat << \SHAR_EOF > '10'
*** ./atk/supportviews/lpair.ch.orig	Sun Jan 14 14:39:15 1990
--- ./atk/supportviews/lpair.ch	Sun Jan 14 14:40:48 1990
***************
*** 55,60 ****
--- 55,64 ----
      GetNth(int ai) returns struct view *;
      SetNth(int ai,register struct view *x) ;
      SetUp(struct view *l1, struct viewlpair *l2, int bsize, int porf, int vorh, boolean moveable) returns struct lpair *;
+ 
+     DoFullUpdate(enum view_UpdateType type, struct rectangle *redrawRectangle);
+     ResetDimensions();
+ 
  macromethods:
      GetObjSize(i) (self->objsize[i])
  classprocedures:
*** ./atk/supportviews/lpair.c.orig	Sun Jan 14 14:39:10 1990
--- ./atk/supportviews/lpair.c	Sun Jan 14 14:43:04 1990
***************
*** 38,44 ****
  /* Forward Declarations */
  static void lpair_ComputeSizesFromTotal ();
  static void lpair_ComputeSizes ();
- static void lpair_ResetDimensions ();
  
  
  /* For use in ComputeSizes below. */
--- 38,43 ----
***************
*** 46,52 ****
  #define max(a, b) ((a < b) ? b : a)
  
  /* Basically, the only reason this routine exists is because the FullUpdate signature does not use rectangles. This routine expects its redrawRectangle argument to be valid know matter what the type argument is. The type arg is just passed through to the children that need to be redrawn. All in all, this, Update, and FullUpdate can probably be simplified. -Z- */
! static void DoFullUpdate(self, type, redrawRectangle)
  struct lpair *self;
  enum view_UpdateType type;
  struct rectangle *redrawRectangle;
--- 45,52 ----
  #define max(a, b) ((a < b) ? b : a)
  
  /* Basically, the only reason this routine exists is because the FullUpdate signature does not use rectangles. This routine expects its redrawRectangle argument to be valid know matter what the type argument is. The type arg is just passed through to the children that need to be redrawn. All in all, this, Update, and FullUpdate can probably be simplified. -Z- */
! void 
! lpair__DoFullUpdate(self, type, redrawRectangle)
  struct lpair *self;
  enum view_UpdateType type;
  struct rectangle *redrawRectangle;
***************
*** 157,163 ****
  		/* I intentionally pass in view_FullRedraw here knowing that the DoFullUpdate
   * will still take the rectangle into account.
   */
! 		DoFullUpdate(self, view_FullRedraw, &redrawRectangle);
  	}
  }
  
--- 157,163 ----
  		/* I intentionally pass in view_FullRedraw here knowing that the DoFullUpdate
   * will still take the rectangle into account.
   */
! 		lpair_DoFullUpdate(self, view_FullRedraw, &redrawRectangle);
  	}
  }
  
***************
*** 194,200 ****
  		lpair_GetVisualBounds(self, &redrawRectangle);
  		break;
  	}
! 	DoFullUpdate(self, type, &redrawRectangle);
  }
  
  
--- 194,200 ----
  		lpair_GetVisualBounds(self, &redrawRectangle);
  		break;
  	}
! 	lpair_DoFullUpdate(self, type, &redrawRectangle);
  }
  
  
***************
*** 416,422 ****
  }
  
  
! static void lpair_ResetDimensions(self)
  register struct lpair *self;
  {
  
--- 416,423 ----
  }
  
  
! void
! lpair__ResetDimensions(self)
  register struct lpair *self;
  {
  
*** ./atk/supportviews/bpair.c.orig	Sun Jan 14 14:50:18 1990
--- ./atk/supportviews/bpair.c	Sun Jan 14 15:02:32 1990
***************
*** 35,41 ****
--- 35,43 ----
  
  /* Forward Declarations */
  static void lpair_ComputeSizes ();
+ #ifdef LPAIR_RDIM_NOT_METHOD
  static void lpair_ResetDimensions();
+ #endif
  
  /* the following two routines are needed for FullUpdate 
  	They are copied from lpair.c, with deletion of the line-between code,
***************
*** 80,85 ****
--- 82,88 ----
      l->objcvt[1-i] = totalsize - l->objcvt[i];
  }
  
+ #ifdef LPAIR_RDIM_NOT_METHOD
  static void lpair_ResetDimensions(self)
  register struct lpair *self;
  {
***************
*** 105,110 ****
--- 108,114 ----
  	}
      }
  }
+ #endif
  
  
  	boolean
***************
*** 151,157 ****
      self->header.lpair.needsfull = 0;
  
      lpair_ComputeSizes((struct lpair *)self);
!     lpair_ResetDimensions((struct lpair *)self);	/* reset the child lpair sizes */
  
      view_GetLogicalBounds(leftTopObject, &r);
      view_FullUpdate(leftTopObject, type, r.left, r.top, r.width, r.height);
--- 155,161 ----
      self->header.lpair.needsfull = 0;
  
      lpair_ComputeSizes((struct lpair *)self);
!     bpair_ResetDimensions(self);	/* reset the child lpair sizes */
  
      view_GetLogicalBounds(leftTopObject, &r);
      view_FullUpdate(leftTopObject, type, r.left, r.top, r.width, r.height);
SHAR_EOF
fi # end of overwriting check
if test -f '11'
then
	echo shar: will not over-write existing file "'11'"
else
cat << \SHAR_EOF > '11'
*** ./atk/supportviews/scroll.ch.orig	Sun Jan 14 18:14:56 1990
--- ./atk/supportviews/scroll.ch	Sun Jan 14 18:17:48 1990
***************
*** 66,71 ****
--- 66,72 ----
      WantUpdate(struct view *requestor);
      LinkTree(struct view *parent);
      UnlinkNotification(struct view *unlinkedTree);
+     DesiredSize(long width, long height, enum view_DSpass pass, long *dWidth, long *dheight) returns enum view_DSattributes;
  
    methods:
      /* A ``location'' is a bitmask of scroll_LEFT, etc. describing the places for the scrollbars to appear. The location returned by GetLocation is the desired location, while GetCurrentLocation returns the real condititions based on the size of the region were in. */
*** ./atk/supportviews/scroll.c.orig	Sun Jan 14 18:15:01 1990
--- ./atk/supportviews/scroll.c	Sun Jan 14 18:17:13 1990
***************
*** 1304,1306 ****
--- 1304,1330 ----
      updatelist_DeleteTree(self->updatelist, unlinkedTree);
      super_UnlinkNotification(self, unlinkedTree);
  }
+ 
+ enum view_DSattributes
+ scroll__DesiredSize(self, width, height, pass, desiredwidth, desiredheight)
+     struct scroll *self;
+     long width, height;
+     enum view_DSpass pass;
+     long *desiredwidth, *desiredheight;
+ {
+     long dw, dh;
+     int sw, sh;
+ 
+ /* the space for the scrollbars */
+     sw = scroll_GetLogicalWidth(self) - self->width;
+     sh = scroll_GetLogicalHeight(self) - self->height;
+ 
+     view_DesiredSize(self->scrollee, width-sw, height-sh, pass, &dw, &dh);
+     *desiredwidth = (pass == view_WidthSet) ? width : dw + sw ;
+     *desiredheight = (pass == view_HeightSet) ? height : dh + sh ;
+ /***
+    fprintf(stderr, "scroll__DesiredSize: scrollee %d %d  me %d %d\n", dw, dh, *desiredwidth, *desiredheight );
+ ***/
+ 
+     return(view_Fixed);
+ }
SHAR_EOF
fi # end of overwriting check
if test -f '12'
then
	echo shar: will not over-write existing file "'12'"
else
cat << \SHAR_EOF > '12'
*** ./overhead/class/pp/classpp.h.orig	Sun Jan 14 16:16:09 1990
--- ./overhead/class/pp/classpp.h	Sun Jan 14 16:17:17 1990
***************
*** 51,70 ****
  #define name_Deallocate 2
  #define name_InitializeClass 3
  #define name_FinalizeObject 4
  /* everything < name_RegularName is a special class procedures */
! #define name_RegularName 5
! #define name_ThisObject 6
! #define name_Self 7
! #define name_Unsigned 8
! #define name_Int 9
! #define name_Float 10
! #define name_Void 11
! #define name_Pointer 12
! #define name_NULL 13
! #define name_MinusOne 14
! #define name_Exit 15
! #define name_Boolean 16
! #define name_Long 17
  
  /*
   * ???
--- 51,71 ----
  #define name_Deallocate 2
  #define name_InitializeClass 3
  #define name_FinalizeObject 4
+ #define name_Destroy 5
  /* everything < name_RegularName is a special class procedures */
! #define name_RegularName 6
! #define name_ThisObject 7
! #define name_Self 8
! #define name_Unsigned 9
! #define name_Int 10
! #define name_Float 11
! #define name_Void 12
! #define name_Pointer 13
! #define name_NULL 14
! #define name_MinusOne 15
! #define name_Exit 16
! #define name_Boolean 17
! #define name_Long 18
  
  /*
   * ???
*** ./overhead/class/pp/class.c.orig	Wed Jan 10 21:51:16 1990
--- ./overhead/class/pp/class.c	Sun Jan 14 16:15:55 1990
***************
*** 135,140 ****
--- 135,141 ----
  static int allocate;			/* TRUE if a allocate procedure was found */
  static int deallocate;			/* TRUE if a deallocate procedure was found */
  static int initializeclass;		/* TRUE if an initializeclass procedure was found */
+ static int destroydefined;		/* TRUE if an destroy procedure was found */
  
  static int SilentMode;			/* TRUE if we are silent except for errors */
  static int QuietMode;			/* TRUE if we are not issuing warnings */
***************
*** 780,785 ****
--- 781,787 ----
  
  	for (mp = methodlist->next; mp != NULL; mp = mp->next)  {
  	    if (mp->type==ptype_classproc && mp->defined)  {
+ 		if (strcmp("Destroy", mp->name) == 0) continue;
  		outstr3("#define %s_%s(%s) \\\n", FinalClassName, mp->name, mp->methodargs);
  		if (mp->argcount != 0)
  		    (void) fprintf(importfile, "    (*((%s (*)()) (%s_classheader.classprocedures->routines[%d])))(&%s_classheader,%s)\n", mp->methodtype, FinalClassName, rtnNum, FinalClassName, mp->methodargs);
***************
*** 886,892 ****
          (void) fprintf(exportfile, "\n};\n\n");
  
          (void) fprintf(exportfile, "struct %s *%s__New();\n", FinalClassName, FinalClassName);
!         (void) fprintf(exportfile, "void %s__Destroy();\n", FinalClassName);
          (void) fprintf(exportfile, "boolean %s__Initialize();\n", FinalClassName);
          (void) fprintf(exportfile, "void %s__Finalize();\n", FinalClassName);
          if (initializeobject && ! initializeobjectdefined)
--- 888,895 ----
          (void) fprintf(exportfile, "\n};\n\n");
  
          (void) fprintf(exportfile, "struct %s *%s__New();\n", FinalClassName, FinalClassName);
! 	if ( ! destroydefined)
!             (void) fprintf(exportfile, "void %s__Destroy();\n", FinalClassName);
          (void) fprintf(exportfile, "boolean %s__Initialize();\n", FinalClassName);
          (void) fprintf(exportfile, "void %s__Finalize();\n", FinalClassName);
          if (initializeobject && ! initializeobjectdefined)
***************
*** 913,918 ****
--- 916,923 ----
  
      for (mp = methodlist->next; mp != NULL; mp = mp->next)
  	if (mp->type==ptype_classproc && mp->defined)
+ 	    if (strcmp( "Destroy", mp->name) == 0) continue;
+ 	    else
  	    (void) fprintf(exportfile,
  			   ",\n    (long (*)()) %s", getFuncName(mp));
  
***************
*** 1041,1058 ****
          }
          (void) fprintf(exportfile, "}\n\n");
  
!         (void) fprintf(exportfile, "void %s__Destroy(classID, self)\n", FinalClassName);
!         (void) fprintf(exportfile, "struct classheader *classID;\n");
!         (void) fprintf(exportfile, "struct %s *self;\n{\n", FinalClassName);
!         if (finalizeobject || FinalParentName[0])
!             (void) fprintf(exportfile, "    %s__Finalize(classID, self);\n", FinalClassName);
!         if (deallocate)  {
!             (void) fprintf(exportfile, "    %s__Deallocate(classID, self);\n", FinalClassName);
!         }
!         else  {
!             (void) fprintf(exportfile, "    free(self);\n");
!         }
!         (void) fprintf(exportfile, "}\n");
      }	/* bottom of if (classDefinition) */
      
      (void) fprintf(exportfile, "\nstruct classinfo *%s__GetClassInfo(classID, versionnumber)\n", FinalClassName);
--- 1046,1065 ----
          }
          (void) fprintf(exportfile, "}\n\n");
  
! 	if ( ! destroydefined ) {
!             (void) fprintf(exportfile, "void %s__Destroy(classID, self)\n", FinalClassName);
!             (void) fprintf(exportfile, "struct classheader *classID;\n");
!             (void) fprintf(exportfile, "struct %s *self;\n{\n", FinalClassName);
!             if (finalizeobject || FinalParentName[0])
!                 (void) fprintf(exportfile, "    %s__Finalize(classID, self);\n", FinalClassName);
!             if (deallocate)  {
! 		(void) fprintf(exportfile, "    %s__Deallocate(classID, self);\n", FinalClassName);
!             }
!             else  {
!                 (void) fprintf(exportfile, "    free(self);\n");
!             }
!             (void) fprintf(exportfile, "}\n");
! 	}
      }	/* bottom of if (classDefinition) */
      
      (void) fprintf(exportfile, "\nstruct classinfo *%s__GetClassInfo(classID, versionnumber)\n", FinalClassName);
***************
*** 1424,1429 ****
--- 1431,1439 ----
  		case name_InitializeClass:
  		    initializeclass = TRUE;
  		    break;
+ 		case name_Destroy:
+ 		    destroydefined = TRUE;
+ 		    break;
  	    }
  	}
      }
***************
*** 2465,2470 ****
--- 2475,2481 ----
      deallocate = FALSE;
  
      initializeclass = FALSE;
+     destroydefined = FALSE;
  
      NumDirectories = 0;	    /* start off with no added search directories */
  
*** ./overhead/class/pp/classpp.l.orig	Wed Nov 22 12:33:23 1989
--- ./overhead/class/pp/classpp.l	Sun Jan 14 16:18:29 1990
***************
*** 23,28 ****
--- 23,29 ----
  Allocate[^A-Z0-9a-z_]		return(class_TokName(name_Allocate));
  Deallocate[^A-Z0-9a-z_]		return(class_TokName(name_Deallocate));
  InitializeClass[^A-Z0-9a-z_]		return(class_TokName(name_InitializeClass));
+ Destroy[^A-Z0-9a-z_]		return(class_TokName(name_Destroy));
  
  self[^A-Z0-9a-z_]			return(class_TokName(name_Self));
  thisobject[^A-Z0-9a-z]		return(class_TokName(name_ThisObject));
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0