[gnu.gdb.bug] Bug

shin@sgtp.apple.juice (Shinichirou Sugou) (04/25/89)

Dear FSF people:

I think it maybe bug, but not sure which causes this bug, gdb or g++.  For the
present, I report to 'gdb'.

My system is, gdb-3.1, g++-1.32, Sun3/60 with OS3.4.  Whole program is
appended at the last of this letter as shar-format.

(0) Please use Sun if possible because this program uses special malloc.o file
    which is pecurial to Sun.  Also, please use GNU's make.  Sun's make will
    result in Makefile error.

(1) Make a directory and rebuild whole sources.  You know the way how to
    rebuild the program from shar-file, don't you? :-)

(2) Type 'make'.  Finally, the object named 'p' will be produced.

(3) Type 'gdb p' to invoke gdb.

(4) Set break point at grafPort::getPortRect by typing 'b grafPort::getPortRect'.

(5) Run the program.

(6) This function returns the 'portRect' (see grafPort.h and rect.h about its
    definition), its value must be...

	portRect = {left = 0, top = 0, right = 80, bottom = 24}

(7) Type 'finish' to get what is retuned.  You will see the incorrect return
    value,

	Value returned is $2 = {left = 0, top = 152880, right = 80, bottom = 0}

What is wrong?

Yours sincerely.

CAUTION: Reply-command supplied by your mail system may NOT generate
         my address correctly.
         Please use the following address instead.

         shin%sgtp.apple.juice%lkbreth.foretune.junet@uunet.uu.net

---
  Shinichirou Sugou   shin%sgtp.apple.juice%lkbreth.foretune.junet@uunet.uu.net

Program sources (as shar format) follows...

#! /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:
#	ch.cc
#	terminal.cc
#	grafPort.cc
#	charMap.cc
#	bitMatrix.cc
#	misc.cc
#	region.cc
#	point.cc
#	rect.cc
#	quickDraw.cc
#	ch.h
#	terminal.h
#	grafPort.h
#	charMap.h
#	bitMatrix.h
#	misc.h
#	region.h
#	point.h
#	rect.h
#	quickDraw.h
#	global.h
#	Makefile
#	.gdbinit
#	dlist
# This archive created: Tue Apr 25 14:16:34 1989
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'ch.cc'
then
	echo shar: "will not over-write existing file 'ch.cc'"
else
cat << \SHAR_EOF > 'ch.cc'
#include	<stream.h>   
#include	<ctype.h>   
#include	"global.h"
#include	"quickDraw.h"   
#include	"ch.h"

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Global -top- */
/**/

void ch::setOrdinary()
/*  Clear all shape flag FALSE and set it ordinary character.  */
{
   reverse = underline = blink = doubleBright = halfBright = FALSE;
}


void ch::setC(uchar c1)
{
   c = c1;
}

uchar ch::getC()
{
   return c;
}

bool ch::isReverse()
{
   return reverse;
}

bool ch::isUnderline()
{
   return underline;
}

bool ch::isBlink()
{
   return blink;
}

bool ch::isDoubleBright()
{
   return doubleBright;
}

bool ch::isHalfBright()
{
   return halfBright;
}

bool ch::isOrdinary()
{
   return !(this->isReverse() || this->isUnderline() || this->isBlink()
            || this->isDoubleBright() || this->isHalfBright());
}

void ch::setReverse(bool v)
{
   assert((v == TRUE || v == FALSE), "illegal argument");
   reverse = v;
}

void ch::setUnderline(bool v)
{
   assert((v == TRUE || v == FALSE), "illegal argument");
   underline = v;
}

void ch::setBlink(bool v)
{
   assert((v == TRUE || v == FALSE), "illegal argument");
   blink = v;
}

void ch::setDoubleBright(bool v)
{
   assert((v == TRUE || v == FALSE), "illegal argument");
   doubleBright = v;
}

void ch::setHalfBright(bool v)
{
   assert((v == TRUE || v == FALSE), "illegal argument");
   halfBright = v;
}

ch::ch(uchar c1)
{
   c = c1;
   reverse = underline = blink = doubleBright = halfBright = FALSE;
}

bool ch::isAscii()
/*  Return TRUE if character is ordinary ascii character (not kanji or hiragana).  */
{
   return isascii(c);
}

void ch::fprint(ostream& s)
/* debugging tool */
{
   s << ((c != 0) ? form("%c", c) : form("^@"));

   char *shape;
   if (this->isOrdinary())
      shape = "ordinary";
   else if (this->isReverse())
      shape = "reverse";
   else if (this->isUnderline())
      shape = "underline";
   else if (this->isBlink())
      shape = "blink";
   else if (this->isDoubleBright())
      shape = "doubleBright";
   else if (this->isHalfBright())
      shape = "halfBright";
   else
      fatal("can't happen");
   if (this->isAscii())
      s << form("(%s)", shape);
}

ostream& operator<<(ostream& s, ch c)
/* debugging tool */
{
   c.fprint(s);
   return s;
}

/**/
/* Global -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'terminal.cc'
then
	echo shar: "will not over-write existing file 'terminal.cc'"
else
cat << \SHAR_EOF > 'terminal.cc'
#include	<stream.h>   
#include	<sgtty.h>   
#include	"global.h"
#include	"quickDraw.h"   

static int ScrWidth, ScrHeight;
char PC; /* for tputs() */
char *BC; /* for tgoto */
char *UP;
short ospeed; /* for tputs() */

static const int speed[] = { 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
                                9600, 19200, 38400 };

/**/
/* Private -top- */
/**/

static fv initScreenSize(int *widthp, int *heightp) /* OK  ERROR */
{
   *widthp = tgetnum("co");
   *heightp = tgetnum("li");
   return (*widthp >0 && *heightp >0) ? OK : ERROR;
}

static void initBaudRate(short *ospeedp)
{
   sgttyb sg;
   ioctl(1, TIOCGETP, (char *)&sg);
   if (sg.sg_ospeed >= sizeof(speed)/sizeof(speed[0])) /* over the vector range */
      fatal("termcap can't get valid baud-rate");
   *ospeedp = short(speed[sg.sg_ospeed]);
}

/**/
/* Private -bottom- */
/**/

/**/
/* Global -top- */
/**/

getScrHeight()
{
   return ScrHeight;
}


getScrWidth()
{
   return ScrWidth;
}

void initTermData()
{
   static bool firstTime = TRUE;
   if (firstTime)
      firstTime = FALSE;
   else
      fatal("don't call initTermData() twice");

   char *termType = getenv("TERM");
   if (termType == NIL)
      fatal("specify a terminal type with 'setenv TERM <yourtype>'");

   /* get terminal type */
   static char termBuf[2048];
   int success = tgetent(termBuf, termType);
   if (success < 0)
      fatal("could not access the termcap data base");
   else if (success == 0)
      fatal("terminal type '%s' is not defined", termType);

   /* extract information that termcap functions use */
   static char *buf; buf = new char[strlen(termBuf)];
   char *tmp = tgetstr("pc", &buf);
   PC = tmp ? *tmp : 0;
   BC = tgetstr("le", &buf);
   UP = tgetstr("up", &buf);
   initBaudRate(&ospeed);

   /* extract various terminal information */
   if (initScreenSize(&ScrWidth, &ScrHeight) != OK)
      fatal("terminal type '%s' is not powerful", termType);
}

/**/
/* Global -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/

extern fv initScreenSize(int*, int*);
SHAR_EOF
fi
if test -f 'grafPort.cc'
then
	echo shar: "will not over-write existing file 'grafPort.cc'"
else
cat << \SHAR_EOF > 'grafPort.cc'
#include	<stream.h>
#include	"global.h"
#include	"quickDraw.h"   
#include	"point.h"
#include	"rect.h"
#include	"bitMatrix.h"
#include	"region.h"
#include	"ch.h"
#include	"charMap.h"
#include	"grafPort.h"

/*  Can't define 'static global' as g++ bug.  */
pattern White;
pattern Black;
pattern Gray;
pattern LtGray;
pattern DkGray;
cursor Arrow;
ch *Screen; /* screen bit image */
charMap ScreenBits;
long RandSeed;

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Global -top- */
/**/

point grafPort::globalToLocal(const point pt)
/*  grafPort::globalToLocal takes a point expressed in global coordinates (with the top
    left corner of the charMap as coordinate (0,0)) and converts it into the local
    coordinates of 'my' grafPort.  The global point can be obtained with the
    grafPort::localToGlobal call.  */
{
   point res = pt;
   res.add(portBits.getBounds().getTopLeft());
   return res;
}
   

point grafPort::localToGlobal(const point pt)
/*  Convert the given point from 'my' grafPort's local coordinate system into a global
    coordinate system with the origin (0,0) at the top left corner of the port's bit
    image (such as the screen).  This global point can then be compared to other global
    points, or be changed into the local coordinates of another grafPort.
    Since a rectangle is defined by two points, you can convert a rectangle into global
    coordinates by performing two LocalToGlobal calls.  You can also convert a rectangle,
    region, or polygon into global coordinates by calling rect::offset, region::offset,
    or poly::offset (the last is not implemented yet).  */
{
   point res = pt;
   res.sub(portBits.getBounds().getTopLeft());
   return res;
}

   

void grafPort::init()
/*  Reinitialize the fields of the grafPort.  Mac's initPort() does the same thing, and
    also it make the argument the current port.  But because N-window's style is OOPS,
    the image 'current port' is not supported.  */
{
   grafPort tmp;
   *this = tmp;
}

void grafPort::setPortBits(charMap cm)
/*  Set portBits of 'me' (note that this function deffers from Mac as Mac's function
    changes the device of 'thePort')to any reviously defined charMap.  This allows you to
    perform all normal drawing and calculations on a buffer other than the screen -- for
    example, a 640-by-7 output buffer for a C. Itoh printer, or a small off-screen image
    for later "stamping" onto the screen.
    Remember to prepare all fields of the charMap before you call
    grafPort::setPortBits().  */
{
   portBits = cm;
}

void grafPort::setDevice(int dv)
/*  Set device of 'me' (note that this function deffers from Mac as Mac's function
    changes the device of 'thePort'), which identifies the logical output device for
    'me'.  The Font Manager uses this information.  The initial device number is 0, which
    represents the screen.  */
{
   device = dv;
}

