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