Bring over lost listing bits from emc-97r1-branch.
[external/binutils.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[MAX_BYTES];
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 < sizeof (data_buffer) - 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 < sizeof (data_buffer) - 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   eject = 1;
928   list = head;
929
930   while (list != (list_info_type *) NULL && 0)
931     {
932       if (list->next)
933         list->frag = list->next->frag;
934       list = list->next;
935
936     }
937
938   list = head->next;
939
940
941   while (list)
942     {
943       width = listing_rhs_width > paper_width ? paper_width :
944         listing_rhs_width;
945
946       switch (list->edict)
947         {
948         case EDICT_LIST:
949           show_listing++;
950           break;
951         case EDICT_NOLIST:
952           show_listing--;
953           break;
954         case EDICT_NOLIST_NEXT:
955           break;
956         case EDICT_EJECT:
957           break;
958         case EDICT_NONE:
959           break;
960         case EDICT_TITLE:
961           title = list->edict_arg;
962           break;
963         case EDICT_SBTTL:
964           subtitle = list->edict_arg;
965           break;
966         default:
967           abort ();
968         }
969
970       if (show_listing > 0)
971         {
972           /* Scan down the list and print all the stuff which can be done
973              with this line (or lines).  */
974           message = 0;
975
976           if (list->hll_file)
977             {
978               current_hll_file = list->hll_file;
979             }
980
981           if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
982             {
983               print_source (current_hll_file, list, buffer, width);
984             }
985
986           if (list->line_contents)
987             {
988               if (!((listing & LISTING_NODEBUG)
989                     && debugging_pseudo (list, list->line_contents)))
990                 {
991                   print_lines (list, list->file->linenum,
992                                list->line_contents, calc_hex (list));
993                 }
994             }
995           else
996             {
997               while (list->file->linenum < list->line
998                      && !list->file->at_end)
999                 {
1000                   unsigned int address;
1001
1002                   p = buffer_line (list->file, buffer, width);
1003
1004                   if (list->file->linenum < list->line)
1005                     address = ~ (unsigned int) 0;
1006                   else
1007                     address = calc_hex (list);
1008
1009                   if (!((listing & LISTING_NODEBUG)
1010                         && debugging_pseudo (list, p)))
1011                     print_lines (list, list->file->linenum, p, address);
1012                 }
1013             }
1014
1015           if (list->edict == EDICT_EJECT)
1016             {
1017               eject = 1;
1018             }
1019         }
1020       else
1021         {
1022           while (list->file->linenum < list->line
1023                  && !list->file->at_end)
1024             p = buffer_line (list->file, buffer, width);
1025         }
1026
1027       if (list->edict == EDICT_NOLIST_NEXT)
1028         --show_listing;
1029
1030       list = list->next;
1031     }
1032   free (buffer);
1033 }
1034
1035 void
1036 listing_print (name)
1037      char *name;
1038 {
1039   int using_stdout;
1040   file_info_type *fi;
1041
1042   title = "";
1043   subtitle = "";
1044
1045   if (name == NULL)
1046     {
1047       list_file = stdout;
1048       using_stdout = 1;
1049     }
1050   else
1051     {
1052       list_file = fopen (name, "w");
1053       if (list_file != NULL)
1054         using_stdout = 0;
1055       else
1056         {
1057           as_perror ("can't open list file: %s", name);
1058           list_file = stdout;
1059           using_stdout = 1;
1060         }
1061     }
1062
1063   if (listing & LISTING_NOFORM)
1064     {
1065       paper_height = 0;
1066     }
1067
1068   if (listing & LISTING_LISTING)
1069     {
1070       listing_listing (name);
1071     }
1072
1073   if (listing & LISTING_SYMBOLS)
1074     {
1075       list_symbol_table ();
1076     }
1077
1078   if (! using_stdout)
1079     {
1080       if (fclose (list_file) == EOF)
1081         as_perror ("error closing list file: %s", name);
1082     }
1083
1084   if (last_open_file)
1085     {
1086       fclose (last_open_file);
1087     }
1088 }
1089
1090
1091 void
1092 listing_file (name)
1093      const char *name;
1094 {
1095   fn = name;
1096 }
1097
1098 void
1099 listing_eject (ignore)
1100      int ignore;
1101 {
1102   if (listing)
1103     listing_tail->edict = EDICT_EJECT;
1104 }
1105
1106 void
1107 listing_flags (ignore)
1108      int ignore;
1109 {
1110   while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
1111     input_line_pointer++;
1112
1113 }
1114
1115 /* Turn listing on or off.  An argument of 0 means to turn off
1116    listing.  An argument of 1 means to turn on listing.  An argument
1117    of 2 means to turn off listing, but as of the next line; that is,
1118    the current line should be listed, but the next line should not.  */
1119
1120 void
1121 listing_list (on)
1122      int on;
1123 {
1124   if (listing)
1125     {
1126       switch (on)
1127         {
1128         case 0:
1129           if (listing_tail->edict == EDICT_LIST)
1130             listing_tail->edict = EDICT_NONE;
1131           else
1132             listing_tail->edict = EDICT_NOLIST;
1133           break;
1134         case 1:
1135           if (listing_tail->edict == EDICT_NOLIST
1136               || listing_tail->edict == EDICT_NOLIST_NEXT)
1137             listing_tail->edict = EDICT_NONE;
1138           else
1139             listing_tail->edict = EDICT_LIST;
1140           break;
1141         case 2:
1142           listing_tail->edict = EDICT_NOLIST_NEXT;
1143           break;
1144         default:
1145           abort ();
1146         }
1147     }
1148 }
1149
1150
1151 void
1152 listing_psize (width_only)
1153      int width_only;
1154 {
1155   if (! width_only)
1156     {
1157       paper_height = get_absolute_expression ();
1158
1159       if (paper_height < 0 || paper_height > 1000)
1160         {
1161           paper_height = 0;
1162           as_warn ("strange paper height, set to no form");
1163         }
1164
1165       if (*input_line_pointer != ',')
1166         {
1167           demand_empty_rest_of_line ();
1168           return;
1169         }
1170
1171       ++input_line_pointer;
1172     }
1173
1174   paper_width = get_absolute_expression ();
1175
1176   demand_empty_rest_of_line ();
1177 }
1178
1179 void
1180 listing_nopage (ignore)
1181      int ignore;
1182 {
1183   paper_height = 0;
1184 }
1185
1186 void
1187 listing_title (depth)
1188      int depth;
1189 {
1190   int quoted;
1191   char *start;
1192   char *ttl;
1193   unsigned int length;
1194
1195   SKIP_WHITESPACE ();
1196   if (*input_line_pointer != '\"')
1197     quoted = 0;
1198   else
1199     {
1200       quoted = 1;
1201       ++input_line_pointer;
1202     }
1203
1204   start = input_line_pointer;
1205
1206   while (*input_line_pointer)
1207     {
1208       if (quoted
1209           ? *input_line_pointer == '\"'
1210           : is_end_of_line[(unsigned char) *input_line_pointer])
1211         {
1212           if (listing)
1213             {
1214               length = input_line_pointer - start;
1215               ttl = xmalloc (length + 1);
1216               memcpy (ttl, start, length);
1217               ttl[length] = 0;
1218               listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1219               listing_tail->edict_arg = ttl;
1220             }
1221           if (quoted)
1222             input_line_pointer++;
1223           demand_empty_rest_of_line ();
1224           return;
1225         }
1226       else if (*input_line_pointer == '\n')
1227         {
1228           as_bad ("New line in title");
1229           demand_empty_rest_of_line ();
1230           return;
1231         }
1232       else
1233         {
1234           input_line_pointer++;
1235         }
1236     }
1237 }
1238
1239
1240
1241 void
1242 listing_source_line (line)
1243      unsigned int line;
1244 {
1245   if (listing)
1246     {
1247       new_frag ();
1248       listing_tail->hll_line = line;
1249       new_frag ();
1250     }
1251 }
1252
1253 void
1254 listing_source_file (file)
1255      const char *file;
1256 {
1257   if (listing)
1258     listing_tail->hll_file = file_info (file);
1259 }
1260
1261
1262
1263 #else
1264
1265
1266 /* Dummy functions for when compiled without listing enabled */
1267
1268 void
1269 listing_flags (ignore)
1270      int ignore;
1271 {
1272   s_ignore (0);
1273 }
1274
1275 void 
1276 listing_list (on)
1277      int on;
1278 {
1279   s_ignore (0);
1280 }
1281
1282 void 
1283 listing_eject (ignore)
1284      int ignore;
1285 {
1286   s_ignore (0);
1287 }
1288
1289 void 
1290 listing_psize (ignore)
1291      int ignore;
1292 {
1293   s_ignore (0);
1294 }
1295
1296 void
1297 listing_nopage (ignore)
1298      int ignore;
1299 {
1300   s_ignore (0);
1301 }
1302
1303 void 
1304 listing_title (depth)
1305      int depth;
1306 {
1307   s_ignore (0);
1308 }
1309
1310 void
1311 listing_file (name)
1312      const char *name;
1313 {
1314
1315 }
1316
1317 void 
1318 listing_newline (name)
1319      char *name;
1320 {
1321
1322 }
1323
1324 void 
1325 listing_source_line (n)
1326      unsigned int n;
1327 {
1328
1329 }
1330 void 
1331 listing_source_file (n)
1332      const char *n;
1333 {
1334
1335 }
1336
1337 #endif