/*
 * database.h --
 *
 * Definitions for the database module.
 * This file defines everything that is visible to clients
 * outside the database module.
 *
 *     ********************************************************************* 
 *     * 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.    * 
 *     *********************************************************************
 *
 * Needs to include: magic.h, tile.h
 *
 * rcsid "$Header: /usr/cvsroot/magic-7.5/database/database.h.in,v 1.18 2008/02/28 21:43:07 tim Exp $"
 */

#ifndef _DATABASE_H
#define	_DATABASE_H

#ifndef	_TILES_H
#include "tiles/tile.h"
#endif	/* _TILES_H */

#ifndef	_HASH_H
#include "utils/hash.h"
#endif	/* _HASH_H */

/* ----------------------- Tunable constants -------------------------- */

#define	MAXPLANES	64	/* Maximum number of planes per cell */

    /*
     * The "unnamed" cell.
     * This is visible only within Magic, and just determines the
     * name by which the initial cell-without-a-name appears.
     */
#define	UNNAMED	"(UNNAMED)"

/* --------------------- Tile types and masks ------------------------- */

typedef int TileType;

/*
 * Tile types are small integers (currently from 0 to TT_MAXTYPES-1).
 * They are used in constructing TileTypeBitMask bitmasks with the
 * operators defined below.  A TileTypeBitMask contains one bit for
 * each possible TileType.
 *
 * A negative value of TileType implies an error condition when received
 * from a routine returning a TileType.  Care should be taken to ensure
 * that a negative TileType is never used to index an array!
 *
 * The last TT_RESERVEDTYPES tile types are reserved for use by clients.
 * Because unsigned chars are used to hold tile types (PaintResultType),
 * this number should not be increased without changing the definition
 * of PaintResultType later in this file.
 *
 * (Magic v.7.1) Macros are generated by script scripts/makedbh,
 * with each macro appropriately constructed for the value of
 * TT_MAXTYPES.
 *
 * Each addition of a word to the bitmask increases computation
 * time on all plane operations in magic!  Choose the smallest number
 * required for the technology files used.  The obvious reaonable values
 * to choose are 96, 192, 256, or 512, corresponding to word array sizes
 * of 3, 6, 8, and 16, respectively.
 */

#define	TT_MAXTYPES		256			/* See above! */
#define	TT_RESERVEDTYPES	2			/* See above! */

/*
 * Note that the value of 5 for TT_WORDSHIFT effectively requires that
 * bits-per-word equal 32 or havoc is likely to result.
 */

#define	TT_BPW		(8 * sizeof (unsigned int))
#define	TT_WORDMASK	(TT_BPW - 1)
#define	TT_WORDSHIFT	5			/* LOG2(TT_BPW) */
#define	TT_MASKWORDS	((TT_MAXTYPES + TT_BPW - 1) / TT_BPW)

typedef struct
{
    unsigned int	tt_words[TT_MASKWORDS];
} TileTypeBitMask;

/*
 * Here's a brief note about how to interpret TileTypeBitMasks:
 * The default TT_MAXTYPES = 256 translates to 8 words.  As an
 * example, to examine TileTypeBitMask DBConnectTbl[65]
 * (in this example DBTypeLongNameTbl[65]="metal1").  In gdb,
 * use "print /x DBConnectTbl[65]" to get:
 *
 * $2 = {tt_words = {0x59800000, 0xc8cc22a6, 0x8000003b, 0xff800008, \
 *	0x38f, 0x0, 0x0, 0x0}}
 *
 * The first word represents types 0-31 (lsb to msb, respectively),
 * the second work represents types 32-63, and so forth.  From this
 * result we see that metal1 (type 65) connects to types 23, 24, 27,
 * 28, and 30 (from the 1st word), 33, 34, 37, 39, 41, and so on.
 * A quick check of DBTypeLongNameTbl[] shows that these types are
 * ndc, pdc, psc, nsc, and so forth.
 */

/*
 * Although some tile types are assigned on a technology-specific basis,
 * certain types are independent of the technology used, and are
 * defined below:
 */
#define	TT_SPACE	0	/* Space tile */
#define	TT_PAINTBASE	1	/* First non-space type */
#define TT_CHECKPAINT   1       /* DRC -- paint has changed */
#define TT_CHECKSUBCELL 2	/* DRC -- subcells have changed */
#define TT_ERROR_P      3       /* DRC -- paint error */
#define TT_ERROR_S      4       /* DRC -- subcell error */
#define TT_ERROR_PS     5       /* DRC --             */
#define TT_MAGNET	6	/* magnet for interactive router */
#define TT_FENCE	7	/* fence for interactive router */
#define TT_ROTATE	8	/* rotate for interactive router */
#define TT_SELECTBASE 	TT_MAGNET /* First selectable type */
#define	TT_TECHDEPBASE	9	/* First technology-dependent type */

#ifdef NONMANHATTAN
#define TT_DIAGONAL	0x40000000	/* Bit set for non-manhattan tiles */
#define TT_SIDE		0x20000000	/* Temporary bit set: 1 = right */
#define TT_DIRECTION	0x10000000	/* Bit set for tile split direction */
#define TT_LEFTMASK	0x00003fff	/* Type for left side of split  */
#define TT_RIGHTMASK	0x0fffc000	/* Type for right side of split */
#endif

/* Pseudo type signifying unexpanded subcells.  Never painted.  -  Only
   used in a few places, e.g.  TouchingTypes() and mzrouter spacing arrays.
 */
#define TT_SUBCELL	TT_MAXTYPES  

/* The following type is used in the paint result tables to save space. */
#if TT_MAXTYPES > 256
typedef unsigned short PaintResultType;
#else
typedef unsigned char PaintResultType;
#endif

/* Which word in a mask contains the bit for type 't'? */
#define	ttWord(t)	((t) >> TT_WORDSHIFT)

/* Which bit in the above word is for type 't'? */
#define	ttBit(t)	((t) & TT_WORDMASK)

