inpgmod.c, #15/15, whitespace
This commit is contained in:
parent
fccdea429c
commit
56b2342df3
|
|
@ -13,58 +13,60 @@ Modified: 2001 Paolo Nenzi (Cider Integration)
|
|||
#include <errno.h>
|
||||
|
||||
#ifdef CIDER
|
||||
|
||||
#include "ngspice/numcards.h"
|
||||
#include "ngspice/carddefs.h"
|
||||
#include "ngspice/numgen.h"
|
||||
#include "ngspice/suffix.h"
|
||||
|
||||
#define E_MISSING -1
|
||||
#define E_AMBIGUOUS -2
|
||||
#define E_MISSING -1
|
||||
#define E_AMBIGUOUS -2
|
||||
|
||||
extern IFcardInfo *INPcardTab[];
|
||||
extern int INPnumCards;
|
||||
static int INPparseNumMod( CKTcircuit* ckt, INPmodel *model, INPtables *tab, char **errMessage );
|
||||
static int INPfindCard( char *name, IFcardInfo *table[], int numCards );
|
||||
static int INPfindParm( char *name, IFparm *table, int numParms );
|
||||
|
||||
static int INPparseNumMod(CKTcircuit *ckt, INPmodel *model, INPtables *tab, char **errMessage);
|
||||
static int INPfindCard(char *name, IFcardInfo *table[], int numCards);
|
||||
static int INPfindParm(char *name, IFparm *table, int numParms);
|
||||
|
||||
#endif
|
||||
|
||||
extern INPmodel *modtab;
|
||||
|
||||
|
||||
/*
|
||||
* code moved from INPgetMod
|
||||
*/
|
||||
static int
|
||||
create_model( CKTcircuit* ckt, INPmodel* modtmp, INPtables* tab )
|
||||
create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab)
|
||||
{
|
||||
IFvalue* val;
|
||||
char *err = NULL, *line, *parm, *endptr;
|
||||
int error, j;
|
||||
double dval;
|
||||
IFvalue *val;
|
||||
char *err = NULL, *line, *parm, *endptr;
|
||||
int error, j;
|
||||
double dval;
|
||||
|
||||
/* not already defined, so create & give parameters */
|
||||
error = ft_sim->newModel (ckt, modtmp->INPmodType, &(modtmp->INPmodfast), modtmp->INPmodName);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
#ifdef CIDER
|
||||
/* Handle Numerical Models Differently */
|
||||
if ( modtmp->INPmodType == INPtypelook("NUMD") ||
|
||||
modtmp->INPmodType == INPtypelook("NBJT") ||
|
||||
modtmp->INPmodType == INPtypelook("NUMD2") ||
|
||||
modtmp->INPmodType == INPtypelook("NBJT2") ||
|
||||
modtmp->INPmodType == INPtypelook("NUMOS") )
|
||||
{
|
||||
error = INPparseNumMod( ckt, modtmp, tab, &err );
|
||||
/* not already defined, so create & give parameters */
|
||||
error = ft_sim->newModel(ckt, modtmp->INPmodType, &(modtmp->INPmodfast), modtmp->INPmodName);
|
||||
if (error)
|
||||
return error;
|
||||
modtmp->INPmodLine->error = err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CIDER
|
||||
/* Handle Numerical Models Differently */
|
||||
if (modtmp->INPmodType == INPtypelook("NUMD") ||
|
||||
modtmp->INPmodType == INPtypelook("NBJT") ||
|
||||
modtmp->INPmodType == INPtypelook("NUMD2") ||
|
||||
modtmp->INPmodType == INPtypelook("NBJT2") ||
|
||||
modtmp->INPmodType == INPtypelook("NUMOS"))
|
||||
{
|
||||
error = INPparseNumMod(ckt, modtmp, tab, &err);
|
||||
if (error)
|
||||
return error;
|
||||
modtmp->INPmodLine->error = err;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* parameter isolation, identification, binding */
|
||||
/* parameter isolation, identification, binding */
|
||||
|
||||
line = modtmp->INPmodLine->line;
|
||||
|
||||
|
|
@ -76,225 +78,233 @@ create_model( CKTcircuit* ckt, INPmodel* modtmp, INPtables* tab )
|
|||
tfree(parm);
|
||||
INPgetTok(&line, &parm, 1); /* throw away 'modname' */
|
||||
tfree(parm);
|
||||
|
||||
while (*line) {
|
||||
INPgetTok(&line, &parm, 1);
|
||||
if (!*parm)
|
||||
continue;
|
||||
INPgetTok(&line, &parm, 1);
|
||||
if (!*parm)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < *(ft_sim->devices[modtmp->INPmodType]->numModelParms); j++) {
|
||||
for (j = 0; j < *(ft_sim->devices[modtmp->INPmodType]->numModelParms); j++) {
|
||||
|
||||
if (strcmp(parm, "txl") == 0)
|
||||
if (strcmp("cpl", ft_sim->devices[modtmp->INPmodType]->modelParms[j].keyword) == 0)
|
||||
strcpy(parm, "cpl");
|
||||
if (strcmp(parm, "txl") == 0)
|
||||
if (strcmp("cpl", ft_sim->devices[modtmp->INPmodType]->modelParms[j].keyword) == 0)
|
||||
strcpy(parm, "cpl");
|
||||
|
||||
if (strcmp(parm, ft_sim->devices[modtmp->INPmodType]->modelParms[j].keyword) == 0) {
|
||||
if (strcmp(parm, ft_sim->devices[modtmp->INPmodType]->modelParms[j].keyword) == 0) {
|
||||
|
||||
val = INPgetValue(ckt, &line, ft_sim->devices[modtmp->INPmodType]->modelParms[j].dataType, tab);
|
||||
val = INPgetValue(ckt, &line, ft_sim->devices[modtmp->INPmodType]->modelParms[j].dataType, tab);
|
||||
|
||||
error = ft_sim->setModelParm (ckt, modtmp->INPmodfast,
|
||||
error = ft_sim->setModelParm(ckt, modtmp->INPmodfast,
|
||||
ft_sim->devices[modtmp->INPmodType]->modelParms[j].id,
|
||||
val, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
break;
|
||||
if (error)
|
||||
return error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(parm, "level") == 0) {
|
||||
/* just grab the level number and throw away */
|
||||
/* since we already have that info from pass1 */
|
||||
val = INPgetValue(ckt, &line, IF_REAL, tab);
|
||||
} else if (j >= *(ft_sim->devices[modtmp->INPmodType]->numModelParms)) {
|
||||
if (strcmp(parm, "level") == 0) {
|
||||
/* just grab the level number and throw away */
|
||||
/* since we already have that info from pass1 */
|
||||
val = INPgetValue(ckt, &line, IF_REAL, tab);
|
||||
} else if (j >= *(ft_sim->devices[modtmp->INPmodType]->numModelParms)) {
|
||||
|
||||
/* want only the parameter names in output - not the values */
|
||||
errno = 0; /* To distinguish success/failure after call */
|
||||
dval = strtod(parm, &endptr);
|
||||
/* Check for various possible errors */
|
||||
if ((errno == ERANGE && dval == HUGE_VAL) || errno != 0) {
|
||||
perror("strtod");
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
/* want only the parameter names in output - not the values */
|
||||
errno = 0; /* To distinguish success/failure after call */
|
||||
dval = strtod(parm, &endptr);
|
||||
/* Check for various possible errors */
|
||||
if ((errno == ERANGE && dval == HUGE_VAL) || errno != 0) {
|
||||
perror("strtod");
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
if (endptr == parm) /* it was no number - it is really a string */
|
||||
err = INPerrCat(err,
|
||||
tprintf("unrecognized parameter (%s) - ignored",
|
||||
parm));
|
||||
}
|
||||
if (endptr == parm) /* it was no number - it is really a string */
|
||||
err = INPerrCat(err,
|
||||
tprintf("unrecognized parameter (%s) - ignored",
|
||||
parm));
|
||||
}
|
||||
FREE(parm);
|
||||
FREE(parm);
|
||||
}
|
||||
|
||||
modtmp->INPmodLine->error = err;
|
||||
|
||||
return 0;
|
||||
modtmp->INPmodLine->error = err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
parse_line( char* line, char* tokens[], int num_tokens, double values[], bool found[] )
|
||||
parse_line(char *line, char *tokens[], int num_tokens, double values[], bool found[])
|
||||
{
|
||||
int get_index = -1;
|
||||
int i;
|
||||
int get_index = -1;
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < num_tokens; i++ )
|
||||
found[i] = FALSE;
|
||||
for (i = 0; i < num_tokens; i++)
|
||||
found[i] = FALSE;
|
||||
|
||||
while (*line) {
|
||||
while (*line) {
|
||||
|
||||
if ( get_index != -1 ) {
|
||||
int error;
|
||||
values[get_index] = INPevaluate( &line, &error, 1 );
|
||||
found[get_index] = TRUE;
|
||||
get_index = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
char *token = NULL;
|
||||
INPgetNetTok( &line, &token, 1 );
|
||||
|
||||
for ( i = 0; i < num_tokens; i++ )
|
||||
if ( strcmp( tokens[i], token ) == 0 )
|
||||
get_index = i;
|
||||
txfree(token);
|
||||
}
|
||||
|
||||
for ( i = 0; i < num_tokens; i++ )
|
||||
if (!found[i])
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_equal( double result, double expectedResult )
|
||||
{
|
||||
return fabs(result - expectedResult) < 1e-15;
|
||||
}
|
||||
|
||||
static bool
|
||||
in_range( double value, double min, double max )
|
||||
{
|
||||
/* the standard binning rule is: min <= value < max */
|
||||
return is_equal(value, min) || (min < value && value < max);
|
||||
}
|
||||
|
||||
char*
|
||||
INPgetModBin( CKTcircuit* ckt, char* name, INPmodel** model, INPtables* tab, char* line )
|
||||
{
|
||||
INPmodel* modtmp;
|
||||
double l, w, lmin, lmax, wmin, wmax;
|
||||
double parse_values[4];
|
||||
bool parse_found[4];
|
||||
static char* instance_tokens[] = { "l", "w" };
|
||||
static char* model_tokens[] = { "lmin", "lmax", "wmin", "wmax" };
|
||||
double scale;
|
||||
|
||||
if (!cp_getvar("scale", CP_REAL, &scale))
|
||||
scale = 1;
|
||||
|
||||
*model = NULL;
|
||||
|
||||
if (!parse_line( line, instance_tokens, 2, parse_values, parse_found ))
|
||||
return NULL;
|
||||
|
||||
l = parse_values[0]*scale;
|
||||
w = parse_values[1]*scale;
|
||||
|
||||
for ( modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel ) {
|
||||
|
||||
if ( model_name_match(name, modtmp->INPmodName) < 2 )
|
||||
continue;
|
||||
|
||||
/* skip if not binnable */
|
||||
if (modtmp->INPmodType != INPtypelook ("BSIM3") &&
|
||||
modtmp->INPmodType != INPtypelook ("BSIM3v32") &&
|
||||
modtmp->INPmodType != INPtypelook ("BSIM3v0") &&
|
||||
modtmp->INPmodType != INPtypelook ("BSIM3v1") &&
|
||||
modtmp->INPmodType != INPtypelook ("BSIM4") &&
|
||||
modtmp->INPmodType != INPtypelook ("BSIM4v5") &&
|
||||
modtmp->INPmodType != INPtypelook ("BSIM4v6") &&
|
||||
modtmp->INPmodType != INPtypelook ("BSIM4v7") &&
|
||||
modtmp->INPmodType != INPtypelook ("HiSIM2") &&
|
||||
modtmp->INPmodType != INPtypelook ("HiSIMHV1") &&
|
||||
modtmp->INPmodType != INPtypelook ("HiSIMHV2"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if illegal device type */
|
||||
if (modtmp->INPmodType < 0) {
|
||||
*model = NULL;
|
||||
return tprintf("Unknown device type for model %s\n", name);
|
||||
}
|
||||
|
||||
if (!parse_line( modtmp->INPmodLine->line, model_tokens, 4, parse_values, parse_found ))
|
||||
continue;
|
||||
|
||||
lmin = parse_values[0]; lmax = parse_values[1];
|
||||
wmin = parse_values[2]; wmax = parse_values[3];
|
||||
|
||||
if ( in_range( l, lmin, lmax ) && in_range( w, wmin, wmax ) ) {
|
||||
/* create unless model is already defined */
|
||||
if ( !modtmp->INPmodfast ) {
|
||||
int error = create_model( ckt, modtmp, tab );
|
||||
if ( error )
|
||||
return NULL;
|
||||
if (get_index != -1) {
|
||||
int error;
|
||||
values[get_index] = INPevaluate(&line, &error, 1);
|
||||
found[get_index] = TRUE;
|
||||
get_index = -1;
|
||||
continue;
|
||||
}
|
||||
*model = modtmp;
|
||||
return NULL;
|
||||
|
||||
char *token = NULL;
|
||||
INPgetNetTok(&line, &token, 1);
|
||||
|
||||
for (i = 0; i < num_tokens; i++)
|
||||
if (strcmp(tokens[i], token) == 0)
|
||||
get_index = i;
|
||||
|
||||
txfree(token);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < num_tokens; i++)
|
||||
if (!found[i])
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
is_equal(double result, double expectedResult)
|
||||
{
|
||||
return fabs(result - expectedResult) < 1e-15;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
in_range(double value, double min, double max)
|
||||
{
|
||||
/* the standard binning rule is: min <= value < max */
|
||||
return is_equal(value, min) || (min < value && value < max);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
INPgetMod(CKTcircuit *ckt, char *name, INPmodel ** model, INPtables * tab)
|
||||
INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char *line)
|
||||
{
|
||||
INPmodel *modtmp;
|
||||
INPmodel *modtmp;
|
||||
double l, w, lmin, lmax, wmin, wmax;
|
||||
double parse_values[4];
|
||||
bool parse_found[4];
|
||||
static char *instance_tokens[] = { "l", "w" };
|
||||
static char *model_tokens[] = { "lmin", "lmax", "wmin", "wmax" };
|
||||
double scale;
|
||||
|
||||
#ifdef TRACE
|
||||
printf("In INPgetMod, examining model %s ...\n", name);
|
||||
#endif
|
||||
if (!cp_getvar("scale", CP_REAL, &scale))
|
||||
scale = 1;
|
||||
|
||||
for (modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel) {
|
||||
*model = NULL;
|
||||
|
||||
#ifdef TRACE
|
||||
printf("In INPgetMod, comparing %s against stored model %s ...\n", name, modtmp->INPmodName);
|
||||
#endif
|
||||
if (!parse_line(line, instance_tokens, 2, parse_values, parse_found))
|
||||
return NULL;
|
||||
|
||||
if (strcmp(modtmp->INPmodName, name) == 0) {
|
||||
/* found the model in question - now instantiate if necessary */
|
||||
/* and return an appropriate pointer to it */
|
||||
l = parse_values[0] * scale;
|
||||
w = parse_values[1] * scale;
|
||||
|
||||
/* if illegal device type */
|
||||
if (modtmp->INPmodType < 0) {
|
||||
for (modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel) {
|
||||
|
||||
#ifdef TRACE
|
||||
printf("In INPgetMod, illegal device type for model %s ...\n", name);
|
||||
#endif
|
||||
if (model_name_match(name, modtmp->INPmodName) < 2)
|
||||
continue;
|
||||
|
||||
*model = NULL;
|
||||
return tprintf("Unknown device type for model %s\n", name);
|
||||
}
|
||||
|
||||
/* create unless model is already defined */
|
||||
if (! modtmp->INPmodfast) {
|
||||
int error = create_model( ckt, modtmp, tab );
|
||||
if ( error ) {
|
||||
*model = NULL;
|
||||
return INPerror(error);
|
||||
/* skip if not binnable */
|
||||
if (modtmp->INPmodType != INPtypelook("BSIM3") &&
|
||||
modtmp->INPmodType != INPtypelook("BSIM3v32") &&
|
||||
modtmp->INPmodType != INPtypelook("BSIM3v0") &&
|
||||
modtmp->INPmodType != INPtypelook("BSIM3v1") &&
|
||||
modtmp->INPmodType != INPtypelook("BSIM4") &&
|
||||
modtmp->INPmodType != INPtypelook("BSIM4v5") &&
|
||||
modtmp->INPmodType != INPtypelook("BSIM4v6") &&
|
||||
modtmp->INPmodType != INPtypelook("BSIM4v7") &&
|
||||
modtmp->INPmodType != INPtypelook("HiSIM2") &&
|
||||
modtmp->INPmodType != INPtypelook("HiSIMHV1") &&
|
||||
modtmp->INPmodType != INPtypelook("HiSIMHV2"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if illegal device type */
|
||||
if (modtmp->INPmodType < 0) {
|
||||
*model = NULL;
|
||||
return tprintf("Unknown device type for model %s\n", name);
|
||||
}
|
||||
|
||||
if (!parse_line(modtmp->INPmodLine->line, model_tokens, 4, parse_values, parse_found))
|
||||
continue;
|
||||
|
||||
lmin = parse_values[0]; lmax = parse_values[1];
|
||||
wmin = parse_values[2]; wmax = parse_values[3];
|
||||
|
||||
if (in_range(l, lmin, lmax) && in_range(w, wmin, wmax)) {
|
||||
/* create unless model is already defined */
|
||||
if (!modtmp->INPmodfast) {
|
||||
int error = create_model(ckt, modtmp, tab);
|
||||
if (error)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*model = modtmp;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
*model = modtmp;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
INPgetMod(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab)
|
||||
{
|
||||
INPmodel *modtmp;
|
||||
|
||||
#ifdef TRACE
|
||||
printf("In INPgetMod, didn't find model for %s, using default ...\n", name);
|
||||
printf("In INPgetMod, examining model %s ...\n", name);
|
||||
#endif
|
||||
|
||||
*model = NULL;
|
||||
return tprintf("Unable to find definition of model %s - default assumed\n", name);
|
||||
for (modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel) {
|
||||
|
||||
#ifdef TRACE
|
||||
printf("In INPgetMod, comparing %s against stored model %s ...\n", name, modtmp->INPmodName);
|
||||
#endif
|
||||
|
||||
if (strcmp(modtmp->INPmodName, name) == 0) {
|
||||
/* found the model in question - now instantiate if necessary */
|
||||
/* and return an appropriate pointer to it */
|
||||
|
||||
/* if illegal device type */
|
||||
if (modtmp->INPmodType < 0) {
|
||||
#ifdef TRACE
|
||||
printf("In INPgetMod, illegal device type for model %s ...\n", name);
|
||||
#endif
|
||||
*model = NULL;
|
||||
return tprintf("Unknown device type for model %s\n", name);
|
||||
}
|
||||
|
||||
/* create unless model is already defined */
|
||||
if (!modtmp->INPmodfast) {
|
||||
int error = create_model(ckt, modtmp, tab);
|
||||
if (error) {
|
||||
*model = NULL;
|
||||
return INPerror(error);
|
||||
}
|
||||
}
|
||||
|
||||
*model = modtmp;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TRACE
|
||||
printf("In INPgetMod, didn't find model for %s, using default ...\n", name);
|
||||
#endif
|
||||
|
||||
*model = NULL;
|
||||
return tprintf("Unable to find definition of model %s - default assumed\n", name);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CIDER
|
||||
/*
|
||||
* Parse a numerical model by running through the list of original
|
||||
|
|
@ -308,14 +318,14 @@ INPgetMod(CKTcircuit *ckt, char *name, INPmodel ** model, INPtables * tab)
|
|||
* other = new card
|
||||
*/
|
||||
static int
|
||||
INPparseNumMod( CKTcircuit* ckt, INPmodel *model, INPtables *tab, char **errMessage )
|
||||
INPparseNumMod(CKTcircuit *ckt, INPmodel *model, INPtables *tab, char **errMessage)
|
||||
{
|
||||
card *txtCard; /* Text description of a card */
|
||||
card *txtCard; /* Text description of a card */
|
||||
GENcard *tmpCard; /* Processed description of a card */
|
||||
IFcardInfo *info = NULL; /* Info about the type of card located */
|
||||
char *cardName = NULL; /* name of a card */
|
||||
int cardNum = 0; /* number of this card in the overall line */
|
||||
char *err = NULL; /* Strings for error messages */
|
||||
IFcardInfo *info = NULL; /* Info about the type of card located */
|
||||
char *cardName = NULL; /* name of a card */
|
||||
int cardNum = 0; /* number of this card in the overall line */
|
||||
char *err = NULL; /* Strings for error messages */
|
||||
int error;
|
||||
|
||||
/* Chase down to the top of the list of actual cards */
|
||||
|
|
@ -366,21 +376,21 @@ INPparseNumMod( CKTcircuit* ckt, INPmodel *model, INPtables *tab, char **errMess
|
|||
/* new command card */
|
||||
if (cardName) /* get rid of old card name */
|
||||
FREE(cardName);
|
||||
INPgetTok(&line,&cardName,1); /* get new card name */
|
||||
INPgetTok(&line, &cardName, 1); /* get new card name */
|
||||
if (*cardName) { /* Found a name? */
|
||||
int lastType = INPfindCard(cardName,INPcardTab,INPnumCards);
|
||||
int lastType = INPfindCard(cardName, INPcardTab, INPnumCards);
|
||||
if (lastType >= 0) {
|
||||
/* Add card structure to model */
|
||||
info = INPcardTab[lastType];
|
||||
error = info->newCard (&tmpCard, model->INPmodfast );
|
||||
error = info->newCard(&tmpCard, model->INPmodfast);
|
||||
if (error)
|
||||
return error;
|
||||
/* Handle parameter-less cards */
|
||||
} else if (cinprefix( cardName, "title", 3 ) ) {
|
||||
} else if (cinprefix(cardName, "title", 3)) {
|
||||
/* Do nothing */
|
||||
} else if (cinprefix( cardName, "comment", 3 ) ) {
|
||||
} else if (cinprefix(cardName, "comment", 3)) {
|
||||
/* Do nothing */
|
||||
} else if (cinprefix( cardName, "end", 3 ) ) {
|
||||
} else if (cinprefix(cardName, "end", 3)) {
|
||||
/* Terminate parsing */
|
||||
*errMessage = err;
|
||||
return 0;
|
||||
|
|
@ -398,16 +408,19 @@ INPparseNumMod( CKTcircuit* ckt, INPmodel *model, INPtables *tab, char **errMess
|
|||
|
||||
/* parse the rest of this line */
|
||||
while (*line) {
|
||||
|
||||
int invert = FALSE;
|
||||
/* Strip leading carat from booleans */
|
||||
if (*line == '^') {
|
||||
invert = TRUE;
|
||||
line++;
|
||||
}
|
||||
|
||||
char *parm; /* name of a parameter */
|
||||
INPgetTok(&line,&parm,1);
|
||||
INPgetTok(&line, &parm, 1);
|
||||
if (!*parm)
|
||||
break;
|
||||
|
||||
int idx = INPfindParm(parm, info->cardParms, info->numParms);
|
||||
if (idx == E_MISSING) {
|
||||
/* parm not found */
|
||||
|
|
@ -420,7 +433,8 @@ INPparseNumMod( CKTcircuit* ckt, INPmodel *model, INPtables *tab, char **errMess
|
|||
tprintf("Error on card %d : ambiguous parameter (%s) - ignored",
|
||||
cardNum, parm));
|
||||
} else {
|
||||
IFvalue *value = INPgetValue( ckt, &line, info->cardParms[idx].dataType, tab );
|
||||
IFvalue *value = INPgetValue(ckt, &line, info->cardParms[idx].dataType, tab);
|
||||
|
||||
/* invert if this is a boolean entry */
|
||||
if (invert) {
|
||||
if ((info->cardParms[idx].dataType & IF_VARTYPES) == IF_FLAG)
|
||||
|
|
@ -430,7 +444,8 @@ INPparseNumMod( CKTcircuit* ckt, INPmodel *model, INPtables *tab, char **errMess
|
|||
tprintf("Error on card %d : non-boolean parameter (%s) - \'^\' ignored",
|
||||
cardNum, parm));
|
||||
}
|
||||
error = info->setCardParm (info->cardParms[idx].id, value, tmpCard );
|
||||
|
||||
error = info->setCardParm(info->cardParms[idx].id, value, tmpCard);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
|
@ -442,11 +457,12 @@ INPparseNumMod( CKTcircuit* ckt, INPmodel *model, INPtables *tab, char **errMess
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Locate the best match to a card name in an IFcardInfo table
|
||||
*/
|
||||
static int
|
||||
INPfindCard( char *name, IFcardInfo *table[], int numCards )
|
||||
INPfindCard(char *name, IFcardInfo *table[], int numCards)
|
||||
{
|
||||
int length = (int) strlen(name);
|
||||
int best = E_MISSING;
|
||||
|
|
@ -455,23 +471,25 @@ INPfindCard( char *name, IFcardInfo *table[], int numCards )
|
|||
int test;
|
||||
|
||||
/* compare all the names in the card table to this name */
|
||||
for ( test = 0; test < numCards; test++ ) {
|
||||
int match = cimatch( name, table[test]->name );
|
||||
if ((match > 0) && (match == bestMatch )){
|
||||
for (test = 0; test < numCards; test++) {
|
||||
int match = cimatch(name, table[test]->name);
|
||||
if ((match > 0) && (match == bestMatch)) {
|
||||
best = E_AMBIGUOUS;
|
||||
} else if ((match > bestMatch) && (match == length)) {
|
||||
best = test;
|
||||
bestMatch = match;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Locate the best match to a parameter name in an IFparm table
|
||||
*/
|
||||
static int
|
||||
INPfindParm( char *name, IFparm *table, int numParms )
|
||||
INPfindParm(char *name, IFparm *table, int numParms)
|
||||
{
|
||||
int length = (int) strlen(name);
|
||||
int best = E_MISSING;
|
||||
|
|
@ -481,9 +499,9 @@ INPfindParm( char *name, IFparm *table, int numParms )
|
|||
int test;
|
||||
|
||||
/* compare all the names in the parameter table to this name */
|
||||
for ( test = 0; test < numParms; test++ ) {
|
||||
int match = cimatch( name, table[test].keyword );
|
||||
if ( (match == length) && (match == (int) strlen(table[test].keyword)) ) {
|
||||
for (test = 0; test < numParms; test++) {
|
||||
int match = cimatch(name, table[test].keyword);
|
||||
if ((match == length) && (match == (int) strlen(table[test].keyword))) {
|
||||
/* exact match */
|
||||
return test;
|
||||
}
|
||||
|
|
@ -496,6 +514,7 @@ INPfindParm( char *name, IFparm *table, int numParms )
|
|||
best = test;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue