226 lines
6.7 KiB
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);
|
|
}
|
|
}
|