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-2013 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, mark@rexx.org  http://www.rexx.org/
33  */
34 
35 
36 #include <the.h>
37 #include <proto.h>
38 
39 /*-------------------------- global   data -----------------------------*/
40 
41 CHARTYPE *last_message=NULL;          /* contents of last error message */
42 int last_message_length=0;
43 static int errors_displayed=0;            /* number of errors displayed */
44 static LINE *first_error=NULL;                   /* first error message */
45 static LINE *last_error=NULL;                     /* last error message */
46 
47 #ifdef HAVE_PROTO
48 static void open_msgline(ROWTYPE,ROWTYPE,ROWTYPE);
49 #else
50 static void open_msgline();
51 #endif
52 /***********************************************************************/
53 #ifdef HAVE_PROTO
display_error(unsigned short err_num,CHARTYPE * mess,bool ignore_bell)54 int display_error(unsigned short err_num,CHARTYPE *mess,bool ignore_bell)
55 #else
56 int display_error(err_num,mess,ignore_bell)
57 unsigned short err_num;
58 CHARTYPE *mess;
59 bool ignore_bell;
60 #endif
61 /***********************************************************************/
62 {
63 static CHARTYPE _THE_FAR *error_message[] =
64 {
65    (CHARTYPE *)"",
66    (CHARTYPE *)"Error 0001: Invalid operand:",
67    (CHARTYPE *)"Error 0002: Too many operands",
68    (CHARTYPE *)"Error 0003: Too few operands",
69    (CHARTYPE *)"Error 0004: Invalid number:",
70    (CHARTYPE *)"Error 0005: Numeric operand too small",
71    (CHARTYPE *)"Error 0006: Numeric operand too large",
72    (CHARTYPE *)"Error 0007: Invalid fileid:",
73    (CHARTYPE *)"Error 0008: Invalid or protected file",
74    (CHARTYPE *)"Error 0009: File not found",
75    (CHARTYPE *)"Error 0010: Path not found",
76    (CHARTYPE *)"Error 0011: File not found in THE_MACRO_PATH:",
77    (CHARTYPE *)"Error 0012: Margins settings are inconsistent",
78    (CHARTYPE *)"Error 0013: Invalid key name:",
79    (CHARTYPE *)"File is read-only:",
80    (CHARTYPE *)"",
81    (CHARTYPE *)"",
82    (CHARTYPE *)"Error 0017: Target not found",
83    (CHARTYPE *)"Error 0018: Invalid line name",
84    (CHARTYPE *)"",
85    (CHARTYPE *)"New file:",
86    (CHARTYPE *)"Error 0021: Invalid command:",
87    (CHARTYPE *)"Error 0022: File has been changed - use QQUIT to really quit",
88    (CHARTYPE *)"Error 0023: Help file not found:",
89    (CHARTYPE *)"Error 0024: Invalid command while running in batch:",
90    (CHARTYPE *)"Error 0025: Error accessing REXX variable",
91    (CHARTYPE *)"",
92    (CHARTYPE *)"",
93    (CHARTYPE *)"",
94    (CHARTYPE *)"Error 0029: Cannot edit -",
95    (CHARTYPE *)"Error 0030: Memory shortage",
96    (CHARTYPE *)"Error 0031: File already exists - use FFILE/SSAVE",
97    (CHARTYPE *)"Error 0032: Invalid hexadecimal or decimal value:",
98    (CHARTYPE *)"",
99    (CHARTYPE *)"Error 0034: Line not found",
100    (CHARTYPE *)"",
101    (CHARTYPE *)"Error 0036: No lines changed",
102    (CHARTYPE *)"Error 0037: Operand too long:",
103    (CHARTYPE *)"Error 0038: Improper cursor position",
104    (CHARTYPE *)"Error 0039: No remembered operand available",
105    (CHARTYPE *)"Error 0040: /bin/sh cannot suspend this process",
106    (CHARTYPE *)"Error 0041: Invalid SOS command:",
107    (CHARTYPE *)"Error 0042: Invalid SET command:",
108    (CHARTYPE *)"",
109    (CHARTYPE *)"Error 0044: No marked block",
110    (CHARTYPE *)"Error 0045: Marked block not in current file",
111    (CHARTYPE *)"Error 0046: Block boundary excluded, not in range, or past truncation column",
112    (CHARTYPE *)"Error 0047: Operation invalid for line blocks",
113    (CHARTYPE *)"Error 0048: Operation invalid for box blocks",
114    (CHARTYPE *)"Error 0049: Operation invalid for stream blocks",
115    (CHARTYPE *)"Error 0050: Invalid move location",
116    (CHARTYPE *)"Error 0051: No preserved settings to restore",
117    (CHARTYPE *)"Error 0052: Non-REXX macros MUST have a first line of /*NOREXX*/",
118    (CHARTYPE *)"Error 0053: Valid only when issued from a REXX macro",
119    (CHARTYPE *)"Error 0054: REXX interpreter returned an error",
120    (CHARTYPE *)"Error 0055: No lines sorted",
121    (CHARTYPE *)"Error 0056: Action invalid in read-only mode.",
122    (CHARTYPE *)"Error 0057: Disk full error",
123    (CHARTYPE *)"Error 0058: Valid only with REXX support:",
124    (CHARTYPE *)"",
125    (CHARTYPE *)"Error 0060: Line name not found:",
126    (CHARTYPE *)"Error 0061: Colour support not available:",
127    (CHARTYPE *)"Error 0062: Operation invalid for multi-line stream blocks",
128    (CHARTYPE *)"Error 0063: Invalid cursor line or column",
129    (CHARTYPE *)"Error 0064: Line not reserved",
130    (CHARTYPE *)"",
131    (CHARTYPE *)"Error 0066: Invalid match position",
132    (CHARTYPE *)"Error 0067: Invalid match character",
133    (CHARTYPE *)"Error 0068: Matching character not found",
134    (CHARTYPE *)"Error 0069: Invalid character",
135    (CHARTYPE *)"",
136    (CHARTYPE *)"",
137    (CHARTYPE *)"",
138    (CHARTYPE *)"",
139    (CHARTYPE *)"",
140    (CHARTYPE *)"Error 0075: Too many sort fields - maximum is 1000",
141    (CHARTYPE *)"Error 0076: Fileid already in ring:",
142    (CHARTYPE *)"Error 0077: Files still open in batch:",
143    (CHARTYPE *)"Error 0078: Printing error:",
144    (CHARTYPE *)"Error 0079: Can't add another tab position; already have 32 defined",
145    (CHARTYPE *)"Error 0080: Can't add another CTLCHAR; already have 64 defined",
146    (CHARTYPE *)"Error 0081: Only single-line marked blocks allowed",
147    (CHARTYPE *)"Error 0082: Feature not supported:",
148    (CHARTYPE *)"Error 0083: Command invalid when ring is empty",
149    (CHARTYPE *)"Unable to restore",
150    (CHARTYPE *)"Error 0085: Length of operand > 10",
151    (CHARTYPE *)"Error 0086: Command line unavailable",
152    (CHARTYPE *)"Error 0087: Cursor line not in scope",
153    (CHARTYPE *)"",
154    (CHARTYPE *)"",
155    (CHARTYPE *)"",
156    (CHARTYPE *)"",
157    (CHARTYPE *)"",
158    (CHARTYPE *)"",
159    (CHARTYPE *)"",
160    (CHARTYPE *)"",
161    (CHARTYPE *)"",
162    (CHARTYPE *)"",
163    (CHARTYPE *)"",
164    (CHARTYPE *)"",
165    (CHARTYPE *)"",
166    (CHARTYPE *)"",
167    (CHARTYPE *)"",
168    (CHARTYPE *)"",
169    (CHARTYPE *)"",
170    (CHARTYPE *)"",
171    (CHARTYPE *)"",
172    (CHARTYPE *)"",
173    (CHARTYPE *)"",
174    (CHARTYPE *)"",
175    (CHARTYPE *)"",
176    (CHARTYPE *)"",
177    (CHARTYPE *)"",
178    (CHARTYPE *)"",
179    (CHARTYPE *)"",
180    (CHARTYPE *)"",
181    (CHARTYPE *)"",
182    (CHARTYPE *)"",
183    (CHARTYPE *)"",
184    (CHARTYPE *)"",
185    (CHARTYPE *)"",
186    (CHARTYPE *)"",
187    (CHARTYPE *)"",
188    (CHARTYPE *)"",
189    (CHARTYPE *)"",
190    (CHARTYPE *)"",
191    (CHARTYPE *)"",
192    (CHARTYPE *)"",
193    (CHARTYPE *)"",
194    (CHARTYPE *)"",
195    (CHARTYPE *)"",
196    (CHARTYPE *)"",
197    (CHARTYPE *)"",
198    (CHARTYPE *)"",
199    (CHARTYPE *)"",
200    (CHARTYPE *)"",
201    (CHARTYPE *)"",
202    (CHARTYPE *)"",
203    (CHARTYPE *)"Error 0138: Unexpected file time stamp change - use FFILE/SSAVE",
204    (CHARTYPE *)"",
205    (CHARTYPE *)"",
206    (CHARTYPE *)"",
207    (CHARTYPE *)"",
208    (CHARTYPE *)"",
209    (CHARTYPE *)"",
210    (CHARTYPE *)"",
211    (CHARTYPE *)"",
212    (CHARTYPE *)"",
213    (CHARTYPE *)"Error 0148: Already recording a macro",
214    (CHARTYPE *)"",
215    (CHARTYPE *)"",
216    (CHARTYPE *)"",
217    (CHARTYPE *)"",
218    (CHARTYPE *)"",
219    (CHARTYPE *)"Error 0154: JOIN would cause truncation",
220    (CHARTYPE *)"",
221    (CHARTYPE *)"",
222    (CHARTYPE *)"",
223    (CHARTYPE *)"",
224    (CHARTYPE *)"",
225    (CHARTYPE *)"",
226    (CHARTYPE *)"",
227    (CHARTYPE *)"",
228    (CHARTYPE *)"",
229    (CHARTYPE *)"",
230    (CHARTYPE *)"",
231    (CHARTYPE *)"",
232    (CHARTYPE *)"",
233    (CHARTYPE *)"",
234    (CHARTYPE *)"",
235    (CHARTYPE *)"",
236    (CHARTYPE *)"",
237    (CHARTYPE *)"",
238    (CHARTYPE *)"",
239    (CHARTYPE *)"",
240    (CHARTYPE *)"",
241    (CHARTYPE *)"",
242    (CHARTYPE *)"",
243    (CHARTYPE *)"",
244    (CHARTYPE *)"",
245    (CHARTYPE *)"",
246    (CHARTYPE *)"",
247    (CHARTYPE *)"",
248    (CHARTYPE *)"",
249    (CHARTYPE *)"",
250    (CHARTYPE *)"",
251    (CHARTYPE *)"Error 0186: Error accessing clipboard",
252    (CHARTYPE *)"Error 0187: No text in clipboard",
253    (CHARTYPE *)"",
254    (CHARTYPE *)"",
255    (CHARTYPE *)"",
256    (CHARTYPE *)"",
257    (CHARTYPE *)"",
258    (CHARTYPE *)"",
259    (CHARTYPE *)"",
260    (CHARTYPE *)"",
261    (CHARTYPE *)"",
262    (CHARTYPE *)"",
263    (CHARTYPE *)"",
264    (CHARTYPE *)"Error 0199: Parser not defined:",
265    (CHARTYPE *)"",
266    (CHARTYPE *)"",
267    (CHARTYPE *)"",
268    (CHARTYPE *)"",
269    (CHARTYPE *)"",
270    (CHARTYPE *)"",
271    (CHARTYPE *)"",
272    (CHARTYPE *)"",
273    (CHARTYPE *)"",
274    (CHARTYPE *)"",
275    (CHARTYPE *)"",
276    (CHARTYPE *)"",
277    (CHARTYPE *)"",
278    (CHARTYPE *)"",
279    (CHARTYPE *)"",
280    (CHARTYPE *)"",
281    (CHARTYPE *)"Error 0216: TLD error:",
282 };
283    int new_last_message_length = 0;
284    int x=0, y=0;
285    int rc=RC_OK;
286 
287    TRACE_FUNCTION("error.c:   display_error");
288 
289    if( curses_started
290    &&  CURRENT_VIEW != NULL
291    &&  CURRENT_WINDOW != NULL )
292       getyx( CURRENT_WINDOW, y, x );
293    /*
294     * Always save message text, even if MSGMODE is OFF...
295     * If no error number, display text only...
296     */
297    new_last_message_length = 2 + ((err_num == 0) ? strlen((DEFCHAR*)mess) : strlen((DEFCHAR*)mess) + strlen((DEFCHAR*)error_message[err_num]) + 1);
298    if (last_message == NULL)
299    {
300       last_message_length = new_last_message_length;
301       last_message = (CHARTYPE *)(*the_malloc)(last_message_length*sizeof(CHARTYPE));
302       if (last_message == NULL)
303       {
304          TRACE_RETURN();
305          return rc;
306       }
307    }
308    else
309    {
310       if (new_last_message_length > last_message_length)
311       {
312          last_message_length = new_last_message_length;
313          last_message = (CHARTYPE *)(*the_realloc)(last_message,last_message_length*sizeof(CHARTYPE));
314          if (last_message == NULL)
315          {
316             TRACE_RETURN();
317             return rc;
318          }
319       }
320    }
321    if (err_num == 0)
322       strcpy((DEFCHAR *)last_message,(DEFCHAR *)mess);
323    else
324       sprintf((DEFCHAR *)last_message,"%s %s",error_message[err_num],mess);
325    /*
326     * If msgmode is off, don't display any errors.
327     */
328    if (CURRENT_VIEW != NULL)
329    {
330       if (!CURRENT_VIEW->msgmode_status)
331       {
332          TRACE_RETURN();
333          return rc;
334       }
335    }
336    /*
337     * If running from NOMSG command, don't display any errors.
338     */
339    if (in_nomsg)
340    {
341       TRACE_RETURN();
342       return rc;
343    }
344 #ifdef MSWIN
345    {
346    char hdr[512];
347    if (in_profile)
348    {
349       if (!error_on_screen
350       &&  !be_quiet)
351       {
352          if (number_of_files == 0)
353             sprintf(hdr,"*** Messages from profile file  ***\n");
354          else
355             sprintf(hdr,"*** Messages from profile file for ***\n%s%s\n",
356                            CURRENT_FILE->fpath,CURRENT_FILE->fname);
357       }
358       error_on_screen = TRUE;
359       Operator("%s%s",hdr,last_message);
360       TRACE_RETURN();
361       return rc;
362    }
363    }
364 #else
365    if (!curses_started)
366    {
367       if (!error_on_screen
368       &&  !be_quiet)
369       {
370          if (number_of_files == 0)
371             fprintf(stderr,"*** Messages from profile file ***\n");
372          else
373             fprintf(stderr,"*** Messages from profile file for %s%s ***\n", CURRENT_FILE->fpath,CURRENT_FILE->fname );
374       }
375       error_on_screen = TRUE;
376       fprintf(stderr,"%s\n",last_message);
377       TRACE_RETURN();
378       return rc;
379    }
380 #endif
381    /*
382     * If SET ERROROUTPUT is ON, write the error message to stderr
383     */
384    if ( ERROROUTPUTx )
385    {
386       fprintf(stderr,"%s\n",last_message);
387    }
388    /*
389     * Append the current message to the end of the error linked list.
390     */
391    last_error = lll_add(first_error,last_error,sizeof(LINE));
392    if (last_error == NULL)
393    {
394       TRACE_RETURN();
395       return rc;
396    }
397    last_error->line = (CHARTYPE *)(*the_malloc)((strlen((DEFCHAR *)last_message)+1)*sizeof(CHARTYPE));
398    if (last_error->line == NULL)
399    {
400       TRACE_RETURN();
401       return rc;
402    }
403    strcpy((DEFCHAR *)last_error->line,(DEFCHAR *)last_message);
404    last_error->length = strlen((DEFCHAR *)last_message);
405    if (first_error == NULL)
406       first_error = last_error;
407    errors_displayed++;
408    rc = expose_msgline();
409    /*
410     * If capturing REXX output, then add a new line to the pseudo file.
411     */
412    if (CAPREXXOUTx
413    &&  rexx_output)
414    {
415       rexxout_number_lines++;
416       rexxout_curr = add_LINE( rexxout_first_line, rexxout_curr, last_message, strlen((DEFCHAR *)last_message), 0, FALSE );
417    }
418 #ifdef HAVE_BEEP
419    if (BEEPx
420    && !ignore_bell)
421       beep();
422 #endif
423    if( curses_started
424    &&  CURRENT_VIEW != NULL
425    &&  CURRENT_WINDOW != NULL )
426       wmove( CURRENT_WINDOW, y, x );
427    if ( first_screen_display )
428       wrefresh( error_window );
429    TRACE_RETURN();
430    return rc;
431 }
432 /***********************************************************************/
433 #ifdef HAVE_PROTO
open_msgline(ROWTYPE base,ROWTYPE off,ROWTYPE rows)434 static void open_msgline(ROWTYPE base, ROWTYPE off,ROWTYPE rows)
435 #else
436 static void open_msgline(base,off,rows)
437 ROWTYPE base,off,rows;
438 #endif
439 /***********************************************************************/
440 {
441    int start_row=0;
442    COLOUR_ATTR attr;
443 
444    TRACE_FUNCTION( "error.c:   open_msgline" );
445    if ( CURRENT_VIEW == NULL
446    ||   CURRENT_FILE == NULL )
447       set_up_default_colours( (FILE_DETAILS *)NULL, &attr, ATTR_MSGLINE );
448    else
449       memcpy( &attr, CURRENT_FILE->attr+ATTR_MSGLINE, sizeof(COLOUR_ATTR) );
450    start_row = calculate_actual_row( base, off, CURRENT_SCREEN.screen_rows, TRUE );
451    if ( base == POSITION_BOTTOM )
452       start_row = start_row - rows + 1;
453    if ( error_window != NULL )
454       delwin( error_window );
455    error_window = newwin( rows, CURRENT_SCREEN.screen_cols, CURRENT_SCREEN.screen_start_row + start_row, CURRENT_SCREEN.screen_start_col );
456    wattrset( error_window, set_colour(&attr) );
457 #ifdef HAVE_KEYPAD
458    keypad( error_window, TRUE );
459 #endif
460    TRACE_RETURN();
461    return;
462 }
463 /***********************************************************************/
464 #ifdef HAVE_PROTO
clear_msgline(int key)465 void clear_msgline(int key)
466 #else
467 void clear_msgline(key)
468 int key;
469 #endif
470 /***********************************************************************/
471 {
472    TRACE_FUNCTION("error.c:   clear_msgline");
473    /*
474     * Only clear the message line if the supplied key matches that set
475     * by SET CLEARERRORKEY.  -1 indicates any key can clear
476     */
477    if ( curses_started && ( key == CLEARERRORKEYx
478                             ||  CLEARERRORKEYx == -1 ) )
479    {
480       errors_displayed = 0;
481       error_on_screen = FALSE;
482       if (error_window != (WINDOW *)NULL)
483       {
484          delwin(error_window);
485          error_window = (WINDOW *)NULL;
486       }
487       first_error = last_error = lll_free(first_error);
488       if (display_screens > 1)
489          redraw_screen((CHARTYPE)(other_screen));
490       redraw_screen(current_screen);
491       doupdate();
492    }
493    TRACE_RETURN();
494    return;
495 }
496 /***********************************************************************/
497 #ifdef HAVE_PROTO
display_prompt(CHARTYPE * prompt)498 void display_prompt(CHARTYPE *prompt)
499 #else
500 void display_prompt(prompt)
501 CHARTYPE *prompt;
502 #endif
503 /***********************************************************************/
504 {
505    TRACE_FUNCTION("error.c:   display_prompt");
506    open_msgline(CURRENT_VIEW->msgline_base,CURRENT_VIEW->msgline_off,1);
507    wmove(error_window,0,0);
508    my_wclrtoeol(error_window);
509    put_string(error_window,0,0,prompt,strlen((DEFCHAR *)prompt));
510    wrefresh(error_window);
511    error_on_screen = TRUE;
512    TRACE_RETURN();
513    return;
514 }
515 /***********************************************************************/
516 #ifdef HAVE_PROTO
expose_msgline(void)517 int expose_msgline(void)
518 #else
519 int expose_msgline()
520 #endif
521 /***********************************************************************/
522 {
523 #define NORMAL_PROMPT "Press any key to continue..."
524 #define IN_MACRO_PROMPT "Press SPACE to terminate macro or any other key to continue..."
525    LINE *curr_error=NULL;
526    register int i=0;
527    ROWTYPE errors_to_display=0;
528    CHARTYPE msgline_base=POSITION_TOP;
529    short msgline_off=2;
530    ROWTYPE msgline_rows=5,max_rows,start_row;
531    int rc=RC_OK;
532    CHARTYPE *prompt;
533 
534    TRACE_FUNCTION("error.c:   expose_msgline");
535    /*
536     * If msgmode is off, don't display any errors.
537     */
538    if (CURRENT_VIEW != NULL)
539    {
540       if (!CURRENT_VIEW->msgmode_status)
541       {
542          TRACE_RETURN();
543          return rc;
544       }
545       msgline_rows = CURRENT_VIEW->msgline_rows;
546       msgline_base = CURRENT_VIEW->msgline_base;
547       msgline_off = CURRENT_VIEW->msgline_off;
548    }
549    curr_error = last_error;
550    /*
551     * Determine the maximum number of rows we can have in the MSGLINE
552     */
553    start_row = calculate_actual_row( msgline_base, msgline_off, CURRENT_SCREEN.screen_rows, TRUE );
554    if ( msgline_base == POSITION_BOTTOM )
555       max_rows = start_row + 1;
556    else
557       max_rows = CURRENT_SCREEN.screen_rows - start_row;
558    /*
559     * Calculate number of errors. This determines size of window to be
560     * created.
561     */
562    if ( msgline_rows == 0 )
563       msgline_rows = min( max_rows, errors_displayed );
564    else
565       msgline_rows = min( msgline_rows, errors_displayed );
566    errors_to_display = min( max_rows, msgline_rows );
567    /*
568     * Create the window; errors_to_display rows long.
569     */
570    open_msgline( msgline_base, msgline_off, errors_to_display );
571    /*
572     * For all errors that are to be displayed, display them starting from
573     * the bottom of the window.
574     */
575    for ( i = errors_to_display - 1; i > -1; i-- )
576    {
577       wmove( error_window, i, 0 );
578       my_wclrtoeol( error_window );
579       if ( CURRENT_VIEW == NULL
580       ||   CURRENT_FILE == NULL)
581          mvwaddstr( error_window, i, 0, (DEFCHAR *)curr_error->line );
582       else
583          put_string( error_window, (ROWTYPE)i, 0, curr_error->line, curr_error->length );
584       curr_error = curr_error->prev;
585    }
586    wnoutrefresh( error_window );
587    error_on_screen = TRUE;
588    if ( errors_to_display
589    &&   errors_to_display == msgline_rows
590    &&   (errors_displayed % errors_to_display) == 1
591    &&   curr_error != NULL )
592    {
593       if ( in_macro )
594          prompt = (CHARTYPE *)IN_MACRO_PROMPT;
595       else
596          prompt = (CHARTYPE *)NORMAL_PROMPT;
597       wmove( error_window, msgline_rows - 1, 0 );
598       my_wclrtoeol( error_window );
599       if ( CURRENT_VIEW == NULL
600       ||   CURRENT_FILE == NULL)
601       {
602          mvwaddstr( error_window, msgline_rows - 1, 0, (DEFCHAR *)prompt );
603       }
604       else
605       {
606          put_string( error_window, (ROWTYPE)(msgline_rows - 1), 0, (CHARTYPE *)prompt, strlen( (DEFCHAR *)prompt ) );
607       }
608       wrefresh( error_window );
609       if ( my_getch( error_window ) == ' ' )
610          rc = RC_TERMINATE_MACRO;
611    }
612    TRACE_RETURN();
613    return rc;
614 }
615