diff --git a/src/include/ngspice/evtproto.h b/src/include/ngspice/evtproto.h
index 813813a6d..41cddde1d 100644
--- a/src/include/ngspice/evtproto.h
+++ b/src/include/ngspice/evtproto.h
@@ -66,6 +66,8 @@ void EVTtermInsert(
int EVTsetup(CKTcircuit *ckt);
+int EVTdest(Evt_Ckt_Data_t *evt);
+
int EVTiter(CKTcircuit *ckt);
void EVTbackup(CKTcircuit *ckt, double new_time);
diff --git a/src/spicelib/analysis/cktdest.c b/src/spicelib/analysis/cktdest.c
index f7fea2805..b2c5331f9 100644
--- a/src/spicelib/analysis/cktdest.c
+++ b/src/spicelib/analysis/cktdest.c
@@ -16,8 +16,7 @@ Author: 1985 Thomas L. Quarles
#include "ngspice/sperror.h"
#ifdef XSPICE
-#include "ngspice/evt.h"
-static int evt_dest(Evt_Ckt_Data_t *evt);
+#include "ngspice/evtproto.h"
#endif
int
@@ -70,7 +69,7 @@ CKTdestroy(CKTcircuit *ckt)
FREE(ckt->CKThead);
#ifdef XSPICE
- evt_dest(ckt->evt);
+ EVTdest(ckt->evt);
FREE(ckt->enh);
FREE(ckt->evt);
#endif
@@ -80,201 +79,3 @@ CKTdestroy(CKTcircuit *ckt)
FREE(ckt);
return(OK);
}
-
-#ifdef XSPICE
-static int
-evt_dest(Evt_Ckt_Data_t *evt)
-{
- int i;
-
- /* Get temporary pointers for fast access */
- Evt_Output_Queue_t *output_queue;
- Evt_Node_Queue_t *node_queue;
- Evt_Inst_Queue_t *inst_queue;
-
- Evt_Output_Info_t **output_table;
- Evt_Node_Info_t **node_table;
- Evt_Port_Info_t **port_table;
-
- Evt_State_Data_t *state_data;
- Evt_State_t *statenext, *state;
-
- Evt_Node_Data_t *node_data;
- Evt_Node_t *rhs, *rhsnext;
-
- Evt_Node_t *node, *nodenext;
-
- Evt_Msg_Data_t *msg_data;
- Evt_Msg_t *msg, *msgnext;
-
- Evt_Inst_Event_t *here;
- Evt_Inst_Event_t *next;
-
- Evt_Output_Event_t *outhere;
- Evt_Output_Event_t *outnext;
-
- /* Exit immediately if no event-driven instances in circuit */
- if (evt->counts.num_insts == 0)
- return(OK);
-
- output_queue = &(evt->queue.output);
- node_queue = &(evt->queue.node);
- inst_queue = &(evt->queue.inst);
-
- output_table = evt->info.output_table;
- node_table = evt->info.node_table;
- port_table = evt->info.port_table;
-
- node_data = evt->data.node;
-
- state_data = evt->data.state;
- msg_data = evt->data.msg;
-
- /* instance queue */
- for (i = 0; i < evt->counts.num_insts; i++) {
- here = inst_queue->head[i];
- while (here) {
- next = here->next;
- tfree(here);
- here = next;
- }
- }
- tfree(inst_queue->head);
- tfree(inst_queue->current);
- tfree(inst_queue->last_step);
- tfree(inst_queue->free);
-
- tfree(inst_queue->modified_index);
- tfree(inst_queue->modified);
- tfree(inst_queue->pending_index);
- tfree(inst_queue->pending);
- tfree(inst_queue->to_call_index);
- tfree(inst_queue->to_call);
-
- /* node queue */
-
- tfree(node_queue->to_eval_index);
- tfree(node_queue->to_eval);
- tfree(node_queue->changed_index);
- tfree(node_queue->changed);
-
- /* output queue */
- for (i = 0; i < evt->counts.num_outputs; i++) {
- outhere = output_queue->head[i];
- while (outhere) {
- outnext = outhere->next;
- tfree(outhere);
- outhere = outnext;
- }
- }
- tfree(output_queue->head);
- tfree(output_queue->current);
- tfree(output_queue->last_step);
- tfree(output_queue->free);
-
- tfree(output_queue->modified_index);
- tfree(output_queue->modified);
- tfree(output_queue->pending_index);
- tfree(output_queue->pending);
- tfree(output_queue->changed_index);
- tfree(output_queue->changed);
-
- /* state data */
- /* only if digital states are there */
- if (state_data) {
- for (i = 0; i < evt->counts.num_insts; i++) {
- state = state_data->head[i];
- while (state) {
- statenext = state->next;
- tfree(state->block);
- tfree(state);
- state = statenext;
- }
- }
-
- tfree(state_data->head);
- tfree(state_data->tail);
- tfree(state_data->last_step);
- tfree(state_data->free);
-
- tfree(state_data->modified);
- tfree(state_data->modified_index);
- tfree(state_data->total_size);
- /* FIXME: more on desc ? */
- tfree(state_data->desc);
- }
-
- /* node data */
- /* only if digital nodes are there */
- if (node_data) {
- for (i = 0; i < evt->counts.num_nodes; i++) {
- node = node_data->head[i];
- while (node) {
- nodenext = node->next;
- tfree(node);
- node = nodenext;
- }
- }
- tfree(node_data->head);
- tfree(node_data->tail);
- tfree(node_data->last_step);
- tfree(node_data->free);
-
- tfree(node_data->modified);
- tfree(node_data->modified_index);
-
- for (i = 0; i < evt->counts.num_nodes; i++) {
- rhs = &(node_data->rhs[i]);
- while (rhs) {
- rhsnext = rhs->next;
- tfree(rhs->inverted_value);
- tfree(rhs->output_value);
- tfree(rhs->node_value);
- rhs = rhsnext;
- }
- }
- tfree(node_data->rhs);
- for (i = 0; i < evt->counts.num_nodes; i++) {
- rhs = &(node_data->rhsold[i]);
- while (rhs) {
- rhsnext = rhs->next;
- tfree(rhs->inverted_value);
- tfree(rhs->output_value);
- tfree(rhs->node_value);
- rhs = rhsnext;
- }
- }
- tfree(node_data->rhsold);
- tfree(node_data->total_load);
- }
-
- /* msg data */
-
- if (msg_data) {
- for (i = 0; i < evt->counts.num_ports; i++) {
- msg = msg_data->head[i];
- while (msg) {
- msgnext = msg->next;
- tfree(msg);
- msg = msgnext;
- }
- }
-
- tfree(msg_data->head);
- tfree(msg_data->tail);
- tfree(msg_data->last_step);
- tfree(msg_data->free);
-
- tfree(msg_data->modified);
- tfree(msg_data->modified_index);
- }
-
- /* still to care for :
- * output_table
- * node_table
- * port_table
- */
-
- return(OK);
-}
-#endif
diff --git a/src/xspice/evt/Makefile.am b/src/xspice/evt/Makefile.am
index 9eba09fe2..827f9e614 100644
--- a/src/xspice/evt/Makefile.am
+++ b/src/xspice/evt/Makefile.am
@@ -13,6 +13,7 @@ libevtxsp_la_SOURCES = \
evtop.c \
evtprint.c \
evtsetup.c \
+ evtdest.c \
evtbackup.c \
evtdeque.c \
evtinit.c \
diff --git a/src/xspice/evt/evtdest.c b/src/xspice/evt/evtdest.c
new file mode 100644
index 000000000..7dae8340c
--- /dev/null
+++ b/src/xspice/evt/evtdest.c
@@ -0,0 +1,320 @@
+#include "ngspice/ngspice.h"
+#include "ngspice/iferrmsg.h"
+
+#include "ngspice/evt.h"
+#include "ngspice/evtproto.h"
+
+
+static void Evt_Node_destroy(Evt_Node_Info_t *info, Evt_Node_t *node);
+static void Evt_Node_Data_destroy(Evt_Ckt_Data_t *evt, Evt_Node_Data_t *node_data);
+static void Evt_Msg_Data_destroy(Evt_Ckt_Data_t *evt, Evt_Msg_Data_t *msg_data);
+static void Evt_Queue_destroy(Evt_Ckt_Data_t *evt, Evt_Queue_t *queue);
+static void Evt_State_Data_destroy(Evt_Ckt_Data_t *evt, Evt_State_Data_t *state_data);
+static void Evt_Data_destroy(Evt_Ckt_Data_t *evt, Evt_Data_t *data);
+static void Evt_Job_destroy(Evt_Job_t *job);
+static void Evt_Info_destroy(Evt_Info_t *info);
+
+
+int
+EVTdest(Evt_Ckt_Data_t *evt)
+{
+ /* Exit immediately if no event-driven instances in circuit */
+ if (evt->counts.num_insts == 0)
+ return OK;
+
+ Evt_Queue_destroy(evt, & evt->queue);
+ Evt_Data_destroy(evt, & evt->data);
+ Evt_Job_destroy(& evt->jobs);
+ Evt_Info_destroy(& evt->info);
+
+ return OK;
+}
+
+
+static void
+Evt_Queue_destroy(Evt_Ckt_Data_t *evt, Evt_Queue_t *queue)
+{
+ Evt_Output_Queue_t *output_queue = &(queue->output);
+ Evt_Node_Queue_t *node_queue = &(queue->node);
+ Evt_Inst_Queue_t *inst_queue = &(queue->inst);
+
+ int i;
+
+ /* instance queue */
+ for (i = 0; i < evt->counts.num_insts; i++) {
+ Evt_Inst_Event_t *event = inst_queue->head[i];
+ while (event) {
+ Evt_Inst_Event_t *next = event->next;
+ tfree(event);
+ event = next;
+ }
+ }
+ tfree(inst_queue->head);
+ tfree(inst_queue->current);
+ tfree(inst_queue->last_step);
+ tfree(inst_queue->free);
+
+ tfree(inst_queue->modified_index);
+ tfree(inst_queue->modified);
+ tfree(inst_queue->pending_index);
+ tfree(inst_queue->pending);
+ tfree(inst_queue->to_call_index);
+ tfree(inst_queue->to_call);
+
+ /* node queue */
+
+ tfree(node_queue->to_eval_index);
+ tfree(node_queue->to_eval);
+ tfree(node_queue->changed_index);
+ tfree(node_queue->changed);
+
+ /* output queue */
+ for (i = 0; i < evt->counts.num_outputs; i++) {
+ Evt_Output_Event_t *event;
+ event = output_queue->head[i];
+ while (event) {
+ Evt_Output_Event_t *next = event->next;
+ tfree(event->value);
+ tfree(event);
+ event = next;
+ }
+ event = output_queue->free[i];
+ while (event) {
+ Evt_Output_Event_t *next = event->next;
+ tfree(event->value);
+ tfree(event);
+ event = next;
+ }
+ }
+ tfree(output_queue->head);
+ tfree(output_queue->current);
+ tfree(output_queue->last_step);
+ tfree(output_queue->free);
+
+ tfree(output_queue->modified_index);
+ tfree(output_queue->modified);
+ tfree(output_queue->pending_index);
+ tfree(output_queue->pending);
+ tfree(output_queue->changed_index);
+ tfree(output_queue->changed);
+}
+
+
+static void
+Evt_Data_destroy(Evt_Ckt_Data_t *evt, Evt_Data_t *data)
+{
+ Evt_State_Data_destroy(evt, data->state);
+ Evt_Node_Data_destroy(evt, data->node);
+ Evt_Msg_Data_destroy(evt, data->msg);
+
+ tfree(data->node);
+ tfree(data->state);
+ tfree(data->msg);
+ tfree(data->statistics);
+}
+
+
+static void
+Evt_State_Data_destroy(Evt_Ckt_Data_t *evt, Evt_State_Data_t *state_data)
+{
+ int i;
+
+ if (!state_data)
+ return;
+
+ for (i = 0; i < evt->counts.num_insts; i++) {
+ Evt_State_t *state = state_data->head[i];
+ while (state) {
+ Evt_State_t *next = state->next;
+ tfree(state->block);
+ tfree(state);
+ state = next;
+ }
+ }
+
+ tfree(state_data->head);
+ tfree(state_data->tail);
+ tfree(state_data->last_step);
+ tfree(state_data->free);
+
+ tfree(state_data->modified);
+ tfree(state_data->modified_index);
+ tfree(state_data->total_size);
+
+ for (i = 0; i < evt->counts.num_insts; i++) {
+ Evt_State_Desc_t *p = state_data->desc[i];
+ while (p) {
+ Evt_State_Desc_t *next_p = p->next;
+ tfree(p);
+ p = next_p;
+ }
+ }
+
+ tfree(state_data->desc);
+}
+
+
+static void
+Evt_Node_Data_destroy(Evt_Ckt_Data_t *evt, Evt_Node_Data_t *node_data)
+{
+ int i;
+
+ if (!node_data)
+ return;
+
+ for (i = 0; i < evt->counts.num_nodes; i++) {
+ Evt_Node_Info_t *info = evt->info.node_table[i];
+ Evt_Node_t *node;
+ node = node_data->head[i];
+ while (node) {
+ Evt_Node_t *next = node->next;
+ Evt_Node_destroy(info, node);
+ tfree(node);
+ node = next;
+ }
+ node = node_data->free[i];
+ while (node) {
+ Evt_Node_t *next = node->next;
+ Evt_Node_destroy(info, node);
+ tfree(node);
+ node = next;
+ }
+ }
+ tfree(node_data->head);
+ tfree(node_data->tail);
+ tfree(node_data->last_step);
+ tfree(node_data->free);
+
+ tfree(node_data->modified);
+ tfree(node_data->modified_index);
+
+ for (i = 0; i < evt->counts.num_nodes; i++) {
+ Evt_Node_Info_t *info = evt->info.node_table[i];
+ Evt_Node_destroy(info, &(node_data->rhs[i]));
+ Evt_Node_destroy(info, &(node_data->rhsold[i]));
+ }
+
+ tfree(node_data->rhs);
+ tfree(node_data->rhsold);
+ tfree(node_data->total_load);
+}
+
+
+static void
+Evt_Node_destroy(Evt_Node_Info_t *info, Evt_Node_t *node)
+{
+ tfree(node->node_value);
+ tfree(node->inverted_value);
+
+ if (node->output_value) {
+ int k = info->num_outputs;
+ while (--k >= 0)
+ tfree(node->output_value[k]);
+ tfree(node->output_value);
+ }
+}
+
+
+static void
+Evt_Msg_Data_destroy(Evt_Ckt_Data_t *evt, Evt_Msg_Data_t *msg_data)
+{
+ int i;
+
+ if (!msg_data)
+ return;
+
+ for (i = 0; i < evt->counts.num_ports; i++) {
+ Evt_Msg_t *msg;
+ msg = msg_data->head[i];
+ while (msg) {
+ Evt_Msg_t *next = msg->next;
+ if (msg->text)
+ tfree(msg->text);
+ tfree(msg);
+ msg = next;
+ }
+ msg = msg_data->free[i];
+ while (msg) {
+ Evt_Msg_t *next = msg->next;
+ if (msg->text)
+ tfree(msg->text);
+ tfree(msg);
+ msg = next;
+ }
+ }
+
+ tfree(msg_data->head);
+ tfree(msg_data->tail);
+ tfree(msg_data->last_step);
+ tfree(msg_data->free);
+
+ tfree(msg_data->modified);
+ tfree(msg_data->modified_index);
+}
+
+
+static void
+Evt_Job_destroy(Evt_Job_t *job)
+{
+ int i;
+
+ for (i = 0; i < job->num_jobs; i++)
+ tfree(job->job_name[i]);
+
+ tfree(job->job_name);
+ tfree(job->node_data);
+ tfree(job->state_data);
+ tfree(job->msg_data);
+ tfree(job->statistics);
+}
+
+
+static void
+Evt_Info_destroy(Evt_Info_t *info)
+{
+ Evt_Inst_Info_t *inst = info->inst_list;
+ while (inst) {
+ Evt_Inst_Info_t *next_inst = inst->next;
+ tfree(inst);
+ inst = next_inst;
+ }
+ tfree(info->inst_table);
+
+ Evt_Node_Info_t *nodei = info->node_list;
+ while (nodei) {
+ Evt_Node_Info_t *next_nodei = nodei->next;
+ tfree(nodei->name);
+
+ Evt_Inst_Index_t *p = nodei->inst_list;
+ while (p) {
+ Evt_Inst_Index_t *next_p = p->next;
+ tfree(p);
+ p = next_p;
+ }
+
+ tfree(nodei);
+ nodei = next_nodei;
+ }
+ tfree(info->node_table);
+
+ Evt_Port_Info_t *port = info->port_list;
+ while (port) {
+ Evt_Port_Info_t *next_port = port->next;
+ tfree(port->node_name);
+ tfree(port->inst_name);
+ tfree(port->conn_name);
+ tfree(port);
+ port = next_port;
+ }
+ tfree(info->port_table);
+
+ Evt_Output_Info_t *output = info->output_list;
+ while (output) {
+ Evt_Output_Info_t *next_output = output->next;
+ tfree(output);
+ output = next_output;
+ }
+ tfree(info->output_table);
+
+ tfree(info->hybrid_index);
+}
diff --git a/src/xspice/evt/evtload.c b/src/xspice/evt/evtload.c
index d4ace6f19..ca6b718b6 100644
--- a/src/xspice/evt/evtload.c
+++ b/src/xspice/evt/evtload.c
@@ -443,6 +443,8 @@ static void EVTadd_msg(
if(msg_data->free[port_index]) {
*msg_ptr = msg_data->free[port_index];
msg_data->free[port_index] = msg_data->free[port_index]->next;
+ if ((*msg_ptr)->text)
+ tfree((*msg_ptr)->text);
}
else {
*msg_ptr = TMALLOC(Evt_Msg_t, 1);
diff --git a/visualc/sharedspice.vcxproj b/visualc/sharedspice.vcxproj
index 1be1a5c07..cd1e2b954 100644
--- a/visualc/sharedspice.vcxproj
+++ b/visualc/sharedspice.vcxproj
@@ -2125,6 +2125,7 @@
+
diff --git a/visualc/vngspice-fftw.vcxproj b/visualc/vngspice-fftw.vcxproj
index 6e0e82d11..42f1425ea 100644
--- a/visualc/vngspice-fftw.vcxproj
+++ b/visualc/vngspice-fftw.vcxproj
@@ -2743,6 +2743,7 @@ lib /machine:x64 /def:..\..\fftw-3.3.4-dll64\libfftw3-3.def /out:$(IntDir)libfft
+
diff --git a/visualc/vngspice.vcxproj b/visualc/vngspice.vcxproj
index f904d3e8c..9f2c9b403 100644
--- a/visualc/vngspice.vcxproj
+++ b/visualc/vngspice.vcxproj
@@ -2709,6 +2709,7 @@
+