static char *SccsId = "@(#)findNetw.c 4.10 (TU-Delft) 08/11/92";
/**********************************************************

Name/Version      : xsls/4.10

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

Author(s)         : A.J. van Genderen
Creation date     : 16-Feb-1987
Modified by       : S. de Graaf
Modification date : 25-Aug-1988


        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-1988, All rights reserved
**********************************************************/
#include "incl.h"

extern int language;
extern int tog_use0;
extern int cirFlag;

extern char **globNets;
extern int *globNetsCheck;
extern int globNets_cnt;

extern char *projname ();

extern struct model_info *Funcs;

struct model_info *Netws;

struct model_info *findNetw (name, imported, father_proj, submod)
char *name;
int imported;
DM_PROJECT *father_proj;
int submod;
{
    DM_PROJECT *proj;
    char *real_name;
    register struct model_info *ntw;
    struct model_info *newNetw ();

    ntw = Netws;
    while (ntw != NULL && strcmp (ntw -> name, name) != 0) {
	ntw = ntw -> next;
    }

    if (ntw != NULL)
	return (ntw);  /* found ! */

    /* not found, read it ! */

    proj = dmFindProjKey (imported, name,
			  father_proj, &real_name, CIRCUIT);

    ntw = newNetw (name, proj, real_name, submod);

    return (ntw);
}

struct model_info *newNetw (name, proj, orig_name, submod)
char *name;
DM_PROJECT *proj;
char *orig_name;
int submod;
{
    struct model_info *ntw;

    PALLOC (ntw, 1, struct model_info);
    ntw -> next = Netws;
    Netws = ntw;
    strcpy (ntw -> name, name);
    strcpy (ntw -> out_name, name);
    strcpy (ntw -> orig_name, orig_name);
    ntw -> proj = proj;

    readTerm (ntw, 0, submod);

    return (ntw);
}

/* readTerm checks out the model and reads the terminals
   of the model.  If the second argument is 1, the model
   is considered to be a function.
*/

static struct term_ref *treflast;

