/* options.c  94.10.14
 * Copyright 1983-1992   Albert Davis
 * set and view options and user controllable variables
 */
#include "ecah.h"
#include "argparse.h"
#include "error.h"
#include "io.h"
#include "options.h"
#include "declare.h"
/*--------------------------------------------------------------------------*/
	void	cmd_options(const char*,int*);
/*--------------------------------------------------------------------------*/
extern const struct ioctrl io;
extern       struct options opt;
/*--------------------------------------------------------------------------*/
void cmd_options(const char *cmd, int *cnt)
{
 int dummy;
 int ii;
 double arg1, arg2;
 int changed = NO;

 while (cmd[*cnt]){
 			/* didsomething avoids heap space problem in MSC */
    int didsomething = argparse(cmd,cnt,REPEAT,
    	"ACCT",		aENUM,		&opt.acct,	YES,
    	"NOACCT",	aENUM,		&opt.acct,	NO,
	"LIST",		aENUM,		&opt.list,	YES,
	"NOLIST",	aENUM,		&opt.list,	NO,
	"MOD",		aENUM,		&opt.nomod,	NO,
	"NOMOD",	aENUM,		&opt.nomod,	YES,
	"PAGE",		aENUM,		&opt.page,	YES,
	"NOPAGE",	aENUM,		&opt.page,	NO,
	"NODE",		aENUM,		&opt.node,	YES,
	"NONODE",	aENUM,		&opt.node,	NO,
	"OPTS",		aENUM,		&opt.opts,	YES,
	"NOOPTS",	aENUM,		&opt.opts,	NO,
	"GMIN",		aUDOUBLE,	&opt.gmin,
	"RELTOL",	aUDOUBLE,	&opt.reltol,
	"ABSTOL",	aUDOUBLE,	&opt.abstol,
	"VNTOL",	aUDOUBLE,	&opt.vntol,
	"TRTOL",	aUDOUBLE,	&opt.trtol,
	"CHGTOL",	aUDOUBLE,	&opt.chgtol,
	"PIVTOL",	aUDOUBLE,	&opt.pivtol,
	"PIVREL",	aUDOUBLE,	&opt.pivrel,
	"NUMDGT",	aFINT,		&opt.numdgt,
	"TNOM",		aODOUBLE,	&opt.tnom,	-ABS_ZERO,
	"CPTIME",	aFINT,		&opt.cptime,
	"LIMTIM",	aFINT,		&opt.limtim,
	"LIMPTS",	aFINT,		&opt.limpts,
	"LVLCOD",	aFINT,		&opt.lvlcod,
	"LVLTIM",	aFINT,		&opt.lvltim,
	"METHOD",	aENUM,		&dummy,		YES,
	"GEAR",		aENUM,		&opt.method,	mGEAR,
	"TRAPezoidal",	aENUM,		&opt.method,	mTRAPEZOID,
	"MAXORD",	aFINT,		&opt.maxord,
	"DEFL", 	aUDOUBLE,	&opt.defl,
	"DEFW", 	aUDOUBLE,	&opt.defw,
	"DEFAD",	aUDOUBLE,	&opt.defad,
	"DEFAS",	aUDOUBLE,	&opt.defas,
 	"");
    if (didsomething)
       changed = YES;
    else if (argparse(cmd,cnt,REPEAT,
	"Seed",		aFINT,		&opt.seed,
	"WCZero",	aUDOUBLE,	&opt.wczero,
	"Damp",		aUDOUBLE,	&opt.damp,
	"Floor",	aUDOUBLE,	&opt.floor,
	"Tempamb",	aODOUBLE,	&opt.tempamb,	-ABS_ZERO,
	"Short",	aUDOUBLE,	&opt.shortckt,
	"TRansits",	aFINT,		&opt.transits,
	"INwidth",	aFINT,		&opt.inwidth,
	"OUTwidth",	aFINT,		&opt.outwidth,
	"XDivisions",	aUDOUBLE,	&opt.xdivisions,
	"YDivisions",	aUDOUBLE,	&opt.ydivisions,
 	""))
       changed = YES;
    else if (argparse(cmd,cnt,REPEAT,
	"NAG",		aENUM,		&opt.picky,	bNOERROR,
	"NONAG",	aENUM,		&opt.picky,	bTRACE,
	"TRACE",	aENUM,		&opt.picky,	bTRACE,
	"NOTRACE",	aENUM,		&opt.picky,	bLOG,
	"LOG",		aENUM,		&opt.picky,	bLOG,
	"NOLOG",	aENUM,		&opt.picky,	bDEBUG,
	"DEBUG",	aENUM,		&opt.picky,	bDEBUG,
	"NODEBUG",	aENUM,		&opt.picky,	bPICKY,
	"PICKY",	aENUM,		&opt.picky,	bPICKY,
	"NOPICKY",	aENUM,		&opt.picky,	bWARNING,
	"WARNing",	aENUM,		&opt.picky,	bWARNING,
	"NOWARN",	aENUM,		&opt.picky,	bDANGER,
	"ERRor",	aENUM,		&opt.picky,	bERROR,
	"NOERRor",	aENUM,		&opt.picky,	bDISASTER,
	"DISASTER",	aENUM,		&opt.picky,	bDISASTER,
	""))
       changed = YES;
    else if (argparse(cmd,cnt,REPEAT,
	"ORder",	aENUM,		&dummy,		YES,
	"REVerse",	aENUM,		&opt.order,	oREVERSE,
	"FORward",	aENUM,		&opt.order,	oFORWARD,
	"AUTo",		aENUM,		&opt.order,	oAUTO,
	"MODe",		aENUM,		&dummy,		YES,
	"ANAlog",	aENUM,		&opt.mode,	mANALOG,
	"DIGital",	aENUM,		&opt.mode,	mDIGITAL,
	"MIXed",	aENUM,		&opt.mode,	mMIXED,
	"DUPcheck",	aENUM,		&opt.dupcheck,	YES,
	"NODUPcheck",	aENUM,		&opt.dupcheck,	NO,
	"BYPass",	aENUM,		&opt.bypass,	YES,
	"NOBYPass",	aENUM,		&opt.bypass,	NO,
	"VBYPass",	aENUM,		&opt.bypass,	bVOLT,
	"INCmode",	aENUM,		&opt.incmode,	YES,
	"NOIncmode",	aENUM,		&opt.incmode,	NO,
	"LUBypasss",	aENUM,		&opt.lubypass,	YES,
	"NOLUbypass",	aENUM,		&opt.lubypass,	NO,
	"LIMIT",	aUDOUBLE,	&opt.limit,
	"VMAX",		aDOUBLE,	&opt.vmax,
	"VMIN",		aDOUBLE,	&opt.vmin,
	"MRT",		aUDOUBLE,	&opt.dtmin,
	"DTMIn",	aUDOUBLE,	&opt.dtmin,
	"DTRatio",	aUDOUBLE,	&opt.dtratio,
	"RSTray",	aENUM,		&opt.rstray,	YES,
	"NORSTray",	aENUM,		&opt.rstray,	NO,
	"CSTray",	aENUM,		&opt.cstray,	YES,
	"NOCSTray",	aENUM,		&opt.cstray,	NO,
	"Harmonics",	aFINT,		&opt.harmonics,
	"TRSTEPGrow",	aUDOUBLE,	&opt.trstepgrow,
	"TRSTEPShrink",	aUDOUBLE,	&opt.trstepshrink,
	"TRReject",	aUDOUBLE,	&opt.trreject,
	"SHOWALL",	aENUM,		&opt.showall,	YES,
	"NOSHOWALL",	aENUM,		&opt.showall,	NO,
	"FOOOO",	aFINT,		&opt.foooo,
	"DIODEflags",	aOCTAL,		&opt.diodeflags,
	"MOSflags",	aOCTAL,		&opt.mosflags,
 	""))
       changed = YES;
    else if (ii = *cnt, argparse(cmd,cnt,ONEPASS,
        "ITL",		a2DOUBLE,	&arg1,		&arg2,
	"")){
       if ((int)arg1 >= 1  &&  (int)arg1 < ITL_COUNT){
	  opt.itl[(int)arg1] = (int)arg2;
       }else{
          *cnt = ii;
	  syntax_check(cmd,cnt,bWARNING);
	  skiparg(cmd,cnt);
       }
       changed = YES;
    }else{
       syntax_check(cmd,cnt,bWARNING);
       skiparg(cmd,cnt);
    }
 }

 if (changed){
 dealloc(YES);
 opt.lowlim = 1 - opt.reltol;
 opt.uplim  = 1 + opt.reltol;
 opt.outwidth = abs(opt.outwidth);
 if (opt.outwidth > MAXWIDTH)
    opt.outwidth = MAXWIDTH;
 }

 if (!changed || opt.opts){
    int where = io.mstdout;
    mprintf(where, ".options ");
    if (opt.acct)   mprintf(where," acct ");
    if (opt.list)   mprintf(where," list ");
    if (opt.nomod)  mprintf(where," nomod ");
    if (opt.page)   mprintf(where," page ");
    if (opt.node)   mprintf(where," node ");
    if (opt.opts)   mprintf(where," opts ");
    mprintf(where, " gmin=%s ",   ftos(opt.gmin,   "", 7, 0));
    mprintf(where, " reltol=%s ", ftos(opt.reltol, "", 7, 0));
    mprintf(where, " abstol=%s ", ftos(opt.abstol, "", 7, 0));
    mprintf(where, " vntol=%s ",  ftos(opt.vntol,  "", 7, 0));
    mprintf(where, " trtol=%s ",  ftos(opt.trtol,  "", 7, 0));
    mprintf(where, " chgtol=%s ", ftos(opt.chgtol, "", 7, 0));
    mprintf(where, " pivtol=%s ", ftos(opt.pivtol, "", 7, 0));
    mprintf(where, " pivrel=%s ", ftos(opt.pivrel, "", 7, 0));
    mprintf(where, " numdgt=%d ", opt.numdgt);
    mprintf(where, " tnom=%s ",   ftos(opt.tnom+ABS_ZERO,   "", 7, 0));
    mprintf(where, " cptime=%d ", opt.cptime);
    mprintf(where, " limtim=%d ", opt.limtim);
    mprintf(where, " limpts=%d ", opt.limpts);
    mprintf(where, " lvlcod=%d ", opt.lvlcod);
    mprintf(where, " lvltim=%d ", opt.lvltim);
    if (opt.method == mTRAPEZOID) mprintf(where, " method=trapezoid ");
    else if (opt.method == mGEAR) mprintf(where, " method=gear ");
    mprintf(where, " maxord=%d ", opt.maxord);
    for (ii=1;  ii<ITL_COUNT;  ii++)
       mprintf(where, " itl%d=%d ", ii, opt.itl[ii]);
    mprintf(where, " defl=%s ", ftos(opt.defl, "", 7, 0));
    mprintf(where, " defw=%s ", ftos(opt.defw, "", 7, 0));
    mprintf(where, " defad=%s ", ftos(opt.defad, "", 7, 0));
    mprintf(where, " defas=%s ", ftos(opt.defas, "", 7, 0));
    mprintf(where, " seed=%d ",   opt.seed);
    mprintf(where, " wczero=%s ", ftos(opt.wczero,  "", 7, 0));
    mprintf(where, " damp=%s ",   ftos(opt.damp,    "", 7, 0));
    mprintf(where, " floor=%s ",  ftos(opt.floor,   "", 7, 0));
    mprintf(where, " tempamb=%s ",ftos(opt.tempamb+ABS_ZERO, "", 7, 0));
    mprintf(where, " short=%s ",  ftos(opt.shortckt,"", 7, 0));
    mprintf(where, " in=%d ",     opt.inwidth);
    mprintf(where, " out=%d ",    opt.outwidth);
    mprintf(where, " xdivisions=%s ",  ftos(opt.xdivisions,   "", 7, 0));
    mprintf(where, " ydivisions=%s ",  ftos(opt.ydivisions,   "", 7, 0));
    if (opt.order == oREVERSE) mprintf(where, " order=reverse ");
    else if (opt.order == oFORWARD) mprintf(where, " order=forward ");
    else if (opt.order == oAUTO) mprintf(where, " order=auto ");
    if (opt.mode == mANALOG) mprintf(where, " mode=analog ");
    else if (opt.mode == mDIGITAL) mprintf(where, " mode=digital ");
    else if (opt.mode == mMIXED) mprintf(where, " mode=mixed ");
    mprintf(where, " transits=%d ",opt.transits);
    mprintf(where," %sdupcheck ", ((opt.dupcheck)?"":"no"));  
    if (opt.bypass == NO) mprintf(where, " nobypass ");
    else if (opt.bypass == YES) mprintf(where, " bypass ");
    else if (opt.bypass == bVOLT) mprintf(where, " vbypass ");
    mprintf(where," %sincmode ", ((opt.incmode)?"":"no"));    
    mprintf(where," %slubypass ", ((opt.lubypass)?"":"no"));    
    mprintf(where, " limit=%s ",  ftos(opt.limit,"", 7, 0));
    mprintf(where, " vmax=%s ",  ftos(opt.vmax,"", 7, 0));
    mprintf(where, " vmin=%s ",  ftos(opt.vmin,"", 7, 0));
    mprintf(where, " dtmin=%s ",  ftos(opt.dtmin,"", 7, 0));
    mprintf(where, " dtratio=%s ",  ftos(opt.dtratio,"", 7, 0));
    mprintf(where," %srstray ", ((opt.rstray)?"":"no"));    
    mprintf(where," %scstray ", ((opt.cstray)?"":"no"));    
    mprintf(where, " harmonics=%d ", opt.harmonics);
    mprintf(where, " trstepgrow=%s ",  ftos(opt.trstepgrow,"", 7, 0));
    mprintf(where, " trstepshrink=%s ",  ftos(opt.trstepshrink,"", 7, 0));
    mprintf(where, " trreject=%s ",  ftos(opt.trreject,"", 7, 0));
    mprintf(where," %sshowall ", ((opt.showall)?"":"no"));    
    if (opt.showall){
       mprintf(where, " foooo=%d ", opt.foooo);
       mprintf(where, " diodeflags=%o ", opt.diodeflags);
       mprintf(where, " mosflags=%o ", opt.mosflags);
    }
    mputc('\n',where);
 }
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
