|
|
|
@ -275,7 +275,6 @@ cimatch(char *p, char *s) |
|
|
|
* since I didn't want to break any fcns which called it from elsewhere than |
|
|
|
* subckt.c. -- SDB 12.3.2003. |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
char * |
|
|
|
gettok(char **s) |
|
|
|
{ |
|
|
|
@ -350,44 +349,63 @@ nexttok(const char *s) |
|
|
|
char * |
|
|
|
gettok_iv(char **s) |
|
|
|
{ |
|
|
|
char c; |
|
|
|
int paren; |
|
|
|
char *token; /* return token */ |
|
|
|
SPICE_DSTRING buf; /* allow any length string */ |
|
|
|
char *p_src = *s; /* location in source string */ |
|
|
|
char c; /* current char */ |
|
|
|
|
|
|
|
paren = 0; |
|
|
|
while (isspace_c(**s) || (**s == '=')) |
|
|
|
(*s)++; |
|
|
|
/* Step past whitespace and '=' */ |
|
|
|
while (isspace_c(c = *p_src) || (c == '=')) { |
|
|
|
p_src++; |
|
|
|
} |
|
|
|
|
|
|
|
if ((!**s) || ((**s != 'v') && (**s != 'i') && (**s != 'V') && (**s != 'I'))) |
|
|
|
return NULL; |
|
|
|
/* Test for valid leading character */ |
|
|
|
if (((c =*p_src) == '\0') || |
|
|
|
((c != 'v') && (c != 'i') && (c != 'V') && (c != 'I'))) { |
|
|
|
*s = p_src; /* update position in string */ |
|
|
|
return (char *) NULL; |
|
|
|
} |
|
|
|
|
|
|
|
// initialize string |
|
|
|
spice_dstring_init(&buf); |
|
|
|
// add v or i to buf |
|
|
|
spice_dstring_append_char(&buf, *(*s)++); |
|
|
|
/* Allocate buffer for token being returned */ |
|
|
|
char * const token = TMALLOC(char, strlen(p_src) + 1); |
|
|
|
char *p_dst = token; /* location in token */ |
|
|
|
|
|
|
|
while ((c = **s) != '\0') { |
|
|
|
if (c == '(') |
|
|
|
paren += 1; |
|
|
|
else if (c == ')') |
|
|
|
paren -= 1; |
|
|
|
if (isspace_c(c)) |
|
|
|
(*s)++; |
|
|
|
else { |
|
|
|
spice_dstring_append_char(&buf, *(*s)++); |
|
|
|
if (paren == 0) |
|
|
|
break; |
|
|
|
// add v or i to buf |
|
|
|
*p_dst++ = *p_src++; |
|
|
|
|
|
|
|
{ |
|
|
|
int n_paren = 0; |
|
|
|
/* Skip any space between v/V/i/I and '(' */ |
|
|
|
p_src = skip_ws(p_src); |
|
|
|
|
|
|
|
while ((c = *p_src) != '\0') { |
|
|
|
/* Keep track of nesting level */ |
|
|
|
if (c == '(') { |
|
|
|
n_paren++; |
|
|
|
} |
|
|
|
else if (c == ')') { |
|
|
|
n_paren--; |
|
|
|
} |
|
|
|
|
|
|
|
if (isspace_c(c)) { /* Do not copy whitespace to output */ |
|
|
|
p_src++; |
|
|
|
} |
|
|
|
else { |
|
|
|
*p_dst++ = *p_src++; |
|
|
|
if (n_paren == 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
while (isspace_c(**s) || **s == ',') |
|
|
|
(*s)++; |
|
|
|
/* Step past whitespace and ',' */ |
|
|
|
while (isspace_c(c = *p_src) || (c == ',')) { |
|
|
|
p_src++; |
|
|
|
} |
|
|
|
|
|
|
|
token = copy(spice_dstring_value(&buf)); |
|
|
|
spice_dstring_free(&buf); |
|
|
|
*s = p_src; /* update position in string */ |
|
|
|
return token; |
|
|
|
} |
|
|
|
} /* end of function gettok_iv */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------* |
|
|
|
@ -650,36 +668,55 @@ get_r_paren(char **s) |
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------* |
|
|
|
* this function strips all white space inside parens |
|
|
|
* is needed in gettoks (dotcards.c) for right processing of expressions |
|
|
|
* like ".plot v( 5,4) v(6)" |
|
|
|
* is needed in gettoks (dotcards.c) for correct processing of expressions |
|
|
|
* like " .plot v( 5 , 4 ) v( 6 )" -> .plot v(5,4) v(6)" |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
char * |
|
|
|
stripWhiteSpacesInsideParens(char *str) |
|
|
|
stripWhiteSpacesInsideParens(const char *str) |
|
|
|
{ |
|
|
|
char *token; /* return token */ |
|
|
|
SPICE_DSTRING buf; /* allow any length string */ |
|
|
|
int i = 0; /* index into string */ |
|
|
|
|
|
|
|
while ((str[i] == ' ') || (str[i] == '\t')) |
|
|
|
i++; |
|
|
|
|
|
|
|
spice_dstring_init(&buf); |
|
|
|
for (; str[i]; i++) |
|
|
|
if (str[i] != '(') { |
|
|
|
spice_dstring_append_char(&buf, str[i]); |
|
|
|
} else { |
|
|
|
spice_dstring_append_char(&buf, str[i]); |
|
|
|
while (str[i++] != ')') |
|
|
|
if (str[i] != ' ') |
|
|
|
spice_dstring_append_char(&buf, str[i]); |
|
|
|
i--; |
|
|
|
str = skip_ws(str); /* Skip leading whitespace */ |
|
|
|
const size_t n_char_str = strlen(str); |
|
|
|
|
|
|
|
/* Allocate buffer for string being built */ |
|
|
|
char * const str_out = TMALLOC(char, n_char_str + 1); |
|
|
|
char *p_dst = str_out; /* location in str_out */ |
|
|
|
char ch; /* current char */ |
|
|
|
|
|
|
|
/* Process input string until its end */ |
|
|
|
for ( ; ; ) { |
|
|
|
/* Add char. If at end of input string, return the string |
|
|
|
* that was built */ |
|
|
|
if ((*p_dst++ = (ch = *str++)) == '\0') { |
|
|
|
return str_out; |
|
|
|
} |
|
|
|
|
|
|
|
token = copy(spice_dstring_value(&buf)); |
|
|
|
spice_dstring_free(&buf); |
|
|
|
return token; |
|
|
|
} |
|
|
|
/* If the char is a ')' add all non-whitespace until ')' or, |
|
|
|
* if the string is malformed, until '\0' */ |
|
|
|
if (ch == '(') { |
|
|
|
for ( ; ; ) { |
|
|
|
/* If at end of input string, the closing ') was missing. |
|
|
|
* The caller will need to resolve this issue. */ |
|
|
|
if ((ch = *str++) == '\0') { |
|
|
|
*p_dst = '\0'; |
|
|
|
return str_out; |
|
|
|
} |
|
|
|
|
|
|
|
if (isspace((int) ch)) { /* skip whitespace */ |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
/* Not whitespace, so add next character */ |
|
|
|
*p_dst++ = ch; |
|
|
|
|
|
|
|
/* If the char that was added was ')', done */ |
|
|
|
if (ch == ')') { |
|
|
|
break; |
|
|
|
} |
|
|
|
} /* end of loop processing () */ |
|
|
|
} /* end of case of '(' found */ |
|
|
|
} /* end of loop over chars in input string */ |
|
|
|
} /* end of function stripWhiteSpacesInsideParens */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
@ -761,3 +798,6 @@ model_name_match(const char *token, const char *model_name) |
|
|
|
|
|
|
|
return 2; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|