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:
Giles Atkinson 2025-01-26 12:10:56 +00:00
parent 350147a231
commit e858ca9465
2 changed files with 62 additions and 123 deletions

View File

@ -62,13 +62,56 @@ static int MIFget_integer(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,
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
@ -94,7 +137,6 @@ MIFgetValue (
int btemp;
int itemp;
double rtemp;
char *stemp;
IFcomplex ctemp;
char *token;
@ -114,6 +156,7 @@ MIFgetValue (
/* initialize stuff if array */
if(is_array) {
token = MIFget_token(line, &token_type);
tfree(token);
@ -129,7 +172,9 @@ MIFgetValue (
/* now get the values into val */
for (;;) {
if ((value_type & ~IF_VECTOR) == IF_STRING)
token = get_string(line, is_array, &token_type);
else
token = MIFget_token(line, &token_type);
/* exit if no more tokens */
@ -163,14 +208,14 @@ MIFgetValue (
break;
case IF_STRING:
val.sValue = MIFget_string(token, err);
val.sValue = token;
token = NULL;
break;
case IF_COMPLEX:
val.cValue = MIFget_complex(token, token_type, line, err);
break;
case IF_FLAGVEC:
btemp = MIFget_boolean(token, err);
val.v.vec.iVec = TREALLOC(int, val.v.vec.iVec, val.v.numValue + 1);
@ -193,10 +238,10 @@ MIFgetValue (
break;
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[val.v.numValue] = stemp;
val.v.vec.sVec[val.v.numValue] = token;
val.v.numValue++;
token = NULL;
break;
case IF_CPLXVEC:
@ -220,6 +265,7 @@ MIFgetValue (
if(! is_array)
break;
if (token)
tfree(token);
} /* 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,

View File

@ -47,11 +47,6 @@ NON-STANDARD FEATURES
#include "ngspice/miftypes.h"
#include "ngspice/mifproto.h"
/* #include "suffix.h" */
/*
MIFgettok
@ -67,7 +62,6 @@ MIFgettok treats ( and ) like whitespace.
char *MIFgettok(char **s)
{
char *ret_str; /* storage for returned string */
char *end;
char *beg;
@ -122,14 +116,12 @@ char *MIFgettok(char **s)
/* else, read until the next delimiter */
else {
beg = *s;
while ((**s != '\0') &&
(!(isspace_c(**s) || (**s == '=') || (**s == '%') ||
(**s == '(') || (**s == ')') || (**s == ',') ||
(**s == '[') || (**s == ']') ||
(**s == '<') || (**s == '>') || (**s == '~')
))) {
while (**s != '\0' &&
!(isspace_c(**s) || **s == '=' || **s == '%' ||
**s == '(' || **s == ')' || **s == ',' ||
**s == '[' || **s == ']' ||
**s == '<' || **s == '>' || **s == '~'))
(*s)++;
}
end = *s;
/* 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);
/* if no next token, return */
if(ret_str == NULL) {