1 /**********
2 Copyright 1990 Regents of the University of California.  All rights reserved.
3 Author: 1988 Thomas L. Quarles
4 **********/
5 
6 #include "ngspice/ngspice.h"
7 #include "ngspice/ifsim.h"
8 #include "ngspice/inpdefs.h"
9 #include "ngspice/inpmacs.h"
10 #include "ngspice/fteext.h"
11 #include "ngspice/compatmode.h"
12 #include "inpxx.h"
13 
INP2C(CKTcircuit * ckt,INPtables * tab,struct card * current)14 void INP2C(CKTcircuit *ckt, INPtables * tab, struct card *current)
15 {
16 
17 /* parse a capacitor card */
18 /* Cname <node> <node> [<val>] [<mname>] [IC=<val>] */
19 
20     static int mytype = -1; /* the type we determine capacitors are */
21     int type = 0;        /* the type the model says it is */
22     char *line;          /* the part of the current line left to parse */
23     char *saveline;      /* ... just in case we need to go back... */
24     char *name;          /* the resistor's name */
25     char *model;         /* the name of the capacitor's model */
26     char *nname1;        /* the first node's name */
27     char *nname2;        /* the second node's name */
28     CKTnode *node1;      /* the first node's node pointer */
29     CKTnode *node2;      /* the second node's node pointer */
30     double val;          /* temp to held resistance */
31     int error;           /* error code temporary */
32     int error1;          /* secondary error code temporary */
33     INPmodel *thismodel; /* pointer to model structure describing our model */
34     GENmodel *mdfast = NULL; /* pointer to the actual model */
35     GENinstance *fast;   /* pointer to the actual instance */
36     IFvalue ptemp;       /* a value structure to package resistance into */
37     int waslead;         /* flag to indicate that funny unlabeled number was found */
38     double leadval;      /* actual value of unlabeled number */
39     IFuid uid;           /* uid for default cap model */
40 
41 #ifdef TRACE
42     printf("In INP2C, Current line: %s\n", current->line);
43 #endif
44 
45     if (mytype < 0) {
46         if ((mytype = INPtypelook("Capacitor")) < 0) {
47             LITERR("Device type Capacitor not supported by this binary\n");
48             return;
49         }
50     }
51     line = current->line;
52     INPgetNetTok(&line, &name, 1);
53     INPinsert(&name, tab);
54     INPgetNetTok(&line, &nname1, 1);
55     INPtermInsert(ckt, &nname1, tab, &node1);
56     INPgetNetTok(&line, &nname2, 1);
57     INPtermInsert(ckt, &nname2, tab, &node2);
58 
59     /* enable reading values like 4u7 */
60     if (newcompat.lt)
61         val = INPevaluateRKM(&line, &error1, 1);	/* [<val>] */
62     else
63         val = INPevaluate(&line, &error1, 1);	/* [<val>] */
64 
65     saveline = line;
66 
67     INPgetNetTok(&line, &model, 1);
68 
69     if (*model && (strcmp(model, "c") != 0)) {
70     /* token isn't null */
71       if (INPlookMod(model)) {
72           /* If this is a valid model connect it */
73           INPinsert(&model, tab);
74           current->error = INPgetMod(ckt, model, &thismodel, tab);
75           if (thismodel != NULL) {
76           if (mytype != thismodel->INPmodType) {
77               LITERR("incorrect model type");
78               return;
79           }
80           mdfast = thismodel->INPmodfast;
81           type = thismodel->INPmodType;
82           }
83       } else {
84           tfree(model);
85           /* It is not a model */
86           line = saveline;    /* go back */
87           type = mytype;
88           if (!tab->defCmod) {    /* create default C model */
89           IFnewUid(ckt, &uid, NULL, "C", UID_MODEL, NULL);
90           IFC(newModel, (ckt, type, &(tab->defCmod), uid));
91           }
92           mdfast = tab->defCmod;
93       }
94       IFC(newInstance, (ckt, mdfast, &fast, name));
95     } else {
96       tfree(model);
97       /* The token is null and a default model will be created */
98       type = mytype;
99       if (!tab->defCmod) {
100           /* create default C model */
101           IFnewUid(ckt, &uid, NULL, "C", UID_MODEL, NULL);
102           IFC(newModel, (ckt, type, &(tab->defCmod), uid));
103       }
104       IFC(newInstance, (ckt, tab->defCmod, &fast, name));
105       if (error1 == 1) {		/* was a c=val construction */
106         val = INPevaluate(&line, &error1, 1);	/* [<val>] */
107 #ifdef TRACE
108         printf ("In INP2C, C=val construction: val=%g\n", val);
109 #endif
110       }
111     }
112 
113     if (error1 == 0) {        /* Looks like a number */
114       ptemp.rValue = val;
115       GCA(INPpName, ("capacitance", &ptemp, ckt, type, fast));
116     }
117 
118     IFC(bindNode, (ckt, fast, 1, node1));
119     IFC(bindNode, (ckt, fast, 2, node2));
120     PARSECALL((&line, ckt, type, fast, &leadval, &waslead, tab));
121     if (waslead) {
122       ptemp.rValue = leadval;
123       GCA(INPpName, ("capacitance", &ptemp, ckt, type, fast));
124     }
125 
126     return;
127 }
128