/* Mask for above word with only bit 't' set */
#define	ttMask(t)	((unsigned int)1 << ttBit(t))

/* Operations for manipulating TileTypeBitMasks */
#define TTMaskSetType(m, t)	((m)->tt_words[ttWord(t)] |= ttMask(t))
#define	TTMaskClearType(m, t)	((m)->tt_words[ttWord(t)] &= ~ttMask(t))
#define	TTMaskHasType(m, t)	(((m)->tt_words[ttWord(t)] & ttMask(t)) != 0)
#define	TTMaskSetOnlyType(m, t)	(TTMaskZero(m), TTMaskSetType(m, t))

/* ---------------------- Planes and masks ---------------------------- */
/*
 * Plane numbers are also small integers.  Certain planes are
 * technology-specific, but others are always present independent
 * of the technology used.
 *
 * Note that the CELL plane and the DRC_CHECK plane are invisible
 * as far as normal painting operations are concerned, but that the
 * DRC_CHECK plane does get written out to the .cad file.
 *
 * The following macros are used for converting between plane numbers
 * and masks of same.
 */
#if (MAXPLANES <= 32)
  #define PlaneMask		int
#else
  #define PlaneMask		dlong
#endif

#define	PlaneNumToMaskBit(p)	((PlaneMask)1 << (p))
#define	PlaneMaskHasPlane(m, p)	(((m) & PlaneNumToMaskBit(p)) != 0)


#define	PL_MAXTYPES	MAXPLANES	/* Maximum number of planes per cell */
#define	PL_CELL		0		/* Cell plane */
#define PL_DRC_CHECK	1		/* DRC plane for CHECK tiles */
#define PL_DRC_ERROR	2		/* DRC plane for ERROR tiles */
#define PL_M_HINT	3		/* magnet hints for irouter */
#define PL_F_HINT       4		/* fence hints for irouter */
#define PL_R_HINT	5		/* rotate hints for irouter */
#define PL_SELECTBASE	PL_M_HINT	/* First plane with selectable types */
#define	PL_TECHDEPBASE	6		/* First technology-dependent plane */
#define PL_PAINTBASE	1		/* Base of paint planes */

/* --------------------------- Labels --------------------------------- */

/*
 * The body of a tile may have a list of labels associated with it.
 * Each label contains a location that indicates the point at which the
 * label is supposed to appear attached.  This location must be within
 * the tile on whose list the label appears.
 */

typedef struct label
{
    TileType             lab_type;      /* Type of material to which this label
                                         * is attached.  This material, or
                                         * other materials that connect it,
                                         * must be present everywhere under
                                         * the area of the label (Magic
                                         * enforces this).  If there isn't
                                         * any such material, lab_type is
                                         * TT_SPACE.
                                         */
    Rect                 lab_rect;      /* Area of label. */
    int			 lab_just;	/* Justification (GEO_NORTH, etc.) */
    unsigned int	 lab_flags;	/* Information, especially for
					 * marking port labels
					 */
    struct label        *lab_next;      /* Next label in list */
    char                 lab_text[4];   /* Actual text of label.  This field
                                         * is just a place-holder: the actual
                                         * field will be large enough to
                                         * contain the label name.  This
                                         * MUST be the last field in the
                                         * structure.
                                         */
} Label;

/*
 * Label flags bit fields
 */

#define PORT_NUM_MASK	0x0fff		/* Mask of port number (up to 4096) */

#define PORT_DIR_MASK	0xf000		/* Mask of all port directions 	   */
#define PORT_DIR_NORTH	0x1000		/* Port allows connection to north */
#define PORT_DIR_EAST	0x2000		/* Port allows connection to east  */
#define PORT_DIR_SOUTH	0x4000		/* Port allows connection to south */
#define PORT_DIR_WEST	0x8000		/* Port allows connection to west  */

#define PORT_CLASS_MASK		 0x70000 /* Mask of all port classes	*/
#define PORT_CLASS_DEFAULT	 0x00000 /* Port takes default class	*/
#define PORT_CLASS_INPUT	 0x10000 /* Port is a digital input	*/
#define PORT_CLASS_OUTPUT	 0x20000 /* Port is a digital output	*/
#define PORT_CLASS_TRISTATE	 0x30000 /* Port is a tri-state output	*/
#define PORT_CLASS_BIDIRECTIONAL 0x40000 /* Port is analog or digital	*/
					 /*    bidirectional		*/
#define PORT_CLASS_FEEDTHROUGH	 0x50000 /* Port touches no active	*/
					 /*    devices			*/

#define PORT_USE_MASK	   0x700000	/* Mask of all port uses	*/
#define PORT_USE_DEFAULT   0x000000	/* Port takes default use	*/
#define PORT_USE_SIGNAL	   0x100000	/* Port is a digital signal	*/
#define PORT_USE_ANALOG	   0x200000	/* Port is an analog signal	*/
#define PORT_USE_POWER	   0x300000	/* Port is a power rail		*/
#define PORT_USE_GROUND    0x400000	/* Port is a ground rail	*/
#define PORT_USE_CLOCK     0x500000	/* Port is a digital clock	*/
					/*    signal			*/
#define PORT_VISITED	   0x800000	/* Bit for checking if a port	*/
					/* has been previously visited.	*/

/*
 * Macros for dealing with label rectangles.
 */

#define	LABELTOUCHPOINT(p, r) \
			((p)->p_x >= (r)->r_xbot && (p)->p_x <= (r)->r_xtop \
		      && (p)->p_y >= (r)->r_ybot && (p)->p_y <= (r)->r_ytop)

/* ------------------- Cell definitions and uses ---------------------- */

/*
 * There are two structures used for cells:
 *
 *	CellDef -- one for the definition of the cell
 *	CellUse -- one for each instantiation of the cell.
 *
 * The CellDef is shared by all of the CellUses of that cell.
 */

