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