Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / osf / uil / UilLstLst.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-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 /* 
24  *  @OSF_COPYRIGHT@
25  *  COPYRIGHT NOTICE
26  *  Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
27  *  ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
28  *  the full copyright text.
29 */ 
30 /* 
31  * HISTORY
32 */ 
33 #ifdef REV_INFO
34 #ifndef lint
35 static char rcsid[] = "$TOG: UilLstLst.c /main/20 1999/07/21 09:03:16 vipin $"
36 #endif
37 #endif
38
39 /*
40 *  (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
41
42 /*
43 **++
44 **  FACILITY:
45 **
46 **      User Interface Language Compiler (UIL)
47 **
48 **  ABSTRACT:
49 **
50 **      This module contains the procedures for managing the UIL listing.
51 **
52 **--
53 **/
54
55
56 /*
57 **
58 **  INCLUDE FILES
59 **
60 **/
61
62 #include <X11/Intrinsic.h>
63 #include <Xm/Xm.h>
64
65 #include <stdarg.h>
66
67 #include "UilDefI.h"
68
69
70 /*
71 **
72 **  EXTERNAL storage used by the listing
73 **
74 */
75
76
77 /*
78 **
79 **  OWN storage used by the listing
80 **
81 */
82
83 externaldef(uil_comp_glbl) char         Uil_lst_c_title2[132];
84
85 static      int                 lst_l_usable_lines;
86 static      int                 lst_l_lines_left;
87 static      int                 lst_l_page_no;
88 static      char                lst_c_title1[132];
89 static      uil_fcb_type        *lst_az_fcb;
90 static       boolean            lst_v_listing_open = FALSE;
91
92 \f
93 /*
94 **++
95 **  FUNCTIONAL DESCRIPTION:
96 **
97 **      This function opens the UIL listing file to be written and
98 **      initializes OWN storage used by the listing package.
99 **
100 **  FORMAL PARAMETERS:
101 **
102 **      none
103 **
104 **  IMPLICIT INPUTS:
105 **
106 **      none
107 **
108 **  IMPLICIT OUTPUTS:
109 **
110 **      lst_l_usable_lines          number of usable lines per page
111 **      lst_l_lines_left            number of lines left on page
112 **      lst_l_page_no               current page number
113 **      lst_c_title1                title line 1
114 **      Uil_lst_c_title2                    title line 2
115 **      lst_v_listing_open          can the listing be written to
116 **
117 **  FUNCTION VALUE:
118 **
119 **      void
120 **
121 **  SIDE EFFECTS:
122 **
123 **      listing file is opened
124 **
125 **--
126 **/
127
128 void    lst_open_listing()
129 {
130     status  open_status;
131     _Xctimeparams       ctime_buf;
132
133     /* allocate fcb */
134
135     lst_az_fcb = (uil_fcb_type *)_get_memory( sizeof( uil_fcb_type ) );
136
137     /* open the listing file */
138
139     open_status = 
140         create_listing_file( lst_az_fcb );
141
142     if ( open_status == src_k_open_error )
143     {
144         diag_issue_diagnostic( d_listing_open,
145                                diag_k_no_source, diag_k_no_column,
146                                lst_az_fcb->expanded_name );
147         /* should never return - error is fatal */
148
149         return;
150     }
151
152     lst_l_lines_left = 0;
153     lst_l_page_no = 0;
154     lst_v_listing_open = TRUE;
155
156     sprintf(lst_c_title1, 
157             "%s %s \t%s\t\t Page ",
158             _host_compiler, _compiler_version,
159             current_time(&ctime_buf));
160
161     /*
162     **  Haven't parsed the module yet.
163     **  UilSarMod.c routines will fill it in.
164     */
165
166     Uil_lst_c_title2[ 0 ] = 0;
167
168 }
169 \f
170 /*
171 **++
172 **  FUNCTIONAL DESCRIPTION:
173 **
174 **      This function does the clean up processing for the listing facility.
175 **
176 **  FORMAL PARAMETERS:
177 **
178 **      none
179 **
180 **  IMPLICIT INPUTS:
181 **
182 **      lst_c_title1                title line 1
183 **      Uil_lst_c_title2                    title line 2
184 **      lst_v_listing_open          can the listing be written to
185 **
186 **  IMPLICIT OUTPUTS:
187 **
188 **      none
189 **
190 **  FUNCTION VALUE:
191 **
192 **      void
193 **
194 **  SIDE EFFECTS:
195 **
196 **      dynamic memory is freed
197 **
198 **--
199 **/
200
201 void    Uil_lst_cleanup_listing()
202 {
203     /*
204     **  Check that there is a listing file requested and that
205     **  it is not already in error.
206     */
207
208     if (!(lst_v_listing_open && Uil_cmd_z_command.v_listing_file))
209         return;
210
211     /*
212     ** free fcb 
213     */
214
215     _free_memory((char*)lst_az_fcb);
216     lst_az_fcb = NULL;
217 }
218
219 \f
220
221
222 \f
223
224
225 /*
226 **++
227 **  FUNCTIONAL DESCRIPTION:
228 **
229 **      routine to create the listing file.
230 **
231 **  FORMAL PARAMETERS:
232 **
233 **      az_fcb              file control block for the file
234 **
235 **  IMPLICIT INPUTS:
236 **
237 **      none
238 **
239 **  IMPLICIT OUTPUTS:
240 **
241 **      none
242 **
243 **  FUNCTION VALUE:
244 **
245 **      src_k_open_normal
246 **      src_k_open_error
247 **
248 **  SIDE EFFECTS:
249 **
250 **      file is created
251 **
252 **--
253 **/
254
255 status  create_listing_file( az_fcb )
256
257 uil_fcb_type                    *az_fcb;
258
259 {
260     /* place the file name in the expanded_name buffer */
261
262     strcpy(az_fcb->expanded_name, Uil_cmd_z_command.ac_listing_file);
263
264     /* open the file */
265
266     az_fcb->az_file_ptr = fopen(Uil_cmd_z_command.ac_listing_file, "w");
267
268     if (az_fcb->az_file_ptr == NULL)
269         return src_k_open_error;
270
271     /* assume 66 lines on a page */
272
273     lst_l_usable_lines = 66 - 9;
274
275     return src_k_open_normal;
276 }
277
278 \f
279 /*
280 **++
281 **  FUNCTIONAL DESCRIPTION:
282 **
283 **      function to write a line to the listing file.
284 **
285 **  FORMAL PARAMETERS:
286 **
287 **      ac_line         text of the line to output
288 **
289 **  IMPLICIT INPUTS:
290 **
291 **      lst_l_lines_left
292 **      lst_l_usable_lines
293 **      lst_az_fcb
294 **      lst_c_title1
295 **      lst_c_title1
296 **
297 **  IMPLICIT OUTPUTS:
298 **
299 **      lst_l_lines_left
300 **
301 **  FUNCTION VALUE:
302 **
303 **      void
304 **
305 **  SIDE EFFECTS:
306 **
307 **      line output to file
308 **
309 **--
310 **/
311
312
313 void    lst_output_line( ac_line, v_new_page )
314
315 char    *ac_line;
316 boolean v_new_page;
317
318 {
319     status      error_status;
320
321     if (!lst_v_listing_open)
322         return;
323
324     /*
325     **  Update the current file and call the Status callback routine to report
326     **  our progress.
327     */
328     Uil_current_file = lst_az_fcb->expanded_name;
329     if (Uil_cmd_z_command.status_cb != (Uil_continue_type(*)())NULL)
330         diag_report_status();    
331
332
333     if ((lst_l_lines_left <= 0) || v_new_page)
334     {
335         lst_l_page_no ++;
336         lst_l_lines_left = lst_l_usable_lines;
337
338         fprintf(lst_az_fcb->az_file_ptr, 
339                 "\f\n%s%d\n%s\n\n", 
340                 lst_c_title1, lst_l_page_no, Uil_lst_c_title2);
341     }
342
343     error_status = fprintf(lst_az_fcb->az_file_ptr, "%s\n", ac_line);
344
345     if (error_status == EOF)
346     {
347         lst_v_listing_open = FALSE;
348         diag_issue_diagnostic( d_listing_write,
349                                diag_k_no_source, diag_k_no_column,
350                                lst_az_fcb->expanded_name );
351     }
352
353     lst_l_lines_left --;
354
355     return;
356 }
357
358 \f
359 /*
360 **++
361 **  FUNCTIONAL DESCRIPTION:
362 **
363 **     function to return ASCII date and time
364 **
365 **  FORMAL PARAMETERS:
366 **
367 **      void
368 **
369 **  IMPLICIT INPUTS:
370 **
371 **      void
372 **
373 **  IMPLICIT OUTPUTS:
374 **
375 **      void
376 **
377 **  FUNCTION VALUE:
378 **
379 **      pointer to a null terminated string
380 **
381 **  SIDE EFFECTS:
382 **
383 **      none
384 **
385 **--
386 **/
387
388 char    *current_time(_Xctimeparams *ctime_buf)
389 {
390     time_t      time_location;
391     char        *ascii_time;
392
393     time_location = time( 0 );
394
395     ascii_time = _XCtime( &time_location, *ctime_buf );
396
397     ascii_time[24] = 0;
398
399     return ascii_time;
400 }
401
402 \f
403 /*
404 **++
405 **  FUNCTIONAL DESCRIPTION:
406 **
407 **      This function outputs the UIL listing file
408 **
409 **  FORMAL PARAMETERS:
410 **
411 **
412 **  IMPLICIT INPUTS:
413 **
414 **
415 **  IMPLICIT OUTPUTS:
416 **
417 **
418 **  SIDE EFFECTS:
419 **
420 **
421 **--
422 **/
423
424 void    lst_output_listing()
425
426 {
427     src_source_record_type  *az_src_rec;
428     char                    src_buffer[ src_k_max_source_line_length+12 ];
429     char                    *src_ptr;
430     int                     i;
431
432     /*
433     **  Check that there is a listing file requested and that
434     **  it is not already in error.
435     */
436
437     if (!(lst_v_listing_open &&
438           Uil_cmd_z_command.v_listing_file)
439        )
440         return;
441
442     /*
443     **  Walk the list of source records.
444     */
445
446     for (az_src_rec = src_az_first_source_record;  
447          az_src_rec != NULL;  
448          az_src_rec = az_src_rec->az_next_source_record)
449     {
450
451         /*
452         **  place the line and file number in the output buffer
453         */
454
455         sprintf(src_buffer, "%5d (%d)\t", 
456                 az_src_rec->w_line_number, 
457                 az_src_rec->b_file_number);
458
459         src_ptr = &(src_buffer[ strlen( src_buffer ) ]);
460         
461         src_retrieve_source( az_src_rec, src_ptr );
462
463         /*
464         **  filter standard unprintable characters if necessary
465         */
466
467         if ( az_src_rec->b_flags & src_m_unprintable_chars)
468             lex_filter_unprintable_chars( (unsigned char*)src_ptr, strlen( src_ptr ), 0 );
469
470         /*
471         **  replace leading formfeed with a blank
472         */
473
474         if ( az_src_rec->b_flags & src_m_form_feed)
475             *src_ptr = ' ';
476
477         lst_output_line( src_buffer, 
478                          (az_src_rec->b_flags & src_m_form_feed) != 0 );
479
480         /*
481         **  if the line has messages, get them displayed
482         */
483
484         if (az_src_rec->az_message_list != NULL)
485         {
486             lst_output_message_ptr_line( az_src_rec, src_ptr );
487             lst_output_messages( az_src_rec->az_message_list );
488         }
489
490         /*
491         **  if the line has machine code, get it displayed if requested
492         */
493
494         if ( (Uil_cmd_z_command.v_show_machine_code) &&
495              (az_src_rec->w_machine_code_cnt > 0) )
496         {
497             lst_output_machine_code( az_src_rec );
498         }
499
500     }
501
502     /*
503     **  output the orphan messages
504     */
505
506     if (src_az_orphan_messages != NULL)
507         lst_output_messages( src_az_orphan_messages );
508
509     /*
510     **  output the file summary
511     */
512
513     lst_output_line( " ", FALSE );
514
515     for (i = 0; i <= src_l_last_source_file_number; i++) {
516
517         uil_fcb_type    *az_fcb;            /* file control block ptr */
518         char            buffer [132];
519
520         az_fcb = src_az_source_file_table [i];
521         sprintf (buffer,
522                  "     File (%d)   %s",
523                  i, az_fcb->expanded_name );
524         lst_output_line( buffer, FALSE );
525     }    
526
527     lst_output_line( " ", FALSE );
528
529     return;
530 }
531 \f
532 /*
533 **++
534 **  FUNCTIONAL DESCRIPTION:
535 **
536 **      This function outputs a list of messages to the UIL listing file
537 **
538 **  FORMAL PARAMETERS:
539 **
540 **      az_message_item     ptr to start of the message list
541 **
542 **  IMPLICIT INPUTS:
543 **
544 **
545 **  IMPLICIT OUTPUTS:
546 **
547 **      none
548 **
549 **  FUNCTION VALUE:
550 **
551 **      void
552 **
553 **  SIDE EFFECTS:
554 **
555 **      messages are written to the listing file
556 **
557 **--
558 **/
559
560 void    lst_output_messages( az_message_item )
561
562 src_message_item_type   *az_message_item;
563
564 {
565     src_message_item_type       *az_msg;
566     char                        buffer[132];
567     int                         msg_no;
568     int                         last_pos;
569     int                         current_pos;
570
571     last_pos = -1;
572     msg_no = 9;
573
574     for (az_msg = az_message_item;  
575          az_msg != NULL;  
576          az_msg = az_msg->az_next_message)
577     {
578         current_pos = az_msg->b_source_pos;
579
580         if (last_pos < current_pos)
581         {
582             last_pos = current_pos;
583             if (last_pos == diag_k_no_column)
584                 msg_no = 0;
585             else
586                 msg_no = (msg_no % 9) + 1;
587         }
588
589
590         sprintf(buffer, "%s (%d) %s", 
591                 diag_get_message_abbrev( az_msg->l_message_number ),
592                 msg_no, 
593                 az_msg->c_text);
594
595         lst_output_line( buffer, FALSE );
596     }    
597
598     lst_output_line( " ", FALSE );
599
600     return;
601 }
602 \f
603 /*
604 **++
605 **  FUNCTIONAL DESCRIPTION:
606 **
607 **      This function outputs a list of machine code items to the
608 **      UIL listing file
609 **
610 **  FORMAL PARAMETERS:
611 **
612 **      az_src_rec          ptr to a source record
613 **
614 **  IMPLICIT INPUTS:
615 **
616 **
617 **  IMPLICIT OUTPUTS:
618 **
619 **      none
620 **
621 **  FUNCTION VALUE:
622 **
623 **      void
624 **
625 **  SIDE EFFECTS:
626 **
627 **      machine code is written to the listing file
628 **
629 **--
630 **/
631
632 void    lst_output_machine_code ( az_src_rec )
633
634 src_source_record_type  *az_src_rec;
635
636 {
637
638     static      src_machine_code_type * * mc_array = NULL;
639     static      unsigned short mc_cnt = 0;
640
641     src_machine_code_type       *az_code;
642     int                         code_cnt, mc_i;
643
644 /*      Go through the machine code list, and save the entries in
645         the array; traverse them in reverse order.  Reuse the vector
646         if it is large enough.  */
647
648
649
650     code_cnt = az_src_rec->w_machine_code_cnt;
651
652     if ((int)mc_cnt < code_cnt) {
653         if (mc_array != NULL) {
654             _free_memory ((char*)mc_array);
655         }
656         mc_array = 
657             (src_machine_code_type * *)_get_memory (sizeof (char *) * code_cnt);
658         mc_cnt = code_cnt;
659     }
660
661     for (az_code = az_src_rec->az_machine_code_list, mc_i = 0;
662          az_code != NULL;  
663          az_code = az_code->az_next_machine_code, mc_i++) {
664         mc_array [mc_i] = az_code;
665     }
666    
667     for (mc_i = code_cnt - 1; mc_i >= 0; mc_i--)
668     {
669
670 #define BIT_64_LONG   ((sizeof(long)*8)==64)
671
672 #define         OFFSET_COL      (BIT_64_LONG ? 75 : 43) /*should be 75 on 64 bit mach, 43 on 32*/
673 #define         TEXT_COL        (BIT_64_LONG ? 82 : 50) /*82 on 64 bit mach, 50 on 32*/
674 #define         BUF_LEN         (BIT_64_LONG ? 164 : 132) /*164 on 64 bit mach. 132 on 32 bit mach.*/
675 #define         HEX_PER_WORD    4
676 #define         HEX_PER_LONG    (BIT_64_LONG ? 16 : 8) /*should be 16 on 64 bit mach., 8 on 32 bit mach*/
677
678 #define         LONG_PER_LINE   4
679 #define         ASCII_PER_LINE  (LONG_PER_LINE * sizeof (long))
680
681         unsigned short  long_cnt, extra_byte_cnt, text_len, code_len,
682                         line_cnt, extra_long_cnt, i, j, code_offset;
683         unsigned char   buffer[ BUF_LEN + 1 ], * text_ptr,
684                         hex_longword [HEX_PER_LONG + 1], line_written;
685         unsigned long   * code_ptr;
686
687         unsigned long temp_long;
688         static unsigned short start_hex_long [4];
689         /*if 64-bit environment, it should have vals { 55, 38, 21, 4 };
690           if 32 bit environment, { 31, 22, 13, 4 };
691         */
692         start_hex_long[0]=(BIT_64_LONG ? 55 : 31);
693         start_hex_long[1]=(BIT_64_LONG ? 38 : 22);
694         start_hex_long[2]=(BIT_64_LONG ? 21 : 13);
695         start_hex_long[3]=4;
696
697
698         az_code = mc_array [mc_i];
699
700         code_ptr = (unsigned long *)az_code -> data.c_data;
701         code_len = az_code -> w_code_len;
702         code_offset = az_code -> w_offset;
703         text_ptr = (unsigned char *)(& az_code -> data.c_data [code_len]);
704         text_len = strlen ((char *)text_ptr);
705         if (text_len > (unsigned short) (BUF_LEN - TEXT_COL + 1))
706             text_len = BUF_LEN - TEXT_COL + 1;
707
708         long_cnt = code_len / sizeof (char *);
709         line_cnt = long_cnt / LONG_PER_LINE;
710         extra_long_cnt = long_cnt % LONG_PER_LINE;
711         extra_byte_cnt = code_len % sizeof (char *);
712
713         _fill (buffer, ' ', sizeof buffer - 1);
714
715
716         sprintf ((char *)hex_longword, "%04X", code_offset);
717         _move  (& buffer [OFFSET_COL - 1], hex_longword, HEX_PER_WORD);
718
719         _move (& buffer [TEXT_COL - 1], text_ptr, text_len);
720         buffer [TEXT_COL + text_len] = '\0';
721
722         line_written = FALSE;
723
724 /*
725 **      Write out entire lines.  Clear the text after the first line.
726 **      Filter all non-printable characters.
727 */
728
729         for (i = 0; i < line_cnt; i++) {
730
731             if (text_len == 0) {
732                 _move  (& buffer [TEXT_COL - 1], code_ptr, ASCII_PER_LINE);
733                 lex_filter_unprintable_chars ((unsigned char*)
734                         & buffer [TEXT_COL - 1], ASCII_PER_LINE,
735                         lex_m_filter_tab );
736                 buffer [TEXT_COL - 1 + ASCII_PER_LINE] = '\0';
737             }
738
739             for (j = 0; j < LONG_PER_LINE; j++, code_ptr++) {
740
741
742               if (BIT_64_LONG){
743
744                 sprintf ((char *)hex_longword, "%lX", (* code_ptr));
745               }
746               else{
747                 sprintf ((char *)hex_longword, "%08X", (* code_ptr));
748               }
749
750                 _move (& buffer [start_hex_long [j]],
751                         hex_longword, HEX_PER_LONG);
752
753             }
754
755
756             lst_output_line((char*) buffer, FALSE );
757             line_written = TRUE;
758
759             code_offset += LONG_PER_LINE * sizeof (long);
760             sprintf ((char *)hex_longword, "%04X", code_offset);
761             _move  (& buffer [OFFSET_COL - 1], hex_longword, HEX_PER_WORD);
762
763             if (i == 0 && text_len > 0) {
764                 _fill (& buffer [TEXT_COL - 1], ' ', text_len);
765             }
766         }
767
768 /*      Write out a partial line.       */
769
770         if (extra_long_cnt > 0 || extra_byte_cnt > 0) {
771
772             if (text_len == 0) {
773                 int     ascii_cnt;
774
775                 ascii_cnt = (extra_long_cnt * sizeof (long)) + extra_byte_cnt;
776                 _move  (& buffer [TEXT_COL - 1], code_ptr, ascii_cnt);
777                 lex_filter_unprintable_chars ((unsigned char*)
778                         & buffer [TEXT_COL - 1], ascii_cnt,
779                         lex_m_filter_tab );
780                 buffer [TEXT_COL - 1 + ascii_cnt] = '\0';
781             }
782
783 /*      Clear code from previous lines, keeping the offset and text if
784         it is there. */
785
786             _fill (buffer, ' ', OFFSET_COL - 1);
787
788             if (extra_long_cnt > 0) {
789
790 /*      Format the code longwords.      */
791
792                 for (i = 0; i < extra_long_cnt; i++, code_ptr++) {
793                     unsigned long temp_long;
794                     if (BIT_64_LONG){
795 /*                    _move( (char*) &temp_long, (char*) code_ptr, sizeof(temp_long));*/
796                       sprintf ((char *)hex_longword, "%lX", (* code_ptr));
797                     }
798                     else{
799                       sprintf ((char *)hex_longword, "%08X", (*code_ptr));
800                     }
801
802                     _move (& buffer [start_hex_long [i]],
803                         hex_longword, HEX_PER_LONG);
804                 }
805             }
806
807 /*      Format the extra code bytes.    */
808
809             if (extra_byte_cnt > 0) {
810                 int             l;
811                 unsigned char   extra_bytes [sizeof (long)];
812
813                 _move (extra_bytes, code_ptr, extra_byte_cnt);
814                 _fill (hex_longword, ' ', HEX_PER_LONG);
815                 for (l = extra_byte_cnt - 1; l >= 0; l--) {
816                 if (BIT_64_LONG)
817                     sprintf ((char *)
818                              & hex_longword [HEX_PER_LONG - (2 * (l + 1))],
819                              "%02X", extra_bytes [l]);
820                 else
821                     sprintf ((char *)
822                              & hex_longword [HEX_PER_LONG - (2 * (l + 1))],
823                              "%02X", extra_bytes [extra_byte_cnt-l-1]);
824                 
825                 }
826                 _move (& buffer [start_hex_long [extra_long_cnt]],
827                         hex_longword, HEX_PER_LONG);
828             }
829
830 /*      Output the partial line.        */
831
832             lst_output_line( (char*)buffer, FALSE );
833
834             line_written = TRUE;
835
836         }
837
838         if (! line_written) {
839             if (text_len > 0) {
840                 lst_output_line((char*) buffer, FALSE );
841             } else {
842                 lst_output_line( " ", FALSE );
843             }
844         }
845
846     }    
847
848
849
850     return;
851 }
852 \f
853 /*
854 **++
855 **  FUNCTIONAL DESCRIPTION:
856 **
857 **      This function outputs a pointer line showing the position of
858 **      diagnostics to the UIL listing file.
859 **
860 **  FORMAL PARAMETERS:
861 **
862 **      az_src_rec          ptr to a source record
863 **
864 **  IMPLICIT INPUTS:
865 **
866 **      none
867 **
868 **  IMPLICIT OUTPUTS:
869 **
870 **      none
871 **
872 **  FUNCTION VALUE:
873 **
874 **      void
875 **
876 **  SIDE EFFECTS:
877 **
878 **      message ptr line is written to the listing file
879 **
880 **--
881 **/
882
883 void    lst_output_message_ptr_line( az_src_rec, src_buffer )
884
885 src_source_record_type  *az_src_rec;
886 char                    *src_buffer;
887
888 {
889     src_message_item_type       *az_msg;
890     char                        buffer[ src_k_max_source_line_length + 3 ];
891     char                        *ptr_buffer;
892     int                         msg_no;
893     int                         pos;
894     int                         msg_pos;
895     char                        c_char;
896     boolean                     v_output_line;
897
898     if (_src_null_access_key( az_src_rec->z_access_key) )
899         return;
900
901     msg_no = 9;
902
903     buffer[ 0 ] = '\t';
904     buffer[ 1 ] = '\t';
905     ptr_buffer = &buffer[ 2 ];
906
907     az_msg = az_src_rec->az_message_list;
908     if (az_msg == NULL)
909         return;
910     msg_pos = az_msg->b_source_pos;
911     if (msg_pos == diag_k_no_column)
912         return;
913
914     v_output_line = FALSE;
915     
916     for (pos = 0;  c_char = src_buffer[ pos ], c_char != 0; )
917     {
918         if (pos < msg_pos)
919         {
920             if (c_char == '\t')
921                 ptr_buffer[ pos++ ] = '\t';
922             else
923                 ptr_buffer[ pos++ ] = ' ';
924
925             continue;
926         }
927     
928         msg_no = (msg_no % 9) + 1;
929         ptr_buffer[ pos++ ] = msg_no + '0';
930         v_output_line = TRUE;
931
932 next_message:
933         az_msg = az_msg->az_next_message;
934         if (az_msg == NULL)
935             goto finished_scan;
936         msg_pos = az_msg->b_source_pos;
937         if ((pos-1) == msg_pos)                 /* pos already advanced */
938             goto next_message;
939         if (msg_pos == diag_k_no_column)
940             goto finished_scan;
941
942     }
943
944 finished_scan:
945     ptr_buffer[ pos ] = 0;
946
947     if (v_output_line)
948         lst_output_line( buffer, FALSE );
949
950     return;
951 }
952
953 \f
954 /*
955 **++
956 **  FUNCTIONAL DESCRIPTION:
957 **
958 **      lst_debug_output sends debugging info to the listing file if
959 **      there is one; if not the output goes to standard output.
960 **
961 **  FORMAL PARAMETERS:
962 **
963 **      standard Xprintf argument list
964 **
965 **  IMPLICIT INPUTS:
966 **
967 **      lst_v_listing_open
968 **
969 **  IMPLICIT OUTPUTS:
970 **
971 **      none
972 **
973 **  FUNCTION VALUE:
974 **
975 **      void
976 **
977 **  SIDE EFFECTS:
978 **
979 **      print lines either in the listing file or to standard output
980 **
981 **--
982 **/
983
984 static  int     cur_pos=0;
985 static  char    buffer[132];
986
987 void    lst_debug_output
988
989         (char *format, ...)
990 {
991     va_list     ap;                     /* ptr to variable length parameter */
992
993     /*
994     **  establish the start of the parameter list
995     */
996
997     va_start(ap,format);
998
999     /*
1000     **  check if the listing file is open for output
1001     */
1002
1003     if (lst_v_listing_open)
1004     {
1005         int     count;
1006         char    *ptr;
1007
1008         vsprintf( &(buffer[cur_pos]), format, ap );
1009
1010         for ( ptr=buffer; ptr[0] != '\0'; ptr += (count+1) )
1011         {
1012             _assert( ptr <= &(buffer[132]), "Overflowed debug listing buffer" );
1013             count = strcspn( ptr, "\n" );
1014             if (count == strlen( ptr )) 
1015             {
1016                 cur_pos = ptr - buffer + count;
1017                 return;
1018             } 
1019             else 
1020             {
1021                 ptr[ count ] = '\0';
1022             }
1023             lst_output_line( ptr, FALSE );
1024         }
1025         cur_pos = 0;
1026
1027     }
1028     else
1029         vprintf( format, ap );
1030
1031     va_end(ap);
1032 }