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