|
|
|
@ -23,15 +23,19 @@ double INPevaluate(char **line, int *error, int gobble) |
|
|
|
|
|
|
|
/* setup */ |
|
|
|
tmpline = *line; |
|
|
|
if (gobble) { |
|
|
|
/* MW. INPgetUTok should be called with gobble=0 or it make |
|
|
|
* errors in v(1,2) exp */ |
|
|
|
*error = INPgetUTok(line, &token, 0); |
|
|
|
if (*error) |
|
|
|
return ((double) 0.0); |
|
|
|
if (gobble == 1) { |
|
|
|
/* MW. INPgetUTok should be called with gobble=0 or it make |
|
|
|
* errors in v(1,2) exp */ |
|
|
|
*error = INPgetUTok(line, &token, 0); |
|
|
|
if (*error) |
|
|
|
return ((double) 0.0); |
|
|
|
} else if (gobble == 2) { |
|
|
|
*error = INPgetU2Tok(line, &token, 0); |
|
|
|
if (*error) |
|
|
|
return ((double) 0.0); |
|
|
|
} else { |
|
|
|
token = *line; |
|
|
|
*error = 0; |
|
|
|
token = *line; |
|
|
|
*error = 0; |
|
|
|
} |
|
|
|
mantis = 0; |
|
|
|
expo1 = 0; |
|
|
|
@ -41,167 +45,167 @@ double INPevaluate(char **line, int *error, int gobble) |
|
|
|
/* loop through all of the input token */ |
|
|
|
here = token; |
|
|
|
if (*here == '+') |
|
|
|
here++; /* plus, so do nothing except skip it */ |
|
|
|
here++; /* plus, so do nothing except skip it */ |
|
|
|
if (*here == '-') { /* minus, so skip it, and change sign */ |
|
|
|
here++; |
|
|
|
sign = -1; |
|
|
|
here++; |
|
|
|
sign = -1; |
|
|
|
} |
|
|
|
if ((*here == 0) || ((!(isdigit(*here))) && (*here != '.'))) { |
|
|
|
/* number looks like just a sign! */ |
|
|
|
*error = 1; |
|
|
|
*error = 1; |
|
|
|
/* back out the 'gettok' operation */ |
|
|
|
*line = tmpline; |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return (0); |
|
|
|
*line = tmpline; |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return (0); |
|
|
|
} |
|
|
|
while (isdigit(*here)) { |
|
|
|
/* digit, so accumulate it. */ |
|
|
|
mantis = 10 * mantis + *here - '0'; |
|
|
|
here++; |
|
|
|
/* digit, so accumulate it. */ |
|
|
|
mantis = 10 * mantis + *here - '0'; |
|
|
|
here++; |
|
|
|
} |
|
|
|
if (*here == 0) { |
|
|
|
/* reached the end of token - done. */ |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return ((double) mantis * sign); |
|
|
|
/* reached the end of token - done. */ |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return ((double) mantis * sign); |
|
|
|
} |
|
|
|
if (*here == ':') { |
|
|
|
/* hack for subcircuit node numbering */ |
|
|
|
*error = 1; |
|
|
|
*line = tmpline; |
|
|
|
return 0.0; |
|
|
|
/* hack for subcircuit node numbering */ |
|
|
|
*error = 1; |
|
|
|
*line = tmpline; |
|
|
|
return 0.0; |
|
|
|
} |
|
|
|
/* after decimal point! */ |
|
|
|
if (*here == '.') { |
|
|
|
/* found a decimal point! */ |
|
|
|
here++; /* skip to next character */ |
|
|
|
if (*here == 0) { |
|
|
|
/* number ends in the decimal point */ |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return ((double) mantis * sign); |
|
|
|
} |
|
|
|
while (isdigit(*here)) { |
|
|
|
/* digit, so accumulate it. */ |
|
|
|
mantis = 10 * mantis + *here - '0'; |
|
|
|
expo1 = expo1 - 1; |
|
|
|
if (*here == 0) { |
|
|
|
/* reached the end of token - done. */ |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return (mantis * sign * pow(10., (double) expo1)); |
|
|
|
} |
|
|
|
here++; |
|
|
|
} |
|
|
|
/* found a decimal point! */ |
|
|
|
here++; /* skip to next character */ |
|
|
|
if (*here == 0) { |
|
|
|
/* number ends in the decimal point */ |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return ((double) mantis * sign); |
|
|
|
} |
|
|
|
while (isdigit(*here)) { |
|
|
|
/* digit, so accumulate it. */ |
|
|
|
mantis = 10 * mantis + *here - '0'; |
|
|
|
expo1 = expo1 - 1; |
|
|
|
if (*here == 0) { |
|
|
|
/* reached the end of token - done. */ |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return (mantis * sign * pow(10., (double) expo1)); |
|
|
|
} |
|
|
|
here++; |
|
|
|
} |
|
|
|
} |
|
|
|
/* now look for "E","e",etc to indicate an exponent */ |
|
|
|
if ((*here == 'E') || (*here == 'e') || (*here == 'D') |
|
|
|
|| (*here == 'd')) { |
|
|
|
/* have an exponent, so skip the e */ |
|
|
|
here++; |
|
|
|
/* now look for exponent sign */ |
|
|
|
if (*here == '+') |
|
|
|
here++; /* just skip + */ |
|
|
|
if (*here == '-') { |
|
|
|
here++; /* skip over minus sign */ |
|
|
|
expsgn = -1; /* and make a negative exponent */ |
|
|
|
/* now look for the digits of the exponent */ |
|
|
|
} |
|
|
|
while (isdigit(*here)) { |
|
|
|
expo2 = 10 * expo2 + *here - '0'; |
|
|
|
here++; |
|
|
|
} |
|
|
|
|| (*here == 'd')) { |
|
|
|
/* have an exponent, so skip the e */ |
|
|
|
here++; |
|
|
|
/* now look for exponent sign */ |
|
|
|
if (*here == '+') |
|
|
|
here++; /* just skip + */ |
|
|
|
if (*here == '-') { |
|
|
|
here++; /* skip over minus sign */ |
|
|
|
expsgn = -1; /* and make a negative exponent */ |
|
|
|
/* now look for the digits of the exponent */ |
|
|
|
} |
|
|
|
while (isdigit(*here)) { |
|
|
|
expo2 = 10 * expo2 + *here - '0'; |
|
|
|
here++; |
|
|
|
} |
|
|
|
} |
|
|
|
/* now we have all of the numeric part of the number, time to |
|
|
|
* look for the scale factor (alphabetic) |
|
|
|
*/ |
|
|
|
switch (*here) { |
|
|
|
case 't': |
|
|
|
case 'T': |
|
|
|
expo1 = expo1 + 12; |
|
|
|
break; |
|
|
|
case 'g': |
|
|
|
case 'G': |
|
|
|
expo1 = expo1 + 9; |
|
|
|
break; |
|
|
|
case 'k': |
|
|
|
case 'K': |
|
|
|
expo1 = expo1 + 3; |
|
|
|
break; |
|
|
|
case 'u': |
|
|
|
case 'U': |
|
|
|
expo1 = expo1 - 6; |
|
|
|
break; |
|
|
|
case 'n': |
|
|
|
case 'N': |
|
|
|
expo1 = expo1 - 9; |
|
|
|
break; |
|
|
|
case 'p': |
|
|
|
case 'P': |
|
|
|
expo1 = expo1 - 12; |
|
|
|
break; |
|
|
|
case 'f': |
|
|
|
case 'F': |
|
|
|
expo1 = expo1 - 15; |
|
|
|
break; |
|
|
|
case 'm': |
|
|
|
case 'M': |
|
|
|
{ |
|
|
|
/* special case for m - may be m or mil or meg */ |
|
|
|
if (*(here + 1) != 0 && *(here + 2) != 0) { |
|
|
|
/* at least 2 characters, so check them. */ |
|
|
|
if ((*(here + 1) == 'E') || (*(here + 1) == 'e')) { |
|
|
|
if ((*(here + 2) == 'G') || (*(here + 2) == 'g')) { |
|
|
|
expo1 = expo1 + 6; |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return (sign * mantis * |
|
|
|
pow((double) 10, |
|
|
|
(double) (expo1 + expsgn * expo2))); |
|
|
|
} |
|
|
|
} else if ((*(here + 1) == 'I') || (*(here + 1) == 'i')) { |
|
|
|
if ((*(here + 2) == 'L') || (*(here + 2) == 'l')) { |
|
|
|
expo1 = expo1 - 6; |
|
|
|
mantis = mantis * 25.4; |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return (sign * mantis * |
|
|
|
pow((double) 10, |
|
|
|
(double) (expo1 + expsgn * expo2))); |
|
|
|
} |
|
|
|
} |
|
|
|
case 't': |
|
|
|
case 'T': |
|
|
|
expo1 = expo1 + 12; |
|
|
|
break; |
|
|
|
case 'g': |
|
|
|
case 'G': |
|
|
|
expo1 = expo1 + 9; |
|
|
|
break; |
|
|
|
case 'k': |
|
|
|
case 'K': |
|
|
|
expo1 = expo1 + 3; |
|
|
|
break; |
|
|
|
case 'u': |
|
|
|
case 'U': |
|
|
|
expo1 = expo1 - 6; |
|
|
|
break; |
|
|
|
case 'n': |
|
|
|
case 'N': |
|
|
|
expo1 = expo1 - 9; |
|
|
|
break; |
|
|
|
case 'p': |
|
|
|
case 'P': |
|
|
|
expo1 = expo1 - 12; |
|
|
|
break; |
|
|
|
case 'f': |
|
|
|
case 'F': |
|
|
|
expo1 = expo1 - 15; |
|
|
|
break; |
|
|
|
case 'm': |
|
|
|
case 'M': |
|
|
|
{ |
|
|
|
/* special case for m - may be m or mil or meg */ |
|
|
|
if (*(here + 1) != 0 && *(here + 2) != 0) { |
|
|
|
/* at least 2 characters, so check them. */ |
|
|
|
if ((*(here + 1) == 'E') || (*(here + 1) == 'e')) { |
|
|
|
if ((*(here + 2) == 'G') || (*(here + 2) == 'g')) { |
|
|
|
expo1 = expo1 + 6; |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return (sign * mantis * |
|
|
|
pow((double) 10, |
|
|
|
(double) (expo1 + expsgn * expo2))); |
|
|
|
} |
|
|
|
} else if ((*(here + 1) == 'I') || (*(here + 1) == 'i')) { |
|
|
|
if ((*(here + 2) == 'L') || (*(here + 2) == 'l')) { |
|
|
|
expo1 = expo1 - 6; |
|
|
|
mantis = mantis * 25.4; |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return (sign * mantis * |
|
|
|
pow((double) 10, |
|
|
|
(double) (expo1 + expsgn * expo2))); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
/* not either special case, so just m => 1e-3 */ |
|
|
|
expo1 = expo1 - 3; |
|
|
|
} |
|
|
|
/* not either special case, so just m => 1e-3 */ |
|
|
|
expo1 = expo1 - 3; |
|
|
|
} |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
if (gobble) { |
|
|
|
FREE(token); |
|
|
|
FREE(token); |
|
|
|
} else { |
|
|
|
*line = here; |
|
|
|
*line = here; |
|
|
|
} |
|
|
|
return (sign * mantis * |
|
|
|
pow((double) 10, (double) (expo1 + expsgn * expo2))); |
|
|
|
pow((double) 10, (double) (expo1 + expsgn * expo2))); |
|
|
|
} |