typedef struct celldef
{
    int			 cd_flags;	/* See definitions below */
    Rect		 cd_bbox;	/* Bounding box for cell */
    char		*cd_file;	/* File containing cell definition */
#ifdef FILE_LOCKS
    int			cd_fd;		/* File descriptor for obtaining and
					 * holding advisory locks.
					 */
#endif
    char		*cd_name;	/* Name of cell */
    struct celluse	*cd_parents;	/* NULL-terminated list of all uses */
    Plane		*cd_planes[MAXPLANES];	/* Tiles */
    ClientData		 cd_client;	/* This space for rent */
    int			 cd_timestamp;	/* Unique integer identifying last
					 * time that paint, labels, or subcell
					 * placements changed in this def.
					 */
    Label		*cd_labels;	/* Label list for this cell */
    Label		*cd_lastLabel; 	/* Last label in list for this cell. */
    char		*cd_technology;	/* Name of technology for this cell 
					 * (Not yet used.)
					 */
    ClientData		 cd_props;	/* Private data used to maintain
					 * lists of properties.  Properties
					 * are name-value pairs and provide
					 * a flexible way of extending the
					 * data that is stored in a CellDef.
					 */
    ClientData		 cd_filler;	/* UNUSED */
    HashTable		 cd_idHash;	/* Maps cell use ids to cell uses.
					 * Indexed by cell use id; value
					 * is a pointer to the CellUse.
					 */
    TileTypeBitMask	 cd_types;	/* Types of tiles in the cell */
} CellDef;

/*
 * Cell definition flags:
 *	CDAVAILABLE means cell has been loaded from disk into main store.
 *	CDMODIFIED means cell has been changed since last write to disk.
 *	    This bit applies only to the real contents of the cell (paint,
 *	    labels, and subcell placements), and not to hint information
 *	    like child bounding box guesses and child timestamps.
 *	CDNOTFOUND means we failed to find the cell on disk once, so
 *	    don't give any more error messages about it.
 *	CDINTERNAL means that this cell is used internally by Magic (e.g.
 *	    for DRC checking or channel decomposition or selection) and
 *	    has nothing to do with the user's layout.  Many things don't
 *	    apply to internal cells (such as design-rule checking).
 *	CDGETNEWSTAMP means the cell has been modified since the
 *	    last time a timestamp was assigned to it, so it needs
 *	    to have a new stamp assigned.
 *	CDSTAMPSCHANGED means that a timestamp has changed in one or
 *	    more children of this cell.
 *	CDBOXESCHANGED means that bounding boxes of one or more children
 *	    have changed.
 *	CDFIXEDBBOX means that this cell has been declared to be a
 *	    pre-extracted subcircuit, so the bounding box should not
 *	    be altered.
 *	CDNOEDIT means that the cell cannot be edited because its file
 *	    is read-only or (if FILE_LOCKS enabled) locked by another user.
 *	CDPROCESSED means that the cell bounding box has been calculated
 *	    and should not be calculated again.
 *	CDFLATGDS is set when the "calma flatten" option is chosen and
 *	    a cell is small and does not call any instances itself.
 *	    The flag is used to identify the cell and remove it after GDS
 *	    input processing.
 *	CDPROCESSEDGDS is set when the cell read from the GDS stream file
 *	    is added to the magic database.  The flag is used to identify
 *	    whether the cell has been processed when forcing the GDS
 *	    stream data to be read in post-order.
 *	CDVENDORGDS indicates that the cell was read from a GDS stream
 *	    with the option "gds readonly true".
 */

#define	CDAVAILABLE	 0x0001
#define	CDMODIFIED	 0x0002
#define	CDNOTFOUND	 0x0004
#define CDINTERNAL	 0x0008
#define CDGETNEWSTAMP	 0x0010
#define CDSTAMPSCHANGED	 0x0020
#define CDBOXESCHANGED	 0x0040
#define CDFIXEDBBOX	 0x0080
#define CDNOEDIT	 0x0100
#define CDPROCESSED	 0x0200
#define CDFLATGDS	 0x0400
#define CDPROCESSEDGDS	 0x0800
#define CDVENDORGDS	 0x1000

/*
 * Description of an array.
 * The bounds xlo .. xhi and ylo .. yhi are transformed versions
 * of the bounds xlo' .. xhi' and ylo' .. yhi' supplied by the
 * user:
 *
 * User supplies:
 *	xlo'	index of leftmost array element in root coordinates
 *	xhi'	index of rightmost array element in root coordinates
 *	ylo'	index of bottommost array element in root coordinates
 *	yhi'	index of topmost array element in root coordinates
 *
 * There is no constraint on the order of any of these indices; xlo' may
 * be less than, equal to, or greater than xhi', and similarly for ylo'
 * and yhi'.
 *
 * In addition, the separations xsep and ysep are transformed versions
 * of the separations xsep' and ysep' supplied by the user:
 *
 * User supplies:
 *	xsep'	(positive) X spacing between array elements in root coords
 *	ysep'	(positive) Y spacing between array elements in root coords
 *
 * When the array is made via DBMakeArray, both the indices and the spacings
 * are transformed down to the coordinates of the CellDef that is the child
 * of the use containing the ArrayInfo.
 *
 * The significance of the various values is as follows:  the [xlo, ylo]	
 * element of the array is gotten by transforming the celldef by the
 * transformation in the celluse.  the [x, y] element is gotten by
 * transforming the celldef by xsep*abs(x-xlo) in x, ysep*abs(y-ylo) in
 * y, and then transforming by the transformation in the celluse.
 */

typedef struct
{
    int		ar_xlo, ar_xhi;		/* Inclusive low/high X bounds */
    int		ar_ylo, ar_yhi;		/* Inclusive low/high Y bounds */
    int		ar_xsep, ar_ysep;	/* X,Y sep between array elements */
} ArrayInfo;

/*
 * Since a cell may be used in an orientation different from that
 * in which it was defined, each cell use contains a transform
 * that will generate coordinates in the world of the parent from
 * the coordinates in the world of the child.  Cells may also be
 * arrayed.  Note:  arraying occurs before the transformation, then
 * the entire array is transformed.
 */

