1132 lines
38 KiB
C
1132 lines
38 KiB
C
/************************************************************************/
|
||
/* SISCO SOFTWARE MODULE HEADER *****************************************/
|
||
/************************************************************************/
|
||
/* (c) Copyright Systems Integration Specialists Company, Inc., */
|
||
/* 1998 - 2005, All Rights Reserved */
|
||
/* */
|
||
/* MODULE NAME : mvl_obj.c */
|
||
/* PRODUCT(S) : MMSEASE-LITE */
|
||
/* */
|
||
/* MODULE DESCRIPTION : */
|
||
/* */
|
||
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
|
||
/* mvl_vmd_dom_add */
|
||
/* mvl_vmd_var_add */
|
||
/* mvl_vmd_nvl_add */
|
||
/* mvl_vmd_jou_add */
|
||
/* mvl_vmd_dom_remove */
|
||
/* mvl_vmd_var_remove */
|
||
/* mvl_vmd_nvl_remove */
|
||
/* mvl_vmd_jou_remove */
|
||
/* mvl_nvl_create */
|
||
/* mvl_nvl_destroy */
|
||
/* mvl_vmd_create */
|
||
/* mvl_vmd_destroy */
|
||
/* */
|
||
/* MODIFICATION LOG : */
|
||
/* Date Who Rev Comments */
|
||
/* -------- --- ------ ------------------------------------------- */
|
||
/* 02/26/08 JRB 28 mvl_vmd_destroy: do NOT free var->data (do */
|
||
/* not know if it was allocated). */
|
||
/* Check var or NVL is deletable before delete. */
|
||
/* mvl_vmd_dom_remove: remove dom objects first.*/
|
||
/* mvl_dom_destroy: do NOT remove dom objects. */
|
||
/* Add mvl_var_add_alloc, mvl_var_create_alloc. */
|
||
/* Add mvl_var_create_derived. */
|
||
/* Remove unused functions. */
|
||
/* 02/21/07 JRB 27 Fix funct names in this module header. */
|
||
/* 12/04/06 JRB 26 mvl_vmd_destroy: add arg to specify which VMD*/
|
||
/* and DO NOT destroy all rpt_ctrl (let user). */
|
||
/* 10/30/06 JRB 25 Add vmd_ctrl arg to several functions & chg */
|
||
/* prefix from "mvl_" to "mvl_vmd_". */
|
||
/* Add vmd_ctrl, net_info args to mvl_nvl_create.*/
|
||
/* Check that (net_info!=NULL) before using it. */
|
||
/* Move "*_delete" to mvl_objb.c with other */
|
||
/* insert/delete functions. */
|
||
/* Add mvl_vmd_create. */
|
||
/* 08/09/06 JRB 24 Free "last_data" only in mvl_var_destroy. */
|
||
/* Save type_ctrl in MVL_VAR_ASSOC. */
|
||
/* mvl_vmd_destroy: free mvl61850_rpt_ctrl_list.*/
|
||
/* 01/30/06 GLB 23 Integrated porting changes for VMS */
|
||
/* 10/25/05 EJV 22 Fix "last_data" memory leaks: alloc only if */
|
||
/* last_data==NULL, free only if last_data!=NULL.*/
|
||
/* 09/22/05 JRB 21 mvl_vmd_destroy: del VMD-spec vars, NVLs too.*/
|
||
/* 06/29/05 CRM 20 Add mvl_vmd_destroy. */
|
||
/* 06/27/05 JRB 19 Alloc "va->last_data" in mvl_nvl_create & */
|
||
/* free it in mvl_nvl_destroy so special NVL */
|
||
/* functs not needed for IEC/UCA reports. */
|
||
/* 06/27/05 JRB 18 mvl_var_create: chk type. */
|
||
/* 04/27/05 CRM 17 Added code to free dom->jou_tbl in */
|
||
/* mvl_dom_destroy */
|
||
/* 06/04/04 JRB 16 mvl_var_create: if (data), set use_static_data.*/
|
||
/* 10/03/03 JRB 15 mvl_nvl_add: set nvl_scope in MVL_NVLIST_CTRL*/
|
||
/* mvl_nvl_add/mvl_var_add: chk for valid dom first*/
|
||
/* 02/25/02 MDE 14 Now get max PDU size from mvl_cfg_info */
|
||
/* 01/23/02 EJV 13 Added journals to domain: */
|
||
/* mvl_init_dom - added max_num_jou param */
|
||
/* mvl_dom_resize - added max_num_jou param */
|
||
/* mvl_dom_create - added max_num_jou param */
|
||
/* mvl_dom_add - added max_num_jou param */
|
||
/* mvl_clear_dom_objs -added code for journals*/
|
||
/* mvl_jou_delete - added DOM_SPEC case */
|
||
/* 10/25/00 JRB 12 Del u_mvl funct ptrs. Call functs directly. */
|
||
/* Control with #ifdefs. */
|
||
/* 04/14/00 JRB 11 Move sort & compare code to mvl_objb.c */
|
||
/* 04/12/00 MDE 10 Moved AA resize code to mvl_acse.c */
|
||
/* 01/21/00 MDE 09 Now use MEM_SMEM for dynamic memory */
|
||
/* 09/15/99 JRB 08 Mv mvl_obj_nosort to mvl_objb.c for DOS link */
|
||
/* 09/13/99 MDE 07 Added SD_CONST modifiers */
|
||
/* 09/07/99 MDE 06 Changed MVL_VA_SCOPE to MVL_SCOPE */
|
||
/* 07/12/99 MDE 05 Fixed problem 'destroying' dom w/NVL or VAR */
|
||
/* 04/07/99 MDE 04 Logging improvements */
|
||
/* 03/18/99 MDE 03 Enhanced dynamic object facilities */
|
||
/* 01/20/99 JRB 02 Reduce # of functions. Chg names and args. */
|
||
/* Call new "mvl_???_insert" functions. */
|
||
/* Add ..nvl_remove, ..nvl_create, ..nvl_destroy*/
|
||
/* 11/18/98 MDE 01 Created */
|
||
/************************************************************************/
|
||
|
||
#include "glbtypes.h"
|
||
#include "sysincs.h"
|
||
#include "mvl_acse.h"
|
||
#include "mvl_log.h"
|
||
#if defined(MVL_UCA)
|
||
#include "mvl_uca.h" /* need "MVLU_RPT_*" */
|
||
#endif
|
||
|
||
/************************************************************************/
|
||
/* For debug version, use a static pointer to avoid duplication of */
|
||
/* __FILE__ strings. */
|
||
/************************************************************************/
|
||
|
||
#ifdef DEBUG_SISCO
|
||
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
|
||
#endif
|
||
|
||
ST_VOID (*u_mvl_dom_destroy) (MVL_DOM_CTRL *dom);
|
||
ST_VOID (*u_mvl_var_destroy)(MVL_VAR_ASSOC *va);
|
||
ST_VOID (*u_mvl_nvl_destroy) (MVL_NVLIST_CTRL *nvl);
|
||
ST_VOID (*u_mvl_jou_destroy) (MVL_JOURNAL_CTRL *jou);
|
||
|
||
/************************************************************************/
|
||
/* SCOPE RESIZING FUNCTIONS */
|
||
/************************************************************************/
|
||
/************************************************************************/
|
||
/* mvl_vmd_resize */
|
||
/************************************************************************/
|
||
|
||
ST_VOID mvl_vmd_resize (ST_INT max_num_dom, ST_INT max_num_var,
|
||
ST_INT max_num_nvl, ST_INT max_num_jou)
|
||
{
|
||
if (max_num_dom < mvl_vmd.num_dom)
|
||
{
|
||
MVL_LOG_NERR0 ("Resizing VMD: new max DOM is less than current");
|
||
max_num_dom = mvl_vmd.num_dom;
|
||
}
|
||
if (max_num_var < mvl_vmd.num_var_assoc)
|
||
{
|
||
MVL_LOG_NERR0 ("Resizing VMD: new max VA is less than current");
|
||
max_num_var = mvl_vmd.num_var_assoc;
|
||
}
|
||
if (max_num_nvl < mvl_vmd.num_nvlist)
|
||
{
|
||
MVL_LOG_NERR0 ("Resizing VMD: new max NVL is less than current");
|
||
max_num_nvl = mvl_vmd.num_nvlist;
|
||
}
|
||
if (max_num_jou < mvl_vmd.num_jou)
|
||
{
|
||
MVL_LOG_NERR0 ("Resizing VMD: new max JOU is less than current");
|
||
max_num_jou = mvl_vmd.num_jou;
|
||
}
|
||
|
||
_mvl_resize_ptr_tbl (&(mvl_vmd.max_num_dom),
|
||
(ST_VOID ***)&(mvl_vmd.dom_tbl), max_num_dom);
|
||
_mvl_resize_ptr_tbl (&(mvl_vmd.max_num_var_assoc),
|
||
(ST_VOID ***)&(mvl_vmd.var_assoc_tbl), max_num_var);
|
||
_mvl_resize_ptr_tbl (&(mvl_vmd.max_num_nvlist),
|
||
(ST_VOID ***)&(mvl_vmd.nvlist_tbl), max_num_nvl);
|
||
_mvl_resize_ptr_tbl (&(mvl_vmd.max_num_jou),
|
||
(ST_VOID ***)&(mvl_vmd.jou_tbl), max_num_jou);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_dom_resize */
|
||
/************************************************************************/
|
||
|
||
ST_VOID mvl_dom_resize (MVL_DOM_CTRL *dom, ST_INT max_num_var,
|
||
ST_INT max_num_nvl, ST_INT max_num_jou)
|
||
{
|
||
if (max_num_var < dom->num_var_assoc)
|
||
{
|
||
MVL_LOG_NERR0 ("Resizing Domain: new max VA is less than current");
|
||
max_num_var = dom->num_var_assoc;
|
||
}
|
||
if (max_num_nvl < dom->num_nvlist)
|
||
{
|
||
MVL_LOG_NERR0 ("Resizing Domain: new max NVL is less than current");
|
||
max_num_nvl = dom->num_nvlist;
|
||
}
|
||
if (max_num_jou < dom->num_jou)
|
||
{
|
||
MVL_LOG_NERR0 ("Resizing Domain: new max JOU is less than current");
|
||
max_num_jou = dom->num_jou;
|
||
}
|
||
|
||
_mvl_resize_ptr_tbl (&(dom->max_num_var_assoc),
|
||
(ST_VOID ***)&(dom->var_assoc_tbl), max_num_var);
|
||
_mvl_resize_ptr_tbl (&(dom->max_num_nvlist),
|
||
(ST_VOID ***)&(dom->nvlist_tbl), max_num_nvl);
|
||
_mvl_resize_ptr_tbl (&(dom->max_num_jou),
|
||
(ST_VOID ***)&(dom->jou_tbl), max_num_jou);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* _mvl_resize_ptr_tbl */
|
||
/************************************************************************/
|
||
|
||
ST_VOID _mvl_resize_ptr_tbl (ST_INT *p_max_num,
|
||
ST_VOID ***p_ptr_tbl, ST_INT new_size)
|
||
{
|
||
|
||
/* See if something needs to be done at all */
|
||
if (*p_max_num == new_size)
|
||
return;
|
||
|
||
/* See if the table is going away altogether */
|
||
if (new_size != 0)
|
||
{
|
||
if (*p_max_num != 0)
|
||
*p_ptr_tbl = (ST_VOID **) M_REALLOC (MSMEM_GEN, *p_ptr_tbl, (new_size * sizeof (ST_VOID *)));
|
||
else /* We did not have a table, but need one now */
|
||
*p_ptr_tbl = (ST_VOID **) M_CALLOC (MSMEM_GEN, new_size, sizeof (ST_VOID *));
|
||
}
|
||
else
|
||
{ /* If we had a table, we need to free it */
|
||
if (*p_max_num != 0)
|
||
M_FREE (MSMEM_GEN, *p_ptr_tbl);
|
||
}
|
||
*p_max_num = new_size;
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_nvl_remove_all */
|
||
/* Remove all VMD-Specific NVLs & Domain-Specific NVLs in this VMD. */
|
||
/* CRITICAL: Use "mvl_vmd_nvl_remove". It makes sure it is safe to */
|
||
/* remove each NVL. */
|
||
/* RETURNS: SD_SUCCESS or SD_FAILURE */
|
||
/************************************************************************/
|
||
ST_RET mvl_nvl_remove_all (MVL_VMD_CTRL *vmd_ctrl)
|
||
{
|
||
ST_INT didx;
|
||
MVL_DOM_CTRL *dom;
|
||
|
||
/* Destroy VMD-Specific NVLs. */
|
||
while (vmd_ctrl->num_nvlist)
|
||
{
|
||
MVL_NVLIST_CTRL *nvl;
|
||
OBJECT_NAME obj;
|
||
nvl = vmd_ctrl->nvlist_tbl[vmd_ctrl->num_nvlist-1]; /* point to last nvl*/
|
||
obj.obj_name.vmd_spec = nvl->name;
|
||
obj.object_tag = VMD_SPEC;
|
||
if (mvl_vmd_nvl_remove (vmd_ctrl, &obj, NULL) != SD_SUCCESS)
|
||
{
|
||
MVL_LOG_ERR1 ("Error removing VMD-specific NVL='%s'", nvl->name);
|
||
return (SD_FAILURE);
|
||
}
|
||
}
|
||
|
||
/* Destroy Domain-Specific NVLs in all domains. */
|
||
for (didx = 0; didx < vmd_ctrl->num_dom; didx++)
|
||
{
|
||
dom = vmd_ctrl->dom_tbl [didx];
|
||
while (dom->num_nvlist)
|
||
{
|
||
MVL_NVLIST_CTRL *nvl;
|
||
OBJECT_NAME obj;
|
||
nvl = dom->nvlist_tbl[dom->num_nvlist-1]; /* point to last nvl*/
|
||
obj.obj_name.item_id = nvl->name;
|
||
obj.domain_id = dom->name;
|
||
obj.object_tag = DOM_SPEC;
|
||
if (mvl_vmd_nvl_remove (vmd_ctrl, &obj, NULL) != SD_SUCCESS)
|
||
{
|
||
MVL_LOG_ERR2 ("Error removing NVL='%s' in domain '%s'", nvl->name, dom->name);
|
||
return (SD_FAILURE);
|
||
}
|
||
}
|
||
}
|
||
return (SD_SUCCESS);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_var_in_nvl */
|
||
/* Is this var used in this NVL? */
|
||
/************************************************************************/
|
||
ST_BOOLEAN mvl_var_in_nvl (MVL_NVLIST_CTRL *nvl, MVL_VAR_ASSOC *var)
|
||
{
|
||
ST_INT vidx;
|
||
MVL_VAR_ASSOC *nvl_var; /* variable used in a NVL */
|
||
|
||
for (vidx = 0; vidx < nvl->num_of_entries; vidx++)
|
||
{
|
||
nvl_var = nvl->entries[vidx];
|
||
if (nvl_var == var || nvl_var->base_va == var)
|
||
{ /* This variable (or a variable derived from it) is used in the NVL. */
|
||
return(SD_TRUE);
|
||
}
|
||
}
|
||
return (SD_FALSE); /* This variable is NOT used in the NVL. */
|
||
}
|
||
/************************************************************************/
|
||
/* mvl_var_deletable */
|
||
/* Is this var deletable (i.e. NOT referenced by other objects)? */
|
||
/************************************************************************/
|
||
ST_BOOLEAN mvl_var_deletable (MVL_VMD_CTRL *vmd_ctrl, MVL_VAR_ASSOC *var)
|
||
{
|
||
ST_INT didx, nvlidx;
|
||
MVL_DOM_CTRL *dom;
|
||
MVL_NVLIST_CTRL *nvl;
|
||
assert (var->base_va == NULL); /* DEBUG: these are always base variables.*/
|
||
|
||
/* Make sure var is not used in any VMD-specific NVL. */
|
||
for (nvlidx = 0; nvlidx < vmd_ctrl->num_nvlist; ++nvlidx)
|
||
{
|
||
nvl = vmd_ctrl->nvlist_tbl[nvlidx];
|
||
if (mvl_var_in_nvl (nvl, var))
|
||
{
|
||
MVL_LOG_ERR2 ("Variable=%s cannot be deleted because it is used in VMD-specific NVL=%s",
|
||
var->name, nvl->name);
|
||
return(SD_FALSE);
|
||
}
|
||
}
|
||
|
||
/* Make sure var is not used in any Domain-specific NVL in any Domain. */
|
||
for (didx = 0; didx < vmd_ctrl->num_dom; didx++)
|
||
{
|
||
dom = vmd_ctrl->dom_tbl [didx];
|
||
for (nvlidx = 0; nvlidx < dom->num_nvlist; nvlidx++)
|
||
{
|
||
nvl = dom->nvlist_tbl[nvlidx];
|
||
if (mvl_var_in_nvl (nvl, var))
|
||
{
|
||
MVL_LOG_ERR2 ("Variable=%s cannot be deleted because it is used in Domain-specific NVL=%s",
|
||
var->name, nvl->name);
|
||
return(SD_FALSE);
|
||
}
|
||
}
|
||
}
|
||
return (SD_TRUE); /* ok to delete it */
|
||
}
|
||
/************************************************************************/
|
||
/* mvl_nvl_deletable */
|
||
/* Is this NVL deletable (i.e. NOT referenced by other objects)? */
|
||
/************************************************************************/
|
||
ST_BOOLEAN mvl_nvl_deletable (MVL_VMD_CTRL *vmd_ctrl, MVL_NVLIST_CTRL *nvl)
|
||
{
|
||
#if defined(MVL_UCA) /* check for IEC 61850 or UCA RCBs using this NVL*/
|
||
MVLU_RPT_CTRL *rptCtrl;
|
||
|
||
/* NOTE: the flag "nvl->mms_deletable" is only used by the MMS service*/
|
||
/* DeleteNamedVariableList, not to prevent MVL from deleting this NVL.*/
|
||
|
||
/* See if NVL is used in any IEC 61850 Report Control Block. */
|
||
//lnk编译修改:原前置程序未使用
|
||
/*for (rptCtrl = mvl61850_rpt_ctrl_list;
|
||
rptCtrl != NULL;
|
||
rptCtrl = (MVLU_RPT_CTRL *) list_get_next (mvl61850_rpt_ctrl_list, rptCtrl))
|
||
{
|
||
if (rptCtrl->dsNvl == nvl)
|
||
{
|
||
MVL_LOG_ERR1 ("NVL='%s' cannot be deleted because it is used in a IEC 61850 Report Control Block",
|
||
nvl->name);
|
||
return (SD_FALSE);
|
||
}
|
||
}*/
|
||
/* See if NVL is used in any UCA Report Control Block. */
|
||
//lnk编译修改:原前置程序未使用
|
||
/*for (rptCtrl = mvlu_rpt_ctrl_list;
|
||
rptCtrl != NULL;
|
||
rptCtrl = (MVLU_RPT_CTRL *) list_get_next (mvlu_rpt_ctrl_list, rptCtrl))
|
||
{
|
||
if (rptCtrl->dsNvl == nvl)
|
||
{
|
||
MVL_LOG_ERR1 ("NVL='%s' cannot be deleted because it is used in a UCA Report Control Block",
|
||
nvl->name);
|
||
return (SD_FALSE);
|
||
}
|
||
}*/
|
||
#endif /* defined(MVL_UCA) */
|
||
/* NOTE: if not MVL_UCA, nothing to check. */
|
||
return (SD_TRUE); /* ok to delete it */
|
||
}
|
||
|
||
/************************************************************************/
|
||
/************************************************************************/
|
||
/* DOMAIN */
|
||
/************************************************************************/
|
||
/************************************************************************/
|
||
/* mvl_vmd_dom_add */
|
||
/* Add a domain. Allocate, fill in, and insert into table. */
|
||
/************************************************************************/
|
||
|
||
MVL_DOM_CTRL *mvl_vmd_dom_add (MVL_VMD_CTRL *vmd_ctrl, ST_CHAR *name, ST_INT max_num_var,
|
||
ST_INT max_num_nvl, ST_INT max_num_jou,
|
||
ST_BOOLEAN copy_name)
|
||
{
|
||
MVL_DOM_CTRL *dom;
|
||
|
||
dom = mvl_dom_create (name, max_num_var, max_num_nvl, max_num_jou, copy_name);
|
||
|
||
/* Insert it in table. */
|
||
if (mvl_vmd_dom_insert (vmd_ctrl, dom))
|
||
{ /* Failed. */
|
||
M_FREE (MSMEM_GEN, dom);
|
||
return (NULL);
|
||
}
|
||
|
||
return (dom);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_dom_create */
|
||
/************************************************************************/
|
||
|
||
MVL_DOM_CTRL *mvl_dom_create (ST_CHAR *name, ST_INT max_num_var,
|
||
ST_INT max_num_nvl, ST_INT max_num_jou,
|
||
ST_BOOLEAN copy_name)
|
||
{
|
||
MVL_DOM_CTRL *dom;
|
||
|
||
/* Allocate object and fill in "name". */
|
||
if (copy_name)
|
||
{
|
||
dom = (MVL_DOM_CTRL *) M_CALLOC (MSMEM_GEN, 1, sizeof (MVL_DOM_CTRL)
|
||
+ strlen (name) + 1);
|
||
dom->name = (ST_CHAR *) (dom+1);
|
||
strcpy (dom->name, name); /* copy name */
|
||
}
|
||
else
|
||
{
|
||
dom = (MVL_DOM_CTRL *) M_CALLOC (MSMEM_GEN, 1, sizeof (MVL_DOM_CTRL));
|
||
dom->name = name; /* point to user buffer */
|
||
}
|
||
|
||
/* Allocate the pointer tables */
|
||
mvl_dom_resize (dom, max_num_var, max_num_nvl, max_num_jou);
|
||
return (dom);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_dom_cleanup */
|
||
/* Remove all objects (NVLs, variables, journals) from this domain. */
|
||
/* CRITICAL: Use "*_remove" functions. They make sure it is safe to */
|
||
/* remove each object. */
|
||
/************************************************************************/
|
||
|
||
ST_RET mvl_dom_cleanup (MVL_VMD_CTRL *vmd_ctrl, MVL_DOM_CTRL *dom)
|
||
{
|
||
ST_INT i;
|
||
|
||
if (dom->foundry_objects)
|
||
{
|
||
MVL_LOG_NERR1 ("Cannot remove objects from domain '%s' because Foundry objects present", dom->name);
|
||
return (SD_FAILURE);
|
||
}
|
||
|
||
/* Remove all NVL from this domain. Stop on first error. */
|
||
while (dom->num_nvlist)
|
||
{
|
||
MVL_NVLIST_CTRL *nvl;
|
||
OBJECT_NAME obj;
|
||
nvl = dom->nvlist_tbl[dom->num_nvlist-1]; /* point to last nvl*/
|
||
obj.obj_name.item_id = nvl->name;
|
||
obj.domain_id = dom->name;
|
||
obj.object_tag = DOM_SPEC;
|
||
if (mvl_vmd_nvl_remove (vmd_ctrl, &obj, NULL) != SD_SUCCESS)
|
||
{
|
||
MVL_LOG_ERR2 ("Error removing NVL='%s' from domain='%s'",
|
||
nvl->name, dom->name);
|
||
return (SD_FAILURE);
|
||
}
|
||
}
|
||
|
||
/* Remove all variables from this domain. Stop on first error. */
|
||
while (dom->num_var_assoc > 0)
|
||
{
|
||
MVL_VAR_ASSOC *var;
|
||
OBJECT_NAME obj;
|
||
var = dom->var_assoc_tbl[dom->num_var_assoc-1]; /* point to last var*/
|
||
obj.obj_name.item_id = var->name;
|
||
obj.domain_id = dom->name;
|
||
obj.object_tag = DOM_SPEC;
|
||
if (mvl_vmd_var_remove (vmd_ctrl, &obj, NULL) != SD_SUCCESS)
|
||
{
|
||
MVL_LOG_ERR2 ("Error removing variable='%s' from domain='%s'",
|
||
var->name, dom->name);
|
||
return (SD_FAILURE);
|
||
}
|
||
}
|
||
|
||
/* Delete the Journal control table. */
|
||
/* DEBUG: Should use mvl_vmd_jou_remove here but it can't fail, so */
|
||
/* using mvl_jou_destroy is just as good for now. */
|
||
if (dom->max_num_jou)
|
||
{
|
||
for (i = 0; i < dom->num_jou; ++i)
|
||
mvl_jou_destroy (dom->jou_tbl[i]);
|
||
}
|
||
dom->num_jou = 0;
|
||
return (SD_SUCCESS);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_vmd_dom_remove */
|
||
/************************************************************************/
|
||
|
||
ST_RET mvl_vmd_dom_remove (MVL_VMD_CTRL *vmd_ctrl, ST_CHAR *dom_name)
|
||
{
|
||
MVL_DOM_CTRL *dom;
|
||
ST_RET retcode = SD_FAILURE;
|
||
|
||
dom = mvl_vmd_find_dom (vmd_ctrl, dom_name);
|
||
if (dom != NULL)
|
||
{
|
||
/* Remove all objects in domain before delete/destroy.*/
|
||
retcode = mvl_dom_cleanup (vmd_ctrl, dom);
|
||
if (retcode)
|
||
MVL_LOG_ERR1 ("Error removing objects from domain, so cannot remove domain '%s'",
|
||
dom->name);
|
||
else
|
||
{ /* cleanup successful */
|
||
/* NOTE: this delete should never fail because we already found it.*/
|
||
dom = mvl_vmd_dom_delete (vmd_ctrl, dom_name);
|
||
if (dom != NULL)
|
||
mvl_dom_destroy (dom); /* cannot fail. retcode already = SD_SUCCESS*/
|
||
else
|
||
retcode = SD_FAILURE; /* delete failed. Should never happen */
|
||
}
|
||
}
|
||
return (retcode);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_dom_destroy */
|
||
/* NOTE: this assumes all objects already removed from domain. */
|
||
/************************************************************************/
|
||
|
||
ST_VOID mvl_dom_destroy (MVL_DOM_CTRL *dom)
|
||
{
|
||
if (u_mvl_dom_destroy != NULL)
|
||
(*u_mvl_dom_destroy)(dom);
|
||
|
||
if (dom->max_num_var_assoc != 0)
|
||
M_FREE (MSMEM_GEN, dom->var_assoc_tbl);
|
||
|
||
if (dom->max_num_nvlist != 0)
|
||
M_FREE (MSMEM_GEN, dom->nvlist_tbl);
|
||
|
||
if (dom->max_num_jou != 0)
|
||
M_FREE (MSMEM_GEN, dom->jou_tbl);
|
||
|
||
M_FREE (MSMEM_GEN, dom);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/**** VARIABLE ASSOCIATIONS */
|
||
/************************************************************************/
|
||
/* mvl_vmd_var_add */
|
||
/* Add a variable association. Allocate, fill in, and insert into table.*/
|
||
/* NOT RECOMMENDED: use mvl_var_add_alloc. */
|
||
/************************************************************************/
|
||
|
||
MVL_VAR_ASSOC *mvl_vmd_var_add (MVL_VMD_CTRL *vmd_ctrl, OBJECT_NAME *obj, MVL_NET_INFO *net_info,
|
||
ST_INT type_id,
|
||
ST_VOID *data,
|
||
MVL_VAR_PROC *proc,
|
||
ST_BOOLEAN copy_name)
|
||
{
|
||
MVL_VAR_ASSOC *va;
|
||
MVL_DOM_CTRL *dom = NULL;
|
||
|
||
/* Find domain, if necessary, before allocating anything. */
|
||
if (obj->object_tag==DOM_SPEC && (dom = mvl_vmd_find_dom (vmd_ctrl, obj->domain_id)) == NULL)
|
||
{
|
||
MVL_LOG_ERR2 ("Error creating VAR '%s': domain '%s' not found",
|
||
obj->obj_name.vmd_spec, obj->domain_id);
|
||
return (NULL);
|
||
}
|
||
|
||
va = mvl_var_create (obj, type_id, data, proc, copy_name);
|
||
|
||
/* Insert it in table. */
|
||
if (va)
|
||
{
|
||
if (mvl_vmd_var_insert (vmd_ctrl, va, obj, net_info))
|
||
{ /* Failed. */
|
||
mvl_var_destroy (va); /* destroy var just created */
|
||
return (NULL);
|
||
}
|
||
}
|
||
|
||
return (va);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_var_create */
|
||
/* NOT RECOMMENDED: use mvl_var_create_alloc. */
|
||
/************************************************************************/
|
||
|
||
MVL_VAR_ASSOC *mvl_var_create (OBJECT_NAME *obj, ST_INT type_id,
|
||
ST_VOID *data, MVL_VAR_PROC *proc,
|
||
ST_BOOLEAN copy_name)
|
||
{
|
||
MVL_VAR_ASSOC *va;
|
||
MVL_TYPE_CTRL *type_ctrl;
|
||
|
||
type_ctrl = mvl_type_ctrl_find (type_id);
|
||
if (type_ctrl == NULL)
|
||
{
|
||
MVL_LOG_ERR0 ("Cannot create variable (type_id invalid).");
|
||
return (NULL);
|
||
}
|
||
|
||
/* Allocate object and fill in "name". */
|
||
if (copy_name)
|
||
{
|
||
va = (MVL_VAR_ASSOC *) M_CALLOC (MSMEM_GEN, 1, sizeof (MVL_VAR_ASSOC)
|
||
+ strlen (obj->obj_name.vmd_spec) + 1);
|
||
va->name = (ST_CHAR *) (va+1);
|
||
strcpy (va->name, obj->obj_name.vmd_spec); /* copy name */
|
||
}
|
||
else
|
||
{
|
||
va = (MVL_VAR_ASSOC *) M_CALLOC (MSMEM_GEN, 1, sizeof (MVL_VAR_ASSOC));
|
||
va->name = obj->obj_name.vmd_spec; /* point to user buffer */
|
||
}
|
||
|
||
/* Fill in rest of object. */
|
||
va->type_id = type_id;
|
||
va->type_ctrl = type_ctrl; /* don't need to call mvl_get_runtime */
|
||
/* to get type details. */
|
||
va->data = data;
|
||
#if defined(MVL_UCA)
|
||
/* If caller set the data ptr (!=NULL), assume they want to use static data.*/
|
||
if (data!=NULL)
|
||
va->use_static_data = SD_TRUE;
|
||
#endif
|
||
va->proc = proc;
|
||
return (va);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_var_add_alloc */
|
||
/* Add a variable association. Allocate, fill in, and insert into table.*/
|
||
/************************************************************************/
|
||
MVL_VAR_ASSOC *mvl_var_add_alloc (MVL_VMD_CTRL *vmd_ctrl,
|
||
OBJECT_NAME *obj,
|
||
MVL_NET_INFO *net_info,
|
||
ST_INT type_id,
|
||
MVL_VAR_PROC *proc)
|
||
{
|
||
MVL_VAR_ASSOC *va;
|
||
MVL_DOM_CTRL *dom = NULL;
|
||
|
||
/* Find domain, if necessary, before allocating anything. */
|
||
if (obj->object_tag==DOM_SPEC && (dom = mvl_vmd_find_dom (vmd_ctrl, obj->domain_id)) == NULL)
|
||
{
|
||
MVL_LOG_ERR2 ("Error creating VAR '%s': domain '%s' not found",
|
||
obj->obj_name.vmd_spec, obj->domain_id);
|
||
return (NULL);
|
||
}
|
||
|
||
va = mvl_var_create_alloc (obj->obj_name.vmd_spec, type_id, proc);
|
||
|
||
/* Insert it in table. */
|
||
if (va)
|
||
{
|
||
if (mvl_vmd_var_insert (vmd_ctrl, va, obj, net_info))
|
||
{ /* Failed. */
|
||
mvl_var_destroy (va); /* destroy var just created */
|
||
return (NULL);
|
||
}
|
||
}
|
||
return (va);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_var_create_alloc */
|
||
/* Create a new variable. ALWAYS allocate a buffer for */
|
||
/* the data (buffer is automatically freed when variable is destroyed). */
|
||
/* CRITICAL: DO NOT use for "derived" variables. Instead use */
|
||
/* mvl_var_create_derived. */
|
||
/************************************************************************/
|
||
MVL_VAR_ASSOC *mvl_var_create_alloc (ST_CHAR *name,
|
||
ST_INT type_id,
|
||
MVL_VAR_PROC *proc)
|
||
{
|
||
MVL_VAR_ASSOC *va;
|
||
MVL_TYPE_CTRL *type_ctrl;
|
||
|
||
type_ctrl = mvl_type_ctrl_find (type_id);
|
||
if (type_ctrl == NULL)
|
||
{
|
||
MVL_LOG_ERR0 ("Cannot create variable (type_id invalid).");
|
||
return (NULL);
|
||
}
|
||
|
||
/* Allocate one buffer for MVL_VAR_ASSOC plus "data" plus "name". */
|
||
va = (MVL_VAR_ASSOC *) chk_calloc (1,
|
||
sizeof (MVL_VAR_ASSOC) /* space for struct*/
|
||
+ type_ctrl->data_size /* space for "data"*/
|
||
+ strlen (name) + 1); /* space for "name"*/
|
||
|
||
/* Set data ptr right after MVL_VAR_ASSOC struct. */
|
||
/* NOTE: data is before name so alignment should be good for any data.*/
|
||
va->data = (va+1);
|
||
/* Set name ptr right after data. */
|
||
va->name = ((ST_CHAR *) (va->data)) + type_ctrl->data_size;
|
||
|
||
strcpy (va->name, name); /* copy name */
|
||
|
||
/* Fill in rest of object. */
|
||
va->type_id = type_id;
|
||
va->type_ctrl = type_ctrl; /* save for easy access later. */
|
||
|
||
va->use_static_data = SD_TRUE; /* always SD_TRUE */
|
||
|
||
va->proc = proc;
|
||
return (va);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_var_create_derived */
|
||
/* Create a "derived" variable. */
|
||
/* NOTE: Structure member "proc" always set to NULL. */
|
||
/* Structure member "data" points inside base variable. */
|
||
/************************************************************************/
|
||
|
||
MVL_VAR_ASSOC *mvl_var_create_derived (ST_CHAR *name,
|
||
ST_INT type_id,
|
||
MVL_VAR_ASSOC *baseVa, /* base variable from which to derive */
|
||
ST_INT offset_from_base,
|
||
ST_RTINT prim_num)
|
||
{
|
||
MVL_VAR_ASSOC *va;
|
||
MVL_TYPE_CTRL *type_ctrl;
|
||
|
||
type_ctrl = mvl_type_ctrl_find (type_id);
|
||
if (type_ctrl == NULL)
|
||
{
|
||
MVL_LOG_ERR0 ("Cannot create variable (type_id invalid).");
|
||
return (NULL);
|
||
}
|
||
|
||
/* Allocate object and fill in "name". */
|
||
va = (MVL_VAR_ASSOC *) chk_calloc (1, sizeof (MVL_VAR_ASSOC)
|
||
+ strlen (name) + 1);
|
||
va->name = (ST_CHAR *) (va+1);
|
||
strcpy (va->name, name); /* copy name */
|
||
|
||
/* Fill in rest of object. */
|
||
va->type_id = type_id;
|
||
va->type_ctrl = type_ctrl; /* save for easy access later. */
|
||
|
||
/* va->proc = NULL (due to calloc above) */
|
||
|
||
/* Set special "va" elements only for derived variables. */
|
||
va->base_va = baseVa;
|
||
va->user_info = baseVa->user_info;
|
||
|
||
/* Save offset_from_base & prim_num passed as arguments. */
|
||
va->offset_from_base = offset_from_base;
|
||
va->prim_num = prim_num;
|
||
|
||
if (va->base_va->use_static_data)
|
||
va->data = (((ST_CHAR *) va->base_va->data) + va->offset_from_base);
|
||
/* else caller must set va->data. */
|
||
|
||
return (va);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_vmd_var_remove */
|
||
/************************************************************************/
|
||
|
||
ST_RET mvl_vmd_var_remove (MVL_VMD_CTRL *vmd_ctrl, OBJECT_NAME *obj, MVL_NET_INFO *net_info)
|
||
{
|
||
MVL_VAR_ASSOC *va;
|
||
|
||
/* First find it & make sure it is deletable. */
|
||
va = mvl_vmd_find_var (vmd_ctrl, obj, net_info);
|
||
if (va == NULL || mvl_var_deletable (vmd_ctrl, va) == SD_FALSE)
|
||
{
|
||
MVL_LOG_ERR1 ("Error deleting variable='%s': not found or not deletable.",
|
||
obj->obj_name.vmd_spec);
|
||
return (SD_FAILURE);
|
||
}
|
||
|
||
va = mvl_vmd_var_delete (vmd_ctrl, obj, net_info);
|
||
if (va == NULL)
|
||
return (SD_FAILURE);
|
||
|
||
mvl_var_destroy (va);
|
||
return (SD_SUCCESS);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_var_destroy */
|
||
/************************************************************************/
|
||
|
||
ST_VOID mvl_var_destroy (MVL_VAR_ASSOC *va)
|
||
{
|
||
if (u_mvl_var_destroy != NULL)
|
||
(*u_mvl_var_destroy)(va);
|
||
|
||
/* "last_data" may have been allocated if this var used in NVL. */
|
||
if (va->last_data)
|
||
chk_free (va->last_data);
|
||
/* renxiaobao 日志
|
||
if (va->last_log_data)
|
||
chk_free (va->last_log_data);*/
|
||
M_FREE (MSMEM_GEN, va);
|
||
}
|
||
|
||
|
||
/************************************************************************/
|
||
/**** NAMED VARIABLE LISTS */
|
||
/************************************************************************/
|
||
/* mvl_vmd_nvl_add */
|
||
/* Add a Named Variable List. Allocate, fill in, and insert into table. */
|
||
/************************************************************************/
|
||
|
||
MVL_NVLIST_CTRL *mvl_vmd_nvl_add (MVL_VMD_CTRL *vmd_ctrl, OBJECT_NAME *nvl_obj, MVL_NET_INFO *net_info,
|
||
ST_INT num_var,
|
||
OBJECT_NAME *var_obj, /* array of var names */
|
||
ST_BOOLEAN copy_name)
|
||
{
|
||
MVL_NVLIST_CTRL *nvl;
|
||
MVL_DOM_CTRL *dom = NULL;
|
||
|
||
/* Find domain, if necessary, before allocating anything. */
|
||
if (nvl_obj->object_tag==DOM_SPEC && (dom = mvl_vmd_find_dom (vmd_ctrl, nvl_obj->domain_id)) == NULL)
|
||
{
|
||
MVL_LOG_ERR2 ("Error creating NVL '%s': domain '%s' not found",
|
||
nvl_obj->obj_name.vmd_spec, nvl_obj->domain_id);
|
||
return (NULL);
|
||
}
|
||
|
||
/* Allocate it AND fill it in. */
|
||
nvl = mvl_nvl_create (vmd_ctrl, nvl_obj->obj_name.vmd_spec, num_var, var_obj, net_info, copy_name);
|
||
if (nvl == NULL)
|
||
return (NULL);
|
||
|
||
/* Add scope info to "nvl". */
|
||
nvl->nvl_scope.scope = nvl_obj->object_tag;
|
||
nvl->nvl_scope.dom = dom; /* NOTE: NULL if not DOM_SPEC (see above) */
|
||
|
||
/* Insert it in table. */
|
||
if (mvl_vmd_nvl_insert (vmd_ctrl, nvl, nvl_obj, net_info))
|
||
{ /* Failed. */
|
||
mvl_nvl_destroy (nvl);
|
||
return (NULL);
|
||
}
|
||
|
||
return (nvl);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_nvl_create */
|
||
/************************************************************************/
|
||
/* Given a list of MMS object names, create a MVL Named Variable List. */
|
||
/* This can include both configured and MVLU manufactured variables */
|
||
/* Use 'mvl_nvl_destroy' to free this NVL. */
|
||
|
||
MVL_NVLIST_CTRL *mvl_nvl_create (MVL_VMD_CTRL *vmd_ctrl,
|
||
ST_CHAR *nvlName,
|
||
ST_INT numNames,
|
||
OBJECT_NAME *var_obj, /* array of var obj names*/
|
||
MVL_NET_INFO *net_info, /* where to find var_obj*/
|
||
/* if it is AA_SPEC */
|
||
ST_BOOLEAN copy_name)
|
||
{
|
||
MVL_NVLIST_CTRL *nvl;
|
||
ST_INT j;
|
||
|
||
/* Allocate object and fill in "name". */
|
||
if (copy_name)
|
||
{
|
||
nvl = (MVL_NVLIST_CTRL *) M_CALLOC (MSMEM_GEN, 1, sizeof (MVL_NVLIST_CTRL)
|
||
+ strlen (nvlName) + 1);
|
||
nvl->name = (ST_CHAR *) (nvl+1);
|
||
strcpy (nvl->name, nvlName); /* copy name */
|
||
}
|
||
else
|
||
{
|
||
nvl = (MVL_NVLIST_CTRL *) M_CALLOC (MSMEM_GEN, 1, sizeof (MVL_NVLIST_CTRL));
|
||
nvl->name = nvlName; /* point to user buffer */
|
||
}
|
||
|
||
/* Fill in rest of object. */
|
||
|
||
nvl->entries = (MVL_VAR_ASSOC **) M_CALLOC (MSMEM_GEN, numNames,
|
||
sizeof (MVL_VAR_ASSOC *));
|
||
nvl->va_scope = (MVL_SCOPE *) M_CALLOC (MSMEM_GEN, numNames,
|
||
sizeof (MVL_SCOPE));
|
||
nvl->num_of_entries = numNames;
|
||
|
||
for (j = 0; j < nvl->num_of_entries; ++j, ++var_obj)
|
||
{
|
||
MVL_VAR_ASSOC *var;
|
||
if ((nvl->entries[j] = var = _mvl_objname_to_va (vmd_ctrl, net_info, MMSOP_INFO_RPT,
|
||
var_obj, &nvl->va_scope[j], SD_FALSE, NULL, NULL)) == NULL)
|
||
{
|
||
MVL_LOG_ERR2 ("Error creating NVL '%s': member variable '%s' not found",
|
||
nvlName, var_obj->obj_name.vmd_spec);
|
||
mvl_nvl_destroy (nvl);
|
||
return (NULL);
|
||
}
|
||
else
|
||
{
|
||
#if defined(MVL_UCA)
|
||
/* Alloc buffer for last data (used for IEC/UCA reports). */
|
||
if (!var->last_data)
|
||
var->last_data = chk_calloc (1, mvl_type_ctrl[var->type_id].data_size);
|
||
/*renxiaobao 日志
|
||
if (!var->last_log_data)
|
||
var->last_log_data = chk_calloc (1, mvl_type_ctrl[var->type_id].data_size);*/
|
||
#endif
|
||
}
|
||
}
|
||
|
||
return (nvl);
|
||
}
|
||
|
||
|
||
/************************************************************************/
|
||
/* mvl_vmd_nvl_remove */
|
||
/* Remove a Named Variable List. Delete it from table and "destroy" it. */
|
||
/************************************************************************/
|
||
|
||
ST_RET mvl_vmd_nvl_remove (MVL_VMD_CTRL *vmd_ctrl, OBJECT_NAME *obj, MVL_NET_INFO *net_info)
|
||
{
|
||
MVL_NVLIST_CTRL *nvl;
|
||
|
||
/* First find it & make sure it is deletable. */
|
||
nvl = mvl_vmd_find_nvl (vmd_ctrl, obj, net_info);
|
||
if (nvl == NULL || mvl_nvl_deletable (vmd_ctrl, nvl) == SD_FALSE)
|
||
{
|
||
MVL_LOG_ERR1 ("Error deleting NVL='%s': not found or not deletable.",
|
||
obj->obj_name.vmd_spec);
|
||
return (SD_FAILURE);
|
||
}
|
||
|
||
/* Delete it from table. */
|
||
if ((nvl = mvl_vmd_nvl_delete (vmd_ctrl, obj, net_info)) == NULL)
|
||
return (SD_FAILURE); /* nvl not found */
|
||
|
||
/* Destroy it. */
|
||
mvl_nvl_destroy (nvl);
|
||
return (SD_SUCCESS);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_nvl_destroy */
|
||
/************************************************************************/
|
||
/* Free a MVL Named Variable List created by 'mvl_nvl_create' */
|
||
|
||
ST_VOID mvl_nvl_destroy (MVL_NVLIST_CTRL *nvl)
|
||
{
|
||
MVL_VAR_ASSOC *va;
|
||
ST_INT i;
|
||
|
||
if (u_mvl_nvl_destroy != NULL)
|
||
(*u_mvl_nvl_destroy)(nvl);
|
||
|
||
/* Free up any manufactured variables */
|
||
for (i = 0; i < nvl->num_of_entries; ++i)
|
||
{
|
||
va = nvl->entries[i];
|
||
#if defined(MVL_UCA) || defined(USE_MANUFACTURED_OBJS)
|
||
/* NOTE: "va" may be NULL if mvl_nvl_create failed while adding entries.*/
|
||
if (va && va->va_to_free == va)
|
||
{
|
||
//u_mvl_free_va (MMSOP_INFO_RPT, va, NULL);//lnk编译删除,原前置程序未使用
|
||
}
|
||
#endif
|
||
}
|
||
|
||
M_FREE (MSMEM_GEN, nvl->entries);
|
||
M_FREE (MSMEM_GEN, nvl->va_scope);
|
||
M_FREE (MSMEM_GEN, nvl);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/**** JOURNALS */
|
||
/************************************************************************/
|
||
/* mvl_vmd_jou_add */
|
||
/* Add a Journal. Allocate, fill in, and insert into table. */
|
||
/************************************************************************/
|
||
|
||
MVL_JOURNAL_CTRL *mvl_vmd_jou_add (MVL_VMD_CTRL *vmd_ctrl, OBJECT_NAME *obj, MVL_NET_INFO *net_info,
|
||
ST_BOOLEAN copy_name)
|
||
{
|
||
MVL_JOURNAL_CTRL *jou;
|
||
|
||
jou = mvl_jou_create (obj, net_info, copy_name);
|
||
if (mvl_vmd_jou_insert (vmd_ctrl, jou, obj, net_info))
|
||
{ /* Failed. */
|
||
M_FREE (MSMEM_GEN, jou);
|
||
return (NULL);
|
||
}
|
||
return (jou);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_jou_create */
|
||
/************************************************************************/
|
||
|
||
MVL_JOURNAL_CTRL *mvl_jou_create (OBJECT_NAME *obj, MVL_NET_INFO *net_info,
|
||
ST_BOOLEAN copy_name)
|
||
{
|
||
MVL_JOURNAL_CTRL *jou;
|
||
|
||
/* Allocate object and fill in "name". */
|
||
if (copy_name)
|
||
{
|
||
jou = (MVL_JOURNAL_CTRL *) M_CALLOC (MSMEM_GEN, 1, sizeof (MVL_JOURNAL_CTRL)
|
||
+ strlen (obj->obj_name.vmd_spec) + 1);
|
||
jou->name = (ST_CHAR *) (jou+1);
|
||
strcpy (jou->name, obj->obj_name.vmd_spec); /* copy name */
|
||
}
|
||
else
|
||
{
|
||
jou = (MVL_JOURNAL_CTRL *) M_CALLOC (MSMEM_GEN, 1, sizeof (MVL_JOURNAL_CTRL));
|
||
jou->name = obj->obj_name.vmd_spec; /* point to user buffer */
|
||
}
|
||
|
||
return (jou);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_vmd_jou_remove */
|
||
/************************************************************************/
|
||
|
||
ST_RET mvl_vmd_jou_remove (MVL_VMD_CTRL *vmd_ctrl, OBJECT_NAME *obj, MVL_NET_INFO *net_info)
|
||
{
|
||
MVL_JOURNAL_CTRL *jou;
|
||
|
||
jou = mvl_vmd_jou_delete (vmd_ctrl, obj, net_info);
|
||
if (jou == NULL)
|
||
return (SD_FAILURE);
|
||
|
||
mvl_jou_destroy (jou);
|
||
return (SD_SUCCESS);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_jou_destroy */
|
||
/************************************************************************/
|
||
|
||
ST_VOID mvl_jou_destroy (MVL_JOURNAL_CTRL *jou)
|
||
{
|
||
if (u_mvl_jou_destroy != NULL)
|
||
(*u_mvl_jou_destroy)(jou);
|
||
|
||
M_FREE (MSMEM_GEN, jou);
|
||
}
|
||
|
||
/************************************************************************/
|
||
/* mvl_vmd_create */
|
||
/* Create a new VMD with empty object arrays. */
|
||
/* Use "mvl_vmd_destroy" to destroy the VMD. */
|
||
/************************************************************************/
|
||
MVL_VMD_CTRL *mvl_vmd_create (ST_INT max_num_dom,
|
||
ST_INT max_num_var,
|
||
ST_INT max_num_nvl,
|
||
ST_INT max_num_journal)
|
||
{
|
||
MVL_VMD_CTRL *vmd_ctrl = chk_calloc (1, sizeof (MVL_VMD_CTRL));
|
||
|
||
vmd_ctrl->max_num_var_assoc = max_num_var;
|
||
if (vmd_ctrl->max_num_var_assoc)
|
||
vmd_ctrl->var_assoc_tbl = (MVL_VAR_ASSOC **) chk_calloc (
|
||
vmd_ctrl->max_num_var_assoc, sizeof (MVL_VAR_ASSOC *));
|
||
|
||
vmd_ctrl->max_num_nvlist = max_num_nvl;
|
||
if (vmd_ctrl->max_num_nvlist)
|
||
vmd_ctrl->nvlist_tbl = (MVL_NVLIST_CTRL **) chk_calloc (
|
||
vmd_ctrl->max_num_nvlist, sizeof (MVL_NVLIST_CTRL *));
|
||
|
||
vmd_ctrl->max_num_dom = max_num_dom;
|
||
if (vmd_ctrl->max_num_dom)
|
||
vmd_ctrl->dom_tbl = (MVL_DOM_CTRL **) chk_calloc (
|
||
vmd_ctrl->max_num_dom, sizeof (MVL_DOM_CTRL *));
|
||
|
||
vmd_ctrl->max_num_jou = max_num_journal;
|
||
if (vmd_ctrl->max_num_jou)
|
||
vmd_ctrl->jou_tbl = (MVL_JOURNAL_CTRL **) chk_calloc (
|
||
vmd_ctrl->max_num_jou, sizeof (MVL_JOURNAL_CTRL *));
|
||
|
||
return (vmd_ctrl);
|
||
};
|
||
|
||
/************************************************************************/
|
||
/* mvl_vmd_destroy */
|
||
/* Destroy all objects in this VMD. */
|
||
/* RETURNS: SD_SUCCESS or error code */
|
||
/************************************************************************/
|
||
ST_RET mvl_vmd_destroy (MVL_VMD_CTRL *vmd_ctrl)
|
||
{
|
||
ST_RET ret;
|
||
ST_INT j;
|
||
MVL_DOM_CTRL *dom;
|
||
|
||
ret = SD_SUCCESS; /* default ret val: returned if LD linked list empty.*/
|
||
|
||
/* Remove all NVL from this VMD and from all Domains before deleting */
|
||
/* Domains. NVLs might reference vars in other domains. */
|
||
/* CRITICAL: Must be done first, or vars can't be destroyed later. */
|
||
ret = mvl_nvl_remove_all (vmd_ctrl);
|
||
if (ret)
|
||
{
|
||
MVL_LOG_ERR0 ("Error destroying VMD: failed removing all NVL.");
|
||
return (ret);
|
||
}
|
||
|
||
/* Delete VMD-Specific Variables. */
|
||
for (j = 0; j < vmd_ctrl->num_var_assoc; ++j)
|
||
mvl_var_destroy (vmd_ctrl->var_assoc_tbl[j]);
|
||
vmd_ctrl->num_var_assoc = 0;
|
||
|
||
/* Delete Domains (always VMD-Specific). */
|
||
while ((dom = mvl_vmd_dom_find_last (vmd_ctrl)) != NULL)
|
||
{
|
||
ret = mvl_vmd_dom_remove (vmd_ctrl, dom->name);
|
||
|
||
if (ret != SD_SUCCESS)
|
||
break;
|
||
}
|
||
|
||
/* Destroy all types for this VMD. */
|
||
if (ret == SD_SUCCESS)
|
||
ret = mvl_vmd_type_id_destroy_all (vmd_ctrl);
|
||
|
||
/* Finally, free the tables and the VMD itself (allocated by mvl_vmd_create).*/
|
||
/* NOTE: can't do this for "mvl_vmd" because it was created by Foundry.*/
|
||
if (vmd_ctrl != &mvl_vmd)
|
||
{
|
||
if (vmd_ctrl->var_assoc_tbl)
|
||
chk_free (vmd_ctrl->var_assoc_tbl);
|
||
if (vmd_ctrl->nvlist_tbl)
|
||
chk_free (vmd_ctrl->nvlist_tbl);
|
||
if (vmd_ctrl->dom_tbl)
|
||
chk_free (vmd_ctrl->dom_tbl);
|
||
if (vmd_ctrl->jou_tbl)
|
||
chk_free (vmd_ctrl->jou_tbl);
|
||
chk_free (vmd_ctrl);
|
||
}
|
||
|
||
return (ret);
|
||
}
|
||
|
||
|