fis-gtm/sr_port/op_fnview.c

496 lines
12 KiB
C

/****************************************************************
* *
* Copyright 2001, 2013 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 "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "dpgbldir.h"
#include "filestruct.h"
#include "jnl.h"
#include "view.h"
#include "stringpool.h"
#include "cmd_qlf.h"
#include "hashtab_mname.h" /* needed for cmmdef.h */
#include "cmidef.h"
#include "cmmdef.h"
#include "tp_frame.h"
#include "collseq.h"
#include "error.h"
#include "op.h"
#include "patcode.h"
#include "mvalconv.h"
#include "lv_val.h"
#include "alias.h"
#include "gtmimagename.h"
#include "fullbool.h"
#include "wbox_test_init.h"
GBLREF spdesc stringpool;
GBLREF int4 cache_hits, cache_fails;
GBLREF unsigned char *stackbase, *stacktop;
GBLREF gd_addr *gd_header;
GBLREF gd_binding *gd_map;
GBLREF gd_binding *gd_map_top;
GBLREF boolean_t certify_all_blocks;
GBLREF sgmnt_addrs *cs_addrs;
GBLREF gv_namehead *gv_target;
GBLREF gv_namehead *reset_gv_target;
GBLREF jnl_fence_control jnl_fence_ctl;
GBLREF bool undef_inhibit;
GBLREF int4 break_message_mask;
GBLREF command_qualifier cmd_qlf;
GBLREF tp_frame *tp_pointer;
GBLREF uint4 dollar_tlevel;
GBLREF int4 zdir_form;
GBLREF boolean_t badchar_inhibit;
GBLREF boolean_t gvdupsetnoop; /* if TRUE, duplicate SETs update journal but not database blocks */
GBLREF int gv_fillfactor;
GBLREF int4 gtm_max_sockets;
error_def(ERR_VIEWFN);
LITREF gtmImageName gtmImageNames[];
LITREF mval literal_zero;
LITREF mval literal_one;
void op_fnview(UNIX_ONLY_COMMA(int numarg) mval *dst, ...)
{
va_list var;
VMS_ONLY(int numarg;)
mval *keyword;
mval *arg;
mstr tmpstr;
int n;
mval v;
viewparm parmblk;
gd_binding *map;
gd_region *reg;
sgmnt_addrs *csa;
short tl, newlevel;
tp_frame *tf;
viewtab_entry *vtp;
collseq *csp;
lv_val *lv;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
VMS_ONLY(va_count(numarg));
if (numarg < 2)
GTMASSERT;
VAR_START(var, dst);
keyword = va_arg(var, mval *);
MV_FORCE_STR(keyword);
numarg -= 2; /* remove destination and keyword from count */
if (numarg > 0)
{
arg = va_arg(var, mval *);
MV_FORCE_STR(arg);
} else
arg = (mval *)NULL;
va_end(var);
vtp = viewkeys(&keyword->str);
view_arg_convert(vtp, arg, &parmblk);
switch (vtp->keycode)
{
# ifdef UNICODE_SUPPORTED
case VTK_BADCHAR:
n = badchar_inhibit ? 0 : 1;
break;
# endif
case VTK_RCHITS:
n = 0;
break;
case VTK_RCMISSES:
n = 0;
break;
case VTK_RCSIZE:
n = 0;
break;
case VTK_STKSIZ:
n = (int)(stackbase - stacktop);
break;
case VTK_ICSIZE:
n = 0; /* must change run-time structure */
break;
case VTK_ICHITS:
n = cache_hits;
break;
case VTK_ICMISS:
n = cache_fails;
break;
case VTK_SPSIZE:
n = (int)(stringpool.top - stringpool.base);
break;
case VTK_GDSCERT:
if (certify_all_blocks)
*dst = literal_one;
else
*dst = literal_zero;
break;
case VTK_GVACC_METH:
assert(gd_header);
assert(parmblk.gv_ptr);
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
assert(parmblk.gv_ptr->open);
switch (parmblk.gv_ptr->dyn.addr->acc_meth)
{
case dba_mm:
tmpstr.addr = "MM";
tmpstr.len = SIZEOF("MM")-1;
break;
case dba_bg:
tmpstr.addr = "BG";
tmpstr.len = SIZEOF("BG")-1;
break;
case dba_cm:
tmpstr.addr = "CM";
tmpstr.len = SIZEOF("CM")-1;
break;
case dba_usr:
tmpstr.addr = "USR";
tmpstr.len = SIZEOF("USR")-1;
break;
default:
GTMASSERT;
}
dst->str = tmpstr;
break;
case VTK_FULLBOOL:
switch (TREF(gtm_fullbool))
{
case GTM_BOOL:
tmpstr.addr = "GT.M Boolean short-circuit";
tmpstr.len = SIZEOF("GT.M Boolean short-circuit")-1;
break;
case FULL_BOOL:
tmpstr.addr = "Standard Boolean evaluation side effects";
tmpstr.len = SIZEOF("Standard Boolean evaluation side effects")-1;
break;
case FULL_BOOL_WARN:
tmpstr.addr = "Boolean side-effect warning";
tmpstr.len = SIZEOF("Boolean side-effect warning")-1;
break;
default:
GTMASSERT;
}
dst->str = tmpstr;
break;
case VTK_GVDUPSETNOOP:
if (gvdupsetnoop)
*dst = literal_one;
else
*dst = literal_zero;
break;
case VTK_GVFILE:
assert(gd_header);
assert(parmblk.gv_ptr);
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
tmpstr.addr = (char *)parmblk.gv_ptr->dyn.addr->fname;
tmpstr.len = parmblk.gv_ptr->dyn.addr->fname_len;
s2pool(&tmpstr);
dst->str = tmpstr;
break;
case VTK_GVFIRST:
if (!gd_header) /* IF GD_HEADER ==0 THEN OPEN GBLDIR */
gvinit();
tmpstr.addr = (char *)gd_header->regions->rname;
tmpstr.len = gd_header->regions->rname_len;
s2pool(&tmpstr);
dst->str = tmpstr;
break;
case VTK_GVNEXT:
assert(gd_header);
if (arg->str.len)
parmblk.gv_ptr++;
if (parmblk.gv_ptr - gd_header->regions >= gd_header->n_regions)
dst->str.len = 0;
else
{
tmpstr.addr = (char *)parmblk.gv_ptr->rname;
tmpstr.len = parmblk.gv_ptr->rname_len;
s2pool(&tmpstr);
dst->str = tmpstr;
}
break;
case VTK_JNLACTIVE:
assert(gd_header);
if (parmblk.gv_ptr)
{
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
csa = &FILE_INFO(parmblk.gv_ptr)->s_addrs;
if (NULL != csa->hdr)
n = csa->hdr->jnl_state;
else
n = -1;
} else
n = 0;
break;
case VTK_JNLFILE:
assert(gd_header);
if (parmblk.gv_ptr)
{
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
csa = &FILE_INFO(parmblk.gv_ptr)->s_addrs;
if (NULL != csa->hdr)
view_jnlfile(dst, parmblk.gv_ptr);
else
dst->str.len = 0;
} else
dst->str.len = 0;
break;
case VTK_JNLTRANSACTION:
n = jnl_fence_ctl.level;
break;
case VTK_LABELS:
n = (cmd_qlf.qlf & CQ_LOWER_LABELS) ? 1 : 0;
break;
case VTK_LVNULLSUBS:
n = TREF(lv_null_subs);
break;
case VTK_NOISOLATION:
if (NOISOLATION_NULL != parmblk.ni_list.type || NULL == parmblk.ni_list.gvnh_list
|| NULL != parmblk.ni_list.gvnh_list->next)
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_VIEWFN);
n = parmblk.ni_list.gvnh_list->gvnh->noisolation;
break;
case VTK_PATCODE:
getpattabnam(&tmpstr);
s2pool(&tmpstr);
dst->str = tmpstr;
break;
#ifdef DEBUG
case VTK_PROBECRIT:
if (!gd_header) /* IF GD_HEADER ==0 THEN OPEN GBLDIR */
gvinit();
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
reg = parmblk.gv_ptr;
grab_crit(reg);
if (!WBTEST_ENABLED(WBTEST_HOLD_CRIT_ENABLED))
rel_crit(reg);
break;
#endif
case VTK_REGION:
/* if gd_header is null then get the current one, and update the gd_map */
if (!gd_header)
{
SET_GD_HEADER(v);
SET_GD_MAP;
}
DEBUG_ONLY(else GD_HEADER_ASSERT);
map = gd_map;
map++; /* get past local locks */
for (; memcmp(parmblk.ident.c, map->name, SIZEOF(mident_fixed)) >= 0; map++)
assert(map < gd_map_top);
reg = map->reg.addr;
tmpstr.addr = (char *)reg->rname;
tmpstr.len = reg->rname_len;
s2pool(&tmpstr);
dst->str = tmpstr;
break;
case VTK_RTNEXT:
view_routines(dst, &parmblk.ident);
break;
case VTK_UNDEF:
n = (undef_inhibit ? 0 : 1);
break;
case VTK_BREAKMSG:
n = break_message_mask;
break;
case VTK_BLFREE:
assert(gd_header);
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
csa = &FILE_INFO(parmblk.gv_ptr)->s_addrs;
if (NULL != csa->hdr)
n = csa->hdr->trans_hist.free_blocks;
else
n = -1;
break;
case VTK_BLTOTAL:
assert(gd_header);
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
csa = &FILE_INFO(parmblk.gv_ptr)->s_addrs;
if (NULL != csa->hdr)
{
n = csa->hdr->trans_hist.total_blks;
n -= (n + csa->hdr->bplmap - 1) / csa->hdr->bplmap;
} else
n = -1;
break;
case VTK_FREEZE:
assert(gd_header);
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
csa = &FILE_INFO(parmblk.gv_ptr)->s_addrs;
if (NULL != csa->hdr)
n = csa->hdr->freeze;
else
n = -1;
break;
case VTK_GVSTATS:
assert(gd_header);
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
csa = &FILE_INFO(parmblk.gv_ptr)->s_addrs;
if (NULL != csa->hdr)
{
# define GVSTATS_MAX_DIGITS MAX_DIGITS_IN_INT8
# define GVSTATS_KEYWORD_SIZE 5 /* THREE PLUS TWO DELIMITERS */
# define GVSTATS_KEYWORD_COUNT n_gvstats_rec_types
# define GVSTATS_MAX_SIZE (GVSTATS_KEYWORD_COUNT * (GVSTATS_MAX_DIGITS + GVSTATS_KEYWORD_SIZE))
ENSURE_STP_FREE_SPACE(GVSTATS_MAX_SIZE);
dst->str.addr = (char *)stringpool.free;
/* initialize cnl->gvstats_rec.db_curr_tn field from file header */
csa->nl->gvstats_rec.db_curr_tn = csa->hdr->trans_hist.curr_tn;
# define GVSTATS_PUT_PARM(TXT, CNTR, cnl) \
{ \
MEMCPY_LIT(stringpool.free, TXT); \
stringpool.free += STR_LIT_LEN(TXT); \
*stringpool.free++ = ':'; \
stringpool.free = i2ascl(stringpool.free, cnl->gvstats_rec.CNTR); \
*stringpool.free++ = ','; \
}
# define TAB_GVSTATS_REC(COUNTER,TEXT1,TEXT2) GVSTATS_PUT_PARM(TEXT1, COUNTER, csa->nl)
# include "tab_gvstats_rec.h"
# undef TAB_GVSTATS_REC
assert(stringpool.free < stringpool.top);
/* subtract one to remove extra trailing delimiter */
dst->str.len = INTCAST((char *)stringpool.free - dst->str.addr - 1);
} else
dst->str.len = 0;
break;
case VTK_TID:
newlevel = MV_FORCE_INT(parmblk.value);
if (!tp_pointer || newlevel <= 0)
dst->str.len = 0;
else
{
tl = dollar_tlevel;
tf = tp_pointer;
while (tl > newlevel)
{
tf = tf->old_tp_frame;
tl--;
}
*dst = tf->trans_id;
}
break;
case VTK_YCOLLATE:
n = MV_FORCE_INT(parmblk.value);
csp = ready_collseq(n);
if (csp)
{
n = (*csp->version)();
n &= 0x000000FF; /* make an unsigned char, essentially */
} else
n = -1;
break;
case VTK_YDIRTREE:
op_gvname(VARLSTCNT(1) parmblk.value);
assert(INVALID_GV_TARGET == reset_gv_target);
reset_gv_target = gv_target;
gv_target = cs_addrs->dir_tree; /* Trick the get program into using the directory tree */
op_gvget(dst);
RESET_GV_TARGET(DO_GVT_GVKEY_CHECK);
break;
case VTK_YLCT:
n = -1;
if (arg)
{
if (0 == MEMCMP_LIT(arg->str.addr, "nct"))
n = TREF(local_coll_nums_as_strings) ? 1 : 0;
else if (0 == MEMCMP_LIT(arg->str.addr, "ncol"))
n = TREF(local_collseq_stdnull);
} else
n = TREF(local_collseq) ? (TREF(local_collseq))->act : 0;
break;
case VTK_ZDEFBUFF:
n = 0;
assert(gd_header);
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
reg = parmblk.gv_ptr;
if (dba_cm == reg->dyn.addr->acc_meth)
n = ((link_info *)reg->dyn.addr->cm_blk->usr)->buffer_size;
break;
case VTK_ZDEFCNT:
n = 0;
assert(gd_header);
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
reg = parmblk.gv_ptr;
if (dba_cm == reg->dyn.addr->acc_meth)
n = ((link_info *)reg->dyn.addr->cm_blk->usr)->buffered_count;
break;
case VTK_ZDEFSIZE:
n = 0;
assert(gd_header);
if (!parmblk.gv_ptr->open)
gv_init_reg(parmblk.gv_ptr);
reg = parmblk.gv_ptr;
if (dba_cm == reg->dyn.addr->acc_meth)
n = ((link_info *)reg->dyn.addr->cm_blk->usr)->buffer_used;
break;
case VTK_ZDIR_FORM:
n = zdir_form;
break;
case VTK_FILLFACTOR:
n = gv_fillfactor;
break;
case VTK_MAXSOCKETS:
n = gtm_max_sockets;
break;
case VTK_LVCREF:
lv = (lv_val *)parmblk.value;
assert(LV_IS_BASE_VAR(lv));
n = lv->stats.crefcnt;
break;
case VTK_LVREF:
lv = (lv_val *)parmblk.value;
assert(LV_IS_BASE_VAR(lv));
n = lv->stats.trefcnt;
break;
case VTK_LVGCOL:
n = als_lvval_gc();
break;
case VTK_IMAGENAME:
dst->str.len = gtmImageNames[image_type].imageNameLen;
dst->str.addr = gtmImageNames[image_type].imageName;
break;
case VTK_LOGTPRESTART:
n = TREF(tprestart_syslog_delta);
break;
# ifndef VMS
case VTK_JNLERROR:
n = TREF(error_on_jnl_file_lost);
break;
# endif
default:
rts_error_csa(CSA_ARG(NULL) VARLSTCNT(1) ERR_VIEWFN);
}
dst->mvtype = vtp->restype;
if (MV_NM == vtp->restype)
MV_FORCE_MVAL(dst, n);
}