static char *SccsId = "@(#)main.c 3.15 (TU-Delft) 03/26/91";
/**********************************************************

Name/Version      : rmdb/3.15

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

Author(s)         : S. de Graaf
Creation date     : 22-Feb-1984
Modified by       : G.W. Sloof
Modification date : 05-Apr-1988
Modified by       : S. de Graaf
Modification date : 11-Apr-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"
#ifdef ESE
#include "eseOption.h"
#include "tversion.h"
#include "malloc.h"
#endif

#define BUFLEN 1024

int setCellName ();

int     sw_verb = 0;
int     sw_imp = 0;
int     sw_force = 0;
int     no_exit = 0;
int     usage = 0;
int     sw_all = 0;
int     sw_lay = 0;
int     sw_cir = 0;
int     sw_flp = 0;
int     sw_cell = 0;
char   *cellname = NULL;		/* used by dmRemoveCell */
char ** viewlist = NULL;
char ** celllist = NULL;

#ifdef ESE
OptionSpec optionSpecs[] = {
    { "", NO, eseHelp, (void *) optionSpecs,
            "-usage:     rmcell [options] [cell...]\nOptions (may be abbreviated) are:"},
    { "all", NO, eseTurnOn, (void *) & sw_all,
            "    -all:                  remove all local cells of specified viewtypes"  },
    { "force", NO, eseTurnOn, (void *) & sw_force,
            "    -force:                do not ask for confirmation" },
    { "release", NO, esePrintString, (void *) TOOLVERSION,
            "    -release:              print the release number of this tool"},
    { "help", NO, eseHelp, (void *) optionSpecs,
            "    -help:                 print this list" },
    { "imported", NO, eseTurnOn, (void *) & sw_imp,
            "    -imported:             remove all imported cells of specified viewtypes" },
    { "verbose", NO, eseTurnOn, (void *) & sw_verb,
            "    -verbose:              print run-time information" },
    { "view", YES, eseListArguments, (void *) & viewlist,
            "    -view viewtype(s):     remove only cells of specified viewtype(s)" },

/*
    { "%cell", YES, setCellName, (void *) & cellname,
            "    -%cell cellname:       do it for cell 'cellname' only"  },
*/
    { "%circuit", NO, eseTurnOn, (void *) & sw_cir,
            "    -%circuit:             do it for this view (only)"  },
    { "%etext", NO, eseText, (void *) NULL,
            "    -%etext:               print the '(int) & etext' number" },
    { "%help", NO, eseHelpAll, (void *) optionSpecs,
            "    -%help:                print this list" },
    { "%layout", NO, eseTurnOn, (void *) & sw_lay,
            "    -%layout:              do it for this view (only)"  },

    { (char *) 0, (char) 0, (IFP) 0, (void *) 0, (char *) 0 },
};
#endif


DM_PROJECT * project;
char    path[80];
char    iclf[80];
char	buf[BUFLEN];

#ifndef ESE
char   *argv0 = "rmdb";		/* program name */
#else
char   *argv0 = "rmcell";		/* program name */
#endif
char   *use_msg =		/* command line */
"\nUsage: %s [-aifv] [-c cellname] [layout] [circuit] [floorplan]\n\n";

main (argc, argv)
int     argc;
char   *argv[];
{
    char   *p;
    int     iarg;		/* argument number */

#ifndef ESE
    freopen ("/dev/null", "w", stdout);

    for (iarg = 1; iarg < argc && argv[iarg][0] == '-'; ++iarg) {
	p = &argv[iarg][1];
	while (*p != '\0') {
	    switch (*p++) {
		case 'a': 
		    ++sw_all;
		    break;
		case 'i': 
		    ++sw_imp;
		    break;
		case 'v': 
		    ++sw_verb;
		    break;
		case 'f': 
		    ++sw_force;
		    break;
		case 'c': 
		    ++sw_cell;
		    ++iarg;
		    cellname = argv[iarg];
		    if (dmTestname (cellname) == -1)
			++usage;
		    break;
		default: 
		    ++usage;
		    PE "%s: -%c: unknown option\n", argv0, *(p - 1));
		    break;
	    }
	}
    }

    for (; iarg < argc; ++iarg) {
	if (strcmp (argv[iarg], LAYOUT) == 0)
	    ++sw_lay;
	else
	    if (strcmp (argv[iarg], CIRCUIT) == 0)
		++sw_cir;
	    else
		if (strcmp (argv[iarg], FLOORPLAN) == 0)
		    ++sw_flp;
		else {
		    ++usage;
		    PE "%s: unknown argument: %s\n",
			argv0, argv[iarg]);
		}
    }