void grafPort::portSize(uint w, uint h)
/*  Change the size of portRect.  THIS DOES NOT AFFECT THE SCREEN; it merely changes the
    size of the "active area" of 'me'.
    The top left corner of the portRect remains at its same location; the width and
    height of the portRect are set to the given width and height.  In other words, this
    function moves the bottom right corner of the portRect to a position relative to the
    top left corner.
    grafPort::portSize() does not change the clipRgn or the visRgn, nor does it affect
    the local coordinate system of the grafPort:  it changes only the portRect's width
    and height.  Remember that all drawing occurs only in the intersection of the
    portBits.bounds and the portRect, clipped to the visRgn and the clipRgn.  */
{
   portRect.set(portRect.getLeft(), portRect.getTop(), portRect.getLeft()+w,
                portRect.getTop()+h);
}

grafPort::~grafPort()
{
   /* empty body */
}

grafPort::grafPort(const grafPort& g)
{
   if (this == &g)
      fatal("syntax error");
   *this = g;
}

void grafPort::operator=(const grafPort& g)
{
   if (this == &g) /* beware of g=g */
      return;
   device = g.device;
   portBits = g.portBits;
   portRect = g.portRect;
   visRgn = g.visRgn;
   clipRgn = g.clipRgn;
   bkPat = g.bkPat;
   fillPat = g.fillPat;
   pnLoc = g.pnLoc;
   pnSize = g.pnSize;
   pnMode = g.pnMode;
   pnPat = g.pnPat;
   pnVis = g.pnVis;
   txFont = g.txFont;
   txFace = g.txFace;
   txMode = g.txMode;
   txSize = g.txSize;
   spExtra = g.spExtra;
   fgColor = g.fgColor;
   bkColor = g.bkColor;
   colrbit = g.colrbit;
   patStretch = g.patStretch;
   picSave = g.picSave;
   rgnSave = g.rgnSave;
   polySave = g.polySave;
   grafProcs = g.grafProcs;
}   

grafPort::grafPort()
{
   device = 0; /* screen */
   portBits = ScreenBits;
   portRect = ScreenBits.getBounds();
   visRgn.rects(ScreenBits.getBounds());
   clipRgn.setRect(-300, -300, 300, 300); /* smaller region than Mac library */
//   clipRgn.setRect(-30, -30, 30, 30); /* smaller region than Mac library */
   bkPat = White;
   fillPat = Black;
   pnLoc.set(0, 0);
   pnSize.set(1, 1);
   pnMode = PatCopy;
   pnPat = Black;
   pnVis = 0;
   txFont = 0;
   txFace = NORMAL;
   txMode = SrcOr;
   txSize = 0;
   spExtra = 0;
   fgColor = BlackColor;
   bkColor = WhiteColor;
   colrbit = 0;
   patStretch = 0;
   picSave = NIL;
   rgnSave = NIL;
   polySave = NIL;
   grafProcs = NIL;
}

void initGraf()
/*  Call initGraf() once and only once at the beginning of your program to initialize
    QuickDraw.  Also, you must call initTermData() preceding initGraf() because two
    functions in initTermData(), getScrWidth() and getScrHeight(), are used.
    It initializes the QuickDraw global variables llistd below.
    ------------------------------------------------------------------------
    variable	type		initial-setting
    ------------------------------------------------------------------------
    White	pattern         all-white pattern
    Black	pattern         all-black pattern
    Gray	pattern         50% gray pattern
    LtGray	pattern         25% gray pattern
    DkGray	pattern         75% gray pattern
    Arrow	cursor          inversed space (black square)
    Screen	ch*		screen bit image
    ScreenBits	charMap         screen, (0, 0, getScrWidth(), getScrHeight())
    RandSeed	long            1
*/
{
   static bool firstTime = TRUE;
   if (firstTime)
      firstTime = FALSE;
   else
      fatal("don't call initGraf() twice");
   
   White.setC(SPACE); White.setOrdinary();
   Black.setC(SPACE); Black.resetShape(); Black.setReverse(TRUE);
   Gray.setC(SPACE); Gray.resetShape(); Gray.setReverse(TRUE); /* no suitable char! */
   LtGray.setC(SPACE); LtGray.resetShape(); LtGray.setReverse(TRUE); /* no suitable char! */
   DkGray.setC(SPACE); DkGray.resetShape(); DkGray.setReverse(TRUE); /* no suitable char! */
   Arrow.setC(CARET); Arrow.setOrdinary(); /* no suitable char! */

   assert((getScrWidth() > 0 && getScrHeight() > 0), "invoke initTermData()");
   Screen = new ch[getScrWidth() * getScrHeight()];
   ScreenBits = charMap(Screen, getScrWidth(), rect(0,0,getScrWidth(), getScrHeight()));

   RandSeed = 1;
}

/**/
/* Global -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/

void grafPort::movePortTo(int leftGlobal, int topGlobal)
/*  Change the position of my grafPort's portRect.  THIS DOES NOT AFFECT THE SCREEN; it
    merely changes the location at which subsequent drawing inside the port will appear.
    The leftGlobal and topGlobal parameters set the distance between the top left corner
    of portBits.bounds and the top left corner of the new portRect.  For example,
    	g.movePortTo(256,171);
    will move the top left corner of the portRect to the center of the screen (if
    portBits is the Macintosh screen) regardless of the local coordinate system.
    Like PortSize, movePortTo does not change the clipRgn or the visRgn, nor does it
    affect the local coordinate system of the grafPort.  */
{
   point localPt = this->globalToLocal(point(leftGlobal, topGlobal));
   portRect.moveTo(localPt.getH(), localPt.getV());
}

mainn()
/* grafPort::movePortTo() Use gdb to examine the portRect's coordinates */
{
   malloc_debug(2);
   initTermData();
   initGraf();
   grafPort g1;
   while (1) {
      point pt; cin >> pt;
      g1.movePortTo(pt.getH(), pt.getV());
      cout << g1.getPortBits().getBounds() NLN;
      cout << g1.getPortRect() NLN NLN; }
}

main()
/* grafPort::getPortRect() */
{
   malloc_debug(2);
   initTermData();
   initGraf();
   grafPort g1;
   g1.getPortRect();
   cout << "end" NLN;
}
SHAR_EOF
fi
if test -f 'charMap.cc'
then
	echo shar: "will not over-write existing file 'charMap.cc'"
else
cat << \SHAR_EOF > 'charMap.cc'
#include	<stream.h>   
#include	"global.h"
#include	"quickDraw.h"   
#include	"point.h"
#include	"rect.h"
#include	"bitMatrix.h"
#include	"region.h"
#include	"ch.h"
#include	"charMap.h"   


/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Global -top- */
/**/

charMap::~charMap()
{
   /* empty body */
}

void charMap::operator=(const charMap& cm)
{
   if (this == &cm) /* beware of cm = cm */
      return;
   baseAddr = cm.baseAddr;
   rowBytes = cm.rowBytes;
   bounds = cm.bounds;
   updateRgn = cm.updateRgn;
}

charMap::charMap(const charMap& cm)
{
   if (this == &cm)
      fatal("syntax error");
   baseAddr = cm.baseAddr;
   rowBytes = cm.rowBytes;
   bounds = cm.bounds;
   updateRgn = cm.updateRgn;
}

charMap::charMap(ch *addr, int row, rect bnd)
/* It is user's responsibility to prepare suffifient character-image (bit-image) area.
   'ch' vector size of at least 'row*bnd.getHeight()' is needed.  'updateRgn' is
   initialized to the same size of 'bounds'.  */
{
   assert((addr != NIL && row >= 0), "illegal argument");
   assert(row >= bnd.getWidth(), "too large bounds");
   baseAddr = addr;
   rowBytes = row;
   bounds = bnd;
   updateRgn.rects(bounds);
}

charMap::charMap()
/*  This constructor assigns dummy value.  Don't use vanilla.  */
{
   baseAddr = NIL;
   rowBytes = 0;
}

/**/
/* Global -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'bitMatrix.cc'
then
	echo shar: "will not over-write existing file 'bitMatrix.cc'"
else
cat << \SHAR_EOF > 'bitMatrix.cc'
#include	<stream.h>   
#include	"global.h"
#include	"quickDraw.h"   
#include	"bitMatrix.h"
#include	"misc.h"   

/**/
/* Global -top- */
/**/

bool bitMatrix::colBitIsClear(uint col)
/*  Return TRUE if all the bits of specified column (scanning vertically) are CLEAR.  The
    empty matrix always returns TRUE.  */
{
   assert((col == 0 || col < width), "lllegal argument");
   for (uint i = 0; i < height; i++)
      if (get(col, i) == SET)
         return FALSE;
   return TRUE;
}

bool bitMatrix::lineBitIsClear(uint line)
/*  Return TRUE if all the bits of specified line (scanning horizontally) are CLEAR.  The
    empty matrix always returns TRUE.  */
{
   assert((line == 0 || line < height), "lllegal argument");
   for (uint i = 0; i < width; i++)
      if (get(i, line) == SET)
         return FALSE;
   return TRUE;
}

bool bitMatrix::equal(bitMatrix bm)
/*  Return TRUE if two bitMatrix 'me' and 'bm' are equal or FALSE if not.  The two
    bitMatrixs must have identical sizes and bit status to be considered to be equal.  */
{
   if (width != bm.width || height != bm.height)
      return FALSE;
   for (uint w = 0; w < width; w++)
      for (uint h = 0; h < height; h++)
         if (mtrx[w][h] != bm.mtrx[w][h])
            return FALSE;
   return TRUE;
}

istream& operator>>(istream& s, bitMatrix& bm)
/*  "3 5"  will bm.resize(3,5).  */
/*  For debugging.  */
{
   cout << "bitMatrix size: h v: ";
   int h = 0, v = 0; s >> h >> v;
   if (s)
      bm.resize(h, v);
   cout << "bit contents: ";
   for (uint col = 0; col < v; col++)
      for (uint line = 0; line < h; line++) {
         int bit; cin >> bit;
         bit ? bm.set(line, col) : bm.clear(line, col); }
   return s;
}

ostream& operator<<(ostream& s, const bitMatrix& m)
/*  For debugging.  */
{
   return m.fprint(s);
}

void bitMatrix::print()
/*  For debugging.  */
{
   if (width == 0 && height == 0)
      cout << "empty bitMatrix\n";
   else
      for (uint j = 0; j < height; j++) {
         for (uint i = 0; i < width; i++)
            cout << mtrx[i][j];
         cout << "\n"; }
}

ostream& bitMatrix::fprint(ostream& s)
/*  For debugging.  */
{
   if (width == 0 && height == 0)
      s << "empty bitMatrix\n";
   else
      for (uint j = 0; j < height; j++) {
         for (uint i = 0; i < width; i++)
            s << mtrx[i][j];
         s << "\n"; }
   return s;
}

bitMatrix::bitMatrix(uint w, uint h, bit val)
/*  Zero sized matrix is also legal.  */
{
   assert((val == CLEAR || val == SET), "Illegal val");
   width = w;
   height = h;
   mtrx = new bit*[width];
   for (uint i = 0; i < width; i++)
      mtrx[i] = new bit[height];
   (val == SET) ? this->set() : this->clear();
}

void bitMatrix::resize(uint w, uint h, bit val)
{
   assert((val == CLEAR || val == SET), "Illegal val");
   if (width != w || height != h) {
      /* de-allocate free space */
      for (uint i = 0; i < width; i++)
         delete mtrx[i];
      delete mtrx;

      /* re-initialize; reallocate */
      width = w;
      height = h;

      mtrx = new bit*[width];
      for (i = 0; i < width; i++)
         mtrx[i] = new bit[height]; }
   (val == SET) ? this->set() : this->clear();
}      

bit bitMatrix::get(uint col, uint line)
/*  Return the bit of 'col/line'.  */
{
   if (col >= width || line >= height)
      fatal("illegal coordinate");
   return mtrx[col][line];
}


void bitMatrix::set(uint col, uint line)
/*  Set bit of 'col/line'.  */
{
   if (col >= width || line >= height)
      fatal("illegal coordinate");
   mtrx[col][line] = SET;
}

void bitMatrix::clear(uint col, uint line)
/*  Clear bit of 'col/line'.  */
{
   if (col >= width || line >= height)
      fatal("illegal coordinate");
   mtrx[col][line] = CLEAR;
}

void bitMatrix::set()
/*  Set all bits.  */
{
   for (uint i = 0; i < width; i++)
      for (uint j = 0; j < height; j++)
         mtrx[i][j] = SET;
}

void bitMatrix::clear()
/*  Clear all bits.  */
{
   for (uint i = 0; i < width; i++)
      for (uint j = 0; j < height; j++)
         mtrx[i][j] = CLEAR;
}

void bitMatrix::operator=(bitMatrix& m)
{
   if (this == &m) /* beware of m=m */
      return;
   if (width != m.width || height != m.height)
      fatal("can't assign different size matrix");
   for (uint i = 0; i < width; i++)
      for (uint j = 0; j < height; j++)
         mtrx[i][j] = m.mtrx[i][j];
}

bitMatrix::bitMatrix(const bitMatrix& m)
{
   if (this == &m)
      fatal("syntax error");
   width = m.width;
   height =m.height;
   mtrx = new bit*[width];
   for (uint i = 0; i < width; i++)
      mtrx[i] = new bit[height];
   *this = m; /* copy bits */
}

bitMatrix::~bitMatrix()
{
   for (uint i = 0; i < width; i++)
      delete mtrx[i];
   delete mtrx;
}

/**/
/* Global -bottom- */
/**/

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'misc.cc'
then
	echo shar: "will not over-write existing file 'misc.cc'"
else
cat << \SHAR_EOF > 'misc.cc'
#include	<stream.h>
#include	<stdio.h>
#include	<stdarg.h>   
#include	"global.h"
#include	"quickDraw.h"   

const MaxCoordinate = 32767;
const MinCoordinate = -32768;

/**/
/* Global -top- */
/**/

void fatal(char *fmt...)
{
   va_list ap;
   va_start(ap, fmt);
   fprintf(stderr, "fatal error: "); vfprintf(stderr, fmt, ap); fprintf(stderr, "\n");
   va_end(ap);
   abort();
}

bool validCoordinate(int i)
/*  Return TRUE if 'i' is valid.  coordinate valid range is between 'MinCoordinate' and
    'MaxCoordinate' inclusive.  */
{
   return MinCoordinate <= i && i <= MaxCoordinate;
}

bool emptyRect(int left, int top, int right, int bottom)
/*  Return TRUE if the specified rectangle is empty.  */
{
   assert((validCoordinate(left) && validCoordinate(top) && validCoordinate(right)
           && validCoordinate(bottom)), "illegal argument");
   return bottom <= top || right <= left;
}

bit and(bit a, bit b)
/*  Return the and of 'a' and 'b'.  */
{
   assert(((a == SET || a == CLEAR) && (b == SET || b == CLEAR)), "illegal argument");
   return (a == SET && b == SET) ? SET : CLEAR;
}

bit or(bit a, bit b)
/*  Return the or of 'a' and 'b'.  */
{
   assert(((a == SET || a == CLEAR) && (b == SET || b == CLEAR)), "illegal argument");
   return (a == SET || b == SET) ? SET : CLEAR;
}

/**/
/* Global -bottom- */
/**/

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'region.cc'
then
	echo shar: "will not over-write existing file 'region.cc'"
else
cat << \SHAR_EOF > 'region.cc'
#include	<stream.h>
#include	"global.h"
#include	"quickDraw.h"   
#include	"misc.h"
#include	"point.h"
#include	"rect.h"
#include	"bitMatrix.h"
#include	"region.h"

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Global -top- */
/**/

region::~region()
{
   /* empty body */
}

void region::sect(region a, region b)
/*  Calculate the intersection of two regions and places the intersection in 'me'.  The
    dstRgn ('me') can be one of the source regions, if desired.
    If the regions do not intersect, or one of the regions is empty, the destination is
    set to the empty region (0,0,0,0).  */
{
   bBox.sect(a.bBox, b.bBox);
   uint w = bBox.getWidth(), h = bBox.getHeight();
   bMap.resize(w, h);
   uint dha = bBox.getLeft() - a.bBox.getLeft(); /* obscure */
   uint dva = bBox.getTop() - a.bBox.getTop(); /* obscure */
   uint dhb = bBox.getLeft() - b.bBox.getLeft(); /* obscure */
   uint dvb = bBox.getTop() - b.bBox.getTop(); /* obscure */
   for (int col = 0; col < w; col++)
      for (int line = 0; line < h; line++)
         (and(a.bMap.get(col+dha, line+dva), b.bMap.get(col+dhb, line+dvb)) == SET) ?
            bMap.set(col, line) : bMap.clear(col, line);
   this->compress();
}



void region::unions(region a, region b)
/*  Calculate the union of two rgions and places the union in 'me'.  The dstRgn 'me' can
    be one of the source regions, if desired.
    If both regions are empty, the destination 'me' is set to the empty region (0,0,0,0).  */
{
   bBox.unions(a.bBox, b.bBox);
   bMap.resize(bBox.getWidth(), bBox.getHeight(), CLEAR);

   /* transfer bits in 'a' as or-mode */
   uint dh = a.bBox.getLeft() - bBox.getLeft(); /* obscure */
   uint dv = a.bBox.getTop() - bBox.getTop(); /* obscure */
   uint w = a.bBox.getWidth();
   uint h = a.bBox.getHeight();
   for (int col = 0; col < w; col++)
      for (int line = 0; line < h; line++)
         (or(bMap.get(col+dh, line+dv), a.bMap.get(col, line)) == SET) ?
            bMap.set(col+dh, line+dv) : bMap.clear(col+dh, line+dv);

   /* transfer bits in 'b' as or-mode */
   dh = b.bBox.getLeft() - bBox.getLeft(); /* obscure */
   dv = b.bBox.getTop() - bBox.getTop(); /* obscure */
   w = b.bBox.getWidth();
   h = b.bBox.getHeight();
   for (col = 0; col < w; col++)
      for (line = 0; line < h; line++)
         (or(bMap.get(col+dh, line+dv), b.bMap.get(col, line)) == SET) ?
            bMap.set(col+dh, line+dv) : bMap.clear(col+dh, line+dv);

   /* settle */
   this->compress();
}

void region::diff(region a, region b)
/*  Subtract srcRgn b from a and place the dirrerence in 'me'.  The 'me' can be one of the
    source regions, if desired.
    If the first source region is empty, the destination is set to the empty region
    (0,0,0,0).  */
{
   /* it suffices to re-calculate bits of 'a' restricted to the area of sRect.
      calculation table follows...
      -------------+---------
      a      b     |  result
      -------------+---------
      SET    SET   |  CLEAR
      SET    CLEAR |  SET
      CLEAR  SET   |  CLEAR
      CLEAR  CLEAR |  CLEAR
      -------------+--------- */
   if (a == b) { /* special case */
      this->setEmpty();
      return; }
   *this = a;
   rect sRect; sRect.sect(a.bBox, b.bBox);
   uint w = sRect.getWidth();
   uint h = sRect.getHeight();
   uint dha = sRect.getLeft() - a.bBox.getLeft();
   uint dva = sRect.getTop() - a.bBox.getTop();
   uint dhb = sRect.getLeft() - b.bBox.getLeft();
   uint dvb = sRect.getTop() - b.bBox.getTop();
   for (uint col = 0; col < w; col++)
      for (uint line = 0; line < h; line++)
         if (a.bMap.get(col+dha, line+dva) == SET && b.bMap.get(col+dhb, line+dvb) == SET)
            bMap.clear(col+dha, line+dva);
   this->compress();
}

void region::xor(region a, region b)
/*  Calculate the difference between the union and the intersection of two regions and
    places the result in 'me'.  The dstRgn 'me' can be one of the source regions, if
    desired.
    If the regions are coincident, the destination is set to the empty region (0,0,0,0).  */
{
   region unions; unions.unions(a, b);
   region sect; sect.sect(a, b);
   this->diff(unions, sect);
}

void region::inset(int dh, int dv)
/*  Shrink or expand the region.  All points on the resion boundary are moved inwards a
    distance of dv vertically and dh horizontally; if dh or dv is negative, the points
    are moved outwards in that direction.  region::inset() leaves the region "centered"
    at the same position, but moves the outline in (for positive values of dh and dv) or
    out (for negative values of dh and dv).  region::inset() of a rectangular region
    works just like rect::inset().  */
{
   region tmp = *this;

   /* resize */
   this->bBox.inset(dh, dv);
   this->bMap.resize(bBox.getWidth(), bBox.getHeight(), SET);

   /* clear the bit within intersection rectangle 'r' where original's bit was clear */
   rect r; r.sect(tmp.bBox, bBox); uint w = r.getWidth(); uint h = r.getHeight();
   for (uint i = 0; i < w; i++)
      for (uint j = 0; j < h; j++)
         if (tmp.bMap.get(i+max(dh,0), j+max(dv,0)) == CLEAR) /* obscure */
            bMap.clear(i-min(dh,0), j-min(dv,0)); /* obscure */
   this->compress();
}

void region::compress()
/*  Compress region data.  Suppose the region is defined like this...
    (0, 0, 6, 6)
    000000
    001100
    001100
    001100
    001100
    000000
    As stripping outerward zeroz doesn't change the region object, region::compress()
    will redefine the region data like this...
    (2, 1, 3, 4)
    11
    11
    11
    11  */
{
   if (this->empty()) {
      if (!bBox.empty())
         this->setEmpty();
      return; }
   else if (bMap.lineBitIsClear(0) && bMap.lineBitIsClear(bBox.getHeight() - 1)) {
      this->inset(0, 1);
      this->compress(); }
   else if (bMap.colBitIsClear(0) && bMap.colBitIsClear(bBox.getWidth() - 1)) {
      this->inset(1, 0);
      this->compress(); }
}

istream& operator>>(istream& s, region& rgn)
/*  For debugging.  */
{
   s >> rgn.bBox;
   rgn.bMap.resize(rgn.bBox.getWidth(), rgn.bBox.getHeight());
   cout << form("bit contents (hor = %u  ver = %u): \n",
                rgn.bBox.getWidth(), rgn.bBox.getHeight());
   for (uint col = 0; col < rgn.bBox.getHeight(); col++)
      for (uint line = 0; line < rgn.bBox.getWidth(); line++) {
         int bit; cin >> bit;
         bit ? rgn.bMap.set(line, col) : rgn.bMap.clear(line, col); }
   return s;
}

bool region::rectIn(rect r)
/*  Check whether the given rectangle intersects 'me', and return TRUE if the intersection
    encloses at least one bit or FALSE if not.  */
{
   region rgn; rgn.rects(r); rgn.sect(rgn, *this);
   return !rgn.empty();
}

bool region::empty()
/*  Return TRUE if the region is an empty region or FALSE if not.  Some of the
    circumstances in which an empty region can be created are: a region::new() call; a
    region::copy() of an empty region; a region::setRect() or region::rect() with an empty
    rectangle as an argument; region::open(); region::offset() of an empty region;
    region::inset() with an empty region or too large an inset; region::sect() of
    nonintersecting regions; region::unions() of two empty regions; and region::diff() or
    region::xor() of two identical or nonintersecting regions.  */
{
   uint w = bBox.getWidth(); uint h = bBox.getHeight();
   for (uint i = 0; i < w; i++)
      for (uint j = 0; j < h; j++)
         if (bMap.get(i, j) == SET)
            return FALSE;
   return TRUE;
}

bool region::ptIn(point pt)
/*  Check whether the pixel below and to the right of the given coordinate point is
    within 'me', and return TRUE if so or FALSE if not.  */
{
   return bBox.ptIn(pt) && bMap.get(pt.getH(), pt.getV()) == SET;
}





bool operator==(region a, region b)
{
   return a.equal(b);
}

bool region::equal(region rgn)
/*  Compare the two regions, 'me' and 'rgn', and return TRUE if they are equal or FALSE if
    not.  The two regions must have identical sizes, shapes, and locations to be
    considered equal.  Any two empty regions are always equal.  */
{
   return bBox.equal(rgn.bBox) && bMap.equal(rgn.bMap);
}

void region::print()
/*  For debugging.  */
{
   cout << this->bBox NLN << this->bMap;
}

ostream& region::fprint(ostream& s)
/*  For debugging.  */
{
   return s << this->bBox NLN << this->bMap;
}

ostream& operator<<(ostream& s, const region& rgn)
/*  For debugging.  */
{
   return rgn.fprint(s);
}

void region::offset(int dh, int dv)
/*  Move the region on the coordinate plane, a distance of dh horizontally and dv
    vertically.  This does not affect the screen unless you subsequently call a routine to
    draw the region.  If dh and dv are positive, the movement is to the right and down; if
    either is negative, the corresponding movement is in the opposite direction.  The
    region retain its size and shape.  */
{
   bBox.offset(dh, dv);
}

void region::rects(rect r)
/*  Destroys the previous structure, then set the new structure to the rectangle specified
    by 'r'.  This is operationally synonymous with region::setRect(), except the input
    rectangle is defined by a rectangle rather than by four boundary coordinates.  */
{
   this->setRect(r.getLeft(), r.getTop(), r.getRight(), r.getBottom());
}


void region::setEmpty()
/*  Destroy the previous structure, then set 'me' to the empty region (0,0,0,0).  */
{
   this->setRect(0,0,0,0);
}

void region::copy(region rgn)
/*  Copy the mathematical structure of 'rgn'.  */
{
   *this = rgn;
}

void region::operator=(const region& rgn)
{
   if (this == &rgn) /* beware of rgn=rgn */
      return;
   if (bBox.getWidth() != rgn.bBox.getWidth() || bBox.getHeight() != rgn.bBox.getHeight())
      bMap.resize(rgn.bBox.getWidth(), rgn.bBox.getHeight());
   bBox = rgn.bBox;
   bMap = rgn.bMap;
}

region::region(const region& rgn) : bBox(0, 0, 0, 0), bMap(0, 0, SET)
{
   if (this == &rgn)
      fatal("syntax error");
   bBox = rgn.bBox;
   bMap.resize(rgn.bMap.getWidth(), rgn.bMap.getHeight());
   bMap = rgn.bMap;
}

void region::setRect(int left, int top, int right, int bottom)
/*  Destroy the previous structure of 'me', then sets the the new structure to the
    rectangle specified by left, top, right, and bottom.
    If the specified rectangle is empty (i.e., left>=right or top>=bottom), the rgion is
    set to the empty region (0,0,0,0).  */
{
   assert((validCoordinate(left) && validCoordinate(top) && validCoordinate(right)
           && validCoordinate(bottom)), "illegal argument");
   if (emptyRect(left, top, right, bottom))
      left = top = right = bottom = 0;
   bBox.set(left, top, right, bottom);
   bMap.resize(right-left, bottom-top, SET);
}

region::region() : bBox(0, 0, 0, 0), bMap(0, 0, SET)
/*  Create the empty region (0, 0, 0, 0).  This function corresponds to NewRgn() in Mac.  */
{
   /* empty body */
}

/**/
/* Global -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'point.cc'
then
	echo shar: "will not over-write existing file 'point.cc'"
else
cat << \SHAR_EOF > 'point.cc'
#include	<stream.h>
#include	"global.h"
#include	"quickDraw.h"   
#include	"point.h"
#include	"misc.h"   

/**/
/* Global -top- */
/**/

point::point()
{
   h = v = 0;
}

point::point(int hc, int vc)
{
   assert((validCoordinate(hc) && validCoordinate(vc)), "Illegal argument");
   h = hc;
   v = vc;
}

istream& operator>>(istream& s, point& p)
/* "3 5"  will p.set(3,5).  */
{
   cout << "point: h v: ";
   int h = 0, v = 0; s >> h >> v;
   if (s)
      p.set(h, v);
   return s;
}

ostream& operator<<(ostream& s, point p)
{
   return s << form("(%d,%d)", p.h, p.v);
}

bool point::ok()
{
   return validCoordinate(h) && validCoordinate(v);
}

void point::add(point pt)
/*  Add the coordinates of 'pt'.  */
{
   assert(pt.ok(), "Illegal argument");
   h += pt.h;
   v += pt.v;
   assert(this->ok(), "Illegal result");
}

void point::sub(point pt)
/*  Subtract the coordinates of 'pt'.  */
{
   assert(pt.ok(), "Illegal argument");
   h -= pt.h;
   v -= pt.v;
   assert(this->ok(), "Illegal result");
}

void point::set(int hc, int vc)
/*  Assign two integer coordinates.  */
{
   assert((validCoordinate(hc) && validCoordinate(vc)), "Illegal argument");
   h = hc;
   v = vc;
}

bool point::equal(point pt)
/*  Compare the 'pt' with 'this' and return TRUE if they are equal or FALSE if not.  */
{
   assert(pt.ok(), "Illegal argument");
   return h == pt.h && v == pt.v;
}

/**/
/* Global -bottom- */
/**/

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'rect.cc'
then
	echo shar: "will not over-write existing file 'rect.cc'"
else
cat << \SHAR_EOF > 'rect.cc'
#include	<stream.h>
#include	"global.h"
#include	"quickDraw.h"   
#include	"point.h"
#include	"rect.h"
#include	"misc.h"   

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Global -top- */
/**/

void rect::moveTo(int left, int top)
/*  Move the top left cornet to the point (left,top).  This function merely moves the
    rect posion, but not its shape.  */
{
   this->offset(left - this->getLeft(), top - this->getTop());
}

bool rect::sect(rect a, rect b)
/*  Calculate the rectangle that is the intersection of the two input input rectangles,
    and returns TRUE if they indeed intersect or FALSE if they do not.  Rectangles that
    "touch" at a line or a point are not considered intersecting, because their
    intersection rectangle (really, in this case, an intersection line or point) does not
    enclose any bits on the bitMap.
    If the rectangles do not intersect, the destination rectangle is set to (0,0,0,0).
    This function works correctly even if one of the source rectangles (argument) is also
    'me'.  */
{
   if (a.empty() || b.empty() || a.bottom <= b.top || b.bottom <= a.top || a.right <= b.left
       || b.right <= a.left) { /* not intersect */
      this->set(0, 0, 0, 0);
      return FALSE; }
   left = max(a.left, b.left);
   top = max(a.top, b.top);
   right = min(a.right, b.right);
   bottom = min(a.bottom, b.bottom);
   return TRUE;
}

bool rect::equal(rect r)
/*  Compare 'r' with 'me' and return TRUE if they are equal or FALSE if not.  The two
    rectangles must have identical boundary coordinates to be considered equal.  */
{
   return left == r.left && top == r.top && right == r.right && bottom == r.bottom;
}

void rect::pt2(point a, point b)
/*  Set 'me' the smallest rectangle which encloses the two input points.  */
{
   int ah = a.getH(), av = a.getV(), bh = b.getH(), bv = b.getV();
   left = min(ah, bh);
   right = max(ah, bh);
   top = min(av, bv);
   bottom = max(av, bv);
}

bool rect::ptIn(point pt)
/*  Determine whether the pixel below and to the right of the given coordinate point is
    enclosed in the specified rectangle 'me', and return TRUE if so or FALSE if not.  */
{
   if (this->empty())
      return FALSE;
   int h = pt.getH(); int v = pt.getV();
   return left <= h && h < right && top <= v && v < bottom;
}

void rect::unions(rect a, rect b)
/*  Calculate the smallest rectangle which encloses both input rectangles.  It works
    correctly even if one of the source rectangles is also 'me'.  */
{
   left = min(a.left, b.left);
   top = min(a.top, b.top);
   right = max(a.right, b.right);
   bottom = max(a.bottom, b.bottom);
}

istream& operator>>(istream& s, rect& r)
/* "3 5 2 9"  will r.set(3,5,2,9).  */
{
   cout << "rect: left top right bottom: ";
   int left = 0, top = 0, right = 0, bottom = 0; s >> left >> top >> right >> bottom;
   if (s)
      r.set(left, top, right, bottom);
   return s;
}

bool rect::empty()
/*  Return TRUE if 'me' is an empty rectangle.  A rectangle is considered empty if
    the bottom coordinate is equal to or less than the top or the right coordinate is
    equal to or less than the left.  */
{
   return bottom <= top || right <= left;
}
         
void rect::inset(int dh, int dv)
/*  Shrink or expand the rectangle (me).  The left and right sides are moved in by the amount
    specified by 'dh'; the top and bottom are moved towards the center by the amount
    specified by 'dv'.  If 'dh' or 'dv' is negative, the appropriate pair of sides is
    moved outwards instead of inwards.
    If the resulting width or height becomes less than 1, the rectangle is set to the
    empty rectangle (0,0,0,0).  */
{
   left += dh;
   top += dv;
   right -= dh;
   bottom -= dv;
   if (top >= bottom || left >= right)
      top = bottom = left = right = 0;
   assert(this->ok(), "Illegal rectangle data");
}

ostream& operator<<(ostream& s, rect r)
{
   return s << form("(%d,%d,%d,%d)", r.left, r.top, r.right, r.bottom);
}

void rect::offset(int dh, int dv)
/*  Move the rectangle (me) by adding 'dh' to each horizontal coordinate and 'dv' to
    each vertical coordinate.  If 'dh' and 'dv' are positive, the movement is to
    the right and down; if either is negative, the corresponding movement is in the opposite
    direction.  The rectangle retains its shape and size; it's merely moved on the
    coordinate plane.  */
{
   left += dh;
   right += dh;
   top += dv;
   bottom += dv;
   assert(this->ok(), "Illegal coordinate");
}

void rect::set(int left, int top, int right, int bottom)
/*  Assign four boundary coordinates.  */
{
   assert(rect::ok(top, left, bottom, right), "Illegal argument");

   this->left = left;
   this->top = top;
   this->right = right;
   this->bottom = bottom;
}

bool rect::ok()
{
   return validCoordinate(this->top) && validCoordinate(this->left)
      && validCoordinate(this->bottom) && validCoordinate(this->right);
}

rect::rect()
/*  Generate empty rectangle.  See the comment of 'rect.h' about empty rectangle.  */
{
   this->left = this->top = this->right = this->bottom = 0;
}

rect::rect(int left, int top, int right, int bottom)
/*  See the comment of 'rect.h' about empty rectangle.
    Assign the four boundary coordinates.  */
{
   assert(rect::ok(left, top, right, bottom), "Illegal argument");

   this->left = left;
   this->top = top;
   this->right = right;
   this->bottom = bottom;
}

bool rect::ok(int left, int top, int right, int bottom)
{
   return validCoordinate(left) && validCoordinate(top) && validCoordinate(right)
           && validCoordinate(bottom);
}

/**/
/* Global -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'quickDraw.cc'
then
	echo shar: "will not over-write existing file 'quickDraw.cc'"
else
cat << \SHAR_EOF > 'quickDraw.cc'
#include	<stream.h>   
#include	"global.h"
#include	"quickDraw.h"

const SrcCopy		= 0;
const SrcOr		= 1;
const SrcXor		= 2;
const SrcBic		= 3;
const NotSrcCopy	= 4;
const NotSrcOr		= 5;
const NotSrcxor		= 6;
const NotSrcbic		= 7;
const PatCopy		= 8;
const PatOr		= 9;
const PatXor		= 10;
const PatBic		= 11;
const NotPatCopy	= 12;
const NotPatOr		= 13;
const NotPatXor		= 14;
const NotPatBic		= 15;

const BlackColor	= 33;
const WhiteColor	= 30;
const RedColor		= 205;
const GreenColor	= 341;
const BlueColor		= 409;
const CyanColor		= 273;
const MagentaColor	= 137;
const YellowColor	= 69;

const PicLParen		= 0;
const PicRParen		= -1;

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Global -top- */
/**/

mainxz()
{}

/**/
/* Global -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'ch.h'
then
	echo shar: "will not over-write existing file 'ch.h'"
else
cat << \SHAR_EOF > 'ch.h'
class ch {
   uchar c;

   /* shape */
   bool reverse;
   bool underline;
   bool blink;
   bool doubleBright;
   bool halfBright;
 public:
   /* constructor etc */
   ch(uchar c = 0);

   /* general */
   uchar getC();
   void setC(uchar);
   void setOrdinary();
   void setReverse(bool);
   void setUnderline(bool);
   void setBlink(bool);
   void setDoubleBright(bool);
   void setHalfBright(bool);
   void resetShape()	{ this->setOrdinary(); }
   bool isOrdinary();
   bool isReverse();
   bool isUnderline();
   bool isBlink();
   bool isDoubleBright();
   bool isHalfBright();
   bool isAscii();

   /* for debugging */
   friend ostream& operator<<(ostream&, ch);
   void fprint(ostream&);
};
SHAR_EOF
fi
if test -f 'terminal.h'
then
	echo shar: "will not over-write existing file 'terminal.h'"
else
cat << \SHAR_EOF > 'terminal.h'
extern void initTermData();
extern getScrWidth();
extern getScrHeight();


extern char PC;
extern char *BC;
extern char *UP;
extern short ospeed;
SHAR_EOF
fi
if test -f 'grafPort.h'
then
	echo shar: "will not over-write existing file 'grafPort.h'"
else
cat << \SHAR_EOF > 'grafPort.h'
typedef ch pattern;
typedef ch cursor;
extern void initGraf(); /* different from Mac;  void argument */
/*  Macintosh 'thePort' variable is not need in N-window.  */
/*  Can't define 'static global' as g++ bug.  */
extern pattern White;
extern pattern Black;
extern pattern Gray;
extern pattern LtGray;
extern pattern DkGray;
extern cursor Arrow;
extern charMap ScreenBits;
extern long RandSeed;

class grafPort {
   int		device;
   charMap	portBits;
   rect		portRect;
   region	visRgn;
   region	clipRgn;
   pattern	bkPat;
   pattern	fillPat;
   point	pnLoc;
   point	pnSize;
   int		pnMode;
   pattern	pnPat;
   int		pnVis;
   int		txFont;
   style	txFace;
   int		txMode;
   int		txSize;
   int		spExtra;
   long		fgColor;
   long		bkColor;
   int		colrbit;
   int		patStretch;
   void		*picSave;
   void		*rgnSave;
   void		*polySave;
   void		*grafProcs;
 public:
   /* constructor etc */
   grafPort(); /* initial value is the same as Mac library OpenPort() */
   grafPort(const grafPort&);
   ~grafPort();
   void operator=(const grafPort&);

   /* Mac library */
   void init();
   void open(); /* not implemented */
   void close(); /* not implemented */
   void setPort(grafPort gp); /* not implemented */
   void getPort(grafPort &gpp); /* not implemented */
   void setDevice(int);
   void setPortBits(charMap);
   void portSize(uint w, uint h);
   point localToGlobal(const point pt);
   point globalToLocal(const point pt);
   void movePortTo(int leftGlobal, int topGlobal);

   /* general */
   charMap getPortBits()	{ return portBits; };
   rect getPortRect()		{ return portRect; };
};
SHAR_EOF
fi
if test -f 'charMap.h'
then
	echo shar: "will not over-write existing file 'charMap.h'"
else
cat << \SHAR_EOF > 'charMap.h'
class charMap {
   ch *baseAddr;
   int rowBytes;
   rect bounds;
   region updateRgn; /* peculiar to N-window;show newly described region since last updated */
 public:
   /* constructor etc */
   charMap(ch *baseAddr, int rowBytes, rect bounds);
   charMap();
   charMap(const charMap&);
   ~charMap();
   void operator=(const charMap&);

   /* general */
   rect getBounds()	{ return bounds; };
};
SHAR_EOF
fi
if test -f 'bitMatrix.h'
then
	echo shar: "will not over-write existing file 'bitMatrix.h'"
else
cat << \SHAR_EOF > 'bitMatrix.h'
class bitMatrix {
   uint width;
   uint height;
   bit **mtrx; /* matrix size is 'mtrx[width][height]' */
 public:
   /* constructer etc */
   bitMatrix(uint width, uint height, bit val=CLEAR);
   bitMatrix(const bitMatrix&);
   ~bitMatrix();
   void operator=(bitMatrix&);

   /* general */
   void set();
   void set(uint col, uint line);
   void clear();
   void clear(uint col, uint line);
   bit get(uint col, uint line);
   void resize(uint width, uint height, bit val=CLEAR);
   uint getWidth()	{ return width; }
   uint getHeight()	{ return height; }
   bool equal(bitMatrix);
   bool lineBitIsClear(uint line);
   bool colBitIsClear(uint col);

   /* for debugging */
   friend istream& operator>>(istream&, bitMatrix&);
   friend ostream& operator<<(ostream&, const bitMatrix&);
   ostream& fprint(ostream&);
   void print();
};
SHAR_EOF
fi
if test -f 'misc.h'
then
	echo shar: "will not over-write existing file 'misc.h'"
