fis-gtm/sr_port/op_fntext.c

125 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"
#include "gtm_stdio.h"
#include "error.h"
#include <rtnhdr.h>
#include "srcline.h"
#include "op.h"
#include "stringpool.h"
#ifdef GTM_TRIGGER
# include "gtm_trigger_trc.h"
#endif
GBLREF spdesc stringpool;
error_def(ERR_TXTSRCMAT);
error_def(ERR_ZLINKFILE);
error_def(ERR_ZLMODULE);
void op_fntext(mval *label, int int_exp, mval *rtn, mval *ret)
/* label contains label to be located or null string */
/* int_exp contains label offset or line number to reference */
/* ret is used to return the correct string to caller */
{
char *cp;
int i, lbl, letter;
mval *temp_rtn, temp_mval;
mstr *sld;
uint4 stat;
rhdtyp *rtn_vector;
boolean_t is_trigger;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
MV_FORCE_STR(label);
MV_FORCE_STR(rtn);
temp_rtn = &temp_mval;
*temp_rtn = *rtn; /* make a copy of the routine in case the caller used the same mval for rtn and ret */
ret->str.len = 0; /* make ret an emptystring in case the return is by way of the condition handler */
ret->mvtype = MV_STR;
sld = (mstr *)NULL;
ESTABLISH(fntext_ch); /* to swallow errors and permit an emptystring result */
GTMTRIG_ONLY(IS_TRIGGER_RTN(&temp_rtn->str, is_trigger));
if ((0 == int_exp) && ((0 == label->str.len) || (0 == *label->str.addr)))
stat = ZEROLINE;
else
{
#ifdef GTM_TRIGGER
if (is_trigger)
{
DBGTRIGR((stderr, "op_fntext: fetching $TEXT() source for a trigger\n"));
assert(FALSE == TREF(in_op_fntext));
TREF(in_op_fntext) = TRUE;
}
#endif
stat = get_src_line(temp_rtn, label, int_exp, &sld, VERIFY);
GTMTRIG_ONLY(TREF(in_op_fntext) = FALSE);
}
if (0 == (stat & (CHECKSUMFAIL | NEGATIVELINE)))
{
if (stat & ZEROLINE)
{
if (NULL == (rtn_vector = find_rtn_hdr(&temp_rtn->str)))
{ /* not here, so try to bring it in */
GTMTRIG_ONLY(if (!is_trigger)) /* Triggers cannot be loaded in this fashion */
{
op_zlink(temp_rtn, 0);
rtn_vector = find_rtn_hdr(&temp_rtn->str);
}
}
if (NULL != rtn_vector)
{
ret->str.addr = rtn_vector->routine_name.addr;
ret->str.len = rtn_vector->routine_name.len;
}
} else if (NULL != sld)
ret->str = *sld;
}
REVERT;
/* If non-empty, copy result to stringpool and
* convert any tabs in linestart to spaces
*/
if (ret->str.len)
{
ENSURE_STP_FREE_SPACE(ret->str.len);
cp = (char *)stringpool.free;
for (i = 0, lbl = 1; i < ret->str.len; i++)
{
letter = ret->str.addr[i];
if (lbl)
{
if ((' ' == letter) || ('\t' == letter))
{
letter = ' ';
lbl = 0;
}
*cp++ = letter;
} else
{
if ((' ' != letter) && ('\t' != letter))
{
memcpy(cp, &ret->str.addr[i], ret->str.len - i);
break;
} else
*cp++ = ' ';
}
}
ret->str.addr = (char *)stringpool.free;
stringpool.free += ret->str.len;
}
return;
}