fis-gtm/sr_port/op_gvnaked.c

116 lines
3.4 KiB
C

/****************************************************************
* *
* Copyright 2001, 2012 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 <stdarg.h>
#include "gtm_string.h"
#include "gdsroot.h"
#include "gdskill.h"
#include "gdsblk.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "filestruct.h"
#include "gdscc.h"
#include "copy.h"
#include "jnl.h"
#include "hashtab_int4.h" /* needed for tp.h */
#include "buddy_list.h" /* needed for tp.h */
#include "tp.h"
#include <rtnhdr.h>
#include "mv_stent.h" /* for COPY_SUBS_TO_GVCURRKEY macro */
#include "subscript.h"
#include "op.h"
#include "gvcst_protos.h" /* for gvcst_root_search prototype */
#include "format_targ_key.h"
#include "gvsub2str.h"
#include "sgnl.h"
#include "mvalconv.h"
#include "tp_set_sgm.h"
GBLREF uint4 dollar_tlevel;
GBLREF gd_addr *gd_header;
GBLREF gv_key *gv_currkey;
GBLREF gv_namehead *gv_target;
GBLREF sgmnt_addrs *cs_addrs;
GBLREF gd_region *gv_cur_region;
GBLREF sgm_info *first_sgm_info;
GBLREF mstr extnam_str;
error_def(ERR_GVNAKED);
error_def(ERR_MAXNRSUBSCRIPTS);
void op_gvnaked(UNIX_ONLY_COMMA(int count_arg) mval *val_arg, ...)
{
va_list var;
int count;
bool was_null, is_null, sbs_cnt;
mval *val;
short max_key;
unsigned char *ptr, *end_ptr;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
extnam_str.len = 0;
if (!gv_currkey || (0 == gv_currkey->prev) || (0 == gv_currkey->end))
rts_error(VARLSTCNT(1) ERR_GVNAKED);
if ((dba_bg == gv_cur_region->dyn.addr->acc_meth) || (dba_mm == gv_cur_region->dyn.addr->acc_meth))
{
assert(INVALID_GV_TARGET != gv_target);
if (dollar_tlevel)
tp_set_sgm();
GVCST_ROOT_SEARCH;
assert(gv_target->gd_csa == cs_addrs);
}
VMS_ONLY(va_count(count));
UNIX_ONLY(count = count_arg;) /* i386 assembler modules may depend on unchanged count */
if (0 >= count)
GTMASSERT;
gv_currkey->end = gv_currkey->prev;
is_null = FALSE;
assert(gv_currkey->end);
was_null = TREF(gv_some_subsc_null);
sbs_cnt = 0;
if (1 < count)
{
/* Use of naked reference can cause increase in number of subscripts. So count the subscripts */
ptr = gv_currkey->base;
end_ptr = ptr + gv_currkey->end;
while (ptr < end_ptr)
if (KEY_DELIMITER == *ptr++)
sbs_cnt++;
if (MAX_GVSUBSCRIPTS < count + sbs_cnt)
rts_error(VARLSTCNT(1) ERR_MAXNRSUBSCRIPTS);
}
/* else naked reference will not increase number of subscripts, so do not worry about exceeding the limit */
VAR_START(var, val_arg);
val = val_arg;
max_key = gv_cur_region->max_key_size;
for ( ; ; )
{
COPY_SUBS_TO_GVCURRKEY(val, max_key, gv_currkey, was_null, is_null); /* updates gv_currkey, was_null, is_null */
if (0 < --count)
val = va_arg(var, mval *);
else
break;
}
va_end(var);
TREF(gv_some_subsc_null) = was_null; /* if true, it indicates there is a null subscript (other than the last subscript)
in current key */
TREF(gv_last_subsc_null) = is_null; /* if true, it indicates that last subscript in current key is null */
if (was_null && (NEVER == gv_cur_region->null_subs))
sgnl_gvnulsubsc();
return;
}