When parsing a XSPICE string-valued model parameter, break only
on a closing quote, string end or white space (if unquoted) and unquoted ']' when parsing an array. That allows generic value overrides for GHDL models to pass through: "-gVar=value". Previously, the string was terminated on '='. Also remove some dead and non-functional code.
This commit is contained in:
parent
350147a231
commit
e858ca9465
|
|
@ -62,13 +62,56 @@ static int MIFget_integer(char *token, char **err);
|
||||||
|
|
||||||
static double MIFget_real(char *token, char **err);
|
static double MIFget_real(char *token, char **err);
|
||||||
|
|
||||||
static char *MIFget_string(char *token, char **err);
|
|
||||||
|
|
||||||
static IFcomplex MIFget_complex(char *token, Mif_Token_Type_t token_type,
|
static IFcomplex MIFget_complex(char *token, Mif_Token_Type_t token_type,
|
||||||
char **line, char **err);
|
char **line, char **err);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Pull a string from a .model card, like MIFget_token() but do not break
|
||||||
|
* on any special characters except '"' and ']'.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char *get_string(char **s, int is_array, Mif_Token_Type_t *token_type)
|
||||||
|
{
|
||||||
|
char *ret_str; /* storage for returned string */
|
||||||
|
char *end;
|
||||||
|
char *beg;
|
||||||
|
|
||||||
|
/* Skip over white space. */
|
||||||
|
|
||||||
|
while (isspace_c(**s))
|
||||||
|
(*s)++;
|
||||||
|
if (!*s) {
|
||||||
|
*token_type = MIF_NO_TOK;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If first character is a quote, read until the closing
|
||||||
|
* quote, or the end of string, discarding the quotes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (**s == '"') {
|
||||||
|
(*s)++;
|
||||||
|
ret_str = gettok_char(s, '"', FALSE, FALSE);
|
||||||
|
if (**s == '"')
|
||||||
|
(*s)++;
|
||||||
|
} else if (is_array && **s == ']') {
|
||||||
|
*token_type = MIF_RARRAY_TOK;
|
||||||
|
(*s)++;
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
/* Read to next white-space, end of line, or end of array. */
|
||||||
|
|
||||||
|
beg = *s;
|
||||||
|
while (**s != '\0' && !(isspace_c(**s) || (is_array && **s == ']')))
|
||||||
|
(*s)++;
|
||||||
|
end = *s;
|
||||||
|
ret_str = copy_substring(beg, end);
|
||||||
|
}
|
||||||
|
*token_type = MIF_STRING;
|
||||||
|
return ret_str;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
MIFgetValue
|
MIFgetValue
|
||||||
|
|
||||||
|
|
@ -94,7 +137,6 @@ MIFgetValue (
|
||||||
int btemp;
|
int btemp;
|
||||||
int itemp;
|
int itemp;
|
||||||
double rtemp;
|
double rtemp;
|
||||||
char *stemp;
|
|
||||||
IFcomplex ctemp;
|
IFcomplex ctemp;
|
||||||
|
|
||||||
char *token;
|
char *token;
|
||||||
|
|
@ -114,6 +156,7 @@ MIFgetValue (
|
||||||
|
|
||||||
|
|
||||||
/* initialize stuff if array */
|
/* initialize stuff if array */
|
||||||
|
|
||||||
if(is_array) {
|
if(is_array) {
|
||||||
token = MIFget_token(line, &token_type);
|
token = MIFget_token(line, &token_type);
|
||||||
tfree(token);
|
tfree(token);
|
||||||
|
|
@ -129,7 +172,9 @@ MIFgetValue (
|
||||||
/* now get the values into val */
|
/* now get the values into val */
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
if ((value_type & ~IF_VECTOR) == IF_STRING)
|
||||||
|
token = get_string(line, is_array, &token_type);
|
||||||
|
else
|
||||||
token = MIFget_token(line, &token_type);
|
token = MIFget_token(line, &token_type);
|
||||||
|
|
||||||
/* exit if no more tokens */
|
/* exit if no more tokens */
|
||||||
|
|
@ -163,14 +208,14 @@ MIFgetValue (
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IF_STRING:
|
case IF_STRING:
|
||||||
val.sValue = MIFget_string(token, err);
|
val.sValue = token;
|
||||||
|
token = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IF_COMPLEX:
|
case IF_COMPLEX:
|
||||||
val.cValue = MIFget_complex(token, token_type, line, err);
|
val.cValue = MIFget_complex(token, token_type, line, err);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case IF_FLAGVEC:
|
case IF_FLAGVEC:
|
||||||
btemp = MIFget_boolean(token, err);
|
btemp = MIFget_boolean(token, err);
|
||||||
val.v.vec.iVec = TREALLOC(int, val.v.vec.iVec, val.v.numValue + 1);
|
val.v.vec.iVec = TREALLOC(int, val.v.vec.iVec, val.v.numValue + 1);
|
||||||
|
|
@ -193,10 +238,10 @@ MIFgetValue (
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IF_STRINGVEC:
|
case IF_STRINGVEC:
|
||||||
stemp = MIFget_string(token, err);
|
|
||||||
val.v.vec.sVec = TREALLOC(char *, val.v.vec.sVec, val.v.numValue + 1);
|
val.v.vec.sVec = TREALLOC(char *, val.v.vec.sVec, val.v.numValue + 1);
|
||||||
val.v.vec.sVec[val.v.numValue] = stemp;
|
val.v.vec.sVec[val.v.numValue] = token;
|
||||||
val.v.numValue++;
|
val.v.numValue++;
|
||||||
|
token = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IF_CPLXVEC:
|
case IF_CPLXVEC:
|
||||||
|
|
@ -220,6 +265,7 @@ MIFgetValue (
|
||||||
if(! is_array)
|
if(! is_array)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (token)
|
||||||
tfree(token);
|
tfree(token);
|
||||||
|
|
||||||
} /* end forever loop */
|
} /* end forever loop */
|
||||||
|
|
@ -302,16 +348,6 @@ static double MIFget_real(char *token, char **err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* *************************************************************** */
|
|
||||||
|
|
||||||
static char *MIFget_string(char *token, char **err)
|
|
||||||
{
|
|
||||||
char* ctoken = MIFcopy(token);
|
|
||||||
*err = NULL;
|
|
||||||
return(ctoken);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* *************************************************************** */
|
/* *************************************************************** */
|
||||||
|
|
||||||
static IFcomplex MIFget_complex(char *token, Mif_Token_Type_t token_type,
|
static IFcomplex MIFget_complex(char *token, Mif_Token_Type_t token_type,
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,6 @@ NON-STANDARD FEATURES
|
||||||
#include "ngspice/miftypes.h"
|
#include "ngspice/miftypes.h"
|
||||||
#include "ngspice/mifproto.h"
|
#include "ngspice/mifproto.h"
|
||||||
|
|
||||||
/* #include "suffix.h" */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
MIFgettok
|
MIFgettok
|
||||||
|
|
@ -67,7 +62,6 @@ MIFgettok treats ( and ) like whitespace.
|
||||||
|
|
||||||
char *MIFgettok(char **s)
|
char *MIFgettok(char **s)
|
||||||
{
|
{
|
||||||
|
|
||||||
char *ret_str; /* storage for returned string */
|
char *ret_str; /* storage for returned string */
|
||||||
char *end;
|
char *end;
|
||||||
char *beg;
|
char *beg;
|
||||||
|
|
@ -122,14 +116,12 @@ char *MIFgettok(char **s)
|
||||||
/* else, read until the next delimiter */
|
/* else, read until the next delimiter */
|
||||||
else {
|
else {
|
||||||
beg = *s;
|
beg = *s;
|
||||||
while ((**s != '\0') &&
|
while (**s != '\0' &&
|
||||||
(!(isspace_c(**s) || (**s == '=') || (**s == '%') ||
|
!(isspace_c(**s) || **s == '=' || **s == '%' ||
|
||||||
(**s == '(') || (**s == ')') || (**s == ',') ||
|
**s == '(' || **s == ')' || **s == ',' ||
|
||||||
(**s == '[') || (**s == ']') ||
|
**s == '[' || **s == ']' ||
|
||||||
(**s == '<') || (**s == '>') || (**s == '~')
|
**s == '<' || **s == '>' || **s == '~'))
|
||||||
))) {
|
|
||||||
(*s)++;
|
(*s)++;
|
||||||
}
|
|
||||||
end = *s;
|
end = *s;
|
||||||
|
|
||||||
/* skip over white spaces, '=', '(', ')', and ',' up to next token */
|
/* skip over white spaces, '=', '(', ')', and ',' up to next token */
|
||||||
|
|
@ -143,94 +135,6 @@ char *MIFgettok(char **s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* preliminary fix */
|
|
||||||
char *MIFgettok(char **s)
|
|
||||||
{
|
|
||||||
|
|
||||||
char *buf; /* temporary storage to copy token into */
|
|
||||||
char *ret_str; /* storage for returned string */
|
|
||||||
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* allocate space big enough for the whole string */
|
|
||||||
|
|
||||||
buf = TMALLOC(char, strlen(*s) + 2);
|
|
||||||
/* FIXME, not yet understood why +1 leads to spurious crash in tfree, if optimized code for Windows*/
|
|
||||||
|
|
||||||
/* skip over any white space */
|
|
||||||
|
|
||||||
while(isspace_c(**s) || (**s == '=') ||
|
|
||||||
(**s == '(') || (**s == ')') || (**s == ','))
|
|
||||||
(*s)++;
|
|
||||||
|
|
||||||
/* isolate the next token */
|
|
||||||
|
|
||||||
switch(**s) {
|
|
||||||
|
|
||||||
case '\0':
|
|
||||||
FREE(buf);
|
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
case '<':
|
|
||||||
case '>':
|
|
||||||
case '[':
|
|
||||||
case ']':
|
|
||||||
case '~':
|
|
||||||
case '%':
|
|
||||||
buf[0] = **s;
|
|
||||||
buf[1] = '\0';
|
|
||||||
(*s)++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
i = 0;
|
|
||||||
/* if first character is a quote, read until the closing */
|
|
||||||
/* quote, or the end of string, discarding the quotes */
|
|
||||||
if(**s == '"') {
|
|
||||||
(*s)++;
|
|
||||||
while( (**s != '\0') && (**s != '"') ) {
|
|
||||||
buf[i] = **s;
|
|
||||||
i++;
|
|
||||||
(*s)++;
|
|
||||||
}
|
|
||||||
if(**s == '"')
|
|
||||||
(*s)++;
|
|
||||||
}
|
|
||||||
/* else, read until the next delimiter */
|
|
||||||
else {
|
|
||||||
while( (**s != '\0') &&
|
|
||||||
(! ( isspace_c(**s) || (**s == '=') || (**s == '%') ||
|
|
||||||
(**s == '(') || (**s == ')') || (**s == ',') ||
|
|
||||||
(**s == '[') || (**s == ']') ||
|
|
||||||
(**s == '<') || (**s == '>') || (**s == '~')
|
|
||||||
) ) ) {
|
|
||||||
buf[i] = **s;
|
|
||||||
i++;
|
|
||||||
(*s)++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[i] = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* skip over white space up to next token */
|
|
||||||
|
|
||||||
while(isspace_c(**s) || (**s == '=') ||
|
|
||||||
(**s == '(') || (**s == ')') || (**s == ','))
|
|
||||||
(*s)++;
|
|
||||||
|
|
||||||
/* make a copy using only the space needed by the string length */
|
|
||||||
/* Changed from copy to MIFcopy by SDB on 6.22.2003 */
|
|
||||||
ret_str = MIFcopy(buf);
|
|
||||||
FREE(buf);
|
|
||||||
|
|
||||||
return(ret_str);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
@ -255,7 +159,6 @@ char *MIFget_token(
|
||||||
|
|
||||||
ret_str = MIFgettok(s);
|
ret_str = MIFgettok(s);
|
||||||
|
|
||||||
|
|
||||||
/* if no next token, return */
|
/* if no next token, return */
|
||||||
|
|
||||||
if(ret_str == NULL) {
|
if(ret_str == NULL) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue