82 lines
2.5 KiB
C
82 lines
2.5 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2009, 2011 Fidelity Information Services, Inc *
|
||
|
* *
|
||
|
* This source code contains the intellectual property *
|
||
|
* of its copyright holder(s), and is made available *
|
||
|
* under a license. If you do not know the terms of *
|
||
|
* the license, please stop and do not read further. *
|
||
|
* *
|
||
|
****************************************************************/
|
||
|
|
||
|
#include "mdef.h"
|
||
|
|
||
|
#include "gtm_stdio.h"
|
||
|
#include "gtm_string.h"
|
||
|
|
||
|
#include "lv_val.h"
|
||
|
#include "gdsroot.h"
|
||
|
#include "gtm_facility.h"
|
||
|
#include "fileinfo.h"
|
||
|
#include "gdsbt.h"
|
||
|
#include "gdsfhead.h"
|
||
|
#include "alias.h"
|
||
|
|
||
|
GBLREF lv_val *active_lv;
|
||
|
GBLREF uint4 dollar_tlevel;
|
||
|
|
||
|
void lv_kill(lv_val *lv, boolean_t dotpsave, boolean_t do_subtree)
|
||
|
{
|
||
|
lv_val *base_lv;
|
||
|
lvTree *lvt_child, *lvt;
|
||
|
boolean_t is_base_var;
|
||
|
symval *sym;
|
||
|
|
||
|
active_lv = (lv_val *)NULL; /* if we get here, subscript set was successful. clear active_lv to avoid later
|
||
|
cleanup problems */
|
||
|
if (lv)
|
||
|
{
|
||
|
is_base_var = LV_IS_BASE_VAR(lv);
|
||
|
base_lv = !is_base_var ? LV_GET_BASE_VAR(lv) : lv;
|
||
|
if (dotpsave && dollar_tlevel && (NULL != base_lv->tp_var) && !base_lv->tp_var->var_cloned)
|
||
|
TP_VAR_CLONE(base_lv); /* clone the tree */
|
||
|
lvt_child = LV_GET_CHILD(lv);
|
||
|
if (do_subtree && (NULL != lvt_child))
|
||
|
{
|
||
|
LV_CHILD(lv) = NULL;
|
||
|
lv_killarray(lvt_child, dotpsave);
|
||
|
}
|
||
|
DECR_AC_REF(lv, dotpsave); /* Decrement alias container refs and cleanup if necessary */
|
||
|
if (!is_base_var && (do_subtree || (NULL == lvt_child)))
|
||
|
{
|
||
|
sym = LV_GET_SYMVAL(base_lv);
|
||
|
for ( ; ; )
|
||
|
{
|
||
|
lvt = LV_GET_PARENT_TREE(lv);
|
||
|
LV_VAL_CLEAR_MVTYPE(lv); /* see comment in macro definition for why this is necessary */
|
||
|
LV_TREE_NODE_DELETE(lvt, (lvTreeNode *)lv);
|
||
|
/* if there is at least one other sibling node to the deleted "lv" the zap stops here */
|
||
|
if (lvt->avl_height)
|
||
|
break;
|
||
|
assert(NULL == lvt->avl_root);
|
||
|
lv = (lv_val *)LVT_PARENT(lvt);
|
||
|
assert(NULL != lv);
|
||
|
LV_CHILD(lv) = NULL;
|
||
|
LVTREE_FREESLOT(lvt);
|
||
|
assert(LV_IS_VAL_DEFINED(lv) == (0 != lv->v.mvtype));
|
||
|
if (LV_IS_VAL_DEFINED(lv))
|
||
|
break;
|
||
|
if (lv == base_lv)
|
||
|
{ /* Base node. Do not invoke LV_FREESLOT/LV_FLIST_ENQUEUE as we will still keep the
|
||
|
* lv_val for the non-existing base local variable pointed to by the curr_symval
|
||
|
* hash table entry. Just clear mvtype to mark the lv_val undefined.
|
||
|
*/
|
||
|
lv->v.mvtype = 0; /* Base node */
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
} else
|
||
|
lv->v.mvtype = 0; /* Base node */
|
||
|
}
|
||
|
}
|