/* main.c  94.05.03
 * Copyright 1983-1992   Albert Davis
 * top level module
 * it all starts here
 */
#include "ecah.h"
#include "argparse.h"
#include "error.h"
#include "io.h"
#include "mode.h"
#include "options.h"
#include "patchlev.h"
#include "status.h"
#include "declare.h"
/*--------------------------------------------------------------------------*/
	int	main(int,const char*[]);
static	void    sign_on(void);
static	void    read_startup_files(void);
static	void    process_cmd_line(int,const char*[]);
static	void	finish(void);
	void	cmdproc(const char*);
/*--------------------------------------------------------------------------*/
extern       struct ioctrl io;
extern const struct options opt;
extern const double zero;
extern const char e_int[];
extern int run_mode;
extern int sim_mode;
extern int sim_phase;
extern FILE *stream[];	    /* reverse of fileno() */
extern jmp_buf envp;
extern int cmdcount;
/*--------------------------------------------------------------------------*/
int main(int argc, const char *argv[])
{
 initialize_io();
 sign_on();
 if (setjmp(envp)){		
    finish();			/* error clean up (from longjmp())	*/
 }else{
    read_startup_files();
    process_cmd_line(argc,argv);
    setup_traps();
 }  
 for (;;){
    char cmdbuf[BUFLEN];
    cmdcount++;
    (void)getcmd("-->", cmdbuf, BUFLEN);
    run_mode = rEXECUTE;
    cmdproc(cmdbuf);
 }
 /*NOTREACHED*/
 return 0;
}
/*--------------------------------------------------------------------------*/
static void sign_on(void)
{
 mprintf(io.mstdout,"ACS (Al's Circuit Simulator) 0.%u\n",PATCHLEVEL);
 mprintf(io.mstdout,"Never trust any version less than 1.0\n");
 mprintf(io.mstdout,"Copyright 1994, Albert Davis\n");
 mprintf(io.mstdout,"ACS comes with ABSOLUTELY NO WARRANTY\n");
 mprintf(io.mstdout,"This is free software, and you are welcome\n");
 mprintf(io.mstdout,"to redistribute it under certain conditions.\n");
 mprintf(io.mstdout,"See the file \"COPYING\" for details\n");
}
/*--------------------------------------------------------------------------*/
static void read_startup_files(void)
{
 char *name;
 if (!!(name = findfile(SYSTEMSTARTFILE, SYSTEMSTARTPATH, R_OK))){
    char cmdbuf[BUFLEN];
    sprintf(cmdbuf, "get %s", name);
    cmdproc(cmdbuf);
 }
 if (!!(name = findfile(USERSTARTFILE, USERSTARTPATH, R_OK))){
    char cmdbuf[BUFLEN];
    sprintf(cmdbuf, "get %s", name);
    cmdproc(cmdbuf);
 }
 cmdproc("clear");
}
/*--------------------------------------------------------------------------*/
static void process_cmd_line(int argc, const char *argv[])
{
 if (argc > 1){
    char cmdbuf[BUFLEN];
    sprintf(cmdbuf, "< %s", argv[1]);
    cmdproc(cmdbuf);
 }
}
/*--------------------------------------------------------------------------*/
/* finish: clean up after a command
 * deallocates space, closes plot windows, resets i/o redirection, etc.
 * This is done separately for exception handling.
 * If a command aborts, clean-up is still done, leaving a consistent state.
 */
static void finish(void)
{
 dc_finish();
 plclose();
 if (zero!=0.)
    error(bWARNING, e_int, "zero");
 io.suppresserrors = NO;
 outreset();
 dealloc(NO);
}
/*--------------------------------------------------------------------------*/
/* cmdproc: process a command
 * parse, and act on, a command string
 */
