Copyright 1990 Regents of the University of California. All rights reserved.
Author: 1988 Thomas L. Quarles
Modified: Paolo Nenzi 2000
Remarks: This code is based on a version written by Serban Popescu which
accepted an optional parameter ac. I have adapted his code
to conform to INP standard. (PN)
**********/
#include "ngspice/ngspice.h"
#include "ngspice/ifsim.h"
#include "ngspice/inpdefs.h"
#include "ngspice/inpmacs.h"
#include "ngspice/fteext.h"
#include "inpxx.h"
#include "ngspice/stringskip.h"
#include "ngspice/compatmode.h"
void INP2R(CKTcircuit *ckt, INPtables * tab, struct card *current)
{
static int mytype = -1;
int type = 0;
char *line;
char *saveline;
char *name;
char *model;
char *nname1;
char *nname2;
CKTnode *node1;
CKTnode *node2;
double val;
int error;
int error1;
INPmodel *thismodel;
GENmodel *mdfast = NULL;
GENinstance *fast = NULL;
IFvalue ptemp;
int waslead;
double leadval;
IFuid uid;
char *s;
#ifdef TRACE
printf("In INP2R, Current line: %s\n", current->line);
#endif
if (mytype < 0) {
if ((mytype = INPtypelook("Resistor")) < 0) {
LITERR("Device type Resistor not supported by this binary\n");
return;
}
}
line = current->line;
INPgetNetTok(&line, &name, 1);
if (*line == '\0') {
fprintf(stderr, "\nWarning: '%s' is not a valid resistor instance line, ignored!\n\n", current->line);
return;
}
INPgetNetTok(&line, &nname1, 1);
if (*line == '\0') {
fprintf(stderr, "\nWarning: '%s' is not a valid resistor instance line, ignored!\n\n", current->line);
return;
}
INPgetNetTok(&line, &nname2, 1);
if (*line == '\0') {
fprintf(stderr, "\nWarning: '%s' is not a valid resistor instance line, ignored!\n\n", current->line);
return;
}
INPinsert(&name, tab);
INPtermInsert(ckt, &nname1, tab, &node1);
INPtermInsert(ckt, &nname2, tab, &node2);
if (newcompat.lt)
val = INPevaluateRKM_R(&line, &error1, 1);
else
val = INPevaluate(&line, &error1, 1);
* follows a number, so must be a model name
* -> MUST be a model name (or null)
*/
#ifdef TRACE
printf("Begining tc=xxx yyyy search and translation in '%s'\n", line);
#endif
This is a re-write of the routine originally proposed by Hitoshi Tanaka.
In my version we simply look for the first occurence of 'tc' followed
by '=' followed by two numbers. If we find it then we splice in "tc2=".
sjb - 2005-05-09 */
for(s = line; NULL != (s = strstr(s, "tc")); ) {
char *p;
size_t left_length;
s = skip_ws(s + 2);
if(*s != '=')
continue;
s = skip_ws(s + 1);
otherwise reject */
if((*s != '+') && (*s != '-') && !isdigit_c(*s))
continue;
s = skip_non_ws(s);
left_length = (size_t) (s - current->line);
s = skip_ws(s);
second number, otherwise reject */
if((*s != '+') && (*s != '-') && !isdigit_c(*s))
continue;
so now we splice in a "tc2=" at the location remembered above. */
p = TMALLOC(char, left_length + 5 + strlen(s) + 1);
by rejecting the translation */
if(!p)
break;
strncpy(p, current->line, left_length);
strcpy(p + left_length, " tc2=");
strcpy(p + left_length + 5, s);
line = p + (line - current->line);
s = p + (s - current->line);
tfree(current->line);
current->line = p;
}
#ifdef TRACE
printf("(Translated) Resistor line: %s\n", current->line);
#endif
saveline = line;
INPgetNetTok(&line, &model, 1);
if (*model && (strcmp(model, "r") != 0)) {
if (INPlookMod(model)) {
#ifdef TRACE
printf("In INP2R, Valid R Model: %s\n", model);
#endif
INPinsert(&model, tab);
current->error = INPgetMod(ckt, model, &thismodel, tab);
if (thismodel != NULL) {
if ((INPtypelook("Resistor") != thismodel->INPmodType)
#ifdef ADMS
&& (INPtypelook("r2_cmc") != thismodel->INPmodType)
#endif
) {
LITERR("incorrect model type for resistor");
return;
}
mdfast = thismodel->INPmodfast;
type = thismodel->INPmodType;
}
} else {
tfree(model);
line = saveline;
type = mytype;
if (!tab->defRmod) {
IFnewUid(ckt, &uid, NULL, "R", UID_MODEL, NULL);
IFC(newModel, (ckt, type, &(tab->defRmod), uid));
}
mdfast = tab->defRmod;
}
IFC(newInstance, (ckt, mdfast, &fast, name));
} else {
tfree(model);
type = mytype;
if (!tab->defRmod) {
IFnewUid(ckt, &uid, NULL, "R", UID_MODEL, NULL);
IFC(newModel, (ckt, type, &(tab->defRmod), uid));
}
IFC(newInstance, (ckt, tab->defRmod, &fast, name));
if (error1 == 1) {
val = INPevaluate(&line, &error1, 1);
#ifdef TRACE
printf ("In INP2R, R=val construction: val=%g\n", val);
#endif
}
}
if (!fast || !fast->GENmodPtr) {
fprintf(stderr, "\nWarning: Instance for resistor '%s' could not be set up properly, ignored!\n\n", current->line);
return;
}
if (error1 == 0) {
ptemp.rValue = val;
GCA(INPpName, ("resistance", &ptemp, ckt, type, fast));
}
IFC(bindNode, (ckt, fast, 1, node1));
IFC(bindNode, (ckt, fast, 2, node2));
PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab));
if (waslead) {
ptemp.rValue = leadval;
GCA(INPpName, ("resistance", &ptemp, ckt, type, fast));
}
return;
}