static char *SccsId = "@(#)readhtm.c 4.3 (TU-Delft) 04/20/93";
/**********************************************************

Name/Version      : makebox/4.3

Language          : C
Operating system  : UNIX SYSTEM V
Host machine      : HP9000

Author(s)         : A.J. van Genderen
Creation date     : 19-Dec-1991
Modified by       : 
Modification date : 


        Delft University of Technology
        Department of Electrical Engineering
        Network Theory Section
        Mekelweg 4 - P.O.Box 5031
        2600 GA DELFT
        The Netherlands

        Phone : 015 - 786234

        COPYRIGHT (C) 1987 , All rights reserved
**********************************************************/
#include "extern.h"

struct term_ref {
    struct geo_term term;
    struct term_ref *next;
};

/*
** read the terminals of a cell that is used as an hierarchical instance
*/

read_hier_term (clp)
struct clist *clp;
{
    DM_STREAM *fp;
    long    bXl, bXr, bYb, bYt;
    long    Xl, Xr, Yb, Yt;
    long    xl, xr, yb, yt;
    long tmp;
    register long i, j;
    register long a, b;
    long *m;
    int do_continue;
    struct tmtx *tm;
    struct tmtx *mcp_tmfirst;
    struct term_ref *terms;
    struct term_ref *terms_last;
    struct term_ref *tref;
    struct term_ref *tref2;
    struct mc_elmt *mcp;

    if (nordatahack)
	return;

    /* first, read terminals */

    terms = NULL;
    terms_last = NULL;

    if (netterm)
	fp = dmOpenStream (cellkey, "netterm", "r");
    else
	fp = dmOpenStream (cellkey, "term", "r");

    while (dmGetDesignData (fp, GEO_TERM) > 0) {
	ALLOCPTR (tref, term_ref);
	strcpy (tref -> term.term_name, gterm.term_name);
	tref -> term.layer_no = gterm.layer_no;
	tref -> term.xl = samples * gterm.xl;
	tref -> term.xr = samples * gterm.xr;
	tref -> term.yb = samples * gterm.yb;
	tref -> term.yt = samples * gterm.yt;
	tref -> term.bxl = samples * gterm.bxl;
	tref -> term.bxr = samples * gterm.bxr;
	tref -> term.byb = samples * gterm.byb;
	tref -> term.byt = samples * gterm.byt;
	tref -> term.dx = samples * gterm.dx;
	tref -> term.nx = gterm.nx;
	tref -> term.dy = samples * gterm.dy;
	tref -> term.ny = gterm.ny;
	tref -> next = 0;
	if (terms_last != NULL)
	    terms_last -> next = tref;
	else
	    terms = tref;
	terms_last = tref;
    }

    dmCloseStream (fp, COMPLETE);

    /* second, read bounding-box */

    fp = dmOpenStream (cellkey, "info3", "r");
    dmGetDesignData (fp, GEO_INFO3);
    dmCloseStream (fp, COMPLETE);

    bXl = samples * ginfo3.bxl;
    bXr = samples * ginfo3.bxr;
    bYb = samples * ginfo3.byb;
    bYt = samples * ginfo3.byt;

    /* third, visit modelcalls */

    if (tm_p) 
	tm = tm_p;
    else 
	tm = tm_s;

    mcp = clp -> mc_p; 

    while ((two_levels && tm)
	   || (!two_levels && mcp)) {

	gtid.term_offset = -1;
	strcpy (gtid.cell_name, mcp -> name);
	if (two_levels) {
	    /*
	    /* if the cell is from two levels deep (or more)
	    /* the instance name may not be unique 
	    */
	    strcpy (gtid.inst_name, ".");
	    gtid.m_nx = 0;
	    gtid.m_ny = 0;
	}
	else {
	    strcpy (gtid.inst_name, mcp -> inst_name);
	    gtid.m_nx = mcp -> nx;
	    gtid.m_ny = mcp -> ny;
	}
	dmPutDesignData (fp_tid, GEO_TID);

	xl = tm -> mtx[0] * bXl + tm -> mtx[1] * bYb + tm -> mtx[2];
	yb = tm -> mtx[3] * bXl + tm -> mtx[4] * bYb + tm -> mtx[5];
	xr = tm -> mtx[0] * bXr + tm -> mtx[1] * bYt + tm -> mtx[2];
	yt = tm -> mtx[3] * bXr + tm -> mtx[4] * bYt + tm -> mtx[5];

	if (xl > xr) { tmp = xl; xl = xr; xr = tmp; }
	if (yb > yt) { tmp = yb; yb = yt; yt = tmp; }

	if (!noTidpos)
	    dmPrintf (fp_tidpos, "%ld %ld\n", xl, yb);

	mcp_tmfirst = tm;

	for (tref = terms; tref; tref = tref -> next) {

	    tm = mcp_tmfirst;

	    mask_no = tref -> term.layer_no;

	    t_mask_no = process -> mask_no[mask_no];
    
	    gtid.term_offset = term_no;
	    strcpy (gtid.term_name, tref -> term.term_name);
	    gtid.t_nx = tref -> term.nx;
	    gtid.t_ny = tref -> term.ny;
	    dmPutDesignData (fp_tid, GEO_TID);

	    for (a = 0;;) {
		for (b = 0;;) {

		    Xl = tref -> term.xl;
		    Xr = tref -> term.xr;

		    for (i = 0;;) {
			Yb = tref -> term.yb;
			Yt = tref -> term.yt;
			for (j = 0;;) {

			    m = tm -> mtx;
			    xl = m[0] * Xl + m[1] * Yb + m[2];
			    yb = m[3] * Xl + m[4] * Yb + m[5];
			    xr = m[0] * Xr + m[1] * Yt + m[2];
			    yt = m[3] * Xr + m[4] * Yt + m[5];

			    if (xl > xr) { tmp = xl; xl = xr; xr = tmp; }
			    if (yb > yt) { tmp = yb; yb = yt; yt = tmp; }

			    /* I'm not sure if partial expansion works
			    /* correctly here
			    */

			    do_continue = 0;
			    if (part_exp) {
				if (xr <= exp_reg[0] || xl >= exp_reg[1]
				||  yt <= exp_reg[2] || yb >= exp_reg[3]) {
				/*
				** the box-coordinates have no overlap
				** with the expansion region
				*/
				    if (t_mask_no) ++term_no;
				    do_continue = 1;
				}
			    }

                            if (!do_continue) {
				gboxlay.xl = xl;
				gboxlay.xr = xr;
				gboxlay.yb = yb;
				gboxlay.yt = yt;

				if (t_mask_no) {
				    gboxlay.chk_type = term_no++;
				    dmPutDesignData (fp_bxx[t_mask_no], 
						     GEO_BOXLAY);
				    ++no_bxx[t_mask_no];
				}
			    }
			    if (++j > tref -> term.ny) break;
			    Yb += tref -> term.dy;
			    Yt += tref -> term.dy;
			}
			if (++i > tref -> term.nx) break;
			Xl += tref -> term.dx;
			Xr += tref -> term.dx;
		    }

		    tm = tm -> tm_next;

		    if (++b > mcp -> ny || two_levels) break;
		}
		if (++a > mcp -> nx || two_levels) break;
	    }

	    t_mask_no = 0;
	}

	if (!two_levels) mcp = mcp -> mc_next;
    }

    tref = terms; 
    while (tref) {
	tref2 = tref -> next;
	FREE (tref);
        tref = tref2;
    }
}