typedef struct celluse
{
    unsigned int	 cu_expandMask;	/* Mask of windows in which this use
					 * is expanded.
					 */
    unsigned char	 cu_flags;	/* See definitions below */
    Transform		 cu_transform;	/* Transform to parent coordinates */
    char		*cu_id;		/* Unique identifier of this use */
    ArrayInfo		 cu_array;	/* Arraying information */
    CellDef		*cu_def;	/* The definition of the cell */
    struct celluse	*cu_nextuse;	/* Next in list of uses of our def,
					 * or NULL for end of list.
					 */
    CellDef		*cu_parent;	/* Cell def containing this use */
    Rect		 cu_bbox;	/* Bounding box of this use, with
					 * arraying taken into account, in
					 * coordinates of the parent def.
					 */
    ClientData		 cu_client;	/* This space for rent */
} CellUse;

/* CellUse flags */
/* CU_LOCKED	means that the cell use is locked, and cannot be
 *		moved, copied, edited, rotated, etc.
 */
#define CU_LOCKED	0x01
/* CU_SELECT_*	are used only with the select cell def.  They indicate
 *		that the selection has been made via a "select chunk"
 *		or "select net" command, and should be treated accordingly.
 */
#define CU_SELECT_NET   0x02
#define CU_SELECT_CHUNK 0x04

/* Character prefix used to denote a locked cell use in a .mag file */
#define CULOCKCHAR	'*'

#define	cu_xlo	cu_array.ar_xlo
#define	cu_ylo	cu_array.ar_ylo
#define	cu_xhi	cu_array.ar_xhi
#define	cu_yhi	cu_array.ar_yhi
#define	cu_xsep	cu_array.ar_xsep
#define	cu_ysep	cu_array.ar_ysep

/*
 * xMask special values.  Note that the usual form of xMask specifies
 * a single-bit value (1, 2, 4, etc.) representing one window from
 * which a command originated.  Any number that is not a power of 2
 * may be used to define a special criterion for determining whether
 * or not to descend into a cell during a tree search, in routine
 * DBDescendSubcell().
 */

#define CU_DESCEND_ALL		0	/* Descend all subcells */
#define CU_DESCEND_SPECIAL	0x0003	/* Descend marked subcells only */
#define CU_DESCEND_NO_SUBCKT	0x0005	/* Descend no subcircuits */
#define CU_DESCEND_NO_VENDOR	0x0006	/* Descend no vendor-GDS subcells */
#define CU_DESCEND_NO_LOCK	0x0007	/* Descend unlocked subcells only */

/*
 * All subcells used by a cell are part of another tile plane,
 * called the `cell plane'.  To handle overlap, each tile in
 * this plane points to a list of cell uses that appear in the
 * area covered by the tile.  Where there is overlap, this list
 * will contain more than one tile.
 */

typedef struct celltilebody
{
    CellUse		*ctb_use;	/* Cell used */
    struct celltilebody	*ctb_next;	/* Next tile body on list */
} CellTileBody;

#ifdef NONMANHATTAN
/*
 * Declare tile type structure for non-manhattan geometry
 */

typedef struct diagonaltilebody
{
    TileType  type_l;
    TileType  type_r;
    unsigned char split_dir;    /* (0 = /, 1 = \) */
} DiagonalTileBody;

/*
 * Structure containing painting information to be passed to the paint  
 * procedure when a diagonal tile is encountered.
 */

typedef struct diag_info
{
   PaintResultType *resultTbl; 
   bool dir;
   bool side;
} DiagInfo;

#endif  /* NONMANHATTAN */

/* -------------------- Search context information -------------------- */

/* Search contexts are used in hierarchical searches */
typedef struct
{
    CellUse	*scx_use;	/* Pointer to cell use currently searched */
    int		 scx_x, scx_y;	/* X and Y array elementS if scx_use is array */
    Rect	 scx_area;	/* Area searched in scx_use->cu_def coords */
    Transform	 scx_trans;	/* Composite transform from coordinates
				 * of the cell use (scx_use) all the way
				 * back to those of the "root" of the
				 * search.
				 */
} SearchContext;

/* ------------------- Pathname of a terminal (label) ----------------- */

/* The following structure is used to build hierarchical label names */
typedef struct
{
    char	*tp_first;	/* Pointer to first character in pathname */
    char	*tp_next;	/* Pointer to next character to be filled in */
    char	*tp_last;	/* Pointer to last available character slot
				 * in pathname.
				 */
} TerminalPath;

/* --------------- Contexts for hierarchical tile searches ------------ */

/*
 * The TreeContext is the glue which holds together the SearchContext
 * of a given search (which varies depending on where in the search we
 * happen to be) and the TreeFilter (see below) which does not.
 */
typedef struct treeContext
{
    SearchContext *tc_scx;		/* Search context (varies) */
    int tc_plane;			/* Current plane of search */
    struct treeFilter *tc_filter;	/* Constant search criteria */
} TreeContext;

/*
 * The TreeFilter is that portion of the argument to the
 * filter procedures associated with tree searches that does
 * not change during the entire search, but serves mainly to
 * pass the search criteria down to the filter functions.
 */
typedef struct treeFilter
{
    int (*tf_func)();		/* Client's filter function */
    ClientData tf_arg;		/* Client's argument to pass to filter */
    TileTypeBitMask *tf_mask;	/* Only process tiles with these types */
    int tf_xmask;		/* Expand mask */
    PlaneMask tf_planes;	/* Mask of planes which will be visited */
#ifdef NONMANHATTAN
    TileType tf_dinfo;		/* Info for processing triangular areas */
#endif
    TerminalPath *tf_tpath;	/* Buffer to hold hierarchical label names */
} TreeFilter;

/* -------------- Undo information passed to DBPaintPlane ------------- */

