Browse Source

* TODO src/circuit/inp2dot.c: Refactoring of the function


			
			
				pre-master-46
			
			
		
arno 26 years ago
parent
commit
e563776de8
  1. 19
      TODO
  2. 274
      src/circuit/inp2dot.c

19
TODO

@ -47,12 +47,9 @@ Move src/devices/disto into src/maths/partialderiv. Partial
derivatives are math functions and should be classified under that
directory.
Refactor src/circuit/inp2dot.c so that the parser calls subroutines
for each possible dotcard. [PARTIAL]
Testability
===========
-----------
Add tests for all functions in the complex library in
src/maths/cmaths.
@ -64,3 +61,17 @@ Add tests for all functions in the polynomial library in
src/maths/poly.
Add more circuit tests into the tests directory.
Documentation
-------------
Update ARCHITECTURE to contain a high level overview of spice.
Convert ngspice.texi further to texinfo format.
Distribute devices documentation into the devices tree. This makes it
easier for developers to update documentation in concert with code.
Update manual pages for spice and nutmeg. Perhaps generate them with
c2man or some other documentation generation utility.

274
src/circuit/inp2dot.c

@ -413,69 +413,20 @@ dot_dc(char *line, void *ckt, INPtables *tab, card *current,
}
/* FIXME: INP2dot(): factor out all analysises. */
int
INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
static int
dot_tf(char *line, void *ckt, INPtables *tab, card *current,
void *task, void *gnode, void *foo)
{
/* .<something> Many possibilities */
char *name; /* the resistor's name */
char *nname1; /* the first node's name */
char *nname2; /* the second node's name */
void *node1; /* the first node's node pointer */
void *node2; /* the second node's node pointer */
int error; /* error code temporary */
IFvalue ptemp; /* a value structure to package resistance into */
IFvalue *parm; /* a pointer to a value struct for function returns */
char *token; /* a token from the line */
int which; /* which analysis we are performing */
int i; /* generic loop variable */
void *foo; /* pointer to analysis */
char *steptype; /* ac analysis, type of stepping function */
double dtemp; /* random double precision temporary */
char *word; /* something to stick a word of input into */
/* the part of the current line left to parse */
char *line = current->line;
char *nname1; /* the first node's name */
char *nname2; /* the second node's name */
void *node1; /* the first node's node pointer */
void *node2; /* the second node's node pointer */
INPgetTok(&line, &token, 1);
if (strcmp(token, ".model") == 0) {
/* don't have to do anything, since models were all done in
* pass 1 */
return (0);
} else if ((strcmp(token, ".width") == 0) ||
strcmp(token, ".print") == 0 || strcmp(token, ".plot") == 0) {
/* obsolete - ignore */
LITERR(" Warning: obsolete control card - ignored \n");
return (0);
} else if ((strcmp(token, ".temp") == 0)) {
/* .temp temp1 temp2 temp3 temp4 ..... */
/* not yet implemented - warn & ignore */
LITERR(" Warning: .TEMP card obsolete - use .options TEMP and TNOM\n");
return (0);
} else if ((strcmp(token, ".op") == 0)) {
return dot_op(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".nodeset") == 0)) {
return dot_nodeset(line, ckt, tab, current, task, gnode);
} else if ((strcmp(token, ".disto") == 0)) {
return dot_disto(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".noise") == 0)) {
return dot_noise(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".four") == 0)
|| (strcmp(token, ".fourier") == 0)) {
/* .four */
/* not implemented - warn & ignore */
LITERR("Use fourier command to obtain fourier analysis\n");
return (0);
} else if ((strcmp(token, ".ic") == 0)) {
return dot_ic(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".ac") == 0)) {
return dot_ac(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".pz") == 0)) {
return dot_pz(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".dc") == 0)) {
return dot_dc(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".tf") == 0)) {
/* .tf v( node1, node2 ) src */
/* .tf vsrc2 src */
which = -1;
@ -489,40 +440,40 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
LITERR("Transfer Function analysis unsupported.\n");
return (0);
}
IFC(newAnalysis, (ckt, which, "Transfer Function", &foo, task))
IFC(newAnalysis, (ckt, which, "Transfer Function", &foo, task));
INPgetTok(&line, &name, 0);
/* name is now either V or I or a serious error */
if (*name == 'v' && strlen(name) == 1) {
if (*line != '(' /* match) */ ) {
if (*line != '(' ) {
/* error, bad input format */
}
INPgetTok(&line, &nname1, 0);
INPtermInsert(ckt, &nname1, tab, &node1);
ptemp.nValue = (IFnode) node1;
GCA(INPapName, (ckt, which, foo, "outpos", &ptemp))
if (*line != /* match ( */ ')') {
GCA(INPapName, (ckt, which, foo, "outpos", &ptemp));
if (*line != ')') {
INPgetTok(&line, &nname2, 1);
INPtermInsert(ckt, &nname2, tab, &node2);
ptemp.nValue = (IFnode) node2;
GCA(INPapName, (ckt, which, foo, "outneg", &ptemp))
ptemp.sValue = (char *)
MALLOC(sizeof(char) *
GCA(INPapName, (ckt, which, foo, "outneg", &ptemp));
ptemp.sValue =
(char *) MALLOC(sizeof(char) *
(5 + strlen(nname1) + strlen(nname2)));
(void) sprintf(ptemp.sValue, "V(%s,%s)", nname1, nname2);
GCA(INPapName, (ckt, which, foo, "outname", &ptemp))
GCA(INPapName, (ckt, which, foo, "outname", &ptemp));
} else {
ptemp.nValue = (IFnode) gnode;
GCA(INPapName, (ckt, which, foo, "outneg", &ptemp))
GCA(INPapName, (ckt, which, foo, "outneg", &ptemp));
ptemp.sValue =
(char *) MALLOC(sizeof(char) * (4 + strlen(nname1)));
(void) sprintf(ptemp.sValue, "V(%s)", nname1);
GCA(INPapName, (ckt, which, foo, "outname", &ptemp))
GCA(INPapName, (ckt, which, foo, "outname", &ptemp));
}
} else if (*name == 'i' && strlen(name) == 1) {
INPgetTok(&line, &name, 1);
INPinsert(&name, tab);
ptemp.uValue = name;
GCA(INPapName, (ckt, which, foo, "outsrc", &ptemp))
GCA(INPapName, (ckt, which, foo, "outsrc", &ptemp));
} else {
LITERR("Syntax error: voltage or current expected.\n");
return 0;
@ -530,9 +481,23 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
INPgetTok(&line, &name, 1);
INPinsert(&name, tab);
ptemp.uValue = name;
GCA(INPapName, (ckt, which, foo, "insrc", &ptemp))
GCA(INPapName, (ckt, which, foo, "insrc", &ptemp));
return (0);
} else if ((strcmp(token, ".tran") == 0)) {
}
static int
dot_tran(char *line, void *ckt, INPtables *tab, card *current,
void *task, void *gnode, void *foo)
{
int error; /* error code temporary */
IFvalue ptemp; /* a value structure to package resistance into */
IFvalue *parm; /* a pointer to a value struct for function returns */
int which; /* which analysis we are performing */
int i; /* generic loop variable */
double dtemp; /* random double precision temporary */
char *word; /* something to stick a word of input into */
/* .tran Tstep Tstop <Tstart <Tmax> > <UIC> */
which = -1;
for (i = 0; i < ft_sim->numAnalyses; i++) {
@ -545,20 +510,20 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
LITERR("Transient analysis unsupported.\n");
return (0);
}
IFC(newAnalysis, (ckt, which, "Transient Analysis", &foo, task))
IFC(newAnalysis, (ckt, which, "Transient Analysis", &foo, task));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tstep */
GCA(INPapName, (ckt, which, foo, "tstep", parm))
GCA(INPapName, (ckt, which, foo, "tstep", parm));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* Tstop */
GCA(INPapName, (ckt, which, foo, "tstop", parm))
GCA(INPapName, (ckt, which, foo, "tstop", parm));
if (*line) {
dtemp = INPevaluate(&line, &error, 1); /* tstart? */
if (error == 0) {
ptemp.rValue = dtemp;
GCA(INPapName, (ckt, which, foo, "tstart", &ptemp))
GCA(INPapName, (ckt, which, foo, "tstart", &ptemp));
dtemp = INPevaluate(&line, &error, 1); /* tmax? */
if (error == 0) {
ptemp.rValue = dtemp;
GCA(INPapName, (ckt, which, foo, "tmax", &ptemp))
GCA(INPapName, (ckt, which, foo, "tmax", &ptemp));
}
}
}
@ -566,22 +531,31 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
INPgetTok(&line, &word, 1); /* uic? */
if (strcmp(word, "uic") == 0) {
ptemp.iValue = 1;
GCA(INPapName, (ckt, which, foo, "uic", &ptemp))
GCA(INPapName, (ckt, which, foo, "uic", &ptemp));
} else {
LITERR(" Error: unknown parameter on .tran - ignored\n");
}
}
return (0);
} else if ((strcmp(token, ".subckt") == 0) ||
(strcmp(token, ".ends") == 0)) {
/* not yet implemented - warn & ignore */
LITERR(" Warning: Subcircuits not yet implemented - ignored \n");
return (0);
} else if ((strcmp(token, ".end") == 0)) {
/* .end - end of input */
/* not allowed to pay attention to additional input - return */
return (1);
} else if (strcmp(token, ".sens") == 0) {
}
static int
dot_sens(char *line, void *ckt, INPtables *tab, card *current,
void *task, void *gnode, void *foo)
{
char *name; /* the resistor's name */
int error; /* error code temporary */
IFvalue ptemp; /* a value structure to package resistance into */
IFvalue *parm; /* a pointer to a value struct for function returns */
int which; /* which analysis we are performing */
int i; /* generic loop variable */
char *nname1; /* the first node's name */
char *nname2; /* the second node's name */
void *node1; /* the first node's node pointer */
void *node2; /* the second node's node pointer */
char *steptype; /* ac analysis, type of stepping function */
which = -1; /* Bug fix from Glao Dezai */
for (i = 0; i < ft_sim->numAnalyses; i++) {
if (strcmp(ft_sim->analyses[i]->name, "SENS") == 0) {
@ -604,7 +578,7 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
INPgetTok(&line, &name, 0);
/* name is now either V or I or a serious error */
if (*name == 'v' && strlen(name) == 1) {
if (*line != '(' /* match) */ ) {
if (*line != '(') {
LITERR("Syntax error: '(' expected after 'v'\n");
return 0;
}
@ -613,29 +587,29 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
ptemp.nValue = (IFnode) node1;
GCA(INPapName, (ckt, which, foo, "outpos", &ptemp))
if (*line != /* match ( */ ')') {
if (*line != ')') {
INPgetTok(&line, &nname2, 1);
INPtermInsert(ckt, &nname2, tab, &node2);
ptemp.nValue = (IFnode) node2;
GCA(INPapName, (ckt, which, foo, "outneg", &ptemp))
GCA(INPapName, (ckt, which, foo, "outneg", &ptemp));
ptemp.sValue = (char *)
MALLOC(sizeof(char) *
(5 + strlen(nname1) + strlen(nname2)));
(void) sprintf(ptemp.sValue, "V(%s,%s)", nname1, nname2);
GCA(INPapName, (ckt, which, foo, "outname", &ptemp))
GCA(INPapName, (ckt, which, foo, "outname", &ptemp));
} else {
ptemp.nValue = (IFnode) gnode;
GCA(INPapName, (ckt, which, foo, "outneg", &ptemp))
GCA(INPapName, (ckt, which, foo, "outneg", &ptemp));
ptemp.sValue =
(char *) MALLOC(sizeof(char) * (4 + strlen(nname1)));
(void) sprintf(ptemp.sValue, "V(%s)", nname1);
GCA(INPapName, (ckt, which, foo, "outname", &ptemp))
GCA(INPapName, (ckt, which, foo, "outname", &ptemp));
}
} else if (*name == 'i' && strlen(name) == 1) {
INPgetTok(&line, &name, 1);
INPinsert(&name, tab);
ptemp.uValue = name;
GCA(INPapName, (ckt, which, foo, "outsrc", &ptemp))
GCA(INPapName, (ckt, which, foo, "outsrc", &ptemp));
} else {
LITERR("Syntax error: voltage or current expected.\n");
return 0;
@ -650,13 +624,13 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
if (name && !strcmp(name, "ac")) {
INPgetTok(&line, &steptype, 1); /* get DEC, OCT, or LIN */
ptemp.iValue = 1;
GCA(INPapName, (ckt, which, foo, steptype, &ptemp))
GCA(INPapName, (ckt, which, foo, steptype, &ptemp));
parm = INPgetValue(ckt, &line, IF_INTEGER, tab); /* number of points */
GCA(INPapName, (ckt, which, foo, "numsteps", parm))
GCA(INPapName, (ckt, which, foo, "numsteps", parm));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstart */
GCA(INPapName, (ckt, which, foo, "start", parm))
GCA(INPapName, (ckt, which, foo, "start", parm));
parm = INPgetValue(ckt, &line, IF_REAL, tab); /* fstop */
GCA(INPapName, (ckt, which, foo, "stop", parm))
GCA(INPapName, (ckt, which, foo, "stop", parm));
return (0);
} else if (name && *name && strcmp(name, "dc")) {
/* Bad flag */
@ -664,9 +638,21 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
return 0;
}
return (0);
}
}
#ifdef WANT_SENSE2
else if ((strcmp(token, ".sens2") == 0)) {
static int
dot_sens2(char *line, void *ckt, INPtables *tab, card *current,
void *task, void *gnode, void *foo)
{
int error; /* error code temporary */
IFvalue ptemp; /* a value structure to package resistance into */
IFvalue *parm; /* a pointer to a value struct for function returns */
int which; /* which analysis we are performing */
int i; /* generic loop variable */
char *token; /* a token from the line */
/* .sens {AC} {DC} {TRAN} [dev=nnn parm=nnn]* */
which = -1;
for (i = 0; i < ft_sim->numAnalyses; i++) {
@ -679,31 +665,30 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
LITERR("Sensitivity-2 analysis unsupported\n");
return (0);
}
IFC(newAnalysis,
(ckt, which, "Sensitivity-2 Analysis", &foo, task)) while (*line) { /* read the entire line */
IFC(newAnalysis, (ckt, which, "Sensitivity-2 Analysis", &foo, task));
while (*line) {
/* read the entire line */
INPgetTok(&line, &token, 1);
for (i = 0; i < ft_sim->analyses[which]->numParms; i++) {
/* find the parameter */
if (0 == strcmp(token,
ft_sim->analyses[which]->
analysisParms[i].keyword)) {
ft_sim->analyses[which]->analysisParms[i].keyword)) {
/* found it, analysis which, parameter i */
if (ft_sim->analyses[which]->
analysisParms[i].dataType & IF_FLAG) {
if (ft_sim->analyses[which]->analysisParms[i].dataType & IF_FLAG) {
/* one of the keywords! */
ptemp.iValue = 1;
error = (*(ft_sim->setAnalysisParm)) (
ckt, foo,
error =
(*(ft_sim->setAnalysisParm)) (ckt, foo,
ft_sim->analyses[which]->analysisParms[i].id,
&ptemp, (IFvalue *) NULL);
&ptemp,
(IFvalue *) NULL);
if (error)
current->error =
INPerrCat(current->error, INPerror(error));
} else {
parm =
INPgetValue(ckt, &line,
ft_sim->analyses[which]->
analysisParms[i].dataType, tab);
ft_sim->analyses[which]->analysisParms[i].dataType, tab);
error =
(*(ft_sim->setAnalysisParm)) (ckt, foo,
ft_sim->
@ -726,6 +711,77 @@ INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
}
}
return (0);
}
#endif
int
INP2dot(void *ckt, INPtables *tab, card *current, void *task, void *gnode)
{
/* .<something> Many possibilities */
char *token; /* a token from the line */
void *foo = NULL; /* pointer to analysis */
/* the part of the current line left to parse */
char *line = current->line;
INPgetTok(&line, &token, 1);
if (strcmp(token, ".model") == 0) {
/* don't have to do anything, since models were all done in
* pass 1 */
return (0);
} else if ((strcmp(token, ".width") == 0) ||
strcmp(token, ".print") == 0 || strcmp(token, ".plot") == 0) {
/* obsolete - ignore */
LITERR(" Warning: obsolete control card - ignored \n");
return (0);
} else if ((strcmp(token, ".temp") == 0)) {
/* .temp temp1 temp2 temp3 temp4 ..... */
/* not yet implemented - warn & ignore */
LITERR(" Warning: .TEMP card obsolete - use .options TEMP and TNOM\n");
return (0);
} else if ((strcmp(token, ".op") == 0)) {
return dot_op(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".nodeset") == 0)) {
return dot_nodeset(line, ckt, tab, current, task, gnode);
} else if ((strcmp(token, ".disto") == 0)) {
return dot_disto(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".noise") == 0)) {
return dot_noise(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".four") == 0)
|| (strcmp(token, ".fourier") == 0)) {
/* .four */
/* not implemented - warn & ignore */
LITERR("Use fourier command to obtain fourier analysis\n");
return (0);
} else if ((strcmp(token, ".ic") == 0)) {
return dot_ic(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".ac") == 0)) {
return dot_ac(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".pz") == 0)) {
return dot_pz(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".dc") == 0)) {
return dot_dc(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".tf") == 0)) {
return dot_tf(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".tran") == 0)) {
return dot_tran(line, ckt, tab, current, task, gnode, foo);
} else if ((strcmp(token, ".subckt") == 0) ||
(strcmp(token, ".ends") == 0)) {
/* not yet implemented - warn & ignore */
LITERR(" Warning: Subcircuits not yet implemented - ignored \n");
return (0);
} else if ((strcmp(token, ".end") == 0)) {
/* .end - end of input */
/* not allowed to pay attention to additional input - return */
return (1);
} else if (strcmp(token, ".sens") == 0) {
return dot_sens(line, ckt, tab, current, task, gnode, foo);
}
#ifdef WANT_SENSE2
else if ((strcmp(token, ".sens2") == 0)) {
return dot_sens2(line, ckt, tab, current, task, gnode, foo);
}
#endif
else if ((strcmp(token, ".probe") == 0)) {

Loading…
Cancel
Save