1 /*
2  * Motif
3  *
4  * Copyright (c) 1987-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22 */
23 #ifdef REV_INFO
24 #ifndef lint
25 static char rcsid[] = "$XConsortium: UilDiags.c /main/15 1996/10/21 11:06:46 cde-osf $"
26 #endif
27 #endif
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 
34 /*
35 **++
36 **  FACILITY:
37 **
38 **      User Interface Language Compiler (UIL)
39 **
40 **  ABSTRACT:
41 **
42 **      This module contains the procedures for issuing diagnostics
43 **	for the UIL compiler.
44 **
45 **
46 **--
47 **/
48 
49 
50 /*
51 **
52 **  INCLUDE FILES
53 **
54 **/
55 
56 #include <stdio.h>
57 #include <signal.h>
58 #include <setjmp.h>
59 #include <X11/Intrinsic.h>
60 #include <X11/Xos.h>
61 #include <Xm/Xm.h>
62 
63 #include <stdarg.h>
64 
65 #include "UilDefI.h"
66 #include "UilMessTab.h"
67 
68 /*
69 **
70 **  EXTERNAL Storage
71 **
72 */
73 
74 externaldef(uil_comp_glbl)	int	Uil_message_count[uil_k_max_status+1];
75 
76 /*
77 **
78 **  OWN Storage
79 **
80 */
81 
82 static	boolean	issuing_diagnostic;
83 static	int	Uil_diag_status_delay_count;
84 
85 /*
86  * Fix for CR 5534 - static storage for old signal handlers
87  */
88 static	void 	(*bus_handler)();
89 static	void 	(*sys_handler)();
90 static	void 	(*fpe_handler)();
91 
92 /*
93 **++
94 **  FUNCTIONAL DESCRIPTION:
95 **
96 **      diag_store_handlers saves the signal handlers from the calling
97 **	application in global variables.
98 **
99 **  FORMAL PARAMETERS:
100 **
101 **	none
102 **
103 **  IMPLICIT INPUTS:
104 **
105 **	none
106 **
107 **  IMPLICIT OUTPUTS:
108 **
109 **	none
110 **
111 **  FUNCTION VALUE:
112 **
113 **      void
114 **
115 **  SIDE EFFECTS:
116 **
117 **      the global signal handler variables are changed.
118 **
119 **--
120 **/
121 
diag_store_handlers(void)122 void    diag_store_handlers
123             ( void )
124 {
125 /*
126  * Fix for CR 5534 - set the file variables for holding previous bus handlers
127  *                   to NULL and then store the old handlers (if any) when
128  *                   calling signal for the Uil handlers
129  */
130     bus_handler = signal( SIGBUS, diag_handler );       /* access violations */
131 #ifdef SIGSYS
132     sys_handler = signal( SIGSYS, diag_handler );       /* bad arguments to sys calls */
133 #endif
134     fpe_handler = signal( SIGFPE, diag_handler );       /* overflows */
135 /*
136  * End Fix for CR 5534
137  */
138 
139 }
140 
141 
142 /*
143 **++
144 **  FUNCTIONAL DESCRIPTION:
145 **
146 **      diag_issue_diagnostic emits a diagnostic to the listing file if
147 **	there is one and also sends an error to standard error file.
148 **
149 **  FORMAL PARAMETERS:
150 **
151 **      d_message_number:  index of the error to issue.  The indices are
152 **			   defined in message.h
153 **	a_src_rec:	   pointer to the source record to issue the
154 **			   diagnostic against.  This data structure has
155 **	l_start_column:	   position within the source line for diagnostic.
156 **			   A negative value indicates no position.
157 **	args:		   a variable length parameter list that holds the
158 **			   arguments to be substituted in the diagnositic
159 **
160 **  IMPLICIT INPUTS:
161 **
162 **      diag_rz_msg_table: table of messages and their severities defined
163 **			   in message_table.h
164 **	diag_rl_external_code:  Possible OS-specific external code
165 **
166 **  IMPLICIT OUTPUTS:
167 **
168 **      messages emitted
169 **
170 **  FUNCTION VALUE:
171 **
172 **      void
173 **
174 **  SIDE EFFECTS:
175 **
176 **      message counts updated
177 **
178 **--
179 **/
180 
181 #define buf_size (src_k_max_source_line_length + 1)
182 
diag_issue_diagnostic(int d_message_number,src_source_record_type * az_src_rec,int l_start_column,...)183 void	diag_issue_diagnostic
184 	    ( int d_message_number, src_source_record_type *az_src_rec,
185 	      int l_start_column, ...)
186 
187 {
188     va_list	ap;			/* ptr to variable length parameter */
189     int		severity;		/* severity of message */
190     int		message_number;		/* message number */
191     char	msg_buffer[132];	/* buffer to construct message */
192     char	ptr_buffer[buf_size];	/* buffer to construct pointer */
193     char	loc_buffer[132];	/* buffer to construct location */
194     char	src_buffer[buf_size];	/* buffer to hold source line */
195 
196     /*
197     **	check if we are in a loop issuing errors
198     */
199 
200     if (issuing_diagnostic)
201     {
202 	_debug_output( "nested diagnostics issued" );
203 	Uil_message_count[ uil_k_severe_status ]++;
204 	uil_exit( uil_k_severe_status );
205     }
206 
207     issuing_diagnostic = TRUE;
208 
209     /*
210     **	determine the severity of the error.  For d_submit_spr we issue
211     **	the fix previous error diagnostic, if we encountered prior errors;
212     **  otherwise we let it thru.
213     */
214 
215     message_number = d_message_number;
216 
217     if (message_number == d_submit_spr)
218 	if (Uil_message_count[ uil_k_error_status ] > 0)
219 	    message_number = d_prev_error;
220 
221     severity = diag_rz_msg_table[ message_number ].l_severity;
222 
223     /*
224     **	check if messages of this severity are to be reported.
225     */
226 
227     switch (severity)
228     {
229     case uil_k_info_status:
230 	if (Uil_cmd_z_command.v_report_info_msg)
231 	    break;
232 
233 	issuing_diagnostic = FALSE;
234 	return;
235 
236     case uil_k_warning_status:
237 	if (Uil_cmd_z_command.v_report_warn_msg)
238 	    break;
239 
240 	issuing_diagnostic = FALSE;
241 	return;
242 
243     default:
244 	;
245     }
246 
247     Uil_message_count[ severity ]++;
248     if (severity > uil_l_compile_status)
249 	uil_l_compile_status = severity;
250 
251     /*
252     **	Diagnostic format varies considerably
253     **	   1) no source
254     **		message
255     **	   2) source but no column
256     **		source line
257     **		message
258     **		location in source message
259     **	   3) source and column
260     **		source line
261     **		column pointer
262     **		message
263     **		location in source message
264     **	   4) source and column but no access key
265     **		message
266     **		location in source message
267     */
268 
269     /*
270     **	substitute any parameters into the error message placing the
271     **	resultant string in msg_buffer
272     */
273 
274     va_start(ap, l_start_column);
275 
276 #ifndef NO_MESSAGE_CATALOG
277     vsnprintf( msg_buffer, sizeof(msg_buffer),
278 	      catgets(uil_catd, UIL_SET1, msg_cat_table[ message_number ],
279 		      diag_rz_msg_table[ message_number ].ac_text),
280 	     ap );
281 #else
282     vsnprintf( msg_buffer, sizeof(msg_buffer),
283 	      diag_rz_msg_table[ message_number ].ac_text,
284 	      ap );
285 #endif
286     va_end(ap);
287 
288     src_buffer[ 0 ] = 0;
289     loc_buffer[ 0 ] = 0;
290     ptr_buffer[ 0 ] = 0;
291 
292     if (az_src_rec != diag_k_no_source)
293     {
294 	if ( !_src_null_access_key(az_src_rec->z_access_key) )
295 	{
296 	    /*
297 	    **	create the location line line
298 	    */
299 
300 #ifndef NO_MESSAGE_CATALOG
301 	    sprintf( loc_buffer,
302 		     catgets(uil_catd, UIL_SET_MISC,
303 			     UIL_MISC_0, "\t\t line: %d  file: %s"),
304 		     az_src_rec->w_line_number,
305 		     src_get_file_name( az_src_rec ) );
306 #else
307 	    sprintf( loc_buffer,
308 		     "\t\t line: %d  file: %s",
309 		     az_src_rec->w_line_number,
310 		     src_get_file_name( az_src_rec ) );
311 #endif
312 
313 	    /*
314 	    **	retrieve the source line
315 	    */
316 
317 	    src_buffer[ 0 ] = '\t';
318 	    src_retrieve_source( az_src_rec, &src_buffer[ 1 ] );
319 
320 	    /*
321 	    **	filter the standard unprintable characters.
322 	    */
323 
324 	    lex_filter_unprintable_chars
325 		    ( (unsigned char *)src_buffer, strlen( src_buffer ), 0 );
326 
327 	    /*
328 	    **	create the column pointer if a source position was given
329 	    */
330 
331 	    if (l_start_column != diag_k_no_column)
332 	    {
333 		int	i;
334 
335 		for (i=0;  i < l_start_column+1;  i++)
336 		{
337 		    if (src_buffer[ i ] == '\t')
338 			ptr_buffer[ i ] = '\t';
339 		    else
340 			ptr_buffer[ i ] = ' ';
341 		 }
342 
343 		ptr_buffer[ i++ ] = '*';
344 		ptr_buffer[ i ]   = 0;
345 	    }
346 	}
347 	else	/* no access key */
348 	{
349 	    /*
350 	    **	create the location line line
351 	    */
352 
353 	    if (l_start_column != diag_k_no_column)
354 #ifndef NO_MESSAGE_CATALOG
355 	      sprintf(loc_buffer,
356 		      catgets(uil_catd, UIL_SET_MISC,
357 			      UIL_MISC_1,
358 			      "\t\t line: %d  position: %d  file: %s"),
359 		      az_src_rec->w_line_number,
360 		      l_start_column + 1,
361 		      src_get_file_name( az_src_rec ) );
362 #else
363 	      sprintf(loc_buffer,
364 		      "\t\t line: %d  position: %d  file: %s",
365 		      az_src_rec->w_line_number,
366 		      l_start_column + 1,
367 		      src_get_file_name( az_src_rec ) );
368 #endif
369 	    else
370 #ifndef NO_MESSAGE_CATALOG
371 		sprintf( loc_buffer, catgets(uil_catd, UIL_SET_MISC,
372 					     UIL_MISC_0,
373 					     "\t\t line: %d  file: %s"),
374 			 az_src_rec->w_line_number,
375 			 src_get_file_name( az_src_rec ) );
376 #else
377 		sprintf( loc_buffer,
378 			 "\t\t line: %d  file: %s",
379 			 az_src_rec->w_line_number,
380 			 src_get_file_name( az_src_rec ) );
381 #endif
382 	}
383     }
384 
385     /*
386     **  issue the error to standard error file (system specific)
387     */
388 
389     write_msg_to_standard_error
390 	( message_number, src_buffer, ptr_buffer, msg_buffer, loc_buffer );
391 
392     /*
393     **	if we have a listing, place message in the source structure
394     */
395 
396     if (Uil_cmd_z_command.v_listing_file)
397 	src_append_diag_info
398 	    ( az_src_rec, l_start_column, msg_buffer, message_number );
399 
400     issuing_diagnostic = FALSE;
401 
402     /*
403     **	if there are fatal errors, print the listing file and exit.
404     */
405 
406     if (Uil_message_count[ uil_k_severe_status] > 0)
407     {
408 	lst_output_listing();
409 	uil_exit( uil_k_severe_status );
410     }
411 
412 }
413 
414 /*
415 **++
416 **  FUNCTIONAL DESCRIPTION:
417 **
418 **      diag_issue_summary emits a diagnostic summary if any diagnostics
419 **	were issued during the compilation
420 **
421 **  FORMAL PARAMETERS:
422 **
423 **      void
424 **
425 **  IMPLICIT INPUTS:
426 **
427 **      Uil_message_count	   table of messages issued
428 **
429 **  IMPLICIT OUTPUTS:
430 **
431 **      messages optionally emitted
432 **
433 **  FUNCTION VALUE:
434 **
435 **      void
436 **
437 **  SIDE EFFECTS:
438 **
439 **      none
440 **
441 **--
442 **/
443 
diag_issue_summary()444 void	diag_issue_summary()
445 
446 {
447 
448     if (uil_l_compile_status == uil_k_success_status)
449 	return;
450 
451     Uil_cmd_z_command.v_report_info_msg = TRUE;
452 
453     diag_issue_diagnostic
454 	( d_summary,
455 	  diag_k_no_source, diag_k_no_column,
456 	  Uil_message_count[ uil_k_error_status ],
457 	  Uil_message_count[ uil_k_warning_status ],
458 	  Uil_message_count[ uil_k_info_status ] );
459 
460     return;
461 }
462 
463 /*
464 **++
465 **  FUNCTIONAL DESCRIPTION:
466 **
467 **      The major constructs in the UIL language each have a data structure
468 **	and a tag value in the first byte of that data structure.  Given
469 **	a tag value, this routine will return a string that can be substituted
470 **      in an error message to describe that construct.
471 **
472 **  FORMAL PARAMETERS:
473 **
474 **      b_tag
475 **
476 **  IMPLICIT INPUTS:
477 **
478 **      none
479 **
480 **  IMPLICIT OUTPUTS:
481 **
482 **      none
483 **
484 **  FUNCTION VALUE:
485 **
486 **      char *	 text corresponding to tag
487 **
488 **  SIDE EFFECTS:
489 **
490 **      none
491 **
492 **--
493 **/
494 
diag_tag_text(b_tag)495 char	*diag_tag_text( b_tag )
496 
497 int XmConst   b_tag;
498 
499 {
500 
501     switch (b_tag)
502     {
503     case sym_k_value_entry:
504 	return "value";
505     case sym_k_widget_entry:
506 	return "widget";
507     case sym_k_gadget_entry:
508 	return "gadget";
509     case sym_k_child_entry:
510 	return "auto child";
511     case sym_k_module_entry:
512 	return "module";
513     case sym_k_proc_def_entry:
514     case sym_k_proc_ref_entry:
515 	return "procedure";
516     case sym_k_identifier_entry:
517 	return "identifier";
518 
519 /*   These are used by the symbol table dumper.    */
520 
521     case sym_k_argument_entry:
522 	return "argument";
523     case sym_k_callback_entry:
524 	return "callback";
525     case sym_k_control_entry:
526 	return "control";
527     case sym_k_name_entry:
528 	return "name";
529     case sym_k_forward_ref_entry:
530 	return "forward ref";
531     case sym_k_external_def_entry:
532 	return "external def";
533     case sym_k_list_entry:
534 	return "list";
535     case sym_k_root_entry:
536 	return "root";
537     case sym_k_include_file_entry:
538 	return "include file";
539     case sym_k_def_obj_entry:
540 	return "default variant";
541     case sym_k_section_entry:
542 	return "section";
543 
544     default:
545 #ifndef NO_MESSAGE_CATALOG
546 	return (catgets(uil_catd, UIL_VALUES, UIL_VAL_1, "** unknown **"));
547 #else
548 	return "** unknown **";
549 #endif
550     }
551 
552 }
553 
554 /*
555 **++
556 **  FUNCTIONAL DESCRIPTION:
557 **
558 **      Each widget in the UIL language has a integer value.  Given this
559 **	value, this routine will return a string that can be substituted
560 **      in an error message to describe that widget.
561 **
562 **  FORMAL PARAMETERS:
563 **
564 **      b_type		integer rep of the widget type
565 **
566 **  IMPLICIT INPUTS:
567 **
568 **      none
569 **
570 **  IMPLICIT OUTPUTS:
571 **
572 **      none
573 **
574 **  FUNCTION VALUE:
575 **
576 **      char *	 text corresponding to type
577 **
578 **  SIDE EFFECTS:
579 **
580 **      none
581 **
582 **--
583 **/
584 
diag_object_text(b_type)585 char	*diag_object_text( b_type )
586 
587 int XmConst   b_type;
588 
589 {
590     if ( b_type <= sym_k_error_object )
591 #ifndef NO_MESSAGE_CATALOG
592 	return (catgets(uil_catd, UIL_VALUES, UIL_VAL_0, "** error **"));
593 #else
594 	return "** error **";
595 #endif
596     if ( b_type <= uil_max_object )
597 	return uil_widget_names[b_type];
598 #ifndef NO_MESSAGE_CATALOG
599     return (catgets(uil_catd, UIL_VALUES, UIL_VAL_1, "** unknown **"));
600 #else
601     return "** unknown **";
602 #endif
603 
604 }
605 
606 /*
607 **++
608 **  FUNCTIONAL DESCRIPTION:
609 **
610 **      Each value in the UIL language has a integer value.  Given this
611 **	value, this routine will return a string that can be substituted
612 **      in an error message to describe that value.
613 **
614 **  FORMAL PARAMETERS:
615 **
616 **      b_type		integer rep of the value type
617 **
618 **  IMPLICIT INPUTS:
619 **
620 **      none
621 **
622 **  IMPLICIT OUTPUTS:
623 **
624 **      none
625 **
626 **  FUNCTION VALUE:
627 **
628 **      char *	 text corresponding to type
629 **
630 **  SIDE EFFECTS:
631 **
632 **      none
633 **
634 **--
635 **/
636 
diag_value_text(b_type)637 char	*diag_value_text( b_type )
638 
639 int XmConst   b_type;
640 
641 {
642 
643     if ( b_type <= sym_k_error_value )
644 #ifndef NO_MESSAGE_CATALOG
645 	return (catgets(uil_catd, UIL_VALUES, UIL_VAL_0, "** error **"));
646 #else
647 	return "** error **";
648 #endif
649     if ( b_type <= sym_k_max_value )
650 	return uil_datatype_names[b_type];
651 #ifndef NO_MESSAGE_CATALOG
652     return (catgets(uil_catd, UIL_VALUES, UIL_VAL_1, "** unknown **"));
653 #else
654     return "** unknown **";
655 #endif
656 
657 }
658 
659 
660 /*
661 **++
662 **  FUNCTIONAL DESCRIPTION:
663 **
664 **      Each charset supported by UIL has a integer value.  Given this
665 **	value, this routine will return a string that can be substituted
666 **      in an error message to describe that charset.
667 **
668 **  FORMAL PARAMETERS:
669 **
670 **      b_type		integer rep of the charset
671 **
672 **  IMPLICIT INPUTS:
673 **
674 **      none
675 **
676 **  IMPLICIT OUTPUTS:
677 **
678 **      none
679 **
680 **  FUNCTION VALUE:
681 **
682 **      char *	 text corresponding to type
683 **
684 **  SIDE EFFECTS:
685 **
686 **      none
687 **
688 **--
689 **/
690 
diag_charset_text(b_type)691 char	*diag_charset_text( b_type )
692 
693 int XmConst   b_type;
694 
695 {
696 
697     if ( b_type <= sym_k_error_charset )
698 #ifndef NO_MESSAGE_CATALOG
699 	return (catgets(uil_catd, UIL_VALUES, UIL_VAL_0, "** error **"));
700 #else
701 	return "** error **";
702 #endif
703     if ( b_type <= uil_max_charset )
704 	return uil_charset_names[b_type];
705 #ifndef NO_MESSAGE_CATALOG
706     return (catgets(uil_catd, UIL_VALUES, UIL_VAL_1, "** unknown **"));
707 #else
708     return "** unknown **";
709 #endif
710 
711 }
712 
713 
714 /*
715 **++
716 **  FUNCTIONAL DESCRIPTION:
717 **
718 **      This routine initializes the diagnostic system.  This includes
719 **	establishes a handler for catastrophic errors and initializing
720 **	error tables.
721 **
722 **  FORMAL PARAMETERS:
723 **
724 **      none
725 **
726 **  IMPLICIT INPUTS:
727 **
728 **      none
729 **
730 **  IMPLICIT OUTPUTS:
731 **
732 **      Uil_message_count
733 **	issuing_diagnostic
734 **	Uil_diag_status_delay_count
735 **
736 **  FUNCTION VALUE:
737 **
738 **      void
739 **
740 **  SIDE EFFECTS:
741 **
742 **      error handler is supplied for SIGBUS, SIGFPE and SIGSYS errors
743 **
744 **--
745 **/
746 
diag_initialize_diagnostics()747 void	diag_initialize_diagnostics()
748 
749 {
750 
751     int	    i;
752 
753     /*
754     **	Set up a handler to be invoked if access violations or
755     **	bad arguments to sys calls occur.
756     **  Other errors should be processed as is standard for the OS.
757     */
758 /*
759  * Fix for CR 5534 - call diag_store_handlers to save the old signal handlers.
760  */
761     diag_store_handlers();
762 /*
763  * End Fix for CR 5534
764  */
765 
766     signal( SIGBUS, diag_handler );	/* access violations */
767 #ifdef SIGSYS
768     signal( SIGSYS, diag_handler );	/* bad arguments to sys calls */
769 #endif
770     signal( SIGFPE, diag_handler );	/* overflows */
771 
772 
773     /*
774     **  Reset the message counts to zero.
775     */
776     for (i=0;  i <= uil_k_max_status;  i++)
777 	Uil_message_count[ i ] = 0;
778 
779 
780     /*
781     **  Clear the flag that we used to detect recursive error reporinting.
782     */
783     issuing_diagnostic = FALSE;
784 
785 
786     /*
787     **  Make sure there is no delay before starting to report status.
788     */
789     Uil_diag_status_delay_count = 0;
790 }
791 
792 
793 /*
794 **++
795 **  FUNCTIONAL DESCRIPTION:
796 **
797 **      This routine resets the handler for detecting overflows.
798 **
799 **  FORMAL PARAMETERS:
800 **
801 **      none
802 **
803 **  IMPLICIT INPUTS:
804 **
805 **      none
806 **
807 **  IMPLICIT OUTPUTS:
808 **
809 **      none
810 **
811 **  FUNCTION VALUE:
812 **
813 **      void
814 **
815 **  SIDE EFFECTS:
816 **
817 **      error handler is supplied for SIGFPE
818 **
819 **--
820 **/
821 
diag_reset_overflow_handler()822 void	diag_reset_overflow_handler()
823 
824 {
825 
826     signal( SIGFPE, diag_handler );	/* overflows */
827 
828 }
829 
830 
831 /*
832 **++
833 **  FUNCTIONAL DESCRIPTION:
834 **
835 **      This routine is the handler for internal errors.
836 **
837 **  FORMAL PARAMETERS:
838 **
839 **      l_error	    type of signal being raised
840 **
841 **  IMPLICIT INPUTS:
842 **
843 **      none
844 **
845 **  IMPLICIT OUTPUTS:
846 **
847 **      none
848 **
849 **  FUNCTION VALUE:
850 **
851 **      void
852 **
853 **  SIDE EFFECTS:
854 **
855 **      image will exit (done by diag_issue_diagnostic)
856 **
857 **--
858 **/
859 
diag_handler(l_error)860 void	diag_handler( l_error )
861 
862 int	l_error;
863 
864 {
865     /*
866     **	This handler is invoked for access violations, oeverflows or bad
867     **  arguments to sys calls.  Other errors are processed as is standard
868     **	for the OS.  The handler checks on overflow to see if we are trying
869     **	to catch them at the moment.  Otherwise it issues an internal error.
870     */
871 
872     if (l_error == SIGFPE)
873     {
874 	if (uil_az_error_env_valid)
875 	{
876 	    longjmp( uil_az_error_env_block, 1);
877 	}
878     }
879 
880 #if debug_version
881     {
882       char	*error_text;
883 
884       switch (l_error)
885 	{
886 	case SIGBUS:
887 	  error_text = "Access Violation";
888 	  break;
889 #ifdef SIGSYS
890 	case SIGSYS:
891 	  error_text = "Bad system call";
892 	  break;
893 #endif
894 	case SIGFPE:
895 	  error_text = "Overflow";
896 	  break;
897 	default:
898 	  error_text = "Unknown reason";
899 	}
900 
901       diag_issue_internal_error( error_text );
902     }
903 
904 #else
905 
906     diag_issue_internal_error( NULL );
907 
908 #endif
909 
910     /* we don't expect to come back */
911 
912 }
913 
914 /*
915 **++
916 **  FUNCTIONAL DESCRIPTION:
917 **
918 **      This routine issues an internal error.
919 **
920 **  FORMAL PARAMETERS:
921 **
922 **      error_text	In the debug version this parameter holds a
923 **			description of the internal error.  In the
924 **			non debug version it is omitted.
925 **
926 **  IMPLICIT INPUTS:
927 **
928 **      none
929 **
930 **  IMPLICIT OUTPUTS:
931 **
932 **      none
933 **
934 **  FUNCTION VALUE:
935 **
936 **      void
937 **
938 **  SIDE EFFECTS:
939 **
940 **      image will exit (done by diag_issue_diagnostic)
941 **
942 **--
943 **/
944 
diag_issue_internal_error(error_text)945 void	diag_issue_internal_error( error_text )
946 
947 char	* error_text;
948 
949 {
950 
951     /*
952     **	This routine is a focal point for issuing internal errors.
953     **  In DEBUG mode it takes an argument that gives more information
954     **	about the failure.
955     */
956 
957 #if debug_version
958 
959     diag_issue_diagnostic
960 	( d_bug_check, diag_k_no_source, diag_k_no_column , error_text );
961 
962 #else
963 
964     diag_issue_diagnostic( d_submit_spr, diag_k_no_source, diag_k_no_column );
965 
966 #endif
967 
968     /* we don't expect to come back */
969 
970 }
971 
972 
973 
974 
975 /*
976 **++
977 **  FUNCTIONAL DESCRIPTION:
978 **
979 **      this routine emits a diagnostic to stderr
980 **
981 **  FORMAL PARAMETERS:
982 **
983 **	msg_number:	message number
984 **      src_buffer:	ptr to source buffer for the error
985 **      ptr_buffer:	ptr to column buffer locator for the error
986 **      msg_buffer:	ptr to message buffer for the error
987 **      loc_buffer:	ptr to location buffer for the error
988 **
989 **  IMPLICIT INPUTS:
990 **
991 **      none
992 **
993 **  IMPLICIT OUTPUTS:
994 **
995 **      messages emitted
996 **
997 **  FUNCTION VALUE:
998 **
999 **      void
1000 **
1001 **  SIDE EFFECTS:
1002 **
1003 **      none
1004 **
1005 **--
1006 **/
1007 
1008 
1009 static char	XmConst success_text[1]  = "";
1010 static char	XmConst info_text[7]     = "Info: ";
1011 static char	XmConst warning_text[10] = "Warning: ";
1012 static char	XmConst error_text[8]    = "Error: ";
1013 static char	XmConst severe_text[9]   = "Severe: ";
1014 
1015 static char	XmConst *severity_table [] =
1016     { success_text, info_text, warning_text, error_text, severe_text, };
1017 
write_msg_to_standard_error(message_number,src_buffer,ptr_buffer,msg_buffer,loc_buffer)1018 void	write_msg_to_standard_error
1019 		(message_number, src_buffer, ptr_buffer, msg_buffer, loc_buffer)
1020 
1021 XmConst int   message_number;
1022 XmConst char  *src_buffer;
1023 XmConst char  *ptr_buffer;
1024 XmConst char  *msg_buffer;
1025 XmConst char  *loc_buffer;
1026 
1027 {
1028 
1029     /*
1030     **  If message callback was supplied, call it with the description of the
1031     **  error instead of writing it to standard output.
1032     */
1033     if (Uil_cmd_z_command.message_cb != (Uil_continue_type(*)())NULL)
1034     {
1035 	Uil_status_type return_status;
1036 /*
1037  * Fix for 5534 - restore the old signal handers before calling message_cb
1038  *                and restore the Uil signal handlers immediately afterwards
1039  */
1040         diag_restore_diagnostics();
1041 	return_status = (*Uil_cmd_z_command.message_cb)(
1042 			    Uil_cmd_z_command.message_data,
1043 			    message_number,
1044 			    diag_rz_msg_table[ message_number ].l_severity,
1045 			    msg_buffer,
1046 			    src_buffer,
1047 			    ptr_buffer,
1048 			    loc_buffer,
1049 			    Uil_message_count);
1050          diag_store_handlers();
1051 /*
1052  * End Fix for 5534
1053  */
1054 
1055 	/*
1056 	**  If request is for termination, then longjmp back to main routine
1057 	**  and set the return status to reflect user abort.
1058 	*/
1059 	if (return_status == Uil_k_terminate)
1060 	    uil_exit (uil_k_error_status);
1061 	else
1062 	    return;
1063     }
1064 
1065 
1066 
1067     /* print source line */
1068 
1069     fprintf ( stderr, "\n" );
1070 
1071     if (src_buffer[ 0 ] != 0)
1072     {
1073 	fprintf ( stderr, "%s\n", src_buffer );
1074      }
1075 
1076     /* print the source column locator line */
1077 
1078     if (ptr_buffer[ 0 ] != 0)
1079     {
1080 	fprintf ( stderr, "%s\n", ptr_buffer );
1081      }
1082 
1083     /* print message line */
1084 
1085 #ifndef NO_MESSAGE_CATALOG
1086     fprintf ( stderr, "%s%s\n",
1087 	      catgets(uil_catd, UIL_SET_MISC,
1088 		      diag_rz_msg_table[ message_number ].l_severity,
1089 		      severity_table
1090 		      [ diag_rz_msg_table[ message_number ].l_severity ]),
1091 	      msg_buffer );
1092 #else
1093     fprintf ( stderr, "%s%s\n",
1094 	      severity_table
1095 		[ diag_rz_msg_table[ message_number ].l_severity ],
1096 	      msg_buffer );
1097 #endif
1098 
1099     /* print location line */
1100 
1101     if (loc_buffer[ 0 ] != 0)
1102     {
1103 	fprintf ( stderr, "%s\n", loc_buffer );
1104      }
1105 
1106 }
1107 
1108 
1109 /*
1110 **++
1111 **  FUNCTIONAL DESCRIPTION:
1112 **
1113 **      function to return abbreviation for a message number
1114 **
1115 **  FORMAL PARAMETERS:
1116 **
1117 **      d_message_number	message number to look up
1118 **
1119 **  IMPLICIT INPUTS:
1120 **
1121 **      none
1122 **
1123 **  IMPLICIT OUTPUTS:
1124 **
1125 **      none
1126 **
1127 **  FUNCTION VALUE:
1128 **
1129 **      ptr to text for message number
1130 **
1131 **  SIDE EFFECTS:
1132 **
1133 **      none
1134 **
1135 **--
1136 **/
1137 
diag_get_message_abbrev(d_message_number)1138 char XmConst *diag_get_message_abbrev( d_message_number )
1139 
1140 int	d_message_number;
1141 
1142 {
1143     return
1144 	severity_table[ diag_rz_msg_table[ d_message_number ].l_severity ];
1145 }
1146 
1147 
1148 
1149 
1150 
1151 /*
1152 **++
1153 **  FUNCTIONAL DESCRIPTION:
1154 **
1155 **	Routine to invoke the user-supplied status callback routine.  If none
1156 **	is supplied this routine returns without error.  Otherwise, the user's
1157 **	delay information is processed and if the requested criteria is met the
1158 **	user's routine is invoked.  with parameters to describe the progress of
1159 **	the compilation.
1160 **
1161 **  FORMAL PARAMETERS:
1162 **
1163 **      none
1164 **
1165 **  IMPLICIT INPUTS:
1166 **
1167 **      Uil_cmd_z_command_line
1168 **
1169 **  IMPLICIT OUTPUTS:
1170 **
1171 **      Uil_diag_status_delay_count
1172 **
1173 **  FUNCTION VALUE:
1174 **
1175 **      none
1176 **
1177 **  SIDE EFFECTS:
1178 **
1179 **      none
1180 **
1181 **--
1182 **/
1183 
diag_report_status()1184 void	diag_report_status ( )
1185 
1186 {
1187     Uil_continue_type	return_status;
1188 
1189     /*
1190     **  If no status callback was supplied, just return.
1191     */
1192     if (Uil_cmd_z_command.status_cb == (Uil_continue_type(*)())NULL) return;
1193 
1194     /*
1195     **	If delay is used up (less than or equal to zero) then invoke the
1196     **	callback, and reset the delay count.
1197     */
1198     if (Uil_diag_status_delay_count <= 0)
1199     {
1200 	Uil_diag_status_delay_count = Uil_cmd_z_command.status_update_delay;
1201 /*
1202  * Fix for CR 5534 - restore the application signal handlers before calling
1203  *                   status_cb and then return the Uil signal handlers
1204  *                   immediately after.
1205  */
1206         diag_restore_diagnostics();
1207 	return_status = (*Uil_cmd_z_command.status_cb)(
1208 			    Uil_cmd_z_command.status_data,
1209 			    Uil_percent_complete,
1210 			    Uil_lines_processed,
1211 			    Uil_current_file,
1212 			    Uil_message_count);
1213         diag_store_handlers();
1214 /*
1215  * End Fix for CR 5534
1216  */
1217 
1218 	/*
1219 	**  If request is for termination, then longjmp back to main routine
1220 	**  and set the return status to reflect user abort.
1221 	*/
1222 	if (return_status == Uil_k_terminate)
1223 	{
1224 	    uil_exit (uil_k_error_status);
1225 	}
1226     }
1227 
1228     /*
1229     **  Delay not used-up, so decrement by one.
1230     */
1231     else
1232 	Uil_diag_status_delay_count--;
1233 
1234 }
1235 
1236 /*
1237 **++
1238 **  FUNCTIONAL DESCRIPTION:
1239 **
1240 **      This routine restores the old signal handlers that were replaced by
1241 **	Uil.  This routine is only called by the callable Uil.
1242 **
1243 **  FORMAL PARAMETERS:
1244 **
1245 **      none
1246 **
1247 **  IMPLICIT INPUTS:
1248 **
1249 **      none
1250 **
1251 **  IMPLICIT OUTPUTS:
1252 **
1253 **	none
1254 **
1255 **  FUNCTION VALUE:
1256 **
1257 **      void
1258 **
1259 **  SIDE EFFECTS:
1260 **
1261 **      error handlers for SIGBUS, SIGFPE and SIGSYS errors are restored to
1262 **	pre-Uil condition.
1263 **
1264 **--
1265 **/
1266 
1267 void
diag_restore_diagnostics(void)1268 diag_restore_diagnostics(void)
1269 {
1270 
1271 /*
1272  * Fix for CR 5534 - restore the old signal handlers
1273  */
1274     signal( SIGBUS, bus_handler );
1275 #ifdef SIGSYS
1276     signal( SIGSYS, sys_handler );
1277 #endif
1278     signal( SIGFPE, fpe_handler );
1279 /*
1280  * End Fix for CR 5534
1281  */
1282 }
1283 
1284