home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / the25.zip / thesrc251.zip / error.c < prev    next >
C/C++ Source or Header  |  1998-04-18  |  17KB  |  480 lines

  1. /***********************************************************************/
  2. /* ERROR.C - Function to display error messages.                       */
  3. /***********************************************************************/
  4. /*
  5.  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
  6.  * Copyright (C) 1991-1997 Mark Hessling
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License as
  10.  * published by the Free Software Foundation; either version 2 of
  11.  * the License, or any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16.  * General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to:
  20.  *
  21.  *    The Free Software Foundation, Inc.
  22.  *    675 Mass Ave,
  23.  *    Cambridge, MA 02139 USA.
  24.  *
  25.  *
  26.  * If you make modifications to this software that you feel increases
  27.  * it usefulness for the rest of the community, please email the
  28.  * changes, enhancements, bug fixes as well as any and all ideas to me.
  29.  * This software is going to be maintained and enhanced as deemed
  30.  * necessary by the community.
  31.  *
  32.  * Mark Hessling                 Email:             M.Hessling@qut.edu.au
  33.  * PO Box 203                    Phone:                    +617 3802 0800
  34.  * Bellara                       http://www.gu.edu.au/gext/the/markh.html
  35.  * QLD 4507                      **** Maintainer PDCurses & REXX/SQL ****
  36.  * Australia                     ************* Author of THE ************
  37.  */
  38.  
  39. /*
  40. $Id: error.c 2.1 1995/06/24 16:29:50 MH Rel MH $
  41. */
  42.  
  43. #include <the.h>
  44. #include <proto.h>
  45.  
  46. /*-------------------------- global   data -----------------------------*/
  47.  
  48. CHARTYPE *last_message=NULL;          /* contents of last error message */
  49. int last_message_length=0;
  50. static int errors_displayed=0;            /* number of errors displayed */
  51. static LINE *first_error=NULL;                   /* first error message */
  52. static LINE *last_error=NULL;                     /* last error message */
  53.  
  54. #ifdef HAVE_PROTO
  55. static void open_msgline(CHARTYPE,short,ROWTYPE);
  56. #else
  57. static void open_msgline();
  58. #endif
  59. /***********************************************************************/
  60. #ifdef HAVE_PROTO
  61. void display_error(unsigned short err_num,CHARTYPE *mess,bool ignore_bell)
  62. #else
  63. void display_error(err_num,mess,ignore_bell)
  64. unsigned short err_num;
  65. CHARTYPE *mess;
  66. bool ignore_bell;
  67. #endif
  68. /***********************************************************************/
  69. {
  70. /*------------------------- external data -----------------------------*/
  71.  extern WINDOW *error_window;
  72.  extern bool error_on_screen;
  73.  extern bool in_nomsg;
  74.  extern bool first_screen_display;
  75.  extern bool curses_started;
  76.  extern bool BEEPx;
  77.  extern CHARTYPE number_of_files;
  78.  extern bool rexx_output;
  79.  extern bool CAPREXXOUTx;
  80.  extern LINE *rexxout_first_line;
  81.  extern LINE *rexxout_curr;
  82.  extern LINETYPE rexxout_number_lines;
  83. /*--------------------------- local data ------------------------------*/
  84.  
  85. static CHARTYPE *error_message[] =
  86. {
  87.  (CHARTYPE *)"",
  88.  (CHARTYPE *)"Error 0001: Invalid operand:",
  89.  (CHARTYPE *)"Error 0002: Too many operands",
  90.  (CHARTYPE *)"Error 0003: Too few operands",
  91.  (CHARTYPE *)"Error 0004: Invalid number:",
  92.  (CHARTYPE *)"Error 0005: Numeric operand too small",
  93.  (CHARTYPE *)"Error 0006: Numeric operand too large",
  94.  (CHARTYPE *)"Error 0007: Invalid fileid:",
  95.  (CHARTYPE *)"Error 0008: Invalid or protected file",
  96.  (CHARTYPE *)"Error 0009: File not found",
  97.  (CHARTYPE *)"Error 0010: Path not found",
  98.  (CHARTYPE *)"Error 0011: File not found in THE_MACRO_PATH:",
  99.  (CHARTYPE *)"Error 0012: Margins settings are inconsistent",
  100.  (CHARTYPE *)"Error 0013: Invalid key name:",
  101.  (CHARTYPE *)"File is read-only:",
  102.  (CHARTYPE *)"",
  103.  (CHARTYPE *)"",
  104.  (CHARTYPE *)"Error 0017: Target not found",
  105.  (CHARTYPE *)"Error 0018: Invalid line name",
  106.  (CHARTYPE *)"",
  107.  (CHARTYPE *)"New file:",
  108.  (CHARTYPE *)"Error 0021: Invalid command:",
  109.  (CHARTYPE *)"Error 0022: File has been changed - use QQUIT to really quit",
  110.  (CHARTYPE *)"Error 0023: Help file not found:",
  111.  (CHARTYPE *)"Error 0024: Invalid command while running in batch:",
  112.  (CHARTYPE *)"Error 0025: Error accessing REXX variable",
  113.  (CHARTYPE *)"",
  114.  (CHARTYPE *)"",
  115.  (CHARTYPE *)"",
  116.  (CHARTYPE *)"Error 0029: Cannot edit -",
  117.  (CHARTYPE *)"Error 0030: Memory shortage",
  118.  (CHARTYPE *)"Error 0031: File already exists - use FFILE/SSAVE",
  119.  (CHARTYPE *)"Error 0032: Invalid hexadecimal or decimal value:",
  120.  (CHARTYPE *)"",
  121.  (CHARTYPE *)"Error 0034: Line not found",
  122.  (CHARTYPE *)"",
  123.  (CHARTYPE *)"Error 0036: No lines changed",
  124.  (CHARTYPE *)"Error 0037: Operand too long:",
  125.  (CHARTYPE *)"Error 0038: Improper cursor position",
  126.  (CHARTYPE *)"Error 0039: No remembered operand available",
  127.  (CHARTYPE *)"Error 0040: /bin/sh cannot suspend this process",
  128.  (CHARTYPE *)"Error 0041: Invalid SOS command:",
  129.  (CHARTYPE *)"Error 0042: Invalid SET command:",
  130.  (CHARTYPE *)"",
  131.  (CHARTYPE *)"Error 0044: No marked block",
  132.  (CHARTYPE *)"Error 0045: Marked block not in current file",
  133.  (CHARTYPE *)"Error 0046: Block boundary excluded, not in range, or past truncation column",
  134.  (CHARTYPE *)"Error 0047: Operation invalid for line blocks",
  135.  (CHARTYPE *)"Error 0048: Operation invalid for box blocks",
  136.  (CHARTYPE *)"Error 0049: Operation invalid for stream blocks",
  137.  (CHARTYPE *)"Error 0050: Invalid move location",
  138.  (CHARTYPE *)"Error 0051: No preserved settings to restore",
  139.  (CHARTYPE *)"Error 0052: Non-REXX macros MUST have a first line of /*NOREXX*/",
  140.  (CHARTYPE *)"Error 0053: Valid only when issued from a REXX macro",
  141.  (CHARTYPE *)"Error 0054: REXX interpreter returned an error",
  142.  (CHARTYPE *)"Error 0055: No lines sorted",
  143.  (CHARTYPE *)"Error 0056: Action invalid in read-only mode.",
  144.  (CHARTYPE *)"Error 0057: Disk full error",
  145.  (CHARTYPE *)"Error 0058: Valid only with REXX support:",
  146.  (CHARTYPE *)"",
  147.  (CHARTYPE *)"Error 0060: Line name not found:",
  148.  (CHARTYPE *)"Error 0061: Colour support not available:",
  149.  (CHARTYPE *)"",
  150.  (CHARTYPE *)"Error 0063: Invalid cursor line or column",
  151.  (CHARTYPE *)"Error 0064: Line not reserved",
  152.  (CHARTYPE *)"",
  153.  (CHARTYPE *)"Error 0066: Invalid match position",
  154.  (CHARTYPE *)"Error 0067: Invalid match character",
  155.  (CHARTYPE *)"Error 0068: Matching character not found",
  156.  (CHARTYPE *)"Error 0069: Invalid character",
  157.  (CHARTYPE *)"",
  158.  (CHARTYPE *)"",
  159.  (CHARTYPE *)"",
  160.  (CHARTYPE *)"",
  161.  (CHARTYPE *)"",
  162.  (CHARTYPE *)"",
  163.  (CHARTYPE *)"",
  164.  (CHARTYPE *)"Error 0077: Files still open in batch:",
  165.  (CHARTYPE *)"",
  166.  (CHARTYPE *)"Error 0079: Can't add another tab position; already have 32 defined",
  167.  (CHARTYPE *)"",
  168.  (CHARTYPE *)"Error 0081: Only single-line marked blocks allowed",
  169.  (CHARTYPE *)"Error 0082: Support for this command unavailable",
  170.  (CHARTYPE *)"Error 0083: Command invalid when ring is empty",
  171.  (CHARTYPE *)"Unable to restore",
  172.  (CHARTYPE *)"Error 0085: Length of operand > 10",
  173.  (CHARTYPE *)"Error 0086: Command line unavailable",
  174.  (CHARTYPE *)"Error 0087: Cursor line not in scope"
  175. };
  176.  int new_last_message_length = 0;
  177. /*--------------------------- processing ------------------------------*/
  178. #ifdef TRACE
  179.  trace_function("error.c:   display_error");
  180. #endif
  181. /*---------------------------------------------------------------------*/
  182. /* Always save message text, even if MSGMODE is OFF...                 */
  183. /* If no error number, display text only...                            */
  184. /*---------------------------------------------------------------------*/
  185.  new_last_message_length = 2 + ((err_num == 0) ? strlen((DEFCHAR*)mess) : strlen((DEFCHAR*)mess) + strlen((DEFCHAR*)error_message[err_num]) + 1);
  186.  if (last_message == NULL)
  187.    {
  188.     last_message_length = new_last_message_length;
  189.     last_message = (CHARTYPE *)(*the_malloc)(last_message_length*sizeof(CHARTYPE));
  190.     if (last_message == NULL)
  191.        return;
  192.    }
  193.  else
  194.    {
  195.     if (new_last_message_length > last_message_length)
  196.       {
  197.        last_message_length = new_last_message_length;
  198.        last_message = (CHARTYPE *)(*the_realloc)(last_message,last_message_length*sizeof(CHARTYPE));
  199.        if (last_message == NULL)
  200.           return;
  201.       }
  202.    }
  203.  if (err_num == 0)
  204.     strcpy((DEFCHAR *)last_message,(DEFCHAR *)mess);
  205.  else
  206.     sprintf((DEFCHAR *)last_message,"%s %s",error_message[err_num],mess);
  207.  
  208. /*---------------------------------------------------------------------*/
  209. /* If msgmode is off, don't display any errors.                        */
  210. /*---------------------------------------------------------------------*/
  211.  if (CURRENT_VIEW != NULL)
  212.    {
  213.     if (!CURRENT_VIEW->msgmode_status)
  214.       {
  215. #ifdef TRACE
  216.        trace_return();
  217. #endif
  218.        return;
  219.       }
  220.    }
  221.  
  222. /*---------------------------------------------------------------------*/
  223. /* If running from NOMSG command, don't display any errors.            */
  224. /*---------------------------------------------------------------------*/
  225.  if (in_nomsg)
  226.    {
  227. #ifdef TRACE
  228.     trace_return();
  229. #endif
  230.     return;
  231.    }
  232.  
  233. #ifdef MSWIN
  234.  {
  235.  char hdr[512];
  236.  if(in_profile)
  237.       {
  238.       if(!error_on_screen)
  239.            {
  240.            if(number_of_files == 0)
  241.                 sprintf(hdr,"*** Messages from profile file  ***\n");
  242.                 else
  243.                 sprintf(hdr,"*** Messages from profile file for ***\n%s%s\n",
  244.                          CURRENT_FILE->fpath,CURRENT_FILE->fname);
  245.            }
  246.       error_on_screen = TRUE;
  247.       Operator("%s%s",hdr,last_message);
  248.       return;
  249.       }
  250.  }
  251. #else
  252.  if (!curses_started)
  253.    {
  254.     if (!error_on_screen)
  255.       {
  256.        if (number_of_files == 0)
  257.           fprintf(stderr,"*** Messages from profile file  ***\n");
  258.        else
  259.           fprintf(stderr,"*** Messages from profile file for %s%s ***\n",
  260.                          CURRENT_FILE->fpath,CURRENT_FILE->fname);
  261.       }
  262.     error_on_screen = TRUE;
  263.     fprintf(stderr,"%s\n",last_message);
  264. #ifdef TRACE
  265.     trace_return();
  266. #endif
  267.     return;
  268.    }
  269. #endif
  270. /*---------------------------------------------------------------------*/
  271. /* Append the current message to the end of the error linked list.     */
  272. /*---------------------------------------------------------------------*/
  273.  last_error = lll_add(first_error,last_error,sizeof(LINE));
  274.  if (last_error == NULL)
  275.    {
  276.     return;
  277.    }
  278.  last_error->line = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)last_message)+1)*sizeof(CHARTYPE));
  279.  if (last_error->line == NULL)
  280.    {
  281.     return;
  282.    }
  283.  strcpy((DEFCHAR *)last_error->line,(DEFCHAR *)last_message);
  284.  last_error->length = strlen((DEFCHAR *)last_message);
  285.  if (first_error == NULL)
  286.     first_error = last_error;
  287.  errors_displayed++;
  288.  
  289.  expose_msgline();
  290. /*---------------------------------------------------------------------*/
  291. /* If capturing REXX output, then add a new line to the pseudo file.   */
  292. /*---------------------------------------------------------------------*/
  293.  if (CAPREXXOUTx
  294.  &&  rexx_output)
  295.    {
  296.     rexxout_number_lines++;
  297.     rexxout_curr = add_line(rexxout_first_line,rexxout_curr,
  298.                             last_message,strlen((DEFCHAR *)last_message),0,FALSE);
  299.    }
  300. #ifdef HAVE_BEEP
  301.  if (BEEPx
  302.  && !ignore_bell)
  303.     beep();
  304. #endif
  305.  if (first_screen_display)
  306.     wrefresh(error_window);
  307. #ifdef TRACE
  308.  trace_return();
  309. #endif
  310.  return;
  311. }
  312. /***********************************************************************/
  313. #ifdef HAVE_PROTO
  314. static void open_msgline(CHARTYPE base,short off,ROWTYPE rows)
  315. #else
  316. static void open_msgline(base,off,rows)
  317. CHARTYPE base;
  318. short off;
  319. ROWTYPE rows;
  320. #endif
  321. /***********************************************************************/
  322. {
  323. /*------------------------- external data -----------------------------*/
  324.  extern WINDOW *error_window;
  325. /*--------------------------- local data ------------------------------*/
  326.  int start_row=0;
  327.  COLOUR_ATTR attr;
  328. /*--------------------------- processing ------------------------------*/
  329. #ifdef TRACE
  330.  trace_function("error.c:   open_msgline");
  331. #endif
  332.  if (CURRENT_VIEW == NULL
  333.  ||  CURRENT_FILE == NULL)
  334.     set_up_default_colours((FILE_DETAILS *)NULL,&attr,ATTR_MSGLINE);
  335.  else
  336.     memcpy(&attr,CURRENT_FILE->attr+ATTR_MSGLINE,sizeof(COLOUR_ATTR));
  337.  start_row = calculate_actual_row(base,off,CURRENT_SCREEN.screen_rows,TRUE);
  338.  if (base == POSITION_BOTTOM)
  339.     start_row = start_row - rows + 1;
  340.  if (error_window != NULL)
  341.     delwin(error_window);
  342.  error_window = newwin(rows,CURRENT_SCREEN.screen_cols,CURRENT_SCREEN.screen_start_row+start_row,CURRENT_SCREEN.screen_start_col);
  343.  wattrset(error_window,set_colour(&attr));
  344. #ifdef TRACE
  345.  trace_return();
  346. #endif
  347.  return;
  348. }
  349. /***********************************************************************/
  350. #ifdef HAVE_PROTO
  351. void clear_msgline(void)
  352. #else
  353. void clear_msgline()
  354. #endif
  355. /***********************************************************************/
  356. {
  357. /*------------------------- external data -----------------------------*/
  358.  extern WINDOW *error_window;
  359.  extern bool error_on_screen;
  360.  extern CHARTYPE display_screens;
  361. /*--------------------------- local data ------------------------------*/
  362. /*--------------------------- processing ------------------------------*/
  363. #ifdef TRACE
  364.  trace_function("error.c:   clear_msgline");
  365. #endif
  366.  errors_displayed = 0;
  367.  error_on_screen = FALSE;
  368.  if (error_window != (WINDOW *)NULL)
  369.    {
  370.     delwin(error_window);
  371.     error_window = (WINDOW *)NULL;
  372.    }
  373.  first_error = last_error = lll_free(first_error);
  374.  if (display_screens > 1)
  375.     redraw_screen(other_screen);
  376.  redraw_screen(current_screen);
  377.  doupdate();
  378. #ifdef TRACE
  379.  trace_return();
  380. #endif
  381.  return;
  382. }
  383. /***********************************************************************/
  384. #ifdef HAVE_PROTO
  385. void display_prompt(CHARTYPE *prompt)
  386. #else
  387. void display_prompt(prompt)
  388. CHARTYPE *prompt;
  389. #endif
  390. /***********************************************************************/
  391. {
  392. /*------------------------- external data -----------------------------*/
  393.  extern WINDOW *error_window;
  394.  extern bool error_on_screen;
  395. /*--------------------------- local data ------------------------------*/
  396. /*--------------------------- processing ------------------------------*/
  397. #ifdef TRACE
  398.  trace_function("error.c:   display_prompt");
  399. #endif
  400.  open_msgline(CURRENT_VIEW->msgline_base,CURRENT_VIEW->msgline_off,1);
  401.  wmove(error_window,0,0);
  402.  my_wclrtoeol(error_window);
  403.  put_string(error_window,0,0,prompt,strlen((DEFCHAR *)prompt));
  404.  wrefresh(error_window);
  405.  error_on_screen = TRUE;
  406. #ifdef TRACE
  407.  trace_return();
  408. #endif
  409.  return;
  410. }
  411. /***********************************************************************/
  412. #ifdef HAVE_PROTO
  413. void expose_msgline(void)
  414. #else
  415. void expose_msgline()
  416. #endif
  417. /***********************************************************************/
  418. {
  419. /*------------------------- external data -----------------------------*/
  420.  extern WINDOW *error_window;
  421.  extern bool error_on_screen;
  422. /*--------------------------- local data ------------------------------*/
  423.  LINE *curr_error=NULL;
  424.  register int i=0,errors_to_display=0;
  425.  CHARTYPE msgline_base=POSITION_TOP;
  426.  short msgline_off=2;
  427.  ROWTYPE msgline_rows=5;
  428. /*--------------------------- processing ------------------------------*/
  429. #ifdef TRACE
  430.  trace_function("error.c:   expose_msgline");
  431. #endif
  432. /*---------------------------------------------------------------------*/
  433. /* If msgmode is off, don't display any errors.                        */
  434. /*---------------------------------------------------------------------*/
  435.  if (CURRENT_VIEW != NULL)
  436.    {
  437.     if (!CURRENT_VIEW->msgmode_status)
  438.       {
  439. #ifdef TRACE
  440.        trace_return();
  441. #endif
  442.        return;
  443.       }
  444.     msgline_rows = CURRENT_VIEW->msgline_rows;
  445.     msgline_base = CURRENT_VIEW->msgline_base;
  446.     msgline_off = CURRENT_VIEW->msgline_off;
  447.    }
  448.  curr_error = last_error;
  449. /*---------------------------------------------------------------------*/
  450. /* Calculate number of errors. This determines size of window to be    */
  451. /* created.                                                            */
  452. /*---------------------------------------------------------------------*/
  453.  errors_to_display = min(msgline_rows,errors_displayed);
  454. /*---------------------------------------------------------------------*/
  455. /* Create the window errors_to_display rows long.                      */
  456. /*---------------------------------------------------------------------*/
  457.  open_msgline(msgline_base,msgline_off,errors_to_display);
  458. /*---------------------------------------------------------------------*/
  459. /* For all errors that are to be displayed, display them starting from */
  460. /* the bottom of the window.                                           */
  461. /*---------------------------------------------------------------------*/
  462.  for (i=errors_to_display-1;i>-1;i--)
  463.    {
  464.     wmove(error_window,i,0);
  465.     my_wclrtoeol(error_window);
  466.     if (CURRENT_VIEW == NULL
  467.     ||  CURRENT_FILE == NULL)
  468.        mvwaddstr(error_window,i,0,(DEFCHAR *)curr_error->line);
  469.     else
  470.        put_string(error_window,i,0,curr_error->line,curr_error->length);
  471.     curr_error = curr_error->prev;
  472.    }
  473.  wnoutrefresh(error_window);
  474.  error_on_screen = TRUE;
  475. #ifdef TRACE
  476.  trace_return();
  477. #endif
  478.  return;
  479. }
  480.