readTerm (m, funf, submod)       
struct model_info *m;        
int funf;
int submod;
{
    char *m_name;
    DM_STREAM *dsp;
    register struct model_info *q;

    /*
    ** In the current database implementation, function blocks
    ** and network desciptions are both stored in the same
    ** cell directory within the circuit view.
    ** Thus, when reading terminals for a function or network
    ** look first if the cell is already checked out.
    */
    m_name = m -> name;
    q = (funf) ? Netws : Funcs;

    while (q != NULL && strcmp (q -> name, m_name) != 0) {
	q = q -> next;
    }

    if (q != NULL) { /* found, already checked out! */
	m -> proj = q -> proj;
	m -> dkey = q -> dkey;
    }
    else {
	m -> dkey = dmCheckOut (m -> proj, m -> orig_name, 
				submod ? ACTUAL : WORKING, 
			        DONTCARE, CIRCUIT, READONLY);
    }

#if NCF_RELEASE < 400
    if (funf) {
#else
    if (funf && cirFlag) {
#endif
	dsp = dmOpenStream (m -> dkey, "fterm", "r");
    }
    else {
	dsp = dmOpenStream (m -> dkey, "term", "r");
    }

    m -> terms = NULL;
    treflast = NULL;

    if (language == SIMON) {
	termRun (m, dsp, !funf, INPUT);
	termRun (m, dsp, !funf, INREAD);
	termRun (m, dsp, !funf, INOUT);
	termRun (m, dsp, !funf, OUTPUT);
    }
    else 
	termRun (m, dsp, !funf, -1);

    dmCloseStream (dsp, COMPLETE);
}

termRun (m, dsp, netw, currType) 
struct model_info *m;
DM_STREAM *dsp;
int netw;
int currType;
{
    int i;
    int type;
    struct term_ref *tref;

    if (netw) {
	for (i = 0; i < globNets_cnt; i++) {
	    globNetsCheck[i] = 0;
	}
    }

    while (dmGetDesignData (dsp, CIR_TERM) > 0) {

	type = findTermType (cterm.term_attribute);

	if (currType >= 0 && currType != type) {
	    continue;
	}

	if (netw && cterm.term_dim == 0) {
	    for (i = 0; i < globNets_cnt; i++) {
		if (strcmp (globNets[i], cterm.term_name) == 0) {
		    break;
		}
	    }
	    if (i < globNets_cnt)
		globNetsCheck[i] = 1;
	}

	if (tog_use0) {
	    if (nameNbr (cterm.term_name) == 0)
		continue;
	}

	PALLOC (tref, 1, struct term_ref);
	PALLOC ((tref -> t), 1, struct cir_term);
	structcpy ((char *)(tref -> t), (char *)&cterm, 
		   sizeof (struct cir_term));
	tref -> type = type;
	tref -> next = NULL;
	if (m -> terms == NULL)
	    m -> terms = tref;
	else
	    treflast -> next = tref;
	treflast = tref;
    }

    if (netw) {
	for (i = 0; i < globNets_cnt; i++) {
	    if (globNetsCheck[i] == 0) {

		/* This name of a global net was not part 
		   of the terminal list, so we add it.
		*/

		PALLOC (tref, 1, struct term_ref);
		PALLOC ((tref -> t), 1, struct cir_term);
		strcpy (tref -> t -> term_name, globNets[i]);
		tref -> t -> term_dim = 0;
		tref -> t -> term_lower = NULL;
		tref -> t -> term_upper = NULL;
		tref -> t -> term_attribute = NULL;
		tref -> type = type;
		tref -> next = NULL;
		if (m -> terms == NULL)
		    m -> terms = tref;
		else
		    treflast -> next = tref;
		treflast = tref;
	    }
	}
    }

    dmSeek (dsp, 0, 0);
}

int findTermType (attrString)
char *attrString;
{
    char *attr;
    char *nextAttr ();
    char *par;
    char *val;
    char buf[256];

    /* first, check possible escher specification */

    if (sscanf (attrString, "%s", buf) > 0) {
	if (strcmp (buf, "input") == 0) {
	    return (INPUT);
	}
	else if (strcmp (buf, "output") == 0) {
	    return (OUTPUT);
	}
	else if (strcmp (buf, "in/output") == 0) {
	    return (INOUT);
	}
    }

    /* next, check possible func_mkdb specification */

    attr = attrString;
    while (attr != NULL ) {

	attr = nextAttr (&par, &val, attr);

	if (par != NULL && val != NULL) {
	    if (strcmp (par, "ftt") == 0) {
		if (val[0] == '0') 
		    return (OUTPUT);
		else if (val[0] == '1') 
		    return (INPUT);
		else if (val[0] == '2') 
		    return (INREAD);
		else if (val[0] == '3') 
		    return (INOUT);
	    }
	}
    }

    return (INOUT);   /* default */
}

prImpNetw ()
{
    switch (language) {
	case SLS :
	    prImpMod (Netws, "networks");
	    break;
	case SPICE :
	    prImpMod (Netws, "circuits");
	    break;
	case EDIF :
	    prImpMod (Netws, "");
	    break;
    }
}

prImpMod (m, str)
struct model_info * m;
char *str;
{
    int first;
    int newproj;
    DM_PROJECT *proj;
    struct model_info *m2;
    char buf[32];
    
    first = 1;
    while (m != NULL) {
	if (m -> imported == IMPORTED && m -> proj != NULL) {
	    
	    /* list imported cells per project */

	    newproj = 1;
	    proj = m -> proj;
	    m2 = m;
	    while (m2 != NULL) {
		if (m2 -> proj == proj) {
		    if (first) {
			if (language != EDIF) {
			    oprint (0, "\n");
			    startComment ();
			    oprint (0, "  -- imported ");
			    oprint (1, str);
			    oprint (1, " --");
			    oprint (0, "\n");
			    startComment ();
			    oprint (0, "\n");
			}
			first = 0;
		    }
		    if (newproj) {
			if (language == EDIF) {
			     oprint (0, "(external ");
#if NCF_RELEASE >= 400
			     oprint (0, projname (proj -> TMPath, 1));
#else
			     oprint (0, projname (proj -> dmpath, 1));
#endif
			     oprint (0, "(edifLevel 0)");
			     oprint (0, "(technology (numberDefinition))");
			}
			else {
			    startComment ();
			    oprint (0, "  ");
#if NCF_RELEASE >= 400
			    nmprint (1, proj -> TMPath, 0, NULL, NULL, 0, 0, 0);
#else
			    nmprint (1, proj -> dmpath, 0, NULL, NULL, 0, 0, 0);
#endif
			    oprint (1, ":");
			    oprint (0, "\n");
			}
			newproj = 0;
		    }
		    if (language == EDIF) {
			prHead (m, 1);
		    }
		    else {
			startComment ();
			oprint (0, "      ");
			sprintf (buf, "%-15s", m2 -> orig_name);
			oprint (0, buf);
			oprint (0, " ");
			oprint (0, m2 -> name);
			oprint (0, "\n");
		    }
		    m2 -> imported = LOCAL;   
		    /* so the input is partly destroyed ! */
		}
		m2 = m2 -> next;
	    }
	    if (language == EDIF) {
		oprint (0, ")");
		oprint (0, ")");
		oprint (0, ")");
	    }
        }
	m = m -> next;
    }

    if (!first) {
	if (language != EDIF)
	    endComment ();
    }
}