typedef struct
{
    CellDef *pu_def;	/* Cell definition being modified */
    int pu_pNum;	/* Index of plane within cell def */
} PaintUndoInfo;

/* ---------------------- Codes for paint/erase ----------------------- */

    /* The following are obsolete and will go away */
#define	ERASE	0	/* Erase type from existing tiles */
#define	PAINT	1	/* Paint type over existing tiles */
#define	WRITE	2	/* Write type unconditionally */

/* ---------------------- Codes for cell printing ---------------------- */

#define SELF	  0
#define PARENTS   1
#define CHILDREN  2
#define CHILDINST 3
#define ALLCELLS  4
#define TOPCELLS  5
#define OTHER	  6

/* -------------------- Exported procedure headers -------------------- */

    /* Painting/erasing */
extern void DBPaint();
extern void DBErase();
extern int  DBSrPaintArea();
extern void DBPaintPlane();
extern void DBPaintPlaneActive();
extern void DBPaintPlaneWrapper();
extern void DBPaintPlaneByProc();
extern void DBPaintPlaneMergeOnce();
extern void DBPaintMask();
extern void DBEraseMask();
extern void DBClearPaintPlane();
extern void DBLockContact();
extern void DBUnlockContact();

#ifdef NONMANHATTAN
extern void DBNMPaintPlane();
#endif

    /* I/O */
extern bool DBCellRead();
extern bool DBTestOpen();
extern char *DBGetTech();
extern bool DBCellWrite();
extern void DBCellReadArea();
extern void DBFileRecovery();
extern bool DBWriteBackup();
extern bool DBReadBackup();
extern void DBRemoveBackup();

    /* Labels */
extern int DBPutLabel();
extern bool DBEraseLabel();
extern void DBEraseLabelAll();
extern void DBEraseLabelsByContent();
extern void DBEraseLabelsByFunction();
extern void DBReOrientLabel();
extern void DBAdjustLabels();

    /* Technology initialization */
extern void DBTechInit();
extern bool DBTechSetTech();
extern void DBTechInitVersion();
extern bool DBTechSetVersion();
extern bool DBTechAddPlane();
extern bool DBTechAddType();
extern bool DBTechAddAlias();
extern void DBTechFinalType();
extern bool DBTechAddConnect();
extern bool DBTechAddContact();
extern bool DBTechAddCompose();
extern TileType DBTechNameType(), DBTechNoisyNameType();
extern int DBTechNamePlane(), DBTechNoisyNamePlane();
extern PlaneMask DBTechNoisyNameMask();
extern PlaneMask DBTechTypesToPlanes();
extern bool DBTechTypesOnPlane();
extern void DBTechInitPlane();
extern void DBTypeInit();
extern void DBTechInitType();
extern void DBTechInitCompose();
extern void DBTechFinalCompose();
extern void DBTechInitContact();
extern void DBTechFinalContact();
extern void DBTechFinalConnect();
extern void DBTechInitConnect();

    /* Cell symbol table */
extern void DBCellInit();
extern void DBCellPrint();
extern void DBUsePrint();
extern void DBTopPrint();
extern CellDef *DBCellLookDef();
extern CellDef *DBCellNewDef();
extern CellDef *DBCellDefAlloc();
extern bool DBCellRenameDef();
extern bool DBCellDeleteDef();
extern void DBCellDefFree();
extern int DBCellSrDefs();
extern CellUse *DBCellNewUse();
extern bool DBCellDeleteUse();
extern CellUse *DBCellFindDup();

    /* Cell selection */
extern CellUse *DBSelectCell();
extern CellUse *DBFindUse();

    /* Insertion/deletion of cell uses into the cell tile plane of a parent */
extern void DBPlaceCell();
extern void DBDeleteCell();
extern void DBClearCellPlane();

    /* Insertion/deletion of cell uses into the name space of a parent */
extern bool DBLinkCell();
extern void DBUnlinkCell();

    /* Deletion of cell defs */
extern void DBUndoReset();

    /* Bounding boxes and arrays */
extern bool DBBoundPlane();
extern void DBComputeUseBbox();
extern void DBReComputeBbox();
extern void DBReComputeBboxVert();
extern void DBMakeArray();
extern void DBSetArray();
extern void DBSetTrans();
extern void DBArrayOverlap();
extern void DBComputeArrayArea();
extern Transform *DBGetArrayTransform();
extern char *DBPrintUseId();

    /* Massive copying */
extern void DBCellCopyPaint();
extern void DBCellCopyAllPaint();
extern void DBCellCopyLabels();
extern void DBCellCopyAllLabels();
extern void DBCellCopyCells();
extern void DBCellCopyAllCells();

    /* Contact image handling */
extern TileType DBPlaneToResidue();
extern TileType DBTechFindStacking();
extern bool DBIsContact();
extern TileTypeBitMask *DBResidueMask();
extern void DBFullResidueMask();

    /* Miscellaneous */
extern void DBCellClearDef();
extern void DBCellCopyDefBody();
extern void DBExpandAll(), DBExpand();
extern bool DBIsAncestor();
extern void DBCellSetAvail();
extern void DBCellClearAvail();
extern bool DBCellGetModified();
extern void DBCellSetModified();
extern void DBFixMismatch();
extern void DBTreeCopyConnect();
extern void DBSeeTypesAll();
extern void DBUpdateStamps();
extern void DBEnumerateTypes();
extern Plane *DBNewPlane();

extern PaintResultType (*DBNewPaintTable())[TT_MAXTYPES][TT_MAXTYPES];
typedef void (*VoidProc)();
VoidProc DBNewPaintPlane();

    /* Diagnostic */
extern void DBTechPrintTypes();
extern void DBTechPrintCanonicalType();

    /* Deallocation */
extern void DBClearCellPlane();
extern void DBClearPaintPlane();
extern void DBFreeCellPlane();
extern void DBFreePaintPlane();

    /* Cell properties */
extern void DBPropPut();
extern ClientData DBPropGet();
extern int DBPropEnum();
extern void DBPropClearAll();

    /* Searching */
