fis-gtm/sr_port/stx_error.c

226 lines
6.7 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 <stdarg.h>
#include "gtm_string.h"
#include "cmd_qlf.h"
#include "compiler.h"
#include "opcode.h"
#include "cgp.h"
#include "io.h"
#include "list_file.h"
#include "gtmmsg.h"
#include "util_format.h"
#include "show_source_line.h"
#ifdef UNICODE_SUPPORTED
#include "gtm_utf8.h"
#endif
GBLREF char source_file_name[];
GBLREF unsigned char *source_buffer;
GBLREF short int source_name_len, source_line;
GBLREF command_qualifier cmd_qlf;
GBLREF bool dec_nofac;
GBLREF boolean_t run_time;
GBLREF char cg_phase;
GBLREF io_pair io_curr_device, io_std_device;
error_def(ERR_ACTLSTTOOLONG);
error_def(ERR_BADCASECODE);
error_def(ERR_BADCHAR);
error_def(ERR_BADCHSET);
error_def(ERR_CEBIGSKIP);
error_def(ERR_CENOINDIR);
error_def(ERR_CETOOLONG);
error_def(ERR_CETOOMANY);
error_def(ERR_CEUSRERROR);
error_def(ERR_FMLLSTMISSING);
error_def(ERR_FMLLSTPRESENT);
error_def(ERR_FOROFLOW);
error_def(ERR_INVDLRCVAL);
error_def(ERR_LABELMISSING);
error_def(ERR_SRCLIN);
error_def(ERR_SRCLOC);
error_def(ERR_SRCNAM);
void stx_error(int in_error, ...)
{
va_list args;
VA_ARG_TYPE cnt, arg1, arg2, arg3, arg4;
bool list, warn;
char msgbuf[MAX_SRCLINE];
char buf[MAX_SRCLINE + LISTTAB + SIZEOF(ARROW)];
char *c;
mstr msg;
boolean_t is_stx_warn; /* current error is actually of type warning and we are in CGP_PARSE phase */
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
va_start(args, in_error);
/* In case of a IS_STX_WARN type of parsing error, we resume parsing so it is important NOT to reset
* the following global variables
* a) saw_side_effect
* b) shift_side_effects
* c) source_error_found
*/
is_stx_warn = (CGP_PARSE == cg_phase) && IS_STX_WARN(in_error) GTMTRIG_ONLY( && !TREF(trigger_compile));
if (!is_stx_warn)
TREF(saw_side_effect) = TREF(shift_side_effects) = FALSE;
if (run_time)
{ /* If the current error is of type STX_WARN then do not issue an error at compile time. Insert
* triple to issue the error at runtime. If and when this codepath is reached at runtime (M command
* could have a postconditional that bypasses this code) issue the rts_error.
* See IS_STX_WARN macro definition for details.
*/
if (is_stx_warn)
{ /* merrors.msg defines INVCMD as a warning but compiler conditions can turn it into an error */
if (ERR_INVCMD != in_error) /* if INVCMD has morphed into an error, it won't match here */
ins_errtriple(in_error);
return;
}
if (TREF(for_stack_ptr) > (oprtype **)TADR(for_stack))
FOR_POP(BLOWN_FOR);
if (ERR_BADCHAR == in_error)
{
cnt = va_arg(args, VA_ARG_TYPE);
assert(cnt == 4);
arg1 = va_arg(args, VA_ARG_TYPE);
arg2 = va_arg(args, VA_ARG_TYPE);
arg3 = va_arg(args, VA_ARG_TYPE);
arg4 = va_arg(args, VA_ARG_TYPE);
va_end(args);
rts_error(VARLSTCNT(6) in_error, cnt, arg1, arg2, arg3, arg4);
} else if ((ERR_LABELMISSING == in_error)
|| (ERR_FMLLSTMISSING == in_error)
|| (ERR_ACTLSTTOOLONG == in_error)
|| (ERR_BADCHSET == in_error)
|| (ERR_BADCASECODE == in_error))
{
cnt = va_arg(args, VA_ARG_TYPE);
assert(cnt == 2);
arg1 = va_arg(args, VA_ARG_TYPE);
arg2 = va_arg(args, VA_ARG_TYPE);
va_end(args);
rts_error(VARLSTCNT(4) in_error, cnt, arg1, arg2);
} else if ((ERR_CEUSRERROR == in_error) || (ERR_INVDLRCVAL == in_error) || (ERR_FOROFLOW == in_error))
{
cnt = va_arg(args, VA_ARG_TYPE);
assert(cnt == 1);
arg1 = va_arg(args, VA_ARG_TYPE);
va_end(args);
rts_error(VARLSTCNT(3) in_error, cnt, arg1);
} else
{
va_end(args);
rts_error(VARLSTCNT(1) in_error);
}
} else if ((CGP_PARSE == cg_phase) && (ERR_INVCMD != in_error)) /* if INVCMD has morphed into an error, won't match here */
ins_errtriple(in_error);
assert(!run_time); /* From here on down, should never go ahead with printing compile-error while in run_time */
flush_pio();
if (TREF(source_error_found))
{
va_end(args);
return;
}
if (!is_stx_warn
&& (ERR_CETOOMANY != in_error) /* compiler escape errors shouldn't hide others */
&& (ERR_CEUSRERROR!= in_error)
&& (ERR_CEBIGSKIP != in_error)
&& (ERR_CETOOLONG != in_error)
&& (ERR_CENOINDIR != in_error))
{
TREF(source_error_found) = (int4)in_error;
}
list = (cmd_qlf.qlf & CQ_LIST) != 0;
warn = (cmd_qlf.qlf & CQ_WARNINGS) != 0;
if (!warn && !list) /*SHOULD BE MESSAGE TYPE IS WARNING OR LESS*/
{
va_end(args);
return;
}
if (list && (io_curr_device.out == io_std_device.out))
warn = FALSE; /* if listing is going to $P, don't double output */
if (ERR_BADCHAR == in_error)
{
memset(buf, ' ', LISTTAB);
show_source_line(&buf[LISTTAB], SIZEOF(buf), warn);
cnt = va_arg(args, VA_ARG_TYPE);
assert(cnt == 4);
arg1 = va_arg(args, VA_ARG_TYPE);
arg2 = va_arg(args, VA_ARG_TYPE);
arg3 = va_arg(args, VA_ARG_TYPE);
arg4 = va_arg(args, VA_ARG_TYPE);
if (warn)
{
dec_err(VARLSTCNT(6) in_error, 4, arg1, arg2, arg3, arg4);
dec_err(VARLSTCNT(4) ERR_SRCNAM, 2, source_name_len, source_file_name);
}
if (list)
list_line(buf);
arg1 = arg2 = arg3 = arg4 = 0;
} else if ((ERR_LABELMISSING == in_error)
|| (ERR_FMLLSTMISSING == in_error)
|| (ERR_ACTLSTTOOLONG == in_error)
|| (ERR_BADCHSET == in_error)
|| (ERR_BADCASECODE == in_error))
{
cnt = va_arg(args, VA_ARG_TYPE);
assert(cnt == 2);
arg1 = va_arg(args, VA_ARG_TYPE);
arg2 = va_arg(args, VA_ARG_TYPE);
if (warn)
{
dec_err(VARLSTCNT(4) in_error, 2, arg1, arg2);
dec_err(VARLSTCNT(4) ERR_SRCNAM, 2, source_name_len, source_file_name);
}
} else
{
memset(buf, ' ', LISTTAB);
show_source_line(&buf[LISTTAB], SIZEOF(buf), warn);
if (warn)
{
if ((ERR_CEUSRERROR != in_error) && (ERR_INVDLRCVAL != in_error) && (ERR_FOROFLOW != in_error))
dec_err(VARLSTCNT(1) in_error);
else
{
cnt = va_arg(args, VA_ARG_TYPE);
assert(cnt == 1);
arg1 = va_arg(args, VA_ARG_TYPE);
dec_err(VARLSTCNT(3) in_error, 1, arg1);
}
}
if (list)
list_line(buf);
arg1 = arg2 = 0;
}
va_end(args);
if (list)
{
va_start(args, in_error);
msg.addr = msgbuf;
msg.len = SIZEOF(msgbuf);
gtm_getmsg(in_error, &msg);
assert(msg.len);
# ifdef UNIX
cnt = va_arg(args, VA_ARG_TYPE);
c = util_format(msgbuf, args, LIT_AND_LEN(buf), (int)cnt);
va_end(TREF(last_va_list_ptr)); /* set by util_format */
# else
c = util_format(msgbuf, args, LIT_AND_LEN(buf));
# endif
va_end(args);
*c = 0;
list_line(buf);
}
}