496 lines
12 KiB
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);
|
|
}
|