|
|
@ -1,7 +1,6 @@ |
|
|
/********** |
|
|
/********** |
|
|
Copyright 1990 Regents of the University of California. All rights reserved. |
|
|
Copyright 1990 Regents of the University of California. All rights reserved. |
|
|
Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group |
|
|
Author: 1988 Wayne A. Christopher, U. C. Berkeley CAD Group |
|
|
Modified: 2000 AlansFixes |
|
|
|
|
|
**********/ |
|
|
**********/ |
|
|
|
|
|
|
|
|
/* |
|
|
/* |
|
|
@ -21,23 +20,19 @@ Modified: 2000 AlansFixes |
|
|
#include "ifsim.h" |
|
|
#include "ifsim.h" |
|
|
#include "jobdefs.h" |
|
|
#include "jobdefs.h" |
|
|
#include "iferrmsg.h" |
|
|
#include "iferrmsg.h" |
|
|
|
|
|
|
|
|
#include "circuits.h" |
|
|
#include "circuits.h" |
|
|
#include "outitf.h" |
|
|
#include "outitf.h" |
|
|
#include "variable.h" |
|
|
#include "variable.h" |
|
|
#include <fcntl.h> |
|
|
|
|
|
#include <time.h> |
|
|
|
|
|
#include "cktdefs.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern void gr_end_iplot(void); |
|
|
extern void gr_end_iplot(void); |
|
|
extern char *spice_analysis_get_name(int index); |
|
|
extern char *spice_analysis_get_name(int index); |
|
|
extern char *spice_analysis_get_description(int index); |
|
|
extern char *spice_analysis_get_description(int index); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* static declarations */ |
|
|
/* static declarations */ |
|
|
static int beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, |
|
|
static int beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, |
|
|
char *refName, int refType, int numNames, char **dataNames, int dataType, |
|
|
|
|
|
bool windowed, runDesc **runp); |
|
|
|
|
|
|
|
|
char *refName, int refType, int numNames, char **dataNames, int dataType, |
|
|
|
|
|
bool windowed, runDesc **runp); |
|
|
static int addDataDesc(runDesc *run, char *name, int type, int ind); |
|
|
static int addDataDesc(runDesc *run, char *name, int type, int ind); |
|
|
static int addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind); |
|
|
static int addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind); |
|
|
static void fileInit(runDesc *run); |
|
|
static void fileInit(runDesc *run); |
|
|
@ -61,13 +56,10 @@ static void freeRun(runDesc *run); |
|
|
#define DOUBLE_PRECISION 15 |
|
|
#define DOUBLE_PRECISION 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static clock_t lastclock, currclock; |
|
|
|
|
|
static float *rowbuf; |
|
|
|
|
|
static int column, rowbuflen; |
|
|
|
|
|
|
|
|
|
|
|
static bool shouldstop = FALSE; /* Tell simulator to stop next time it asks. */ |
|
|
|
|
|
static bool printinfo = FALSE; /* Print informational "error messages". */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool shouldstop = FALSE; /* Tell simulator to stop next time it asks. */ |
|
|
|
|
|
static bool printinfo = FALSE; /* Print informational "error messages". */ |
|
|
|
|
|
|
|
|
/* The two "begin plot" routines share all their internals... */ |
|
|
/* The two "begin plot" routines share all their internals... */ |
|
|
|
|
|
|
|
|
@ -118,14 +110,12 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch |
|
|
int numsaves; |
|
|
int numsaves; |
|
|
int i, j, depind; |
|
|
int i, j, depind; |
|
|
char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP]; |
|
|
char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP]; |
|
|
char *ch, tmpname[BSIZE_SP]; |
|
|
|
|
|
bool saveall = TRUE; |
|
|
|
|
|
bool savealli = FALSE; |
|
|
|
|
|
|
|
|
bool saveall = TRUE; |
|
|
char *an_name; |
|
|
char *an_name; |
|
|
|
|
|
|
|
|
/* Check to see if we want to print informational data. */ |
|
|
/* Check to see if we want to print informational data. */ |
|
|
if (cp_getvar("printinfo", VT_BOOL, (char *) &printinfo)) |
|
|
if (cp_getvar("printinfo", VT_BOOL, (char *) &printinfo)) |
|
|
fprintf(cp_err, "(debug printing enabled)\n"); |
|
|
|
|
|
|
|
|
fprintf(cp_err, "(debug printing enabled)\n"); |
|
|
|
|
|
|
|
|
*runp = run = alloc(struct runDesc); |
|
|
*runp = run = alloc(struct runDesc); |
|
|
|
|
|
|
|
|
@ -150,23 +140,17 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch |
|
|
saveall = FALSE; |
|
|
saveall = FALSE; |
|
|
for (i = 0; i < numsaves; i++) { |
|
|
for (i = 0; i < numsaves; i++) { |
|
|
if (saves[i].analysis && !cieq(saves[i].analysis, an_name)) { |
|
|
if (saves[i].analysis && !cieq(saves[i].analysis, an_name)) { |
|
|
/* ignore this one this time around */ |
|
|
|
|
|
savesused[i] = TRUE; |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
if (cieq(saves[i].name, "all") || cieq(saves[i].name, "allv")) { |
|
|
|
|
|
saveall = TRUE; |
|
|
|
|
|
|
|
|
/* ignore this one this time around */ |
|
|
savesused[i] = TRUE; |
|
|
savesused[i] = TRUE; |
|
|
saves[i].used = 1; |
|
|
|
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
if (cieq(saves[i].name, "alli")) { |
|
|
|
|
|
savealli = TRUE; |
|
|
|
|
|
|
|
|
if (cieq(saves[i].name, "all")) { |
|
|
|
|
|
saveall = TRUE; |
|
|
savesused[i] = TRUE; |
|
|
savesused[i] = TRUE; |
|
|
saves[i].used = 1; |
|
|
|
|
|
|
|
|
saves[i].used = 1; |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* Pass 0. */ |
|
|
/* Pass 0. */ |
|
|
@ -175,7 +159,7 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch |
|
|
for (i = 0; i < numsaves; i++) |
|
|
for (i = 0; i < numsaves; i++) |
|
|
if (!savesused[i] && name_eq(saves[i].name, refName)) { |
|
|
if (!savesused[i] && name_eq(saves[i].name, refName)) { |
|
|
savesused[i] = TRUE; |
|
|
savesused[i] = TRUE; |
|
|
saves[i].used = 1; |
|
|
|
|
|
|
|
|
saves[i].used = 1; |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
run->refIndex = -1; |
|
|
run->refIndex = -1; |
|
|
@ -185,95 +169,32 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch |
|
|
/* Pass 1. */ |
|
|
/* Pass 1. */ |
|
|
if (numsaves && !saveall) { |
|
|
if (numsaves && !saveall) { |
|
|
for (i = 0; i < numsaves; i++) { |
|
|
for (i = 0; i < numsaves; i++) { |
|
|
if (!savesused[i]) { |
|
|
|
|
|
for (j = 0; j < numNames; j++) { |
|
|
|
|
|
if (name_eq(saves[i].name, dataNames[j])) { |
|
|
|
|
|
addDataDesc(run, dataNames[j], dataType, j); |
|
|
|
|
|
savesused[i] = TRUE; |
|
|
|
|
|
saves[i].used = 1; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (!savesused[i]) { |
|
|
|
|
|
for (j = 0; j < numNames; j++) { |
|
|
|
|
|
if (name_eq(saves[i].name, dataNames[j])) { |
|
|
|
|
|
addDataDesc(run, dataNames[j], dataType, j); |
|
|
|
|
|
savesused[i] = TRUE; |
|
|
|
|
|
saves[i].used = 1; |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
for (i = 0; i < numNames; i++) |
|
|
for (i = 0; i < numNames; i++) |
|
|
if (!refName || !name_eq(dataNames[i], refName)) { |
|
|
if (!refName || !name_eq(dataNames[i], refName)) { |
|
|
if (!strstr(dataNames[i], "#internal") && |
|
|
|
|
|
!strstr(dataNames[i], "#source") && |
|
|
|
|
|
!strstr(dataNames[i], "#drain") && |
|
|
|
|
|
!strstr(dataNames[i], "#collector") && |
|
|
|
|
|
!strstr(dataNames[i], "#emitter") && |
|
|
|
|
|
!strstr(dataNames[i], "#base")) { |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
addDataDesc(run, dataNames[i], dataType, i); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* Pass 1 and a bit. */ |
|
|
|
|
|
if (savealli) { |
|
|
|
|
|
depind=0; |
|
|
|
|
|
for (i = 0; i < numNames; i++) { |
|
|
|
|
|
if (strstr(dataNames[i], "#internal") || |
|
|
|
|
|
strstr(dataNames[i], "#source") || |
|
|
|
|
|
strstr(dataNames[i], "#drain") || |
|
|
|
|
|
strstr(dataNames[i], "#collector") || |
|
|
|
|
|
strstr(dataNames[i], "#emitter") || |
|
|
|
|
|
strstr(dataNames[i], "#base")) { |
|
|
|
|
|
tmpname[0]='@'; |
|
|
|
|
|
tmpname[1]='\0'; |
|
|
|
|
|
strncat(tmpname, dataNames[i], BSIZE_SP-1); |
|
|
|
|
|
ch=strchr(tmpname, '#'); |
|
|
|
|
|
|
|
|
|
|
|
if (strstr(ch, "#collector")!=NULL) { |
|
|
|
|
|
strcpy(ch, "[ic]"); |
|
|
|
|
|
} else if (strstr(ch, "#base")!=NULL) { |
|
|
|
|
|
strcpy(ch, "[ib]"); |
|
|
|
|
|
} else if (strstr(ch, "#emitter")!=NULL) { |
|
|
|
|
|
strcpy(ch, "[ie]"); |
|
|
|
|
|
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) { |
|
|
|
|
|
addSpecialDesc(run, tmpname, namebuf, parambuf, depind); |
|
|
|
|
|
}; |
|
|
|
|
|
strcpy(ch, "[is]"); |
|
|
|
|
|
} else if (strstr(ch, "#drain")!=NULL) { |
|
|
|
|
|
strcpy(ch, "[id]"); |
|
|
|
|
|
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) { |
|
|
|
|
|
addSpecialDesc(run, tmpname, namebuf, parambuf, depind); |
|
|
|
|
|
}; |
|
|
|
|
|
strcpy(ch, "[ig]"); |
|
|
|
|
|
} else if (strstr(ch, "#source")!=NULL) { |
|
|
|
|
|
strcpy(ch, "[is]"); |
|
|
|
|
|
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) { |
|
|
|
|
|
addSpecialDesc(run, tmpname, namebuf, parambuf, depind); |
|
|
|
|
|
}; |
|
|
|
|
|
strcpy(ch, "[ib]"); |
|
|
|
|
|
} else |
|
|
|
|
|
if ((strstr(ch, "#internal")!=NULL)&&(tmpname[1]=='d')) { |
|
|
|
|
|
strcpy(ch, "[id]"); |
|
|
|
|
|
} else { |
|
|
|
|
|
fprintf(cp_err, |
|
|
|
|
|
"Debug: could output current for %s\n", tmpname); |
|
|
|
|
|
continue; |
|
|
|
|
|
}; |
|
|
|
|
|
if (parseSpecial(tmpname, namebuf, parambuf, depbuf)) { |
|
|
|
|
|
if (*depbuf) { fprintf( stderr, |
|
|
|
|
|
"Warning : unexpected dependant variable on %s\n", tmpname); |
|
|
|
|
|
} else { |
|
|
|
|
|
addSpecialDesc(run, tmpname, namebuf, parambuf, depind); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Pass 2. */ |
|
|
/* Pass 2. */ |
|
|
for (i = 0; i < numsaves; i++) { |
|
|
for (i = 0; i < numsaves; i++) { |
|
|
if (savesused[i]) |
|
|
if (savesused[i]) |
|
|
continue; |
|
|
continue; |
|
|
if (!parseSpecial(saves[i].name, namebuf, parambuf, depbuf)) { |
|
|
if (!parseSpecial(saves[i].name, namebuf, parambuf, depbuf)) { |
|
|
if (saves[i].analysis) |
|
|
|
|
|
fprintf(cp_err, "Warning: can't parse '%s': ignored\n", |
|
|
|
|
|
saves[i].name); |
|
|
|
|
|
|
|
|
if (saves[i].analysis) |
|
|
|
|
|
fprintf(cp_err, "Warning: can't parse '%s': ignored\n", |
|
|
|
|
|
saves[i].name); |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
/* Now, if there's a dep variable, do we already have it? */ |
|
|
/* Now, if there's a dep variable, do we already have it? */ |
|
|
@ -294,7 +215,7 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch |
|
|
} |
|
|
} |
|
|
addDataDesc(run, dataNames[j], dataType, j); |
|
|
addDataDesc(run, dataNames[j], dataType, j); |
|
|
savesused[i] = TRUE; |
|
|
savesused[i] = TRUE; |
|
|
saves[i].used = 1; |
|
|
|
|
|
|
|
|
saves[i].used = 1; |
|
|
depind = j; |
|
|
depind = j; |
|
|
} else |
|
|
} else |
|
|
depind = run->data[j].outIndex; |
|
|
depind = run->data[j].outIndex; |
|
|
@ -303,22 +224,22 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (numsaves) { |
|
|
if (numsaves) { |
|
|
for (i = 0; i < numsaves; i++) { |
|
|
|
|
|
tfree(saves[i].analysis); |
|
|
|
|
|
tfree(saves[i].name); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
for (i = 0; i < numsaves; i++) { |
|
|
|
|
|
tfree(saves[i].analysis); |
|
|
|
|
|
tfree(saves[i].name); |
|
|
|
|
|
} |
|
|
tfree(savesused); |
|
|
tfree(savesused); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (numNames |
|
|
if (numNames |
|
|
&& (run->numData == 1 |
|
|
|
|
|
&& (run->refIndex != -1 |
|
|
|
|
|
|| run->numData == 0) |
|
|
|
|
|
&& run->refIndex == -1)) |
|
|
|
|
|
|
|
|
&& (run->numData == 1 |
|
|
|
|
|
&& (run->refIndex != -1 |
|
|
|
|
|
|| run->numData == 0) |
|
|
|
|
|
&& run->refIndex == -1)) |
|
|
{ |
|
|
{ |
|
|
fprintf(cp_err, "Error: no data saved for %s; analysis not run\n", |
|
|
|
|
|
spice_analysis_get_description(((JOB *) analysisPtr)->JOBtype)); |
|
|
|
|
|
return E_NOTFOUND; |
|
|
|
|
|
|
|
|
fprintf(cp_err, "Error: no data saved for %s; analysis not run\n", |
|
|
|
|
|
spice_analysis_get_description(((JOB *) analysisPtr)->JOBtype)); |
|
|
|
|
|
return E_NOTFOUND; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* Now that we have our own data structures built up, let's see what |
|
|
/* Now that we have our own data structures built up, let's see what |
|
|
@ -331,8 +252,8 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch |
|
|
fileInit(run); |
|
|
fileInit(run); |
|
|
else { |
|
|
else { |
|
|
plotInit(run); |
|
|
plotInit(run); |
|
|
if (refName) |
|
|
|
|
|
run->runPlot->pl_ndims = 1; |
|
|
|
|
|
|
|
|
if (refName) |
|
|
|
|
|
run->runPlot->pl_ndims = 1; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return (OK); |
|
|
return (OK); |
|
|
@ -344,9 +265,7 @@ addDataDesc(runDesc *run, char *name, int type, int ind) |
|
|
dataDesc *data; |
|
|
dataDesc *data; |
|
|
|
|
|
|
|
|
if (!run->numData) |
|
|
if (!run->numData) |
|
|
{run->data = (dataDesc *) tmalloc(32768); |
|
|
|
|
|
run->data = (dataDesc *) trealloc(run->data, sizeof (dataDesc)); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
run->data = (dataDesc *) tmalloc(sizeof (dataDesc)); |
|
|
else |
|
|
else |
|
|
run->data = (dataDesc *) trealloc((char *) run->data, |
|
|
run->data = (dataDesc *) trealloc((char *) run->data, |
|
|
sizeof (dataDesc) * (run->numData + 1)); |
|
|
sizeof (dataDesc) * (run->numData + 1)); |
|
|
@ -377,8 +296,7 @@ addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind) |
|
|
char *unique; /* unique char * from back-end */ |
|
|
char *unique; /* unique char * from back-end */ |
|
|
|
|
|
|
|
|
if (!run->numData) |
|
|
if (!run->numData) |
|
|
{run->data = (dataDesc *) tmalloc(32768); |
|
|
|
|
|
run->data = (dataDesc *) trealloc(run->data, sizeof (dataDesc));} |
|
|
|
|
|
|
|
|
run->data = (dataDesc *) tmalloc(sizeof (dataDesc)); |
|
|
else |
|
|
else |
|
|
run->data = (dataDesc *) trealloc((char *) run->data, |
|
|
run->data = (dataDesc *) trealloc((char *) run->data, |
|
|
sizeof (dataDesc) * (run->numData + 1)); |
|
|
sizeof (dataDesc) * (run->numData + 1)); |
|
|
@ -406,7 +324,7 @@ addSpecialDesc(runDesc *run, char *name, char *devname, char *param, int depind) |
|
|
return (OK); |
|
|
return (OK); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
int |
|
|
OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) |
|
|
OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) |
|
|
@ -421,28 +339,17 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) |
|
|
run->pointCount++; |
|
|
run->pointCount++; |
|
|
|
|
|
|
|
|
if (run->writeOut) { |
|
|
if (run->writeOut) { |
|
|
if (run->pointCount == 1) |
|
|
|
|
|
fileInit_pass2(plotPtr); |
|
|
|
|
|
|
|
|
if (run->pointCount == 1) |
|
|
|
|
|
fileInit_pass2(plotPtr); |
|
|
fileStartPoint(run->fp, run->binary, run->pointCount); |
|
|
fileStartPoint(run->fp, run->binary, run->pointCount); |
|
|
|
|
|
|
|
|
if (run->refIndex != -1) { |
|
|
if (run->refIndex != -1) { |
|
|
if (run->isComplex){ |
|
|
|
|
|
|
|
|
if (run->isComplex) |
|
|
fileAddComplexValue(run->fp, run->binary, refValue->cValue); |
|
|
fileAddComplexValue(run->fp, run->binary, refValue->cValue); |
|
|
currclock = clock(); |
|
|
|
|
|
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) { |
|
|
|
|
|
fprintf(stderr, " Reference value : % 12.5e\r", |
|
|
|
|
|
refValue->cValue.real); |
|
|
|
|
|
lastclock = currclock; |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
else |
|
|
fileAddRealValue(run->fp, run->binary, refValue->rValue); |
|
|
fileAddRealValue(run->fp, run->binary, refValue->rValue); |
|
|
currclock = clock(); |
|
|
|
|
|
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) { |
|
|
|
|
|
fprintf(stderr, " Reference value : % 12.5e\r", refValue->rValue); |
|
|
|
|
|
lastclock = currclock; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < run->numData; i++) { |
|
|
for (i = 0; i < run->numData; i++) { |
|
|
/* we've already printed reference vec first */ |
|
|
/* we've already printed reference vec first */ |
|
|
if (run->data[i].outIndex == -1) continue; |
|
|
if (run->data[i].outIndex == -1) continue; |
|
|
@ -461,22 +368,7 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) |
|
|
} else { |
|
|
} else { |
|
|
/* should pre-check instance */ |
|
|
/* should pre-check instance */ |
|
|
if (!getSpecial(&run->data[i], run, &val)) |
|
|
if (!getSpecial(&run->data[i], run, &val)) |
|
|
{ |
|
|
|
|
|
if (run->pointCount==1) |
|
|
|
|
|
fprintf(stderr, "Warning: unrecognized variable - %s\n", |
|
|
|
|
|
run->data[i].name); |
|
|
|
|
|
if (run->isComplex) { |
|
|
|
|
|
val.cValue.real=0; |
|
|
|
|
|
val.cValue.imag=0; |
|
|
|
|
|
fileAddComplexValue(run->fp, run->binary, |
|
|
|
|
|
val.cValue); |
|
|
|
|
|
} else { |
|
|
|
|
|
val.rValue=0; |
|
|
|
|
|
fileAddRealValue(run->fp, run->binary, |
|
|
|
|
|
val.rValue); |
|
|
|
|
|
}; |
|
|
|
|
|
continue; |
|
|
continue; |
|
|
}; |
|
|
|
|
|
if (run->data[i].type == IF_REAL) |
|
|
if (run->data[i].type == IF_REAL) |
|
|
fileAddRealValue(run->fp, run->binary, |
|
|
fileAddRealValue(run->fp, run->binary, |
|
|
val.rValue); |
|
|
val.rValue); |
|
|
@ -488,10 +380,6 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
fileEndPoint(run->fp, run->binary); |
|
|
fileEndPoint(run->fp, run->binary); |
|
|
if (ferror(run->fp)) { |
|
|
|
|
|
fprintf(stderr, "Warning: rawfile write error !!\n"); |
|
|
|
|
|
shouldstop = TRUE; |
|
|
|
|
|
}; |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
for (i = 0; i < run->numData; i++) { |
|
|
for (i = 0; i < run->numData; i++) { |
|
|
if (run->data[i].outIndex == -1) { |
|
|
if (run->data[i].outIndex == -1) { |
|
|
@ -533,7 +421,7 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr) |
|
|
return (OK); |
|
|
return (OK); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ARGSUSED */ /* until some code gets written */ |
|
|
/* ARGSUSED */ /* until some code gets written */ |
|
|
int |
|
|
int |
|
|
@ -555,7 +443,7 @@ OUTwEnd(void *plotPtr) |
|
|
return (OK); |
|
|
return (OK); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int |
|
|
int |
|
|
OUTendPlot(void *plotPtr) |
|
|
OUTendPlot(void *plotPtr) |
|
|
@ -578,7 +466,7 @@ OUTendPlot(void *plotPtr) |
|
|
return (OK); |
|
|
return (OK); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ARGSUSED */ /* until some code gets written */ |
|
|
/* ARGSUSED */ /* until some code gets written */ |
|
|
int |
|
|
int |
|
|
@ -594,7 +482,7 @@ OUTendDomain(void *plotPtr) |
|
|
return (OK); |
|
|
return (OK); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ARGSUSED */ /* until some code gets written */ |
|
|
/* ARGSUSED */ /* until some code gets written */ |
|
|
int |
|
|
int |
|
|
@ -606,34 +494,34 @@ OUTattributes(void *plotPtr, char *varName, int param, IFvalue *value) |
|
|
int i; |
|
|
int i; |
|
|
|
|
|
|
|
|
if (param == OUT_SCALE_LIN) |
|
|
if (param == OUT_SCALE_LIN) |
|
|
type = GRID_LIN; |
|
|
|
|
|
|
|
|
type = GRID_LIN; |
|
|
else if (param == OUT_SCALE_LOG) |
|
|
else if (param == OUT_SCALE_LOG) |
|
|
type = GRID_XLOG; |
|
|
|
|
|
|
|
|
type = GRID_XLOG; |
|
|
else |
|
|
else |
|
|
return E_UNSUPP; |
|
|
|
|
|
|
|
|
return E_UNSUPP; |
|
|
|
|
|
|
|
|
if (run->writeOut) { |
|
|
if (run->writeOut) { |
|
|
if (varName) { |
|
|
|
|
|
for (i = 0; i < run->numData; i++) |
|
|
|
|
|
if (!strcmp(varName, run->data[i].name)) |
|
|
|
|
|
run->data[i].gtype = type; |
|
|
|
|
|
} else { |
|
|
|
|
|
run->data[run->refIndex].gtype = type; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (varName) { |
|
|
|
|
|
for (i = 0; i < run->numData; i++) |
|
|
|
|
|
if (!strcmp(varName, run->data[i].name)) |
|
|
|
|
|
run->data[i].gtype = type; |
|
|
|
|
|
} else { |
|
|
|
|
|
run->data[run->refIndex].gtype = type; |
|
|
|
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
if (varName) { |
|
|
|
|
|
for (d = run->runPlot->pl_dvecs; d; d = d->v_next) |
|
|
|
|
|
if (!strcmp(varName, d->v_name)) |
|
|
|
|
|
d->v_gridtype = type; |
|
|
|
|
|
} else { |
|
|
|
|
|
run->runPlot->pl_scale->v_gridtype = type; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
if (varName) { |
|
|
|
|
|
for (d = run->runPlot->pl_dvecs; d; d = d->v_next) |
|
|
|
|
|
if (!strcmp(varName, d->v_name)) |
|
|
|
|
|
d->v_gridtype = type; |
|
|
|
|
|
} else { |
|
|
|
|
|
run->runPlot->pl_scale->v_gridtype = type; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return (OK); |
|
|
return (OK); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The file writing routines. */ |
|
|
/* The file writing routines. */ |
|
|
|
|
|
|
|
|
@ -641,12 +529,7 @@ static void |
|
|
fileInit(runDesc *run) |
|
|
fileInit(runDesc *run) |
|
|
{ |
|
|
{ |
|
|
char buf[513]; |
|
|
char buf[513]; |
|
|
int i, tmp, sweep; |
|
|
|
|
|
float ftmp; |
|
|
|
|
|
time_t time_of_day; |
|
|
|
|
|
CKTcircuit *ckt; |
|
|
|
|
|
|
|
|
|
|
|
lastclock = clock(); |
|
|
|
|
|
|
|
|
int i; |
|
|
|
|
|
|
|
|
/* This is a hack. */ |
|
|
/* This is a hack. */ |
|
|
run->isComplex = FALSE; |
|
|
run->isComplex = FALSE; |
|
|
@ -655,163 +538,34 @@ fileInit(runDesc *run) |
|
|
run->isComplex = TRUE; |
|
|
run->isComplex = TRUE; |
|
|
|
|
|
|
|
|
i = 0; |
|
|
i = 0; |
|
|
|
|
|
|
|
|
/* Write PROBE version marker */ |
|
|
|
|
|
|
|
|
|
|
|
tmp=0xFFFFFFFF; |
|
|
|
|
|
fwrite((char *)&tmp,sizeof(tmp),1,run->fp); |
|
|
|
|
|
i += sizeof(tmp); |
|
|
|
|
|
tmp=0xF3FFFFFF; |
|
|
|
|
|
fwrite((char *)&tmp,sizeof(tmp),1,run->fp); |
|
|
|
|
|
i += sizeof(tmp); |
|
|
|
|
|
|
|
|
|
|
|
/* Write Title String */ |
|
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Title: %s\n", run->name); |
|
|
sprintf(buf, "Title: %s\n", run->name); |
|
|
i += strlen(buf); |
|
|
i += strlen(buf); |
|
|
fputs(buf, run->fp); |
|
|
fputs(buf, run->fp); |
|
|
|
|
|
|
|
|
/* Write \0 for Title string and \0 for empty SubTitle string */ |
|
|
|
|
|
|
|
|
|
|
|
tmp=0; |
|
|
|
|
|
fwrite((char *)&tmp,2,1,run->fp); |
|
|
|
|
|
i += 2; |
|
|
|
|
|
|
|
|
|
|
|
/* get the time and date */ |
|
|
|
|
|
|
|
|
|
|
|
time_of_day = time( NULL ); |
|
|
|
|
|
|
|
|
|
|
|
/* Write Time String */ |
|
|
|
|
|
|
|
|
|
|
|
strftime( buf, 9, "%H:%M:%S", |
|
|
|
|
|
localtime( &time_of_day ) ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Date: %s\n", datestring()); |
|
|
i += strlen(buf); |
|
|
i += strlen(buf); |
|
|
fputs(buf, run->fp); |
|
|
fputs(buf, run->fp); |
|
|
tmp=0; |
|
|
|
|
|
fwrite((char *)&tmp,1,1,run->fp); |
|
|
|
|
|
i += 1; |
|
|
|
|
|
|
|
|
|
|
|
/* Write Date String */ |
|
|
|
|
|
|
|
|
|
|
|
strftime( buf, 9, "%d/%m/%y", |
|
|
|
|
|
localtime( &time_of_day ) ); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sprintf(buf, "Plotname: %s\n", run->type); |
|
|
i += strlen(buf); |
|
|
i += strlen(buf); |
|
|
fputs(buf, run->fp); |
|
|
fputs(buf, run->fp); |
|
|
tmp=0; |
|
|
|
|
|
fwrite((char *)&tmp,1,1,run->fp); |
|
|
|
|
|
i += 1; |
|
|
|
|
|
|
|
|
|
|
|
/* Write Temperature */ |
|
|
|
|
|
|
|
|
|
|
|
ckt=run->circuit; |
|
|
|
|
|
ftmp=ckt->CKTtemp-273.15; |
|
|
|
|
|
fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp); |
|
|
|
|
|
i += sizeof(ftmp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Write Analysis Type */ |
|
|
|
|
|
|
|
|
|
|
|
if (strncasecmp(run->type,"AC",2)==0) { |
|
|
|
|
|
sprintf(buf, "AC Sweep"); |
|
|
|
|
|
sweep=2; |
|
|
|
|
|
} else if (strncasecmp(run->type,"DC",2)==0) { |
|
|
|
|
|
sprintf(buf, "DC Sweep"); |
|
|
|
|
|
sweep=1; |
|
|
|
|
|
} else if (strncasecmp(run->type,"Tran",4)==0) { |
|
|
|
|
|
sprintf(buf, "Transient Analysis"); |
|
|
|
|
|
sweep=4; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
sprintf(buf, "Flags: %s\n", run->isComplex ? "complex" : "real"); |
|
|
|
|
|
i += strlen(buf); |
|
|
|
|
|
fputs(buf, run->fp); |
|
|
|
|
|
sprintf(buf, "No. Variables: %d\n", run->numData); |
|
|
|
|
|
i += strlen(buf); |
|
|
|
|
|
fputs(buf, run->fp); |
|
|
|
|
|
sprintf(buf, "No. Points: "); |
|
|
i += strlen(buf); |
|
|
i += strlen(buf); |
|
|
fputs(buf, run->fp); |
|
|
fputs(buf, run->fp); |
|
|
|
|
|
|
|
|
/* Write \0 for Analysis Type string and \0 for empty Comment string */ |
|
|
|
|
|
|
|
|
|
|
|
tmp=0; |
|
|
|
|
|
fwrite((char *)&tmp,2,1,run->fp); |
|
|
|
|
|
i += 2; |
|
|
|
|
|
|
|
|
|
|
|
/* Write Program ID */ |
|
|
|
|
|
|
|
|
|
|
|
tmp=0x00011A22; |
|
|
|
|
|
fwrite((char *)&tmp,sizeof(tmp),1,run->fp); |
|
|
|
|
|
i += sizeof(tmp); |
|
|
|
|
|
|
|
|
|
|
|
/* Write All-Columns Flag */ |
|
|
|
|
|
|
|
|
|
|
|
tmp=0; |
|
|
|
|
|
fwrite((char *)&tmp,2,1,run->fp); |
|
|
|
|
|
i += 2; |
|
|
|
|
|
|
|
|
|
|
|
/* Write Complex-Data Flag */ |
|
|
|
|
|
|
|
|
|
|
|
tmp = run->isComplex ? 2 : 1; |
|
|
|
|
|
fwrite((char *)&tmp,2,1,run->fp); |
|
|
|
|
|
i += 2; |
|
|
|
|
|
|
|
|
|
|
|
/* Write Datatype Flag (PROBE_ANALOG) */ |
|
|
|
|
|
|
|
|
|
|
|
tmp = 0; |
|
|
|
|
|
fwrite((char *)&tmp,2,1,run->fp); |
|
|
|
|
|
i += 2; |
|
|
|
|
|
|
|
|
|
|
|
/* Write Digital Data Length (meaningless if analogue data) */ |
|
|
|
|
|
|
|
|
|
|
|
tmp=0; |
|
|
|
|
|
fwrite((char *)&tmp,sizeof(tmp),1,run->fp); |
|
|
|
|
|
i += sizeof(tmp); |
|
|
|
|
|
|
|
|
|
|
|
/* Write space for no. of rows */ |
|
|
|
|
|
|
|
|
|
|
|
fflush(run->fp); /* Gotta do this for LATTICE. */ |
|
|
fflush(run->fp); /* Gotta do this for LATTICE. */ |
|
|
if (run->fp == stdout || (run->pointPos = ftell(run->fp)) <= 0) |
|
|
if (run->fp == stdout || (run->pointPos = ftell(run->fp)) <= 0) |
|
|
run->pointPos = i; |
|
|
|
|
|
tmp=0; |
|
|
|
|
|
fwrite((char *)&tmp,sizeof(tmp),1,run->fp); |
|
|
|
|
|
i += sizeof(tmp); |
|
|
|
|
|
|
|
|
|
|
|
/* Write no. of cols */ |
|
|
|
|
|
|
|
|
|
|
|
fwrite(&(run->numData),2,1,run->fp); |
|
|
|
|
|
i += 2; |
|
|
|
|
|
#ifdef AlansFixes |
|
|
|
|
|
fprintf(stderr, "No. of Data Columns : %d \n", run->numData); |
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
/* Write Sweep Mode Flag */ |
|
|
|
|
|
|
|
|
|
|
|
fwrite((char *)&sweep,2,1,run->fp); |
|
|
|
|
|
i += 2; |
|
|
|
|
|
|
|
|
|
|
|
/* Write sweep variable start value */ |
|
|
|
|
|
|
|
|
|
|
|
ftmp=0; |
|
|
|
|
|
fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp); |
|
|
|
|
|
i += sizeof(ftmp); |
|
|
|
|
|
|
|
|
|
|
|
/* Write sweep variable end value */ |
|
|
|
|
|
|
|
|
|
|
|
ftmp=0; |
|
|
|
|
|
fwrite((char *)&ftmp,sizeof(ftmp),1,run->fp); |
|
|
|
|
|
i += sizeof(ftmp); |
|
|
|
|
|
|
|
|
|
|
|
/* Write Secondary Sweep Variable name (null string) */ |
|
|
|
|
|
|
|
|
run->pointPos = i; |
|
|
|
|
|
fprintf(run->fp, "0 \n"); /* Save 8 spaces here. */ |
|
|
|
|
|
|
|
|
tmp=0; |
|
|
|
|
|
fwrite((char *)&tmp,1,1,run->fp); |
|
|
|
|
|
i += 1; |
|
|
|
|
|
|
|
|
|
|
|
/* Write Digital Section Flag */ |
|
|
|
|
|
|
|
|
|
|
|
tmp = 0; |
|
|
|
|
|
fwrite((char *)&tmp,2,1,run->fp); |
|
|
|
|
|
i += 2; |
|
|
|
|
|
|
|
|
|
|
|
fflush(run->fp); /* Make sure this gets to disk */ |
|
|
|
|
|
|
|
|
fprintf(run->fp, "Command: version %s\n", ft_sim->version); |
|
|
|
|
|
fprintf(run->fp, "Variables:\n"); |
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void |
|
|
static void |
|
|
@ -819,90 +573,34 @@ fileInit_pass2(runDesc *run) |
|
|
{ |
|
|
{ |
|
|
int i, type; |
|
|
int i, type; |
|
|
char *name, buf[BSIZE_SP]; |
|
|
char *name, buf[BSIZE_SP]; |
|
|
char *ch, *end; |
|
|
|
|
|
int tmp; |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < run->numData; i++) { |
|
|
for (i = 0; i < run->numData; i++) { |
|
|
|
|
|
|
|
|
if ((run->data[i].regular == FALSE) || |
|
|
|
|
|
cieq(run->data[i].name, "time") || |
|
|
|
|
|
cieq(run->data[i].name, "sweep") || |
|
|
|
|
|
cieq(run->data[i].name, "frequency")) |
|
|
|
|
|
(void) sprintf(name, "%s", run->data[i].name); |
|
|
|
|
|
else |
|
|
|
|
|
(void) sprintf(name, "V(%s)", run->data[i].name); |
|
|
|
|
|
|
|
|
|
|
|
if (ch=strstr(name, "#branch")) { |
|
|
|
|
|
name[0]='I'; |
|
|
|
|
|
*ch++=')'; |
|
|
|
|
|
*ch='\0'; |
|
|
|
|
|
|
|
|
if (isdigit(*run->data[i].name)) { |
|
|
|
|
|
(void) sprintf(buf, "V(%s)", run->data[i].name); |
|
|
|
|
|
name = buf; |
|
|
|
|
|
} else { |
|
|
|
|
|
name = run->data[i].name; |
|
|
|
|
|
} |
|
|
|
|
|
if (substring("#branch", name)) |
|
|
type = SV_CURRENT; |
|
|
type = SV_CURRENT; |
|
|
} |
|
|
|
|
|
else if (cieq(name, "time")) |
|
|
else if (cieq(name, "time")) |
|
|
type = SV_TIME; |
|
|
type = SV_TIME; |
|
|
else if (cieq(name, "frequency")) |
|
|
else if (cieq(name, "frequency")) |
|
|
type = SV_FREQUENCY; |
|
|
type = SV_FREQUENCY; |
|
|
else |
|
|
else |
|
|
type = SV_VOLTAGE; |
|
|
type = SV_VOLTAGE; |
|
|
if (*name=='@') { |
|
|
|
|
|
type = SV_CURRENT; |
|
|
|
|
|
memmove(name, &name[1], strlen(name)-1); |
|
|
|
|
|
if ((ch=strchr(name, '['))!=NULL) { |
|
|
|
|
|
ch++; |
|
|
|
|
|
strncpy(buf, ch, BSIZE_SP); |
|
|
|
|
|
ch--; |
|
|
|
|
|
*ch='\0'; |
|
|
|
|
|
if ((ch=strchr(buf, ']'))!=NULL) *ch='\0'; |
|
|
|
|
|
strcat(buf, "("); |
|
|
|
|
|
if ((ch=strchr(name, ':'))!=NULL) { |
|
|
|
|
|
ch++; |
|
|
|
|
|
strncat(buf, ch, BSIZE_SP-strlen(buf)); |
|
|
|
|
|
ch--; |
|
|
|
|
|
*ch='\0'; |
|
|
|
|
|
if ((ch=strrchr(buf, ':'))!=NULL) { |
|
|
|
|
|
ch++; |
|
|
|
|
|
memmove(&ch[strlen(name)], ch, strlen(ch)+1); |
|
|
|
|
|
memmove(ch, name, strlen(name)); |
|
|
|
|
|
}; |
|
|
|
|
|
} else { |
|
|
|
|
|
strncat(buf, name, BSIZE_SP-strlen(buf)); |
|
|
|
|
|
}; |
|
|
|
|
|
strcat(buf, ")"); |
|
|
|
|
|
}; |
|
|
|
|
|
strncpy(name, buf, BSIZE_SP); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
while ((ch=strchr(name, ':'))!=NULL) |
|
|
|
|
|
*ch='.'; |
|
|
|
|
|
|
|
|
|
|
|
if ((ch=strchr(name, '('))!=NULL) { |
|
|
|
|
|
ch++; |
|
|
|
|
|
end=(char *)memchr(name, '\0', BSIZE_SP); |
|
|
|
|
|
while (strchr(ch, '.')!=NULL) { |
|
|
|
|
|
memmove(ch+1, ch, end-ch+1); |
|
|
|
|
|
end++; |
|
|
|
|
|
*ch='x'; |
|
|
|
|
|
ch=strchr(ch, '.'); |
|
|
|
|
|
ch++; |
|
|
|
|
|
}; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
fprintf(run->fp, "%s", name); |
|
|
|
|
|
tmp=0; |
|
|
|
|
|
fwrite((void *)&tmp,1,1,run->fp); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fflush(run->fp); /* Make all sure this gets to disk */ |
|
|
|
|
|
|
|
|
fprintf(run->fp, "\t%d\t%s\t%s", i, name, |
|
|
|
|
|
ft_typenames(type)); |
|
|
|
|
|
if (run->data[i].gtype == GRID_XLOG) |
|
|
|
|
|
fprintf(run->fp, "\tgrid=3"); |
|
|
|
|
|
fprintf(run->fp, "\n"); |
|
|
|
|
|
|
|
|
/* Allocate Row buffer */ |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
rowbuflen=(run->numData)*sizeof(float); |
|
|
|
|
|
if (run->isComplex) rowbuflen *=2; |
|
|
|
|
|
rowbuf=(float *)tmalloc(rowbuflen); |
|
|
|
|
|
|
|
|
fprintf(run->fp, "%s:\n", run->binary ? "Binary" : "Values"); |
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void |
|
|
static void |
|
|
@ -910,11 +608,6 @@ fileStartPoint(FILE *fp, bool bin, int num) |
|
|
{ |
|
|
{ |
|
|
if (!bin) |
|
|
if (!bin) |
|
|
fprintf(fp, "%d\t", num - 1); |
|
|
fprintf(fp, "%d\t", num - 1); |
|
|
|
|
|
|
|
|
/* reset set buffer pointer to zero */ |
|
|
|
|
|
|
|
|
|
|
|
column = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
@ -922,53 +615,23 @@ fileStartPoint(FILE *fp, bool bin, int num) |
|
|
static void |
|
|
static void |
|
|
fileAddRealValue(FILE *fp, bool bin, double value) |
|
|
fileAddRealValue(FILE *fp, bool bin, double value) |
|
|
{ |
|
|
{ |
|
|
if (bin) { |
|
|
|
|
|
if (value<(-FLT_MAX)) { |
|
|
|
|
|
fprintf(stderr, |
|
|
|
|
|
"Warning, double to float conversion overflow !\n"); |
|
|
|
|
|
rowbuf[column++]=(-FLT_MAX); |
|
|
|
|
|
} else if (value>(FLT_MAX)) { |
|
|
|
|
|
fprintf(stderr, |
|
|
|
|
|
"Warning, double to float conversion overflow !\n"); |
|
|
|
|
|
rowbuf[column++]=FLT_MAX; |
|
|
|
|
|
} else { |
|
|
|
|
|
rowbuf[column++]=value; |
|
|
|
|
|
}; |
|
|
|
|
|
} else |
|
|
|
|
|
fprintf(fp, "\t%.*e\n", DOUBLE_PRECISION, value); |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
if (bin) |
|
|
|
|
|
fwrite((char *) &value, sizeof (double), 1, fp); |
|
|
|
|
|
else |
|
|
|
|
|
fprintf(fp, "\t%.*e\n", DOUBLE_PRECISION, value); |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void |
|
|
static void |
|
|
fileAddComplexValue(FILE *fp, bool bin, IFcomplex value) |
|
|
fileAddComplexValue(FILE *fp, bool bin, IFcomplex value) |
|
|
{ |
|
|
{ |
|
|
|
|
|
|
|
|
if (bin) { |
|
|
|
|
|
if (value.real<(-FLT_MAX)) { |
|
|
|
|
|
fprintf(stderr, |
|
|
|
|
|
"Warning, double to float conversion overflow !\n"); |
|
|
|
|
|
rowbuf[column++]=(-FLT_MAX); |
|
|
|
|
|
} else if (value.real>(FLT_MAX)) { |
|
|
|
|
|
fprintf(stderr, |
|
|
|
|
|
"Warning, double to float conversion overflow !\n"); |
|
|
|
|
|
rowbuf[column++]=FLT_MAX; |
|
|
|
|
|
} else { |
|
|
|
|
|
rowbuf[column++]=value.real; |
|
|
|
|
|
}; |
|
|
|
|
|
if (value.imag<(-FLT_MAX)) { |
|
|
|
|
|
fprintf(stderr, |
|
|
|
|
|
"Warning, double to float conversion overflow !\n"); |
|
|
|
|
|
rowbuf[column++]=(-FLT_MAX); |
|
|
|
|
|
} else if (value.imag>(FLT_MAX)) { |
|
|
|
|
|
fprintf(stderr, |
|
|
|
|
|
"Warning, double to float conversion overflow !\n"); |
|
|
|
|
|
rowbuf[column++]=FLT_MAX; |
|
|
|
|
|
} else { |
|
|
|
|
|
rowbuf[column++]=value.imag; |
|
|
|
|
|
}; |
|
|
|
|
|
} else { |
|
|
|
|
|
fprintf(fp, "\t%.*e,%.*e\n", DOUBLE_PRECISION, value.real, |
|
|
|
|
|
|
|
|
if (bin) { |
|
|
|
|
|
fwrite((char *) &value.real, sizeof (double), 1, fp); |
|
|
|
|
|
fwrite((char *) &value.imag, sizeof (double), 1, fp); |
|
|
|
|
|
} else { |
|
|
|
|
|
fprintf(fp, "\t%.*e,%.*e\n", DOUBLE_PRECISION, value.real, |
|
|
DOUBLE_PRECISION, value.imag); |
|
|
DOUBLE_PRECISION, value.imag); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -978,8 +641,6 @@ fileAddComplexValue(FILE *fp, bool bin, IFcomplex value) |
|
|
static void |
|
|
static void |
|
|
fileEndPoint(FILE *fp, bool bin) |
|
|
fileEndPoint(FILE *fp, bool bin) |
|
|
{ |
|
|
{ |
|
|
/* write row buffer to file */ |
|
|
|
|
|
fwrite((char *)rowbuf, rowbuflen, 1, fp); |
|
|
|
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -989,30 +650,22 @@ static void |
|
|
fileEnd(runDesc *run) |
|
|
fileEnd(runDesc *run) |
|
|
{ |
|
|
{ |
|
|
long place; |
|
|
long place; |
|
|
int nrows; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (run->fp != stdout) { |
|
|
if (run->fp != stdout) { |
|
|
place = ftell(run->fp); |
|
|
|
|
|
fseek(run->fp, run->pointPos, 0); |
|
|
|
|
|
nrows=run->pointCount; |
|
|
|
|
|
fprintf(stderr, "\nNo. of Data Rows : %d\n", nrows); |
|
|
|
|
|
fwrite(&nrows,sizeof(nrows),1,run->fp); |
|
|
|
|
|
fseek(run->fp, place, 0); |
|
|
|
|
|
|
|
|
place = ftell(run->fp); |
|
|
|
|
|
fseek(run->fp, run->pointPos, 0); |
|
|
|
|
|
fprintf(run->fp, "%d", run->pointCount); |
|
|
|
|
|
fseek(run->fp, place, 0); |
|
|
} else { |
|
|
} else { |
|
|
/* Yet another hack-around */ |
|
|
|
|
|
fprintf(stderr, "@@@ %ld %d\n", run->pointPos, run->pointCount); |
|
|
|
|
|
|
|
|
/* Yet another hack-around */ |
|
|
|
|
|
fprintf(stderr, "@@@ %ld %d\n", run->pointPos, run->pointCount); |
|
|
} |
|
|
} |
|
|
fflush(run->fp); |
|
|
fflush(run->fp); |
|
|
|
|
|
|
|
|
/* deallocate row buffer */ |
|
|
|
|
|
|
|
|
|
|
|
tfree(rowbuf); |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The plot maintenance routines. */ |
|
|
/* The plot maintenance routines. */ |
|
|
|
|
|
|
|
|
@ -1116,7 +769,7 @@ plotEnd(runDesc *run) |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ParseSpecial takes something of the form "@name[param,index]" and rips |
|
|
/* ParseSpecial takes something of the form "@name[param,index]" and rips |
|
|
* out name, param, andstrchr. |
|
|
* out name, param, andstrchr. |
|
|
@ -1130,7 +783,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind) |
|
|
*dev = *param = *ind = '\0'; |
|
|
*dev = *param = *ind = '\0'; |
|
|
|
|
|
|
|
|
if (*name != '@') |
|
|
if (*name != '@') |
|
|
return FALSE; |
|
|
|
|
|
|
|
|
return (FALSE); |
|
|
name++; |
|
|
name++; |
|
|
|
|
|
|
|
|
s = dev; |
|
|
s = dev; |
|
|
@ -1138,7 +791,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind) |
|
|
*s++ = *name++; |
|
|
*s++ = *name++; |
|
|
*s = '\0'; |
|
|
*s = '\0'; |
|
|
if (!*name) |
|
|
if (!*name) |
|
|
return TRUE; |
|
|
|
|
|
|
|
|
return (TRUE); |
|
|
name++; |
|
|
name++; |
|
|
|
|
|
|
|
|
s = param; |
|
|
s = param; |
|
|
@ -1148,7 +801,7 @@ parseSpecial(char *name, char *dev, char *param, char *ind) |
|
|
if (*name == ']') |
|
|
if (*name == ']') |
|
|
return (!name[1] ? TRUE : FALSE); |
|
|
return (!name[1] ? TRUE : FALSE); |
|
|
else if (!*name) |
|
|
else if (!*name) |
|
|
return FALSE; |
|
|
|
|
|
|
|
|
return (FALSE); |
|
|
name++; |
|
|
name++; |
|
|
|
|
|
|
|
|
s = ind; |
|
|
s = ind; |
|
|
@ -1156,9 +809,9 @@ parseSpecial(char *name, char *dev, char *param, char *ind) |
|
|
*s++ = *name++; |
|
|
*s++ = *name++; |
|
|
*s = '\0'; |
|
|
*s = '\0'; |
|
|
if (*name && !name[1]) |
|
|
if (*name && !name[1]) |
|
|
return TRUE; |
|
|
|
|
|
|
|
|
return (TRUE); |
|
|
else |
|
|
else |
|
|
return FALSE; |
|
|
|
|
|
|
|
|
return (FALSE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* This routine must match two names with or without a V() around them. */ |
|
|
/* This routine must match two names with or without a V() around them. */ |
|
|
@ -1171,14 +824,14 @@ name_eq(char *n1, char *n2) |
|
|
if ((s =strchr(n1, '('))) { |
|
|
if ((s =strchr(n1, '('))) { |
|
|
strcpy(buf1, s); |
|
|
strcpy(buf1, s); |
|
|
if (!(s =strchr(buf1, ')'))) |
|
|
if (!(s =strchr(buf1, ')'))) |
|
|
return FALSE; |
|
|
|
|
|
|
|
|
return (FALSE); |
|
|
*s = '\0'; |
|
|
*s = '\0'; |
|
|
n1 = buf1; |
|
|
n1 = buf1; |
|
|
} |
|
|
} |
|
|
if ((s =strchr(n2, '('))) { |
|
|
if ((s =strchr(n2, '('))) { |
|
|
strcpy(buf2, s); |
|
|
strcpy(buf2, s); |
|
|
if (!(s =strchr(buf2, ')'))) |
|
|
if (!(s =strchr(buf2, ')'))) |
|
|
return FALSE; |
|
|
|
|
|
|
|
|
return (FALSE); |
|
|
*s = '\0'; |
|
|
*s = '\0'; |
|
|
n2 = buf2; |
|
|
n2 = buf2; |
|
|
} |
|
|
} |
|
|
@ -1197,24 +850,24 @@ getSpecial(dataDesc *desc, runDesc *run, IFvalue *val) |
|
|
desc->specName, &desc->specFast, ft_sim, &desc->type, |
|
|
desc->specName, &desc->specFast, ft_sim, &desc->type, |
|
|
&selector) == OK) { |
|
|
&selector) == OK) { |
|
|
desc->type &= (IF_REAL | IF_COMPLEX); /* mask out other bits */ |
|
|
desc->type &= (IF_REAL | IF_COMPLEX); /* mask out other bits */ |
|
|
return TRUE; |
|
|
|
|
|
|
|
|
return(TRUE); |
|
|
} else if ((vv = if_getstat(run->circuit, &desc->name[1]))) { |
|
|
} else if ((vv = if_getstat(run->circuit, &desc->name[1]))) { |
|
|
/* skip @ sign */ |
|
|
|
|
|
|
|
|
/* skip @ sign */ |
|
|
desc->type = IF_REAL; |
|
|
desc->type = IF_REAL; |
|
|
if (vv->va_type == VT_REAL) |
|
|
if (vv->va_type == VT_REAL) |
|
|
val->rValue = vv->va_real; |
|
|
|
|
|
|
|
|
val->rValue = vv->va_real; |
|
|
else if (vv->va_type == VT_NUM) |
|
|
else if (vv->va_type == VT_NUM) |
|
|
val->rValue = vv->va_num; |
|
|
|
|
|
|
|
|
val->rValue = vv->va_num; |
|
|
else if (vv->va_type == VT_BOOL) |
|
|
else if (vv->va_type == VT_BOOL) |
|
|
val->rValue = (vv->va_bool ? 1.0 : 0.0); |
|
|
|
|
|
|
|
|
val->rValue = (vv->va_bool ? 1.0 : 0.0); |
|
|
else { |
|
|
else { |
|
|
return FALSE; /* not a real */ |
|
|
|
|
|
|
|
|
return (FALSE); /* not a real */ |
|
|
} |
|
|
} |
|
|
tfree(vv); |
|
|
tfree(vv); |
|
|
return TRUE; |
|
|
|
|
|
|
|
|
return(TRUE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return FALSE; |
|
|
|
|
|
|
|
|
return (FALSE); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void |
|
|
static void |
|
|
@ -1272,8 +925,8 @@ OUTerror(int flags, char *format, IFuid *names) |
|
|
int nindex = 0; |
|
|
int nindex = 0; |
|
|
|
|
|
|
|
|
if ((flags == ERR_INFO) && cp_getvar("printinfo", VT_BOOL, |
|
|
if ((flags == ERR_INFO) && cp_getvar("printinfo", VT_BOOL, |
|
|
(char *) &printinfo)) |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
(char *) &printinfo)) |
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
for (m = msgs; m->flag; m++) |
|
|
for (m = msgs; m->flag; m++) |
|
|
if (flags & m->flag) |
|
|
if (flags & m->flag) |
|
|
@ -1281,10 +934,10 @@ OUTerror(int flags, char *format, IFuid *names) |
|
|
|
|
|
|
|
|
for (s = format, bptr = buf; *s; s++) { |
|
|
for (s = format, bptr = buf; *s; s++) { |
|
|
if (*s == '%' && (s == format || *(s-1) != '%') && *(s+1) == 's') { |
|
|
if (*s == '%' && (s == format || *(s-1) != '%') && *(s+1) == 's') { |
|
|
if (names[nindex]) |
|
|
|
|
|
strcpy(bptr, names[nindex]); |
|
|
|
|
|
else |
|
|
|
|
|
strcpy(bptr, "(null)"); |
|
|
|
|
|
|
|
|
if (names[nindex]) |
|
|
|
|
|
strcpy(bptr, names[nindex]); |
|
|
|
|
|
else |
|
|
|
|
|
strcpy(bptr, "(null)"); |
|
|
bptr += strlen(bptr); |
|
|
bptr += strlen(bptr); |
|
|
s++; |
|
|
s++; |
|
|
nindex++; |
|
|
nindex++; |
|
|
@ -1296,4 +949,4 @@ OUTerror(int flags, char *format, IFuid *names) |
|
|
fprintf(cp_err, "%s\n", buf); |
|
|
fprintf(cp_err, "%s\n", buf); |
|
|
fflush(cp_err); |
|
|
fflush(cp_err); |
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |