home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
the25.zip
/
thesrc251.zip
/
error.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-18
|
17KB
|
480 lines
/***********************************************************************/
/* ERROR.C - Function to display error messages. */
/***********************************************************************/
/*
* THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
* Copyright (C) 1991-1997 Mark Hessling
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation, Inc.
* 675 Mass Ave,
* Cambridge, MA 02139 USA.
*
*
* If you make modifications to this software that you feel increases
* it usefulness for the rest of the community, please email the
* changes, enhancements, bug fixes as well as any and all ideas to me.
* This software is going to be maintained and enhanced as deemed
* necessary by the community.
*
* Mark Hessling Email: M.Hessling@qut.edu.au
* PO Box 203 Phone: +617 3802 0800
* Bellara http://www.gu.edu.au/gext/the/markh.html
* QLD 4507 **** Maintainer PDCurses & REXX/SQL ****
* Australia ************* Author of THE ************
*/
/*
$Id: error.c 2.1 1995/06/24 16:29:50 MH Rel MH $
*/
#include <the.h>
#include <proto.h>
/*-------------------------- global data -----------------------------*/
CHARTYPE *last_message=NULL; /* contents of last error message */
int last_message_length=0;
static int errors_displayed=0; /* number of errors displayed */
static LINE *first_error=NULL; /* first error message */
static LINE *last_error=NULL; /* last error message */
#ifdef HAVE_PROTO
static void open_msgline(CHARTYPE,short,ROWTYPE);
#else
static void open_msgline();
#endif
/***********************************************************************/
#ifdef HAVE_PROTO
void display_error(unsigned short err_num,CHARTYPE *mess,bool ignore_bell)
#else
void display_error(err_num,mess,ignore_bell)
unsigned short err_num;
CHARTYPE *mess;
bool ignore_bell;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern WINDOW *error_window;
extern bool error_on_screen;
extern bool in_nomsg;
extern bool first_screen_display;
extern bool curses_started;
extern bool BEEPx;
extern CHARTYPE number_of_files;
extern bool rexx_output;
extern bool CAPREXXOUTx;
extern LINE *rexxout_first_line;
extern LINE *rexxout_curr;
extern LINETYPE rexxout_number_lines;
/*--------------------------- local data ------------------------------*/
static CHARTYPE *error_message[] =
{
(CHARTYPE *)"",
(CHARTYPE *)"Error 0001: Invalid operand:",
(CHARTYPE *)"Error 0002: Too many operands",
(CHARTYPE *)"Error 0003: Too few operands",
(CHARTYPE *)"Error 0004: Invalid number:",
(CHARTYPE *)"Error 0005: Numeric operand too small",
(CHARTYPE *)"Error 0006: Numeric operand too large",
(CHARTYPE *)"Error 0007: Invalid fileid:",
(CHARTYPE *)"Error 0008: Invalid or protected file",
(CHARTYPE *)"Error 0009: File not found",
(CHARTYPE *)"Error 0010: Path not found",
(CHARTYPE *)"Error 0011: File not found in THE_MACRO_PATH:",
(CHARTYPE *)"Error 0012: Margins settings are inconsistent",
(CHARTYPE *)"Error 0013: Invalid key name:",
(CHARTYPE *)"File is read-only:",
(CHARTYPE *)"",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0017: Target not found",
(CHARTYPE *)"Error 0018: Invalid line name",
(CHARTYPE *)"",
(CHARTYPE *)"New file:",
(CHARTYPE *)"Error 0021: Invalid command:",
(CHARTYPE *)"Error 0022: File has been changed - use QQUIT to really quit",
(CHARTYPE *)"Error 0023: Help file not found:",
(CHARTYPE *)"Error 0024: Invalid command while running in batch:",
(CHARTYPE *)"Error 0025: Error accessing REXX variable",
(CHARTYPE *)"",
(CHARTYPE *)"",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0029: Cannot edit -",
(CHARTYPE *)"Error 0030: Memory shortage",
(CHARTYPE *)"Error 0031: File already exists - use FFILE/SSAVE",
(CHARTYPE *)"Error 0032: Invalid hexadecimal or decimal value:",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0034: Line not found",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0036: No lines changed",
(CHARTYPE *)"Error 0037: Operand too long:",
(CHARTYPE *)"Error 0038: Improper cursor position",
(CHARTYPE *)"Error 0039: No remembered operand available",
(CHARTYPE *)"Error 0040: /bin/sh cannot suspend this process",
(CHARTYPE *)"Error 0041: Invalid SOS command:",
(CHARTYPE *)"Error 0042: Invalid SET command:",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0044: No marked block",
(CHARTYPE *)"Error 0045: Marked block not in current file",
(CHARTYPE *)"Error 0046: Block boundary excluded, not in range, or past truncation column",
(CHARTYPE *)"Error 0047: Operation invalid for line blocks",
(CHARTYPE *)"Error 0048: Operation invalid for box blocks",
(CHARTYPE *)"Error 0049: Operation invalid for stream blocks",
(CHARTYPE *)"Error 0050: Invalid move location",
(CHARTYPE *)"Error 0051: No preserved settings to restore",
(CHARTYPE *)"Error 0052: Non-REXX macros MUST have a first line of /*NOREXX*/",
(CHARTYPE *)"Error 0053: Valid only when issued from a REXX macro",
(CHARTYPE *)"Error 0054: REXX interpreter returned an error",
(CHARTYPE *)"Error 0055: No lines sorted",
(CHARTYPE *)"Error 0056: Action invalid in read-only mode.",
(CHARTYPE *)"Error 0057: Disk full error",
(CHARTYPE *)"Error 0058: Valid only with REXX support:",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0060: Line name not found:",
(CHARTYPE *)"Error 0061: Colour support not available:",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0063: Invalid cursor line or column",
(CHARTYPE *)"Error 0064: Line not reserved",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0066: Invalid match position",
(CHARTYPE *)"Error 0067: Invalid match character",
(CHARTYPE *)"Error 0068: Matching character not found",
(CHARTYPE *)"Error 0069: Invalid character",
(CHARTYPE *)"",
(CHARTYPE *)"",
(CHARTYPE *)"",
(CHARTYPE *)"",
(CHARTYPE *)"",
(CHARTYPE *)"",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0077: Files still open in batch:",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0079: Can't add another tab position; already have 32 defined",
(CHARTYPE *)"",
(CHARTYPE *)"Error 0081: Only single-line marked blocks allowed",
(CHARTYPE *)"Error 0082: Support for this command unavailable",
(CHARTYPE *)"Error 0083: Command invalid when ring is empty",
(CHARTYPE *)"Unable to restore",
(CHARTYPE *)"Error 0085: Length of operand > 10",
(CHARTYPE *)"Error 0086: Command line unavailable",
(CHARTYPE *)"Error 0087: Cursor line not in scope"
};
int new_last_message_length = 0;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("error.c: display_error");
#endif
/*---------------------------------------------------------------------*/
/* Always save message text, even if MSGMODE is OFF... */
/* If no error number, display text only... */
/*---------------------------------------------------------------------*/
new_last_message_length = 2 + ((err_num == 0) ? strlen((DEFCHAR*)mess) : strlen((DEFCHAR*)mess) + strlen((DEFCHAR*)error_message[err_num]) + 1);
if (last_message == NULL)
{
last_message_length = new_last_message_length;
last_message = (CHARTYPE *)(*the_malloc)(last_message_length*sizeof(CHARTYPE));
if (last_message == NULL)
return;
}
else
{
if (new_last_message_length > last_message_length)
{
last_message_length = new_last_message_length;
last_message = (CHARTYPE *)(*the_realloc)(last_message,last_message_length*sizeof(CHARTYPE));
if (last_message == NULL)
return;
}
}
if (err_num == 0)
strcpy((DEFCHAR *)last_message,(DEFCHAR *)mess);
else
sprintf((DEFCHAR *)last_message,"%s %s",error_message[err_num],mess);
/*---------------------------------------------------------------------*/
/* If msgmode is off, don't display any errors. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW != NULL)
{
if (!CURRENT_VIEW->msgmode_status)
{
#ifdef TRACE
trace_return();
#endif
return;
}
}
/*---------------------------------------------------------------------*/
/* If running from NOMSG command, don't display any errors. */
/*---------------------------------------------------------------------*/
if (in_nomsg)
{
#ifdef TRACE
trace_return();
#endif
return;
}
#ifdef MSWIN
{
char hdr[512];
if(in_profile)
{
if(!error_on_screen)
{
if(number_of_files == 0)
sprintf(hdr,"*** Messages from profile file ***\n");
else
sprintf(hdr,"*** Messages from profile file for ***\n%s%s\n",
CURRENT_FILE->fpath,CURRENT_FILE->fname);
}
error_on_screen = TRUE;
Operator("%s%s",hdr,last_message);
return;
}
}
#else
if (!curses_started)
{
if (!error_on_screen)
{
if (number_of_files == 0)
fprintf(stderr,"*** Messages from profile file ***\n");
else
fprintf(stderr,"*** Messages from profile file for %s%s ***\n",
CURRENT_FILE->fpath,CURRENT_FILE->fname);
}
error_on_screen = TRUE;
fprintf(stderr,"%s\n",last_message);
#ifdef TRACE
trace_return();
#endif
return;
}
#endif
/*---------------------------------------------------------------------*/
/* Append the current message to the end of the error linked list. */
/*---------------------------------------------------------------------*/
last_error = lll_add(first_error,last_error,sizeof(LINE));
if (last_error == NULL)
{
return;
}
last_error->line = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)last_message)+1)*sizeof(CHARTYPE));
if (last_error->line == NULL)
{
return;
}
strcpy((DEFCHAR *)last_error->line,(DEFCHAR *)last_message);
last_error->length = strlen((DEFCHAR *)last_message);
if (first_error == NULL)
first_error = last_error;
errors_displayed++;
expose_msgline();
/*---------------------------------------------------------------------*/
/* If capturing REXX output, then add a new line to the pseudo file. */
/*---------------------------------------------------------------------*/
if (CAPREXXOUTx
&& rexx_output)
{
rexxout_number_lines++;
rexxout_curr = add_line(rexxout_first_line,rexxout_curr,
last_message,strlen((DEFCHAR *)last_message),0,FALSE);
}
#ifdef HAVE_BEEP
if (BEEPx
&& !ignore_bell)
beep();
#endif
if (first_screen_display)
wrefresh(error_window);
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
static void open_msgline(CHARTYPE base,short off,ROWTYPE rows)
#else
static void open_msgline(base,off,rows)
CHARTYPE base;
short off;
ROWTYPE rows;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern WINDOW *error_window;
/*--------------------------- local data ------------------------------*/
int start_row=0;
COLOUR_ATTR attr;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("error.c: open_msgline");
#endif
if (CURRENT_VIEW == NULL
|| CURRENT_FILE == NULL)
set_up_default_colours((FILE_DETAILS *)NULL,&attr,ATTR_MSGLINE);
else
memcpy(&attr,CURRENT_FILE->attr+ATTR_MSGLINE,sizeof(COLOUR_ATTR));
start_row = calculate_actual_row(base,off,CURRENT_SCREEN.screen_rows,TRUE);
if (base == POSITION_BOTTOM)
start_row = start_row - rows + 1;
if (error_window != NULL)
delwin(error_window);
error_window = newwin(rows,CURRENT_SCREEN.screen_cols,CURRENT_SCREEN.screen_start_row+start_row,CURRENT_SCREEN.screen_start_col);
wattrset(error_window,set_colour(&attr));
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
void clear_msgline(void)
#else
void clear_msgline()
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern WINDOW *error_window;
extern bool error_on_screen;
extern CHARTYPE display_screens;
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("error.c: clear_msgline");
#endif
errors_displayed = 0;
error_on_screen = FALSE;
if (error_window != (WINDOW *)NULL)
{
delwin(error_window);
error_window = (WINDOW *)NULL;
}
first_error = last_error = lll_free(first_error);
if (display_screens > 1)
redraw_screen(other_screen);
redraw_screen(current_screen);
doupdate();
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
void display_prompt(CHARTYPE *prompt)
#else
void display_prompt(prompt)
CHARTYPE *prompt;
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern WINDOW *error_window;
extern bool error_on_screen;
/*--------------------------- local data ------------------------------*/
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("error.c: display_prompt");
#endif
open_msgline(CURRENT_VIEW->msgline_base,CURRENT_VIEW->msgline_off,1);
wmove(error_window,0,0);
my_wclrtoeol(error_window);
put_string(error_window,0,0,prompt,strlen((DEFCHAR *)prompt));
wrefresh(error_window);
error_on_screen = TRUE;
#ifdef TRACE
trace_return();
#endif
return;
}
/***********************************************************************/
#ifdef HAVE_PROTO
void expose_msgline(void)
#else
void expose_msgline()
#endif
/***********************************************************************/
{
/*------------------------- external data -----------------------------*/
extern WINDOW *error_window;
extern bool error_on_screen;
/*--------------------------- local data ------------------------------*/
LINE *curr_error=NULL;
register int i=0,errors_to_display=0;
CHARTYPE msgline_base=POSITION_TOP;
short msgline_off=2;
ROWTYPE msgline_rows=5;
/*--------------------------- processing ------------------------------*/
#ifdef TRACE
trace_function("error.c: expose_msgline");
#endif
/*---------------------------------------------------------------------*/
/* If msgmode is off, don't display any errors. */
/*---------------------------------------------------------------------*/
if (CURRENT_VIEW != NULL)
{
if (!CURRENT_VIEW->msgmode_status)
{
#ifdef TRACE
trace_return();
#endif
return;
}
msgline_rows = CURRENT_VIEW->msgline_rows;
msgline_base = CURRENT_VIEW->msgline_base;
msgline_off = CURRENT_VIEW->msgline_off;
}
curr_error = last_error;
/*---------------------------------------------------------------------*/
/* Calculate number of errors. This determines size of window to be */
/* created. */
/*---------------------------------------------------------------------*/
errors_to_display = min(msgline_rows,errors_displayed);
/*---------------------------------------------------------------------*/
/* Create the window errors_to_display rows long. */
/*---------------------------------------------------------------------*/
open_msgline(msgline_base,msgline_off,errors_to_display);
/*---------------------------------------------------------------------*/
/* For all errors that are to be displayed, display them starting from */
/* the bottom of the window. */
/*---------------------------------------------------------------------*/
for (i=errors_to_display-1;i>-1;i--)
{
wmove(error_window,i,0);
my_wclrtoeol(error_window);
if (CURRENT_VIEW == NULL
|| CURRENT_FILE == NULL)
mvwaddstr(error_window,i,0,(DEFCHAR *)curr_error->line);
else
put_string(error_window,i,0,curr_error->line,curr_error->length);
curr_error = curr_error->prev;
}
wnoutrefresh(error_window);
error_on_screen = TRUE;
#ifdef TRACE
trace_return();
#endif
return;
}