diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 7b9612932..b720e5a4a 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -2458,6 +2458,12 @@ static int is_a_modelname(char *s, const char* line) if (*evalrc == '\0' && !error) return FALSE; } + if (newcompat.lt && *line == 'l') { + evalrc = s; + INPevaluateRKM_L(&evalrc, &error, 0); + if (*evalrc == '\0' && !error) + return FALSE; + } /* first character of model name is character from alphabet */ if (isalpha_c(s[0])) return TRUE; diff --git a/src/include/ngspice/inpdefs.h b/src/include/ngspice/inpdefs.h index 94eb5ae19..49488ea88 100644 --- a/src/include/ngspice/inpdefs.h +++ b/src/include/ngspice/inpdefs.h @@ -118,6 +118,7 @@ char *INPerror(int); double INPevaluate(char **, int *, int); double INPevaluateRKM_R(char **, int *, int); double INPevaluateRKM_C(char **, int *, int); +double INPevaluateRKM_L(char **, int *, int); char *INPfindLev(char *, int *); char *INPgetMod(CKTcircuit *, char *, INPmodel **, INPtables *); char *INPgetModBin(CKTcircuit *, char *, INPmodel **, INPtables *, char *); diff --git a/src/spicelib/parser/inp2l.c b/src/spicelib/parser/inp2l.c index 3af47c8ff..da66650f0 100644 --- a/src/spicelib/parser/inp2l.c +++ b/src/spicelib/parser/inp2l.c @@ -8,6 +8,7 @@ Author: 1988 Thomas L. Quarles #include "ngspice/inpdefs.h" #include "ngspice/inpmacs.h" #include "ngspice/fteext.h" +#include "ngspice/compatmode.h" #include "inpxx.h" void INP2L(CKTcircuit *ckt, INPtables * tab, struct card *current) @@ -54,8 +55,14 @@ void INP2L(CKTcircuit *ckt, INPtables * tab, struct card *current) INPtermInsert(ckt, &nname1, tab, &node1); INPgetNetTok(&line, &nname2, 1); INPtermInsert(ckt, &nname2, tab, &node2); - val = INPevaluate(&line, &error1, 1); - + +// val = INPevaluate(&line, &error1, 1); + + /* enable reading values like 4u7 */ + if (newcompat.lt) + val = INPevaluateRKM_L(&line, &error1, 1); /* [] */ + else + val = INPevaluate(&line, &error1, 1); /* [] */ saveline = line; INPgetNetTok(&line, &model, 1); diff --git a/src/spicelib/parser/inpeval.c b/src/spicelib/parser/inpeval.c index 32236d39b..dd48e1431 100644 --- a/src/spicelib/parser/inpeval.c +++ b/src/spicelib/parser/inpeval.c @@ -661,3 +661,237 @@ INPevaluateRKM_C(char** line, int* error, int gobble) pow(10.0, (double)(expo1 + expsgn * expo2))); } +/* In addition to fcn INPevaluate() above, allow values like 4k7, + similar to the RKM code (used by inp2r) */ +double +INPevaluateRKM_L(char** line, int* error, int gobble) +/* gobble: non-zero to gobble rest of token, zero to leave it alone */ +{ + char* token; + char* here; + double mantis; + double deci; + int expo1; + int expo2; + int expo3; + int sign; + int expsgn; + char* tmpline; + bool hasmulti = FALSE; + + /* 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 (0.0); + } + else { + token = *line; + *error = 0; + } + + mantis = 0; + deci = 0; + expo1 = 0; + expo2 = 0; + expo3 = 0; + sign = 1; + expsgn = 1; + + /* loop through all of the input token */ + here = token; + + if (*here == '+') + here++; /* plus, so do nothing except skip it */ + else if (*here == '-') { /* minus, so skip it, and change sign */ + here++; + sign = -1; + } + + if ((*here == '\0') || ((!(isdigit_c(*here))) && (*here != '.') && (*here != 'r'))) { + /* number looks like just a sign! */ + *error = 1; + if (gobble) { + FREE(token); + /* back out the 'gettok' operation */ + *line = tmpline; + } + return (0); + } + + while (isdigit_c(*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 == ':') { + /* ':' is no longer used for subcircuit node numbering + but is part of ternary function a?b:c + FIXME : subcircuit models still use ':' for model numbering + Will this hurt somewhere? */ + if (gobble) { + FREE(token); + } + else { + *line = here; + } + return ((double)mantis * sign); + } + + /* 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_c(*here)) { + /* digit, so accumulate it. */ + mantis = 10 * mantis + *here - '0'; + expo1 = expo1 - 1; + 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 + */ + else if (*here == '-') { + here++; /* skip over minus sign */ + expsgn = -1; /* and make a negative exponent */ + /* now look for the digits of the exponent */ + } + + while (isdigit_c(*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; + hasmulti = TRUE; + break; + case 'g': + case 'G': + expo1 = expo1 + 9; + hasmulti = TRUE; + break; + case 'k': + case 'K': + expo1 = expo1 + 3; + hasmulti = TRUE; + break; + case 'u': + case 'U': + expo1 = expo1 - 6; + hasmulti = TRUE; + break; + case 'r': + case 'R': + + expo1 = expo1; + hasmulti = TRUE; + break; + case 'n': + case 'N': + expo1 = expo1 - 9; + hasmulti = TRUE; + break; + case 'p': + case 'P': + expo1 = expo1 - 12; + hasmulti = TRUE; + break; + case 'f': + case 'F': + expo1 = expo1 - 15; + hasmulti = TRUE; + break; + case 'm': + case 'M': + if (((here[1] == 'E') || (here[1] == 'e')) && + ((here[2] == 'G') || (here[2] == 'g'))) + { + expo1 = expo1 + 6; /* Meg */ + here += 2; + hasmulti = TRUE; + } + else if (((here[1] == 'I') || (here[1] == 'i')) && + ((here[2] == 'L') || (here[2] == 'l'))) + { + expo1 = expo1 - 6; + mantis *= 25.4; /* Mil */ + } + else { + expo1 = expo1 - 3; /* Meg as well */ + hasmulti = TRUE; + } + break; + case 'l': + case 'L': + expo1 = expo1 - 3; /* m, milli */ + hasmulti = TRUE; + break; + default: + break; + } + + /* read a digit after multiplier */ + if (hasmulti) { + here++; + while (isdigit_c(*here)) { + deci = 10 * deci + *here - '0'; + expo3 = expo3 - 1; + here++; + } + mantis = mantis + deci * pow(10.0, (double)expo3); + } + + if (gobble) { + FREE(token); + } + else { + *line = here; + } + + return (sign * mantis * + pow(10.0, (double)(expo1 + expsgn * expo2))); +} +