extern int DBTreeSrTiles();
extern int DBTreeSrUniqueTiles();
extern int DBNoTreeSrTiles();
extern int DBTreeSrLabels();
extern int DBTreeSrCells();
extern int DBSrRoots();
extern int DBCellEnum();
extern int DBSrCellUses();
extern int DBArraySr();
extern bool DBNearestLabel();
extern int DBSrLabelLoc();
#ifdef NONMANHATTAN
extern TileType DBTransformDiagonal();
#endif

/* -------------------------- Layer locking ------------------------------*/

extern TileTypeBitMask DBActiveLayerBits; /* Layers that are locked */

#define LOCKLAYERCHAR '-'   /* Layer names beginning with this are locked */
#define LockedLayer(tiletype)  (!TTMaskHasType(&DBActiveLayerBits, tiletype)) 

/* ---------- Internal units to Lambda conversion factor ---------------- */

extern int DBLambda[2];

/* -------------------- Exported magic file suffix -------------------- */

extern char *DBSuffix;		/* Suffix appended to all Magic cell names */

/* -------------------- User Interface Stuff -------------------------- */

extern bool DBVerbose;		/* If FALSE, don't print warning messages */

/* ------------------ Exported technology variables ------------------- */

/***
 *** The following variables should be considered
 *** read-only to all clients of the database module.
 ***/

    /* Name, version, and description of the current technology */
extern char *DBTechName;
extern char *DBTechVersion;
extern char *DBTechDescription;

    /*
     * Predefined masks of tile types.
     * The number of built-in types is just TT_TECHDEPBASE.
     */
extern TileTypeBitMask DBZeroTypeBits;		/* All zeroes */
extern TileTypeBitMask DBAllTypeBits;		/* All ones */
extern TileTypeBitMask DBBuiltinLayerBits;	/* All built-in types */
extern TileTypeBitMask DBAllButSpaceBits;	/* All but space */
extern TileTypeBitMask DBAllButSpaceAndDRCBits;	/* All but space and drc */
extern TileTypeBitMask DBSpaceBits;		/* Space only */

    /*
     * Number of tile types, including those specied by the technology
     * file and those built-in to Magic, but not including those automatically
     * generated to represent contact images.  Also, a mask of those
     * types contained in the technology file.
     */
extern int DBNumUserLayers;
extern TileTypeBitMask DBUserLayerBits;		/* Including space */

    /* Total number of Magic tile types in this technology */
extern int DBNumTypes;

    /* Total number of tile planes */
extern int DBNumPlanes;

/* Abbreviations */
#define	NT	TT_MAXTYPES
#define	NP	PL_MAXTYPES

    /* Alias names for groups of types defined in the tech file */
extern HashTable	DBTypeAliasTable;

    /* Gives the official long name of each plane: */
extern char		*DBPlaneLongNameTbl[NP];

    /* Gives a short name for each plane: */
extern char		*DBPlaneShortName();

    /* Gives for each plane a mask of all tile types stored in that plane: */
extern TileTypeBitMask	DBPlaneTypes[NP];

    /* Similar to DBPlaneTypes[], but no type appears on more than one plane.
     * Effectively, the reverse lookup of DBPlane(type) (DBTypePlaneTbl[type]).
     */
extern TileTypeBitMask  DBHomePlaneTypes[NP];

    /* Gives a TileTypeBitMask for everything that connects to a type.
     * Bit x is set in mask DBConnectTbl[y] if any image of x connects
     * to any image of y.
     */
extern TileTypeBitMask	DBConnectTbl[NT];

    /* Complement of above: everything not connected to a type */
extern TileTypeBitMask	DBNotConnectTbl[NT];

    /*
     * Gives a TileTypeBitMask of all types that correspond to a given
     * layer.  Used for contacts that have images in more than one
     * plane.
     */
extern TileTypeBitMask	DBLayerTypeMaskTbl[NT];

    /*
     * Gives a plane mask of all planes that have tiles that connect to
     * tiles of a given type.  This is only used for contacts; it tells
     * which other planes contain images of the contact.  A tile's own
     * plane is never included in its plane mask.  Non-contact types
     * always have 0 DBConnPlanes entries.
     */
extern PlaneMask DBConnPlanes[NT];

    /*
     * Similar to DBConnPlanes[], but this time it is non-zero
     * for those planes to which each type connects, exclusive
     * of its home plane and those planes to which it connects as a
     * contact.  These planes needn't be adjacent.  For example, a
     * p-well is connected to p-substrate diffusion that overlaps it;
     * also, p well contacts connect to a p-well.  This information
     * is currently used only in the circuit extractor.
     */
extern PlaneMask DBAllConnPlanes[NT];

    /*
     * Each TileType has a home plane.  The TileType only appears on
     * its home plane.  The only exception is TT_SPACE, which can appear
     * on any plane.  (For debugging, there may be other cases).
     *
     * DBTypePlaneTbl gives the home plane for a given TileType,
     * and DBTypePlaneMaskTbl gives a mask of the planes on which
     * it appears (all planes for TT_SPACE, one plane for others).
     */
extern int		DBTypePlaneTbl[TT_MAXTYPES];
extern PlaneMask	DBTypePlaneMaskTbl[TT_MAXTYPES];

    /* Gives the long name for each tile type: */
extern char		*DBTypeLongNameTbl[TT_MAXTYPES];

    /* Gives a short name for a tile type: */
extern char		*DBTypeShortName();

    /*
     * The following give masks of all planes that may be affected
     * when material of a given type is painted/erased:
     */
extern PlaneMask	DBTypePaintPlanesTbl[TT_MAXTYPES];
extern PlaneMask	DBTypeErasePlanesTbl[TT_MAXTYPES];

    /*
     * Gives the resulting tile type when one tile type is painted over
     * another in a given plane:
     *
     *	newType = DBPaintResult[pNum][paintType][oldType]
     */
