* macro.c (macro_expand_body): In MRI mode, just copy a single &.
[deliverable/binutils-gdb.git] / gas / listing.c
1 /* listing.c - mainting assembly listings
2 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 /*
21 Contributed by Steve Chamberlain
22 sac@cygnus.com
23
24
25 A listing page looks like:
26
27 LISTING_HEADER sourcefilename pagenumber
28 TITLE LINE
29 SUBTITLE LINE
30 linenumber address data source
31 linenumber address data source
32 linenumber address data source
33 linenumber address data source
34
35 If not overridden, the listing commands are:
36
37 .title "stuff"
38 Put "stuff" onto the title line
39 .sbttl "stuff"
40 Put stuff onto the subtitle line
41
42 If these commands come within 10 lines of the top of the page, they
43 will affect the page they are on, as well as any subsequent page
44
45 .eject
46 Thow a page
47 .list
48 Increment the enable listing counter
49 .nolist
50 Decrement the enable listing counter
51
52 .psize Y[,X]
53 Set the paper size to X wide and Y high. Setting a psize Y of
54 zero will suppress form feeds except where demanded by .eject
55
56 If the counter goes below zero, listing is suppressed.
57
58
59 Listings are a maintained by read calling various listing_<foo>
60 functions. What happens most is that the macro NO_LISTING is not
61 defined (from the Makefile), then the macro LISTING_NEWLINE expands
62 into a call to listing_newline. The call is done from read.c, every
63 time it sees a newline, and -l is on the command line.
64
65 The function listing_newline remembers the frag associated with the
66 newline, and creates a new frag - note that this is wasteful, but not
67 a big deal, since listing slows things down a lot anyway. The
68 function also rememebers when the filename changes.
69
70 When all the input has finished, and gas has had a chance to settle
71 down, the listing is output. This is done by running down the list of
72 frag/source file records, and opening the files as needed and printing
73 out the bytes and chars associated with them.
74
75 The only things which the architecture can change about the listing
76 are defined in these macros:
77
78 LISTING_HEADER The name of the architecture
79 LISTING_WORD_SIZE The make of the number of bytes in a word, this determines
80 the clumping of the output data. eg a value of
81 2 makes words look like 1234 5678, whilst 1
82 would make the same value look like 12 34 56
83 78
84 LISTING_LHS_WIDTH Number of words of above size for the lhs
85
86 LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
87 for the second line
88
89 LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation
90 LISTING_RHS_WIDTH Number of chars from the input file to print
91 on a line
92 */
93
94 #include <ctype.h>
95
96 #include "as.h"
97 #include <obstack.h>
98 #include "input-file.h"
99 #include "subsegs.h"
100
101 #ifndef NO_LISTING
102 #ifndef LISTING_HEADER
103 #define LISTING_HEADER "GAS LISTING"
104 #endif
105 #ifndef LISTING_WORD_SIZE
106 #define LISTING_WORD_SIZE 4
107 #endif
108 #ifndef LISTING_LHS_WIDTH
109 #define LISTING_LHS_WIDTH 1
110 #endif
111 #ifndef LISTING_LHS_WIDTH_SECOND
112 #define LISTING_LHS_WIDTH_SECOND 1
113 #endif
114 #ifndef LISTING_RHS_WIDTH
115 #define LISTING_RHS_WIDTH 100
116 #endif
117 #ifndef LISTING_LHS_CONT_LINES
118 #define LISTING_LHS_CONT_LINES 4
119 #endif
120
121
122
123
124 /* This structure remembers which .s were used */
125 typedef struct file_info_struct
126 {
127 char *filename;
128 int linenum;
129 FILE *file;
130 struct file_info_struct *next;
131 int at_end;
132 }
133
134 file_info_type;
135
136
137 /* this structure rememebrs which line from which file goes into which
138 frag */
139 typedef struct list_info_struct
140 {
141 /* Frag which this line of source is nearest to */
142 fragS *frag;
143 /* The actual line in the source file */
144 unsigned int line;
145 /* Pointer to the file info struct for the file which this line
146 belongs to */
147 file_info_type *file;
148
149 /* Next in list */
150 struct list_info_struct *next;
151
152
153 /* Pointer to the file info struct for the high level language
154 source line that belongs here */
155 file_info_type *hll_file;
156
157 /* High level language source line */
158 int hll_line;
159
160
161 /* Pointer to any error message associated with this line */
162 char *message;
163
164 enum
165 {
166 EDICT_NONE,
167 EDICT_SBTTL,
168 EDICT_TITLE,
169 EDICT_NOLIST,
170 EDICT_LIST,
171 EDICT_EJECT
172 } edict;
173 char *edict_arg;
174
175 }
176
177 list_info_type;
178
179
180 static struct list_info_struct *head;
181 struct list_info_struct *listing_tail;
182 extern int listing;
183
184 static int paper_width = 200;
185 static int paper_height = 60;
186
187 /* File to output listings to. */
188 static FILE *list_file;
189
190 /* this static array is used to keep the text of data to be printed
191 before the start of the line.
192 It is stored so we can give a bit more info on the next line. To much, and large
193 initialized arrays will use up lots of paper.
194 */
195
196 static char data_buffer[100];
197 static unsigned int data_buffer_size;
198
199
200 /* Prototypes. */
201 static void listing_message PARAMS ((const char *name, const char *message));
202 static file_info_type *file_info PARAMS ((const char *file_name));
203 static void new_frag PARAMS ((void));
204 static char *buffer_line PARAMS ((file_info_type *file,
205 char *line, unsigned int size));
206 static void listing_page PARAMS ((list_info_type *list));
207 static unsigned int calc_hex PARAMS ((list_info_type *list));
208 static void print_lines PARAMS ((list_info_type *list,
209 char *string,
210 unsigned int address));
211 static void list_symbol_table PARAMS ((void));
212 static void print_source PARAMS ((file_info_type *current_file,
213 list_info_type *list,
214 char *buffer,
215 unsigned int width));
216 static int debugging_pseudo PARAMS ((char *line));
217 static void listing_listing PARAMS ((char *name));
218
219
220 static void
221 listing_message (name, message)
222 const char *name;
223 const char *message;
224 {
225 unsigned int l = strlen (name) + strlen (message) + 1;
226 char *n = (char *) xmalloc (l);
227 strcpy (n, name);
228 strcat (n, message);
229 if (listing_tail != (list_info_type *) NULL)
230 {
231 listing_tail->message = n;
232 }
233 }
234
235 void
236 listing_warning (message)
237 const char *message;
238 {
239 listing_message ("Warning:", message);
240 }
241
242 void
243 listing_error (message)
244 const char *message;
245 {
246 listing_message ("Error:", message);
247 }
248
249
250
251
252 static file_info_type *file_info_head;
253
254 static file_info_type *
255 file_info (file_name)
256 const char *file_name;
257 {
258 /* Find an entry with this file name */
259 file_info_type *p = file_info_head;
260
261 while (p != (file_info_type *) NULL)
262 {
263 if (strcmp (p->filename, file_name) == 0)
264 return p;
265 p = p->next;
266 }
267
268 /* Make new entry */
269
270 p = (file_info_type *) xmalloc (sizeof (file_info_type));
271 p->next = file_info_head;
272 file_info_head = p;
273 p->filename = xmalloc ((unsigned long) strlen (file_name) + 1);
274 strcpy (p->filename, file_name);
275 p->linenum = 0;
276 p->at_end = 0;
277
278 p->file = fopen (p->filename, "r");
279 if (p->file)
280 fgetc (p->file);
281
282 return p;
283 }
284
285
286 static void
287 new_frag ()
288 {
289
290 frag_wane (frag_now);
291 frag_new (0);
292
293 }
294
295 void
296 listing_newline (ps)
297 char *ps;
298 {
299 char *file;
300 unsigned int line;
301 static unsigned int last_line = 0xffff;
302 static char *last_file = NULL;
303 list_info_type *new;
304
305 if (listing == 0)
306 return;
307
308 if (now_seg == absolute_section)
309 return;
310
311 as_where (&file, &line);
312 if (line != last_line || (last_file && file && strcmp(file, last_file)))
313 {
314 last_line = line;
315 last_file = file;
316 new_frag ();
317
318 new = (list_info_type *) xmalloc (sizeof (list_info_type));
319 new->frag = frag_now;
320 new->line = line;
321 new->file = file_info (file);
322
323 if (listing_tail)
324 {
325 listing_tail->next = new;
326 }
327 else
328 {
329 head = new;
330 }
331 listing_tail = new;
332 new->next = (list_info_type *) NULL;
333 new->message = (char *) NULL;
334 new->edict = EDICT_NONE;
335 new->hll_file = (file_info_type *) NULL;
336 new->hll_line = 0;
337 new_frag ();
338 }
339 }
340
341 /* Attach all current frags to the previous line instead of the
342 current line. This is called by the MIPS backend when it discovers
343 that it needs to add some NOP instructions; the added NOP
344 instructions should go with the instruction that has the delay, not
345 with the new instruction. */
346
347 void
348 listing_prev_line ()
349 {
350 list_info_type *l;
351 fragS *f;
352
353 if (head == (list_info_type *) NULL
354 || head == listing_tail)
355 return;
356
357 new_frag ();
358
359 for (l = head; l->next != listing_tail; l = l->next)
360 ;
361
362 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
363 if (f->line == listing_tail)
364 f->line = l;
365
366 listing_tail->frag = frag_now;
367 new_frag ();
368 }
369
370 /*
371 This function returns the next source line from the file supplied,
372 truncated to size. It appends a fake line to the end of each input
373 file to make
374 */
375
376 static char *
377 buffer_line (file, line, size)
378 file_info_type * file;
379 char *line;
380 unsigned int size;
381 {
382 unsigned int count = 0;
383 int c;
384
385 char *p = line;
386
387 /* If we couldn't open the file, return an empty line */
388 if (file->file == (FILE *) NULL || file->at_end)
389 {
390 return "";
391 }
392
393 if (file->linenum == 0)
394 rewind (file->file);
395
396 c = fgetc (file->file);
397
398 size -= 1; /* leave room for null */
399
400 while (c != EOF && c != '\n')
401 {
402 if (count < size)
403 *p++ = c;
404 count++;
405
406 c = fgetc (file->file);
407
408 }
409 if (c == EOF)
410 {
411 file->at_end = 1;
412 *p++ = '.';
413 *p++ = '.';
414 *p++ = '.';
415 }
416 file->linenum++;
417 *p++ = 0;
418 return line;
419 }
420
421
422 static const char *fn;
423
424 static unsigned int eject; /* Eject pending */
425 static unsigned int page; /* Current page number */
426 static char *title; /* current title */
427 static char *subtitle; /* current subtitle */
428 static unsigned int on_page; /* number of lines printed on current page */
429
430
431 static void
432 listing_page (list)
433 list_info_type *list;
434 {
435 /* Grope around, see if we can see a title or subtitle edict coming up
436 soon (we look down 10 lines of the page and see if it's there)*/
437 if ((eject || (on_page >= paper_height)) && paper_height != 0)
438 {
439 unsigned int c = 10;
440 int had_title = 0;
441 int had_subtitle = 0;
442
443 page++;
444
445 while (c != 0 && list)
446 {
447 if (list->edict == EDICT_SBTTL && !had_subtitle)
448 {
449 had_subtitle = 1;
450 subtitle = list->edict_arg;
451 }
452 if (list->edict == EDICT_TITLE && !had_title)
453 {
454 had_title = 1;
455 title = list->edict_arg;
456 }
457 list = list->next;
458 c--;
459 }
460
461
462 if (page > 1)
463 {
464 fprintf (list_file, "\f");
465 }
466
467 fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
468 fprintf (list_file, "%s\n", title);
469 fprintf (list_file, "%s\n", subtitle);
470 on_page = 3;
471 eject = 0;
472 }
473 }
474
475
476 static unsigned int
477 calc_hex (list)
478 list_info_type * list;
479 {
480 list_info_type *first = list;
481 unsigned int address = (unsigned int) ~0;
482
483 fragS *frag;
484 fragS *frag_ptr;
485
486 unsigned int byte_in_frag;
487
488
489 /* Find first frag which says it belongs to this line */
490 frag = list->frag;
491 while (frag && frag->line != list)
492 frag = frag->fr_next;
493
494 frag_ptr = frag;
495
496 data_buffer_size = 0;
497
498 /* Dump all the frags which belong to this line */
499 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
500 {
501 /* Print as many bytes from the fixed part as is sensible */
502 byte_in_frag = 0;
503 while (byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof (data_buffer) - 10)
504 {
505 if (address == ~0)
506 {
507 address = frag_ptr->fr_address;
508 }
509
510 sprintf (data_buffer + data_buffer_size,
511 "%02X",
512 (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
513 data_buffer_size += 2;
514 byte_in_frag++;
515 }
516 {
517 unsigned int var_rep_max = byte_in_frag;
518 unsigned int var_rep_idx = byte_in_frag;
519
520 /* Print as many bytes from the variable part as is sensible */
521 while ((byte_in_frag
522 < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)
523 && data_buffer_size < sizeof (data_buffer) - 10)
524 {
525 if (address == ~0)
526 {
527 address = frag_ptr->fr_address;
528 }
529 sprintf (data_buffer + data_buffer_size,
530 "%02X",
531 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
532 #if 0
533 data_buffer[data_buffer_size++] = '*';
534 data_buffer[data_buffer_size++] = '*';
535 #endif
536 data_buffer_size += 2;
537
538 var_rep_idx++;
539 byte_in_frag++;
540
541 if (var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
542 var_rep_idx = var_rep_max;
543 }
544 }
545
546 frag_ptr = frag_ptr->fr_next;
547 }
548 data_buffer[data_buffer_size++] = 0;
549 return address;
550 }
551
552
553
554
555
556
557 static void
558 print_lines (list, string, address)
559 list_info_type *list;
560 char *string;
561 unsigned int address;
562 {
563 unsigned int idx;
564 unsigned int nchars;
565 unsigned int lines;
566 unsigned int byte_in_word = 0;
567 char *src = data_buffer;
568
569 /* Print the stuff on the first line */
570 listing_page (list);
571 nchars = (LISTING_WORD_SIZE * 2 + 1) * LISTING_LHS_WIDTH;
572 /* Print the hex for the first line */
573 if (address == ~0)
574 {
575 fprintf (list_file, "% 4d ", list->line);
576 for (idx = 0; idx < nchars; idx++)
577 fprintf (list_file, " ");
578
579 fprintf (list_file, "\t%s\n", string ? string : "");
580 on_page++;
581 listing_page (0);
582
583 }
584 else
585 {
586 if (had_errors ())
587 {
588 fprintf (list_file, "% 4d ???? ", list->line);
589 }
590 else
591 {
592 fprintf (list_file, "% 4d %04x ", list->line, address);
593 }
594
595 /* And the data to go along with it */
596 idx = 0;
597
598 while (*src && idx < nchars)
599 {
600 fprintf (list_file, "%c%c", src[0], src[1]);
601 src += 2;
602 byte_in_word++;
603 if (byte_in_word == LISTING_WORD_SIZE)
604 {
605 fprintf (list_file, " ");
606 idx++;
607 byte_in_word = 0;
608 }
609 idx += 2;
610 }
611
612 for (; idx < nchars; idx++)
613 fprintf (list_file, " ");
614
615 fprintf (list_file, "\t%s\n", string ? string : "");
616 on_page++;
617 listing_page (list);
618 if (list->message)
619 {
620 fprintf (list_file, "**** %s\n", list->message);
621 listing_page (list);
622 on_page++;
623 }
624
625 for (lines = 0;
626 lines < LISTING_LHS_CONT_LINES
627 && *src;
628 lines++)
629 {
630 nchars = ((LISTING_WORD_SIZE * 2) + 1) * LISTING_LHS_WIDTH_SECOND - 1;
631 idx = 0;
632 /* Print any more lines of data, but more compactly */
633 fprintf (list_file, "% 4d ", list->line);
634
635 while (*src && idx < nchars)
636 {
637 fprintf (list_file, "%c%c", src[0], src[1]);
638 src += 2;
639 idx += 2;
640 byte_in_word++;
641 if (byte_in_word == LISTING_WORD_SIZE)
642 {
643 fprintf (list_file, " ");
644 idx++;
645 byte_in_word = 0;
646 }
647 }
648
649 fprintf (list_file, "\n");
650 on_page++;
651 listing_page (list);
652
653 }
654
655
656 }
657 }
658
659
660 static void
661 list_symbol_table ()
662 {
663 extern symbolS *symbol_rootP;
664 int got_some = 0;
665
666 symbolS *ptr;
667 eject = 1;
668 listing_page (0);
669
670 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
671 {
672 if (ptr->sy_frag->line)
673 {
674 if (S_GET_NAME (ptr))
675 {
676 char buf[30], fmt[8];
677 valueT val = S_GET_VALUE (ptr);
678
679 /* @@ Note that this is dependent on the compilation options,
680 not solely on the target characteristics. */
681 if (sizeof (val) == 4 && sizeof (int) == 4)
682 sprintf (buf, "%08lx", (unsigned long) val);
683 else if (sizeof (val) <= sizeof (unsigned long))
684 {
685 sprintf (fmt, "%%0%lulx",
686 (unsigned long) (sizeof (val) * 2));
687 sprintf (buf, fmt, (unsigned long) val);
688 }
689 #if defined (BFD64)
690 else if (sizeof (val) > 4)
691 {
692 char buf1[30];
693 sprintf_vma (buf1, val);
694 strcpy (buf, "00000000");
695 strcpy (buf + 8 - strlen (buf1), buf1);
696 }
697 #endif
698 else
699 abort ();
700
701 if (!got_some)
702 {
703 fprintf (list_file, "DEFINED SYMBOLS\n");
704 on_page++;
705 got_some = 1;
706 }
707
708 fprintf (list_file, "%20s:%-5d %s:%s %s\n",
709 ptr->sy_frag->line->file->filename,
710 ptr->sy_frag->line->line,
711 segment_name (S_GET_SEGMENT (ptr)),
712 buf, S_GET_NAME (ptr));
713
714 on_page++;
715 listing_page (0);
716 }
717 }
718
719 }
720 if (!got_some)
721 {
722 fprintf (list_file, "NO DEFINED SYMBOLS\n");
723 on_page++;
724 }
725 fprintf (list_file, "\n");
726 on_page++;
727 listing_page (0);
728
729 got_some = 0;
730
731 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
732 {
733 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
734 {
735 if (ptr->sy_frag->line == 0
736 #ifdef S_IS_REGISTER
737 && !S_IS_REGISTER (ptr)
738 #endif
739 && S_GET_SEGMENT (ptr) != reg_section)
740 {
741 if (!got_some)
742 {
743 got_some = 1;
744 fprintf (list_file, "UNDEFINED SYMBOLS\n");
745 on_page++;
746 listing_page (0);
747 }
748 fprintf (list_file, "%s\n", S_GET_NAME (ptr));
749 on_page++;
750 listing_page (0);
751 }
752 }
753 }
754 if (!got_some)
755 {
756 fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
757 on_page++;
758 listing_page (0);
759 }
760 }
761
762 static void
763 print_source (current_file, list, buffer, width)
764 file_info_type *current_file;
765 list_info_type *list;
766 char *buffer;
767 unsigned int width;
768 {
769 if (current_file->file)
770 {
771 while (current_file->linenum < list->hll_line
772 && !current_file->at_end)
773 {
774 char *p = buffer_line (current_file, buffer, width);
775 fprintf (list_file, "%4d:%-13s **** %s\n", current_file->linenum,
776 current_file->filename, p);
777 on_page++;
778 listing_page (list);
779 }
780 }
781 }
782
783 /* Sometimes the user doesn't want to be bothered by the debugging
784 records inserted by the compiler, see if the line is suspicious */
785
786 static int
787 debugging_pseudo (line)
788 char *line;
789 {
790 while (isspace (*line))
791 line++;
792
793 if (*line != '.')
794 return 0;
795
796 line++;
797
798 if (strncmp (line, "def", 3) == 0)
799 return 1;
800 if (strncmp (line, "val", 3) == 0)
801 return 1;
802 if (strncmp (line, "scl", 3) == 0)
803 return 1;
804 if (strncmp (line, "line", 4) == 0)
805 return 1;
806 if (strncmp (line, "endef", 5) == 0)
807 return 1;
808 if (strncmp (line, "ln", 2) == 0)
809 return 1;
810 if (strncmp (line, "type", 4) == 0)
811 return 1;
812 if (strncmp (line, "size", 4) == 0)
813 return 1;
814 if (strncmp (line, "dim", 3) == 0)
815 return 1;
816 if (strncmp (line, "tag", 3) == 0)
817 return 1;
818
819 if (strncmp (line, "stabs", 5) == 0)
820 return 1;
821 if (strncmp (line, "stabn", 5) == 0)
822 return 1;
823
824 return 0;
825
826 }
827
828 static void
829 listing_listing (name)
830 char *name;
831 {
832 list_info_type *list = head;
833 file_info_type *current_hll_file = (file_info_type *) NULL;
834 char *message;
835 char *buffer;
836 char *p;
837 int show_listing = 1;
838 unsigned int width;
839
840 buffer = xmalloc (LISTING_RHS_WIDTH);
841 eject = 1;
842 list = head;
843
844 while (list != (list_info_type *) NULL && 0)
845 {
846 if (list->next)
847 list->frag = list->next->frag;
848 list = list->next;
849
850 }
851
852 list = head->next;
853
854
855 while (list)
856 {
857 width = LISTING_RHS_WIDTH > paper_width ? paper_width :
858 LISTING_RHS_WIDTH;
859
860 switch (list->edict)
861 {
862 case EDICT_LIST:
863 show_listing++;
864 break;
865 case EDICT_NOLIST:
866 show_listing--;
867 break;
868 case EDICT_EJECT:
869 break;
870 case EDICT_NONE:
871 break;
872 case EDICT_TITLE:
873 title = list->edict_arg;
874 break;
875 case EDICT_SBTTL:
876 subtitle = list->edict_arg;
877 break;
878 default:
879 abort ();
880 }
881
882 if (show_listing > 0)
883 {
884 /* Scan down the list and print all the stuff which can be done
885 with this line (or lines). */
886 message = 0;
887
888 if (list->hll_file)
889 {
890 current_hll_file = list->hll_file;
891 }
892
893 if (current_hll_file && list->hll_line && listing & LISTING_HLL)
894 {
895 print_source (current_hll_file, list, buffer, width);
896 }
897
898 while (list->file->file
899 && list->file->linenum < list->line
900 && !list->file->at_end)
901 {
902 p = buffer_line (list->file, buffer, width);
903
904 if (!((listing & LISTING_NODEBUG) && debugging_pseudo (p)))
905 {
906 print_lines (list, p, calc_hex (list));
907 }
908 }
909
910 if (list->edict == EDICT_EJECT)
911 {
912 eject = 1;
913 }
914 }
915 else
916 {
917 while (list->file->file
918 && list->file->linenum < list->line
919 && !list->file->at_end)
920 p = buffer_line (list->file, buffer, width);
921 }
922
923 list = list->next;
924 }
925 free (buffer);
926 }
927
928 void
929 listing_print (name)
930 char *name;
931 {
932 title = "";
933 subtitle = "";
934
935 if (name == NULL)
936 list_file = stdout;
937 else
938 {
939 list_file = fopen (name, "w");
940 if (list_file == NULL)
941 {
942 as_perror ("can't open list file: %s", name);
943 list_file = stdout;
944 }
945 }
946
947 if (listing & LISTING_NOFORM)
948 {
949 paper_height = 0;
950 }
951
952 if (listing & LISTING_LISTING)
953 {
954 listing_listing (name);
955
956 }
957 if (listing & LISTING_SYMBOLS)
958 {
959 list_symbol_table ();
960 }
961 }
962
963
964 void
965 listing_file (name)
966 const char *name;
967 {
968 fn = name;
969 }
970
971 void
972 listing_eject (ignore)
973 int ignore;
974 {
975 if (listing)
976 listing_tail->edict = EDICT_EJECT;
977 }
978
979 void
980 listing_flags (ignore)
981 int ignore;
982 {
983 while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
984 input_line_pointer++;
985
986 }
987
988 void
989 listing_list (on)
990 int on;
991 {
992 if (listing)
993 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
994 }
995
996
997 void
998 listing_psize (width_only)
999 int width_only;
1000 {
1001 if (! width_only)
1002 {
1003 paper_height = get_absolute_expression ();
1004
1005 if (paper_height < 0 || paper_height > 1000)
1006 {
1007 paper_height = 0;
1008 as_warn ("strange paper height, set to no form");
1009 }
1010
1011 if (*input_line_pointer != ',')
1012 {
1013 demand_empty_rest_of_line ();
1014 return;
1015 }
1016
1017 ++input_line_pointer;
1018 }
1019
1020 paper_width = get_absolute_expression ();
1021
1022 demand_empty_rest_of_line ();
1023 }
1024
1025 void
1026 listing_nopage (ignore)
1027 int ignore;
1028 {
1029 paper_height = 0;
1030 }
1031
1032 void
1033 listing_title (depth)
1034 int depth;
1035 {
1036 int quoted;
1037 char *start;
1038 char *ttl;
1039 unsigned int length;
1040
1041 SKIP_WHITESPACE ();
1042 if (*input_line_pointer != '\"')
1043 quoted = 0;
1044 else
1045 {
1046 quoted = 1;
1047 ++input_line_pointer;
1048 }
1049
1050 start = input_line_pointer;
1051
1052 while (*input_line_pointer)
1053 {
1054 if (quoted
1055 ? *input_line_pointer == '\"'
1056 : is_end_of_line[(unsigned char) *input_line_pointer])
1057 {
1058 if (listing)
1059 {
1060 length = input_line_pointer - start;
1061 ttl = xmalloc (length + 1);
1062 memcpy (ttl, start, length);
1063 ttl[length] = 0;
1064 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1065 listing_tail->edict_arg = ttl;
1066 }
1067 if (quoted)
1068 input_line_pointer++;
1069 demand_empty_rest_of_line ();
1070 return;
1071 }
1072 else if (*input_line_pointer == '\n')
1073 {
1074 as_bad ("New line in title");
1075 demand_empty_rest_of_line ();
1076 return;
1077 }
1078 else
1079 {
1080 input_line_pointer++;
1081 }
1082 }
1083 }
1084
1085
1086
1087 void
1088 listing_source_line (line)
1089 unsigned int line;
1090 {
1091 if (listing)
1092 {
1093 new_frag ();
1094 listing_tail->hll_line = line;
1095 new_frag ();
1096 }
1097 }
1098
1099 void
1100 listing_source_file (file)
1101 const char *file;
1102 {
1103 if (listing)
1104 listing_tail->hll_file = file_info (file);
1105 }
1106
1107
1108
1109 #else
1110
1111
1112 /* Dummy functions for when compiled without listing enabled */
1113
1114 void
1115 listing_flags (ignore)
1116 int ignore;
1117 {
1118 s_ignore (0);
1119 }
1120
1121 void
1122 listing_list (on)
1123 int on;
1124 {
1125 s_ignore (0);
1126 }
1127
1128 void
1129 listing_eject (ignore)
1130 int ignore;
1131 {
1132 s_ignore (0);
1133 }
1134
1135 void
1136 listing_psize (ignore)
1137 int ignore;
1138 {
1139 s_ignore (0);
1140 }
1141
1142 void
1143 listing_nopage (ignore)
1144 int ignore;
1145 {
1146 s_ignore (0);
1147 }
1148
1149 void
1150 listing_title (depth)
1151 int depth;
1152 {
1153 s_ignore (0);
1154 }
1155
1156 void
1157 listing_file (name)
1158 const char *name;
1159 {
1160
1161 }
1162
1163 void
1164 listing_newline (name)
1165 char *name;
1166 {
1167
1168 }
1169
1170 void
1171 listing_source_line (n)
1172 unsigned int n;
1173 {
1174
1175 }
1176 void
1177 listing_source_file (n)
1178 const char *n;
1179 {
1180
1181 }
1182
1183 #endif
This page took 0.07517 seconds and 4 git commands to generate.