static char *SccsId = "@(#)main.c 4.7 (TU-Delft) 12/21/90";
/**********************************************************

Name/Version      : makebox/4.7

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

Author(s)         : J. Annevelink
Creation date     : 18-May-1983
Modified by       : S. de Graaf
Modification date : 11-May-1987


        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 "define.h"
#ifdef ESE
#include "eseOption.h"
#include "tversion.h"
#endif

struct ctree *celltree;	/* root node of cell-tree */
struct cptrl *cptrhead;	/* head node of cell-ptr-list */
struct cptrl *cptrlast;	/* last node of cell-ptr-list */
struct cptrl *cptr;	/* cell-ptr of current cell */
struct wdw  *mc_bboxl;	/* head node of mc-bbox-list */
struct wdw  **arl_ptr;	/* ptr to current act-reg-list */

DM_PROCDATA *process;	/* ptr to process information */
DM_PROJECT  *project;	/* project access key */
DM_CELL     *cellkey;	/* cell access key */
DM_CELL     *top_key;	/* top cell access key */
DM_STREAM  **fp_bxx;	/* pointers to "_bxx" files */
DM_STREAM   *fp_tid;	/* pointer to "exp_tid" file */
char    fn_exp[80];     /* path of "exp_dat" file */

long   *no_bxx;		/* no_of_boxes array */
long    exp_reg[4];     /* expansion region array */
int     part_exp = FALSE; /* partial expansion flag */
long    maxol = 6;      /* default max. overlay value */
long    exp_depth = 0;  /* depth of linear expansion */
long    usr_chlev = 1;  /* hier. check level */
long    term_no;        /* count number of terminals */
long    chtype;         /* current checktype */
long    fchtype;        /* final checktype */
int     mask_no;        /* mask number */
int     level;          /* level of current cell */
char ** coord_list = 0;
char  * topcellname = NULL;	/* cell to be expanded */
int     verbose = FALSE;/* verbose mode flag */

char    fname[256];	/* complete filename path */
#ifndef ESE
char   *argv0 = "makeboxh";	/* program name */
char   *use_msg =		/* command line */
"\nUsage: %s [-v] [-cL] [-oM] [-wXl,Xr,Yb,Yt] cell\n\n";
#else
char   *argv0 = "mkboxh";        /* program name */
char   *use_msg =               /* command line */
"\nUsage: %s [options] cell\n\n";
#endif

#ifdef ESE
OptionSpec optionSpecs[] = {
    { "usage", NO, eseHelp, (void *) optionSpecs,
            "-usage:     mkboxh [options] cell\nOptions (may be abbreviated) are:"},
    { "%etext", NO, eseText, (void *) NULL,
            "    -%etext:            print the '(int) & etext' number" },
    { "%help", NO, eseHelpAll, (void *) optionSpecs,
            "    -%help:            print this list" },
    { "release", NO, esePrintString, (void *) TOOLVERSION,
            "    -release:          print the release number of this tool"},
    { "help", NO, eseHelp, (void *) optionSpecs,
            "    -help:             print this list" },
    { "maxdepth", YES, eseAssignIntArgument, (void *) & exp_depth,
            "    -maxdepth number:  set maximum expansion depth to number, default is 0" },
    { "%overlap", YES, eseAssignIntArgument, (void *) & maxol,
            "    -%overlap number:  set size of active region to 'number', default: 6 micron" },

/*
    { "%local", NO, eseTurnOn, (void *) & Lflag,
            "    -%local:           do local cells only"  },
    { "%units", YES, eseAssignIntArgument, (void *) & samples,
            "    -%units number:    1 lambda = 'number' database units,\n                       'number' must be one of  1, 2, 4, 5, 8 (default) or 10" },
*/
    { "verbose", NO, eseTurnOn, (void *) & verbose,
            "    -verbose:          print run-time information" },
    { "%window", YES, eseListArguments, (void *) & coord_list,
            "    -%window Xl,Xr,Yb,Yt:   define expansion window, default is bounding box" },
    { (char *) 0, (char) 0, (IFP) 0, (void *) 0, (char *) 0 },
};
#endif