#else
    celllist = (char **) calloc (argc, sizeof (char *));
    if (eseOptionHandler (argc, argv, optionSpecs, argc, celllist) != 0) {
	usage++;
    }

    if (celllist[0]) {
        sw_cell++;
    }

    if (sw_all && sw_cell) {
        PE "You must specify either -all or cell...\n");
        usage++;
    }
    if (!sw_imp && !sw_all && !sw_cell) {
        PE "You must specify either -imported or -all or cell...\n");
        usage++;
    }

    if (!viewlist) {
            PE "You must specify at least one viewtype with the '-view' option\n");
            usage++;
    }
    while (viewlist && viewlist[0]) {
        if (strncmp (viewlist[0], "layout", strlen (viewlist[0])) == 0) {
            sw_lay = 1;
        }
        else if (strncmp (viewlist[0], "circuit", strlen (viewlist[0])) == 0) {
            sw_cir = 1;
        }
        else {
            PE "-view: '%s' does not exist", viewlist[0]);
            usage++;
        }
        viewlist++;
    }

    if (usage)
	exit (1);

    if (!sw_force && (sw_cell || sw_all)) {
	if (sw_lay) {
	    if (confirm_view (LAYOUT) == -1) {
		sw_lay = 0;
	    }
	}
	if (sw_cir) {
	    if (confirm_view (CIRCUIT) == -1) {
		sw_cir = 0;
	    }
	}
	if (!sw_cir && !sw_lay) {
	    exit (1);
	}

	if (sw_cell) {
	    int i = 0;
	    int maxi = 0;
	    while (celllist[maxi++] != NULL);
	    while (celllist[i] != NULL) { /* it was late when I wrote this */
		PE "All specified viewtypes of cell %s, are you sure? [y/n]: ",
			celllist[i]);
		if ((fgets (buf, BUFLEN, stdin) == 0) || (buf[0] != 'y')) {
		    celllist[i] = celllist[--maxi];
		    if (i == maxi) {
			celllist[i] = NULL;
		    }
		}
		else {
		    i++;
		}
	    }
	}
    }
    if (!sw_force && sw_imp) {
	PE "All imported cells of specified viewtypes,\n\tare you sure? [y/n]: ");
	if ((fgets (buf, BUFLEN, stdin) == 0) || (buf[0] != 'y')) {
	    sw_imp = 0;
	}
    }

#endif
#ifndef ESE

    if (usage || !(sw_all || sw_lay || sw_cir || sw_flp)) {
	if (sw_cell && !(sw_all || sw_lay || sw_cir || sw_flp)) {
	    PE "-c option must be combined with -a or view-type(s)\n");
	}
	exit (1);
    }
 /* so if sw_cell : still 'viewtype' or '-a' required */

    if (sw_cell && sw_imp) {
	PE "Use of options -c and -i together not supported yet\n");
	die (1);
    }

    if ((sw_lay || sw_cir || sw_flp) && !sw_cell && !sw_force) {
    /* user wants to remove all cells of one or more viewtypes : confirm */
	if (sw_lay)
	    if (confirm_view (LAYOUT) == -1) {
		sw_lay = 0;
	    }
	if (sw_cir)
	    if (confirm_view (CIRCUIT) == -1) {
		sw_cir = 0;
	    }
	if (sw_flp)
	    if (confirm_view (FLOORPLAN) == -1) {
		sw_flp = 0;
	    }
	if (!sw_lay && !sw_cir && !sw_flp) {
	/* nothing confirmed : exit */
	    die (1);
	}
    }

    if (sw_all && !sw_lay && !sw_cir && !sw_flp) {
	if (!sw_force) { 
	    if (!sw_cell)
		PE "All viewtypes of all cells, are you sure? [y/n]: ");
	    else
		PE "All viewtypes of cell %s, are you sure? [y/n]: ", cellname);
	    if ((fgets (buf, BUFLEN, stdin) == 0) || (buf[0] != 'y'))
	    /* if (getchar () != 'y') */
		die (1);
	}
	sw_lay = sw_cir = sw_flp = 1;
    }
#endif

#ifndef MSDOS
    signal (SIGHUP, SIG_IGN);	/* ignore hangup signal */
    signal (SIGINT, SIG_IGN);	/* ignore interrupt */