extern PaintResultType	DBPaintResultTbl[NP][NT][NT];

    /*
     * Gives the resulting tile type when one tile type is erased over
     * another in a given plane:
     *
     *	newType = DBEraseResult[pNum][paintType][oldType]
     */
extern PaintResultType	DBEraseResultTbl[NP][NT][NT];

    /*
     * Gives the resulting tile type when one tile type is 'written'
     * over a given plane.  This corresponds to the case where the
     * written type replaces the old tile without regard to the type
     * of the old tile.
     *
     *	paintType = DBWriteResultTbl[paintType][oldType]
     */
extern PaintResultType	DBWriteResultTbl[NT][NT];

/* --------------------- Exported macros ------------------------------ */

    /*
     * Macros for reading the paint/erase tables:
     *	resultType = DBStdPaintEntry(oldType, paintType, planeNum)
     *	resultType = DBStdEraseEntry(oldType, paintType, planeNum)
     */
#define	DBStdPaintEntry(h,t,p) 	(DBPaintResultTbl[p][t][h])
#define	DBStdEraseEntry(h,t,p)	(DBEraseResultTbl[p][t][h])

    /*
     * Macros for constructing the pointer to pass to DBPaintPlane
     * as the result table.
     */
#define	DBStdPaintTbl(t,p)	(&DBPaintResultTbl[p][t][0])
#define	DBStdEraseTbl(t,p)	(&DBEraseResultTbl[p][t][0])
#define DBStdWriteTbl(t)	(&DBWriteResultTbl[t][0])

    /*
     * int DBPlane(type) TileType type;
     * Returns the home plane of 'type'.
     */
#define	DBPlane(type)		(DBTypePlaneTbl[type])

    /*
     * char *DBTypeLongName(type) TileType type;
     * Returns the long name of 'type'.
     */
#define	DBTypeLongName(type)	(DBTypeLongNameTbl[type])

    /*
     * char *DBPlaneLongName(p) int p;
     * Returns the long name of plane 'plane'.
     */
#define	DBPlaneLongName(p)	(DBPlaneLongNameTbl[p])

    /*
     * bool DBConnectsTo(t1, t2) TileType t1, t2;
     * Returns TRUE if types 't1' and 't2' are electrically connected.
     */
#define	DBConnectsTo(t1, t2)	(TTMaskHasType(&DBConnectTbl[t1], t2))

    /*
     * bool DBTypesOnSamePlane(t1, t2) TileType t1, t2;
     * Returns TRUE if types 't1' and 't2' exist on the same plane.
     */
#define DBTypesOnSamePlane(t1, t2) \
			(DBTypePlaneMaskTbl[t1] & DBTypePlaneMaskTbl[t2])

    /*
     * bool DBPaintOnPlane(t, p) TileType t; int p;
     * bool DBEraseOnPlane(t, p) TileType t; int p;
     *
     * Return TRUE if tile type 't' has any effect on plane 'p'
     * when being painted/erased.
     */
#define	DBPaintOnPlane(t, p)	(PlaneMaskHasPlane(DBTypePaintPlanesTbl[t], p))
#define	DBEraseOnPlane(t, p)	(PlaneMaskHasPlane(DBTypeErasePlanesTbl[t], p))

    /*
     * bool DBPaintOnTypePlanes(t1, t2) TileType t1, t2;
     * bool DBEraseOnTypePlanes(t1, t2) TileType t1, t2;
     *
     * Return TRUE if tile type 't1' has any effect on planes defined
     * for type 't2' when being painted/erased.
     */
#define	DBPaintOnTypePlanes(t1, t2) \
			(DBTypePaintPlanesTbl[t1] & DBTypePlaneMaskTbl[t2])
#define	DBEraseOnTypePlanes(t1, t2) \
			(DBTypePaintPlanesTbl[t1] & DBTypePlaneMaskTbl[t2])

    /*
     * bool DBTypeOnPlane(t, p) TileType t; int p;
     * Returns TRUE if tile type 't' exists on plane 'p'.
     */
#define DBTypeOnPlane(t, p)	(PlaneMaskHasPlane(DBTypePlaneMaskTbl[t], p))

/* --------- Tile types and masks (auto-generated by makedbh) ------------ */

#define TTMaskZero(m) ( \
	(m)->tt_words[7] = 0, \
	(m)->tt_words[6] = 0, \
	(m)->tt_words[5] = 0, \
	(m)->tt_words[4] = 0, \
	(m)->tt_words[3] = 0, \
	(m)->tt_words[2] = 0, \
	(m)->tt_words[1] = 0, \
	(m)->tt_words[0] = 0)

#define TTMaskIsZero(m) ( \
	(m)->tt_words[7] == 0 && \
	(m)->tt_words[6] == 0 && \
	(m)->tt_words[5] == 0 && \
	(m)->tt_words[4] == 0 && \
	(m)->tt_words[3] == 0 && \
	(m)->tt_words[2] == 0 && \
	(m)->tt_words[1] == 0 && \
	(m)->tt_words[0] == 0)

#define TTMaskEqual(m, n) ( \
	(m)->tt_words[7] == (n)->tt_words[7] && \
	(m)->tt_words[6] == (n)->tt_words[6] && \
	(m)->tt_words[5] == (n)->tt_words[5] && \
	(m)->tt_words[4] == (n)->tt_words[4] && \
	(m)->tt_words[3] == (n)->tt_words[3] && \
	(m)->tt_words[2] == (n)->tt_words[2] && \
	(m)->tt_words[1] == (n)->tt_words[1] && \
	(m)->tt_words[0] == (n)->tt_words[0])

#define TTMaskIntersect(m, n) ( \
	((m)->tt_words[7] & (n)->tt_words[7]) || \
	((m)->tt_words[6] & (n)->tt_words[6]) || \
	((m)->tt_words[5] & (n)->tt_words[5]) || \
	((m)->tt_words[4] & (n)->tt_words[4]) || \
	((m)->tt_words[3] & (n)->tt_words[3]) || \
	((m)->tt_words[2] & (n)->tt_words[2]) || \
	((m)->tt_words[1] & (n)->tt_words[1]) || \
	((m)->tt_words[0] & (n)->tt_words[0]))

