static char *SccsId = "@(#)dblist1.c 1.1 (TU-Delft) 04/16/86";
/**********************************************************

Name/Version      : dblist1/1.1

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

Author(s)         : S. de Graaf
Creation date     : 10-Jan-1986
Modified by       : S. de Graaf
Modification date : 16-Apr-1986


        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) 1986 , All rights reserved
**********************************************************/
#include "stdio.h"

char *strcpy ();
char *strcat ();
char *malloc ();
char *argv0 = "dblist1";

struct mo_elmt {
    char mo[20];
    int  nr_mc;
    struct mo_elmt *l;
    struct mo_elmt *r;
};

struct mc_elmt {
    char mo[20];
    char mi[20];
    int  nx;
    int  ny;
    struct mc_elmt *c;
    struct mc_elmt *s;
};

struct mc_elmt *alloc_mc_elmt ();
struct mo_elmt *alloc_mo_elmt ();
struct mo_elmt *molist;
struct mo_elmt *model;
char path[80];
char mcinst[20];
char mcname[20];
int  mcnx, mcny;
int  level = 0;

main (argc, argv)
int   argc;
char *argv[];
{
    if (argc != 2) die (0, argv0);
    strcpy (mcname, argv[1]);
    molist = alloc_mo_elmt (mcname);
    trav_mctree (alloc_mc_elmt ());
    exit (0);
}

trav_mctree (pmc)
struct mc_elmt *pmc;
{
    struct mc_elmt *p;
    int i;

    if (upd_molist (molist, pmc->mo)) read_mc (pmc);
    for (i = 0; i < level; ++i) printf("    ");
    if (level == 0) printf ("%s", pmc->mo);
    else printf ("%-8s <%-9s [%d,%d]", pmc->mo, pmc->mi, pmc->nx, pmc->ny);
    printf (" (%d)\n", model->nr_mc);
    ++level;
    for (p = pmc->c; p; p = p->s) {
	trav_mctree (p);
    }
    free ((char *)pmc);
    --level;
}

struct mc_elmt *alloc_mc_elmt ()
{
    struct mc_elmt *p;

    p = (struct mc_elmt *) malloc (sizeof (struct mc_elmt));
    if (!p) die (3, "alloc_mc_elmt");
    strcpy (p->mo, mcname);
    strcpy (p->mi, mcinst);
    strcat (p->mi, ">");
    p->nx = mcnx;
    p->ny = mcny;
    p->c = p->s = 0;
    return (p);
}

read_mc (p)
struct mc_elmt *p;
{
    struct mc_elmt **pp;
    FILE *fp;
    int i;

    sprintf (path, "%s/layout/%s_mc", p->mo, p->mo);
    if (!(fp = fopen (path, "r"))) die (1, path);

    pp = &p->c;

    for (;;)
    {
	i = fscanf (fp,
		"%s%*d%*d%*d%*d%s%*d%*d%*d%*d%*d%*d%*d%d%*d%d",
		mcinst, mcname, &mcnx, &mcny);

	if (i != 4)
	    if (i == EOF) break;
	    else  die (2, path);

	++model->nr_mc;
	*pp = alloc_mc_elmt ();
	pp = &(*pp)->s;
    }

    fclose (fp);
}

upd_molist (p, name)
struct mo_elmt *p; char *name;
{
    int i;

    i = strcmp (name, p->mo);
    if (i < 0) {
	if (p->l) return (upd_molist (p->l, name));
	p->l = alloc_mo_elmt (name);
	model = p->l;
	return (1);
    }
    if (i > 0) {
	if (p->r) return (upd_molist (p->r, name));
	p->r = alloc_mo_elmt (name);
	model = p->r;
	return (1);
    }
    model = p;
    if (p == molist) return (1);
    return (0);
}

struct mo_elmt *alloc_mo_elmt (name)
char *name;
{
    struct mo_elmt *p;

    p = (struct mo_elmt *) malloc (sizeof (struct mo_elmt));
    if (!p) die (3, "alloc_mo_elmt");
    strcpy (p->mo, name);
    p->nr_mc = 0;
    p->l = p->r = 0;
    return (p);
}

char *errlist[] = {
    "\nUsage: %s model",
    "cannot open file: %s",
    "read error in file: %s",
    "%s: no more core"
};

die (nr, s)
int   nr;
char *s;
{
    if (nr) fprintf (stderr, "\n%s: ", argv0);
    fprintf (stderr, errlist[nr], s);
    fprintf (stderr, "\n\n");
    exit (1);
}