else
cat << \SHAR_EOF > 'misc.h'
extern void fatal(char*...);
extern bool validCoordinate(int);
extern bool emptyRect(int, int, int, int);
extern bit or(bit, bit);
extern bit and(bit, bit);


SHAR_EOF
fi
if test -f 'region.h'
then
	echo shar: "will not over-write existing file 'region.h'"
else
cat << \SHAR_EOF > 'region.h'
/*  NewRgn() and DisposeRgn() in Mac are not supported because constructor and destructor
    play role.  */

class region {
   rect bBox; /* boundary */
   bitMatrix bMap; /* CLEAR bit represents the hole */
 public:
   /* constructor etc */
   region();
   region(const region&);
   ~region();
   void operator=(const region&);

   /* Mac library */
   void copy(region);
   void setEmpty();
   void setRect(int left, int top, int right, int bottom);
   void rects(rect); /* modify name to overcome g++ bug  */
   void open(); /* not implemented */
   void close(); /* not implemented */
   void offset(int dh, int dv);
   void inset(int dh, int dv);
   void sect(region a, region b);
   void unions(region a, region b);
   void diff(region a, region b);
   void xor(region a, region b);
   bool ptIn(point);
   bool rectIn(rect);
   bool equal(region);
   bool empty();

   void frame();
   void paint();
   void erase();
   void invert();
   void fill();

   /* general */
   void compress();
   friend bool operator==(region, region);

   /* for debugging */
   friend ostream& operator<<(ostream&, const region&);
   friend istream& operator>>(istream&, region&);
   ostream& fprint(ostream&);
   void print();
};

   
SHAR_EOF
fi
if test -f 'point.h'
then
	echo shar: "will not over-write existing file 'point.h'"
else
cat << \SHAR_EOF > 'point.h'
/*  Both horizontal and vertical coordinate reside in MaxCoordinate and MinCoordinate
    inclusive.  */
class point {
   int h; /* horizontal coordinate */
   int v; /* vertical coordinate */
 public:
   /* constructor etc */
   point(int h, int v);
   point();

   /* general */
   getH()	{ return h; }
   getV()	{ return v; }
   bool ok();

   /* Mac library */
   void add(point);
   void sub(point);
   void set(int h, int v);
   bool equal(point);

   /* for debugging */
   friend ostream& operator<<(ostream&, point);
   friend istream& operator>>(istream&, point&);
};
SHAR_EOF
fi
if test -f 'rect.h'
then
	echo shar: "will not over-write existing file 'rect.h'"
else
cat << \SHAR_EOF > 'rect.h'
/*  Following four coordinate value must be 'validCoordinate(int)'.
    If the bottom coordinate of a rectangle is equal to or less than the top, or
    the right coordinate is equal to or less than the left, the rectangle is an empty
    rectangle (i.e., one that contains no bits).  */
class rect {
   int left;
   int top;
   int right;
   int bottom;
 public:
   /* constructor etc */
   rect(int left, int top, int right, int bottom);
   rect();

   /* Mac library */
   void set(int left, int top, int right, int bottom);
   void offset(int dh, int dv);
   void inset(int dh, int dv);
   bool sect(rect a, rect b);
   void unions(rect a, rect b);
   bool ptIn(point);
   void pt2(point, point);
   void ptToAngle(point, int*); /* not implemented */
   bool equal(rect);
   bool empty();

   void frame();
   void paint();
   void erase();
   void invert();
   void fill();

   /* general */
   bool ok();
   bool ok(int left, int top, int right, int bottom);
   uint getWidth()	{ return max(0, right-left); };
   uint getHeight()	{ return max(0, bottom-top); };
   int getLeft()	{ return left; };
   int getTop()		{ return top; };
   int getRight()	{ return right; };
   int getBottom()	{ return bottom; };
   point getTopLeft()	{ point pt(left, top); return pt; };
   void moveTo(int left, int top);

   /* for debugging */
   friend ostream& operator<<(ostream&, rect);
   friend istream& operator>>(istream&, rect&);
};


SHAR_EOF
fi
if test -f 'quickDraw.h'
then
	echo shar: "will not over-write existing file 'quickDraw.h'"
else
cat << \SHAR_EOF > 'quickDraw.h'

extern const SrcCopy;
extern const SrcOr;
extern const SrcXor;
extern const SrcBic;
extern const NotSrcCopy;
extern const NotSrcOr;
extern const NotSrcxor;
extern const NotSrcbic;
extern const PatCopy;
extern const PatOr;
extern const PatXor;
extern const PatBic;
extern const NotPatCopy;
extern const NotPatOr;
extern const NotPatXor;
extern const NotPatBic;

extern const BlackColor;
extern const WhiteColor;
extern const RedColor;
extern const GreenColor;
extern const BlueColor;
extern const CyanColor;
extern const MagentaColor;
extern const YellowColor;

extern const PicLParen;
extern const PicRParen;

enum bit { CLEAR = 0, SET = 1 };
enum style { NORMAL, BOLD, ITALIC, UNDERLINE, OUTLINE, SHADOW, CONDENSE, EXTEND };
SHAR_EOF
fi
if test -f 'global.h'
then
	echo shar: "will not over-write existing file 'global.h'"
else
cat << \SHAR_EOF > 'global.h'
#define max(A,B) ((A)>(B) ? (A):(B))
#define min(A,B) ((A)<(B) ? (A):(B))
#define until(A)	while (!(A))
#define forever()	while (1)   
#ifndef NO_DEBUG
#  define _assert(ex,msg) {if (!(ex)) fatal(msg);}
#  define assert(ex,msg) {if (!(ex)) fatal(msg);}
#else
#  define _assert(ex,msg) ;
#  define assert(ex,msg) ;
#endif NDEBUG

#define NLN << "\n"
#define NIL 0
#define SPACE ' '
#define CARET '^'

typedef unsigned int uint;
typedef unsigned char uchar;
enum fv { OK, ERROR };

extern const MaxCoordinate;
extern const MinCoordinate;

/* make lint silent */
void malloc_debug(int);
SHAR_EOF
fi
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
C++ = g++
C++FLAGS = -g
CPPFLAGS =
LDFLAGS =
LINT = /usr/bin/lint
LINTFLAGS = -h
LIBS = /usr/lib/debug/malloc.o -ltermlib -lm

SRC =\
	ch.cc\
	terminal.cc\
	grafPort.cc\
        charMap.cc\
        bitMatrix.cc\
        misc.cc\
        region.cc\
        point.cc\
        rect.cc\
        quickDraw.cc
OBJ := $(subst .cc,.o, $(SRC))
HDR = $(subst .cc,.h, $(SRC)) global.h
PRG = p

$(PRG): $(OBJ)
	$(C++) $(C++FLAGS) $(OBJ) -o $(PRG) $(LIBS)

clean:
	\rm -rf $(OBJ) core mon.out gmon.out

tags: $(SRC) Makefile
	etags -et $(HDR) $(SRC) main.cc dbg.cc trash.cc
	touch tags

dlist: $(HDR)
	$(C++) -MM $(SRC) > dlist

shar:
	shar $(SRC) $(HDR) Makefile .gdbinit dlist > shar.file

#
# implicit rules
#
.cc .o:
	$(C++) $(C++FLAGS) -o $@ $< $(LIBS)

%:%.sh
	cp $< $@
	chmod +x $@

#
# misc
#
.PRECIOUS: tags

#
# dependency-list.
# 
include dlist

SHAR_EOF
fi
if test -f '.gdbinit'
then
	echo shar: "will not over-write existing file '.gdbinit'"
else
cat << \SHAR_EOF > '.gdbinit'
# Initialization for N-window
unset env TERMCAP
set env TERM vt100
printf "Caution: environment TERM is set to vt100.  Modify '.gdbinit' as you wish.\n"



# Switch to the file 'p'
define dbgp
exec p
sym p
core
end

document dbgp
Switchs to the file 'p'.  Core infomation is discarded, too.
end

# Print the next node
define nn
p $->next
end
document nn
Print the next node of linear list.
end

# Print the previous node
define pn
p $->prev
end
document pn
Print the previous node of linear list.
end

# Print the next track
define nt
p $->littleBr
end
document nt
Print the next track.
end

# Print the previous track
define pt
p $->bigBr
end
document pt
Print the previous track.
end

# Print the current node
define cn
p $
end
document cn
Print the current node of linear list.
end

# Print the content of the next node
define nc
p *$->next
end
document nc
Print the content of the next node
end

# Print the content of the previous node
define pc
p *$->prev
end
document pc
Print the content of the previous node
end

# Print the content of the current node
define cc
p *$
end
document cc
Print the content of the current node
end


# Lpr Cell and SymTable data.
define prall
set $tmp = lprCellAll()
set $tmp = lprNl(5)
set $tmp = lprSymTable()
set $tmp = lprPage()
end
document prall
Lpr Cell and SymTable data.
end

# Lpr Cell.
define prcell
set $tmp = lprCellAll()
set $tmp = lprNl(5)
end
document prcell
Lpr Cell data.
end

# Lpr Symtable.
define prsym
set $tmp = lprSymTable()
set $tmp = lprPage()
end
document prsym
Lpr all Symtable data.
end
SHAR_EOF
fi
if test -f 'dlist'
then
	echo shar: "will not over-write existing file 'dlist'"
else
cat << \SHAR_EOF > 'dlist'
ch.o : ch.cc global.h quickDraw.h ch.h 
terminal.o : terminal.cc global.h quickDraw.h 
grafPort.o : grafPort.cc global.h quickDraw.h point.h \
  rect.h bitMatrix.h region.h ch.h charMap.h grafPort.h 
charMap.o : charMap.cc global.h quickDraw.h point.h \
  rect.h bitMatrix.h region.h ch.h charMap.h 
bitMatrix.o : bitMatrix.cc global.h quickDraw.h bitMatrix.h \
  misc.h 
misc.o : misc.cc global.h quickDraw.h 
region.o : region.cc global.h quickDraw.h misc.h point.h \
  rect.h bitMatrix.h region.h 
point.o : point.cc global.h quickDraw.h point.h misc.h 
rect.o : rect.cc global.h quickDraw.h point.h rect.h \
  misc.h 
quickDraw.o : quickDraw.cc global.h quickDraw.h 
SHAR_EOF
fi
exit 0
#	End of shell archive

shin@sgtp.apple.juice (Shinichirou Sugou) (04/28/89)

