XSPICE filesource: remove segfault with op before tran

This commit is contained in:
h_vogt 2012-09-07 23:48:09 +02:00
parent 9de9336581
commit 5ce51f148e
2 changed files with 153 additions and 120 deletions

View File

@ -11,6 +11,7 @@ Thomas Sailer
AUTHORS
20 May 2011 Thomas Sailer
03 Sep 2012 Holger Vogt
MODIFICATIONS
@ -19,7 +20,8 @@ MODIFICATIONS
SUMMARY
This file contains the model-specific routines used to
functionally describe the gain code model.
functionally describe the file source code model used
to read an array of analog values per time step from a file.
INTERFACES
@ -55,18 +57,38 @@ NON-STANDARD FEATURES
/*=== MACROS ===========================*/
#if defined(__MINGW32__) || defined(_MSC_VER)
#define DIR_PATHSEP "\\"
#define DIR_PATHSEP "\\"
#else
#define DIR_PATHSEP "/"
#define DIR_PATHSEP "/"
#endif
#if defined(_MSC_VER)
#define strdup _strdup
#define snprintf _snprintf
#endif
/*=== LOCAL VARIABLES & TYPEDEFS =======*/
struct filesource_state {
FILE *fp;
long pos;
unsigned char atend;
FILE *fp;
long pos;
unsigned char atend;
};
typedef struct {
double *amplinterval; /* the storage array for the
amplitude offsets */
double *timeinterval; /* the storage array for the
time offset */
struct filesource_state *state; /* the storage array for the
filesource status. */
} Local_Data_t;
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/
@ -76,19 +98,19 @@ struct filesource_state {
/*==============================================================================
FUNCTION void cm_gain()
FUNCTION void cm_filesource()
AUTHORS
2 Oct 1991 Jeffrey P. Murray
20 May 2011 Thomas Sailer
MODIFICATIONS
NONE
07 Sept 2012 Holger Vogt
SUMMARY
This function implements the gain code model.
This function implements the filesource code model.
INTERFACES
@ -117,121 +139,125 @@ NON-STANDARD FEATURES
void cm_filesource(ARGS) /* structure holding parms, inputs, outputs, etc. */
{
int size;
int amplscalesize;
int amploffssize;
double *timeinterval;
double *amplinterval;
struct filesource_state *state;
int size;
int amplscalesize;
int amploffssize;
if(ANALYSIS == MIF_AC) {
return;
}
size = PORT_SIZE(out);
if (INIT == 1) {
/* Allocate storage for internal state */
cm_analog_alloc(0, 2 * sizeof(double));
cm_analog_alloc(1, size * (int) (2 * sizeof(double)));
cm_analog_alloc(2, sizeof(struct filesource_state));
}
timeinterval = (double *)cm_analog_get_ptr(0, 0);
amplinterval = (double *)cm_analog_get_ptr(1, 0);
state = (struct filesource_state *)cm_analog_get_ptr(2, 0);
if (INIT == 1) {
int i;
timeinterval[0] = timeinterval[1] = PARAM_NULL(timeoffset) ? 0.0 : PARAM(timeoffset);
for (i = 0; i < size; ++i)
amplinterval[2 * i] = amplinterval[2 * i + 1] = PARAM_NULL(amploffset) ? 0.0 : PARAM(amploffset[i]);
state->fp = fopen(PARAM(file), "r");
state->pos = 0;
state->atend = 0;
if (!state->fp) {
char *lbuffer, *p;
Local_Data_t *loc; /* Pointer to local static data, not to be included
in the state vector */
if(ANALYSIS == MIF_AC) {
return;
}
size = PORT_SIZE(out);
if (INIT == 1) {
int i;
/*** allocate static storage for *loc ***/
STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t ));
loc = STATIC_VAR (locdata);
/* Allocate storage for internal state */
loc->timeinterval = (double*)calloc(2, sizeof(double));
loc->amplinterval = (double*)calloc(2 * size, sizeof(double));
loc->state = (struct filesource_state*)malloc(sizeof(struct filesource_state));
loc->timeinterval[0] = loc->timeinterval[1] = PARAM_NULL(timeoffset) ? 0.0 : PARAM(timeoffset);
for (i = 0; i < size; ++i)
loc->amplinterval[2 * i] = loc->amplinterval[2 * i + 1] = PARAM_NULL(amploffset) ? 0.0 : PARAM(amploffset[i]);
loc->state->fp = fopen(PARAM(file), "r");
loc->state->pos = 0;
loc->state->atend = 0;
if (!loc->state->fp) {
char *lbuffer, *p;
lbuffer = getenv("NGSPICE_INPUT_DIR");
if (lbuffer && *lbuffer) {
p = (char*) malloc(strlen(lbuffer) + strlen(DIR_PATHSEP) + strlen(PARAM(file)) + 1);
sprintf(p, "%s%s%s", lbuffer, DIR_PATHSEP, PARAM(file));
state->fp = fopen(p, "r");
loc->state->fp = fopen(p, "r");
free(p);
}
if (!state->fp) {
char msg[512];
snprintf(msg, sizeof(msg), "cannot open file %s", PARAM(file));
cm_message_send(msg);
state->atend = 1;
}
}
}
amplscalesize = PARAM_NULL(amplscale) ? 0 : PARAM_SIZE(amplscale);
amploffssize = PARAM_NULL(amploffset) ? 0 : PARAM_SIZE(amploffset);
while (TIME >= timeinterval[1] && !state->atend) {
char line[512];
char *cp, *cpdel;
char *cp2;
double t;
int i;
if (ftell(state->fp) != state->pos) {
clearerr(state->fp);
fseek(state->fp, state->pos, SEEK_SET);
}
if (!fgets(line, sizeof(line), state->fp)) {
state->atend = 1;
break;
}
state->pos = ftell(state->fp);
cpdel = cp = strdup(line);
while (*cp && isspace(*cp))
++cp;
if (*cp == '#' || *cp == ';') {
free(cpdel);
continue;
}
t = strtod(cp, &cp2);
if (cp2 == cp) {
free(cpdel);
continue;
}
cp = cp2;
if (!PARAM_NULL(timescale))
t *= PARAM(timescale);
if (!PARAM_NULL(timerelative) && PARAM(timerelative) == MIF_TRUE)
t += timeinterval[1];
else if (!PARAM_NULL(timeoffset))
t += PARAM(timeoffset);
timeinterval[0] = timeinterval[1];
timeinterval[1] = t;
for (i = 0; i < size; ++i)
amplinterval[2 * i] = amplinterval[2 * i + 1];
for (i = 0; i < size; ++i) {
while (*cp && (isspace(*cp) || *cp == ','))
++cp;
t = strtod(cp, &cp2);
if (cp2 == cp)
break;
cp = cp2;
if (i < amplscalesize)
t *= PARAM(amplscale[i]);
if (i < amploffssize)
t += PARAM(amploffset[i]);
amplinterval[2 * i + 1] = t;
}
free(cpdel);
}
if (TIME < timeinterval[1] && timeinterval[0] < timeinterval[1] && 0.0 <= timeinterval[0]) {
if (!PARAM_NULL(amplstep) && PARAM(amplstep) == MIF_TRUE) {
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = amplinterval[2 * i];
} else {
double mul0 = (timeinterval[1] - TIME) / (timeinterval[1] - timeinterval[0]);
double mul1 = 1.0 - mul0;
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = mul0 * amplinterval[2 * i] + mul1 * amplinterval[2 * i + 1];
}
} else {
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = amplinterval[2 * i + 1];
}
if (!loc->state->fp) {
char msg[512];
snprintf(msg, sizeof(msg), "cannot open file %s", PARAM(file));
cm_message_send(msg);
loc->state->atend = 1;
}
}
}
amplscalesize = PARAM_NULL(amplscale) ? 0 : PARAM_SIZE(amplscale);
amploffssize = PARAM_NULL(amploffset) ? 0 : PARAM_SIZE(amploffset);
loc = STATIC_VAR (locdata);
while (TIME >= loc->timeinterval[1] && !loc->state->atend) {
char line[512];
char *cp, *cpdel;
char *cp2;
double t;
int i;
if (ftell(loc->state->fp) != loc->state->pos) {
clearerr(loc->state->fp);
fseek(loc->state->fp, loc->state->pos, SEEK_SET);
}
if (!fgets(line, sizeof(line), loc->state->fp)) {
loc->state->atend = 1;
break;
}
loc->state->pos = ftell(loc->state->fp);
cpdel = cp = strdup(line);
while (*cp && isspace(*cp))
++cp;
if (*cp == '#' || *cp == ';') {
free(cpdel);
continue;
}
t = strtod(cp, &cp2);
if (cp2 == cp) {
free(cpdel);
continue;
}
cp = cp2;
if (!PARAM_NULL(timescale))
t *= PARAM(timescale);
if (!PARAM_NULL(timerelative) && PARAM(timerelative) == MIF_TRUE)
t += loc->timeinterval[1];
else if (!PARAM_NULL(timeoffset))
t += PARAM(timeoffset);
loc->timeinterval[0] = loc->timeinterval[1];
loc->timeinterval[1] = t;
for (i = 0; i < size; ++i)
loc->amplinterval[2 * i] = loc->amplinterval[2 * i + 1];
for (i = 0; i < size; ++i) {
while (*cp && (isspace(*cp) || *cp == ','))
++cp;
t = strtod(cp, &cp2);
if (cp2 == cp)
break;
cp = cp2;
if (i < amplscalesize)
t *= PARAM(amplscale[i]);
if (i < amploffssize)
t += PARAM(amploffset[i]);
loc->amplinterval[2 * i + 1] = t;
}
free(cpdel);
}
if (TIME < loc->timeinterval[1] && loc->timeinterval[0] < loc->timeinterval[1] && 0.0 <= loc->timeinterval[0]) {
if (!PARAM_NULL(amplstep) && PARAM(amplstep) == MIF_TRUE) {
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = loc->amplinterval[2 * i];
} else {
double mul0 = (loc->timeinterval[1] - TIME) / (loc->timeinterval[1] - loc->timeinterval[0]);
double mul1 = 1.0 - mul0;
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = mul0 * loc->amplinterval[2 * i] + mul1 * loc->amplinterval[2 * i + 1];
}
} else {
int i;
for (i = 0; i < size; ++i)
OUTPUT(out[i]) = loc->amplinterval[2 * i + 1];
}
}

View File

@ -80,3 +80,10 @@ Limits: -
Vector: no
Vector_Bounds: -
Null_Allowed: yes
STATIC_VAR_TABLE:
Static_Var_Name: locdata
Description: "local static data"
Data_Type: pointer