ngspice/src/xspice/mif/mifdelete.c

201 lines
6.0 KiB
C

/*============================================================================
FILE MIFdelete.c
MEMBER OF process XSPICE
Public Domain
Georgia Tech Research Corporation
Atlanta, Georgia 30332
PROJECT A-8503
AUTHORS
9/12/91 Bill Kuhn
MODIFICATIONS
<date> <person name> <nature of modifications>
SUMMARY
This file contains the function used by SPICE to delete an
instance and its allocated data structures from the internal
circuit description data structures.
INTERFACES
MIFdelete()
REFERENCED FILES
None.
NON-STANDARD FEATURES
None.
============================================================================*/
#include "ngspice/ngspice.h"
#include "ngspice/sperror.h"
#include "ngspice/gendefs.h"
#include "ngspice/mifproto.h"
#include "ngspice/mifdefs.h"
#include "ngspice/evt.h"
#if defined(_MSC_VER) || defined(__MINGW32__)
#include "ngspice/mifparse.h"
#endif
#include "ngspice/suffix.h"
#include "ngspice/devdefs.h"
/*
MIFdelete
This function deletes a particular instance from the linked list
of instance structures, freeing all dynamically allocated memory
used by the instance structure.
*/
int
MIFdelete(GENinstance *gen_inst)
{
int i;
int j;
int k;
int num_conn;
int num_port;
int num_inst_var;
MIFinstance *here = (MIFinstance *) gen_inst;
/*******************************************/
/* instance->callback(..., MIF_CB_DESTROY) */
/*******************************************/
if (here->callback) {
Mif_Private_t cm_data;
/* Prepare the structure to be passed to the code model */
cm_data.num_conn = here->num_conn;
cm_data.conn = here->conn;
cm_data.num_param = here->num_param;
cm_data.param = here->param;
cm_data.num_inst_var = here->num_inst_var;
cm_data.inst_var = here->inst_var;
cm_data.callback = &(here->callback);
here->callback(&cm_data, MIF_CB_DESTROY);
}
/*******************************/
/* Free the instance structure */
/*******************************/
/* Loop through all connections on the instance */
/* and dismantle the stuff allocated during readin/setup */
/* in MIFinit_inst, MIFget_port, and MIFsetup */
num_conn = here->num_conn;
for (i = 0; i < num_conn; i++) {
/* If connection never used, skip it */
if (here->conn[i]->is_null)
continue;
/* If analog output, lots to free... */
if (here->conn[i]->is_output && here->analog) {
num_port = here->conn[i]->size;
/* For each port on the connector */
for (j = 0; j < num_port; j++) {
/* Free the partial/ac_gain/smp stuff allocated in MIFsetup */
for (k = 0; k < num_conn; k++) {
if ((here->conn[k]->is_null) || (! here->conn[k]->is_input))
continue;
if (here->conn[i]->port[j]->partial)
FREE(here->conn[i]->port[j]->partial[k].port);
if (here->conn[i]->port[j]->ac_gain)
FREE(here->conn[i]->port[j]->ac_gain[k].port);
if (here->conn[i]->port[j]->smp_data.input)
FREE(here->conn[i]->port[j]->smp_data.input[k].port);
}
FREE(here->conn[i]->port[j]->partial);
FREE(here->conn[i]->port[j]->ac_gain);
FREE(here->conn[i]->port[j]->smp_data.input);
/* but don't free strings. They are either not owned */
/* by the inst or are part of tokens. SPICE3C1 never */
/* frees tokens, so we don't either... */
}
}
/* Free the basic port structure allocated in MIFget_port */
num_port = here->conn[i]->size;
for (j = 0; j < num_port; j++) {
Evt_Output_Event_t *evt;
/* Memory allocated in mif_inp2.c and evtload.c. */
FREE(here->conn[i]->port[j]->type_str);
evt = here->conn[i]->port[j]->next_event;
if (evt) {
FREE(evt->value);
FREE(evt);
}
FREE(here->conn[i]->port[j]);
}
FREE(here->conn[i]->port);
}
/* Free the connector stuff allocated in MIFinit_inst */
/* Don't free name/description! They are not owned */
/* by the instance */
for (i = 0; i < num_conn; i++) {
FREE(here->conn[i]);
}
FREE(here->conn);
/* Loop through all instance variables on the instance */
/* and free stuff */
num_inst_var = here->num_inst_var;
for (i = 0; i < num_inst_var; i++) {
if (here->inst_var[i]->element != NULL) {
/* Do not delete inst_var[i]->element if MS Windows and is_array==1.
Memory is then allocated in the code model dll, and it cannot be
guaranteed that it can be freed safely here! A small memory leak is created.
FIXME
Finally one has to free the memory in the same module where allocated. */
#if defined(_MSC_VER) || defined(__MINGW32__)
if (!DEVices[MIFmodPtr(here)->MIFmodType]->DEVpublic.inst_var[i].is_array)
#endif
FREE(here->inst_var[i]->element);
}
FREE(here->inst_var[i]);
}
FREE(here->inst_var);
/* ************************************************************* */
/* Dont free params here. They are not currently implemented on */
/* a per-instance basis, so their allocated space is owned by */
/* the parent model, not the instance. Param stuff will be freed */
/* by MIFmDelete */
/* ************************************************************* */
/* Free the stuff used by the cm_... functions */
if (here->num_state && here->state)
FREE(here->state);
if (here->num_intgr && here->intgr)
FREE(here->intgr);
if (here->num_conv && here->conv)
FREE(here->conv);
MIF_free_noise_state(here);
return OK;
}