fis-gtm/sr_port/indirection.c

109 lines
3.2 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 "gtm_string.h" /* needed by INCREMENT_EXPR_DEPTH */
#include "compiler.h"
#include "opcode.h"
#include "mdq.h"
#include "toktyp.h"
#include "advancewindow.h"
#include "fullbool.h"
#include "show_source_line.h"
#include "stringpool.h"
GBLREF boolean_t run_time;
GBLREF char *lexical_ptr;
GBLREF spdesc stringpool;
GBLREF unsigned char *source_buffer;
GBLREF short int source_column;
error_def(ERR_BOOLSIDEFFECT);
error_def(ERR_EXPR);
error_def(ERR_LPARENMISSING);
error_def(ERR_MAXNRSUBSCRIPTS);
error_def(ERR_RPARENMISSING);
error_def(ERR_SIDEEFFECTEVAL);
int indirection(oprtype *a)
{
char c;
oprtype *sb1, *sb2, subs[MAX_INDSUBSCRIPTS], x;
triple *next, *ref;
int parens, oldlen, len;
char *start, *end, *oldend;
boolean_t concat_athashes;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
assert(TK_ATSIGN == TREF(window_token));
concat_athashes = (2 == source_column);
INCREMENT_EXPR_DEPTH;
advancewindow();
if (!expratom(a))
{
DECREMENT_EXPR_DEPTH;
stx_error(ERR_EXPR);
return FALSE;
}
coerce(a, OCT_MVAL);
ex_tail(a);
ENCOUNTERED_SIDE_EFFECT;
DECREMENT_EXPR_DEPTH;
if ((TK_ATSIGN == TREF(window_token)) || ((TK_ATHASH == TREF(window_token)) && concat_athashes))
{
(TREF(indirection_mval)).mvtype = 0;
(TREF(indirection_mval)).str.len = 0;
do {
start = lexical_ptr;
advancewindow();
if (TK_LPAREN != TREF(window_token))
{
stx_error(ERR_LPARENMISSING);
return FALSE;
}
advancewindow();
if (!parse_until_rparen_or_space() || (TK_RPAREN != TREF(window_token)))
{
stx_error(ERR_RPARENMISSING);
return FALSE;
}
end = (char *)source_buffer + (INTPTR_T)source_column - 1; /* lexical_ptr before last advancewindow */
len = INTCAST(end - start);
oldlen = (TREF(indirection_mval)).str.len;
ENSURE_STP_FREE_SPACE(oldlen + len);
/* Ok to copy from beginning each iteration because we generally expect no more than two iterations,
* and that's with nested indirection.
*/
memcpy(stringpool.free, (TREF(indirection_mval)).str.addr, oldlen);
if (oldlen)
{
oldend = (char *)stringpool.free + oldlen - 1;
assert(*oldend == ')');
*oldend = ',';
}
(TREF(indirection_mval)).mvtype = MV_STR;
(TREF(indirection_mval)).str.addr = (char *)stringpool.free;
(TREF(indirection_mval)).str.len = oldlen + len;
stringpool.free += oldlen;
memcpy(stringpool.free, start, len);
stringpool.free += len;
advancewindow();
} while ((TK_ATHASH == TREF(window_token)) && concat_athashes);
ref = newtriple(OC_INDNAME);
ref->operand[0] = *a;
ref->operand[1] = put_lit(&(TREF(indirection_mval)));
(TREF(indirection_mval)).mvtype = 0; /* so stp_gcol (BYPASSOK) - if invoked later - can free up space */
*a = put_tref(ref);
}
return TRUE;
}