#define TTMaskCom(m) ( \
	((m)->tt_words[7] = ~(m)->tt_words[7]), \
	((m)->tt_words[6] = ~(m)->tt_words[6]), \
	((m)->tt_words[5] = ~(m)->tt_words[5]), \
	((m)->tt_words[4] = ~(m)->tt_words[4]), \
	((m)->tt_words[3] = ~(m)->tt_words[3]), \
	((m)->tt_words[2] = ~(m)->tt_words[2]), \
	((m)->tt_words[1] = ~(m)->tt_words[1]), \
	((m)->tt_words[0] = ~(m)->tt_words[0]))

#define TTMaskCom2(m, n) ( \
	((m)->tt_words[7] = ~(n)->tt_words[7]), \
	((m)->tt_words[6] = ~(n)->tt_words[6]), \
	((m)->tt_words[5] = ~(n)->tt_words[5]), \
	((m)->tt_words[4] = ~(n)->tt_words[4]), \
	((m)->tt_words[3] = ~(n)->tt_words[3]), \
	((m)->tt_words[2] = ~(n)->tt_words[2]), \
	((m)->tt_words[1] = ~(n)->tt_words[1]), \
	((m)->tt_words[0] = ~(n)->tt_words[0]))

#define TTMaskSetMask(m, n) ( \
	((m)->tt_words[7] |= (n)->tt_words[7]), \
	((m)->tt_words[6] |= (n)->tt_words[6]), \
	((m)->tt_words[5] |= (n)->tt_words[5]), \
	((m)->tt_words[4] |= (n)->tt_words[4]), \
	((m)->tt_words[3] |= (n)->tt_words[3]), \
	((m)->tt_words[2] |= (n)->tt_words[2]), \
	((m)->tt_words[1] |= (n)->tt_words[1]), \
	((m)->tt_words[0] |= (n)->tt_words[0]))

#define TTMaskSetMask3(m, n, o) ( \
	((m)->tt_words[7] |= (n)->tt_words[7] | (o)->tt_words[7]), \
	((m)->tt_words[6] |= (n)->tt_words[6] | (o)->tt_words[6]), \
	((m)->tt_words[5] |= (n)->tt_words[5] | (o)->tt_words[5]), \
	((m)->tt_words[4] |= (n)->tt_words[4] | (o)->tt_words[4]), \
	((m)->tt_words[3] |= (n)->tt_words[3] | (o)->tt_words[3]), \
	((m)->tt_words[2] |= (n)->tt_words[2] | (o)->tt_words[2]), \
	((m)->tt_words[1] |= (n)->tt_words[1] | (o)->tt_words[1]), \
	((m)->tt_words[0] |= (n)->tt_words[0] | (o)->tt_words[0]))

#define TTMaskAndMask(m, n) ( \
	((m)->tt_words[7] &= (n)->tt_words[7]), \
	((m)->tt_words[6] &= (n)->tt_words[6]), \
	((m)->tt_words[5] &= (n)->tt_words[5]), \
	((m)->tt_words[4] &= (n)->tt_words[4]), \
	((m)->tt_words[3] &= (n)->tt_words[3]), \
	((m)->tt_words[2] &= (n)->tt_words[2]), \
	((m)->tt_words[1] &= (n)->tt_words[1]), \
	((m)->tt_words[0] &= (n)->tt_words[0]))

#define TTMaskAndMask3(m, n, o) ( \
	((m)->tt_words[7] = (n)->tt_words[7] & (o)->tt_words[7]), \
	((m)->tt_words[6] = (n)->tt_words[6] & (o)->tt_words[6]), \
	((m)->tt_words[5] = (n)->tt_words[5] & (o)->tt_words[5]), \
	((m)->tt_words[4] = (n)->tt_words[4] & (o)->tt_words[4]), \
	((m)->tt_words[3] = (n)->tt_words[3] & (o)->tt_words[3]), \
	((m)->tt_words[2] = (n)->tt_words[2] & (o)->tt_words[2]), \
	((m)->tt_words[1] = (n)->tt_words[1] & (o)->tt_words[1]), \
	((m)->tt_words[0] = (n)->tt_words[0] & (o)->tt_words[0]))

#define TTMaskClearMask(m, n) ( \
	((m)->tt_words[7] &= ~(n)->tt_words[7]), \
	((m)->tt_words[6] &= ~(n)->tt_words[6]), \
	((m)->tt_words[5] &= ~(n)->tt_words[5]), \
	((m)->tt_words[4] &= ~(n)->tt_words[4]), \
	((m)->tt_words[3] &= ~(n)->tt_words[3]), \
	((m)->tt_words[2] &= ~(n)->tt_words[2]), \
	((m)->tt_words[1] &= ~(n)->tt_words[1]), \
	((m)->tt_words[0] &= ~(n)->tt_words[0]))

#define TTMaskClearMask3(m, n, o) ( \
	((m)->tt_words[7] = (n)->tt_words[7] & ~(o)->tt_words[7]), \
	((m)->tt_words[6] = (n)->tt_words[6] & ~(o)->tt_words[6]), \
	((m)->tt_words[5] = (n)->tt_words[5] & ~(o)->tt_words[5]), \
	((m)->tt_words[4] = (n)->tt_words[4] & ~(o)->tt_words[4]), \
	((m)->tt_words[3] = (n)->tt_words[3] & ~(o)->tt_words[3]), \
	((m)->tt_words[2] = (n)->tt_words[2] & ~(o)->tt_words[2]), \
	((m)->tt_words[1] = (n)->tt_words[1] & ~(o)->tt_words[1]), \
	((m)->tt_words[0] = (n)->tt_words[0] & ~(o)->tt_words[0]))

#endif /* _DATABASE_H */