void cmdproc(const char *cmd)
{
 int cnt = 0;
 static struct time_s timecheck;
 int didsomething = YES;

 error(bTRACE, "%s\n", cmd);

 time_check(&timecheck);
 time_zstart(&timecheck);
 sim_mode = sNONE;
 sim_phase = pNONE;
 if (argparse(cmd,&cnt,ONEPASS,
	"Ac",	    aFUNCTION,		 cmd_ac,
	"ALArm",    a2FUNCTION, plclear, cmd_alarm,
	"ALTer",    aFUNCTION,		 cmd_alter,
	"Build",    a2FUNCTION, plclear, cmd_build,
	"CHDir",    a2FUNCTION, plclear, cmd_chdir,
	"CDir",	    a2FUNCTION, plclear, cmd_chdir,
	"CLEAR",    a2FUNCTION, plclear, cmd_clear,
	"CRTSET",   a2FUNCTION, plclear, cmd_crtset,
	""))
    ;	/* split to hide sun lint bug. */
 else if (argparse(cmd,&cnt,ONEPASS,
	"DC",	    aFUNCTION,	    	 cmd_dc,
	"DELete",   a2FUNCTION, plclear, cmd_delete,
	"DIsto",    aFUNCTION,		 cmd_disto,
	"Edit",	    a2FUNCTION, plclear, cmd_edit,
	"END",	    aFUNCTION,		 cmd_quit,
	"ENDS",	    aFUNCTION,		 cmd_ends,
	"EXIt",	    a2FUNCTION, plclear, cmd_quit,
	"FANout",   a2FUNCTION, plclear, cmd_fanout,
	"FAult",    aFUNCTION,	   	 cmd_fault,
	""))
    ;	/* split to hide sun lint bug. */
 else if (argparse(cmd,&cnt,ONEPASS,
	"FOurier",  aFUNCTION,	   	 cmd_fourier,
	"Generator",a2FUNCTION, plclear, cmd_generator,
	"GET",	    a2FUNCTION, plclear, cmd_get,
	"Help",	    a2FUNCTION, plclear, cmd_help,
	"IC",	    aFUNCTION,		 cmd_ic,
	"INsert",   a2FUNCTION, plclear, cmd_insert,
	"List",	    a2FUNCTION, plclear, cmd_list,
	"LOg",	    aFUNCTION,	   	 cmd_log,
	""))
    ;	/* split to hide sun lint bug. */
 else if (argparse(cmd,&cnt,ONEPASS,
	"MArk",	    aFUNCTION,	   	 cmd_mark,
	"MErge",    a2FUNCTION, plclear, cmd_merge,
	"MODEl",    aFUNCTION,		 cmd_model,
	"Modify",   a2FUNCTION, plclear, cmd_modify,
	"NODeset",  aFUNCTION,		 cmd_nodeset,
	"NOIse",    aFUNCTION,		 cmd_noise,
	"OP",	    aFUNCTION,	    	 cmd_op,
	""))
    ;	/* split to hide sun lint bug. */
 else if (argparse(cmd,&cnt,ONEPASS,
	"OPTions",  a2FUNCTION, plclear, cmd_options,
	"PAuse",    aFUNCTION,	   	 cmd_pause,
	"PLot",	    a2FUNCTION, plclear, cmd_plot,
	"PRint",    a2FUNCTION, plclear, cmd_print,
	"PRobe",    a2FUNCTION, plclear, cmd_print,
	"Quit",	    a2FUNCTION, plclear, cmd_quit,
	"Restore",  a2FUNCTION, plclear, cmd_restore,
	"SAve",	    a2FUNCTION, plclear, cmd_save,
	""))
    ;	/* split to hide sun lint bug. */
 else if (argparse(cmd,&cnt,ONEPASS,
	"SENs",	    aFUNCTION,		 cmd_sens,
	"SEt",	    a2FUNCTION, plclear, cmd_options,
	"SPectrum", aFUNCTION,	   	 cmd_fourier,
	"STatus",   a2FUNCTION, plclear, cmd_status,
	"SUbckt",   aFUNCTION,		 cmd_subckt,
	"SWeep",    a2FUNCTION, plclear, cmd_sweep,
	"TEmp",	    aFUNCTION,		 cmd_temp,
	"TF",	    aFUNCTION,		 cmd_tf,
	""))
    ;	/* split to hide sun lint bug. */
 else if (argparse(cmd,&cnt,ONEPASS,
	"TItle",    a2FUNCTION, plclear, cmd_title,
	"TRansient",aFUNCTION,	   	 cmd_tr,
	"UNFault",  aFUNCTION,	   	 cmd_unfault,
	"UNMark",   aFUNCTION,	   	 cmd_unmark,
	"Width",    aFUNCTION,		 cmd_options,
	"!",	    a2FUNCTION, plclear, cmd_system,
	"<",	    aFUNCTION,	   	 cmd_run,
	""))
    ;	/* split to hide sun lint bug. */
 else if (argparse(cmd,&cnt,ONEPASS,
	">",	    aFUNCTION,	   	 cmd_file,
	""))
    ;
 else{    /* comment or error */
    cmd_comment(cmd,&cnt);
    didsomething = NO;
 }
 if (opt.acct  &&  didsomething){
    time_check(&timecheck);
    mprintf(io.mstdout,"time=%8.2f\n",
    		timecheck.last_user + timecheck.last_system);
 }
 finish();
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