Dear FSF people:

I think this is bug in gdb-3.1.  My system is Sun3/60 with OS3.4, gcc-3.4, and
gdb-3.1.

Whole source program (as shar-format) is appended to the last.  Please unshar
sources and type 'make' to generate executable code named 'p' (please use GNU
make if possible, also use Sun if possible because special malloc.o file
pecurial to Sun is used here).

Type

    foo% gdb p

to invoke gdb-3.1.

Type

    (gdb) run

to run the program 'p'.

'p' will require four integers (coordinates of a rectangle).

    left top right bottom: 

Type four values like these delimiting with space (value itself is not
important in this case).

    1 2 3 4 <CR>

Again, 'p' will require two more integers (coordinates of a point).

    h v: 

Here, type Control-C to interrupt program.

The screen looks like this.

    Program received signal 2, Interrupt
    0x5e40 in read ()
    (gdb) 

Type 'bt' to examine the backtracks of entire stack.

Gdb-3.1 can't print the correct stack information.

    (gdb) bt
    #0  0x5e40 in read ()
    #1  0x3 in ?? ()

While gdb-2.8 does without problem.

    (gdb-2.8) bt
    #0  0x5e40 in read ()
    #1  0x3f10 in _doscan ()
    #2  0x3e12 in _doscan ()
    #3  0x3b4c in scanf ()
    #4  0x29f4 in readPt (ptp=(struct point *) 0xefffd50) (point.c line 87)
    #5  0x2762 in main () (rect.c line 239)


CAUTION: Reply-command supplied by your mail system may NOT generate
         my address correctly.
         Please use the following address instead.

         shin%sgtp.apple.juice%lkbreth.foretune.junet@uunet.uu.net

---
  Shinichirou Sugou   shin%sgtp.apple.juice%lkbreth.foretune.junet@uunet.uu.net


Sources follows...

#! /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:
#	rect.c
#	misc.c
#	point.c
#	rect.h
#	misc.h
#	point.h
#	global.h
#	Makefile
#	dlist
#	.gdbinit
# This archive created: Fri Apr 28 14:54:22 1989
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f 'rect.c'
then
	echo shar: "will not over-write existing file 'rect.c'"
else
cat << \SHAR_EOF > 'rect.c'
#include	<stdio.h>
#include	"global.h"
#include	"misc.h"
#include	"point.h"
#include	"rect.h"

static void setEmptyRect();

/**/
/* Global -top- */
/**/

bool
okRect(rp)
Rect *rp;
{
   return rp != NIL && okHLoc(rp->left) && okHLoc(rp->right) && okVLoc(rp->top)
      && okVLoc(rp->bottom);
}

bool
EqualRect(ap, bp)
Rect *ap;
Rect *bp;
/* EqualRect compares the two rectangles and returns TRUE if they are equal or 
FALSE if
   not.  The two rectangles must have identical boundary coordinates to be cons
idered
   equal. */
{
   assert((okRect(ap) && okRect(bp)), "invalid rect");
   return ap->left == bp->left && ap->top == bp->top && ap->right == bp->right
      && ap->bottom == bp->bottom;
}

void
UnionRect(srcAp, srcBp, dstp)
Rect *srcAp;
Rect *srcBp;
Rect *dstp;
/* UnionRect calculates the smallest rectangle which encloses both input rectan
gles.  It
   works correctly even if one of the source rectangles is also the destination
. */
{
   if (EmptyRect(srcAp) && EmptyRect(srcBp))
      setEmptyRect(dstp);
   else if (EmptyRect(srcAp))
      copyRect(srcBp, dstp);
   else if (EmptyRect(srcBp))
      copyRect(srcAp, dstp);
   else {
      dstp->left   = min(srcAp->left, srcBp->left);
      dstp->right  = max(srcAp->right, srcBp->right);
      dstp->top    = min(srcAp->top, srcBp->top);
      dstp->bottom = max(srcAp->bottom, srcBp->bottom); }
}

void
copyRect(srcp, dstp)
Rect *srcp;
Rect *dstp;                         /* result */
/* This is not the funtion of Mac toolbox.
   copyRect copies the coordinates of srcp into dstp. */
{
   assert(okRect(srcp), "invalid rect");
   dstp->left   = srcp->left;
   dstp->top    = srcp->top;
   dstp->right  = srcp->right;
   dstp->bottom = srcp->bottom;
}

bool
SectRect(srcRectAp, srcRectBp, dstRectp)
Rect *srcRectAp;
Rect *srcRectBp;
Rect *dstRectp;
/* SectRect calculates the rectangle that is the intersection of the two input
   rectangles, and returns TRUE if they indeed intersect or FALSE if they do no
t.
   Rectangles that "touch" at a line or a point are not considered intersecting
, because
   their intersection rectangle (really, in this case, an intersection line or 
point)
   does not enclose any bits on the bitMap.
   If the rectangles do not intersect, the destination rectangle is set to (0,0
,0,0).
   SectRect works correctly even if one of the source rectangles is also the de
stination. */
{
   dstRectp->left   = max(srcRectAp->left, srcRectBp->left);
   dstRectp->right  = min(srcRectAp->right, srcRectBp->right);
   dstRectp->top    = max(srcRectAp->top, srcRectBp->top);
   dstRectp->bottom = min(srcRectAp->bottom, srcRectBp->bottom);
   if (EmptyRect(dstRectp))
      setEmptyRect(dstRectp);
   return !EmptyRect(dstRectp);
}


void
InsetRect(rp, dh, dv)
Rect *rp;
int dh;
int dv;
/* InsetRect shrinks or expands the rectangle.  The left and right sides are mo
ved in by
   the amount specified by dh; the top and bottom are moved towards the center 
by the
   amount specified by dv.  If dh or dv is negative, the appropriate pair of si
des is
   moved outwards instead of inwards.  The effect is to alter the size by 2*dh
   horizontally and 2*dv vertically, with the rectangle remaining centered in t
he same
   place on the coordinate plane.
   If the resulting width or height becomes less than 1, the rectangle is set t
o the
   empty rectangle (0,0,0,0). */
{
   assert(okRect(rp), "invalid rect");
   rp->left += dh;
   rp->right -= dh;
   rp->top += dv;
   rp->bottom -= dv;
   if (EmptyRect(rp))
      setEmptyRect(rp);
}

bool
EmptyRect(rp)
Rect *rp;
/* EmptyRect returns TRUE if the given rectangle is an empty rectangle or FALSE
 if not.
   A rectangle is considered empty if the bottom coordinate is equal to or less
 than the
   top or the right coordinate is equal to or less than the left. */
{
   assert(okRect(rp), "invalid rect");
   return rp->bottom <= rp->top || rp->right <= rp->left;
}

void
OffsetRect(rp, dh, dv)
Rect *rp;                           /* result */
int dh;
int dv;
/* OffsetRect moves the rectangle by adding dh to each horizontal coordinate an
d dv to
   each vertical coordinate.  If dh and dv are positive, the movement is to the
 right and
   down; if either is negative, the corresponding movement is in the opposite d
irection.
   The rectangle retains its shape and size; it's merely moved on the coordinat
e plane.
   This does not affect the screen unless you subsequently call a routine to dr
aw within
   the rectangle. */
{
   assert((okRect(rp) && okHLoc(dh) && okVLoc(dv)), "illegal argument");
   rp->left += dh;
   rp->right += dh;
   rp->top += dv;
   rp->bottom += dv;
}

void
SetRect(rp, left, top, right, bottom)
Rect *rp;                           /* result */
int left;
int top;
int right;
int bottom;
/* SetRect assigns the four boundary coordinates to the rectangle.  The result 
is a
   rectangle with coordinates (left,top,right,bottom).
   This procedure is supplied as a utility to help you shorten your program tex
t.  If you
   want a more readable text at the expense of length, you can assign integers 
(or
   points) directly into the rectangle's fields.  There is not significant code
 size of
   execution speed advantage to either method; one's just easier to write, and 
the
   other's easier to read. */
{
   rp->left = left;
   rp->top = top;
   rp->right = right;
   rp->bottom = bottom;
   assert(okRect(rp), "invalid rect");
}

/**/
/* Global -bottom- */
/**/

/**/
/* Private -top- */
/**/

static void
setEmptyRect(rp)
Rect *rp;
/* This is not the function of Mac toolbox.
   Set the rectangle empty (0,0,0,0). */
{
   /* Don't invoke okRect(rp) because setEmptyRect is sometimes called with uni
nitialized
      variable. */
   SetRect(rp, 0, 0, 0, 0);
}

/**/
/* Private -bottom- */
/**/

/**/
/* Debug -top- */
/**/

void
readRect(rp)
Rect *rp;                         /* result */
/* Debugging. */
{
   xprintf("left top right bottom: ");
   xscanf("%d%d%d%d", &rp->left, &rp->top, &rp->right, &rp->bottom);
   assert(okRect(rp), "invalid rect");
}

void
printRect(rp)
Rect *rp;
/* Debugging. */
{
   assert(okRect(rp), "invalid rect");
   xprintf("(%d,%d,%d,%d)", rp->left, rp->top, rp->right, rp->bottom);
}

/**/
/* Debug -bottom- */
/**/

bool
PtInRect(ptp, rp)
Point *ptp;
Rect *rp;
/* PtInRect determines whether the pixel below and to the right of the given co
ordinate
   point is enclosed in the specified rectangle, and returns TRUE if so or FALS
E if not. */
{
   assert((okPt(ptp) && okRect(rp)), "invalid argument");
   return rp->left <= ptp->h && ptp->h < rp->right
      && rp->top <= ptp->v && ptp->v < rp->bottom;
}

void
main()
/* PtInRect() */
{
   Rect r;
   Point pt;

   malloc_debug(MALLOC_LEVEL);
   readRect(&r);
   forever() {
      readPt(&pt);
      xprintf("%s\n\n", PtInRect(&pt, &r) ? "within" : "no, not"); }
}
   
SHAR_EOF
fi
if test -f 'misc.c'
then
	echo shar: "will not over-write existing file 'misc.c'"
else
cat << \SHAR_EOF > 'misc.c'
#include	<stdio.h>
#include	"global.h"

/**/
/* Global -top- */
/**/

void
fatal(msg)
char *msg;
/* Print error message and dumps core. */
{
   xfprintf(stderr, "fatal error: %s\n", msg);
   (void)abort();
}