main (argc, argv)
int     argc;
char   *argv[];
{
    int     sig_handler (); /* signal handler */
    char   *setval ();
    char   *p;
    int     iarg;	    /* argument number */
    int     partial = FALSE;/* partial expansion flag */
    int     usage = 0;

    fclose (stdin); /* to free one file descriptor */

#ifndef ESE
    for (iarg = 1; iarg < argc && argv[iarg][0] == '-'; iarg++) {
	p = &argv[iarg][1];
	while (*p != '\0') {
	    switch (*p++) {
		case 'c': 
		    p = setval (&exp_depth, p);
		    if (exp_depth <= 0) {
			++usage;
			errexit (-8, "");
		    }
		    break;
		case 'o': 
		    p = setval (&maxol, p);
		    break;
		case 'v': 
		    verbose = TRUE;
		    break;
		case 'w': 
		    partial = TRUE;
		    if (*(p = setval (&exp_reg[0], p)) != ',') {
			++usage;
			errexit (-2, "");
			break;
		    }
		    if (*(p = setval (&exp_reg[1], ++p)) != ',') {
			++usage;
			errexit (-2, "");
			break;
		    }
		    if (*(p = setval (&exp_reg[2], ++p)) != ',') {
			++usage;
			errexit (-2, "");
			break;
		    }
		    p = setval (&exp_reg[3], ++p);
		    if (exp_reg[0] >= exp_reg[1]
		    ||  exp_reg[2] >= exp_reg[3]) {
			++usage;
			errexit (-3, ""); /* incorrect window */
		    }
		    break;
		default: 
		    ++usage;
		    P_E "%s: -%c: unknown option\n",
				argv0, *(p - 1));
		    break;
	    }
	}
    }

    if (argc != iarg + 1) {
	++usage;
	if (iarg >= argc)
	    errexit (-1, "");
	else
	    errexit (-5, "");
    }
    if (usage) {
	P_E use_msg, argv0);
	exit (1);
    }
    topcellname = argv[iarg];
#else
    if (eseOptionHandler (argc, argv, optionSpecs, 1, &topcellname) > 0) {
	P_E use_msg, argv0);
        exit (1);
    }
    if (!topcellname) {
	P_E use_msg, argv0);
	exit (1);
    }
    if (coord_list && coord_list[0] != NULL) {
        if (coord_list[1] == NULL || 
                coord_list[2] == NULL || 
                coord_list[3] == NULL || 
                coord_list[4] != NULL) {
            errexit (2, "");
        }
        partial = TRUE;
        exp_reg[0] = atol (coord_list[0]);
        exp_reg[1] = atol (coord_list[1]);
        exp_reg[2] = atol (coord_list[2]);
        exp_reg[3] = atol (coord_list[3]);

        if (exp_reg[0] >= exp_reg[1] || exp_reg[2] >= exp_reg[3]) {
            errexit (3, ""); /* incorrect window */
        }
    }
    if (!topcellname) {
        errexit (1, "");
    }
#endif


    signal (SIGHUP, SIG_IGN); /* ignore hangup signal */

    if (signal (SIGINT, SIG_IGN) != SIG_IGN)
	signal (SIGINT, sig_handler);
    signal (SIGQUIT, SIG_IGN);
    signal (SIGTERM, sig_handler);

    dmInit (argv0);
    project = dmOpenProject (DEFAULT_PROJECT, DEFAULT_MODE);
#ifndef ESE
    sprintf (fn_exp, "%s/exp_dat", project -> dmpath);
    unlink (fn_exp);
#else 
    sprintf (fn_exp, "/dev/null");
#endif


    process = (DM_PROCDATA *) dmGetMetaDesignData (PROCESS, project);

    if (exp_depth)
	usr_chlev = exp_depth;

    if (verbose) {
	P_E "process: %s (procid = %d)\n",
		process -> pr_name, project -> procid);
	P_E "hierarchical expansion\n");
	if (partial) {
	    P_E "exp. region: %d, %d, %d, %d\n",
		exp_reg[0], exp_reg[1], exp_reg[2], exp_reg[3]);
	}
#ifndef ESE
	P_E "user check level: %d\n", usr_chlev);
	P_E "max overlay val.: %d\n", maxol);
#else
	if (maxol != 6)
	    P_E "max overlay val.: %d\n", maxol);
	P_E "max. expansion depth: %d\n", usr_chlev);
#endif
    }

    /* allocate and initialize root nodes of cell-tree
    ** and cell-ptr-list; init also file "exp_dat".
    */
    celltree = upd_cptrl (topcellname);
    cptrhead = cptrlast;

    for (cptr = cptrhead; cptr; cptr = cptr -> next) {
#ifdef DEBUG
pr_cptrl (cptr);
pr_ctree (cptr -> cell);
P_E "=> exp_cell(cptr->cell): %08x (cptr = %08x)\n",
cptr -> cell, cptr);
#endif
	if (verbose)
	    P_E "cell: %s\n", cptr -> cell -> name);
	exp_cell (cptr -> cell, partial);
	partial = FALSE;
    }

    dmCloseProject (project, COMPLETE);
    dmQuit ();
    if (verbose) P_E "%s: -- program finished --\n", argv0);
    exit (0);
}

char   *setval (ip, s)
long   *ip;
char   *s;
{
    int     neg = 1;
    long    val = 0;

    if (*s == '-') {
	neg = -1;
	++s;
    }
    while (*s >= '0' && *s <= '9')
	val = (10 * val) + (*s++ - '0');
    *ip = val * neg;
    return (s);
}

sig_handler (sig) /* signal handler */
int sig;
{
    char buf[6];
    signal (sig, SIG_IGN); /* ignore signal */
    sprintf (buf, "%d", sig);
    errexit (9, buf);
}
