|
|
|
@ -19,24 +19,26 @@ prefix(const char *p, const char *s) |
|
|
|
{ |
|
|
|
while (*p && (*p == *s)) |
|
|
|
p++, s++; |
|
|
|
|
|
|
|
if (!*p) |
|
|
|
return (TRUE); |
|
|
|
else |
|
|
|
return (FALSE); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Create a copy of a string. */ |
|
|
|
|
|
|
|
char * |
|
|
|
copy(const char *str) |
|
|
|
{ |
|
|
|
char *p; |
|
|
|
|
|
|
|
|
|
|
|
if (!str) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
if ((p = TMALLOC(char, strlen(str) + 1)) != NULL) |
|
|
|
(void) strcpy(p, str); |
|
|
|
(void) strcpy(p, str); |
|
|
|
return(p); |
|
|
|
} |
|
|
|
|
|
|
|
@ -88,7 +90,6 @@ tvprintf(const char *fmt, va_list args) |
|
|
|
p = TREALLOC(char, p, size); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return (p == buf) ? copy(p) : p; |
|
|
|
} |
|
|
|
|
|
|
|
@ -117,7 +118,7 @@ substring(const char *sub, const char *str) |
|
|
|
|
|
|
|
while (*str) { |
|
|
|
if (*str == *sub) { |
|
|
|
t = str; |
|
|
|
t = str; |
|
|
|
for (s = sub; *s; s++) { |
|
|
|
if (!*t || (*s != *t++)) |
|
|
|
break; |
|
|
|
@ -127,9 +128,11 @@ substring(const char *sub, const char *str) |
|
|
|
} |
|
|
|
str++; |
|
|
|
} |
|
|
|
|
|
|
|
return (FALSE); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Append one character to a string. Don't check for overflow. */ |
|
|
|
/* Almost like strcat( ) XXX */ |
|
|
|
|
|
|
|
@ -143,6 +146,7 @@ appendc(char *s, char c) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Try to identify an integer that begins a string. Stop when a non- |
|
|
|
* numeric character is reached. |
|
|
|
*/ |
|
|
|
@ -153,11 +157,13 @@ scannum(char *str) |
|
|
|
{ |
|
|
|
int i = 0; |
|
|
|
|
|
|
|
while(isdigit_c(*str)) |
|
|
|
while (isdigit_c(*str)) |
|
|
|
i = i * 10 + *(str++) - '0'; |
|
|
|
|
|
|
|
return(i); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Case insensitive str eq. */ |
|
|
|
/* Like strcasecmp( ) XXX */ |
|
|
|
|
|
|
|
@ -171,9 +177,11 @@ cieq(const char *p, const char *s) |
|
|
|
p++; |
|
|
|
s++; |
|
|
|
} |
|
|
|
|
|
|
|
return (*s ? FALSE : TRUE); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Case insensitive prefix. */ |
|
|
|
|
|
|
|
int |
|
|
|
@ -186,135 +194,147 @@ ciprefix(const char *p, const char *s) |
|
|
|
p++; |
|
|
|
s++; |
|
|
|
} |
|
|
|
|
|
|
|
return (TRUE); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
strtolower(char *str) |
|
|
|
{ |
|
|
|
if (str) |
|
|
|
while (*str) { |
|
|
|
if(isupper_c(*str)) |
|
|
|
if (isupper_c(*str)) |
|
|
|
*str = tolower_c(*str); |
|
|
|
str++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
strtoupper(char *str) |
|
|
|
{ |
|
|
|
if (str) |
|
|
|
while (*str) { |
|
|
|
if(islower_c(*str)) |
|
|
|
if (islower_c(*str)) |
|
|
|
*str = toupper_c(*str); |
|
|
|
str++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef CIDER |
|
|
|
|
|
|
|
/* |
|
|
|
* Imported from cider file support/strmatch.c |
|
|
|
* Original copyright notice: |
|
|
|
* Author: 1991 David A. Gates, U. C. Berkeley CAD Group |
|
|
|
* |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
* Case-insensitive test of whether p is a prefix of s and at least the |
|
|
|
* first n characters are the same |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
cinprefix( |
|
|
|
register char *p, register char *s, |
|
|
|
register int n) |
|
|
|
cinprefix(register char *p, register char *s, register int n) |
|
|
|
{ |
|
|
|
if (!p || !s) return( 0 ); |
|
|
|
|
|
|
|
while (*p) { |
|
|
|
if ((isupper_c(*p) ? tolower_c(*p) : *p) != (isupper_c(*s) ? tolower_c(*s) : *s)) |
|
|
|
return( 0 ); |
|
|
|
p++; |
|
|
|
s++; |
|
|
|
n--; |
|
|
|
} |
|
|
|
if (n > 0) |
|
|
|
return( 0 ); |
|
|
|
else |
|
|
|
return( 1 ); |
|
|
|
} |
|
|
|
|
|
|
|
if (!p || !s) |
|
|
|
return(0); |
|
|
|
|
|
|
|
while (*p) { |
|
|
|
if ((isupper_c(*p) ? tolower_c(*p) : *p) != (isupper_c(*s) ? tolower_c(*s) : *s)) |
|
|
|
return(0); |
|
|
|
p++; |
|
|
|
s++; |
|
|
|
n--; |
|
|
|
} |
|
|
|
|
|
|
|
if (n > 0) |
|
|
|
return(0); |
|
|
|
else |
|
|
|
return(1); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
* Case-insensitive match of prefix string p against string s |
|
|
|
* returns the number of matching characters |
|
|
|
* |
|
|
|
* |
|
|
|
*/ |
|
|
|
|
|
|
|
int |
|
|
|
cimatch( |
|
|
|
register char *p, register char *s) |
|
|
|
|
|
|
|
int |
|
|
|
cimatch(register char *p, register char *s) |
|
|
|
{ |
|
|
|
register int n = 0; |
|
|
|
|
|
|
|
if (!p || !s) return( 0 ); |
|
|
|
|
|
|
|
while (*p) { |
|
|
|
if ((isupper_c(*p) ? tolower_c(*p) : *p) != (isupper_c(*s) ? tolower_c(*s) : *s)) |
|
|
|
return( n ); |
|
|
|
p++; |
|
|
|
s++; |
|
|
|
n++; |
|
|
|
} |
|
|
|
return( n ); |
|
|
|
} |
|
|
|
|
|
|
|
register int n = 0; |
|
|
|
|
|
|
|
if (!p || !s) |
|
|
|
return(0); |
|
|
|
|
|
|
|
while (*p) { |
|
|
|
if ((isupper_c(*p) ? tolower_c(*p) : *p) != (isupper_c(*s) ? tolower_c(*s) : *s)) |
|
|
|
return(n); |
|
|
|
p++; |
|
|
|
s++; |
|
|
|
n++; |
|
|
|
} |
|
|
|
|
|
|
|
return(n); |
|
|
|
} |
|
|
|
|
|
|
|
#endif /* CIDER */ |
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------* |
|
|
|
* gettok skips over whitespace and returns the next token found. This is |
|
|
|
* the original version. It does not "do the right thing" when you have |
|
|
|
* gettok skips over whitespace and returns the next token found. This is |
|
|
|
* the original version. It does not "do the right thing" when you have |
|
|
|
* parens or commas anywhere in the nodelist. Note that I left this unmodified |
|
|
|
* 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) |
|
|
|
{ |
|
|
|
char c; |
|
|
|
int paren; |
|
|
|
char *beg, *token ; /* return token */ |
|
|
|
char *beg, *token; /* return token */ |
|
|
|
|
|
|
|
paren = 0; |
|
|
|
|
|
|
|
*s = skip_ws(*s); |
|
|
|
if (!**s) |
|
|
|
return (NULL); |
|
|
|
beg = *s ; |
|
|
|
|
|
|
|
beg = *s; |
|
|
|
while ((c = **s) != '\0' && !isspace_c(c)) { |
|
|
|
if (c == '(') |
|
|
|
paren += 1; |
|
|
|
else if (c == ')') |
|
|
|
paren -= 1; |
|
|
|
else if (c == ',' && paren < 1) |
|
|
|
break; |
|
|
|
(*s)++ ; |
|
|
|
if (c == '(') |
|
|
|
paren += 1; |
|
|
|
else if (c == ')') |
|
|
|
paren -= 1; |
|
|
|
else if (c == ',' && paren < 1) |
|
|
|
break; |
|
|
|
(*s)++; |
|
|
|
} |
|
|
|
token = copy_substring(beg, *s) ; |
|
|
|
token = copy_substring(beg, *s); |
|
|
|
|
|
|
|
while (isspace_c(**s) || **s == ',') |
|
|
|
(*s)++; |
|
|
|
return ( token ) ; |
|
|
|
|
|
|
|
return (token); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------* |
|
|
|
* nexttok skips over whitespaces and the next token in s |
|
|
|
* returns NULL if there is nothing left to skip. |
|
|
|
* It replaces constructs like txfree(gettok(&actstring)) by |
|
|
|
* actstring = nexttok(actstring). This is derived from the original gettok version. |
|
|
|
* It does not "do the right thing" when |
|
|
|
* you have parens or commas anywhere in the nodelist. |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
* nexttok skips over whitespaces and the next token in s |
|
|
|
* returns NULL if there is nothing left to skip. |
|
|
|
* It replaces constructs like txfree(gettok(&actstring)) by |
|
|
|
* actstring = nexttok(actstring). This is derived from the original gettok version. |
|
|
|
* It does not "do the right thing" when |
|
|
|
* you have parens or commas anywhere in the nodelist. |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
char * |
|
|
|
nexttok(const char *s) |
|
|
|
{ |
|
|
|
@ -324,7 +344,7 @@ nexttok(const char *s) |
|
|
|
if (!*s) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
for (;*s && !isspace_c(*s); s++) |
|
|
|
for (; *s && !isspace_c(*s); s++) |
|
|
|
if (*s == '(') |
|
|
|
paren += 1; |
|
|
|
else if (*s == ')') |
|
|
|
@ -340,157 +360,167 @@ nexttok(const char *s) |
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------* |
|
|
|
* gettok skips over whitespaces or '=' and returns the next token found, |
|
|
|
* gettok skips over whitespaces or '=' and returns the next token found, |
|
|
|
* if the token is something like i(xxx), v(yyy), or v(xxx,yyy) |
|
|
|
* -- h_vogt 10.07.2010. |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
char * |
|
|
|
gettok_iv(char **s) |
|
|
|
{ |
|
|
|
char c; |
|
|
|
int paren; |
|
|
|
char *token ; /* return token */ |
|
|
|
SPICE_DSTRING buf ; /* allow any length string */ |
|
|
|
char *token; /* return token */ |
|
|
|
SPICE_DSTRING buf; /* allow any length string */ |
|
|
|
|
|
|
|
paren = 0; |
|
|
|
while ((isspace_c(**s)) || (**s=='=')) |
|
|
|
while ((isspace_c(**s)) || (**s == '=')) |
|
|
|
(*s)++; |
|
|
|
|
|
|
|
if ((!**s) || ((**s != 'v') && (**s != 'i') && (**s != 'V') && (**s != 'I'))) |
|
|
|
return (NULL); |
|
|
|
|
|
|
|
// initialize string |
|
|
|
spice_dstring_init(&buf); |
|
|
|
// add v or i to buf |
|
|
|
spice_dstring_append_char( &buf, *(*s)++ ) ; |
|
|
|
spice_dstring_append_char(&buf, *(*s)++); |
|
|
|
|
|
|
|
while ((c = **s) != '\0') { |
|
|
|
if (c == '(') |
|
|
|
paren += 1; |
|
|
|
else if (c == ')') |
|
|
|
paren -= 1; |
|
|
|
if (isspace_c(c)) |
|
|
|
if (isspace_c(c)) |
|
|
|
(*s)++; |
|
|
|
else { |
|
|
|
spice_dstring_append_char( &buf, *(*s)++ ) ; |
|
|
|
if (paren == 0) break; |
|
|
|
spice_dstring_append_char(&buf, *(*s)++); |
|
|
|
if (paren == 0) |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
while (isspace_c(**s) || **s == ',') |
|
|
|
(*s)++; |
|
|
|
token = copy( spice_dstring_value(&buf) ) ; |
|
|
|
spice_dstring_free(&buf) ; |
|
|
|
return ( token ) ; |
|
|
|
|
|
|
|
token = copy(spice_dstring_value(&buf)); |
|
|
|
spice_dstring_free(&buf); |
|
|
|
return (token); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------* |
|
|
|
* gettok_noparens was added by SDB on 4.21.2003. |
|
|
|
* It acts like gettok, except that it treats parens and commas like |
|
|
|
* whitespace while looking for the POLY token. That is, it stops |
|
|
|
* parsing and returns when it finds one of those chars. It is called from |
|
|
|
* whitespace while looking for the POLY token. That is, it stops |
|
|
|
* parsing and returns when it finds one of those chars. It is called from |
|
|
|
* 'translate' (subckt.c). |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
char * |
|
|
|
gettok_noparens(char **s) |
|
|
|
{ |
|
|
|
char c; |
|
|
|
char *beg, *token ; /* return token */ |
|
|
|
char *beg, *token; /* return token */ |
|
|
|
|
|
|
|
*s = skip_ws(*s); |
|
|
|
|
|
|
|
if (!**s) |
|
|
|
return (NULL); /* return NULL if we come to end of line */ |
|
|
|
|
|
|
|
beg = *s ; |
|
|
|
while ((c = **s) != '\0' && |
|
|
|
!isspace_c(c) && |
|
|
|
( **s != '(' ) && |
|
|
|
( **s != ')' ) && |
|
|
|
( **s != ',') |
|
|
|
) { |
|
|
|
(*s)++ ; |
|
|
|
beg = *s; |
|
|
|
while ((c = **s) != '\0' && |
|
|
|
!isspace_c(c) && |
|
|
|
(**s != '(') && |
|
|
|
(**s != ')') && |
|
|
|
(**s != ',') |
|
|
|
) { |
|
|
|
(*s)++; |
|
|
|
} |
|
|
|
token = copy_substring(beg, *s); |
|
|
|
|
|
|
|
token = copy_substring(beg, *s) ; |
|
|
|
|
|
|
|
/* Now iterate up to next non-whitespace char */ |
|
|
|
*s = skip_ws(*s); |
|
|
|
|
|
|
|
return ( token ) ; |
|
|
|
return (token); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
char * |
|
|
|
gettok_instance(char **s) |
|
|
|
{ |
|
|
|
char c; |
|
|
|
char *beg, *token ; /* return token */ |
|
|
|
char *beg, *token; /* return token */ |
|
|
|
|
|
|
|
*s = skip_ws(*s); |
|
|
|
|
|
|
|
if (!**s) |
|
|
|
return (NULL); /* return NULL if we come to end of line */ |
|
|
|
|
|
|
|
beg = *s ; |
|
|
|
while ((c = **s) != '\0' && |
|
|
|
!isspace_c(c) && |
|
|
|
( **s != '(' ) && |
|
|
|
( **s != ')' ) |
|
|
|
) { |
|
|
|
(*s)++ ; |
|
|
|
beg = *s; |
|
|
|
while ((c = **s) != '\0' && |
|
|
|
!isspace_c(c) && |
|
|
|
(**s != '(') && |
|
|
|
(**s != ')') |
|
|
|
) { |
|
|
|
(*s)++; |
|
|
|
} |
|
|
|
|
|
|
|
token = copy_substring(beg, *s) ; |
|
|
|
token = copy_substring(beg, *s); |
|
|
|
|
|
|
|
/* Now iterate up to next non-whitespace char */ |
|
|
|
*s = skip_ws(*s); |
|
|
|
|
|
|
|
return ( token ) ; |
|
|
|
return (token); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* get the next token starting at next non white spice, stopping |
|
|
|
at p, if inc_p is true, then including p, else excluding p, |
|
|
|
return NULL if p is not found. |
|
|
|
If '}', ']' or ')' and nested is true, find corresponding p |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
char * |
|
|
|
gettok_char(char **s, char p, bool inc_p, bool nested) |
|
|
|
{ |
|
|
|
char c; |
|
|
|
char *beg, *token ; /* return token */ |
|
|
|
char *beg, *token; /* return token */ |
|
|
|
|
|
|
|
*s = skip_ws(*s); |
|
|
|
|
|
|
|
if (!**s) |
|
|
|
return (NULL); /* return NULL if we come to end of line */ |
|
|
|
|
|
|
|
beg = *s ; |
|
|
|
if (nested && (( p == '}' ) || ( p == ')' ) || ( p == ']'))) { |
|
|
|
beg = *s; |
|
|
|
if (nested && ((p == '}') || (p == ')') || (p == ']'))) { |
|
|
|
char q; |
|
|
|
int count = 0; |
|
|
|
/* find opening bracket */ |
|
|
|
if ( p == '}' ) |
|
|
|
if (p == '}') |
|
|
|
q = '{'; |
|
|
|
else if(p == ']' ) |
|
|
|
else if (p == ']') |
|
|
|
q = '['; |
|
|
|
else |
|
|
|
q = '('; |
|
|
|
/* add string in front of q, excluding q */ |
|
|
|
while ((c = **s) != '\0' && ( **s != q )) { |
|
|
|
(*s)++ ; |
|
|
|
while ((c = **s) != '\0' && (**s != q)) { |
|
|
|
(*s)++; |
|
|
|
} |
|
|
|
/* return if nested bracket found, excluding its character */ |
|
|
|
while ((c = **s) != '\0') { |
|
|
|
if (c == q) count++; |
|
|
|
else if (c == p) count--; |
|
|
|
while ((c = **s) != '\0') { |
|
|
|
if (c == q) |
|
|
|
count++; |
|
|
|
else if (c == p) |
|
|
|
count--; |
|
|
|
if (count == 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
(*s)++ ; |
|
|
|
(*s)++; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
/* just look for p and return string, excluding p */ |
|
|
|
while ((c = **s) != '\0' && ( **s != p )) { |
|
|
|
(*s)++ ; |
|
|
|
while ((c = **s) != '\0' && (**s != p)) { |
|
|
|
(*s)++; |
|
|
|
} |
|
|
|
|
|
|
|
if (c == '\0') |
|
|
|
@ -499,48 +529,50 @@ gettok_char(char **s, char p, bool inc_p, bool nested) |
|
|
|
|
|
|
|
if (inc_p) |
|
|
|
/* add p */ |
|
|
|
(*s)++ ; |
|
|
|
(*s)++; |
|
|
|
|
|
|
|
token = copy_substring(beg, *s) ; |
|
|
|
token = copy_substring(beg, *s); |
|
|
|
|
|
|
|
/* Now iterate up to next non-whitespace char */ |
|
|
|
*s = skip_ws(*s); |
|
|
|
|
|
|
|
return ( token ) ; |
|
|
|
return (token); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------* |
|
|
|
* gettok_node was added by SDB on 12.3.2003 |
|
|
|
* It acts like gettok, except that it treats parens and commas like |
|
|
|
* whitespace (i.e. it ignores them). Use it when parsing through netnames |
|
|
|
* (node names) since they may be grouped using ( , ). |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
char * |
|
|
|
gettok_node(char **s) |
|
|
|
{ |
|
|
|
char c; |
|
|
|
char *token ; /* return token */ |
|
|
|
char *token; /* return token */ |
|
|
|
|
|
|
|
if (*s == NULL) |
|
|
|
return NULL; |
|
|
|
|
|
|
|
while (isspace_c(**s) || |
|
|
|
( **s == '(' ) || |
|
|
|
( **s == ')' ) || |
|
|
|
( **s == ',') |
|
|
|
) |
|
|
|
(**s == '(') || |
|
|
|
(**s == ')') || |
|
|
|
(**s == ',') |
|
|
|
) |
|
|
|
(*s)++; /* iterate over whitespace and ( , ) */ |
|
|
|
|
|
|
|
if (!**s) |
|
|
|
return (NULL); /* return NULL if we come to end of line */ |
|
|
|
|
|
|
|
token = *s; |
|
|
|
while ((c = **s) != '\0' && |
|
|
|
!isspace_c(c) && |
|
|
|
( **s != '(' ) && |
|
|
|
( **s != ')' ) && |
|
|
|
( **s != ',') |
|
|
|
) { /* collect chars until whitespace or ( , ) */ |
|
|
|
while ((c = **s) != '\0' && |
|
|
|
!isspace_c(c) && |
|
|
|
(**s != '(') && |
|
|
|
(**s != ')') && |
|
|
|
(**s != ',') |
|
|
|
) { /* collect chars until whitespace or ( , ) */ |
|
|
|
(*s)++; |
|
|
|
} |
|
|
|
|
|
|
|
@ -548,29 +580,32 @@ gettok_node(char **s) |
|
|
|
|
|
|
|
/* Now iterate up to next non-whitespace char */ |
|
|
|
while (isspace_c(**s) || |
|
|
|
( **s == '(' ) || |
|
|
|
( **s == ')' ) || |
|
|
|
( **s == ',') |
|
|
|
) |
|
|
|
(**s == '(') || |
|
|
|
(**s == ')') || |
|
|
|
(**s == ',') |
|
|
|
) |
|
|
|
(*s)++; /* iterate over whitespace and ( , ) */ |
|
|
|
|
|
|
|
return ( token ) ; |
|
|
|
return (token); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------* |
|
|
|
* get_l_paren iterates the pointer forward in a string until it hits |
|
|
|
* the position after the next left paren "(". It returns 0 if it found a left |
|
|
|
* the position after the next left paren "(". It returns 0 if it found a left |
|
|
|
* paren, and 1 if no left paren is found. It is called from 'translate' |
|
|
|
* (subckt.c). |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
int |
|
|
|
get_l_paren(char **s) |
|
|
|
{ |
|
|
|
while (**s && ( **s != '(' ) ) |
|
|
|
while (**s && (**s != '(')) |
|
|
|
(*s)++; |
|
|
|
|
|
|
|
if (!**s) |
|
|
|
return (1); |
|
|
|
|
|
|
|
|
|
|
|
(*s)++; |
|
|
|
|
|
|
|
if (!**s) |
|
|
|
@ -582,15 +617,17 @@ get_l_paren(char **s) |
|
|
|
|
|
|
|
/*-------------------------------------------------------------------------* |
|
|
|
* get_r_paren iterates the pointer forward in a string until it hits |
|
|
|
* the position after the next right paren ")". It returns 0 if it found a right |
|
|
|
* the position after the next right paren ")". It returns 0 if it found a right |
|
|
|
* paren, and 1 if no right paren is found. It is called from 'translate' |
|
|
|
* (subckt.c). |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
int |
|
|
|
get_r_paren(char **s) |
|
|
|
{ |
|
|
|
while (**s && ( **s != ')' ) ) |
|
|
|
while (**s && (**s != ')')) |
|
|
|
(*s)++; |
|
|
|
|
|
|
|
if (!**s) |
|
|
|
return (1); |
|
|
|
|
|
|
|
@ -598,7 +635,7 @@ get_r_paren(char **s) |
|
|
|
|
|
|
|
if (!**s) |
|
|
|
return (1); |
|
|
|
else |
|
|
|
else |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
@ -607,85 +644,93 @@ get_r_paren(char **s) |
|
|
|
* is needed in gettoks (dotcards.c) for right processing of expressions |
|
|
|
* like ".plot v( 5,4) v(6)" |
|
|
|
*-------------------------------------------------------------------------*/ |
|
|
|
|
|
|
|
char * |
|
|
|
stripWhiteSpacesInsideParens(char *str) |
|
|
|
{ |
|
|
|
char *token ; /* return token */ |
|
|
|
SPICE_DSTRING buf ; /* allow any length string */ |
|
|
|
int i = 0 ; /* index into string */ |
|
|
|
char *token; /* return token */ |
|
|
|
SPICE_DSTRING buf; /* allow any length string */ |
|
|
|
int i = 0; /* index into string */ |
|
|
|
|
|
|
|
while ( (str[i] == ' ') || (str[i] == '\t') ) |
|
|
|
while ((str[i] == ' ') || (str[i] == '\t')) |
|
|
|
i++; |
|
|
|
|
|
|
|
spice_dstring_init(&buf) ; |
|
|
|
for(i=i; str[i]!='\0'; i++) |
|
|
|
{ |
|
|
|
if ( str[i] != '(' ) { |
|
|
|
spice_dstring_append_char( &buf, str[i] ) ; |
|
|
|
spice_dstring_init(&buf); |
|
|
|
for (i = i; str[i] != '\0'; 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] ) ; |
|
|
|
spice_dstring_append_char(&buf, str[i]); |
|
|
|
while ((str[i++] != ')')) { |
|
|
|
if (str[i] != ' ') |
|
|
|
spice_dstring_append_char(&buf, str[i]); |
|
|
|
} |
|
|
|
i--; |
|
|
|
} |
|
|
|
} |
|
|
|
token = copy( spice_dstring_value(&buf) ) ; |
|
|
|
spice_dstring_free(&buf) ; |
|
|
|
return ( token ) ; |
|
|
|
|
|
|
|
token = copy(spice_dstring_value(&buf)); |
|
|
|
spice_dstring_free(&buf); |
|
|
|
return (token); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
isquote( char ch ) |
|
|
|
isquote(char ch) |
|
|
|
{ |
|
|
|
return ( ch == '\'' || ch == '"' ); |
|
|
|
return (ch == '\'' || ch == '"'); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
is_arith_char( char c ) |
|
|
|
is_arith_char(char c) |
|
|
|
{ |
|
|
|
if (c != '\0' && strchr("+-*/()<>?:|&^!%\\", c)) |
|
|
|
return TRUE; |
|
|
|
else |
|
|
|
return FALSE; |
|
|
|
if (c != '\0' && strchr("+-*/()<>?:|&^!%\\", c)) |
|
|
|
return TRUE; |
|
|
|
else |
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool |
|
|
|
str_has_arith_char( char *s ) |
|
|
|
str_has_arith_char(char *s) |
|
|
|
{ |
|
|
|
while ( *s && *s != '\0' ) { |
|
|
|
if ( is_arith_char(*s) ) return TRUE; |
|
|
|
s++; |
|
|
|
} |
|
|
|
return FALSE; |
|
|
|
while (*s && *s != '\0') { |
|
|
|
if (is_arith_char(*s)) |
|
|
|
return TRUE; |
|
|
|
s++; |
|
|
|
} |
|
|
|
|
|
|
|
return FALSE; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
get_comma_separated_values( char *values[], char *str ) { |
|
|
|
int count = 0; |
|
|
|
char *ptr, *comma_ptr, keep; |
|
|
|
|
|
|
|
while ( ( comma_ptr = strchr( str, ',' ) ) != NULL ) { |
|
|
|
ptr = comma_ptr - 1; |
|
|
|
while ( isspace_c(*ptr) ) ptr--; |
|
|
|
ptr++; keep = *ptr; *ptr = '\0'; |
|
|
|
get_comma_separated_values(char *values[], char *str) { |
|
|
|
int count = 0; |
|
|
|
char *ptr, *comma_ptr, keep; |
|
|
|
|
|
|
|
while ((comma_ptr = strchr(str, ',')) != NULL) { |
|
|
|
ptr = comma_ptr - 1; |
|
|
|
while (isspace_c(*ptr)) |
|
|
|
ptr--; |
|
|
|
ptr++; keep = *ptr; *ptr = '\0'; |
|
|
|
values[count++] = strdup(str); |
|
|
|
*ptr = keep; |
|
|
|
str = skip_ws(comma_ptr + 1); |
|
|
|
} |
|
|
|
values[count++] = strdup(str); |
|
|
|
*ptr = keep; |
|
|
|
str = skip_ws(comma_ptr + 1); |
|
|
|
} |
|
|
|
values[count++] = strdup(str); |
|
|
|
return count; |
|
|
|
return count; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
check if the given token matches a model name |
|
|
|
either exact |
|
|
|
then return 1 |
|
|
|
either exact |
|
|
|
then return 1 |
|
|
|
or |
|
|
|
modulo a trailing model binning extension '\.[0-9]+' |
|
|
|
then return 2 |
|
|
|
modulo a trailing model binning extension '\.[0-9]+' |
|
|
|
then return 2 |
|
|
|
*/ |
|
|
|
|
|
|
|
int |
|
|
|
|