279 lines
6.5 KiB
C
279 lines
6.5 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 "gtm_string.h"
|
|
#include "gtm_strings.h"
|
|
#include "gdsroot.h"
|
|
#include "gdsblk.h"
|
|
#include "gtm_ctype.h"
|
|
#include "gtm_facility.h"
|
|
#include "gtm_stdlib.h"
|
|
#include "fileinfo.h"
|
|
#include "gdsbt.h"
|
|
#include "gdsfhead.h"
|
|
#include "min_max.h" /* needed for init_root_gv.h */
|
|
#include "init_root_gv.h"
|
|
#include "util.h"
|
|
#include "cli.h"
|
|
#include "stringpool.h"
|
|
#include "dse.h"
|
|
#include "mvalconv.h"
|
|
#include "op.h"
|
|
#include "format_targ_key.h"
|
|
|
|
#ifdef GTM_TRIGGER
|
|
#include "hashtab_mname.h"
|
|
#include <rtnhdr.h>
|
|
#include "gv_trigger.h" /* needed for INIT_ROOT_GVT */
|
|
#include "targ_alloc.h"
|
|
#endif
|
|
#ifdef UNICODE_SUPPORTED
|
|
#include "gtm_utf8.h"
|
|
#endif
|
|
|
|
GBLREF gv_key *gv_currkey;
|
|
GBLREF sgmnt_addrs *cs_addrs;
|
|
GBLREF gd_region *gv_cur_region;
|
|
GBLREF mval curr_gbl_root;
|
|
GBLREF gv_namehead *gv_target;
|
|
|
|
LITREF mval literal_hasht;
|
|
|
|
int dse_getki(char *dst, int *len, char *qual, int qual_len)
|
|
{
|
|
char buf[MAX_ZWR_KEY_SZ], *src, *temp_dst, *bot, *top, *tmp, slit[MAX_KEY_SZ + 1], key_buf[MAX_KEY_SZ + 1];
|
|
short int max_key;
|
|
unsigned short buf_len;
|
|
int key_len, dlr_num, dlr_len;
|
|
int num;
|
|
unsigned char *ptr;
|
|
mval key_subsc;
|
|
sgmnt_addrs *csa;
|
|
span_subs subs;
|
|
|
|
buf_len = SIZEOF(buf);
|
|
if (!cli_get_str(qual, buf, &buf_len))
|
|
return FALSE;
|
|
bot = temp_dst = (char *)&key_buf[0];
|
|
top = &buf[buf_len];
|
|
src = &buf[0];
|
|
if (*src++ != '^')
|
|
{
|
|
util_out_print("Error: invalid key.", TRUE);
|
|
return FALSE;
|
|
}
|
|
if ((*src >= 'A' && *src <= 'Z') ||
|
|
(*src >= 'a' && *src <= 'z') ||
|
|
(*src == '%') || (*src == '#')) /* first letter must be an alphabet or % or # */
|
|
{
|
|
*temp_dst++ = *src++;
|
|
} else
|
|
{
|
|
util_out_print("Error: invalid key.", TRUE);
|
|
return FALSE;
|
|
}
|
|
for ( ; *src != '(' && src < top ;src++)
|
|
{
|
|
if ((*src >= 'A' && *src <= 'Z') ||
|
|
(*src >= 'a' && *src <= 'z') ||
|
|
(*src >= '0' && *src <= '9'))
|
|
*temp_dst = *src;
|
|
else
|
|
{
|
|
util_out_print("Error: invalid key.", TRUE);
|
|
return FALSE;
|
|
}
|
|
temp_dst++;
|
|
}
|
|
*temp_dst = '\0';
|
|
|
|
csa = cs_addrs;
|
|
key_len = (int )(temp_dst - bot);
|
|
INIT_ROOT_GVT(bot, key_len, curr_gbl_root);
|
|
bot = (char *)&gv_currkey->base[0];
|
|
temp_dst = (char *)&gv_currkey->base[0] + gv_currkey->end;
|
|
max_key = gv_cur_region->max_key_size;
|
|
if ('(' == *src)
|
|
{
|
|
src++;
|
|
for (;;)
|
|
{
|
|
key_subsc.mvtype = MV_STR;
|
|
if ('$' == *src) /* may be a $char() */
|
|
{
|
|
src++;
|
|
if ((dlr_len = parse_dlr_char(src, top, slit)) > 0)
|
|
{
|
|
key_subsc.str.addr = slit;
|
|
key_subsc.str.len = STRLEN(slit);
|
|
src += dlr_len;
|
|
} else
|
|
{
|
|
util_out_print("Error: invalid key.", TRUE);
|
|
return FALSE;
|
|
}
|
|
} else if ('#' == *src)
|
|
{ /*Special spanning global subscript*/
|
|
if ('S' != toupper(*(src + 1)) && 'P' != toupper(*(src + 2))
|
|
&& 'A' != toupper(*(src + 3)) && 'N' != toupper(*(src + 4)))
|
|
{
|
|
util_out_print("Error: invalid key.", TRUE);
|
|
return FALSE;
|
|
}
|
|
src = src + SPAN_SUBS_LEN + 1;
|
|
for (num = 0, src++; *src != ')'; num = (num * DECIMAL_BASE + (int)(*src++ - ASCII_0)))
|
|
;
|
|
ptr = gv_currkey->base + gv_currkey->end;
|
|
num = num - 1;
|
|
SPAN_INITSUBS(&subs, num);
|
|
SPAN_SUBSCOPY_SRC2DST(ptr, (unsigned char *)&subs);
|
|
ptr = ptr + SPAN_SUBS_LEN;
|
|
*ptr++ = KEY_DELIMITER;
|
|
*ptr = KEY_DELIMITER;
|
|
gv_currkey->end = ptr - gv_currkey->base;
|
|
break;
|
|
} else if (*src != '\"') /* numerical subscript */
|
|
{
|
|
for (key_subsc.str.addr = src ; *src != ')' && *src != ','; src++)
|
|
{
|
|
if (src == top || (*src < '0' || *src > '9') && *src != '-' && *src != '.')
|
|
{
|
|
util_out_print("Error: invalid key.", TRUE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
key_subsc.str.len = INTCAST(src - key_subsc.str.addr);
|
|
s2n(&key_subsc);
|
|
key_subsc.mvtype &= MV_NUM_MASK;
|
|
} else
|
|
{
|
|
src++;
|
|
tmp = slit;
|
|
for (;;)
|
|
{
|
|
if (src == top)
|
|
{
|
|
util_out_print("Error: invalid key.", TRUE);
|
|
return FALSE;
|
|
}
|
|
if (*src == '\"')
|
|
if (*++src != '\"')
|
|
break;
|
|
*tmp++ = *src++;
|
|
}
|
|
key_subsc.str.addr = slit;
|
|
key_subsc.str.len = INTCAST(tmp - slit);
|
|
}
|
|
if ( 0 == key_subsc.str.len && NEVER == cs_addrs->hdr->null_subs)
|
|
{
|
|
util_out_print("Error: Null subscripts not allowed", TRUE);
|
|
return FALSE;
|
|
}
|
|
mval2subsc(&key_subsc, gv_currkey);
|
|
if (gv_currkey->end >= max_key)
|
|
ISSUE_GVSUBOFLOW_ERROR(gv_currkey);
|
|
if (*src != ',')
|
|
break;
|
|
src++;
|
|
}
|
|
if (*src++ != ')')
|
|
{
|
|
util_out_print("Error: invalid key.", TRUE);
|
|
return FALSE;
|
|
}
|
|
temp_dst = (char *)&gv_currkey->base[0] + gv_currkey->end;
|
|
}
|
|
if (src != top)
|
|
{
|
|
util_out_print("Error: invalid key.", TRUE);
|
|
return FALSE;
|
|
}
|
|
*len = (int)(temp_dst - bot + 1);
|
|
memcpy(dst, &gv_currkey->base[0], *len);
|
|
return TRUE;
|
|
}
|
|
|
|
int parse_dlr_char(char *src, char *top, char *dlr_subsc)
|
|
{
|
|
int indx = 0, dlr_len, dlr_val, harlen;
|
|
char lcl_buf[MAX_KEY_SZ + 1];
|
|
char *tmp_buf, *strnext;
|
|
boolean_t dlrzchar = FALSE;
|
|
|
|
tmp_buf = src;
|
|
|
|
if ('Z' == TOUPPER(*tmp_buf))
|
|
{
|
|
dlrzchar = TRUE;
|
|
tmp_buf++;
|
|
}
|
|
if ('C' != TOUPPER(*tmp_buf++))
|
|
return 0;
|
|
if ('H' == TOUPPER(*tmp_buf))
|
|
{
|
|
if (top - tmp_buf <= STR_LIT_LEN("har") || STRNCASECMP(tmp_buf, "har", STR_LIT_LEN("har")))
|
|
{
|
|
if (!dlrzchar)
|
|
return 0;
|
|
tmp_buf++;
|
|
}
|
|
else
|
|
tmp_buf += STR_LIT_LEN("har");
|
|
|
|
} else if (dlrzchar)
|
|
return 0;
|
|
|
|
if (*tmp_buf++ != '(')
|
|
return 0;
|
|
if (!ISDIGIT_ASCII(*tmp_buf))
|
|
return 0;
|
|
while (tmp_buf != top)
|
|
{
|
|
if (ISDIGIT_ASCII(*tmp_buf))
|
|
lcl_buf[indx++] = *tmp_buf;
|
|
else if (',' == *tmp_buf || ')' == *tmp_buf)
|
|
{
|
|
lcl_buf[indx] = '\0';
|
|
dlr_val = ATOI(lcl_buf);
|
|
if (0 > dlr_val)
|
|
return 0;
|
|
if (!gtm_utf8_mode || dlrzchar)
|
|
{
|
|
if (255 < dlr_val)
|
|
return 0;
|
|
*dlr_subsc++ = dlr_val;
|
|
}
|
|
#ifdef UNICODE_SUPPORTED
|
|
else {
|
|
strnext = (char *)UTF8_WCTOMB(dlr_val, dlr_subsc);
|
|
if (strnext == dlr_subsc)
|
|
return 0;
|
|
dlr_subsc = strnext;
|
|
}
|
|
#endif
|
|
indx = 0;
|
|
if (')' == *tmp_buf)
|
|
{
|
|
*dlr_subsc = '\0';
|
|
break;
|
|
}
|
|
} else
|
|
return 0;
|
|
tmp_buf++;
|
|
}
|
|
if (tmp_buf == top)
|
|
return 0;
|
|
tmp_buf++;
|
|
return (int)(tmp_buf - src);
|
|
}
|