home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
p2demo21.exe
/
PEL
/
ERRORFIX.PEL
< prev
next >
Wrap
Text File
|
1995-04-11
|
48KB
|
1,514 lines
# $Header: P:\source\wmacros\errorfix.pev 1.123.1.0 11 Apr 1995 14:44:26 WALKER $
## $Tabs:4 7$
##############################################################################
#
# Compuware Corporation
# 31440 Northwestern Highway
# Farmington Hills, Michigan 48334-2564
#
# This source code listing contains information that is
# proprietary to Compuware Corporation and may not be copied
# duplicated, translated, transmitted, stored, retrieved
# or in any manner or by any method conveyed or disclosed
# to a third party or parties without express written
# permission from Compuware Corporation.
#
#
##############################################################################
#### $Workfile: errorfix.pel $: Compiling and Error locating utilities
## Overview of compile/errorfix language support
##
## The two most essential global functions defined here are
## "compile_buffer()" and "goto_next_error()". Compile_buffer uses the
## name of the current buffer to determine what language is being used,
## and then issues a command line to the shell invoking the appropriate
## compiler. Upon completion of the shell process, the captured error
## output is passed on to the goto_next_error() function.
## goto_next_error() knows the syntax of the error messages produced by
## each compiler, and uses that information to find the name of the
## source file where the error occurred, and the location within that
## file. The goto_next_error() function may also be invoked again
## independently from the keyboard, where it will scan forward in the
## error listing for the next error encountered.
##
## To add support for a new compiler, the arrays "compiler_cmd_array"
## and "compiler_err_array" must be augmented and, depending on the
## error message syntax of the new compiler, a new compiler-specific
## error message parsing function may have to be added. The function
## add_compiler() can be used to update the compiler arrays. It may be
## called from within the user's local_setup() function, or from within
## the cpe.cfg file. For more information on adding a new error
## message function, see the comments in function errorInfo() near the
## end of this file.
##
## ---------------------------------------------------------------------
## Clipper & FORCE compiler support enhancements provided by
## Pedro P. Polakoff III of 3P Software, Inc.
global compile_flags = 0 # Flags to pass to system for the compile.
global background_compile = 1 # TRUE = compile in the background.
global list_all_output = 0 # TRUE = add all compiler output to error list.
global compile_input = 0 # TRUE = force input box on all compiles.
global compile_chdir = 1 # TRUE = change to directory that contains the
# file to be compiled before compiling.
local errorSrcName
local errorLine
local errorColumn
local errorLength
local errorText
local errorCompleteText
local errorsFound
local errorInfoPrefix
# typedef struct compiles
# {
# string name;
# string dlgid;
# bool input;
# bool output;
# string filename;
# } current_compiles[];
local current_compiles[]
local compile_pipes[]
## compile_buffer()
#
# compile the current buffer
#
global function compile_buffer(list_all, background, disable_dialog,
input_file, source_file)
{
local ch
local fh
local num
local cmd
local ext
local cwd
local fid2
local name
local file
local data
local fileid
local pipeid
local outfile
local flags = compile_flags
local in_background = background_compile
local all_output = list_all_output
local needs_input = compile_input
local source_filename = length(source_file) ? source_file : buffer_filename
local temp_file = ""
local status = -1
local dlgid = 0
local fid = -1
# reset microfocus global variables incase this is not the first time through
reset_mf_globs();
## use the filename extension to decide which compiler to use
ext = path_ext( source_filename );
if ( !ext )
{
# treat the name "makefile" with no extension as if it has
# a ".mak" extension
if ( path_fname( source_filename ) == "makefile" )
ext = ".mak"
else
ext = "NULL_ext"
}
cmd = CommandLine(ext, 1, source_filename);
num = cmd+0
if (num == -1)
{
warning( "Don't know how to compile %s files.", ext );
return status;
}
else if (num == -2)
{
warning( "Don't know how to compile with the %s compiler.", name);
return status;
}
else
{
name = CompilerName(ext)
if (length(input_file))
needs_input = TRUE
else
{
file = CompilerInput(name)
num = file+0
if (num >= 0)
{
needs_input = TRUE
if (num != 1)
input_file = file
}
}
}
if (length(input_file))
{
if (cindex("><=+", prefix(input_file, 1)))
{
data = substr(input_file, 2)
input_file = temp_file = create_temp_name()
fh = fopen(input_file, 1)
fprintf(fh, "%s\n", data)
fclose(fh)
}
}
if (!disable_dialog)
{
cmd = prompt_history( "COMPILE", "Compile command: ", cmd, 1, 1, "compile_dialog" )
}
if ( cmd )
{
flags = or(flags, CompilerFlags(name))
if (compile_chdir || CompilerChdir(name))
{
cwd = getcwd()
chdir(path_path(source_filename))
}
if (argcount())
{
if (!all_output)
all_output = or(list_all, needs_input)
if (argcount() >= 2)
{
if (!(in_background = background))
flags = and(flags, not(or(SYS_ASYNC, SYS_DETACHED)))
}
else
in_background = CompilerBackground(name)
}
else if (!all_output)
all_output = CompilerOutput(name) > 0
if(CompilerSaveAll(name))
{
# write all modified buffers to disk;
write_all_buffers();
}
else
{
# write current buffer to disk if modified;
if (and(buffer_flags, BUFFER_MODIFIED))
write_buffer_key()
}
# Do not compile PEL in the background as this causes problems!
if (ext != ".pel" && (ErrorFormat(ext) != "microfocus") && !and(flags, SYS_DOSSHELL) && \
(in_background || and(flags, or(SYS_ASYNC, SYS_DETACHED))))
{
pipeid = create_pipes()
}
else
pipeid = 0
errorsFound = 0
if (!disable_dialog)
{
dlgid = create_compile_dialog(source_filename, needs_input && pipeid)
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Compiling " source_filename "...")
}
else
message("Compiling %s...", source_filename)
if (pipeid)
{
status = system( cmd, pipeid, pipeid, pipeid, or(flags, SYS_ASYNC) )
if ( status > 0 )
{
attach_event_handler(EVENT.PROCESS_COMPLETE, function_id("check_compile"))
attach_event_handler(EVENT.PIPE_DATA, function_id("pipedata") )
if (dlgid)
{
set_dialog_item(dlgid, DI_STOP_BUTTON, DAC_ENABLE )
compile_pipes[dlgid] = pipeid
}
current_compiles[pipeid].name = name
current_compiles[pipeid].dlgid = dlgid
current_compiles[pipeid].input = needs_input
current_compiles[pipeid].output = all_output
current_compiles[pipeid].filename = source_filename
process_pipes( pipeid, 1, 0 )
if (dlgid && needs_input)
set_dialog_item(dlgid, DI_INPUT, DAC_SETFOCUS)
# stuff the input data down the pipe.
if (length(input_file))
{
fid = fopen(input_file, 0)
if (fid > -1)
{
while ((data = fgets(fid)))
pputs(data "\n", pipeid)
fclose(fid)
}
else
warning("unable to open %s for input", input_file)
}
}
else if ( pipeid )
close_pipes(pipeid)
}
else
{
idle(TRUE)
outfile = create_temp_name(0, "err", ltrim(ext, ".") "_" )
if (and(flags, SYS_DOSSHELL))
{
status = system( cmd, input_file, outfile, outfile,
and(flags, not(or(SYS_ASYNC, SYS_DETACHED))),
CompilerDOSSettingsArray(name))
}
else if ( (fid = fopen( outfile, 2 )) != -1 )
{
status = system( cmd, input_file, fid, fid,
and(flags, not(or(SYS_ASYNC, SYS_DETACHED))))
fclose( fid )
}
else
{
warning( "could not create temp file %s", outfile )
status = -1
}
if ( status >= 0 )
{
if( ErrorFormat(ext) == "microfocus")
{
unlink(outfile);
outfile = path_path(buffer_filename) path_fname(buffer_filename) ".lst";
display_errors(source_filename, outfile, name, all_output,
dlgid, TRUE)
}
else
display_errors(source_filename, outfile, name, all_output,
dlgid, FALSE)
}
if ( !errorsFound && status > 0)
{
if (dlgid)
{
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Compile returned error code " status ".")
}
else
warning("Compile returned error code " status ".")
}
}
if ( status < 0 )
{
if (dlgid)
{
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Unable to execute compile command, Error code = " status ".")
}
else
warning("Unable to execute compile command, Error code = " status ".")
}
if (length(temp_file))
unlink(temp_file)
if (compile_chdir)
chdir(cwd)
}
return status
}
# called to create the compile dialog
local function create_compile_dialog(source_filename, needs_input)
{
local dlgid = create_list_dialog("Compile - " source_filename, \
editor_helpfile, "compile_list_callback", \
needs_input);
set_dialog_item(dlgid, DI_GOTO_BUTTON, DAC_DISABLE )
set_dialog_item(dlgid, DI_NEXT_BUTTON, DAC_DISABLE )
set_dialog_item(dlgid, DI_PREV_BUTTON, DAC_DISABLE )
set_dialog_item(dlgid, DI_STOP_BUTTON, DAC_DISABLE )
begin_list_dialog(dlgid)
return dlgid
}
# called to query whether the dialog has an input box.
global function compile_has_input( dlghand )
{
if ( dlghand in compile_pipes )
return current_compiles[compile_pipes[dlghand]].needs_input > 0
else
return 0
}
# called when the stop button on the compile dialog box is pressed
global function stop_button_pressed( dlghand )
{
if ( argcount() < 1 )
dlghand = callback_dialog_handle
if ( dlghand in compile_pipes )
close_pipes( compile_pipes[dlghand] )
process_background(STOP_BACKGROUND)
if ( fileid != -1 )
{
fclose(fileid)
fileid = -1
}
}
# called when the compile dialog box is closed
global function close_dialog_box( dlghand )
{
if ( argcount() < 1 )
dlghand = callback_dialog_handle
if ( dlghand in compile_pipes )
close_pipes( compile_pipes[dlghand] )
}
# called when the enter button is pressed.
global function send_compile_data( dlghand, data )
{
if ( dlghand in compile_pipes )
{
set_dialog_item(dlghand, IDL_LIST, DAC_SELECT_INDEX,
add_item_to_list(dlghand, data, "", 0, 0, 0))
pputs(data "\n", compile_pipes[dlghand])
set_dialog_item(dlghand, DI_INPUT, DAC_SETFOCUS)
}
}
# ---------------------------------------------------------------------------
## check_compile()
#
# Event handler for EVENT.PROCESS_COMPLETE gets called when a process
# has completed. process_id is set to the process that has just
# finished.
#
global function check_compile()
{
if ( process_pipe in current_compiles )
compile_done( process_pipe )
}
local function compile_done(pid)
{
local dlgid = current_compiles[pid].dlgid
if (current_compiles[pid].input)
{
if (query_dialog_item(dlgid, DI_INPUT, DAC_SETFOCUS))
set_dialog_item(dlgid, IDL_LIST, DAC_SETFOCUS)
set_dialog_item(dlgid, DI_INPUT, DAC_DISABLE )
set_dialog_item(dlgid, DI_ENTER_BUTTON, DAC_DISABLE )
}
set_dialog_item(dlgid, DI_STOP_BUTTON, DAC_DISABLE )
if (dlgid)
{
if ( errorsFound > 0 )
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Compile complete, " errorsFound " errors/warnings found." )
else if ( process_rc > 0)
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Command returned error code " process_rc ".")
else
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Compile complete, No errors found." )
}
else
{
if ( errorsFound > 0 )
message("Compile complete, " errorsFound " errors/warnings found." )
else if ( process_rc > 0)
message("Command returned error code " process_rc ".")
else
message("Compile complete, No errors found." )
}
delete_event(EVENT.PIPE_DATA, function_id("pipedata"))
delete_event(EVENT.PROCESS_COMPLETE, function_id("check_compile"))
delete current_compiles [ pid ]
delete compile_pipes [ dlgid ]
}
# ---------------------------------------------------------------------------
## pipedata()
#
# Event handler for EVENT.PIPE_DATA to retrieve the error messages from the
# pipe and place them into the error dialog.
#
global function pipedata()
{
local name
local level
local dlgid
local input
local output
local filename
local errorOutputText
local index = -1
if ( process_pipe in current_compiles )
{
errorCompleteText = pipe_data
if (length(errorCompleteText))
{
name = current_compiles[process_pipe].name
dlgid = current_compiles[process_pipe].dlgid
input = current_compiles[process_pipe].input
output = current_compiles[process_pipe].output
filename = current_compiles[process_pipe].filename
errorInfoPrefix = ErrorFormat(name);
level = errorInfo()
if ( level > 0 )
{
if (!dlgid)
{
dlgid = create_compile_dialog(filename, input)
current_compiles[process_pipe].dlgid = dlgid
}
if (!errorsFound)
{
set_dialog_item(dlgid, DI_NEXT_BUTTON, DAC_ENABLE )
set_dialog_item(dlgid, DI_PREV_BUTTON, DAC_ENABLE )
}
errorsFound++
# if (list_all_output || (length(errorText) == 0) )
if (output || (length(errorText) == 0) )
errorOutputText = errorCompleteText
else
errorOutputText = errorText
index = add_item_to_list(dlgid, errorOutputText,
errorSrcName, errorLine, errorColumn,
errorLength ? errorLength : errorColumn > 1 ? -2 : -1)
}
else if (dlgid)
{
if (output || level < 0)
index = add_item_to_list(dlgid, errorCompleteText, "", 0, 0, 0)
else
{
errorCompleteText = ltrim(errorCompleteText)
if (length(errorCompleteText))
set_dialog_window(dlgid, DWC_STATUSBARTEXT, errorCompleteText)
}
}
if (dlgid && input && index >= 0)
set_dialog_item(dlgid, IDL_LIST, DAC_SELECT_INDEX, index)
}
}
}
# ---------------------------------------------------------------------------
## display_errors()
#
# Parse the error message file and put the error messages into the
# error dialog.
#
# needs to be global to this module because if the stop button is
# pressed we need to close the file.
local fileid = -1
global function display_errors(sourceFileName, errorFileName, errorCompiler,
list_all, dlgid, saveFile)
{
local data
local level
local line = 1
local errorOutputText
process_background(ENABLE_FOREGROUND)
if (!argcount())
sourceFileName = buffer_filename
if (argcount() < 2 || !length(errorFileName))
errorFileName = bld_fnam(sourceFileName, sourceFileName, "err")
if (argcount() < 3 || !length(errorCompiler))
errorCompiler = CompilerName(path_ext(sourceFileName))
if (argcount() < 5)
list_all = list_all_output
fileid = fopen(errorFileName, 0)
if ( fileid == -1 )
{
if (dlgid)
{
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Unable to open file " errorFileName)
}
else
warning("Unable to open file " errorFileName)
}
else
{
if (dlgid)
set_dialog_window(dlgid, DWC_STATUSBARTEXT, "Parsing errors...")
errorInfoPrefix = ErrorFormat(errorCompiler);
while (( errorCompleteText = fgets(fileid) ))
{
line++
level = errorInfo()
if ( level > 0 )
{
if (!dlgid)
dlgid = create_compile_dialog(sourceFileName)
if (!errorsFound)
{
set_dialog_item(dlgid, DI_NEXT_BUTTON, DAC_ENABLE )
set_dialog_item(dlgid, DI_PREV_BUTTON, DAC_ENABLE )
}
errorsFound++
# If the file name is not specified in the error file,
# default to the error file itself.
# I put this here because of Microfocus list files.
if(!errorSrcName)
errorSrcName = errorFileName;
# if (list_all_output || (length(errorText) == 0) )
if (list_all || (length(errorText) == 0) )
errorOutputText = errorCompleteText
else
errorOutputText = errorText
add_item_to_list(dlgid,
errorOutputText,
errorSrcName, errorLine, errorColumn,
errorLength ? errorLength : errorColumn > 1 ? -2 : -1)
}
else if (dlgid)
{
if (list_all || level < 0)
add_item_to_list(dlgid, errorCompleteText, "", 0, 0, 0)
else
{
errorCompleteText = ltrim(errorCompleteText)
if (length(errorCompleteText))
set_dialog_window(dlgid, DWC_STATUSBARTEXT, errorCompleteText)
}
}
if ( dlgid && and(status_bar_flags, STB_MESSAGES) && line % 20 == 0 )
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Parsing error file line " line)
}
fclose(fileid)
fileid = -1
# saveFile is set if we have loaded from an error file on disk
# which means we haven't done a compile_buffer command
if ( !saveFile )
unlink(errorFileName)
if (dlgid)
{
if ( errorsFound > 0 )
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Compile complete, " errorsFound " errors/warnings found." )
else
set_dialog_window(dlgid, DWC_STATUSBARTEXT,
"Compile complete, No errors found." )
}
else if ( errorsFound > 0 )
message("Compile complete, " errorsFound " errors/warnings found." )
else
message("Compile complete, No errors found." )
}
process_background(END_BACKGROUND)
}
global function goto_prev_error()
{
goto_prev_item()
}
## goto_next_error() #PUBLIC
#
# display an individual error message
#
global function goto_next_error( errorFileId, suppressDisplayErrors )
{
goto_next_item()
}
## errorInfo()
#
# Calls the appropriate compiler specific xxxErrorInfo function to find
# error and warning messages in the error file and extract salient
# information. Additional functions may be added here, if desired, to
# support different compilers. Each new function should have a name which
# consists of the compiler type, as defined in the init_compilers() function,
# followed by "ErrorInfo". Each new ErrorInfo function should set
# the following variables:
#
#
# errorSrcName - the name of the source filename appearing in the
# error message
#
# errorLine - the line number in the current source file where the
# error occurred.
#
# errorColumn - the column where the error occurred (or 0 if unknown)
#
# errorLength - the length of the error (to hilight) or 0 to hilight line.
#
# errorText - the text of the message to be displayed in the
# dialog window.
#
#
# In addition, the variable errorCompleteText will be displayed if the file
# named in errorSrcName cannot be located.
#
#
# The function return value should be as follows:
# 0 - if no more error or warning messages could be found,
# 1 - if the message is for a non-fatal error or warning,
# 2 - if the message is for a severe error.
#
local function errorInfo()
{
local pos
local functionId
local functionName
local functionParm
# initialize
errorSrcName = ""
errorText = ""
errorLine = 0
errorColumn = 0
errorLength = 0
# Determine which xxxErrorInfo function to use. Known compiler
# types and source file extensions are listed in the function
# "init_compilers()".
if ( errorInfoPrefix == "none" || errorInfoPrefix == "[None]" )
return -1 # no errorInfo function exists for this compiler
# Append the name "ErrorInfo" to the compiler type and
# use it if a function by that name exists.
if ((pos = cindex(errorInfoPrefix, ",")))
{
functionParm = substr(errorInfoPrefix, pos+1)
functionName = prefix(prefix(errorInfoPrefix, pos-1), 8 ) "ErrorInfo";
}
else
functionName = prefix( errorInfoPrefix, 8 ) "ErrorInfo";
if (functionParm)
functionId = function_id( functionName, functionParm )
else
functionId = function_id( functionName )
if ( functionId )
return execute_function( functionId )
else
return genericErrorInfo() # otherwise use the default errorfix routine
}
# ------------------- Generic ErrorInfo function ----------------------------
global function genericErrorInfo()
{
#====================================================================
# This function is invoked whenever no explicit xxxErrorInfo()
# function has been defined for the current compiler. It supports
# the error message syntax for several compilers, for example:
#
# Microsoft C and MASM:
# <sourcefile>(<line number>): "error"|"warning" <errno>: <message>
#
# Microsoft FORTRAN:
# <sourcefile>(<line number>) : "error"|"warning" <errno> : <message>
#
# Lattice C:
# <sourcefile> <line number> "Error"|"Warning" <errno>: <message>
#
# Borland Turbo Pascal:
# <sourcefile>(<line number>): "Error"|"Warning" <errno>: <message>
#
# FORCE:
# <sourcefile>(<line number>) : "Error"(<errno>) : <message>
#
# IBM CSet/2 & IBM CSet++:
# <sourcefile>(<line>:<column>) : "error"|"warning" <errno>: <message>
#
#====================================================================
local errorLevel
local searchFor = "(^fatal )|[ \t(]+\\c[0-9].*(<[eE]rror|<[wW]arning)[ \t(].*:"
local tempText
local colon, paren
# scan the error file for the next appropriate message
if ( !match( errorCompleteText, searchFor ) )
return 0 # no more applicable messages
# handle fatal errors and other messages with no source filename
tempText = substr(errorCompleteText, 0, 6)
if ((tolower(tempText) == "fatal " ) || \
(!match( errorCompleteText, /^[( \t]*[^( \t]+\./ )))
{
errorSrcName = ""
errorLine = 0
errorColumn = 0
errorLevel = 2
}
else
{
# get the source filename
match( errorCompleteText, /[^( \t]+/ )
errorSrcName = substr( errorCompleteText, RSTART, RLENGTH )
# get the line position of the error
tempText = substr(errorCompleteText, RSTART + RLENGTH + 1, 20)
errorLine = atoi( tempText )
# get the column position of the error
colon = cindex(tempText, ":")
paren = cindex(tempText, ")")
if (colon && paren && colon < paren)
errorColumn = atoi(substr(tempText, colon+1))
else
errorColumn = 0
# determine the severity of the error
match( errorCompleteText, "<error>|<warning>" )
tempText = substr(errorCompleteText, RSTART, RLENGTH)
tempText = substr(tempText, 0, 5)
errorLevel = (tolower(tempText) == "error") ? 2 : 1
}
# get the text of the message
match( errorCompleteText, ":\\c" )
tempText = substr(tempText, RSTART, RLENGTH)
match( tempText, "<" )
tempText = substr(tempText, RSTART, RLENGTH)
errorText = substr(tempText, RSTART)
return errorLevel
}
# ------------------- ErrorInfo function for PEL ----------------------------
global function pelErrorInfo()
{
#====================================================================
#
# error message syntax for INTERSOLV Pel compiler:
#
# <sourcefile>(<line number>):"[fatal] error"|"warning":
# <space>|<newline> <message>
#
#====================================================================
local errorLevel
local searchFor = ":.*(error|warning).*:\\c"
local delimit
# scan the error string for an appropriate message
if ( !match( errorCompleteText, searchFor ) )
return 0 # not a valid error message
# get the source filename
match( errorCompleteText, /[^( ]+/ )
errorSrcName = substr( errorCompleteText, RSTART, RLENGTH )
# get the line and column position of the error
if ( substr( errorCompleteText, RSTART+RLENGTH, 1 ) == "(" )
errorLine = atoi( substr( errorCompleteText, RSTART+RLENGTH+1 ))
# determine the severity of the error
errorLevel = (errorCompleteText ~ /warning:/) ? 1 : 2
errorText = ltrim(errorCompleteText, errorSrcName)
# Removed by WGN since this line just duplicates errorText in errorCompleteText
# errorCompleteText = errorCompleteText errorText
# get the text of the message
match( errorText, ": ")
errorText = substr( errorText, RSTART+1 )
return errorLevel
}
# ------------------- ErrorInfo function for Microfocus COBOL ---------------
local function reset_mf_globs()
{
mfFirstFound = FALSE;
mfErrorNum = "";
mfErrorLine = 0;
mfSrcName = "";
}
local mfFirstFound = FALSE;
local mfErrorNum;
local mfErrorLine;
local mfSrcName = "";
global function microfocErrorInfo(linenum)
{
#====================================================================
#
# error message syntax for Microfocus COBOL compiler:
#
# *<err number>-<E|S|I|F><more than one *>\n
# **<error message>\n
# <white space><line number><code>\n
#
#====================================================================
local errorLevel = 0;
local arr;
local firstsearchFor = "^\\*[ ]*[0-9]+-[EFISUW][\\*]+";
local secondsearchFor = "^\\*\\* .*";
local thirdsearchFor = "first used on line [0-9]+";
if((prefix(errorCompleteText, 13) == "* Micro Focus") && !mfSrcName)
{
mfSrcName = "23";
# warning("found first line of name >" errorCompleteText "<");
}
else if(mfSrcName == "23")
{
split(errorCompleteText, arr);
mfSrcName = arr[2];
# warning("mfsrcname set to <" mfSrcName ">");
}
if(!mfFirstFound && match(errorCompleteText, firstsearchFor) )
{
# found the first line of a message, rip out error number and save;
mfErrorNum = prefix(errorCompleteText, 7);
mfFirstFound = TRUE;
}
else if(mfFirstFound && match(errorCompleteText, secondsearchFor) )
{
# found a matching second line after a matching first line;
# get the rest of the error info;
if(match(errorCompleteText, thirdsearchFor))
errorLine = atoi(substr(errorCompleteText, RSTART + 19));
else
errorLine = mfErrorLine;
errorText = mfErrorNum ": " ltrim(substr(errorCompleteText, 3));
errorSrcName = mfSrcName;
mfFirstFound = FALSE;
errorLevel = 1;
}
else
{
# no matching firstline, no matching second after first;
split(errorCompleteText, arr);
mfErrorLine = atoi(arr[1]);
mfFirstFound = FALSE;
}
return errorLevel;
}
# ------------------- ErrorInfo function for Realia COBOL ---------------
global function realiaErrorInfo()
{
#====================================================================
#
# error message syntax for Realia COBOL compiler:
#
# <line number> <err number> <E|S|I|F> <error message>
#
#====================================================================
local errorLevel = 0;
local arr;
local searchFor = "^*[0-9]+ [0-9]+ [EFISUW] ";
if(!mfSrcName && match(errorCompleteText, "CA-Realia COBOL"))
{
split(errorCompleteText, arr);
mfSrcName = arr[7];
}
else if(match(errorCompleteText, searchFor) )
{
split(errorCompleteText, arr);
errorLine = atoi(arr[1]);
errorText = ltrim(errorCompleteText);
errorSrcName = mfSrcName;
errorLevel = (arr[3] == "W") ? 1 : 2;
}
return errorLevel;
}
# ------------------- ErrorInfo function for Turbo C ------------------------
global function turbocErrorInfo()
{
#====================================================================
#
# error message syntax for Borland Turbo C (Version 2.0):
#
# "Error"|"Warning" <sourcefile> <line number>: <message>
#
#====================================================================
local errorLevel
local searchFor = "^(Error|Warning).* \\c[0-9]+:"
# scan the error file for the next appropriate message
if ( !match( errorCompleteText, searchFor ) )
return 0 # not a valid error message
# determine the severity of the error
errorLevel = (errorCompleteText ~ /^Error/) ? 2 : 1
# strip off the Warning|Error string
strtok( errorCompleteText, "[ \t]+" )
# get the source filename
errorSrcName = strtok()
# get the line and column position of the error
errorLine = atoi( strtok("", "[ :\t]+") )
errorColumn = 0
# get the text of the message
errorText = get_tokstring()
return errorLevel
}
# ------------------- ErrorInfo function for Zortech C and C++ --------------
global function watcomErrorInfo()
{
#====================================================================
#
# error message syntax for Watcom C and C++
#
# Watcom C and C++:
# "<sourcefile>" line <line number>: "warning"|"syntax error"|
# "preprocessor error"|"fatal error"|"lexical error": <message>
#
#====================================================================
return otherErrorInfo( "%f(\\()%1(\\)):.*(col )%c(\\) )%t" )
}
# ------------------- ErrorInfo function for Zortech C and C++ --------------
global function zortechErrorInfo()
{
#====================================================================
#
# error message syntax for Zortech C and C++
#
# Zortech C and C++:
# "<sourcefile>" line <line number>: "warning"|"syntax error"|
# "preprocessor error"|"fatal error"|"lexical error": <message>
#
#====================================================================
local errorLevel
local searchFor = "(^\".*\",? line \\c[0-9]*[ :]*(warning|(syntax|preprocessor|fatal|lexical) error):?)" \
"|\\c(Global Optimizer|Intermediate file|Fatal|Syntax|Preprocessor|lexical) error:+"
local fnameline
local tempText
# scan the error file for the next appropriate message
if ( !match( errorCompleteText, searchFor))
return 0 # no more applicable messages
# get the source filename
errorSrcName = substr( errorCompleteText, 2,
cindex( substr( errorCompleteText, 2 ), "\"" ) - 1)
# determine the severity of the error
errorLevel = (errorCompleteText ~ /warning:/) ? 1 : 2
# get the line and column position of the error
tempText = substr(errorCompleteText, 0, 10)
errorLine = atoi( tempText )
errorColumn = 0
# get the text of the message
match( errorCompleteText, "(warning|error):\\c" )
tempText = substr(errorCompleteText, RSTART, RLENGTH)
errorText = ltrim(tempText)
return errorLevel
}
# ------------------- ErrorInfo function for Lahey FORTRAN ------------------
global laheyLine
global laheyText
global function laheyErrorInfo()
{
#====================================================================
#
# error message syntax for Lahey FORTRAN 77
#
# Lahey FORTRAN 77:
# "Compiling line : <line num>" This is only shown one time
# "File <source file name>, line <line num>: <copy of program line>
# <'^' pointer to Column position of Error>
# "(FATAL|WARNING) - <message>
#
#====================================================================
local errorLevel
local searchFor = "^(FATAL|WARNING)[ \t]* -\\c"
local fnameline
if (laheyText)
{
# the error message could span a couple of lines
if (errorCompleteText !~ /\.$/)
{
laheyText = laheyText errorCompleteText
return 0 # Error Message Not Complete
}
}
else
{
# scan the error file for the next appropriate message
if ( match( errorCompleteText, searchFor))
{
laheyText = errorCompleteText
return 0 # Error Message Not Complete
}
else
return 0 # no more applicable messages
}
errorCompleteText = laheyText
laheyText = ""
delete laheyText
# get the source filename
if (match( errorCompleteText, "File .*, line[ \t]+[0-9]+\\."))
{
# The line number and file name are on the same line.
fnameline = substr( errorCompleteText, RSTART+5 );
errorSrcName = trim(ltrim(substr( fnameline, 1,
cindex( fnameline, "," ) - 1 )))
# get the line and column position of the error
match( fnameline, "line[ \t]+[0-9]" )
fnameline = ltrim(substr( fnameline, RSTART + 4 ));
errorLine = atoi( fnameline )
errorColumn = 0
}
else if (match( errorCompleteText, "^File[ \t]+.* line +\\c[0-9]*"))
{
# The line number and file name are on a different line.
fnameline = substr( errorCompleteText, RSTART+5 );
match( fnameline, "," )
errorSrcName = substr( fnameline, 1, RSTART - 1 )
# get the line and column position of the error
match( fnameline, "line[ \t]+[0-9]" )
fnameline = ltrim(substr( fnameline, RSTART + 4 ));
errorLine = atoi( fnameline )
errorColumn = 0
}
else
{
return 0;
}
# determine the severity of the error
errorLevel = (errorCompleteText ~ /WARNING/) ? 1 : 2
# get the text of the message
if (match(errorCompleteText, "(FATAL|WARNING)[ \t]*-"))
errorText = ltrim(substr(errorCompleteText , RSTART + RLENGTH ));
return errorLevel
}
# ------------------- ErrorInfo function for Advantage ADA ------------------
global function adaErrorInfo()
{
#====================================================================
#
# error message syntax for Advantage ADA
#
# "<filename>", <line num>: <message>
#
#====================================================================
local errorLevel
local searchFor = "^\".*\", \\c[0-9]*:"
local tempText
# scan the error file for the next appropriate message
if ( !match( errorCompleteText, searchFor) )
return 0 # no more applicable messages
# get the source filename
errorSrcName = substr( errorCompleteText, 2,
cindex( substr( errorCompleteText, 2 ), "\"" ) - 1)
# determine the severity of the error
errorLevel = (errorCompleteText ~ /error/) ? 2 : 1
# get the line and column position of the error
tempText = substr(errorCompleteText, 0, 10)
errorLine = atoi( tempText )
errorColumn = 0
# get the text of the message
match( errorCompleteText, ":\\c" )
tempText = substr(errorCompleteText, RSTART, RLENGTH)
errorText = ltrim(errorCompleteText, tempText)
return errorLevel
}
# ------------------- ErrorInfo functions for Clipper -----------------------
global clipperPos
global clipperLine
global clipperText
global clipperSrcName
global function clipper8ErrorInfo()
{
#====================================================================
#
# error message syntax for Nantucket Clipper Summer87
#
# "Compiling <file>" (This is only shown one time)
# "line <line>: <message>"
# <copy of program line>
# <'^' pointer to Column position of Error>
#
#
# Clipper Support added by P. Polakoff III, 3P Software, Inc.
#
#====================================================================
local errorLevel
local searchFor = "^line \\c[0-9]+:"
local fnameline
if (substr(errorCompleteText, 1, 9) == "Compiling")
clipperSrcName = ltrim( trim( substr(errorCompleteText, 10 )))
# scan the error file for the next appropriate message
else if ( match( errorCompleteText, searchFor) )
{
# get the line of the error
errorLine = atoi(substr(errorCompleteText, RSTART, 10))
# get the text of the message
errorText = trim( substr( errorCompleteText, \
match( errorCompleteText, ":" ) + 1 ))
clipperPos = 1 # Re-set the Position Counter.
}
else if (clipperPos)
{
if (++clipperPos == 3)
{
# get the column position of the error
errorColumn = match(errorCompleteText , "\\^" )
errorLine = clipperLine
errorText = clipperText
errorLevel = 2
errorSrcName = clipperSrcName
return errorLevel # Ah-Ha - This is indeed the last line of the error
}
}
return 0 # Not the last line of an error message.
}
global function clipper5ErrorInfo()
{
#====================================================================
#
# error message syntax for Nantucket Clipper 5.0 (B93)
#
# <sourcefile>(<line number>) "Error"|"Warning" <errno> <message>
#
#====================================================================
local errorLevel
local searchFor = "\\(\\c[0-9]+\\) +(Error|Warning)"
local tempText
# scan the error file for the next appropriate message
if ( !match( errorCompleteText, searchFor) )
return 0 # no more applicable messages
# get the source filename
match( errorCompleteText, /[^( \t]+/ )
errorSrcName = substr( errorCompleteText, RSTART, RLENGTH )
# get the line and column position of the error
tempText = substr(errorCompleteText, 0, 10)
errorLine = atoi( tempText )
# determine the severity of the error
match( errorCompleteText, "<error>|<warning>")
tempText = substr(errorCompleteText, RSTART, RLENGTH)
tempText = substr(errorCompleteText, 0, 5)
errorLevel = (tolower(tempText) == "error") ? 2 : 1
# get the text of the message
tempText = substr(errorCompleteText, RSTART, RLENGTH)
errorText = ltrim(errorCompleteText, tempText)
return errorLevel
}
global function otherErrorInfo(searchPattern)
{
#====================================================================
# This function is invoked when a user-defined pattern is supplied
# for error message parsing.
#
# The pattern is a regular expression the contains the following
# special codes to indicate where the relevant information is.
#
# %f = Source Filename.
# %l = Error Line.
# %c = Error Column.
# %t = Error Message Text.
# %h = Hilight length.
# %v = Error Level.
#
#====================================================================
local errorLevel
local pattern
local before
local value
local after
local text
local what
local pos
errorSrcName = ""
errorText = ""
errorLine = 0
errorLevel = 0
errorColumn = 0
errorLength = 0
pattern = searchPattern
text = errorCompleteText
pos = cindex(pattern, "%")
while (pos)
{
if (pos == 1)
before = ""
else
before = prefix(pattern, pos - 1)
what = toupper(substr(pattern, pos+1, 1))
pattern = substr(pattern, pos+2)
pos = cindex(pattern, "%")
if (pos == 0)
after = pattern
else
after = prefix(pattern, pos - 1)
if (match(text, before ".*" after))
{
match(text, before)
text = substr(text, RSTART + RLENGTH)
if (length(after))
{
match(text, after)
value = prefix(text, RSTART - 1)
}
else
value = text
if (what == "F")
errorSrcName = value
else if (what == "T")
errorText = value
else if (what == "L")
errorLine = atoi(value)
else if (what == "C")
errorColumn = atoi(value)
else if (what == "H")
errorLength = atoi(value)
else if (what == "V")
errorLevel = atoi(value)
}
}
return errorLevel ? errorLevel : length(errorText) > 0 && errorLine
}
# ---------------------------------------------------------------------------
## display_error_file_key()
#
# Presents a dialog box from which to select an error message file to be
# parsed into the error dialog.
#
local IDD_DISPLAY_ERRORS = 1450
local IDE_COMPILER_LIST = 1451
local IDE_ERROR_FILE_NAME = 1452
local error_filename
local dialog_return_value
global function display_error_file_key( sourceFileName, errorFileName )
{
local dlgid
local name
local bufid
# reset microfocus global variables in case this is not the first time through
reset_mf_globs();
error_filename = length(sourceFileName) ? sourceFileName : buffer_filename
dlgid = create_dialog(function_id("display_error_callback"), 0, IDD_DISPLAY_ERRORS )
attach_help( editor_helpfile, dlgid )
add_dialog_item(dlgid, IDE_ERROR_FILE_NAME, DCTRL_EDIT_KEY)
add_dialog_item(dlgid, IDE_COMPILER_LIST, DCTRL_COMBO_BOX)
if ( !errorFileName )
errorFileName = bld_fnam(error_filename, error_filename, "err")
set_dialog_item(dlgid, IDE_ERROR_FILE_NAME, DAC_SET_TEXT_LEN, 512 )
set_dialog_item(dlgid, IDE_ERROR_FILE_NAME, DAC_EDIT_TEXT, errorFileName, 1 )
begin_dialog(dlgid, TRUE)
if ( dialog_return_value.FileName == "" )
return
bufid = next_buffer( path_fname(dialog_return_value.FileName) path_ext(dialog_return_value.FileName))
if ( bufid )
{
if ( buffer_filename == dialog_return_value.FileName )
{
warning(dialog_return_value.FileName " currently loaded in a buffer")
return
}
}
errorsFound = 0;
dlgid = create_compile_dialog(error_filename)
display_errors(error_filename, dialog_return_value.FileName,
dialog_return_value.CompilerName, list_all_output, dlgid,
TRUE)
}
global function display_error_callback()
{
local dlgid
local i, index, found_ext
local old_prompt_response
local call_hand = callback_dialog_handle
if ( ( callback_msg == DM_CLICK && callback_index == DI_HELP ) ||
( callback_msg == DM_HELPREQUESTED ) )
{
if(isWindows())
display_help("Error file", callback_dialog_handle);
else
display_help("errorfile", call_hand)
return DRC_MSG_PROCESSED
} # end DI_HELP
# fill in combo box
else if ( callback_msg == DM_INIT )
{
found_ext = 0
index = -1
for(i in compilers)
{
if (i != "[None]")
{
index = set_dialog_item(call_hand, IDE_COMPILER_LIST,
DAC_ADD_ITEM, i)
if (index != -1 && CompilerName(path_ext(error_filename)) == i)
{
found_ext = 1
set_dialog_item(call_hand, IDE_COMPILER_LIST,
DAC_SELECT_INDEX, index )
}
}
}
if ( found_ext == 0 && index != -1 )
set_dialog_item(call_hand, IDE_COMPILER_LIST, DAC_SELECT_INDEX, 0 )
}
else if ( callback_msg == DM_OK )
{
cleanup_prompt_history("EDITFILE")
dialog_return_value.FileName = query_dialog_item(call_hand, IDE_ERROR_FILE_NAME, DAC_EDIT_TEXT)
dialog_return_value.CompilerName = query_dialog_item(call_hand, IDE_COMPILER_LIST, DAC_SELECT_ITEM)
}
else if ( callback_msg == DM_CLOSE || callback_index == DI_CANCEL)
{
cleanup_prompt_history("EDITFILE")
dialog_return_value.FileName = ""
dialog_return_value.CompilerName = ""
return DRC_EXIT
}
else if ( callback_msg == DM_INVALID_PCHAR && callback_index == IDE_ERROR_FILE_NAME )
{
dialog_history( call_hand, callback_index, "EDITFILE")
# This is here while we fix the prompt focus problem
set_dialog_window(call_hand, DWC_TO_TOP)
set_dialog_item(call_hand, IDE_ERROR_FILE_NAME, DAC_EDIT_TEXT, prompt_response)
return DRC_MSG_PROCESSED
}
return DRC_CONTINUE
}