xref: /netbsd-src/external/gpl3/binutils.old/dist/gas/listing.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1 /* listing.c - maintain assembly listings
2    Copyright (C) 1991-2022 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA
19    02110-1301, USA.  */
20 
21 /* Contributed by Steve Chamberlain <sac@cygnus.com>
22 
23  A listing page looks like:
24 
25  LISTING_HEADER  sourcefilename pagenumber
26  TITLE LINE
27  SUBTITLE LINE
28  linenumber address data  source
29  linenumber address data  source
30  linenumber address data  source
31  linenumber address data  source
32 
33  If not overridden, the listing commands are:
34 
35  .title  "stuff"
36  	Put "stuff" onto the title line
37  .sbttl  "stuff"
38         Put stuff onto the subtitle line
39 
40   If these commands come within 10 lines of the top of the page, they
41   will affect the page they are on, as well as any subsequent page
42 
43  .eject
44  	Throw a page
45  .list
46  	Increment the enable listing counter
47  .nolist
48  	Decrement the enable listing counter
49 
50  .psize Y[,X]
51  	Set the paper size to X wide and Y high. Setting a psize Y of
52 	zero will suppress form feeds except where demanded by .eject
53 
54  If the counter goes below zero, listing is suppressed.
55 
56  Listings are a maintained by read calling various listing_<foo>
57  functions.  What happens most is that the macro NO_LISTING is not
58  defined (from the Makefile), then the macro LISTING_NEWLINE expands
59  into a call to listing_newline.  The call is done from read.c, every
60  time it sees a newline, and -l is on the command line.
61 
62  The function listing_newline remembers the frag associated with the
63  newline, and creates a new frag - note that this is wasteful, but not
64  a big deal, since listing slows things down a lot anyway.  The
65  function also remembers when the filename changes.
66 
67  When all the input has finished, and gas has had a chance to settle
68  down, the listing is output. This is done by running down the list of
69  frag/source file records, and opening the files as needed and printing
70  out the bytes and chars associated with them.
71 
72  The only things which the architecture can change about the listing
73  are defined in these macros:
74 
75  LISTING_HEADER		The name of the architecture
76  LISTING_WORD_SIZE      The make of the number of bytes in a word, this determines
77  			the clumping of the output data. eg a value of
78 			2 makes words look like 1234 5678, whilst 1
79 			would make the same value look like 12 34 56
80 			78
81  LISTING_LHS_WIDTH      Number of words of above size for the lhs
82 
83  LISTING_LHS_WIDTH_SECOND   Number of words for the data on the lhs
84  			for the second line
85 
86  LISTING_LHS_CONT_LINES	Max number of lines to use up for a continuation
87  LISTING_RHS_WIDTH      Number of chars from the input file to print
88                         on a line.  */
89 
90 #include "as.h"
91 #include "filenames.h"
92 #include "safe-ctype.h"
93 #include "input-file.h"
94 #include "subsegs.h"
95 #include "bfdver.h"
96 #include <time.h>
97 #include <stdarg.h>
98 
99 #ifndef NO_LISTING
100 
101 #ifndef LISTING_HEADER
102 #define LISTING_HEADER "GAS LISTING"
103 #endif
104 #ifndef LISTING_WORD_SIZE
105 #define LISTING_WORD_SIZE 4
106 #endif
107 #ifndef LISTING_LHS_WIDTH
108 #define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
109 #endif
110 #ifndef LISTING_LHS_WIDTH_SECOND
111 #define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
112 #endif
113 #ifndef LISTING_RHS_WIDTH
114 #define LISTING_RHS_WIDTH 100
115 #endif
116 #ifndef LISTING_LHS_CONT_LINES
117 #define LISTING_LHS_CONT_LINES 4
118 #endif
119 #define MAX_DATELEN 30
120 
121 /* This structure remembers which .s were used.  */
122 typedef struct file_info_struct
123 {
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 enum edict_enum
132 {
133   EDICT_NONE,
134   EDICT_SBTTL,
135   EDICT_TITLE,
136   EDICT_NOLIST,
137   EDICT_LIST,
138   EDICT_NOLIST_NEXT,
139   EDICT_EJECT
140 };
141 
142 
143 struct list_message
144 {
145   char *message;
146   struct list_message *next;
147 };
148 
149 /* This structure remembers which line from which file goes into which
150    frag.  */
151 struct list_info_struct
152 {
153   /* Frag which this line of source is nearest to.  */
154   fragS *frag;
155 
156   /* The actual line in the source file.  */
157   unsigned int line;
158 
159   /* Pointer to the file info struct for the file which this line
160      belongs to.  */
161   file_info_type *file;
162 
163   /* The expanded text of any macro that may have been executing.  */
164   char *line_contents;
165 
166   /* Next in list.  */
167   struct list_info_struct *next;
168 
169   /* Pointer to the file info struct for the high level language
170      source line that belongs here.  */
171   file_info_type *hll_file;
172 
173   /* High level language source line.  */
174   unsigned int hll_line;
175 
176   /* Pointers to linked list of messages associated with this line.  */
177   struct list_message *messages, *last_message;
178 
179   enum edict_enum edict;
180   char *edict_arg;
181 
182   /* Nonzero if this line is to be omitted because it contains
183      debugging information.  This can become a flags field if we come
184      up with more information to store here.  */
185   int debugging;
186 };
187 
188 typedef struct list_info_struct list_info_type;
189 
190 int listing_lhs_width        = LISTING_LHS_WIDTH;
191 int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
192 int listing_lhs_cont_lines   = LISTING_LHS_CONT_LINES;
193 int listing_rhs_width        = LISTING_RHS_WIDTH;
194 
195 struct list_info_struct *        listing_tail;
196 
197 static file_info_type *          file_info_head;
198 static file_info_type *          last_open_file_info;
199 static FILE *                    last_open_file;
200 static struct list_info_struct * head;
201 static int                       paper_width = 200;
202 static int                       paper_height = 60;
203 
204 extern int                       listing;
205 
206 /* File to output listings to.  */
207 static FILE *list_file;
208 
209 /* This static array is used to keep the text of data to be printed
210    before the start of the line.  */
211 
212 #define MAX_BYTES							\
213   (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width			\
214    + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second)	\
215       * listing_lhs_cont_lines)						\
216    + 20)
217 
218 static char *data_buffer;
219 
220 /* Prototypes.  */
221 static void listing_message (const char *, const char *);
222 static file_info_type *file_info (const char *);
223 static void new_frag (void);
224 static void listing_page (list_info_type *);
225 static unsigned int calc_hex (list_info_type *);
226 static void print_lines (list_info_type *, unsigned int, const char *,
227 			 unsigned int);
228 static void list_symbol_table (void);
229 static int debugging_pseudo (list_info_type *, const char *);
230 static void listing_listing (char *);
231 
232 static void
listing_message(const char * name,const char * message)233 listing_message (const char *name, const char *message)
234 {
235   if (listing_tail != (list_info_type *) NULL)
236     {
237       char *n = concat (name, message, (char *) NULL);
238       struct list_message *lm = XNEW (struct list_message);
239       lm->message = n;
240       lm->next = NULL;
241 
242       if (listing_tail->last_message)
243 	listing_tail->last_message->next = lm;
244       else
245 	listing_tail->messages = lm;
246       listing_tail->last_message = lm;
247     }
248 }
249 
250 void
listing_warning(const char * message)251 listing_warning (const char *message)
252 {
253   listing_message (_("Warning: "), message);
254 }
255 
256 void
listing_error(const char * message)257 listing_error (const char *message)
258 {
259   listing_message (_("Error: "), message);
260 }
261 
262 static file_info_type *
file_info(const char * file_name)263 file_info (const char *file_name)
264 {
265   /* Find an entry with this file name.  */
266   file_info_type *p = file_info_head;
267 
268   while (p != (file_info_type *) NULL)
269     {
270       if (filename_cmp (p->filename, file_name) == 0)
271 	return p;
272       p = p->next;
273     }
274 
275   /* Make new entry.  */
276   p = XNEW (file_info_type);
277   p->next = file_info_head;
278   file_info_head = p;
279   p->filename = xstrdup (file_name);
280   p->pos = 0;
281   p->linenum = 0;
282   p->at_end = 0;
283 
284   return p;
285 }
286 
287 static void
new_frag(void)288 new_frag (void)
289 {
290   frag_wane (frag_now);
291   frag_new (0);
292 }
293 
294 void
listing_newline(char * ps)295 listing_newline (char *ps)
296 {
297   const char *file;
298   unsigned int line;
299   static unsigned int last_line = 0xffff;
300   static const char *last_file = NULL;
301   list_info_type *new_i = NULL;
302 
303   if (listing == 0)
304     return;
305 
306   if (now_seg == absolute_section)
307     return;
308 
309 #ifdef OBJ_ELF
310   /* In ELF, anything in a section beginning with .debug or .line is
311      considered to be debugging information.  This includes the
312      statement which switches us into the debugging section, which we
313      can only set after we are already in the debugging section.  */
314   if ((listing & LISTING_NODEBUG) != 0
315       && listing_tail != NULL
316       && ! listing_tail->debugging)
317     {
318       const char *segname;
319 
320       segname = segment_name (now_seg);
321       if (startswith (segname, ".debug")
322 	  || startswith (segname, ".line"))
323 	listing_tail->debugging = 1;
324     }
325 #endif
326 
327   /* PR 21977 - use the physical file name not the logical one unless high
328      level source files are being included in the listing.  */
329   if (listing & LISTING_HLL)
330     file = as_where (&line);
331   else
332     file = as_where_physical (&line);
333 
334   if (ps == NULL)
335     {
336       if (line == last_line
337 	  && !(last_file && file && filename_cmp (file, last_file)))
338 	return;
339 
340       new_i = XNEW (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
350 	 line here (assuming of course that we actually have a line of
351 	 input to read), so that it can be displayed in the listing
352 	 that is produced at the end of the assembly.  */
353       if (strcmp (file, _("{standard input}")) == 0
354 	  && input_line_pointer != NULL)
355 	{
356 	  char *copy, *src, *dest;
357 	  int len;
358 	  int seen_quote = 0;
359 	  int seen_slash = 0;
360 
361 	  for (copy = input_line_pointer;
362 	       *copy && (seen_quote
363 			 || is_end_of_line [(unsigned char) *copy] != 1);
364 	       copy++)
365 	    {
366 	      if (seen_slash)
367 		seen_slash = 0;
368 	      else if (*copy == '\\')
369 		seen_slash = 1;
370 	      else if (*copy == '"')
371 		seen_quote = !seen_quote;
372 	    }
373 
374 	  len = copy - input_line_pointer + 1;
375 
376 	  copy = XNEWVEC (char, len);
377 
378 	  src = input_line_pointer;
379 	  dest = copy;
380 
381 	  while (--len)
382 	    {
383 	      unsigned char c = *src++;
384 
385 	      /* Omit control characters in the listing.  */
386 	      if (!ISCNTRL (c))
387 		*dest++ = c;
388 	    }
389 
390 	  *dest = 0;
391 
392 	  new_i->line_contents = copy;
393 	}
394       else
395 	new_i->line_contents = NULL;
396     }
397   else
398     {
399       new_i = XNEW (list_info_type);
400       new_i->line_contents = ps;
401     }
402 
403   last_line = line;
404   last_file = file;
405 
406   new_frag ();
407 
408   if (listing_tail)
409     listing_tail->next = new_i;
410   else
411     head = new_i;
412 
413   listing_tail = new_i;
414 
415   new_i->frag = frag_now;
416   new_i->line = line;
417   new_i->file = file_info (file);
418   new_i->next = (list_info_type *) NULL;
419   new_i->messages = NULL;
420   new_i->last_message = NULL;
421   new_i->edict = EDICT_NONE;
422   new_i->hll_file = (file_info_type *) NULL;
423   new_i->hll_line = 0;
424   new_i->debugging = 0;
425 
426   new_frag ();
427 
428 #ifdef OBJ_ELF
429   /* In ELF, anything in a section beginning with .debug or .line is
430      considered to be debugging information.  */
431   if ((listing & LISTING_NODEBUG) != 0)
432     {
433       const char *segname;
434 
435       segname = segment_name (now_seg);
436       if (startswith (segname, ".debug")
437 	  || startswith (segname, ".line"))
438 	new_i->debugging = 1;
439     }
440 #endif
441 }
442 
443 /* Attach all current frags to the previous line instead of the
444    current line.  This is called by the MIPS backend when it discovers
445    that it needs to add some NOP instructions; the added NOP
446    instructions should go with the instruction that has the delay, not
447    with the new instruction.  */
448 
449 void
listing_prev_line(void)450 listing_prev_line (void)
451 {
452   list_info_type *l;
453   fragS *f;
454 
455   if (head == (list_info_type *) NULL
456       || head == listing_tail)
457     return;
458 
459   new_frag ();
460 
461   for (l = head; l->next != listing_tail; l = l->next)
462     ;
463 
464   for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
465     if (f->line == listing_tail)
466       f->line = l;
467 
468   listing_tail->frag = frag_now;
469   new_frag ();
470 }
471 
472 /* This function returns the next source line from the file supplied,
473    truncated to size.  It appends a fake line to the end of each input
474    file to make using the returned buffer simpler.  */
475 
476 static const char *
buffer_line(file_info_type * file,char * line,unsigned int size)477 buffer_line (file_info_type *file, char *line, unsigned int size)
478 {
479   unsigned int count = 0;
480   int c;
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       /* Open the file in the binary mode so that ftell above can
497 	 return a reliable value that we can feed to fseek below.  */
498       last_open_file_info = file;
499       last_open_file = fopen (file->filename, FOPEN_RB);
500       if (last_open_file == NULL)
501 	{
502 	  file->at_end = 1;
503 	  return "";
504 	}
505 
506       /* Seek to where we were last time this file was open.  */
507       if (file->pos)
508 	fseek (last_open_file, file->pos, SEEK_SET);
509     }
510 
511   c = fgetc (last_open_file);
512 
513   while (c != EOF && c != '\n' && c != '\r')
514     {
515       if (++count < size)
516 	*p++ = c;
517       c = fgetc (last_open_file);
518     }
519 
520   /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
521      is followed by '\r', swallow that as well.  */
522   if (c == '\r' || c == '\n')
523     {
524       int next = fgetc (last_open_file);
525 
526       if ((c == '\r' && next != '\n')
527 	  || (c == '\n' && next != '\r'))
528 	ungetc (next, last_open_file);
529     }
530 
531   if (c == EOF)
532     {
533       file->at_end = 1;
534       if (count + 3 < size)
535 	{
536 	  *p++ = '.';
537 	  *p++ = '.';
538 	  *p++ = '.';
539 	}
540     }
541   file->linenum++;
542   *p++ = 0;
543   return line;
544 }
545 
546 
547 /* This function rewinds the requested file back to the line requested,
548    reads it in again into the buffer provided and then restores the file
549    back to its original location.  */
550 
551 static void
rebuffer_line(file_info_type * file,unsigned int linenum,char * buffer,unsigned int size)552 rebuffer_line (file_info_type *  file,
553 	       unsigned int      linenum,
554 	       char *            buffer,
555 	       unsigned int      size)
556 {
557   unsigned int count = 0;
558   unsigned int current_line;
559   char * p = buffer;
560   long pos;
561   long pos2;
562   int c;
563   bool found = false;
564 
565   /* Sanity checks.  */
566   if (file == NULL || buffer == NULL || size <= 1 || file->linenum <= linenum)
567     return;
568 
569   /* Check the cache and see if we last used this file.  */
570   if (last_open_file_info == NULL || file != last_open_file_info)
571     {
572       if (last_open_file)
573 	{
574 	  last_open_file_info->pos = ftell (last_open_file);
575 	  fclose (last_open_file);
576 	}
577 
578       /* Open the file in the binary mode so that ftell above can
579 	 return a reliable value that we can feed to fseek below.  */
580       last_open_file_info = file;
581       last_open_file = fopen (file->filename, FOPEN_RB);
582       if (last_open_file == NULL)
583 	{
584 	  file->at_end = 1;
585 	  return;
586 	}
587 
588       /* Seek to where we were last time this file was open.  */
589       if (file->pos)
590 	fseek (last_open_file, file->pos, SEEK_SET);
591     }
592 
593   /* Remember where we are in the current file.  */
594   pos2 = pos = ftell (last_open_file);
595   if (pos < 3)
596     return;
597   current_line = file->linenum;
598 
599   /* Leave room for the nul at the end of the buffer.  */
600   size -= 1;
601   buffer[size] = 0;
602 
603   /* Increment the current line count by one.
604      This is to allow for the fact that we are searching for the
605      start of a previous line, but we do this by detecting end-of-line
606      character(s) not start-of-line characters.  */
607   ++ current_line;
608 
609   while (pos2 > 0 && ! found)
610     {
611       char * ptr;
612 
613       /* Move backwards through the file, looking for earlier lines.  */
614       pos2 = (long) size > pos2 ? 0 : pos2 - size;
615       fseek (last_open_file, pos2, SEEK_SET);
616 
617       /* Our caller has kindly provided us with a buffer, so we use it.  */
618       if (fread (buffer, 1, size, last_open_file) != size)
619 	{
620 	  as_warn (_("unable to rebuffer file: %s\n"), file->filename);
621 	  return;
622 	}
623 
624       for (ptr = buffer + size; ptr >= buffer; -- ptr)
625 	{
626 	  if (*ptr == '\n')
627 	    {
628 	      -- current_line;
629 
630 	      if (current_line == linenum)
631 		{
632 		  /* We have found the start of the line we seek.  */
633 		  found = true;
634 
635 		  /* FIXME: We could skip the read-in-the-line code
636 		     below if we know that we already have the whole
637 		     line in the buffer.  */
638 
639 		  /* Advance pos2 to the newline character we have just located.  */
640 		  pos2 += (ptr - buffer);
641 
642 		  /* Skip the newline and, if present, the carriage return.  */
643 		  if (ptr + 1 == buffer + size)
644 		    {
645 		      ++pos2;
646 		      if (fgetc (last_open_file) == '\r')
647 			++ pos2;
648 		    }
649 		  else
650 		    pos2 += (ptr[1] == '\r' ? 2 : 1);
651 
652 		  /* Move the file pointer to this location.  */
653 		  fseek (last_open_file, pos2, SEEK_SET);
654 		  break;
655 		}
656 	    }
657 	}
658     }
659 
660   /* Read in the line.  */
661   c = fgetc (last_open_file);
662 
663   while (c != EOF && c != '\n' && c != '\r')
664     {
665       if (count < size)
666 	*p++ = c;
667       count++;
668 
669       c = fgetc (last_open_file);
670     }
671 
672   /* If '\r' is followed by '\n', swallow that.  Likewise, if '\n'
673      is followed by '\r', swallow that as well.  */
674   if (c == '\r' || c == '\n')
675     {
676       int next = fgetc (last_open_file);
677 
678       if ((c == '\r' && next != '\n')
679 	  || (c == '\n' && next != '\r'))
680 	ungetc (next, last_open_file);
681     }
682 
683   /* Terminate the line.  */
684   *p++ = 0;
685 
686   /* Reset the file position.  */
687   fseek (last_open_file, pos, SEEK_SET);
688 }
689 
690 static const char *fn;
691 static unsigned int eject;	/* Eject pending.  */
692 static unsigned int page;	/* Current page number.  */
693 static const char *title;	/* Current title.  */
694 static const char *subtitle;	/* Current subtitle.  */
695 static unsigned int on_page;	/* Number of lines printed on current page.  */
696 
697 static void
listing_page(list_info_type * list)698 listing_page (list_info_type *list)
699 {
700   /* Grope around, see if we can see a title or subtitle edict coming up
701      soon.  (we look down 10 lines of the page and see if it's there)  */
702   if ((eject || (on_page >= (unsigned int) paper_height))
703       && paper_height != 0)
704     {
705       unsigned int c = 10;
706       int had_title = 0;
707       int had_subtitle = 0;
708 
709       page++;
710 
711       while (c != 0 && list)
712 	{
713 	  if (list->edict == EDICT_SBTTL && !had_subtitle)
714 	    {
715 	      had_subtitle = 1;
716 	      subtitle = list->edict_arg;
717 	    }
718 	  if (list->edict == EDICT_TITLE && !had_title)
719 	    {
720 	      had_title = 1;
721 	      title = list->edict_arg;
722 	    }
723 	  list = list->next;
724 	  c--;
725 	}
726 
727       if (page > 1)
728 	{
729 	  fprintf (list_file, "\f");
730 	}
731 
732       fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
733       fprintf (list_file, "%s\n", title);
734       fprintf (list_file, "%s\n", subtitle);
735       on_page = 3;
736       eject = 0;
737     }
738 }
739 
740 /* Print a line into the list_file.  Update the line count
741    and if necessary start a new page.  */
742 
743 static void
emit_line(list_info_type * list,const char * format,...)744 emit_line (list_info_type * list, const char * format, ...)
745 {
746   va_list args;
747 
748   va_start (args, format);
749 
750   vfprintf (list_file, format, args);
751   on_page++;
752   listing_page (list);
753 
754   va_end (args);
755 }
756 
757 static unsigned int
calc_hex(list_info_type * list)758 calc_hex (list_info_type *list)
759 {
760   int data_buffer_size;
761   list_info_type *first = list;
762   unsigned int address = ~(unsigned int) 0;
763   fragS *frag;
764   fragS *frag_ptr;
765   unsigned int octet_in_frag;
766 
767   /* Find first frag which says it belongs to this line.  */
768   frag = list->frag;
769   while (frag && frag->line != list)
770     frag = frag->fr_next;
771 
772   frag_ptr = frag;
773 
774   data_buffer_size = 0;
775 
776   /* Dump all the frags which belong to this line.  */
777   while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
778     {
779       /* Print as many bytes from the fixed part as is sensible.  */
780       octet_in_frag = 0;
781       while (octet_in_frag < frag_ptr->fr_fix
782 	     && data_buffer_size < MAX_BYTES - 3)
783 	{
784 	  if (address == ~(unsigned int) 0)
785 	    address = frag_ptr->fr_address / OCTETS_PER_BYTE;
786 
787 	  sprintf (data_buffer + data_buffer_size,
788 		   "%02X",
789 		   (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
790 	  data_buffer_size += 2;
791 	  octet_in_frag++;
792 	}
793       if (frag_ptr->fr_type == rs_fill)
794 	{
795 	  unsigned int var_rep_max = octet_in_frag;
796 	  unsigned int var_rep_idx = octet_in_frag;
797 
798 	  /* Print as many bytes from the variable part as is sensible.  */
799 	  while ((octet_in_frag
800 		  < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)
801 		 && data_buffer_size < MAX_BYTES - 3)
802 	    {
803 	      if (address == ~(unsigned int) 0)
804 		address = frag_ptr->fr_address / OCTETS_PER_BYTE;
805 
806 	      sprintf (data_buffer + data_buffer_size,
807 		       "%02X",
808 		       (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
809 	      data_buffer_size += 2;
810 
811 	      var_rep_idx++;
812 	      octet_in_frag++;
813 
814 	      if (var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
815 		var_rep_idx = var_rep_max;
816 	    }
817 	}
818 
819       frag_ptr = frag_ptr->fr_next;
820     }
821   data_buffer[data_buffer_size] = '\0';
822   return address;
823 }
824 
825 static void
print_lines(list_info_type * list,unsigned int lineno,const char * string,unsigned int address)826 print_lines (list_info_type *list, unsigned int lineno,
827 	     const char *string, unsigned int address)
828 {
829   unsigned int idx;
830   unsigned int nchars;
831   unsigned int lines;
832   unsigned int octet_in_word = 0;
833   char *src = data_buffer;
834   int cur;
835   struct list_message *msg;
836 
837   /* Print the stuff on the first line.  */
838   listing_page (list);
839   nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
840 
841   /* Print the hex for the first line.  */
842   if (address == ~(unsigned int) 0)
843     {
844       fprintf (list_file, "% 4d     ", lineno);
845       for (idx = 0; idx < nchars; idx++)
846 	fprintf (list_file, " ");
847 
848       emit_line (NULL, "\t%s\n", string ? string : "");
849       return;
850     }
851 
852   if (had_errors ())
853     fprintf (list_file, "% 4d ???? ", lineno);
854   else
855     fprintf (list_file, "% 4d %04x ", lineno, address);
856 
857   /* And the data to go along with it.  */
858   idx = 0;
859   cur = 0;
860   while (src[cur] && idx < nchars)
861     {
862       int offset;
863       offset = cur;
864       fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
865       cur += 2;
866       octet_in_word++;
867 
868       if (octet_in_word == LISTING_WORD_SIZE)
869 	{
870 	  fprintf (list_file, " ");
871 	  idx++;
872 	  octet_in_word = 0;
873 	}
874 
875       idx += 2;
876     }
877 
878   for (; idx < nchars; idx++)
879     fprintf (list_file, " ");
880 
881   emit_line (list, "\t%s\n", string ? string : "");
882 
883   for (msg = list->messages; msg; msg = msg->next)
884     emit_line (list, "****  %s\n", msg->message);
885 
886   for (lines = 0;
887        lines < (unsigned int) listing_lhs_cont_lines
888 	 && src[cur];
889        lines++)
890     {
891       nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
892       idx = 0;
893 
894       /* Print any more lines of data, but more compactly.  */
895       fprintf (list_file, "% 4d      ", lineno);
896 
897       while (src[cur] && idx < nchars)
898 	{
899 	  int offset;
900 	  offset = cur;
901 	  fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
902 	  cur += 2;
903 	  idx += 2;
904 	  octet_in_word++;
905 
906 	  if (octet_in_word == LISTING_WORD_SIZE)
907 	    {
908 	      fprintf (list_file, " ");
909 	      idx++;
910 	      octet_in_word = 0;
911 	    }
912 	}
913 
914       emit_line (list, "\n");
915     }
916 }
917 
918 static void
list_symbol_table(void)919 list_symbol_table (void)
920 {
921   extern symbolS *symbol_rootP;
922   int got_some = 0;
923 
924   symbolS *ptr;
925   eject = 1;
926   listing_page (NULL);
927 
928   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
929     {
930       if (SEG_NORMAL (S_GET_SEGMENT (ptr))
931 	  || S_GET_SEGMENT (ptr) == absolute_section)
932 	{
933 	  /* Don't report section symbols.  They are not interesting.  */
934 	  if (symbol_section_p (ptr))
935 	    continue;
936 
937 	  if (S_GET_NAME (ptr))
938 	    {
939 	      char buf[30], fmt[8];
940 	      valueT val = S_GET_VALUE (ptr);
941 
942 	      /* @@ Note that this is dependent on the compilation options,
943 		 not solely on the target characteristics.  */
944 	      if (sizeof (val) == 4 && sizeof (int) == 4)
945 		sprintf (buf, "%08lx", (unsigned long) val);
946 	      else if (sizeof (val) <= sizeof (unsigned long))
947 		{
948 		  sprintf (fmt, "%%0%lulx",
949 			   (unsigned long) (sizeof (val) * 2));
950 		  sprintf (buf, fmt, (unsigned long) val);
951 		}
952 #if defined (BFD64)
953 	      else if (sizeof (val) > 4)
954 		sprintf_vma (buf, val);
955 #endif
956 	      else
957 		abort ();
958 
959 	      if (!got_some)
960 		{
961 		  fprintf (list_file, "DEFINED SYMBOLS\n");
962 		  on_page++;
963 		  got_some = 1;
964 		}
965 
966 	      if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
967 		{
968 		  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
969 			   symbol_get_frag (ptr)->line->file->filename,
970 			   symbol_get_frag (ptr)->line->line,
971 			   segment_name (S_GET_SEGMENT (ptr)),
972 			   buf, S_GET_NAME (ptr));
973 		}
974 	      else
975 		{
976 		  fprintf (list_file, "%33s:%s %s\n",
977 			   segment_name (S_GET_SEGMENT (ptr)),
978 			   buf, S_GET_NAME (ptr));
979 		}
980 
981 	      on_page++;
982 	      listing_page (NULL);
983 	    }
984 	}
985 
986     }
987   if (!got_some)
988     {
989       fprintf (list_file, "NO DEFINED SYMBOLS\n");
990       on_page++;
991     }
992   emit_line (NULL, "\n");
993 
994   got_some = 0;
995 
996   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
997     {
998       if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
999 	{
1000 	  if (S_GET_SEGMENT (ptr) == undefined_section)
1001 	    {
1002 	      if (!got_some)
1003 		{
1004 		  got_some = 1;
1005 
1006 		  emit_line (NULL, "UNDEFINED SYMBOLS\n");
1007 		}
1008 
1009 	      emit_line (NULL, "%s\n", S_GET_NAME (ptr));
1010 	    }
1011 	}
1012     }
1013 
1014   if (!got_some)
1015     emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
1016 }
1017 
1018 typedef struct cached_line
1019 {
1020   file_info_type * file;
1021   unsigned int     line;
1022   char             buffer [LISTING_RHS_WIDTH];
1023 } cached_line;
1024 
1025 static void
print_source(file_info_type * current_file,list_info_type * list,unsigned int width)1026 print_source (file_info_type *  current_file,
1027 	      list_info_type *  list,
1028 	      unsigned int      width)
1029 {
1030 #define NUM_CACHE_LINES  3
1031   static cached_line cached_lines[NUM_CACHE_LINES];
1032   static int next_free_line = 0;
1033   cached_line * cache = NULL;
1034 
1035   if (current_file->linenum > list->hll_line
1036       && list->hll_line > 0)
1037     {
1038       /* This can happen with modern optimizing compilers.  The source
1039 	 lines from the high level language input program are split up
1040 	 and interleaved, meaning the line number we want to display
1041 	 (list->hll_line) can have already been displayed.  We have
1042 	 three choices:
1043 
1044 	   a. Do nothing, since we have already displayed the source
1045 	      line.  This was the old behaviour.
1046 
1047 	   b. Display the particular line requested again, but only
1048 	      that line.  This is the new behaviour.
1049 
1050 	   c. Display the particular line requested again and reset
1051 	      the current_file->line_num value so that we redisplay
1052 	      all the following lines as well the next time we
1053 	      encounter a larger line number.  */
1054       int i;
1055 
1056       /* Check the cache, maybe we already have the line saved.  */
1057       for (i = 0; i < NUM_CACHE_LINES; i++)
1058 	if (cached_lines[i].file == current_file
1059 	    && cached_lines[i].line == list->hll_line)
1060 	  {
1061 	    cache = cached_lines + i;
1062 	    break;
1063 	  }
1064 
1065       if (i == NUM_CACHE_LINES)
1066 	{
1067 	  cache = cached_lines + next_free_line;
1068 	  next_free_line ++;
1069 	  if (next_free_line == NUM_CACHE_LINES)
1070 	    next_free_line = 0;
1071 
1072 	  cache->file = current_file;
1073 	  cache->line = list->hll_line;
1074 	  cache->buffer[0] = 0;
1075 	  rebuffer_line (current_file, cache->line, cache->buffer, width);
1076 	}
1077 
1078       emit_line (list, "%4u:%-13s **** %s\n",
1079 		 cache->line, cache->file->filename, cache->buffer);
1080       return;
1081     }
1082 
1083   if (!current_file->at_end)
1084     {
1085       int num_lines_shown = 0;
1086 
1087       while (current_file->linenum < list->hll_line
1088 	     && !current_file->at_end)
1089 	{
1090 	  const char *p;
1091 
1092 	  cache = cached_lines + next_free_line;
1093 	  cache->file = current_file;
1094 	  cache->line = current_file->linenum + 1;
1095 	  cache->buffer[0] = 0;
1096 	  p = buffer_line (current_file, cache->buffer, width);
1097 
1098 	  /* Cache optimization:  If printing a group of lines
1099 	     cache the first and last lines in the group.  */
1100 	  if (num_lines_shown == 0)
1101 	    {
1102 	      next_free_line ++;
1103 	      if (next_free_line == NUM_CACHE_LINES)
1104 		next_free_line = 0;
1105 	    }
1106 
1107 	  emit_line (list, "%4u:%-13s **** %s\n",
1108 		     cache->line, cache->file->filename, p);
1109 	  num_lines_shown ++;
1110 	}
1111     }
1112 }
1113 
1114 /* Sometimes the user doesn't want to be bothered by the debugging
1115    records inserted by the compiler, see if the line is suspicious.  */
1116 
1117 static int
debugging_pseudo(list_info_type * list,const char * line)1118 debugging_pseudo (list_info_type *list, const char *line)
1119 {
1120 #ifdef OBJ_ELF
1121   static int in_debug;
1122   int was_debug;
1123 #endif
1124 
1125   if (list->debugging)
1126     {
1127 #ifdef OBJ_ELF
1128       in_debug = 1;
1129 #endif
1130       return 1;
1131     }
1132 #ifdef OBJ_ELF
1133   was_debug = in_debug;
1134   in_debug = 0;
1135 #endif
1136 
1137   while (ISSPACE (*line))
1138     line++;
1139 
1140   if (*line != '.')
1141     {
1142 #ifdef OBJ_ELF
1143       /* The ELF compiler sometimes emits blank lines after switching
1144          out of a debugging section.  If the next line drops us back
1145          into debugging information, then don't print the blank line.
1146          This is a hack for a particular compiler behaviour, not a
1147          general case.  */
1148       if (was_debug
1149 	  && *line == '\0'
1150 	  && list->next != NULL
1151 	  && list->next->debugging)
1152 	{
1153 	  in_debug = 1;
1154 	  return 1;
1155 	}
1156 #endif
1157 
1158       return 0;
1159     }
1160 
1161   line++;
1162 
1163   if (startswith (line, "def"))
1164     return 1;
1165   if (startswith (line, "val"))
1166     return 1;
1167   if (startswith (line, "scl"))
1168     return 1;
1169   if (startswith (line, "line"))
1170     return 1;
1171   if (startswith (line, "endef"))
1172     return 1;
1173   if (startswith (line, "ln"))
1174     return 1;
1175   if (startswith (line, "type"))
1176     return 1;
1177   if (startswith (line, "size"))
1178     return 1;
1179   if (startswith (line, "dim"))
1180     return 1;
1181   if (startswith (line, "tag"))
1182     return 1;
1183   if (startswith (line, "stabs"))
1184     return 1;
1185   if (startswith (line, "stabn"))
1186     return 1;
1187 
1188   return 0;
1189 }
1190 
1191 static void
listing_listing(char * name ATTRIBUTE_UNUSED)1192 listing_listing (char *name ATTRIBUTE_UNUSED)
1193 {
1194   list_info_type *list = head;
1195   file_info_type *current_hll_file = (file_info_type *) NULL;
1196   char *buffer;
1197   const char *p;
1198   int show_listing = 1;
1199   unsigned int width;
1200 
1201   buffer = XNEWVEC (char, listing_rhs_width);
1202   data_buffer = XNEWVEC (char, MAX_BYTES);
1203   eject = 1;
1204   list = head->next;
1205 
1206   while (list)
1207     {
1208       unsigned int list_line;
1209 
1210       width = listing_rhs_width > paper_width ? paper_width :
1211 	listing_rhs_width;
1212 
1213       list_line = list->line;
1214       switch (list->edict)
1215 	{
1216 	case EDICT_LIST:
1217 	  /* Skip all lines up to the current.  */
1218 	  list_line--;
1219 	  break;
1220 	case EDICT_NOLIST:
1221 	  show_listing--;
1222 	  break;
1223 	case EDICT_NOLIST_NEXT:
1224 	  if (show_listing == 0)
1225 	    list_line--;
1226 	  break;
1227 	case EDICT_EJECT:
1228 	  break;
1229 	case EDICT_NONE:
1230 	  break;
1231 	case EDICT_TITLE:
1232 	  title = list->edict_arg;
1233 	  break;
1234 	case EDICT_SBTTL:
1235 	  subtitle = list->edict_arg;
1236 	  break;
1237 	default:
1238 	  abort ();
1239 	}
1240 
1241       if (show_listing <= 0)
1242 	{
1243 	  while (list->file->linenum < list_line
1244 		 && !list->file->at_end)
1245 	    p = buffer_line (list->file, buffer, width);
1246 	}
1247 
1248       if (list->edict == EDICT_LIST
1249 	  || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1250 	{
1251 	  /* Enable listing for the single line that caused the enable.  */
1252 	  list_line++;
1253 	  show_listing++;
1254 	}
1255 
1256       if (show_listing > 0)
1257 	{
1258 	  /* Scan down the list and print all the stuff which can be done
1259 	     with this line (or lines).  */
1260 	  if (list->hll_file)
1261 	    current_hll_file = list->hll_file;
1262 
1263 	  if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1264 	    print_source (current_hll_file, list, width);
1265 
1266 	  if (list->line_contents)
1267 	    {
1268 	      if (!((listing & LISTING_NODEBUG)
1269 		    && debugging_pseudo (list, list->line_contents)))
1270 		print_lines (list,
1271 			     list->file->linenum == 0 ? list->line : list->file->linenum,
1272 			     list->line_contents, calc_hex (list));
1273 
1274 	      free (list->line_contents);
1275 	      list->line_contents = NULL;
1276 	    }
1277 	  else
1278 	    {
1279 	      while (list->file->linenum < list_line
1280 		     && !list->file->at_end)
1281 		{
1282 		  unsigned int address;
1283 
1284 		  p = buffer_line (list->file, buffer, width);
1285 
1286 		  if (list->file->linenum < list_line)
1287 		    address = ~(unsigned int) 0;
1288 		  else
1289 		    address = calc_hex (list);
1290 
1291 		  if (!((listing & LISTING_NODEBUG)
1292 			&& debugging_pseudo (list, p)))
1293 		    print_lines (list, list->file->linenum, p, address);
1294 		}
1295 	    }
1296 
1297 	  if (list->edict == EDICT_EJECT)
1298 	    eject = 1;
1299 	}
1300 
1301       if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1302 	--show_listing;
1303 
1304       list = list->next;
1305     }
1306 
1307   free (buffer);
1308   free (data_buffer);
1309   data_buffer = NULL;
1310 }
1311 
1312 /* Print time stamp in ISO format:  yyyy-mm-ddThh:mm:ss.ss+/-zzzz.  */
1313 
1314 static void
print_timestamp(void)1315 print_timestamp (void)
1316 {
1317   const time_t now = time (NULL);
1318   struct tm * timestamp;
1319   char stampstr[MAX_DATELEN];
1320 
1321   /* Any portable way to obtain subsecond values???  */
1322   timestamp = localtime (&now);
1323   strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1324   fprintf (list_file, _("\n time stamp    \t: %s\n\n"), stampstr);
1325 }
1326 
1327 static void
print_single_option(char * opt,int * pos)1328 print_single_option (char * opt, int *pos)
1329 {
1330   int opt_len = strlen (opt);
1331 
1332    if ((*pos + opt_len) < paper_width)
1333      {
1334         fprintf (list_file, _("%s "), opt);
1335         *pos = *pos + opt_len;
1336      }
1337    else
1338      {
1339         fprintf (list_file, _("\n\t%s "), opt);
1340         *pos = opt_len;
1341      }
1342 }
1343 
1344 /* Print options passed to as.  */
1345 
1346 static void
print_options(char ** argv)1347 print_options (char ** argv)
1348 {
1349   const char *field_name = _("\n options passed\t: ");
1350   int pos = strlen (field_name);
1351   char **p;
1352 
1353   fputs (field_name, list_file);
1354   for (p = &argv[1]; *p != NULL; p++)
1355     if (**p == '-')
1356       {
1357         /* Ignore these.  */
1358         if (strcmp (*p, "-o") == 0)
1359           {
1360             if (p[1] != NULL)
1361               p++;
1362             continue;
1363           }
1364         if (strcmp (*p, "-v") == 0)
1365           continue;
1366 
1367         print_single_option (*p, &pos);
1368       }
1369 }
1370 
1371 /* Print a first section with basic info like file names, as version,
1372    options passed, target, and timestamp.
1373    The format of this section is as follows:
1374 
1375    AS VERSION
1376 
1377    fieldname TAB ':' fieldcontents
1378   { TAB fieldcontents-cont }  */
1379 
1380 static void
listing_general_info(char ** argv)1381 listing_general_info (char ** argv)
1382 {
1383   /* Print the stuff on the first line.  */
1384   eject = 1;
1385   listing_page (NULL);
1386 
1387   fprintf (list_file,
1388            _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1389            VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1390   print_options (argv);
1391   fprintf (list_file, _("\n input file    \t: %s"), fn);
1392   fprintf (list_file, _("\n output file   \t: %s"), out_file_name);
1393   fprintf (list_file, _("\n target        \t: %s"), TARGET_CANONICAL);
1394   print_timestamp ();
1395 }
1396 
1397 void
listing_print(char * name,char ** argv)1398 listing_print (char *name, char **argv)
1399 {
1400   int using_stdout;
1401 
1402   title = "";
1403   subtitle = "";
1404 
1405   if (name == NULL)
1406     {
1407       list_file = stdout;
1408       using_stdout = 1;
1409     }
1410   else
1411     {
1412       list_file = fopen (name, FOPEN_WT);
1413       if (list_file != NULL)
1414 	using_stdout = 0;
1415       else
1416 	{
1417 	  as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1418 	  list_file = stdout;
1419 	  using_stdout = 1;
1420 	}
1421     }
1422 
1423   if (listing & LISTING_NOFORM)
1424     paper_height = 0;
1425 
1426   if (listing & LISTING_GENERAL)
1427     listing_general_info (argv);
1428 
1429   if (listing & LISTING_LISTING)
1430     listing_listing (name);
1431 
1432   if (listing & LISTING_SYMBOLS)
1433     list_symbol_table ();
1434 
1435   if (! using_stdout)
1436     {
1437       if (fclose (list_file) == EOF)
1438 	as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1439     }
1440 
1441   if (last_open_file)
1442     fclose (last_open_file);
1443 }
1444 
1445 void
listing_file(const char * name)1446 listing_file (const char *name)
1447 {
1448   fn = name;
1449 }
1450 
1451 void
listing_eject(int ignore ATTRIBUTE_UNUSED)1452 listing_eject (int ignore ATTRIBUTE_UNUSED)
1453 {
1454   if (listing)
1455     listing_tail->edict = EDICT_EJECT;
1456 }
1457 
1458 /* Turn listing on or off.  An argument of 0 means to turn off
1459    listing.  An argument of 1 means to turn on listing.  An argument
1460    of 2 means to turn off listing, but as of the next line; that is,
1461    the current line should be listed, but the next line should not.  */
1462 
1463 void
listing_list(int on)1464 listing_list (int on)
1465 {
1466   if (listing)
1467     {
1468       switch (on)
1469 	{
1470 	case 0:
1471 	  if (listing_tail->edict == EDICT_LIST)
1472 	    listing_tail->edict = EDICT_NONE;
1473 	  else
1474 	    listing_tail->edict = EDICT_NOLIST;
1475 	  break;
1476 	case 1:
1477 	  if (listing_tail->edict == EDICT_NOLIST
1478 	      || listing_tail->edict == EDICT_NOLIST_NEXT)
1479 	    listing_tail->edict = EDICT_NONE;
1480 	  else
1481 	    listing_tail->edict = EDICT_LIST;
1482 	  break;
1483 	case 2:
1484 	  listing_tail->edict = EDICT_NOLIST_NEXT;
1485 	  break;
1486 	default:
1487 	  abort ();
1488 	}
1489     }
1490 }
1491 
1492 void
listing_psize(int width_only)1493 listing_psize (int width_only)
1494 {
1495   if (! width_only)
1496     {
1497       paper_height = get_absolute_expression ();
1498 
1499       if (paper_height < 0 || paper_height > 1000)
1500 	{
1501 	  paper_height = 0;
1502 	  as_warn (_("strange paper height, set to no form"));
1503 	}
1504 
1505       if (*input_line_pointer != ',')
1506 	{
1507 	  demand_empty_rest_of_line ();
1508 	  return;
1509 	}
1510 
1511       ++input_line_pointer;
1512     }
1513 
1514   {
1515     expressionS exp;
1516 
1517     (void) expression_and_evaluate (& exp);
1518 
1519     if (exp.X_op == O_constant)
1520       {
1521 	offsetT new_width = exp.X_add_number;
1522 
1523 	if (new_width > 7)
1524 	  paper_width = new_width;
1525 	else
1526 	  as_bad (_("new paper width is too small"));
1527       }
1528     else if (exp.X_op != O_absent)
1529       as_bad (_("bad or irreducible expression for paper width"));
1530     else
1531       as_bad (_("missing expression for paper width"));
1532   }
1533 
1534   demand_empty_rest_of_line ();
1535 }
1536 
1537 void
listing_nopage(int ignore ATTRIBUTE_UNUSED)1538 listing_nopage (int ignore ATTRIBUTE_UNUSED)
1539 {
1540   paper_height = 0;
1541 }
1542 
1543 void
listing_title(int depth)1544 listing_title (int depth)
1545 {
1546   int quoted;
1547   char *start;
1548   char *ttl;
1549   unsigned int length;
1550 
1551   SKIP_WHITESPACE ();
1552   if (*input_line_pointer != '\"')
1553     quoted = 0;
1554   else
1555     {
1556       quoted = 1;
1557       ++input_line_pointer;
1558     }
1559 
1560   start = input_line_pointer;
1561 
1562   while (*input_line_pointer)
1563     {
1564       if (quoted
1565 	  ? *input_line_pointer == '\"'
1566 	  : is_end_of_line[(unsigned char) *input_line_pointer])
1567 	{
1568 	  if (listing)
1569 	    {
1570 	      length = input_line_pointer - start;
1571 	      ttl = xmemdup0 (start, length);
1572 	      listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1573 	      listing_tail->edict_arg = ttl;
1574 	    }
1575 	  if (quoted)
1576 	    input_line_pointer++;
1577 	  demand_empty_rest_of_line ();
1578 	  return;
1579 	}
1580       else if (*input_line_pointer == '\n')
1581 	{
1582 	  as_bad (_("new line in title"));
1583 	  demand_empty_rest_of_line ();
1584 	  return;
1585 	}
1586       else
1587 	{
1588 	  input_line_pointer++;
1589 	}
1590     }
1591 }
1592 
1593 void
listing_source_line(unsigned int line)1594 listing_source_line (unsigned int line)
1595 {
1596   if (listing)
1597     {
1598       new_frag ();
1599       listing_tail->hll_line = line;
1600       new_frag ();
1601     }
1602 }
1603 
1604 void
listing_source_file(const char * file)1605 listing_source_file (const char *file)
1606 {
1607   if (listing)
1608     listing_tail->hll_file = file_info (file);
1609 }
1610 
1611 #else
1612 
1613 /* Dummy functions for when compiled without listing enabled.  */
1614 
1615 void
listing_list(int on)1616 listing_list (int on)
1617 {
1618   s_ignore (0);
1619 }
1620 
1621 void
listing_eject(int ignore)1622 listing_eject (int ignore)
1623 {
1624   s_ignore (0);
1625 }
1626 
1627 void
listing_psize(int ignore)1628 listing_psize (int ignore)
1629 {
1630   s_ignore (0);
1631 }
1632 
1633 void
listing_nopage(int ignore)1634 listing_nopage (int ignore)
1635 {
1636   s_ignore (0);
1637 }
1638 
1639 void
listing_title(int depth)1640 listing_title (int depth)
1641 {
1642   s_ignore (0);
1643 }
1644 
1645 void
listing_file(const char * name)1646 listing_file (const char *name)
1647 {
1648 }
1649 
1650 void
listing_newline(char * name)1651 listing_newline (char *name)
1652 {
1653 }
1654 
1655 void
listing_source_line(unsigned int n)1656 listing_source_line (unsigned int n)
1657 {
1658 }
1659 
1660 void
listing_source_file(const char * n)1661 listing_source_file (const char *n)
1662 {
1663 }
1664 
1665 #endif
1666