#endif

    dmInit (argv0);
    project = dmOpenProject (DEFAULT_PROJECT, DEFAULT_MODE);
    chdir (project -> dmpath);

    if (sw_imp) {
	if (sw_lay) {
	    rem_imp (LAYOUT);
	}
	if (sw_cir) {
	    rem_imp (CIRCUIT);
	}
#ifndef ESE
	if (sw_flp) {
	    rem_imp (FLOORPLAN);
	}
#endif
    }

    if (sw_all && !sw_cell) {
	if (sw_lay) {
	    rem_view (project, LAYOUT);
	}
	if (sw_cir) {
	    rem_view (project, CIRCUIT);
	}
#ifndef ESE
	if (sw_flp) {
	    rem_view (project, FLOORPLAN);
	}
#endif
    }
    else {
	no_exit = 1;
#ifdef ESE
	for ( ;celllist[0] != NULL; celllist++) {
	    cellname = celllist[0];
#endif
	    if (sw_lay) {
		if (sw_verb)
		    PE "removing cell %s of view-type '%s'\n",
			    cellname, LAYOUT);
		if (dmRemoveCell (project, cellname, ACTUAL, DONTCARE, LAYOUT) != 0) {
		    PE "%s: cannot remove cell '%s' of view-type '%s'\n",
						    argv0, cellname, LAYOUT);
		}
	    }
	    if (sw_cir) {
		if (sw_verb)
		    PE "removing cell %s of view-type '%s'\n",
			    cellname, CIRCUIT);
		if (dmRemoveCell (project, cellname, ACTUAL, DONTCARE, CIRCUIT) != 0) {
		    PE "%s: cannot remove cell '%s' of view-type '%s'\n",
						    argv0, cellname, CIRCUIT);
		}
	    }
#ifndef ESE
	    if (sw_flp) {
		if (dmRemoveCell (project, cellname, ACTUAL, DONTCARE, FLOORPLAN) != 0) {
		    PE "%s: cannot remove cell '%s' of view-type '%s'\n",
						    argv0, cellname, FLOORPLAN);
		}
	    }
#endif
#ifdef ESE
	}
#endif
    }

    die (0);			

}   /* end of main */

	
confirm_view (view)
char   *view;
{
    PE "Remove all specified cells of view-type '%s' : are you sure? [y/n]: ", view);
    if (fgets (buf, BUFLEN, stdin) && (buf[0] == 'y'))
	return (0);
    else
	return (-1);
}

rem_imp (view)
char   *view;
{
#ifdef MSDOS
	sprintf (path, "%s/impclist", view);
#else
	sprintf (path, "%s/impcelllist", view);
#endif
	fclose (fopen (path, "w"));
}

rem_view (project, view)
DM_PROJECT *project;
char   *view;
{
    if (!sw_imp) {
#ifdef MSDOS
	sprintf (path, "%s/impclist", view);
	sprintf (iclf, "%s.icl", view);
#else
	sprintf (path, "%s/impcelllist", view);
	sprintf (iclf, "%s.icl.%d", view, getpid ());
#endif
	if (link (path, iclf))
	    errexit (2, path);
    }
    _dmRmView (project, view);
    empty_dir (view);
}

dmError (s)
char   *s;
{
    PE "%s: ", argv0);
    dmPerror (s);
    if (no_exit == 0) errexit (1, "");
}

char   *err_list[] = {
     /* 0 */ "%s",
     /* 1 */ "error in DMI function",
     /* 2 */ "cannot link file: %s",
     /* 3 */ "warning: cannot create file: %s",
     /* 4 */ "warning: cannot create directory: %s",
     /* 5 */ "warning: cannot remove directory: %s",
     /* 6 */ "cannot unlink file: %s",
     /* 7 */ "unknown error"
};

errexit (errno, s)
int     errno;
char   *s;
{
    int     i;

    i = (errno < 0) ? -errno : errno;
    if (i > 7) i = 7;

    PE "%s: ", argv0);
    PE err_list[i], s);
    PE "\n");

    if (errno >= 0)
	die (1);
}

die (status)
int     status;
{
    if (!sw_force) {
	if (status)
	    PE "%s: -- program aborted --\n", argv0);
#ifndef ESE
	else
	    PE "%s: -- program finished --\n", argv0);
#endif
    }
    if (project)
	dmCloseProject (project, QUIT);
    dmQuit ();
    exit (status);
}

int setCellName (cellVar, aCellName)
char ** cellVar;
char * aCellName;
{
    (* cellVar) = aCellName;
    sw_cell++;
    return 0;
}

#ifdef MSDOS
link (s,t)
char *s, *t;
{
	FILE *fp1, *fp2;
	int c;
	fp1 = fopen (s, "r");
	fp2 = fopen (t, "w");
	if (fp1 == NULL || fp2 == NULL) return (1);

	while ( (c=fgetc(fp1)) != EOF)
		fputc (c,fp2);

	fclose (fp1);
	fclose (fp2);
	return (0);
}
#endif
