listing.c revision 38889
133965Sjdp/* listing.c - mainting assembly listings
238889Sjdp   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998
338889Sjdp   Free Software Foundation, Inc.
433965Sjdp
533965SjdpThis file is part of GAS, the GNU Assembler.
633965Sjdp
733965SjdpGAS is free software; you can redistribute it and/or modify
833965Sjdpit under the terms of the GNU General Public License as published by
933965Sjdpthe Free Software Foundation; either version 2, or (at your option)
1033965Sjdpany later version.
1133965Sjdp
1233965SjdpGAS is distributed in the hope that it will be useful,
1333965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of
1433965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965SjdpGNU General Public License for more details.
1633965Sjdp
1733965SjdpYou should have received a copy of the GNU General Public License
1833965Sjdpalong with GAS; see the file COPYING.  If not, write to the Free
1933965SjdpSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
2033965Sjdp02111-1307, USA. */
2133965Sjdp
2233965Sjdp/*
2333965Sjdp Contributed by Steve Chamberlain
2433965Sjdp 		sac@cygnus.com
2533965Sjdp
2633965Sjdp
2733965Sjdp A listing page looks like:
2833965Sjdp
2933965Sjdp LISTING_HEADER  sourcefilename pagenumber
3033965Sjdp TITLE LINE
3133965Sjdp SUBTITLE LINE
3233965Sjdp linenumber address data  source
3333965Sjdp linenumber address data  source
3433965Sjdp linenumber address data  source
3533965Sjdp linenumber address data  source
3633965Sjdp
3733965Sjdp If not overridden, the listing commands are:
3833965Sjdp
3933965Sjdp .title  "stuff"
4033965Sjdp 	Put "stuff" onto the title line
4133965Sjdp .sbttl  "stuff"
4233965Sjdp        Put stuff onto the subtitle line
4333965Sjdp
4433965Sjdp  If these commands come within 10 lines of the top of the page, they
4533965Sjdp  will affect the page they are on, as well as any subsequent page
4633965Sjdp
4733965Sjdp .eject
4833965Sjdp 	Thow a page
4933965Sjdp .list
5033965Sjdp 	Increment the enable listing counter
5133965Sjdp .nolist
5233965Sjdp 	Decrement the enable listing counter
5333965Sjdp
5433965Sjdp .psize Y[,X]
5533965Sjdp 	Set the paper size to X wide and Y high. Setting a psize Y of
5633965Sjdp	zero will suppress form feeds except where demanded by .eject
5733965Sjdp
5833965Sjdp If the counter goes below zero, listing is suppressed.
5933965Sjdp
6033965Sjdp
6133965Sjdp Listings are a maintained by read calling various listing_<foo>
6233965Sjdp functions.  What happens most is that the macro NO_LISTING is not
6333965Sjdp defined (from the Makefile), then the macro LISTING_NEWLINE expands
6433965Sjdp into a call to listing_newline.  The call is done from read.c, every
6533965Sjdp time it sees a newline, and -l is on the command line.
6633965Sjdp
6733965Sjdp The function listing_newline remembers the frag associated with the
6833965Sjdp newline, and creates a new frag - note that this is wasteful, but not
6933965Sjdp a big deal, since listing slows things down a lot anyway.  The
7033965Sjdp function also rememebers when the filename changes.
7133965Sjdp
7233965Sjdp When all the input has finished, and gas has had a chance to settle
7333965Sjdp down, the listing is output. This is done by running down the list of
7433965Sjdp frag/source file records, and opening the files as needed and printing
7533965Sjdp out the bytes and chars associated with them.
7633965Sjdp
7733965Sjdp The only things which the architecture can change about the listing
7833965Sjdp are defined in these macros:
7933965Sjdp
8033965Sjdp LISTING_HEADER		The name of the architecture
8133965Sjdp LISTING_WORD_SIZE      The make of the number of bytes in a word, this determines
8233965Sjdp 			the clumping of the output data. eg a value of
8333965Sjdp			2 makes words look like 1234 5678, whilst 1
8433965Sjdp			would make the same value look like 12 34 56
8533965Sjdp			78
8633965Sjdp LISTING_LHS_WIDTH      Number of words of above size for the lhs
8733965Sjdp
8833965Sjdp LISTING_LHS_WIDTH_SECOND   Number of words for the data on the lhs
8933965Sjdp 			for the second line
9033965Sjdp
9133965Sjdp LISTING_LHS_CONT_LINES	Max number of lines to use up for a continutation
9233965Sjdp LISTING_RHS_WIDTH      Number of chars from the input file to print
9333965Sjdp                        on a line
9433965Sjdp*/
9533965Sjdp
9633965Sjdp#include <ctype.h>
9733965Sjdp
9833965Sjdp#include "as.h"
9933965Sjdp#include <obstack.h>
10033965Sjdp#include "input-file.h"
10133965Sjdp#include "subsegs.h"
10233965Sjdp
10333965Sjdp#ifndef NO_LISTING
10438889Sjdp
10533965Sjdp#ifndef LISTING_HEADER
10633965Sjdp#define LISTING_HEADER "GAS LISTING"
10733965Sjdp#endif
10833965Sjdp#ifndef LISTING_WORD_SIZE
10933965Sjdp#define LISTING_WORD_SIZE 4
11033965Sjdp#endif
11133965Sjdp#ifndef LISTING_LHS_WIDTH
11233965Sjdp#define LISTING_LHS_WIDTH 1
11333965Sjdp#endif
11433965Sjdp#ifndef LISTING_LHS_WIDTH_SECOND
11533965Sjdp#define LISTING_LHS_WIDTH_SECOND 1
11633965Sjdp#endif
11733965Sjdp#ifndef LISTING_RHS_WIDTH
11833965Sjdp#define LISTING_RHS_WIDTH 100
11933965Sjdp#endif
12033965Sjdp#ifndef LISTING_LHS_CONT_LINES
12133965Sjdp#define LISTING_LHS_CONT_LINES 4
12233965Sjdp#endif
12333965Sjdp
12433965Sjdp/* This structure remembers which .s were used */
12533965Sjdptypedef struct file_info_struct
12633965Sjdp{
12738889Sjdp  struct file_info_struct *next;
12833965Sjdp  char *filename;
12938889Sjdp  long pos;
13038889Sjdp  unsigned int linenum;
13133965Sjdp  int at_end;
13233965Sjdp}
13333965Sjdpfile_info_type;
13433965Sjdp
13533965Sjdp
13633965Sjdp/* this structure rememebrs which line from which file goes into which
13733965Sjdp   frag */
13838889Sjdpstruct list_info_struct
13933965Sjdp{
14033965Sjdp  /* Frag which this line of source is nearest to */
14133965Sjdp  fragS *frag;
14238889Sjdp
14333965Sjdp  /* The actual line in the source file */
14433965Sjdp  unsigned int line;
14533965Sjdp  /* Pointer to the file info struct for the file which this line
14633965Sjdp     belongs to */
14733965Sjdp  file_info_type *file;
14833965Sjdp
14938889Sjdp  /* The expanded text of any macro that may have been executing.  */
15038889Sjdp  char *line_contents;
15138889Sjdp
15233965Sjdp  /* Next in list */
15333965Sjdp  struct list_info_struct *next;
15433965Sjdp
15533965Sjdp  /* Pointer to the file info struct for the high level language
15633965Sjdp     source line that belongs here */
15733965Sjdp  file_info_type *hll_file;
15833965Sjdp  /* High level language source line */
15938889Sjdp  unsigned int hll_line;
16033965Sjdp
16133965Sjdp  /* Pointer to any error message associated with this line */
16233965Sjdp  char *message;
16333965Sjdp
16433965Sjdp  enum
16533965Sjdp    {
16633965Sjdp      EDICT_NONE,
16733965Sjdp      EDICT_SBTTL,
16833965Sjdp      EDICT_TITLE,
16933965Sjdp      EDICT_NOLIST,
17033965Sjdp      EDICT_LIST,
17133965Sjdp      EDICT_NOLIST_NEXT,
17233965Sjdp      EDICT_EJECT
17333965Sjdp    } edict;
17433965Sjdp  char *edict_arg;
17533965Sjdp
17638889Sjdp  /* Nonzero if this line is to be omitted because it contains
17738889Sjdp     debugging information.  This can become a flags field if we come
17838889Sjdp     up with more information to store here.  */
17938889Sjdp  int debugging;
18038889Sjdp};
18133965Sjdp
18238889Sjdptypedef struct list_info_struct list_info_type;
18333965Sjdp
18433965Sjdpstatic struct list_info_struct *head;
18533965Sjdpstruct list_info_struct *listing_tail;
18633965Sjdpextern int listing;
18733965Sjdp
18833965Sjdpstatic int paper_width = 200;
18933965Sjdpstatic int paper_height = 60;
19033965Sjdp
19133965Sjdp/* File to output listings to.  */
19233965Sjdpstatic FILE *list_file;
19333965Sjdp
19438889Sjdp/* This static array is used to keep the text of data to be printed
19538889Sjdp   before the start of the line.  */
19633965Sjdp
19738889Sjdp#define MAX_BYTES							\
19838889Sjdp  (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width			\
19938889Sjdp   + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second)	\
20038889Sjdp      * listing_lhs_cont_lines)						\
20138889Sjdp   + 20)
20233965Sjdp
20338889Sjdpstatic char *data_buffer;
20433965Sjdp
20533965Sjdp/* Prototypes.  */
20633965Sjdpstatic void listing_message PARAMS ((const char *name, const char *message));
20733965Sjdpstatic file_info_type *file_info PARAMS ((const char *file_name));
20833965Sjdpstatic void new_frag PARAMS ((void));
20933965Sjdpstatic char *buffer_line PARAMS ((file_info_type *file,
21033965Sjdp				  char *line, unsigned int size));
21133965Sjdpstatic void listing_page PARAMS ((list_info_type *list));
21233965Sjdpstatic unsigned int calc_hex PARAMS ((list_info_type *list));
21333965Sjdpstatic void print_lines PARAMS ((list_info_type *, unsigned int,
21433965Sjdp				 char *, unsigned int));
21533965Sjdpstatic void list_symbol_table PARAMS ((void));
21633965Sjdpstatic void print_source PARAMS ((file_info_type *current_file,
21733965Sjdp				  list_info_type *list,
21833965Sjdp				  char *buffer,
21933965Sjdp				  unsigned int width));
22038889Sjdpstatic int debugging_pseudo PARAMS ((list_info_type *, const char *));
22133965Sjdpstatic void listing_listing PARAMS ((char *name));
22233965Sjdp
22333965Sjdp
22433965Sjdpstatic void
22533965Sjdplisting_message (name, message)
22633965Sjdp     const char *name;
22733965Sjdp     const char *message;
22833965Sjdp{
22933965Sjdp  unsigned int l = strlen (name) + strlen (message) + 1;
23033965Sjdp  char *n = (char *) xmalloc (l);
23133965Sjdp  strcpy (n, name);
23233965Sjdp  strcat (n, message);
23333965Sjdp  if (listing_tail != (list_info_type *) NULL)
23433965Sjdp    {
23533965Sjdp      listing_tail->message = n;
23633965Sjdp    }
23733965Sjdp}
23833965Sjdp
23933965Sjdpvoid
24033965Sjdplisting_warning (message)
24133965Sjdp     const char *message;
24233965Sjdp{
24333965Sjdp  listing_message ("Warning:", message);
24433965Sjdp}
24533965Sjdp
24633965Sjdpvoid
24733965Sjdplisting_error (message)
24833965Sjdp     const char *message;
24933965Sjdp{
25033965Sjdp  listing_message ("Error:", message);
25133965Sjdp}
25233965Sjdp
25333965Sjdp
25438889Sjdpint listing_lhs_width = LISTING_LHS_WIDTH;
25538889Sjdpint listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
25638889Sjdpint listing_lhs_cont_lines = LISTING_LHS_CONT_LINES;
25738889Sjdpint listing_rhs_width = LISTING_RHS_WIDTH;
25833965Sjdp
25933965Sjdp
26033965Sjdpstatic file_info_type *file_info_head;
26138889Sjdpstatic file_info_type *last_open_file_info;
26238889Sjdpstatic FILE *last_open_file;
26333965Sjdp
26433965Sjdpstatic file_info_type *
26533965Sjdpfile_info (file_name)
26633965Sjdp     const char *file_name;
26733965Sjdp{
26833965Sjdp  /* Find an entry with this file name */
26933965Sjdp  file_info_type *p = file_info_head;
27033965Sjdp
27133965Sjdp  while (p != (file_info_type *) NULL)
27233965Sjdp    {
27333965Sjdp      if (strcmp (p->filename, file_name) == 0)
27433965Sjdp	return p;
27533965Sjdp      p = p->next;
27633965Sjdp    }
27733965Sjdp
27833965Sjdp  /* Make new entry */
27933965Sjdp
28033965Sjdp  p = (file_info_type *) xmalloc (sizeof (file_info_type));
28133965Sjdp  p->next = file_info_head;
28233965Sjdp  file_info_head = p;
28333965Sjdp  p->filename = xmalloc ((unsigned long) strlen (file_name) + 1);
28433965Sjdp  strcpy (p->filename, file_name);
28538889Sjdp  p->pos = 0;
28633965Sjdp  p->linenum = 0;
28733965Sjdp  p->at_end = 0;
28833965Sjdp
28933965Sjdp  return p;
29033965Sjdp}
29133965Sjdp
29233965Sjdp
29333965Sjdpstatic void
29433965Sjdpnew_frag ()
29533965Sjdp{
29633965Sjdp
29733965Sjdp  frag_wane (frag_now);
29833965Sjdp  frag_new (0);
29933965Sjdp
30033965Sjdp}
30133965Sjdp
30233965Sjdpvoid
30333965Sjdplisting_newline (ps)
30433965Sjdp     char *ps;
30533965Sjdp{
30633965Sjdp  char *file;
30733965Sjdp  unsigned int line;
30833965Sjdp  static unsigned int last_line = 0xffff;
30933965Sjdp  static char *last_file = NULL;
31038889Sjdp  list_info_type *new = NULL;
31133965Sjdp
31233965Sjdp  if (listing == 0)
31333965Sjdp    return;
31433965Sjdp
31533965Sjdp  if (now_seg == absolute_section)
31633965Sjdp    return;
31733965Sjdp
31838889Sjdp#ifdef OBJ_ELF
31938889Sjdp  /* In ELF, anything in a section beginning with .debug or .line is
32038889Sjdp     considered to be debugging information.  This includes the
32138889Sjdp     statement which switches us into the debugging section, which we
32238889Sjdp     can only set after we are already in the debugging section.  */
32338889Sjdp  if ((listing & LISTING_NODEBUG) != 0
32438889Sjdp      && listing_tail != NULL
32538889Sjdp      && ! listing_tail->debugging)
32638889Sjdp    {
32738889Sjdp      const char *segname;
32838889Sjdp
32938889Sjdp      segname = segment_name (now_seg);
33038889Sjdp      if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
33138889Sjdp	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
33238889Sjdp	listing_tail->debugging = 1;
33338889Sjdp    }
33438889Sjdp#endif
33538889Sjdp
33633965Sjdp  as_where (&file, &line);
33738889Sjdp  if (ps == NULL)
33833965Sjdp    {
33938889Sjdp      if (line == last_line && !(last_file && file && strcmp(file, last_file)))
34038889Sjdp	return;
34133965Sjdp
34233965Sjdp      new = (list_info_type *) xmalloc (sizeof (list_info_type));
34338889Sjdp      new->line_contents = NULL;
34438889Sjdp    }
34538889Sjdp  else
34638889Sjdp    {
34738889Sjdp      new = (list_info_type *) xmalloc (sizeof (list_info_type));
34838889Sjdp      new->line_contents = ps;
34938889Sjdp    }
35033965Sjdp
35138889Sjdp  last_line = line;
35238889Sjdp  last_file = file;
35338889Sjdp  new_frag ();
35438889Sjdp
35538889Sjdp  if (listing_tail)
35638889Sjdp    {
35738889Sjdp      listing_tail->next = new;
35833965Sjdp    }
35938889Sjdp  else
36038889Sjdp    {
36138889Sjdp      head = new;
36238889Sjdp    }
36338889Sjdp  listing_tail = new;
36438889Sjdp
36538889Sjdp  new->frag = frag_now;
36638889Sjdp  new->line = line;
36738889Sjdp  new->file = file_info (file);
36838889Sjdp  new->next = (list_info_type *) NULL;
36938889Sjdp  new->message = (char *) NULL;
37038889Sjdp  new->edict = EDICT_NONE;
37138889Sjdp  new->hll_file = (file_info_type *) NULL;
37238889Sjdp  new->hll_line = 0;
37338889Sjdp  new->debugging = 0;
37438889Sjdp  new_frag ();
37538889Sjdp
37638889Sjdp#ifdef OBJ_ELF
37738889Sjdp  /* In ELF, anything in a section beginning with .debug or .line is
37838889Sjdp     considered to be debugging information.  */
37938889Sjdp  if ((listing & LISTING_NODEBUG) != 0)
38038889Sjdp    {
38138889Sjdp      const char *segname;
38238889Sjdp
38338889Sjdp      segname = segment_name (now_seg);
38438889Sjdp      if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
38538889Sjdp	  || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
38638889Sjdp	new->debugging = 1;
38738889Sjdp    }
38838889Sjdp#endif
38933965Sjdp}
39033965Sjdp
39133965Sjdp/* Attach all current frags to the previous line instead of the
39233965Sjdp   current line.  This is called by the MIPS backend when it discovers
39333965Sjdp   that it needs to add some NOP instructions; the added NOP
39433965Sjdp   instructions should go with the instruction that has the delay, not
39533965Sjdp   with the new instruction.  */
39633965Sjdp
39733965Sjdpvoid
39833965Sjdplisting_prev_line ()
39933965Sjdp{
40033965Sjdp  list_info_type *l;
40133965Sjdp  fragS *f;
40233965Sjdp
40333965Sjdp  if (head == (list_info_type *) NULL
40433965Sjdp      || head == listing_tail)
40533965Sjdp    return;
40633965Sjdp
40733965Sjdp  new_frag ();
40833965Sjdp
40933965Sjdp  for (l = head; l->next != listing_tail; l = l->next)
41033965Sjdp    ;
41133965Sjdp
41233965Sjdp  for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
41333965Sjdp    if (f->line == listing_tail)
41433965Sjdp      f->line = l;
41533965Sjdp
41633965Sjdp  listing_tail->frag = frag_now;
41733965Sjdp  new_frag ();
41833965Sjdp}
41933965Sjdp
42033965Sjdp/*
42133965Sjdp This function returns the next source line from the file supplied,
42233965Sjdp truncated to size.  It appends a fake line to the end of each input
42333965Sjdp file to make
42433965Sjdp*/
42533965Sjdp
42633965Sjdpstatic char *
42733965Sjdpbuffer_line (file, line, size)
42833965Sjdp     file_info_type * file;
42933965Sjdp     char *line;
43033965Sjdp     unsigned int size;
43133965Sjdp{
43233965Sjdp  unsigned int count = 0;
43333965Sjdp  int c;
43433965Sjdp
43533965Sjdp  char *p = line;
43633965Sjdp
43733965Sjdp  /* If we couldn't open the file, return an empty line */
43838889Sjdp  if (file->at_end)
43938889Sjdp    return "";
44038889Sjdp
44138889Sjdp  /* Check the cache and see if we last used this file.  */
44238889Sjdp  if (!last_open_file_info || file != last_open_file_info)
44333965Sjdp    {
44438889Sjdp      if (last_open_file)
44538889Sjdp	{
44638889Sjdp	  last_open_file_info->pos = ftell (last_open_file);
44738889Sjdp	  fclose (last_open_file);
44838889Sjdp	}
44938889Sjdp
45038889Sjdp      last_open_file_info = file;
45138889Sjdp      last_open_file = fopen (file->filename, "r");
45238889Sjdp      if (last_open_file == NULL)
45338889Sjdp	{
45438889Sjdp	  file->at_end = 1;
45538889Sjdp	  return "";
45638889Sjdp	}
45738889Sjdp
45838889Sjdp      /* Seek to where we were last time this file was open.  */
45938889Sjdp      if (file->pos)
46038889Sjdp	fseek(last_open_file, file->pos, SEEK_SET);
46133965Sjdp    }
46233965Sjdp
46338889Sjdp  c = fgetc (last_open_file);
46433965Sjdp
46533965Sjdp  size -= 1;			/* leave room for null */
46633965Sjdp
46733965Sjdp  while (c != EOF && c != '\n')
46833965Sjdp    {
46933965Sjdp      if (count < size)
47033965Sjdp	*p++ = c;
47133965Sjdp      count++;
47233965Sjdp
47338889Sjdp      c = fgetc (last_open_file);
47433965Sjdp
47533965Sjdp    }
47633965Sjdp  if (c == EOF)
47733965Sjdp    {
47833965Sjdp      file->at_end = 1;
47933965Sjdp      *p++ = '.';
48033965Sjdp      *p++ = '.';
48133965Sjdp      *p++ = '.';
48233965Sjdp    }
48333965Sjdp  file->linenum++;
48433965Sjdp  *p++ = 0;
48533965Sjdp  return line;
48633965Sjdp}
48733965Sjdp
48833965Sjdp
48933965Sjdpstatic const char *fn;
49033965Sjdp
49133965Sjdpstatic unsigned int eject;	/* Eject pending */
49233965Sjdpstatic unsigned int page;	/* Current page number */
49333965Sjdpstatic char *title;		/* current title */
49433965Sjdpstatic char *subtitle;		/* current subtitle */
49533965Sjdpstatic unsigned int on_page;	/* number of lines printed on current page */
49633965Sjdp
49733965Sjdp
49833965Sjdpstatic void
49933965Sjdplisting_page (list)
50033965Sjdp     list_info_type *list;
50133965Sjdp{
50233965Sjdp  /* Grope around, see if we can see a title or subtitle edict coming up
50333965Sjdp     soon  (we look down 10 lines of the page and see if it's there)*/
50438889Sjdp  if ((eject || (on_page >= (unsigned int) paper_height)) && paper_height != 0)
50533965Sjdp    {
50633965Sjdp      unsigned int c = 10;
50733965Sjdp      int had_title = 0;
50833965Sjdp      int had_subtitle = 0;
50933965Sjdp
51033965Sjdp      page++;
51133965Sjdp
51233965Sjdp      while (c != 0 && list)
51333965Sjdp	{
51433965Sjdp	  if (list->edict == EDICT_SBTTL && !had_subtitle)
51533965Sjdp	    {
51633965Sjdp	      had_subtitle = 1;
51733965Sjdp	      subtitle = list->edict_arg;
51833965Sjdp	    }
51933965Sjdp	  if (list->edict == EDICT_TITLE && !had_title)
52033965Sjdp	    {
52133965Sjdp	      had_title = 1;
52233965Sjdp	      title = list->edict_arg;
52333965Sjdp	    }
52433965Sjdp	  list = list->next;
52533965Sjdp	  c--;
52633965Sjdp	}
52733965Sjdp
52833965Sjdp
52933965Sjdp      if (page > 1)
53033965Sjdp	{
53133965Sjdp	  fprintf (list_file, "\f");
53233965Sjdp	}
53333965Sjdp
53433965Sjdp      fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
53533965Sjdp      fprintf (list_file, "%s\n", title);
53633965Sjdp      fprintf (list_file, "%s\n", subtitle);
53733965Sjdp      on_page = 3;
53833965Sjdp      eject = 0;
53933965Sjdp    }
54033965Sjdp}
54133965Sjdp
54233965Sjdp
54333965Sjdpstatic unsigned int
54433965Sjdpcalc_hex (list)
54533965Sjdp     list_info_type * list;
54633965Sjdp{
54738889Sjdp  int data_buffer_size;
54833965Sjdp  list_info_type *first = list;
54938889Sjdp  unsigned int address = ~ (unsigned int) 0;
55033965Sjdp  fragS *frag;
55133965Sjdp  fragS *frag_ptr;
55233965Sjdp  unsigned int byte_in_frag;
55333965Sjdp
55433965Sjdp  /* Find first frag which says it belongs to this line */
55533965Sjdp  frag = list->frag;
55633965Sjdp  while (frag && frag->line != list)
55733965Sjdp    frag = frag->fr_next;
55833965Sjdp
55933965Sjdp  frag_ptr = frag;
56033965Sjdp
56133965Sjdp  data_buffer_size = 0;
56233965Sjdp
56333965Sjdp  /* Dump all the frags which belong to this line */
56433965Sjdp  while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
56533965Sjdp    {
56633965Sjdp      /* Print as many bytes from the fixed part as is sensible */
56733965Sjdp      byte_in_frag = 0;
56838889Sjdp      while ((offsetT) byte_in_frag < frag_ptr->fr_fix
56938889Sjdp	     && data_buffer_size < MAX_BYTES - 3)
57033965Sjdp	{
57138889Sjdp	  if (address == ~ (unsigned int) 0)
57233965Sjdp	    {
57333965Sjdp	      address = frag_ptr->fr_address;
57433965Sjdp	    }
57533965Sjdp
57633965Sjdp	  sprintf (data_buffer + data_buffer_size,
57733965Sjdp		   "%02X",
57833965Sjdp		   (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
57933965Sjdp	  data_buffer_size += 2;
58033965Sjdp	  byte_in_frag++;
58133965Sjdp	}
58233965Sjdp      {
58333965Sjdp	unsigned int var_rep_max = byte_in_frag;
58433965Sjdp	unsigned int var_rep_idx = byte_in_frag;
58533965Sjdp
58633965Sjdp	/* Print as many bytes from the variable part as is sensible */
58738889Sjdp	while (((offsetT) byte_in_frag
58833965Sjdp		< frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)
58938889Sjdp	       && data_buffer_size < MAX_BYTES - 3)
59033965Sjdp	  {
59138889Sjdp	    if (address == ~ (unsigned int) 0)
59233965Sjdp	      {
59333965Sjdp		address = frag_ptr->fr_address;
59433965Sjdp	      }
59533965Sjdp	    sprintf (data_buffer + data_buffer_size,
59633965Sjdp		     "%02X",
59733965Sjdp		     (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
59833965Sjdp#if 0
59933965Sjdp	    data_buffer[data_buffer_size++] = '*';
60033965Sjdp	    data_buffer[data_buffer_size++] = '*';
60133965Sjdp#endif
60233965Sjdp	    data_buffer_size += 2;
60333965Sjdp
60433965Sjdp	    var_rep_idx++;
60533965Sjdp	    byte_in_frag++;
60633965Sjdp
60738889Sjdp	    if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
60833965Sjdp	      var_rep_idx = var_rep_max;
60933965Sjdp	  }
61033965Sjdp      }
61133965Sjdp
61233965Sjdp      frag_ptr = frag_ptr->fr_next;
61333965Sjdp    }
61438889Sjdp  data_buffer[data_buffer_size] = '\0';
61533965Sjdp  return address;
61633965Sjdp}
61733965Sjdp
61833965Sjdp
61933965Sjdp
62033965Sjdp
62133965Sjdp
62233965Sjdp
62333965Sjdpstatic void
62433965Sjdpprint_lines (list, lineno, string, address)
62533965Sjdp     list_info_type *list;
62633965Sjdp     unsigned int lineno;
62733965Sjdp     char *string;
62833965Sjdp     unsigned int address;
62933965Sjdp{
63033965Sjdp  unsigned int idx;
63133965Sjdp  unsigned int nchars;
63233965Sjdp  unsigned int lines;
63333965Sjdp  unsigned int byte_in_word = 0;
63433965Sjdp  char *src = data_buffer;
63533965Sjdp
63633965Sjdp  /* Print the stuff on the first line */
63733965Sjdp  listing_page (list);
63838889Sjdp  nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
63933965Sjdp  /* Print the hex for the first line */
64038889Sjdp  if (address == ~ (unsigned int) 0)
64133965Sjdp    {
64233965Sjdp      fprintf (list_file, "% 4d     ", lineno);
64333965Sjdp      for (idx = 0; idx < nchars; idx++)
64433965Sjdp	fprintf (list_file, " ");
64533965Sjdp
64633965Sjdp      fprintf (list_file, "\t%s\n", string ? string : "");
64733965Sjdp      on_page++;
64833965Sjdp      listing_page (0);
64933965Sjdp
65033965Sjdp    }
65133965Sjdp  else
65233965Sjdp    {
65333965Sjdp      if (had_errors ())
65433965Sjdp	{
65533965Sjdp	  fprintf (list_file, "% 4d ???? ", lineno);
65633965Sjdp	}
65733965Sjdp      else
65833965Sjdp	{
65933965Sjdp	  fprintf (list_file, "% 4d %04x ", lineno, address);
66033965Sjdp	}
66133965Sjdp
66233965Sjdp      /* And the data to go along with it */
66333965Sjdp      idx = 0;
66433965Sjdp
66533965Sjdp      while (*src && idx < nchars)
66633965Sjdp	{
66733965Sjdp	  fprintf (list_file, "%c%c", src[0], src[1]);
66833965Sjdp	  src += 2;
66933965Sjdp	  byte_in_word++;
67033965Sjdp	  if (byte_in_word == LISTING_WORD_SIZE)
67133965Sjdp	    {
67233965Sjdp	      fprintf (list_file, " ");
67333965Sjdp	      idx++;
67433965Sjdp	      byte_in_word = 0;
67533965Sjdp	    }
67633965Sjdp	  idx += 2;
67733965Sjdp	}
67833965Sjdp
67933965Sjdp      for (; idx < nchars; idx++)
68033965Sjdp	fprintf (list_file, " ");
68133965Sjdp
68233965Sjdp      fprintf (list_file, "\t%s\n", string ? string : "");
68333965Sjdp      on_page++;
68433965Sjdp      listing_page (list);
68533965Sjdp      if (list->message)
68633965Sjdp	{
68733965Sjdp	  fprintf (list_file, "****  %s\n", list->message);
68833965Sjdp	  listing_page (list);
68933965Sjdp	  on_page++;
69033965Sjdp	}
69133965Sjdp
69233965Sjdp      for (lines = 0;
69338889Sjdp	   lines < (unsigned int) listing_lhs_cont_lines && *src;
69433965Sjdp	   lines++)
69533965Sjdp	{
69638889Sjdp	  nchars = (((LISTING_WORD_SIZE * 2) + 1)
69738889Sjdp		    * listing_lhs_width_second - 1);
69833965Sjdp	  idx = 0;
69933965Sjdp	  /* Print any more lines of data, but more compactly */
70033965Sjdp	  fprintf (list_file, "% 4d      ", lineno);
70133965Sjdp
70233965Sjdp	  while (*src && idx < nchars)
70333965Sjdp	    {
70433965Sjdp	      fprintf (list_file, "%c%c", src[0], src[1]);
70533965Sjdp	      src += 2;
70633965Sjdp	      idx += 2;
70733965Sjdp	      byte_in_word++;
70833965Sjdp	      if (byte_in_word == LISTING_WORD_SIZE)
70933965Sjdp		{
71033965Sjdp		  fprintf (list_file, " ");
71133965Sjdp		  idx++;
71233965Sjdp		  byte_in_word = 0;
71333965Sjdp		}
71433965Sjdp	    }
71533965Sjdp
71633965Sjdp	  fprintf (list_file, "\n");
71733965Sjdp	  on_page++;
71833965Sjdp	  listing_page (list);
71933965Sjdp
72033965Sjdp	}
72133965Sjdp
72233965Sjdp
72333965Sjdp    }
72433965Sjdp}
72533965Sjdp
72633965Sjdp
72733965Sjdpstatic void
72833965Sjdplist_symbol_table ()
72933965Sjdp{
73033965Sjdp  extern symbolS *symbol_rootP;
73133965Sjdp  int got_some = 0;
73233965Sjdp
73333965Sjdp  symbolS *ptr;
73433965Sjdp  eject = 1;
73533965Sjdp  listing_page (0);
73633965Sjdp
73733965Sjdp  for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
73833965Sjdp    {
73938889Sjdp      if (SEG_NORMAL (S_GET_SEGMENT (ptr))
74038889Sjdp	  || S_GET_SEGMENT (ptr) == absolute_section)
74133965Sjdp	{
74238889Sjdp#ifdef BFD_ASSEMBLER
74338889Sjdp	  /* Don't report section symbols.  They are not interesting.  */
74438889Sjdp	  if (ptr->bsym->flags & BSF_SECTION_SYM)
74538889Sjdp	    continue;
74638889Sjdp#endif
74733965Sjdp	  if (S_GET_NAME (ptr))
74833965Sjdp	    {
74933965Sjdp	      char buf[30], fmt[8];
75033965Sjdp	      valueT val = S_GET_VALUE (ptr);
75133965Sjdp
75233965Sjdp	      /* @@ Note that this is dependent on the compilation options,
75333965Sjdp		 not solely on the target characteristics.  */
75433965Sjdp	      if (sizeof (val) == 4 && sizeof (int) == 4)
75533965Sjdp		sprintf (buf, "%08lx", (unsigned long) val);
75633965Sjdp	      else if (sizeof (val) <= sizeof (unsigned long))
75733965Sjdp		{
75833965Sjdp		  sprintf (fmt, "%%0%lulx",
75933965Sjdp			   (unsigned long) (sizeof (val) * 2));
76033965Sjdp		  sprintf (buf, fmt, (unsigned long) val);
76133965Sjdp		}
76233965Sjdp#if defined (BFD64)
76333965Sjdp	      else if (sizeof (val) > 4)
76433965Sjdp		sprintf_vma (buf, val);
76533965Sjdp#endif
76633965Sjdp	      else
76733965Sjdp		abort ();
76833965Sjdp
76933965Sjdp	      if (!got_some)
77033965Sjdp		{
77133965Sjdp		  fprintf (list_file, "DEFINED SYMBOLS\n");
77233965Sjdp		  on_page++;
77333965Sjdp		  got_some = 1;
77433965Sjdp		}
77533965Sjdp
77638889Sjdp	      if (ptr->sy_frag && ptr->sy_frag->line)
77738889Sjdp		{
77838889Sjdp		  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
77938889Sjdp			   ptr->sy_frag->line->file->filename,
78038889Sjdp			   ptr->sy_frag->line->line,
78138889Sjdp			   segment_name (S_GET_SEGMENT (ptr)),
78238889Sjdp			   buf, S_GET_NAME (ptr));
78338889Sjdp		}
78438889Sjdp	      else
78538889Sjdp		{
78638889Sjdp		  fprintf (list_file, "%33s:%s %s\n",
78738889Sjdp			   segment_name (S_GET_SEGMENT (ptr)),
78838889Sjdp			   buf, S_GET_NAME (ptr));
78938889Sjdp		}
79033965Sjdp
79133965Sjdp	      on_page++;
79233965Sjdp	      listing_page (0);
79333965Sjdp	    }
79433965Sjdp	}
79533965Sjdp
79633965Sjdp    }
79733965Sjdp  if (!got_some)
79833965Sjdp    {
79933965Sjdp      fprintf (list_file, "NO DEFINED SYMBOLS\n");
80033965Sjdp      on_page++;
80133965Sjdp    }
80233965Sjdp  fprintf (list_file, "\n");
80333965Sjdp  on_page++;
80433965Sjdp  listing_page (0);
80533965Sjdp
80633965Sjdp  got_some = 0;
80733965Sjdp
80833965Sjdp  for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
80933965Sjdp    {
81033965Sjdp      if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
81133965Sjdp	{
81238889Sjdp	  if (S_GET_SEGMENT (ptr) == undefined_section)
81333965Sjdp	    {
81433965Sjdp	      if (!got_some)
81533965Sjdp		{
81633965Sjdp		  got_some = 1;
81733965Sjdp		  fprintf (list_file, "UNDEFINED SYMBOLS\n");
81833965Sjdp		  on_page++;
81933965Sjdp		  listing_page (0);
82033965Sjdp		}
82133965Sjdp	      fprintf (list_file, "%s\n", S_GET_NAME (ptr));
82233965Sjdp	      on_page++;
82333965Sjdp	      listing_page (0);
82433965Sjdp	    }
82533965Sjdp	}
82633965Sjdp    }
82733965Sjdp  if (!got_some)
82833965Sjdp    {
82933965Sjdp      fprintf (list_file, "NO UNDEFINED SYMBOLS\n");
83033965Sjdp      on_page++;
83133965Sjdp      listing_page (0);
83233965Sjdp    }
83333965Sjdp}
83433965Sjdp
83533965Sjdpstatic void
83633965Sjdpprint_source (current_file, list, buffer, width)
83733965Sjdp     file_info_type *current_file;
83833965Sjdp     list_info_type *list;
83933965Sjdp     char *buffer;
84033965Sjdp     unsigned int width;
84133965Sjdp{
84238889Sjdp  if (!current_file->at_end)
84333965Sjdp    {
84433965Sjdp      while (current_file->linenum < list->hll_line
84533965Sjdp	     && !current_file->at_end)
84633965Sjdp	{
84733965Sjdp	  char *p = buffer_line (current_file, buffer, width);
84838889Sjdp	  fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum,
84933965Sjdp		   current_file->filename, p);
85033965Sjdp	  on_page++;
85133965Sjdp	  listing_page (list);
85233965Sjdp	}
85333965Sjdp    }
85433965Sjdp}
85533965Sjdp
85633965Sjdp/* Sometimes the user doesn't want to be bothered by the debugging
85738889Sjdp   records inserted by the compiler, see if the line is suspicious.  */
85833965Sjdp
85933965Sjdpstatic int
86038889Sjdpdebugging_pseudo (list, line)
86138889Sjdp     list_info_type *list;
86238889Sjdp     const char *line;
86333965Sjdp{
86438889Sjdp  static int in_debug;
86538889Sjdp  int was_debug;
86638889Sjdp
86738889Sjdp  if (list->debugging)
86838889Sjdp    {
86938889Sjdp      in_debug = 1;
87038889Sjdp      return 1;
87138889Sjdp    }
87238889Sjdp
87338889Sjdp  was_debug = in_debug;
87438889Sjdp  in_debug = 0;
87538889Sjdp
87638889Sjdp  while (isspace ((unsigned char) *line))
87733965Sjdp    line++;
87833965Sjdp
87933965Sjdp  if (*line != '.')
88038889Sjdp    {
88138889Sjdp#ifdef OBJ_ELF
88238889Sjdp      /* The ELF compiler sometimes emits blank lines after switching
88338889Sjdp         out of a debugging section.  If the next line drops us back
88438889Sjdp         into debugging information, then don't print the blank line.
88538889Sjdp         This is a hack for a particular compiler behaviour, not a
88638889Sjdp         general case.  */
88738889Sjdp      if (was_debug
88838889Sjdp	  && *line == '\0'
88938889Sjdp	  && list->next != NULL
89038889Sjdp	  && list->next->debugging)
89138889Sjdp	{
89238889Sjdp	  in_debug = 1;
89338889Sjdp	  return 1;
89438889Sjdp	}
89538889Sjdp#endif
89633965Sjdp
89738889Sjdp      return 0;
89838889Sjdp    }
89938889Sjdp
90033965Sjdp  line++;
90133965Sjdp
90233965Sjdp  if (strncmp (line, "def", 3) == 0)
90333965Sjdp    return 1;
90433965Sjdp  if (strncmp (line, "val", 3) == 0)
90533965Sjdp    return 1;
90633965Sjdp  if (strncmp (line, "scl", 3) == 0)
90733965Sjdp    return 1;
90833965Sjdp  if (strncmp (line, "line", 4) == 0)
90933965Sjdp    return 1;
91033965Sjdp  if (strncmp (line, "endef", 5) == 0)
91133965Sjdp    return 1;
91233965Sjdp  if (strncmp (line, "ln", 2) == 0)
91333965Sjdp    return 1;
91433965Sjdp  if (strncmp (line, "type", 4) == 0)
91533965Sjdp    return 1;
91633965Sjdp  if (strncmp (line, "size", 4) == 0)
91733965Sjdp    return 1;
91833965Sjdp  if (strncmp (line, "dim", 3) == 0)
91933965Sjdp    return 1;
92033965Sjdp  if (strncmp (line, "tag", 3) == 0)
92133965Sjdp    return 1;
92233965Sjdp
92333965Sjdp  if (strncmp (line, "stabs", 5) == 0)
92433965Sjdp    return 1;
92533965Sjdp  if (strncmp (line, "stabn", 5) == 0)
92633965Sjdp    return 1;
92733965Sjdp
92833965Sjdp  return 0;
92933965Sjdp}
93033965Sjdp
93133965Sjdpstatic void
93233965Sjdplisting_listing (name)
93333965Sjdp     char *name;
93433965Sjdp{
93533965Sjdp  list_info_type *list = head;
93633965Sjdp  file_info_type *current_hll_file = (file_info_type *) NULL;
93733965Sjdp  char *message;
93833965Sjdp  char *buffer;
93933965Sjdp  char *p;
94033965Sjdp  int show_listing = 1;
94133965Sjdp  unsigned int width;
94233965Sjdp
94338889Sjdp  buffer = xmalloc (listing_rhs_width);
94438889Sjdp  data_buffer = xmalloc (MAX_BYTES);
94533965Sjdp  eject = 1;
94633965Sjdp  list = head;
94733965Sjdp
94833965Sjdp  while (list != (list_info_type *) NULL && 0)
94933965Sjdp    {
95033965Sjdp      if (list->next)
95133965Sjdp	list->frag = list->next->frag;
95233965Sjdp      list = list->next;
95333965Sjdp
95433965Sjdp    }
95533965Sjdp
95633965Sjdp  list = head->next;
95733965Sjdp
95833965Sjdp
95933965Sjdp  while (list)
96033965Sjdp    {
96138889Sjdp      width = listing_rhs_width > paper_width ? paper_width :
96238889Sjdp	listing_rhs_width;
96333965Sjdp
96433965Sjdp      switch (list->edict)
96533965Sjdp	{
96633965Sjdp	case EDICT_LIST:
96733965Sjdp	  show_listing++;
96833965Sjdp	  break;
96933965Sjdp	case EDICT_NOLIST:
97033965Sjdp	  show_listing--;
97133965Sjdp	  break;
97233965Sjdp	case EDICT_NOLIST_NEXT:
97333965Sjdp	  break;
97433965Sjdp	case EDICT_EJECT:
97533965Sjdp	  break;
97633965Sjdp	case EDICT_NONE:
97733965Sjdp	  break;
97833965Sjdp	case EDICT_TITLE:
97933965Sjdp	  title = list->edict_arg;
98033965Sjdp	  break;
98133965Sjdp	case EDICT_SBTTL:
98233965Sjdp	  subtitle = list->edict_arg;
98333965Sjdp	  break;
98433965Sjdp	default:
98533965Sjdp	  abort ();
98633965Sjdp	}
98733965Sjdp
98833965Sjdp      if (show_listing > 0)
98933965Sjdp	{
99033965Sjdp	  /* Scan down the list and print all the stuff which can be done
99133965Sjdp	     with this line (or lines).  */
99233965Sjdp	  message = 0;
99333965Sjdp
99433965Sjdp	  if (list->hll_file)
99533965Sjdp	    {
99633965Sjdp	      current_hll_file = list->hll_file;
99733965Sjdp	    }
99833965Sjdp
99938889Sjdp	  if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
100033965Sjdp	    {
100133965Sjdp	      print_source (current_hll_file, list, buffer, width);
100233965Sjdp	    }
100333965Sjdp
100438889Sjdp	  if (list->line_contents)
100533965Sjdp	    {
100638889Sjdp	      if (!((listing & LISTING_NODEBUG)
100738889Sjdp		    && debugging_pseudo (list, list->line_contents)))
100838889Sjdp		{
100938889Sjdp 		  print_lines (list, list->file->linenum,
101038889Sjdp			       list->line_contents, calc_hex (list));
101138889Sjdp		}
101238889Sjdp	    }
101338889Sjdp	  else
101438889Sjdp	    {
101538889Sjdp	      while (list->file->linenum < list->line
101638889Sjdp		     && !list->file->at_end)
101738889Sjdp		{
101838889Sjdp		  unsigned int address;
101933965Sjdp
102038889Sjdp		  p = buffer_line (list->file, buffer, width);
102133965Sjdp
102238889Sjdp		  if (list->file->linenum < list->line)
102338889Sjdp		    address = ~ (unsigned int) 0;
102438889Sjdp		  else
102538889Sjdp		    address = calc_hex (list);
102633965Sjdp
102738889Sjdp		  if (!((listing & LISTING_NODEBUG)
102838889Sjdp			&& debugging_pseudo (list, p)))
102938889Sjdp		    print_lines (list, list->file->linenum, p, address);
103038889Sjdp		}
103133965Sjdp	    }
103233965Sjdp
103333965Sjdp	  if (list->edict == EDICT_EJECT)
103433965Sjdp	    {
103533965Sjdp	      eject = 1;
103633965Sjdp	    }
103733965Sjdp	}
103833965Sjdp      else
103933965Sjdp	{
104038889Sjdp	  while (list->file->linenum < list->line
104133965Sjdp		 && !list->file->at_end)
104233965Sjdp	    p = buffer_line (list->file, buffer, width);
104333965Sjdp	}
104433965Sjdp
104533965Sjdp      if (list->edict == EDICT_NOLIST_NEXT)
104633965Sjdp	--show_listing;
104733965Sjdp
104833965Sjdp      list = list->next;
104933965Sjdp    }
105038889Sjdp
105133965Sjdp  free (buffer);
105238889Sjdp  free (data_buffer);
105338889Sjdp  data_buffer = NULL;
105433965Sjdp}
105533965Sjdp
105633965Sjdpvoid
105733965Sjdplisting_print (name)
105833965Sjdp     char *name;
105933965Sjdp{
106033965Sjdp  int using_stdout;
106133965Sjdp
106233965Sjdp  title = "";
106333965Sjdp  subtitle = "";
106433965Sjdp
106533965Sjdp  if (name == NULL)
106633965Sjdp    {
106733965Sjdp      list_file = stdout;
106833965Sjdp      using_stdout = 1;
106933965Sjdp    }
107033965Sjdp  else
107133965Sjdp    {
107233965Sjdp      list_file = fopen (name, "w");
107333965Sjdp      if (list_file != NULL)
107433965Sjdp	using_stdout = 0;
107533965Sjdp      else
107633965Sjdp	{
107733965Sjdp	  as_perror ("can't open list file: %s", name);
107833965Sjdp	  list_file = stdout;
107933965Sjdp	  using_stdout = 1;
108033965Sjdp	}
108133965Sjdp    }
108233965Sjdp
108333965Sjdp  if (listing & LISTING_NOFORM)
108433965Sjdp    {
108533965Sjdp      paper_height = 0;
108633965Sjdp    }
108733965Sjdp
108833965Sjdp  if (listing & LISTING_LISTING)
108933965Sjdp    {
109033965Sjdp      listing_listing (name);
109133965Sjdp    }
109233965Sjdp
109333965Sjdp  if (listing & LISTING_SYMBOLS)
109433965Sjdp    {
109533965Sjdp      list_symbol_table ();
109633965Sjdp    }
109733965Sjdp
109833965Sjdp  if (! using_stdout)
109933965Sjdp    {
110033965Sjdp      if (fclose (list_file) == EOF)
110133965Sjdp	as_perror ("error closing list file: %s", name);
110233965Sjdp    }
110333965Sjdp
110438889Sjdp  if (last_open_file)
110533965Sjdp    {
110638889Sjdp      fclose (last_open_file);
110733965Sjdp    }
110833965Sjdp}
110933965Sjdp
111033965Sjdp
111133965Sjdpvoid
111233965Sjdplisting_file (name)
111333965Sjdp     const char *name;
111433965Sjdp{
111533965Sjdp  fn = name;
111633965Sjdp}
111733965Sjdp
111833965Sjdpvoid
111933965Sjdplisting_eject (ignore)
112033965Sjdp     int ignore;
112133965Sjdp{
112233965Sjdp  if (listing)
112333965Sjdp    listing_tail->edict = EDICT_EJECT;
112433965Sjdp}
112533965Sjdp
112633965Sjdpvoid
112733965Sjdplisting_flags (ignore)
112833965Sjdp     int ignore;
112933965Sjdp{
113033965Sjdp  while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
113133965Sjdp    input_line_pointer++;
113233965Sjdp
113333965Sjdp}
113433965Sjdp
113533965Sjdp/* Turn listing on or off.  An argument of 0 means to turn off
113633965Sjdp   listing.  An argument of 1 means to turn on listing.  An argument
113733965Sjdp   of 2 means to turn off listing, but as of the next line; that is,
113833965Sjdp   the current line should be listed, but the next line should not.  */
113933965Sjdp
114033965Sjdpvoid
114133965Sjdplisting_list (on)
114233965Sjdp     int on;
114333965Sjdp{
114433965Sjdp  if (listing)
114533965Sjdp    {
114633965Sjdp      switch (on)
114733965Sjdp	{
114833965Sjdp	case 0:
114933965Sjdp	  if (listing_tail->edict == EDICT_LIST)
115033965Sjdp	    listing_tail->edict = EDICT_NONE;
115133965Sjdp	  else
115233965Sjdp	    listing_tail->edict = EDICT_NOLIST;
115333965Sjdp	  break;
115433965Sjdp	case 1:
115533965Sjdp	  if (listing_tail->edict == EDICT_NOLIST
115633965Sjdp	      || listing_tail->edict == EDICT_NOLIST_NEXT)
115733965Sjdp	    listing_tail->edict = EDICT_NONE;
115833965Sjdp	  else
115933965Sjdp	    listing_tail->edict = EDICT_LIST;
116033965Sjdp	  break;
116133965Sjdp	case 2:
116233965Sjdp	  listing_tail->edict = EDICT_NOLIST_NEXT;
116333965Sjdp	  break;
116433965Sjdp	default:
116533965Sjdp	  abort ();
116633965Sjdp	}
116733965Sjdp    }
116833965Sjdp}
116933965Sjdp
117033965Sjdp
117133965Sjdpvoid
117233965Sjdplisting_psize (width_only)
117333965Sjdp     int width_only;
117433965Sjdp{
117533965Sjdp  if (! width_only)
117633965Sjdp    {
117733965Sjdp      paper_height = get_absolute_expression ();
117833965Sjdp
117933965Sjdp      if (paper_height < 0 || paper_height > 1000)
118033965Sjdp	{
118133965Sjdp	  paper_height = 0;
118233965Sjdp	  as_warn ("strange paper height, set to no form");
118333965Sjdp	}
118433965Sjdp
118533965Sjdp      if (*input_line_pointer != ',')
118633965Sjdp	{
118733965Sjdp	  demand_empty_rest_of_line ();
118833965Sjdp	  return;
118933965Sjdp	}
119033965Sjdp
119133965Sjdp      ++input_line_pointer;
119233965Sjdp    }
119333965Sjdp
119433965Sjdp  paper_width = get_absolute_expression ();
119533965Sjdp
119633965Sjdp  demand_empty_rest_of_line ();
119733965Sjdp}
119833965Sjdp
119933965Sjdpvoid
120033965Sjdplisting_nopage (ignore)
120133965Sjdp     int ignore;
120233965Sjdp{
120333965Sjdp  paper_height = 0;
120433965Sjdp}
120533965Sjdp
120633965Sjdpvoid
120733965Sjdplisting_title (depth)
120833965Sjdp     int depth;
120933965Sjdp{
121033965Sjdp  int quoted;
121133965Sjdp  char *start;
121233965Sjdp  char *ttl;
121333965Sjdp  unsigned int length;
121433965Sjdp
121533965Sjdp  SKIP_WHITESPACE ();
121633965Sjdp  if (*input_line_pointer != '\"')
121733965Sjdp    quoted = 0;
121833965Sjdp  else
121933965Sjdp    {
122033965Sjdp      quoted = 1;
122133965Sjdp      ++input_line_pointer;
122233965Sjdp    }
122333965Sjdp
122433965Sjdp  start = input_line_pointer;
122533965Sjdp
122633965Sjdp  while (*input_line_pointer)
122733965Sjdp    {
122833965Sjdp      if (quoted
122933965Sjdp	  ? *input_line_pointer == '\"'
123033965Sjdp	  : is_end_of_line[(unsigned char) *input_line_pointer])
123133965Sjdp	{
123233965Sjdp	  if (listing)
123333965Sjdp	    {
123433965Sjdp	      length = input_line_pointer - start;
123533965Sjdp	      ttl = xmalloc (length + 1);
123633965Sjdp	      memcpy (ttl, start, length);
123733965Sjdp	      ttl[length] = 0;
123833965Sjdp	      listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
123933965Sjdp	      listing_tail->edict_arg = ttl;
124033965Sjdp	    }
124133965Sjdp	  if (quoted)
124233965Sjdp	    input_line_pointer++;
124333965Sjdp	  demand_empty_rest_of_line ();
124433965Sjdp	  return;
124533965Sjdp	}
124633965Sjdp      else if (*input_line_pointer == '\n')
124733965Sjdp	{
124833965Sjdp	  as_bad ("New line in title");
124933965Sjdp	  demand_empty_rest_of_line ();
125033965Sjdp	  return;
125133965Sjdp	}
125233965Sjdp      else
125333965Sjdp	{
125433965Sjdp	  input_line_pointer++;
125533965Sjdp	}
125633965Sjdp    }
125733965Sjdp}
125833965Sjdp
125933965Sjdp
126033965Sjdp
126133965Sjdpvoid
126233965Sjdplisting_source_line (line)
126333965Sjdp     unsigned int line;
126433965Sjdp{
126533965Sjdp  if (listing)
126633965Sjdp    {
126733965Sjdp      new_frag ();
126833965Sjdp      listing_tail->hll_line = line;
126933965Sjdp      new_frag ();
127033965Sjdp    }
127133965Sjdp}
127233965Sjdp
127333965Sjdpvoid
127433965Sjdplisting_source_file (file)
127533965Sjdp     const char *file;
127633965Sjdp{
127733965Sjdp  if (listing)
127833965Sjdp    listing_tail->hll_file = file_info (file);
127933965Sjdp}
128033965Sjdp
128133965Sjdp
128233965Sjdp
128333965Sjdp#else
128433965Sjdp
128533965Sjdp
128633965Sjdp/* Dummy functions for when compiled without listing enabled */
128733965Sjdp
128833965Sjdpvoid
128933965Sjdplisting_flags (ignore)
129033965Sjdp     int ignore;
129133965Sjdp{
129233965Sjdp  s_ignore (0);
129333965Sjdp}
129433965Sjdp
129533965Sjdpvoid
129633965Sjdplisting_list (on)
129733965Sjdp     int on;
129833965Sjdp{
129933965Sjdp  s_ignore (0);
130033965Sjdp}
130133965Sjdp
130233965Sjdpvoid
130333965Sjdplisting_eject (ignore)
130433965Sjdp     int ignore;
130533965Sjdp{
130633965Sjdp  s_ignore (0);
130733965Sjdp}
130833965Sjdp
130933965Sjdpvoid
131033965Sjdplisting_psize (ignore)
131133965Sjdp     int ignore;
131233965Sjdp{
131333965Sjdp  s_ignore (0);
131433965Sjdp}
131533965Sjdp
131633965Sjdpvoid
131733965Sjdplisting_nopage (ignore)
131833965Sjdp     int ignore;
131933965Sjdp{
132033965Sjdp  s_ignore (0);
132133965Sjdp}
132233965Sjdp
132333965Sjdpvoid
132433965Sjdplisting_title (depth)
132533965Sjdp     int depth;
132633965Sjdp{
132733965Sjdp  s_ignore (0);
132833965Sjdp}
132933965Sjdp
133033965Sjdpvoid
133133965Sjdplisting_file (name)
133233965Sjdp     const char *name;
133333965Sjdp{
133433965Sjdp
133533965Sjdp}
133633965Sjdp
133733965Sjdpvoid
133833965Sjdplisting_newline (name)
133933965Sjdp     char *name;
134033965Sjdp{
134133965Sjdp
134233965Sjdp}
134333965Sjdp
134433965Sjdpvoid
134533965Sjdplisting_source_line (n)
134633965Sjdp     unsigned int n;
134733965Sjdp{
134833965Sjdp
134933965Sjdp}
135033965Sjdpvoid
135133965Sjdplisting_source_file (n)
135233965Sjdp     const char *n;
135333965Sjdp{
135433965Sjdp
135533965Sjdp}
135633965Sjdp
135733965Sjdp#endif
1358