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