bool
okVLoc(v)
int v;
/* Return TRUE if vertical coordinate is valid. */
{
   return MIN_V <= v && v <= MAX_V;
}

bool
okHLoc(h)
int h;
/* Return TRUE if horizontal coordinate is valid. */
{
   return MIN_H <= h && h <= MAX_H;
}

/**/
/* Global -bottom- */
/**/

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Debug -top- */
/**/

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'point.c'
then
	echo shar: "will not over-write existing file 'point.c'"
else
cat << \SHAR_EOF > 'point.c'
#include	<stdio.h>
#include	"global.h"
#include	"misc.h"
#include	"point.h"

/**/
/* Global -top- */
/**/

bool
okPt(ptp)
Point *ptp;
/* Return TRUE if coordinates are valid. */
{
   return ptp != NIL && okHLoc(ptp->h) && okVLoc(ptp->v);
}

void
SubPt(srcPtp, dstPtp)
Point *srcPtp;
Point *dstPtp;                      /* result */
/* SubPt subtracts the coordinates of srcPt to the coordiantes of dstPt, and re
turn the
   result in dstPt. */
{
   assert((okPt(srcPtp) && okPt(dstPtp)), "invalid point");
   dstPtp->h -= srcPtp->h;
   dstPtp->v -= srcPtp->v;
}


void
AddPt(srcPtp, dstPtp)
Point *srcPtp;
Point *dstPtp;                      /* result */
/* AddPt adds the coordinates of srcPt to the coordiantes of dstPt, and return 
the result
   in dstPt. */
{
   assert((okPt(srcPtp) && okPt(dstPtp)), "invalid point");
   dstPtp->h += srcPtp->h;
   dstPtp->v += srcPtp->v;
}

bool
EqualPt(ptAp, ptBp)
Point *ptAp;
Point *ptBp;
/* EqualPt compares the two points and returns TRUE if they are equal or FALSE 
if not. */
{
   assert((okPt(ptAp) && okPt(ptBp)), "invalid point");
   return ptAp->h == ptBp->h && ptAp->v == ptBp->v;
}

void
SetPt(ptp, h, v)
Point *ptp;                         /* result */
int h;
int v;
/* SetPt assigns two integer coordinates to a variable of type Point*. */
{
   ptp->h = h;
   ptp->v = v;
   assert(okPt(ptp), "invalid point");
}

/**/
/* Global -bottom- */
/**/

/**/
/* Private -top- */
/**/

/**/
/* Private -bottom- */
/**/

/**/
/* Debug -top- */
/**/

void
readPt(ptp)
Point *ptp;                         /* result */
/* Debugging. */
{
   xprintf("h v: ");
   if (scanf("%d%d", &ptp->h, &ptp->v) != 2)
      fatal("scanf error");
   assert(okPt(ptp), "invalid point");
}

void
printPt(ptp)
Point *ptp;
/* Debugging tool. */
{
   assert(okPt(ptp), "invalid point");
   fprintPt(stdout, ptp);
}

void
fprintPt(stream, ptp)
FILE *stream;
Point *ptp;
/* Debugging tool. */
{
   assert(okPt(ptp), "invalid point");
   (void)fprintf(stream, "(%d,%d)", ptp->h, ptp->v);
   (void)fflush(stream);
}

/**/
/* Debug -bottom- */
/**/
SHAR_EOF
fi
if test -f 'rect.h'
then
	echo shar: "will not over-write existing file 'rect.h'"
else
cat << \SHAR_EOF > 'rect.h'
/* Mac toolbox. */
extern void SetRect();
extern bool EmptyRect();
extern void OffsetRect();
extern void InsetRect();
extern bool SectRect();
extern void UnionRect();
extern bool EqualRect();

/* General. */
extern void copyRect();
extern bool okRect();

/* Debugging. */
extern void readRect();
SHAR_EOF
fi
if test -f 'misc.h'
then
	echo shar: "will not over-write existing file 'misc.h'"
else
cat << \SHAR_EOF > 'misc.h'
extern void fatal();
extern bool okVLoc();
extern bool okHLoc();
SHAR_EOF
fi
if test -f 'point.h'
then
	echo shar: "will not over-write existing file 'point.h'"
else
cat << \SHAR_EOF > 'point.h'
/* Mac toolbox. */
extern void SetPt();
extern void AddPt();

/* General. */
extern bool okPt();

/* Debugging. */
extern void fprintPt();
extern void printPt();
extern void readPt();
SHAR_EOF
fi
if test -f 'global.h'
then
	echo shar: "will not over-write existing file 'global.h'"
else
cat << \SHAR_EOF > 'global.h'
#define NLN		(void)printf("\n")
#define TRUE		1
#define FALSE		0
#define NIL		0
#define xprintf		(void)printf
#define xfprintf	(void)fprintf
#define xscanf		(void)scanf
#define xfscanf		(void)fscanf
#define until(A)	while (!(A))
#define forever()	while (TRUE)
/* Horizontal coordinates range from -32768 to +32767, and vertical coordinates
 have the
   same range. */
#define MAX_H		32767
#define MAX_V		32767
#define MIN_H		-32768
#define MIN_V		-32768

#define max(A,B)	((A)>(B) ? (A):(B))
#define min(A,B)	((A)<(B) ? (A):(B))
#ifndef NO_DEBUG
#  define _assert(ex,msg)	{if (!(ex)) fatal(msg);}
#  define assert(ex,msg)	{if (!(ex)) fatal(msg);}
#else
#  define _assert(ex,msg)	;
#  define assert(ex,msg)	;
#endif NDEBUG

struct point {
   int h;                           /* Horizontal coordinate. */
   int v;                           /* Vertical coordinate. */
};
typedef struct point Point;

struct rect {
   int left;
   int top;
   int right;
   int bottom;
};
typedef struct rect Rect;

typedef int bool;

/* UNIX library definition. */
extern int printf();
extern int fprintf();
extern int fflush();
extern int malloc_debug();
extern int scanf();
extern int abort();

SHAR_EOF
fi
if test -f 'Makefile'
then
	echo shar: "will not over-write existing file 'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
#
# Makefile for Neuron-Toolbox	by S.Sugou 4/27 1989
#
# 'make debug' generates debug version.
# 'make lint' invokes lint. But, you should invoke 'lint.rc' instead of 'make l
int'.
# 'make tags' creates TAGS.
# 'make clean' removes some files.
# 'make shar' creates shar file.
#

CFLAGS = $(GNU_CFLAGS) -g -DMALLOC_LEVEL=2
CPPFLAGS =
LDFLAGS =
LINTFLAGS = -abchux -DMALLOC_LEVEL
LIBS = /usr/lib/debug/malloc.o -lm -lmp
PRG = p

GNU_CFLAGS = -traditional -Wall
SUN_CFLAGS = -fswitch

#debug := CC = cc.GNU
#debug := CFLAGS = $(GNU_CFLAGS) -g -DMALLOC_LEVEL=2
#debug := CC = cc.Sun
#debug := CFLAGS = $(SUN_CFLAGS) -g -DMALLOC_LEVEL=2


SRC =\
	rect.c\
	misc.c\
	point.c
 
HDR = $(SRC:.c=.h) global.h
OBJ = $(SRC:.c=.o)
LINTFILES = $(SRC:.c=.ln)

debug: $(PRG)

$(PRG): $(OBJ)
	$(CC) $(CFLAGS) $(OBJ) $(LIBS) -o $(PRG)
	@make lint

tags: $(SRC) Makefile
	etags -et $(SRC) $(HDR) main.c dbg.c trash.c
	touch tags
clean:
	-\rm -f $(OBJ) $(LINTFILES) core mon.out gmon.out

dlist: $(SRC)
	$(CC) -MM $(SRC) > dlist

lint: $(LINTFILES)
	lint $(LINTFLAGS) $(LINTFILES)
	@touch lint

shar:
	shar $(SRC) $(HDR) Makefile dlist .gdbinit > shar.file

.PRECIOUS: lint tags

#
# dependency-list.
# 
include dlist

#
# implict rule.
#
%:%.sh
	cp $< $@
	chmod +x $@
%.ln:%.c
	lint $(LINTFLAGS) -i $<
SHAR_EOF
fi
if test -f 'dlist'
then
	echo shar: "will not over-write existing file 'dlist'"
else
cat << \SHAR_EOF > 'dlist'
rect.o : rect.c global.h misc.h point.h rect.h 
misc.o : misc.c global.h 
point.o : point.c global.h misc.h point.h 
SHAR_EOF
fi
if test -f '.gdbinit'
then
	echo shar: "will not over-write existing file '.gdbinit'"
else
cat << \SHAR_EOF > '.gdbinit'
# Initialization for Neuron-Toolbox
unset env TERMCAP
set env TERM vt100
printf "Caution: environment TERM is set to vt100.  Modify '.gdbinit' as you wi
sh.\n"

# Switch to the file 'p'
define dbgp
exec p
sym p
core
end

document dbgp
Switchs to the file 'p'.  Core infomation is discarded, too.
end

# Print the next node
define nn
p $->next
end
document nn
Print the next node of linear list.
end

# Print the previous node
define pn
p $->prev
end
document pn
Print the previous node of linear list.
end

# Print the next track
define nt
p $->littleBr
end
document nt
Print the next track.
end

# Print the previous track
define pt
p $->bigBr
end
document pt
Print the previous track.
end

# Print the current node
define cn
p $
end
document cn
Print the current node of linear list.
end

# Print the content of the next node
define nc
p *$->next
end
document nc
Print the content of the next node
end

# Print the content of the previous node
define pc
p *$->prev
end
document pc
Print the content of the previous node
end

# Print the content of the current node
define cc
p *$
end
document cc
Print the content of the current node
end


# Lpr Cell and SymTable data.
define prall
set $tmp = lprCellAll()
set $tmp = lprNl(5)
set $tmp = lprSymTable()
set $tmp = lprPage()
end
document prall
Lpr Cell and SymTable data.
end

# Lpr Cell.
define prcell
set $tmp = lprCellAll()
set $tmp = lprNl(5)
end
document prcell
Lpr Cell data.
end

# Lpr Symtable.
define prsym
set $tmp = lprSymTable()
set $tmp = lprPage()
end
document prsym
Lpr all Symtable data.
end
SHAR_EOF
fi
exit 0
#	End of shell archive