You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

205 lines
4.4 KiB

/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Thomas L. Quarles
**********/
#include "ngspice.h"
#include <stdio.h>
#include <ctype.h>
#include "inpdefs.h"
#include "inp.h"
double INPevaluate(char **line, int *error, int gobble)
/* non-zero to gobble rest of token, zero to leave it alone */
{
char *token;
char *here;
double mantis;
int expo1;
int expo2;
int sign;
int expsgn;
char *tmpline;
/* setup */
tmpline = *line;
if (gobble) {
*error = INPgetUTok(line, &token, 1);
if (*error)
return ((double) 0.0);
} else {
token = *line;
*error = 0;
}
mantis = 0;
expo1 = 0;
expo2 = 0;
sign = 1;
expsgn = 1;
/* loop through all of the input token */
here = token;
if (*here == '+')
here++; /* plus, so do nothing except skip it */
if (*here == '-') { /* minus, so skip it, and change sign */
here++;
sign = -1;
}
if ((*here == 0) || ((!(isdigit(*here))) && (*here != '.'))) {
/* number looks like just a sign! */
*error = 1;
/* back out the 'gettok' operation */
*line = tmpline;
if (gobble) {
FREE(token);
} else {
*line = here;
}
return (0);
}
while (isdigit(*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);
}
if (*here == ':') {
/* 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++;
}
}
/* 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++;
}
}
/* 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)));
}
}
}
/* not either special case, so just m => 1e-3 */
expo1 = expo1 - 3;
}
break;
default:
break;
}
if (gobble) {
FREE(token);
} else {
*line = here;
}
return (sign * mantis *
pow((double) 10, (double) (expo1 + expsgn * expo2)));
}