169 lines
4.8 KiB
C
169 lines
4.8 KiB
C
|
|
/*
|
|||
|
|
* DBcount.c --
|
|||
|
|
*
|
|||
|
|
* Functions to compute statistics on the paint of
|
|||
|
|
* a tree of cells.
|
|||
|
|
*
|
|||
|
|
* *********************************************************************
|
|||
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|||
|
|
* * Permission to use, copy, modify, and distribute this *
|
|||
|
|
* * software and its documentation for any purpose and without *
|
|||
|
|
* * fee is hereby granted, provided that the above copyright *
|
|||
|
|
* * notice appear in all copies. The University of California *
|
|||
|
|
* * makes no representations about the suitability of this *
|
|||
|
|
* * software for any purpose. It is provided "as is" without *
|
|||
|
|
* * express or implied warranty. Export of this software outside *
|
|||
|
|
* * of the United States of America may require an export license. *
|
|||
|
|
* *********************************************************************
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#ifndef lint
|
|||
|
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/database/DBcount.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|||
|
|
#endif /* not lint */
|
|||
|
|
|
|||
|
|
#include <stdio.h>
|
|||
|
|
#include "utils/magic.h"
|
|||
|
|
#include "utils/hash.h"
|
|||
|
|
#include "utils/geometry.h"
|
|||
|
|
#include "tiles/tile.h"
|
|||
|
|
#include "database/database.h"
|
|||
|
|
#include "database/databaseInt.h"
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
* ----------------------------------------------------------------------------
|
|||
|
|
*
|
|||
|
|
* DBTreeCountPaint --
|
|||
|
|
*
|
|||
|
|
* Allow the client to compute statistics on the paint in a subtree.
|
|||
|
|
* The client provides three functions: 'count', 'hiercount', and
|
|||
|
|
* 'cleanup', which should be of the following form:
|
|||
|
|
*
|
|||
|
|
* int
|
|||
|
|
* count(def, cdata)
|
|||
|
|
* CellDef *def;
|
|||
|
|
* ClientData cdata;
|
|||
|
|
* {
|
|||
|
|
* }
|
|||
|
|
*
|
|||
|
|
* The 'count' function is applied in a pre-order traversal of the
|
|||
|
|
* cell graph; if it returns 0 then the subcells of 'def' are visited;
|
|||
|
|
* if it returns 1 then the subcells are not visited.
|
|||
|
|
*
|
|||
|
|
* int
|
|||
|
|
* hiercount(parent, uses, child, cdata)
|
|||
|
|
* CellDef *parent, *child;
|
|||
|
|
* int uses; /# Scale factor: number of times child
|
|||
|
|
* # is used by parent
|
|||
|
|
* #/
|
|||
|
|
* ClientData cdata;
|
|||
|
|
* {
|
|||
|
|
* }
|
|||
|
|
*
|
|||
|
|
* The 'hiercount' function is applied in a post-order traversal of
|
|||
|
|
* the cell graph, ie, it is applied only after all children of a
|
|||
|
|
* cell have been visited.
|
|||
|
|
*
|
|||
|
|
* int
|
|||
|
|
* cleanup(def, cdata)
|
|||
|
|
* CellDef *def;
|
|||
|
|
* ClientData cdata;
|
|||
|
|
* {
|
|||
|
|
* }
|
|||
|
|
*
|
|||
|
|
* The 'cleanup' function is applied in a pre-order traversal of the
|
|||
|
|
* cell graph; if it returns 0 then the subcells of 'def' are visited;
|
|||
|
|
* if it returns 1 then the subcells are not visited.
|
|||
|
|
*
|
|||
|
|
* Results:
|
|||
|
|
* None.
|
|||
|
|
*
|
|||
|
|
* Side effects:
|
|||
|
|
* Applies the client procedures as described above.
|
|||
|
|
* The client is free to use each CellDef's cd_client
|
|||
|
|
* field, but should reset this field to zero when the
|
|||
|
|
* cleanup procedure is supplied.
|
|||
|
|
*
|
|||
|
|
* Algorithm:
|
|||
|
|
* We first visit all CellDefs in the tree, applying the
|
|||
|
|
* client's 'count' procedure to each CellDef.
|
|||
|
|
*
|
|||
|
|
* Next, we make a second pass over the cells, applying
|
|||
|
|
* the client's 'hiercount' procedure to each CellDef
|
|||
|
|
* in post-order (ie, the 'hiercount' procedure is first
|
|||
|
|
* applied recursively to all the subtrees of a given
|
|||
|
|
* def before being applied to the def itself).
|
|||
|
|
*
|
|||
|
|
* Finally, we make a pass over all CellDefs and apply
|
|||
|
|
* the client's 'cleanup' procedure.
|
|||
|
|
*
|
|||
|
|
* ----------------------------------------------------------------------------
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
struct countArg
|
|||
|
|
{
|
|||
|
|
int (*ca_count)();
|
|||
|
|
int (*ca_hiercount)();
|
|||
|
|
ClientData ca_cdata;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
DBTreeCountPaint(def, count, hiercount, cleanup, cdata)
|
|||
|
|
CellDef *def;
|
|||
|
|
int (*count)();
|
|||
|
|
int (*hiercount)();
|
|||
|
|
int (*cleanup)();
|
|||
|
|
ClientData cdata;
|
|||
|
|
{
|
|||
|
|
struct countArg ca;
|
|||
|
|
int dbCountFunc(), dbCountHierFunc();
|
|||
|
|
|
|||
|
|
ca.ca_cdata = cdata;
|
|||
|
|
|
|||
|
|
/* Apply the count procedure to each cell */
|
|||
|
|
ca.ca_count = count;
|
|||
|
|
if ((*count)(def, cdata) == 0)
|
|||
|
|
(void) DBCellEnum(def, dbCountFunc, (ClientData) &ca);
|
|||
|
|
|
|||
|
|
/* Now the hiercount */
|
|||
|
|
ca.ca_hiercount = hiercount;
|
|||
|
|
(void) DBCellEnum(def, dbCountHierFunc, (ClientData) &ca);
|
|||
|
|
|
|||
|
|
/* Now the cleanup */
|
|||
|
|
ca.ca_count = cleanup;
|
|||
|
|
if ((*cleanup)(def, cdata) == 0)
|
|||
|
|
(void) DBCellEnum(def, dbCountFunc, (ClientData) &ca);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
dbCountFunc(use, ca)
|
|||
|
|
CellUse *use;
|
|||
|
|
struct countArg *ca;
|
|||
|
|
{
|
|||
|
|
if ((*ca->ca_count)(use->cu_def, ca->ca_cdata) == 0)
|
|||
|
|
(void) DBCellEnum(use->cu_def, dbCountFunc, (ClientData) ca);
|
|||
|
|
return (0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
dbCountHierFunc(use, ca)
|
|||
|
|
CellUse *use;
|
|||
|
|
struct countArg *ca;
|
|||
|
|
{
|
|||
|
|
int nx, ny;
|
|||
|
|
|
|||
|
|
(void) DBCellEnum(use->cu_def, dbCountHierFunc, (ClientData) ca);
|
|||
|
|
if (use->cu_xlo > use->cu_xhi)
|
|||
|
|
nx = use->cu_xlo - use->cu_xhi + 1;
|
|||
|
|
else
|
|||
|
|
nx = use->cu_xhi - use->cu_xlo + 1;
|
|||
|
|
|
|||
|
|
if (use->cu_ylo > use->cu_yhi)
|
|||
|
|
ny = use->cu_ylo - use->cu_yhi + 1;
|
|||
|
|
else
|
|||
|
|
ny = use->cu_yhi - use->cu_ylo + 1;
|
|||
|
|
|
|||
|
|
(*ca->ca_hiercount)(use->cu_parent, nx * ny, use->cu_def, ca->ca_cdata);
|
|||
|
|
return (0);
|
|||
|
|
}
|