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