* listing.c (struct file_info_struct): Rename end_pending field to
[external/binutils.git] / gas / listing.c
1 /* listing.c - mainting assembly listings
2    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
3
4 This file is part of GAS, the GNU Assembler.
5
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 /*
21  Contributed by Steve Chamberlain
22                 sac@cygnus.com
23
24
25  A listing page looks like:
26
27  LISTING_HEADER  sourcefilename pagenumber
28  TITLE LINE
29  SUBTITLE LINE
30  linenumber address data  source
31  linenumber address data  source
32  linenumber address data  source
33  linenumber address data  source
34
35  If not overridden, the listing commands are:
36
37  .title  "stuff"
38         Put "stuff" onto the title line
39  .sbttl  "stuff"
40         Put stuff onto the subtitle line
41
42   If these commands come within 10 lines of the top of the page, they
43   will affect the page they are on, as well as any subsequent page
44
45  .eject
46         Thow a page
47  .list
48         Increment the enable listing counter
49  .nolist
50         Decrement the enable listing counter
51
52  .psize Y[,X]
53         Set the paper size to X wide and Y high. Setting a psize Y of
54         zero will suppress form feeds except where demanded by .eject
55
56  If the counter goes below zero, listing is suppressed.
57
58
59  Listings are a maintained by read calling various listing_<foo>
60  functions.  What happens most is that the macro NO_LISTING is not
61  defined (from the Makefile), then the macro LISTING_NEWLINE expands
62  into a call to listing_newline.  The call is done from read.c, every
63  time it sees a newline, and -l is on the command line.
64
65  The function listing_newline remembers the frag associated with the
66  newline, and creates a new frag - note that this is wasteful, but not
67  a big deal, since listing slows things down a lot anyway.  The
68  function also rememebers when the filename changes.
69
70  When all the input has finished, and gas has had a chance to settle
71  down, the listing is output. This is done by running down the list of
72  frag/source file records, and opening the files as needed and printing
73  out the bytes and chars associated with them.
74
75  The only things which the architecture can change about the listing
76  are defined in these macros:
77
78  LISTING_HEADER         The name of the architecture
79  LISTING_WORD_SIZE      The make of the number of bytes in a word, this determines
80                         the clumping of the output data. eg a value of
81                         2 makes words look like 1234 5678, whilst 1
82                         would make the same value look like 12 34 56
83                         78
84  LISTING_LHS_WIDTH      Number of words of above size for the lhs
85
86  LISTING_LHS_WIDTH_SECOND   Number of words for the data on the lhs
87                         for the second line
88
89  LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation
90  LISTING_RHS_WIDTH      Number of chars from the input file to print
91                         on a line
92 */
93
94 #include <ctype.h>
95
96 #include "as.h"
97 #include <obstack.h>
98 #include "input-file.h"
99 #include "subsegs.h"
100
101 #ifndef NO_LISTING
102 #ifndef LISTING_HEADER
103 #define LISTING_HEADER "GAS LISTING"
104 #endif
105 #ifndef LISTING_WORD_SIZE
106 #define LISTING_WORD_SIZE 4
107 #endif
108 #ifndef LISTING_LHS_WIDTH
109 #define LISTING_LHS_WIDTH 1
110 #endif
111 #ifndef LISTING_LHS_WIDTH_SECOND
112 #define LISTING_LHS_WIDTH_SECOND 1
113 #endif
114 #ifndef LISTING_RHS_WIDTH
115 #define LISTING_RHS_WIDTH 100
116 #endif
117 #ifndef LISTING_LHS_CONT_LINES
118 #define LISTING_LHS_CONT_LINES 4
119 #endif
120
121
122
123
124 /* This structure remembers which .s were used */
125 typedef struct file_info_struct
126 {
127   char *filename;
128   int linenum;
129   FILE *file;
130   struct file_info_struct *next;
131   int at_end;
132 }
133
134 file_info_type;
135
136
137 /* this structure rememebrs which line from which file goes into which
138    frag */
139 typedef struct list_info_struct
140 {
141   /* Frag which this line of source is nearest to */
142   fragS *frag;
143   /* The actual line in the source file */
144   unsigned int line;
145   /* Pointer to the file info struct for the file which this line
146      belongs to */
147   file_info_type *file;
148
149   /* Next in list */
150   struct list_info_struct *next;
151
152
153   /* Pointer to the file info struct for the high level language
154      source line that belongs here */
155   file_info_type *hll_file;
156
157   /* High level language source line */
158   int hll_line;
159
160
161   /* Pointer to any error message associated with this line */
162   char *message;
163
164   enum
165     {
166       EDICT_NONE,
167       EDICT_SBTTL,
168       EDICT_TITLE,
169       EDICT_NOLIST,
170       EDICT_LIST,
171       EDICT_EJECT
172     } edict;
173   char *edict_arg;
174
175 }
176
177 list_info_type;
178
179
180 static struct list_info_struct *head;
181 struct list_info_struct *listing_tail;
182 extern int listing;
183 extern fragS *frag_now;
184
185
186 static int paper_width = 200;
187 static int paper_height = 60;
188
189
190 /* this static array is used to keep the text of data to be printed
191    before the start of the line.
192     It is stored so we can give a bit more info on the next line.  To much, and large
193    initialized arrays will use up lots of paper.
194  */
195
196 static char data_buffer[100];
197 static unsigned int data_buffer_size;
198
199
200 /* Prototypes.  */
201 static void listing_message PARAMS ((const char *name, const char *message));
202 static file_info_type *file_info PARAMS ((const char *file_name));
203 static void new_frag PARAMS ((void));
204 static char *buffer_line PARAMS ((file_info_type *file,
205                                   char *line, unsigned int size));
206 static void listing_page PARAMS ((list_info_type *list));
207 static unsigned int calc_hex PARAMS ((list_info_type *list));
208 static void print_lines PARAMS ((list_info_type *list,
209                                  char *string,
210                                  unsigned int address));
211 static void list_symbol_table PARAMS ((void));
212 static void print_source PARAMS ((file_info_type *current_file,
213                                   list_info_type *list,
214                                   char *buffer,
215                                   unsigned int width));
216 static int debugging_pseudo PARAMS ((char *line));
217 static void listing_listing PARAMS ((char *name));
218
219
220 static void
221 listing_message (name, message)
222      const char *name;
223      const char *message;
224 {
225   unsigned int l = strlen (name) + strlen (message) + 1;
226   char *n = (char *) xmalloc (l);
227   strcpy (n, name);
228   strcat (n, message);
229   if (listing_tail != (list_info_type *) NULL)
230     {
231       listing_tail->message = n;
232     }
233 }
234
235 void
236 listing_warning (message)
237      const char *message;
238 {
239   listing_message ("Warning:", message);
240 }
241
242 void
243 listing_error (message)
244      const char *message;
245 {
246   listing_message ("Error:", message);
247 }
248
249
250
251
252 static file_info_type *file_info_head;
253
254 static file_info_type *
255 file_info (file_name)
256      const char *file_name;
257 {
258   /* Find an entry with this file name */
259   file_info_type *p = file_info_head;
260
261   while (p != (file_info_type *) NULL)
262     {
263       if (strcmp (p->filename, file_name) == 0)
264         return p;
265       p = p->next;
266     }
267
268   /* Make new entry */
269
270   p = (file_info_type *) xmalloc (sizeof (file_info_type));
271   p->next = file_info_head;
272   file_info_head = p;
273   p->filename = xmalloc ((unsigned long) strlen (file_name) + 1);
274   strcpy (p->filename, file_name);
275   p->linenum = 0;
276   p->at_end = 0;
277
278   p->file = fopen (p->filename, "r");
279   if (p->file)
280     fgetc (p->file);
281
282   return p;
283 }
284
285
286 static void
287 new_frag ()
288 {
289
290   frag_wane (frag_now);
291   frag_new (0);
292
293 }
294
295 void
296 listing_newline (ps)
297      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;
304
305   as_where (&file, &line);
306   if (line != last_line || (last_file && file && strcmp(file, last_file)))
307     {
308       last_line = line;
309       last_file = file;
310       new_frag ();
311
312       new = (list_info_type *) xmalloc (sizeof (list_info_type));
313       new->frag = frag_now;
314       new->line = line;
315       new->file = file_info (file);
316
317       if (listing_tail)
318         {
319           listing_tail->next = new;
320         }
321       else
322         {
323           head = new;
324         }
325       listing_tail = new;
326       new->next = (list_info_type *) NULL;
327       new->message = (char *) NULL;
328       new->edict = EDICT_NONE;
329       new->hll_file = (file_info_type *) NULL;
330       new->hll_line = 0;
331       new_frag ();
332     }
333 }
334
335 /* Attach all current frags to the previous line instead of the
336    current line.  This is called by the MIPS backend when it discovers
337    that it needs to add some NOP instructions; the added NOP
338    instructions should go with the instruction that has the delay, not
339    with the new instruction.  */
340
341 void
342 listing_prev_line ()
343 {
344   list_info_type *l;
345   fragS *f;
346
347   if (head == (list_info_type *) NULL
348       || head == listing_tail)
349     return;
350
351   new_frag ();
352
353   for (l = head; l->next != listing_tail; l = l->next)
354     ;
355
356   for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
357     if (f->line == listing_tail)
358       f->line = l;
359
360   listing_tail->frag = frag_now;
361   new_frag ();
362 }
363
364 /*
365  This function returns the next source line from the file supplied,
366  truncated to size.  It appends a fake line to the end of each input
367  file to make
368 */
369
370 static char *
371 buffer_line (file, line, size)
372      file_info_type * file;
373      char *line;
374      unsigned int size;
375 {
376   unsigned int count = 0;
377   int c;
378
379   char *p = line;
380
381   /* If we couldn't open the file, return an empty line */
382   if (file->file == (FILE *) NULL || file->at_end)
383     {
384       return "";
385     }
386
387   if (file->linenum == 0)
388     rewind (file->file);
389
390   c = fgetc (file->file);
391
392   size -= 1;                    /* leave room for null */
393
394   while (c != EOF && c != '\n')
395     {
396       if (count < size)
397         *p++ = c;
398       count++;
399
400       c = fgetc (file->file);
401
402     }
403   if (c == EOF)
404     {
405       file->at_end = 1;
406       *p++ = '.';
407       *p++ = '.';
408       *p++ = '.';
409     }
410   file->linenum++;
411   *p++ = 0;
412   return line;
413 }
414
415
416 static const char *fn;
417
418 static unsigned int eject;      /* Eject pending */
419 static unsigned int page;       /* Current page number */
420 static char *title;             /* current title */
421 static char *subtitle;          /* current subtitle */
422 static unsigned int on_page;    /* number of lines printed on current page */
423
424
425 static void
426 listing_page (list)
427      list_info_type *list;
428 {
429   /* Grope around, see if we can see a title or subtitle edict coming up
430      soon  (we look down 10 lines of the page and see if it's there)*/
431   if ((eject || (on_page >= paper_height)) && paper_height != 0)
432     {
433       unsigned int c = 10;
434       int had_title = 0;
435       int had_subtitle = 0;
436
437       page++;
438
439       while (c != 0 && list)
440         {
441           if (list->edict == EDICT_SBTTL && !had_subtitle)
442             {
443               had_subtitle = 1;
444               subtitle = list->edict_arg;
445             }
446           if (list->edict == EDICT_TITLE && !had_title)
447             {
448               had_title = 1;
449               title = list->edict_arg;
450             }
451           list = list->next;
452           c--;
453         }
454
455
456       if (page > 1)
457         {
458           printf ("\f");
459         }
460
461       printf ("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
462       printf ("%s\n", title);
463       printf ("%s\n", subtitle);
464       on_page = 3;
465       eject = 0;
466     }
467 }
468
469
470 static unsigned int
471 calc_hex (list)
472      list_info_type * list;
473 {
474   list_info_type *first = list;
475   unsigned int address = (unsigned int) ~0;
476
477   fragS *frag;
478   fragS *frag_ptr;
479
480   unsigned int byte_in_frag;
481
482
483   /* Find first frag which says it belongs to this line */
484   frag = list->frag;
485   while (frag && frag->line != list)
486     frag = frag->fr_next;
487
488   frag_ptr = frag;
489
490   data_buffer_size = 0;
491
492   /* Dump all the frags which belong to this line */
493   while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
494     {
495       /* Print as many bytes from the fixed part as is sensible */
496       byte_in_frag = 0;
497       while (byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof (data_buffer) - 10)
498         {
499           if (address == ~0)
500             {
501               address = frag_ptr->fr_address;
502             }
503
504           sprintf (data_buffer + data_buffer_size,
505                    "%02X",
506                    (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
507           data_buffer_size += 2;
508           byte_in_frag++;
509         }
510       {
511         unsigned int var_rep_max = byte_in_frag;
512         unsigned int var_rep_idx = byte_in_frag;
513
514         /* Print as many bytes from the variable part as is sensible */
515         while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
516                && data_buffer_size < sizeof (data_buffer) - 10)
517           {
518             if (address == ~0)
519               {
520                 address = frag_ptr->fr_address;
521               }
522             sprintf (data_buffer + data_buffer_size,
523                      "%02X",
524                      (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
525 #if 0
526             data_buffer[data_buffer_size++] = '*';
527             data_buffer[data_buffer_size++] = '*';
528 #endif
529             data_buffer_size += 2;
530
531             var_rep_idx++;
532             byte_in_frag++;
533
534             if (var_rep_idx >= frag_ptr->fr_var)
535               var_rep_idx = var_rep_max;
536           }
537       }
538
539       frag_ptr = frag_ptr->fr_next;
540     }
541   data_buffer[data_buffer_size++] = 0;
542   return address;
543 }
544
545
546
547
548
549
550 static void
551 print_lines (list, string, address)
552      list_info_type *list;
553      char *string;
554      unsigned int address;
555 {
556   unsigned int idx;
557   unsigned int nchars;
558   unsigned int lines;
559   unsigned int byte_in_word = 0;
560   char *src = data_buffer;
561
562   /* Print the stuff on the first line */
563   listing_page (list);
564   nchars = (LISTING_WORD_SIZE * 2 + 1) * LISTING_LHS_WIDTH;
565   /* Print the hex for the first line */
566   if (address == ~0)
567     {
568       printf ("% 4d     ", list->line);
569       for (idx = 0; idx < nchars; idx++)
570         printf (" ");
571
572       printf ("\t%s\n", string ? string : "");
573       on_page++;
574       listing_page (0);
575
576     }
577   else
578     {
579       if (had_errors ())
580         {
581           printf ("% 4d ???? ", list->line);
582         }
583       else
584         {
585           printf ("% 4d %04x ", list->line, address);
586         }
587
588       /* And the data to go along with it */
589       idx = 0;
590
591       while (*src && idx < nchars)
592         {
593           printf ("%c%c", src[0], src[1]);
594           src += 2;
595           byte_in_word++;
596           if (byte_in_word == LISTING_WORD_SIZE)
597             {
598               printf (" ");
599               idx++;
600               byte_in_word = 0;
601             }
602           idx += 2;
603         }
604
605       for (; idx < nchars; idx++)
606         printf (" ");
607
608       printf ("\t%s\n", string ? string : "");
609       on_page++;
610       listing_page (list);
611       if (list->message)
612         {
613           printf ("****  %s\n", list->message);
614           listing_page (list);
615           on_page++;
616         }
617
618       for (lines = 0;
619            lines < LISTING_LHS_CONT_LINES
620            && *src;
621            lines++)
622         {
623           nchars = ((LISTING_WORD_SIZE * 2) + 1) * LISTING_LHS_WIDTH_SECOND - 1;
624           idx = 0;
625           /* Print any more lines of data, but more compactly */
626           printf ("% 4d      ", list->line);
627
628           while (*src && idx < nchars)
629             {
630               printf ("%c%c", src[0], src[1]);
631               src += 2;
632               idx += 2;
633               byte_in_word++;
634               if (byte_in_word == LISTING_WORD_SIZE)
635                 {
636                   printf (" ");
637                   idx++;
638                   byte_in_word = 0;
639                 }
640             }
641
642           printf ("\n");
643           on_page++;
644           listing_page (list);
645
646         }
647
648
649     }
650 }
651
652
653 static void
654 list_symbol_table ()
655 {
656   extern symbolS *symbol_rootP;
657   int got_some = 0;
658
659   symbolS *ptr;
660   eject = 1;
661   listing_page (0);
662
663   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
664     {
665       if (ptr->sy_frag->line)
666         {
667           if (S_GET_NAME (ptr))
668             {
669               char buf[30], fmt[8];
670               valueT val = S_GET_VALUE (ptr);
671
672               /* @@ Note that this is dependent on the compilation options,
673                  not solely on the target characteristics.  */
674               if (sizeof (val) == 4 && sizeof (int) == 4)
675                 sprintf (buf, "%08lx", (unsigned long) val);
676               else if (sizeof (val) <= sizeof (unsigned long))
677                 {
678                   sprintf (fmt, "%%0%lulx",
679                            (unsigned long) (sizeof (val) * 2));
680                   sprintf (buf, fmt, (unsigned long) val);
681                 }
682 #if defined (BFD64)
683               else if (sizeof (val) > 4)
684                 {
685                   char buf1[30];
686                   sprintf_vma (buf1, val);
687                   strcpy (buf, "00000000");
688                   strcpy (buf + 8 - strlen (buf1), buf1);
689                 }
690 #endif
691               else
692                 abort ();
693
694               if (!got_some)
695                 {
696                   printf ("DEFINED SYMBOLS\n");
697                   on_page++;
698                   got_some = 1;
699                 }
700
701               printf ("%20s:%-5d  %s:%s %s\n",
702                       ptr->sy_frag->line->file->filename,
703                       ptr->sy_frag->line->line,
704                       segment_name (S_GET_SEGMENT (ptr)),
705                       buf, S_GET_NAME (ptr));
706
707               on_page++;
708               listing_page (0);
709             }
710         }
711
712     }
713   if (!got_some)
714     {
715       printf ("NO DEFINED SYMBOLS\n");
716       on_page++;
717     }
718   printf ("\n");
719   on_page++;
720   listing_page (0);
721
722   got_some = 0;
723
724   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
725     {
726       if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
727         {
728           if (ptr->sy_frag->line == 0
729 #ifdef S_IS_REGISTER
730               && !S_IS_REGISTER (ptr)
731 #endif
732               && S_GET_SEGMENT (ptr) != reg_section)
733             {
734               if (!got_some)
735                 {
736                   got_some = 1;
737                   printf ("UNDEFINED SYMBOLS\n");
738                   on_page++;
739                   listing_page (0);
740                 }
741               printf ("%s\n", S_GET_NAME (ptr));
742               on_page++;
743               listing_page (0);
744             }
745         }
746     }
747   if (!got_some)
748     {
749       printf ("NO UNDEFINED SYMBOLS\n");
750       on_page++;
751       listing_page (0);
752     }
753 }
754
755 static void
756 print_source (current_file, list, buffer, width)
757      file_info_type *current_file;
758      list_info_type *list;
759      char *buffer;
760      unsigned int width;
761 {
762   if (current_file->file)
763     {
764       while (current_file->linenum < list->hll_line
765              && !current_file->at_end)
766         {
767           char *p = buffer_line (current_file, buffer, width);
768           printf ("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
769           on_page++;
770           listing_page (list);
771         }
772     }
773 }
774
775 /* Sometimes the user doesn't want to be bothered by the debugging
776    records inserted by the compiler, see if the line is suspicious */
777
778 static int
779 debugging_pseudo (line)
780      char *line;
781 {
782   while (isspace (*line))
783     line++;
784
785   if (*line != '.')
786     return 0;
787
788   line++;
789
790   if (strncmp (line, "def", 3) == 0)
791     return 1;
792   if (strncmp (line, "val", 3) == 0)
793     return 1;
794   if (strncmp (line, "scl", 3) == 0)
795     return 1;
796   if (strncmp (line, "line", 4) == 0)
797     return 1;
798   if (strncmp (line, "endef", 5) == 0)
799     return 1;
800   if (strncmp (line, "ln", 2) == 0)
801     return 1;
802   if (strncmp (line, "type", 4) == 0)
803     return 1;
804   if (strncmp (line, "size", 4) == 0)
805     return 1;
806   if (strncmp (line, "dim", 3) == 0)
807     return 1;
808   if (strncmp (line, "tag", 3) == 0)
809     return 1;
810
811   if (strncmp (line, "stabs", 5) == 0)
812     return 1;
813   if (strncmp (line, "stabn", 5) == 0)
814     return 1;
815
816   return 0;
817
818 }
819
820 static void
821 listing_listing (name)
822      char *name;
823 {
824   list_info_type *list = head;
825   file_info_type *current_hll_file = (file_info_type *) NULL;
826   char *message;
827   char *buffer;
828   char *p;
829   int show_listing = 1;
830   unsigned int width;
831
832   buffer = xmalloc (LISTING_RHS_WIDTH);
833   eject = 1;
834   list = head;
835
836   while (list != (list_info_type *) NULL && 0)
837     {
838       if (list->next)
839         list->frag = list->next->frag;
840       list = list->next;
841
842     }
843
844   list = head->next;
845
846
847   while (list)
848     {
849       width = LISTING_RHS_WIDTH > paper_width ? paper_width :
850         LISTING_RHS_WIDTH;
851
852       switch (list->edict)
853         {
854         case EDICT_LIST:
855           show_listing++;
856           break;
857         case EDICT_NOLIST:
858           show_listing--;
859           break;
860         case EDICT_EJECT:
861           break;
862         case EDICT_NONE:
863           break;
864         case EDICT_TITLE:
865           title = list->edict_arg;
866           break;
867         case EDICT_SBTTL:
868           subtitle = list->edict_arg;
869           break;
870         default:
871           abort ();
872         }
873
874       if (show_listing > 0)
875         {
876           /* Scan down the list and print all the stuff which can be done
877              with this line (or lines).  */
878           message = 0;
879
880           if (list->hll_file)
881             {
882               current_hll_file = list->hll_file;
883             }
884
885           if (current_hll_file && list->hll_line && listing & LISTING_HLL)
886             {
887               print_source (current_hll_file, list, buffer, width);
888             }
889
890           while (list->file->file
891                  && list->file->linenum < list->line
892                  && !list->file->at_end)
893             {
894               p = buffer_line (list->file, buffer, width);
895
896               if (!((listing & LISTING_NODEBUG) && debugging_pseudo (p)))
897                 {
898                   print_lines (list, p, calc_hex (list));
899                 }
900             }
901
902           if (list->edict == EDICT_EJECT)
903             {
904               eject = 1;
905             }
906         }
907       else
908         {
909           while (list->file->file
910                  && list->file->linenum < list->line
911                  && !list->file->at_end)
912             p = buffer_line (list->file, buffer, width);
913         }
914
915       list = list->next;
916     }
917   free (buffer);
918 }
919
920 void
921 listing_print (name)
922      char *name;
923 {
924   title = "";
925   subtitle = "";
926
927   if (listing & LISTING_NOFORM)
928     {
929       paper_height = 0;
930     }
931
932   if (listing & LISTING_LISTING)
933     {
934       listing_listing (name);
935
936     }
937   if (listing & LISTING_SYMBOLS)
938     {
939       list_symbol_table ();
940     }
941 }
942
943
944 void
945 listing_file (name)
946      const char *name;
947 {
948   fn = name;
949 }
950
951 void
952 listing_eject (ignore)
953      int ignore;
954 {
955   listing_tail->edict = EDICT_EJECT;
956 }
957
958 void
959 listing_flags (ignore)
960      int ignore;
961 {
962   while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
963     input_line_pointer++;
964
965 }
966
967 void
968 listing_list (on)
969      int on;
970 {
971   listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
972 }
973
974
975 void
976 listing_psize (ignore)
977      int ignore;
978 {
979   paper_height = get_absolute_expression ();
980
981   if (paper_height < 0 || paper_height > 1000)
982     {
983       paper_height = 0;
984       as_warn ("strange paper height, set to no form");
985     }
986   if (*input_line_pointer == ',')
987     {
988       input_line_pointer++;
989       paper_width = get_absolute_expression ();
990     }
991 }
992
993
994 void
995 listing_title (depth)
996      int depth;
997 {
998   char *start;
999   char *ttl;
1000   unsigned int length;
1001
1002   SKIP_WHITESPACE ();
1003   if (*input_line_pointer == '\"')
1004     {
1005       input_line_pointer++;
1006       start = input_line_pointer;
1007
1008       while (*input_line_pointer)
1009         {
1010           if (*input_line_pointer == '\"')
1011             {
1012               length = input_line_pointer - start;
1013               ttl = xmalloc (length + 1);
1014               memcpy (ttl, start, length);
1015               ttl[length] = 0;
1016               listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1017               listing_tail->edict_arg = ttl;
1018               input_line_pointer++;
1019               demand_empty_rest_of_line ();
1020               return;
1021             }
1022           else if (*input_line_pointer == '\n')
1023             {
1024               as_bad ("New line in title");
1025               demand_empty_rest_of_line ();
1026               return;
1027             }
1028           else
1029             {
1030               input_line_pointer++;
1031             }
1032         }
1033     }
1034   else
1035     {
1036       as_bad ("expecting title in quotes");
1037     }
1038 }
1039
1040
1041
1042 void
1043 listing_source_line (line)
1044      unsigned int line;
1045 {
1046   new_frag ();
1047   listing_tail->hll_line = line;
1048   new_frag ();
1049
1050 }
1051
1052 void
1053 listing_source_file (file)
1054      const char *file;
1055 {
1056   if (listing_tail)
1057     listing_tail->hll_file = file_info (file);
1058 }
1059
1060
1061
1062 #else
1063
1064
1065 /* Dummy functions for when compiled without listing enabled */
1066
1067 void
1068 listing_flags (ignore)
1069      int ignore;
1070 {
1071   s_ignore (0);
1072 }
1073
1074 void 
1075 listing_list (on)
1076      int on;
1077 {
1078   s_ignore (0);
1079 }
1080
1081 void 
1082 listing_eject (ignore)
1083      int ignore;
1084 {
1085   s_ignore (0);
1086 }
1087
1088 void 
1089 listing_psize (ignore)
1090      int ignore;
1091 {
1092   s_ignore (0);
1093 }
1094
1095 void 
1096 listing_title (depth)
1097      int depth;
1098 {
1099   s_ignore (0);
1100 }
1101
1102 void
1103 listing_file (name)
1104      const char *name;
1105 {
1106
1107 }
1108
1109 void 
1110 listing_newline (name)
1111      char *name;
1112 {
1113
1114 }
1115
1116 void 
1117 listing_source_line (n)
1118      unsigned int n;
1119 {
1120
1121 }
1122 void 
1123 listing_source_file (n)
1124      const char *n;
1125 {
1126
1127 }
1128
1129 #endif