|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T o
Length: 8845 (0x228d)
Types: TextFile
Names: »object.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Life/object.c«
#ifdef SCCS
static char *sccsid = "@(#)object.c 1.17 2/2/85";
static char *cpyrid = "@(#)Copyright (C) 1985 by D Bell";
#endif
#include "life.h"
/*
* Find the given named object. Returns NULL if nonexistant. The special
* name of "." means the current object. The special name of ".." means
* the previous object.
*/
struct object *
findobject(str)
register char *str; /* name to find */
{
register struct object *obj; /* current object */
if (str[0] == '.') { /* check for "." or ".." */
if (str[1] == '\0') return(curobj);
if ((str[1] == '.') && (str[2] == '\0')) return(prevobj);
}
for (obj = objects; obj; obj = obj->o_next) {
if (strcmp(obj->o_name, str) == 0) return(obj);
}
return(NULL);
}
/* Create the given named object, or return it if it already exists. */
struct object *
getobject(str)
register char *str; /* name to find */
{
register struct object *obj; /* current object */
for (obj = objects; obj; obj = obj->o_next) {
if (strcmp(obj->o_name, str) == 0) return(obj);
}
if (strlen(str) > MAXNAME) error("Object name too long");
if ((reserve==0) && BADNAME(str)) error("Cannot create reserved name");
obj = allocobject();
obj->o_next = objects;
objects = obj;
strcpy(obj->o_name, str);
return(obj);
}
/*
* Set an object as the current one. The old current object is remembered
* so that it can be referenced using "..". This cancels any insert mode.
*/
setobject(obj)
register struct object *obj; /* new object to set */
{
mode = M_MOVE;
if (obj == curobj) return;
prevobj = curobj;
curobj = obj;
redraw = 1;
}
/* Delete all cells of an object */
zeroobject(obj)
register struct object *obj;
{
register struct row *rp;
rp = obj->o_firstrow;
if (rp == termrow) return;
for (; rp != termrow; rp = rp->r_next) {
if (rp->r_firstcell == termcell) continue;
rp->r_lastcell->c_next = freecells;
freecells = rp->r_firstcell;
obj->o_count -= rp->r_count;
}
obj->o_lastrow->r_next = freerows;
freerows = obj->o_firstrow;
obj->o_firstrow = termrow;
obj->o_lastrow = NULL;
}
/*
* Destroy the existence of an object. If it is the current object,
* switch the current object back to the previous object.
*/
destroyobject(obj)
register struct object *obj; /* object to delete */
{
register struct object *pobj; /* previous object */
if (obj == NULL) return;
if (obj->o_reserved) error("Cannot destroy reserved object");
if (obj == prevobj) prevobj = mainobject;
if (obj == curobj) {
curobj = prevobj;
prevobj = mainobject;
redraw = 1;
}
zeroobject(obj);
if (objects == obj) { /* first object in list */
objects = obj->o_next;
obj->o_next = freeobjects;
freeobjects = obj;
return;
}
for (pobj = objects; pobj->o_next != obj; pobj = pobj->o_next) ;
pobj->o_next = obj->o_next;
obj->o_next = freeobjects;
freeobjects = obj;
}
/*
* Move one object to another. The source object is zeroed, and the
* previous contents of the destination object are lost.
*/
moveobject(sobj, dobj)
register struct object *sobj; /* source object */
register struct object *dobj; /* destination object */
{
if (sobj == dobj) error("Moving object to itself");
zeroobject(dobj);
dobj->o_currow = sobj->o_currow;
dobj->o_curcol = sobj->o_curcol;
dobj->o_minrow = sobj->o_minrow;
dobj->o_maxrow = sobj->o_maxrow;
dobj->o_mincol = sobj->o_mincol;
dobj->o_maxcol = sobj->o_maxcol;
dobj->o_scale = sobj->o_scale;
dobj->o_autoscale = sobj->o_autoscale;
dobj->o_prow = sobj->o_prow;
dobj->o_pcol = sobj->o_pcol;
dobj->o_firstrow = sobj->o_firstrow;
dobj->o_lastrow = sobj->o_lastrow;
dobj->o_count = sobj->o_count;
sobj->o_firstrow = termrow;
sobj->o_lastrow = NULL;
sobj->o_count = 0;
}
/*
* Add one object to another. The source object is unchanged. The
* destination object will get all cells from both objects. If disp is
* RELATIVE, the object is displaced as specified by the two object's cursor
* positions. Otherwise, the addition is performed with absolute coordinates.
*/
addobject(sobj, dobj, disp)
register struct object *sobj; /* source object */
register struct object *dobj; /* destination object */
{
register struct row *rp; /* current row */
register struct cell *cp; /* current cell */
register int newrow; /* new row number */
int rowdisp, coldisp; /* displacements */
if (sobj == dobj) error("Adding object to itself");
rowdisp = 0;
coldisp = 0;
if (disp == RELATIVE) {
rowdisp = dobj->o_currow - sobj->o_currow;
coldisp = dobj->o_curcol - sobj->o_curcol;
}
for (rp = sobj->o_firstrow; rp != termrow; rp = rp->r_next) {
newrow = rp->r_row + rowdisp;
for (cp = rp->r_firstcell; cp != termcell; cp = cp->c_next) {
addcell(dobj, newrow, cp->c_col + coldisp);
}
}
}
/*
* Copy one object to another. The source object is unchanged.
* The current contents of the destination object are lost.
*/
copyobject(sobj, dobj)
register struct object *sobj; /* source object */
register struct object *dobj; /* destination object */
{
if (sobj == dobj) error("Copying object to itself");
zeroobject(dobj);
addobject(sobj, dobj, ABSOLUTE);
dobj->o_currow = sobj->o_currow;
dobj->o_curcol = sobj->o_curcol;
dobj->o_minrow = sobj->o_minrow;
dobj->o_maxrow = sobj->o_maxrow;
dobj->o_mincol = sobj->o_mincol;
dobj->o_maxcol = sobj->o_maxcol;
dobj->o_scale = sobj->o_scale;
dobj->o_autoscale = sobj->o_autoscale;
dobj->o_prow = sobj->o_prow;
dobj->o_pcol = sobj->o_pcol;
}
/*
* Show the list of objects. If all is nonzero, all objects will be
* shown. Otherwise, only objects not starting with a period are shown.
*/
listobjects(all)
{
register struct object *obj; /* current object */
register int ch; /* current character */
int minrow, maxrow, mincol, maxcol; /* current bounds */
dpywindow(0, -1, 0, -1);
dpystr("cells height width gen scale object\n");
dpystr("----- ------ ----- --- ----- ------\n");
for (obj = objects; obj; obj = obj->o_next) {
if ((all == 0) && (obj->o_name[0] == '.')) continue;
ch = ' ';
if (obj == prevobj) ch = '+';
if (obj == curobj) ch = '*';
minmax(obj, &minrow, &maxrow, &mincol, &maxcol);
dpyprintf("%d\t%d\t%d\t%d\t%d\t%c %s\n",
obj->o_count, (maxrow - minrow + 1),
(maxcol - mincol + 1), obj->o_gen,
obj->o_scale, ch, obj->o_name);
}
dpyprintf("\n\
In object column, '*' = current object, '+' = previous object\n");
if (all == 0)
dpyprintf("Use -a to show objects beginning with '.'\n");
spacewait();
}
/*
* Find the minimum and maximum row and column numbers for an object.
* If there are no cells in the object, the mins will be one more than
* the maxes. Returns nonzero if the object has no cells.
*/
minmax(obj, minrow, maxrow, mincol, maxcol)
struct object *obj; /* object to examine */
long *minrow, *maxrow, *mincol, *maxcol; /* pointers to result */
{
register struct row *rp; /* current row */
register int maxr, minr, maxc, minc; /* current results */
int err; /* return value */
minr = INFINITY;
maxr = -INFINITY;
minc = INFINITY;
maxc = -INFINITY;
err = 1;
for (rp = obj->o_firstrow; rp != termrow; rp = rp->r_next) {
if (rp->r_firstcell == termcell) continue;
if (rp->r_row < minr) minr = rp->r_row;
maxr = rp->r_row;
if (rp->r_firstcell->c_col<minc) minc = rp->r_firstcell->c_col;
if (rp->r_lastcell->c_col>maxc) maxc = rp->r_lastcell->c_col;
err = 0;
}
if (err) { /* no cells in object */
minr = 1;
maxr = 0;
minc = 1;
maxc = 0;
}
*minrow = minr;
*maxrow = maxr;
*mincol = minc;
*maxcol = maxc;
return(err);
}
/*
* Search forwards for the nth next object, restarting at the top if necessary.
* If all is nonzero, or if wrap around occurs, the search will be over all
* objects. Otherwise, objects found in previous searches will be skipped.
* Returns nonzero if nothing was found.
*/
searchobject(obj, count, all)
register struct object *obj; /* object to search through */
{
register struct row *rp; /* current row being examined */
register struct cell *cp; /* current cell begin examined */
register long row; /* current row */
register long col; /* current column */
if (all) clearmarks(obj, MARK_SRC);
row = obj->o_currow;
col = obj->o_curcol;
for (rp = obj->o_firstrow; row > rp->r_row; rp = rp->r_next) ;
for (cp = rp->r_firstcell; col > cp->c_col; cp = cp->c_next) ;
if ((row == rp->r_row) && (col == cp->c_col) &&
((cp->c_marks & MARK_SRC) == 0)) count++;
while (1) {
if (stop) return(0);
if (cp == termcell) {
rp = rp->r_next;
if (rp == termrow) {
clearmarks(obj, MARK_SRC);
rp = obj->o_firstrow;
}
cp = rp->r_firstcell;
continue;
}
if ((cp->c_marks & MARK_SRC) == 0) {
markobject(obj, rp->r_row, cp->c_col, MARK_SRC);
if (--count <= 0) break;
}
cp = cp->c_next;
}
obj->o_currow = rp->r_row;
obj->o_curcol = cp->c_col;
return(0);
}