fis-gtm/sr_port/view_arg_convert.c

284 lines
9.8 KiB
C

/****************************************************************
* *
* Copyright 2001, 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_string.h"
#include "buddy_list.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "view.h"
#include "toktyp.h"
#include "targ_alloc.h"
#include "valid_mname.h"
#include "dpgbldir.h"
#include "lv_val.h" /* needed for "symval" structure */
#include "min_max.h"
LITREF mval literal_one;
GBLREF gd_addr *gd_header;
GBLREF gvt_container *gvt_pending_list;
GBLREF buddy_list *gvt_pending_buddy_list;
GBLREF symval *curr_symval;
static buddy_list *noisolation_buddy_list; /* a buddy_list for maintaining the globals that are noisolated */
void view_arg_convert(viewtab_entry *vtp, mval *parm, viewparm *parmblk)
{
static int4 first_time = TRUE;
int n, res;
ht_ent_mname *tabent;
mstr tmpstr, namestr;
gd_region *r_top, *r_ptr;
mname_entry gvent, lvent;
mident_fixed lcl_buff;
unsigned char global_names[1024], stashed;
noisolation_element *gvnh_entry;
unsigned char *src, *nextsrc, *src_top, *dst, *dst_top, y;
gd_binding *temp_gd_map, *temp_gd_map_top;
gv_namehead *temp_gv_target;
gvt_container *gvtc;
gvnh_reg_t *gvnh_reg;
error_def(ERR_VIEWARGCNT);
error_def(ERR_NOREGION);
error_def(ERR_VIEWGVN);
error_def(ERR_VIEWLVN);
switch(vtp->parm)
{
case VTP_NULL:
if (parm != 0)
rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
break;
case (VTP_NULL | VTP_VALUE):
if (NULL == parm)
{
parmblk->value = (mval *)&literal_one;
break;
}
/* caution: fall through */
case VTP_VALUE:
if (NULL == parm)
rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
parmblk->value = parm;
break;
case (VTP_NULL | VTP_DBREGION):
if (NULL == parm)
{
parmblk->gv_ptr = 0;
break;
}
/* caution: fall through */
case VTP_DBREGION:
if (NULL == parm)
rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
if (!gd_header) /* IF GD_HEADER ==0 THEN OPEN GBLDIR */
gvinit();
r_ptr = gd_header->regions;
if (!parm->str.len && vtp->keycode == VTK_GVNEXT) /* "" => 1st region */
parmblk->gv_ptr = r_ptr;
else
{
for (r_top = r_ptr + gd_header->n_regions; ; r_ptr++)
{
if (r_ptr >= r_top)
rts_error(VARLSTCNT(4) ERR_NOREGION,2, parm->str.len, parm->str.addr);
tmpstr.len = r_ptr->rname_len;
tmpstr.addr = (char *) r_ptr->rname;
MSTR_CMP(tmpstr, parm->str, n);
if (0 == n)
break;
}
parmblk->gv_ptr = r_ptr;
}
break;
case VTP_DBKEY:
if (NULL == parm)
rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
if (!gd_header) /* IF GD_HEADER ==0 THEN OPEN GBLDIR */
gvinit();
memset(&parmblk->ident.c[0], 0, SIZEOF(parmblk->ident));
if (parm->str.len >= 2 && *parm->str.addr == '^')
{
namestr.addr = parm->str.addr + 1; /* skip initial '^' */
namestr.len = parm->str.len - 1;
if (namestr.len > MAX_MIDENT_LEN)
namestr.len = MAX_MIDENT_LEN;
if (valid_mname(&namestr))
memcpy(&parmblk->ident.c[0], namestr.addr, namestr.len);
else
rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, parm->str.len, parm->str.addr);
} else
rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, parm->str.len, parm->str.addr);
break;
case VTP_RTNAME:
if (NULL == parm)
rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
memset(&parmblk->ident.c[0], 0, SIZEOF(parmblk->ident));
if (parm->str.len > 0)
memcpy(&parmblk->ident.c[0], parm->str.addr,
(parm->str.len <= MAX_MIDENT_LEN ? parm->str.len : MAX_MIDENT_LEN));
break;
case VTP_NULL | VTP_DBKEYLIST:
if (NULL == parm || 0 == parm->str.len)
{
parmblk->ni_list.gvnh_list = NULL;
parmblk->ni_list.type = NOISOLATION_NULL;
break;
}
/* caution : explicit fall through */
case VTP_DBKEYLIST:
if (NULL == parm)
rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
if (!gd_header)
gvinit();
if (first_time)
{
noisolation_buddy_list = (buddy_list *)malloc(SIZEOF(buddy_list));
initialize_list(noisolation_buddy_list, SIZEOF(noisolation_element), NOISOLATION_INIT_ALLOC);
gvt_pending_buddy_list = (buddy_list *)malloc(SIZEOF(buddy_list));
initialize_list(gvt_pending_buddy_list, SIZEOF(gvt_container), NOISOLATION_INIT_ALLOC);
first_time = FALSE;
}
if (SIZEOF(global_names) <= parm->str.len)
GTMASSERT;
tmpstr.len = parm->str.len; /* we need to change len and should not change parm->str, so take a copy */
tmpstr.addr = parm->str.addr;
if (0 != tmpstr.len)
{
switch (*tmpstr.addr)
{
case '+' :
parmblk->ni_list.type = NOISOLATION_PLUS;
tmpstr.addr++;
tmpstr.len--;
break;
case '-' :
parmblk->ni_list.type = NOISOLATION_MINUS;
tmpstr.addr++;
tmpstr.len--;
break;
default :
parmblk->ni_list.type = NOISOLATION_NULL;
break;
}
memcpy(global_names, tmpstr.addr, tmpstr.len);
global_names[tmpstr.len] = '\0';
src = (unsigned char *)strtok((char *)global_names, ",");
REINITIALIZE_LIST(noisolation_buddy_list); /* reinitialize the noisolation buddy_list */
parmblk->ni_list.gvnh_list = NULL;
for ( ; src < &global_names[tmpstr.len + 1]; src = nextsrc)
{
nextsrc = (unsigned char *)strtok(NULL, ",");
if (NULL == nextsrc)
nextsrc = &global_names[tmpstr.len + 1];
if (nextsrc - src >= 2 && '^' == *src)
{
namestr.addr = (char *)src + 1; /* skip initial '^' */
namestr.len = INTCAST(nextsrc - src - 2); /* don't count initial ^ and trailing 0 */
if (namestr.len > MAX_MIDENT_LEN)
namestr.len = MAX_MIDENT_LEN;
if (valid_mname(&namestr))
{
memcpy(&lcl_buff.c[0], namestr.addr, namestr.len);
gvent.var_name.len = namestr.len;
} else
rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, nextsrc - src - 1, src);
} else
rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, nextsrc - src - 1, src);
temp_gv_target = NULL;
gvent.var_name.addr = &lcl_buff.c[0];
COMPUTE_HASH_MNAME(&gvent);
if (NULL == (tabent = lookup_hashtab_mname(gd_header->tab_ptr, &gvent))
|| (NULL == (gvnh_reg = (gvnh_reg_t *)tabent->value)))
{
temp_gd_map = gd_header->maps;
temp_gd_map_top = temp_gd_map + gd_header->n_maps;
temp_gd_map++; /* get past local locks */
for (; (res = memcmp(gvent.var_name.addr, &(temp_gd_map->name[0]),
gvent.var_name.len)) >= 0; temp_gd_map++)
{
assert (temp_gd_map < temp_gd_map_top);
if (0 == res && 0 != temp_gd_map->name[gvent.var_name.len])
break;
}
r_ptr = temp_gd_map->reg.addr;
assert(r_ptr->max_key_size <= MAX_KEY_SZ);
temp_gv_target = (gv_namehead *)targ_alloc(r_ptr->max_key_size, &gvent, r_ptr);
gvnh_reg = (gvnh_reg_t *)malloc(SIZEOF(gvnh_reg_t));
gvnh_reg->gvt = temp_gv_target;
gvnh_reg->gd_reg = r_ptr;
if (NULL != tabent)
{ /* Since the global name was found but gv_target was null and
* now we created a new gv_target, the hash table key must point
* to the newly created gv_target->gvname. */
tabent->key = temp_gv_target->gvname;
tabent->value = (char *)gvnh_reg;
} else
{
if (!add_hashtab_mname((hash_table_mname *)gd_header->tab_ptr,
&temp_gv_target->gvname, gvnh_reg, &tabent))
GTMASSERT;
}
if (!r_ptr->open)
{ /* Record list of all gv_targets that have been allocated BEFORE the
* region has been opened. Once the region gets opened, we will re-examine
* this list and reallocate them (if needed) since they have now been
* allocated using the region's max_key_size value which could potentially
* be different from the max_key_size value in the corresponding database
* file header.
*/
gvtc = (gvt_container *)get_new_free_element(gvt_pending_buddy_list);
gvtc->gvnh_reg = gvnh_reg;
assert(!gvtc->gvnh_reg->gd_reg->open);
gvtc->next_gvtc = (struct gvt_container_struct *)gvt_pending_list;
gvt_pending_list = gvtc;
}
} else
temp_gv_target = gvnh_reg->gvt;
gvnh_entry = (noisolation_element *)get_new_element(noisolation_buddy_list, 1);
gvnh_entry->gvnh = temp_gv_target;
gvnh_entry->next = parmblk->ni_list.gvnh_list;
parmblk->ni_list.gvnh_list = gvnh_entry;
}
} else
rts_error(VARLSTCNT(4) ERR_VIEWGVN, 2, tmpstr.len, tmpstr.addr);
break;
case VTP_LVN:
if (NULL == parm)
rts_error(VARLSTCNT(4) ERR_VIEWARGCNT, 2, strlen((const char *)vtp->keyword), vtp->keyword);
if (0 < parm->str.len)
{
lvent.var_name.addr = parm->str.addr;
lvent.var_name.len = parm->str.len;
if (lvent.var_name.len > MAX_MIDENT_LEN)
lvent.var_name.len = MAX_MIDENT_LEN;
if (!valid_mname(&lvent.var_name))
rts_error(VARLSTCNT(4) ERR_VIEWLVN, 2, parm->str.len, parm->str.addr);
} else
rts_error(VARLSTCNT(4) ERR_VIEWLVN, 2, parm->str.len, parm->str.addr);
/* Now look up the name.. */
COMPUTE_HASH_MNAME(&lvent);
if ((tabent = lookup_hashtab_mname(&curr_symval->h_symtab, &lvent)) && (NULL != tabent->value))
parmblk->value = (mval *)tabent->value; /* Return lv_val ptr */
else
rts_error(VARLSTCNT(4) ERR_VIEWLVN, 2, parm->str.len, parm->str.addr);
break;
default:
GTMASSERT;
}
}