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

Name/Version      : makebox/4.18

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

Author(s)         : S. de Graaf
Creation date     : 22-Apr-1986
Modified by       : S. de Graaf
Modification date : 11-Dec-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"
#include <unistd.h>
#ifdef ESE
#include "eseOption.h"
#include "tversion.h"
#endif

DM_PROCDATA *process;
struct clist *celllist;
struct tmtx  *tm_p, *tm_s;

DM_PROJECT *project;	/* project access key */
DM_CELL    *cellkey;	/* cell access key */
DM_STREAM **fp_bxx;	/* pointers to "bxx" files */
DM_STREAM **fp_nxx;	/* pointers to "nxx" files */
DM_STREAM  *fp_tidpos;  /* pointer to "tidpos" file (position of instances) */
DM_STREAM  *fp_tid;	/* pointer to "tid" file */
DM_STREAM  *fp_spec;	/* pointer to "spec" file */

double  atan ();
double *px, *py;	/* pointer to point array x,y */
double  rad01, rad90;	/* number of rad's for x degrees */
char    fn_exp[DM_MAXPATHLEN]; /* path of "exp_dat" file */
char    buf[256];	/* temp. string buffer */
char   *cellname;	/* current cell name */
char   *topcellname;	/* top cell name */

long   *no_bxx;		/* number of boxes */
long    exp_reg[4];     /* expansion region */
int     part_exp = 0;   /* partial expansion flag */
int     dflag = 0;      /* discretisize nor-elmts to boxes */
long    exp_depth = -1; /* depth of linear expansion */
long    term_no = 0;    /* count number of terminals */
int     mask_no;        /* mask number */
int     t_mask_no = 0;  /* terminal mask number */
int     level = 1;      /* level of current cell */
int     pt_size = 512;  /* size of point array's */
int     s_mode;         /* special mode flag */
int     Lflag = 0;          /* only Local cells (if true) */
int     verbose = 0;    /* verbose mode flag */
int     noImageMode = 0; /* no automatic image mode for SoG (seadif etc.) */
int     nordatahack = 0;    /* nordata flag */
int     hier_mode = 0;  /* hierarchical mode flag */
int     netterm = 0;    /* special hierarchical mode, read the stream 'netterm'
                           instead of the stream 'term' for each subcell, 
			   generate a 'nettid' stream instead of a 
			   'tid' stream, and generate 'n_xx_bxx' files
			   instead of 't_xx_bxx' files */
int	add3Dbox = 0;   /* Also read stream "3Dbox" (instead of only "box") */
int     noTidpos = 0;   /* Do not generate tidpos stream */
int     usage = 0;
long    nr_of_s = 0;
char    ** coord_list = NULL;
int     noErrMes = 0;

char * imageName = NULL;

#ifdef ESE
int     samples = -1;    /* number of samples per lambda */
#else
int samples = 0;
#endif

#ifndef ESE
char   *argv0 = "makeboxl";     /* program name */
char   *use_msg =               /* command line */
"\nUsage: %s [-H] [-L] [-cL] [-d[N]] [-v] [-wXl,Xr,Yb,Yt] [-i] cell\n\n";
#else
char   *argv0 = "mkboxl";        /* program name */
char   *use_msg =               /* command line */
"\nUsage: %s [options] cell\n\n";
#endif


#ifdef ESE
OptionSpec optionSpecs[] = {
    { "", NO, eseHelp, (void *) optionSpecs,
            "usage:     mkboxl [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" },
    { "help", NO, eseHelp, (void *) optionSpecs,
            "    -help:             print this list" },
    { "hierarchical", NO, eseTurnOn, (void *) & hier_mode,
            "    -hierarchical:     mixed linear/hierachical mode" },
    { "release", NO, esePrintString, (void *) TOOLVERSION,
            "    -release:          print the release number of this tool"},
    { "maxdepth", YES, eseAssignIntArgument, (void *) & exp_depth,
            "    -maxdepth number:  set maximum expansion depth to number, default is inf." },
    { "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" },
    { "%noimagemode", NO, eseTurnOn, (void *) & noImageMode,
            "    -%noimagemode:              no automatic image mode" },
    { "%nordata", NO, eseTurnOn, (void *) & nordatahack,
            "    -%nordata:              generate non-orthogonal data" },
    { "%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 */

    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 'L': 
		    ++Lflag;
		    break;
		case 'c': 
		    p = setval (&exp_depth, p);
		    if (exp_depth < 0) {
			++usage;
			errexit (-8, "");
		    }
		    break;
		case 'd': 
		    ++dflag;
		    p = setval (&nr_of_s, p);
		    samples = nr_of_s;
		    if (samples != 0 && samples != 1 && samples != 2
			&& samples != 4 && samples != 5
			&& samples != 8 && samples != 10) {
			++usage;
			errexit (-11, "");
		    }
		    break;
		case 'v': 
		    ++verbose;
		    break;
		case 'w': 
		    ++part_exp;
		    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;
		case 'H':
		    ++hier_mode;
		    break;
		case 'z':
		    ++nordatahack;
		    break;
		case 'N':
		    ++netterm;
		    ++hier_mode;
		    break;
		case 'M':
		    ++add3Dbox;
		    break;
		case 'i': 
		    ++noImageMode;
		    break;
		case 'b':
		    ++noTidpos;
		    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, "-window");
        }
        part_exp++;
	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, "-window"); /* incorrect window */
        }
    }

    if (samples != -1)
	dflag++;
    else
        samples = 0;

    if (samples != 0 && samples != 1 && samples != 2
	    && samples != 4 && samples != 5
	    && samples != 8 && samples != 10) {
	errexit (11, "-units");
     }
     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

    if (dflag && samples == 0) {
	samples = project -> n_samples;
    }


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

    if (exp_depth < 0)
	exp_depth = 1000; /* arbitrary big integer */

#   if NCF_RELEASE < 400
    if (noImageMode == 0) {
	char buf[DM_MAXPATHLEN];
	sprintf (buf, "%s/seadif", project -> dmpath);
	if (access (buf, W_OK) == 0) {
	    if (verbose)
		P_E "makeboxl running in fishbone image mode\n");
	    imageName = "IMAGE";
	}
    }
#   endif /* NCF_RELEASE < 400 */

    if (verbose) {
	P_E "process: %s (procid = %d)\n",
	    process -> pr_name, project -> procid);
	if (hier_mode)
	    P_E "mixed linear/hierarchical expansion (lin. exp. depth = %d)\n", 
							       exp_depth);
	else
	    P_E "linear expansion (exp. depth = %d)\n", exp_depth);
	if (Lflag)
	    P_E "expansion of local cells only\n");
	if (dflag)
	    P_E "discretization (nr. of samples = %d)\n", samples);
	if (part_exp) {
	    P_E "partial expansion (exp. region = %ld, %ld, %ld, %ld)\n",
		exp_reg[0], exp_reg[1], exp_reg[2], exp_reg[3]);
	}
	P_E "cell: %s\n", topcellname);
    }

    rad90 = 2.0 * atan (1.0);
    rad01 = rad90 / 90.0;

    exp_cell (topcellname);

    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    i = 0;

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

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