ngspice/src/frontend/parser/numparse.c

168 lines
4.4 KiB
C
Raw Normal View History

2000-04-27 22:03:57 +02:00
/**********
Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
**********/
/* This routine parses a number. */
2000-04-27 22:03:57 +02:00
#include <config.h>
#include <ngspice.h>
#include <bool.h>
2000-04-27 22:03:57 +02:00
#include "ftedefs.h"
#include "numparse.h"
static double
* TODO, doc/ngspice.texi: Small updates * configure.in: New --enable-smoketest. * src/main.c src/ngspice.c src/frontend/outitf.c src/frontend/runcoms.c src/frontend/spiceif.c src/frontend/parser/numparse.c src/include/cktdefs.h src/include/fteext.h src/include/inpdefs.h src/include/jobdefs.h src/include/ngspice.h src/include/tskdefs.h src/spicelib/analysis/Makefile.am src/spicelib/analysis/acsetp.c src/spicelib/analysis/cktaskaq.c src/spicelib/analysis/cktdojob.c src/spicelib/analysis/cktnewan.c src/spicelib/analysis/cktsetap.c src/spicelib/analysis/cktsopt.c src/spicelib/analysis/ckttroub.c src/spicelib/analysis/dcosetp.c src/spicelib/analysis/dctsetp.c src/spicelib/analysis/dsetparm.c src/spicelib/analysis/nsetparm.c src/spicelib/analysis/pzsetp.c src/spicelib/analysis/senssetp.c src/spicelib/analysis/tfsetp.c src/spicelib/analysis/transetp.c src/spicelib/devices/bjt/bjtdset.h src/spicelib/devices/bjt/bjtext.h src/spicelib/devices/bjt/bjtsetup.c src/spicelib/devices/bsim2/b2set.c src/spicelib/devices/bsim3/b3acld.c src/spicelib/devices/bsim3/b3set.c src/spicelib/devices/bsim3/bsim3def.h src/spicelib/devices/csw/cswtrunc.c src/spicelib/devices/dio/diodset.c src/spicelib/devices/dio/dioinit.c src/spicelib/devices/jfet/jfetset.c src/spicelib/devices/mes/messetup.c src/spicelib/devices/mos1/mos1ask.c src/spicelib/devices/mos1/mos1set.c src/spicelib/devices/mos1/mos1temp.c src/spicelib/devices/mos3/mos3load.c src/spicelib/devices/mos6/mos6set.c src/spicelib/devices/sw/swtrunc.c src/spicelib/parser/inppas2.c src/spicelib/parser/inppas3.c src/spicelib/parser/inppas3.h: Paolo and I have integrated patches from Alan Gillespie <Alan.Gillespie@analog.com>.
2000-09-05 21:48:22 +02:00
power10(double num) /* Chris Inbody */
2000-04-27 22:03:57 +02:00
{
double d = 1.0;
while (num-- > 0)
d *= 10.0;
return (d);
}
bool ft_strictnumparse = FALSE;
/* Parse a number. This will handle things like 10M, etc... If the number
* must not end before the end of the string, then whole is TRUE.
* If whole is FALSE and there is more left to the number, the argument
* is advanced to the end of the word. Returns NULL
* if no number can be found or if there are trailing characters when
* whole is TRUE.
*
2000-04-27 22:03:57 +02:00
* If ft_strictnumparse is TRUE, and whole is FALSE, the first of the
* trailing characters must be a '_'. */
2000-04-27 22:03:57 +02:00
double *
ft_numparse(char **s, bool whole)
{
double mant = 0.0;
int sign = 1, exsign = 1, p;
double expo = 0.0;
static double num;
char *string = *s;
/* See if the number begins with + or -. */
if (*string == '+')
string++;
else if (*string == '-') {
string++;
sign = -1;
}
/* We don't want to recognise "P" as 0P, or .P as 0.0P... */
if ((!isdigit(*string) && *string != '.') ||
((*string == '.') && !isdigit(string[1])))
return (NULL);
/* Now accumulate a number. Note ascii dependencies here... */
while (isdigit(*string))
mant = mant * 10.0 + (*string++ - '0');
/* Now maybe a decimal point. */
if (*string == '.') {
string++;
p = 1;
while (isdigit(*string))
* TODO, doc/ngspice.texi: Small updates * configure.in: New --enable-smoketest. * src/main.c src/ngspice.c src/frontend/outitf.c src/frontend/runcoms.c src/frontend/spiceif.c src/frontend/parser/numparse.c src/include/cktdefs.h src/include/fteext.h src/include/inpdefs.h src/include/jobdefs.h src/include/ngspice.h src/include/tskdefs.h src/spicelib/analysis/Makefile.am src/spicelib/analysis/acsetp.c src/spicelib/analysis/cktaskaq.c src/spicelib/analysis/cktdojob.c src/spicelib/analysis/cktnewan.c src/spicelib/analysis/cktsetap.c src/spicelib/analysis/cktsopt.c src/spicelib/analysis/ckttroub.c src/spicelib/analysis/dcosetp.c src/spicelib/analysis/dctsetp.c src/spicelib/analysis/dsetparm.c src/spicelib/analysis/nsetparm.c src/spicelib/analysis/pzsetp.c src/spicelib/analysis/senssetp.c src/spicelib/analysis/tfsetp.c src/spicelib/analysis/transetp.c src/spicelib/devices/bjt/bjtdset.h src/spicelib/devices/bjt/bjtext.h src/spicelib/devices/bjt/bjtsetup.c src/spicelib/devices/bsim2/b2set.c src/spicelib/devices/bsim3/b3acld.c src/spicelib/devices/bsim3/b3set.c src/spicelib/devices/bsim3/bsim3def.h src/spicelib/devices/csw/cswtrunc.c src/spicelib/devices/dio/diodset.c src/spicelib/devices/dio/dioinit.c src/spicelib/devices/jfet/jfetset.c src/spicelib/devices/mes/messetup.c src/spicelib/devices/mos1/mos1ask.c src/spicelib/devices/mos1/mos1set.c src/spicelib/devices/mos1/mos1temp.c src/spicelib/devices/mos3/mos3load.c src/spicelib/devices/mos6/mos6set.c src/spicelib/devices/sw/swtrunc.c src/spicelib/parser/inppas2.c src/spicelib/parser/inppas3.c src/spicelib/parser/inppas3.h: Paolo and I have integrated patches from Alan Gillespie <Alan.Gillespie@analog.com>.
2000-09-05 21:48:22 +02:00
mant += (*string++ - '0') / power10(p++);
2000-04-27 22:03:57 +02:00
}
/* Now look for the scale factor or the exponent (can't have both). */
switch (*string) {
case 'e':
case 'E':
/* Parse another number. */
string++;
if (*string == '+') {
exsign = 1;
string++;
} else if (*string == '-') {
exsign = -1;
string++;
}
while(isdigit(*string))
expo = expo * 10.0 + (*string++ - '0');
if (*string == '.') {
string++;
p = 1;
while (isdigit(*string))
* TODO, doc/ngspice.texi: Small updates * configure.in: New --enable-smoketest. * src/main.c src/ngspice.c src/frontend/outitf.c src/frontend/runcoms.c src/frontend/spiceif.c src/frontend/parser/numparse.c src/include/cktdefs.h src/include/fteext.h src/include/inpdefs.h src/include/jobdefs.h src/include/ngspice.h src/include/tskdefs.h src/spicelib/analysis/Makefile.am src/spicelib/analysis/acsetp.c src/spicelib/analysis/cktaskaq.c src/spicelib/analysis/cktdojob.c src/spicelib/analysis/cktnewan.c src/spicelib/analysis/cktsetap.c src/spicelib/analysis/cktsopt.c src/spicelib/analysis/ckttroub.c src/spicelib/analysis/dcosetp.c src/spicelib/analysis/dctsetp.c src/spicelib/analysis/dsetparm.c src/spicelib/analysis/nsetparm.c src/spicelib/analysis/pzsetp.c src/spicelib/analysis/senssetp.c src/spicelib/analysis/tfsetp.c src/spicelib/analysis/transetp.c src/spicelib/devices/bjt/bjtdset.h src/spicelib/devices/bjt/bjtext.h src/spicelib/devices/bjt/bjtsetup.c src/spicelib/devices/bsim2/b2set.c src/spicelib/devices/bsim3/b3acld.c src/spicelib/devices/bsim3/b3set.c src/spicelib/devices/bsim3/bsim3def.h src/spicelib/devices/csw/cswtrunc.c src/spicelib/devices/dio/diodset.c src/spicelib/devices/dio/dioinit.c src/spicelib/devices/jfet/jfetset.c src/spicelib/devices/mes/messetup.c src/spicelib/devices/mos1/mos1ask.c src/spicelib/devices/mos1/mos1set.c src/spicelib/devices/mos1/mos1temp.c src/spicelib/devices/mos3/mos3load.c src/spicelib/devices/mos6/mos6set.c src/spicelib/devices/sw/swtrunc.c src/spicelib/parser/inppas2.c src/spicelib/parser/inppas3.c src/spicelib/parser/inppas3.h: Paolo and I have integrated patches from Alan Gillespie <Alan.Gillespie@analog.com>.
2000-09-05 21:48:22 +02:00
expo += (*string++ - '0') / power10(p++);
2000-04-27 22:03:57 +02:00
}
expo *= exsign;
break;
case 't':
case 'T':
expo = 12.0;
string++;
break;
case 'g':
case 'G':
expo = 9.0;
string++;
break;
case 'k':
case 'K':
expo = 3.0;
string++;
break;
case 'u':
case 'U':
expo = -6.0;
string++;
break;
case 'n':
case 'N':
expo = -9.0;
string++;
break;
case 'p':
case 'P':
expo = -12.0;
string++;
break;
case 'f':
case 'F':
expo = -15.0;
string++;
break;
case 'm':
case 'M':
/* Can be either m, mil, or meg. */
if (string[1] && string[2] &&
((string[1] == 'e') || (string[1] == 'E')) &&
((string[2] == 'g') || (string[2] == 'G'))) {
expo = 6.0;
string += 3;
} else if (string[1] && string[2] &&
((string[1] == 'i') || (string[1] == 'I')) &&
((string[2] == 'l') || (string[2] == 'L'))) {
expo = -6.0;
mant *= 25.4;
string += 3;
} else {
expo = -3.0;
string++;
}
break;
}
if (whole && *string != '\0') {
return (NULL);
} else if (ft_strictnumparse && *string && isdigit(string[-1])) {
if (*string == '_')
while (isalpha(*string) || (*string == '_'))
string++;
else
return (NULL);
} else {
while (isalpha(*string) || (*string == '_'))
string++;
}
*s = string;
num = sign * mant * pow(10.0, expo);
if (ft_parsedb)
fprintf(cp_err, "numparse: got %e, left = %s\n", num, *s);
return (&num);
}