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