/* ac_setup.c  94.10.09
 * Copyright 1983-1992   Albert Davis
 * ac analysis setup
 */
#include "ecah.h"
#include "ac.h"
#include "argparse.h"
#include "error.h"
#include "io.h"
#include "mode.h"
#include "options.h"
#include "probh.h"
#include "worst.h"
#include "declare.h"
/*--------------------------------------------------------------------------*/
	void	ac_setup(const char*,int*,ac_t*);
static	void	ac_optby(const char*,int*);
static	void	ac_optdecade(const char*,int*);
static	void	ac_optlin(const char*,int*);
static	void	ac_optoctave(const char*,int*);
static	void	ac_opttimes(const char*,int*);
/*--------------------------------------------------------------------------*/
extern const probe_t *plotlist[];
extern       struct ioctrl io;
extern const struct options opt;
extern int worstcase;	/* worst case, monte carlo mode	(enum type, worst.h)*/
extern double temp;	/* actual ambient temperature, kelvin		    */
static int needslinfix;	/* flag: lin option needs patch later (spice compat)*/
static ac_t *ac;
/*--------------------------------------------------------------------------*/
void ac_setup(const char *cmd, int *cnt, ac_t *params)
{
 ac = params;
 io.where |= io.mstdout;
 temp = opt.tempamb;
 io.ploton = io.plotset && count_probes(plotlist[sAC]) > 0;
 ac->cold = ac->cont = ac->echo = worstcase = NO;
 for (;;){
    if (argparse(cmd,cnt,REPEAT,
	"*",		aFUNCTION,  ac_opttimes,
    	"ACMAx",	aENUM,	    &worstcase,	wMAXAC,
	"ACMIn",	aENUM,	    &worstcase,	wMINAC,
	"Ambient",	aODOUBLE,   &temp,	opt.tempamb,
	"By",		aFUNCTION,  ac_optby,
	"COLD",		aENUM,	    &ac->cold,	YES,
	"CONTinue",	aENUM,	    &ac->cont,	YES,
    	"DCMAx",	aENUM,	    &worstcase,	wMAXDC,
	"DCMIn",	aENUM,	    &worstcase,	wMINDC,
	"Decade",	aFUNCTION,  ac_optdecade,
	"Echo",		aENUM,	    &ac->echo,	YES,
	"LAg",		aENUM,	    &worstcase, wLAG,
	"LEad",		aENUM,	    &worstcase, wLEAD,
        "LIn",		aFUNCTION,  ac_optlin,
	"MAx",		aENUM,	    &worstcase, wMAXAC,
	"MIn",		aENUM,	    &worstcase, wMINAC,
	"NOPlot",	aENUM,	    &io.ploton, NO,
	"Octave",	aFUNCTION,  ac_optoctave,
	"PLot",		aENUM,	    &io.ploton, YES,
	"Reftemp",	aODOUBLE,   &temp,	opt.tnom,
	"SEnsitivity",	aENUM,	    &worstcase, wSENS,
	"Temperature",	aODOUBLE,   &temp,	-ABS_ZERO,
	"TImes",	aFUNCTION,  ac_opttimes,
	""))
	;	
    else if (isfloat(cmd[*cnt])){
       ac->start = ctof(cmd,cnt);
       ac->stop  = ctof(cmd,cnt);
       if (ac->stop==0.)
          ac->stop = ac->start;
       if (isfloat(cmd[*cnt]))
          ac_optby(cmd,cnt);
    }else if (outset(cmd,cnt,"","")){
	;
    }else{
	syntax_check(cmd,cnt,bWARNING);
	break;
    }
 }
 initio(io.where,io.whence);
 if (worstcase==wRAND  ||  worstcase==wWORST)
    io.ploton = NO;
 if (needslinfix){			    /* LIN option is # of points.  */
     ac->step=(ac->stop-ac->start)/(ac->step-1.);
     					    /* Must compute ac->step after */
     needslinfix = NO;			    /* reading start and stop,	   */
 }					    /* but step must be read first */
 if (ac->step==0.){			    /* for Spice compatibility	   */
    ac->step = ac->stop - ac->start;
    ac->linswp = YES;
 }
}
/*--------------------------------------------------------------------------*/
static void ac_optby(const char *cmd, int *cnt)
{
 ac->step = ctof(cmd,cnt);
 needslinfix = NO;
 ac->linswp = YES;
}
/*--------------------------------------------------------------------------*/
static void ac_optdecade(const char *cmd, int *cnt)
{
 ac->step = fabs(ctof(cmd,cnt));
 if (ac->step == 0.)
    ac->step = 1.;
 ac->step = pow(10., 1./ac->step);
 needslinfix = NO;
 ac->linswp = NO;
}
/*--------------------------------------------------------------------------*/
static void ac_optlin(const char *cmd, int *cnt)
{
 ac->step = fabs(ctof(cmd,cnt));	/* need to fix ac->step, later	*/
 if (ac->step == 0.)			/* do it at the end of ac_setup	*/
    ac->step = 1.;			/* a kluge, but this is a patch	*/
 needslinfix = YES;			/* and I am too lazy to do it	*/
 ac->linswp = YES;			/* right.			*/
}
/*--------------------------------------------------------------------------*/
static void ac_optoctave(const char *cmd, int *cnt)
{
 ac->step = fabs(ctof(cmd,cnt));
 if (ac->step == 0.)
    ac->step = 1.;
 ac->step = pow(2.00000001, 1./ac->step);
 needslinfix = NO;
 ac->linswp = NO;
}
/*--------------------------------------------------------------------------*/
static void ac_opttimes(const char *cmd, int *cnt)
{
 ac->step = fabs(ctof(cmd,cnt));
 if (ac->step == 0.   &&   ac->start != 0.)
    ac->step = ac->stop / ac->start;
 needslinfix = NO;
 ac->linswp = NO;
}
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
