home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume8
/
mgt
/
part01
/
tree.c
< prev
Wrap
C/C++ Source or Header
|
1990-02-23
|
6KB
|
371 lines
/*
"mgt" Copyright 1990 Shodan
All Rights Reserved.
Program by Greg Hale
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that this entire comment and copyright notice appear in all
copies and that both that copyright notice and this permission notice
appear in supporting documentation. No representations are made about
the suitability of this software for any purpose. It is provided "as
is" without express or implied warranty.
Please send copies of extensions to:
hale@scam.berkeley.edu
128.32.138.4 scam.berkeley.edu sting sting.Berkeley.EDU
Donations for the 'From My Go Teacher' series may be sent to:
Shodan
P.O. Box 4456
Berkeley, CA 94704
(415) 849-9475
*/
#include "mgt.h"
#include "var.h"
#include "file.h"
#define MAXNODE (65536/sizeof(node))
static char bitmask[] = {1<<0,1<<1,1<<2,1<<3,1<<4,1<<5,1<<6,1<<7,1<<8};
#define byteNumXY(x,y) (((x)+(y)*19)/8)
#define bitNumXY(x,y) (((x)+(y)*19)%8)
static depthrec d;
static int newNodeNum;
FUNCTION void clearCoordList(c)
coordListP c;
{
int i;
for (i=8; i--;)
c->b[i]=0;
}
FUNCTION boolean getCoord(x,y,c)
int x,y;
coordListP c;
{
return c->b[byteNumXY(x,y)] & bitmask[bitNumXY(x,y)];
}
FUNCTION void setCoord(x,y,c)
int x,y;
coordListP c;
{
int bytenum,bitnum;
bytenum = byteNumXY(x,y);
bitnum = bitNumXY(x,y);
c->b[bytenum] |= bitmask[bitnum];
}
FUNCTION void clearCoord(x,y,c)
int x,y;
coordListP c;
{
int bytenum;
bytenum = byteNumXY(x,y);
c->b[bytenum] &= (~bitmask[bitNumXY(x,y)]);
}
FUNCTION void initNodes()
{
newNodeNum = 1;
}
FUNCTION nodep newNode()
{
nodep new;
new = (nodep)calloc(1,sizeof(node));
if (!new)
barf("Memory allocation failure (newnode)");
new->nodeNum = newNodeNum++;
return new;
}
FUNCTION void freeNode(n)
nodep n;
{
if (n) {
delNode(n->nextSibling);
delNode(n->child);
free(n);
}
}
FUNCTION char *dupStr(s)
char *s;
{
char *c;
c = (char *)malloc((unsigned)strlen(s)+1);
if (!c)
barf("Memory allocation failure (dupstr)");
strcpy(c,s);
return c;
}
/* not done yet */
FUNCTION void freeProps(n)
nodep n;
{
switch (n->p->t) {
}
}
FUNCTION void delNode(n)
nodep n;
{
freeProps(n);
free(n);
}
FUNCTION void addprop(n,p)
nodep n;
property *p;
{
p->next = n->p;
n->p = p;
}
FUNCTION property *getprop(n,t)
nodep n;
token t;
{
property *p;
p = n->p;
while (p && p->t != t)
p = p->next;
return p;
}
FUNCTION int treeCountSiblings(n)
{
int i;
nodep n1;
n1 = child(n,false);
i = 0;
while (n1) {
n1 = nextSibling(n1,false);
i++;
}
return i;
}
FUNCTION nodep nthChild(n,c,bSearch) /* nodep, int, boolean */
nodep n;
int c;
boolean bSearch;
{
if (n->child) {
n = child(n,bSearch);
while (c-- && n)
n = nextSibling(n,bSearch);
} else {
n = 0;
}
return n;
}
/*
*
*
* TREE WALK functions
* KEEP TRACK OF DEPTH AS WELL
*
*
*
*/
FUNCTION nodep parent(n,bSearch)
nodep n;
boolean bSearch;
{
if (bSearch && n->parent)
--d.depth;
return n->parent;
}
FUNCTION nodep child(n,bSearch)
nodep n;
boolean bSearch;
{
if (bSearch && n->child)
d.d[++d.depth]=0;
return n->child;
}
FUNCTION nodep lastSibling(n,bSearch)
nodep n;
boolean bSearch;
{
if (bSearch && n->lastSibling)
d.d[d.depth]--;
return n->lastSibling;
}
FUNCTION nodep nextSibling(n,bSearch)
nodep n;
boolean bSearch;
{
if (bSearch && n->nextSibling)
d.d[d.depth]++;
return n->nextSibling;
}
FUNCTION nodep treeLastSibling(n,bSearch)
nodep n;
boolean bSearch;
{
/* n = treeFirstSibling(n,bSearch); */
while (n->nextSibling) {
if (bSearch)
d.d[d.depth]++;
n = n->nextSibling;
}
return n;
}
FUNCTION nodep treeFirstSibling(n,bSearch)
nodep n;
boolean bSearch;
{
if (bSearch)
d.d[d.depth] = 0;
while(n->lastSibling)
n = n->lastSibling;
}
/* go to next node down the tree. Stop if at bottom. */
FUNCTION nodep treeDown(n,bSearch)
nodep n;
boolean bSearch;
{
if (n->child) {
BUG("treeDown: going down\n");
return child(n,bSearch);
} else {
BUG("treeDown: stop\n");
return n;
}
}
/* backup, stop if at top */
FUNCTION nodep treeUp(n,bSearch)
nodep n;
boolean bSearch;
{
if (n->parent) {
BUG("treeUp: going up\n");
return parent(n,bSearch);
} else {
BUG("treeUp: staying\n");
return n;
}
}
/* go to next node backing up the tree only */
FUNCTION nodep treeNextUp(n,bSearch)
nodep n;
boolean bSearch;
{
if (n->nextSibling) {
BUG("nextSibling ");
return nextSibling(n,bSearch);
} else if (n->parent) {
BUG("nextup-parent ");
while (n->parent && !n->nextSibling)
n = parent(n,bSearch);
if (n->nextSibling)
return nextSibling(n,bSearch);
else return n;
} else if (n->child) {
BUG("child ");
return child(n,bSearch);
} else {
BUG("current ");
return n;
}
}
/* go to next node, backup if neccessary */
FUNCTION nodep treeNext(n,bSearch)
nodep n;
boolean bSearch;
{
nodep r;
BUG("treeNext:");
if (n != (r = treeDown(n,bSearch))) {
BUG("going down ");
} else {
BUG("going up ");
r = treeNextUp(n,bSearch);
}
BUG("\n");
return r;
}
FUNCTION nodep lastChildOfLastSibling(n,bSearch)
nodep n;
boolean bSearch;
{
while(n->nextSibling)
n = nextSibling(n,bSearch);
if (n->child)
return lastChildOfLastSibling(child(n,bSearch),bSearch);
else return n;
}
/* go to next node, backup if neccessary */
FUNCTION nodep treeLast(n,bSearch)
nodep n;
boolean bSearch;
{
nodep r;
if (n->lastSibling) {
n = lastSibling(n,bSearch);
if (n->child)
r = lastChildOfLastSibling(child(n,bSearch),bSearch);
else
r = n;
} else if (n->parent) {
/* r = treeLast(parent(n,bSearch),bSearch); */
r = parent(n,bSearch);
} else if (n->child) {
r = lastChildOfLastSibling(child(n,bSearch),bSearch);
} else {
r = n;
}
return r;
}
FUNCTION int treeWillBranch(n)
nodep n;
{
return n->child && n->child->nextSibling;
}
FUNCTION void initDepth()
{
d.depth = 0;
d.d[0] = 0;
}
FUNCTION void updateDepth()
{
/* (*io->printDepth)(&d); */
}