static char *SccsId = "@(#)main.c 4.9 (TU-Delft) 04/27/92";
/**********************************************************

Name/Version      : macro/4.9

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

Author(s)         : A.J. van Genderen
Creation date     : 5-Feb-1992
Modified by       : 
Modification date : 


        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) 1992 , All rights reserved
**********************************************************/
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dmincl.h>
#ifdef ESE
#include "eseOption.h"
#include "tversion.h"
#endif

#ifdef ESE
char *argv0 = "mkmacro";
#else
char *argv0 = "macro";
#endif
char *use_msg = "\nUsage: %s [-s | -u] [ cell ... ]\n\n";

int tog_set;
int tog_unset;

DM_PROJECT *dmproject = NULL;

#ifdef ESE
OptionSpec optionSpecs[] = {
    { "usage", NO, eseHelp, (void *) optionSpecs,
            "-usage:            mkmacro [options] [ cell ... ]\nOptions (may be abbreviated) are:"},
    { "set", NO, eseTurnOn, (void *) & tog_set ,
            "    -set:              set macro flag "  },
    { "unset", NO, eseTurnOn, (void *) & tog_unset ,
            "    -unset:            unset macro flag "  },
    { "%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" },
    { "release", NO, esePrintString, (void *) TOOLVERSION,
            "    -release:          print the release number of this tool"},
    { (char *) 0, (char) 0, (IFP) 0, (void *) 0, (char *) 0 },
};
#endif

int set_val;

main (argc, argv)
int argc;
char *argv[];
{
    char *s;
    char **cellNames;
    int cell_cnt;
    char *cell;

    int exist;
    int isMacro;
    int mode;
    int flag;
    struct stat buf;

    DM_CELL *cellKey;
    DM_STREAM *dsp;
    char **celllist;

    set_val = 0;

    cellNames = (char **) calloc (argc, sizeof (char *));

#ifndef ESE
    cell_cnt = 0;
    while (--argc > 0) {
        if ((*++argv)[0] == '-' ) {
	    for (s = *argv + 1; *s != '\0'; s++) {
	        switch (*s) {
		    case 's':
			set_val = 1;
			break;
		    case 'u':
			set_val = 2;
			break;
		    default: 
		        fprintf (stderr, 
				 "%s: illegal option: %c\n", argv0, *s);
		        exit (1);
	        }
	    }
	}
	else {
	    cellNames[cell_cnt++] = *argv;
	}
    }
    cellNames[cell_cnt] = NULL;
#else
    tog_set = 0;
    tog_unset = 0;

    if (eseOptionHandler (argc, argv, optionSpecs, argc, cellNames)) {
	fprintf (stderr, use_msg, argv0);
	exit (1);
    }

    if (tog_set) set_val = 1;
    else if (tog_unset) set_val = 2;
#endif

    dmInit (argv0);
    dmproject = dmOpenProject (DEFAULT_PROJECT, DEFAULT_MODE);

    initIntrup ();

    if (*cellNames == NULL) {

	fprintf (stdout, "\nmacros:\n\n");

	celllist = (char **)dmGetMetaDesignData (CELLLIST, dmproject, LAYOUT);
	while (*celllist) {

	    cellKey = dmCheckOut (dmproject, *celllist, WORKING, 
				     DONTCARE, LAYOUT, READONLY);

	    if (dmStat (cellKey, "is_macro", &buf) == 0) {
		dsp = dmOpenStream (cellKey, "is_macro", "r");
		if (fscanf (dsp -> dmfp, "%d", &flag) > 0 && flag == 1)
		    fprintf (stdout, "   %s\n", *celllist);
		dmCloseStream (dsp, COMPLETE);
	    }

	    dmCheckIn (cellKey, COMPLETE);

	    celllist++;
	}

	fprintf (stdout, "\n");
    }
    else {

	while (*cellNames) {

	    cell = *cellNames++;

	    if (set_val)
		mode = ATTACH;
	    else
		mode = READONLY;

	    cellKey = dmCheckOut (dmproject, cell, WORKING, DONTCARE, 
							   LAYOUT, mode);

	    exist = 0;
	    if (dmStat (cellKey, "is_macro", &buf) == 0) {
		dsp = dmOpenStream (cellKey, "is_macro", "r");
		if (fscanf (dsp -> dmfp, "%d", &flag) > 0 && flag == 1)
		    exist = 1;
		dmCloseStream (dsp, COMPLETE);
	    }
	    isMacro = exist;

	    if (set_val == 1 && !exist) {
		dsp = dmOpenStream (cellKey, "is_macro", "w");
		fprintf (dsp -> dmfp, "1\n");
		dmCloseStream (dsp, COMPLETE);
		isMacro = 1;
	    }
	    if (set_val == 2 && exist) {
		dsp = dmOpenStream (cellKey, "is_macro", "w");
		fprintf (dsp -> dmfp, "0\n");
		dmCloseStream (dsp, COMPLETE);
		isMacro = 0;
	    }

	    dmCheckIn (cellKey, COMPLETE);

	    fprintf (stderr, "%s: macro = %s\n", 
			 cell, ((isMacro) ? ("yes") : ("no")));
	}
    }

    if (dmproject) dmCloseProject (dmproject, COMPLETE);
    dmQuit ();

    return (0);
}

initIntrup ()
{
    int int_hdl ();

    if (signal (SIGINT, SIG_IGN) != SIG_IGN)   
        signal (SIGINT, int_hdl);
        /* only when value was not SIG_IGN, a jump must be done to int_hdl */
    if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
        signal (SIGQUIT, int_hdl);
        /* only when value was not SIG_IGN, a jump must be done to int_hdl */
    signal (SIGTERM, int_hdl);
    signal (SIGILL, int_hdl);
    signal (SIGFPE, int_hdl);
#ifdef SIGBUS /* [ps] */
    signal (SIGBUS, int_hdl);
#endif
    signal (SIGSEGV, int_hdl);
}

int_hdl (sig)   /* interrupt handler */
int sig;
{
    switch (sig) {
        case SIGILL :
            fprintf (stderr, "Illegal instruction\n");
            break;
        case SIGFPE :
            fprintf (stderr, "Floating point exception\n");
            break;
#ifdef SIGBUS /* [ps] */
        case SIGBUS :
            fprintf (stderr, "Bus error\n");
            break;
#endif
        case SIGSEGV :
            fprintf (stderr, "Segmentation violation\n");
            break;
        default :
            break;
    }

    die ();
}

dmError (s)
char *s;
{
    dmPerror (s);
    die ();
}

die () 
{
    if (dmproject) dmCloseProject (dmproject, QUIT);
    dmQuit ();
    exit (1);
}
