* listing.c (list_symbol_table): Build a format string based on the size of the
[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 end_pending;
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->end_pending = 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)
383     {
384       return "";
385     }
386
387   if (file->linenum == 0)
388     rewind (file->file);
389
390   if (file->end_pending == 10)
391     {
392       *p++ = '\n';
393 #if 1
394       fseek (file->file, 0, 0);
395       file->linenum = 0;
396 #else
397       file->linenum = 9999999;
398 #endif
399       file->end_pending = 0;
400     }
401   c = fgetc (file->file);
402
403
404   size -= 1;                    /* leave room for null */
405
406   while (c != EOF && c != '\n')
407     {
408       if (count < size)
409         *p++ = c;
410       count++;
411
412       c = fgetc (file->file);
413
414     }
415   if (c == EOF)
416     {
417       file->end_pending++;
418       *p++ = '.';
419       *p++ = '.';
420       *p++ = '.';
421     }
422   file->linenum++;
423   *p++ = 0;
424   return line;
425 }
426
427
428 static const char *fn;
429
430 static unsigned int eject;      /* Eject pending */
431 static unsigned int page;       /* Current page number */
432 static char *title;             /* current title */
433 static char *subtitle;          /* current subtitle */
434 static unsigned int on_page;    /* number of lines printed on current page */
435
436
437 static void
438 listing_page (list)
439      list_info_type *list;
440 {
441   /* Grope around, see if we can see a title or subtitle edict coming up
442      soon  (we look down 10 lines of the page and see if it's there)*/
443   if ((eject || (on_page >= paper_height)) && paper_height != 0)
444     {
445       unsigned int c = 10;
446       int had_title = 0;
447       int had_subtitle = 0;
448
449       page++;
450
451       while (c != 0 && list)
452         {
453           if (list->edict == EDICT_SBTTL && !had_subtitle)
454             {
455               had_subtitle = 1;
456               subtitle = list->edict_arg;
457             }
458           if (list->edict == EDICT_TITLE && !had_title)
459             {
460               had_title = 1;
461               title = list->edict_arg;
462             }
463           list = list->next;
464           c--;
465         }
466
467
468       if (page > 1)
469         {
470           printf ("\f");
471         }
472
473       printf ("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
474       printf ("%s\n", title);
475       printf ("%s\n", subtitle);
476       on_page = 3;
477       eject = 0;
478     }
479 }
480
481
482 static unsigned int
483 calc_hex (list)
484      list_info_type * list;
485 {
486   list_info_type *first = list;
487   unsigned int address = (unsigned int) ~0;
488
489   fragS *frag;
490   fragS *frag_ptr;
491
492   unsigned int byte_in_frag;
493
494
495   /* Find first frag which says it belongs to this line */
496   frag = list->frag;
497   while (frag && frag->line != list)
498     frag = frag->fr_next;
499
500   frag_ptr = frag;
501
502   data_buffer_size = 0;
503
504   /* Dump all the frags which belong to this line */
505   while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
506     {
507       /* Print as many bytes from the fixed part as is sensible */
508       byte_in_frag = 0;
509       while (byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof (data_buffer) - 10)
510         {
511           if (address == ~0)
512             {
513               address = frag_ptr->fr_address;
514             }
515
516           sprintf (data_buffer + data_buffer_size,
517                    "%02X",
518                    (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
519           data_buffer_size += 2;
520           byte_in_frag++;
521         }
522       {
523         unsigned int var_rep_max = byte_in_frag;
524         unsigned int var_rep_idx = byte_in_frag;
525
526         /* Print as many bytes from the variable part as is sensible */
527         while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
528                && data_buffer_size < sizeof (data_buffer) - 10)
529           {
530             if (address == ~0)
531               {
532                 address = frag_ptr->fr_address;
533               }
534             sprintf (data_buffer + data_buffer_size,
535                      "%02X",
536                      (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
537 #if 0
538             data_buffer[data_buffer_size++] = '*';
539             data_buffer[data_buffer_size++] = '*';
540 #endif
541             data_buffer_size += 2;
542
543             var_rep_idx++;
544             byte_in_frag++;
545
546             if (var_rep_idx >= frag_ptr->fr_var)
547               var_rep_idx = var_rep_max;
548           }
549       }
550
551       frag_ptr = frag_ptr->fr_next;
552     }
553   data_buffer[data_buffer_size++] = 0;
554   return address;
555 }
556
557
558
559
560
561
562 static void
563 print_lines (list, string, address)
564      list_info_type *list;
565      char *string;
566      unsigned int address;
567 {
568   unsigned int idx;
569   unsigned int nchars;
570   unsigned int lines;
571   unsigned int byte_in_word = 0;
572   char *src = data_buffer;
573
574   /* Print the stuff on the first line */
575   listing_page (list);
576   nchars = (LISTING_WORD_SIZE * 2 + 1) * LISTING_LHS_WIDTH;
577   /* Print the hex for the first line */
578   if (address == ~0)
579     {
580       printf ("% 4d     ", list->line);
581       for (idx = 0; idx < nchars; idx++)
582         printf (" ");
583
584       printf ("\t%s\n", string ? string : "");
585       on_page++;
586       listing_page (0);
587
588     }
589   else
590     {
591       if (had_errors ())
592         {
593           printf ("% 4d ???? ", list->line);
594         }
595       else
596         {
597           printf ("% 4d %04x ", list->line, address);
598         }
599
600       /* And the data to go along with it */
601       idx = 0;
602
603       while (*src && idx < nchars)
604         {
605           printf ("%c%c", src[0], src[1]);
606           src += 2;
607           byte_in_word++;
608           if (byte_in_word == LISTING_WORD_SIZE)
609             {
610               printf (" ");
611               idx++;
612               byte_in_word = 0;
613             }
614           idx += 2;
615         }
616
617       for (; idx < nchars; idx++)
618         printf (" ");
619
620       printf ("\t%s\n", string ? string : "");
621       on_page++;
622       listing_page (list);
623       if (list->message)
624         {
625           printf ("****  %s\n", list->message);
626           listing_page (list);
627           on_page++;
628         }
629
630       for (lines = 0;
631            lines < LISTING_LHS_CONT_LINES
632            && *src;
633            lines++)
634         {
635           nchars = ((LISTING_WORD_SIZE * 2) + 1) * LISTING_LHS_WIDTH_SECOND - 1;
636           idx = 0;
637           /* Print any more lines of data, but more compactly */
638           printf ("% 4d      ", list->line);
639
640           while (*src && idx < nchars)
641             {
642               printf ("%c%c", src[0], src[1]);
643               src += 2;
644               idx += 2;
645               byte_in_word++;
646               if (byte_in_word == LISTING_WORD_SIZE)
647                 {
648                   printf (" ");
649                   idx++;
650                   byte_in_word = 0;
651                 }
652             }
653
654           printf ("\n");
655           on_page++;
656           listing_page (list);
657
658         }
659
660
661     }
662 }
663
664
665 static void
666 list_symbol_table ()
667 {
668   extern symbolS *symbol_rootP;
669   int got_some = 0;
670
671   symbolS *ptr;
672   eject = 1;
673   listing_page (0);
674
675   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
676     {
677       if (ptr->sy_frag->line)
678         {
679           if (S_GET_NAME (ptr))
680             {
681               char buf[30], fmt[8];
682               valueT val = S_GET_VALUE (ptr);
683
684               /* @@ Note that this is dependent on the compilation options,
685                  not solely on the target characteristics.  */
686               if (sizeof (val) == 4 && sizeof (int) == 4)
687                 sprintf (buf, "%08lx", (unsigned long) val);
688               else if (sizeof (val) <= sizeof (unsigned long))
689                 {
690                   sprintf (fmt, "%%0%dlx", sizeof (val) * 2);
691                   sprintf (buf, fmt, (unsigned long) val);
692                 }
693 #if defined (BFD64)
694               else if (sizeof (val) > 4)
695                 {
696                   char buf1[30];
697                   sprintf_vma (buf1, val);
698                   strcpy (buf, "00000000");
699                   strcpy (buf + 8 - strlen (buf1), buf1);
700                 }
701 #endif
702               else
703                 abort ();
704
705               if (!got_some)
706                 {
707                   printf ("DEFINED SYMBOLS\n");
708                   on_page++;
709                   got_some = 1;
710                 }
711
712               printf ("%20s:%-5d  %s:%s %s\n",
713                       ptr->sy_frag->line->file->filename,
714                       ptr->sy_frag->line->line,
715                       segment_name (S_GET_SEGMENT (ptr)),
716                       buf, S_GET_NAME (ptr));
717
718               on_page++;
719               listing_page (0);
720             }
721         }
722
723     }
724   if (!got_some)
725     {
726       printf ("NO DEFINED SYMBOLS\n");
727       on_page++;
728     }
729   printf ("\n");
730   on_page++;
731   listing_page (0);
732
733   got_some = 0;
734
735   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
736     {
737       if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
738         {
739           if (ptr->sy_frag->line == 0
740 #ifdef S_IS_REGISTER
741               && !S_IS_REGISTER (ptr)
742 #endif
743               && S_GET_SEGMENT (ptr) != reg_section)
744             {
745               if (!got_some)
746                 {
747                   got_some = 1;
748                   printf ("UNDEFINED SYMBOLS\n");
749                   on_page++;
750                   listing_page (0);
751                 }
752               printf ("%s\n", S_GET_NAME (ptr));
753               on_page++;
754               listing_page (0);
755             }
756         }
757     }
758   if (!got_some)
759     {
760       printf ("NO UNDEFINED SYMBOLS\n");
761       on_page++;
762       listing_page (0);
763     }
764 }
765
766 static void
767 print_source (current_file, list, buffer, width)
768      file_info_type *current_file;
769      list_info_type *list;
770      char *buffer;
771      unsigned int width;
772 {
773   if (current_file->file)
774     {
775       while (current_file->linenum < list->hll_line
776              && current_file->end_pending == 0)
777         {
778           char *p = buffer_line (current_file, buffer, width);
779           printf ("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
780           on_page++;
781           listing_page (list);
782         }
783     }
784 }
785
786 /* Sometimes the user doesn't want to be bothered by the debugging
787    records inserted by the compiler, see if the line is suspicious */
788
789 static int
790 debugging_pseudo (line)
791      char *line;
792 {
793   while (isspace (*line))
794     line++;
795
796   if (*line != '.')
797     return 0;
798
799   line++;
800
801   if (strncmp (line, "def", 3) == 0)
802     return 1;
803   if (strncmp (line, "val", 3) == 0)
804     return 1;
805   if (strncmp (line, "scl", 3) == 0)
806     return 1;
807   if (strncmp (line, "line", 4) == 0)
808     return 1;
809   if (strncmp (line, "endef", 5) == 0)
810     return 1;
811   if (strncmp (line, "ln", 2) == 0)
812     return 1;
813   if (strncmp (line, "type", 4) == 0)
814     return 1;
815   if (strncmp (line, "size", 4) == 0)
816     return 1;
817   if (strncmp (line, "dim", 3) == 0)
818     return 1;
819   if (strncmp (line, "tag", 3) == 0)
820     return 1;
821
822   if (strncmp (line, "stabs", 5) == 0)
823     return 1;
824   if (strncmp (line, "stabn", 5) == 0)
825     return 1;
826
827   return 0;
828
829 }
830
831 static void
832 listing_listing (name)
833      char *name;
834 {
835   list_info_type *list = head;
836   file_info_type *current_hll_file = (file_info_type *) NULL;
837   char *message;
838   char *buffer;
839   char *p;
840   int show_listing = 1;
841   unsigned int width;
842
843   buffer = xmalloc (LISTING_RHS_WIDTH);
844   eject = 1;
845   list = head;
846
847   while (list != (list_info_type *) NULL && 0)
848     {
849       if (list->next)
850         list->frag = list->next->frag;
851       list = list->next;
852
853     }
854
855   list = head->next;
856
857
858   while (list)
859     {
860       width = LISTING_RHS_WIDTH > paper_width ? paper_width :
861         LISTING_RHS_WIDTH;
862
863       switch (list->edict)
864         {
865         case EDICT_LIST:
866           show_listing++;
867           break;
868         case EDICT_NOLIST:
869           show_listing--;
870           break;
871         case EDICT_EJECT:
872           break;
873         case EDICT_NONE:
874           break;
875         case EDICT_TITLE:
876           title = list->edict_arg;
877           break;
878         case EDICT_SBTTL:
879           subtitle = list->edict_arg;
880           break;
881         default:
882           abort ();
883         }
884
885       if (show_listing > 0)
886         {
887           /* Scan down the list and print all the stuff which can be done
888              with this line (or lines).  */
889           message = 0;
890
891           if (list->hll_file)
892             {
893               current_hll_file = list->hll_file;
894             }
895
896           if (current_hll_file && list->hll_line && listing & LISTING_HLL)
897             {
898               print_source (current_hll_file, list, buffer, width);
899             }
900
901           while (list->file->file
902                  && list->file->linenum < list->line
903                  && !list->file->end_pending)
904             {
905               p = buffer_line (list->file, buffer, width);
906
907               if (!((listing & LISTING_NODEBUG) && debugging_pseudo (p)))
908                 {
909                   print_lines (list, p, calc_hex (list));
910                 }
911             }
912
913           if (list->edict == EDICT_EJECT)
914             {
915               eject = 1;
916             }
917         }
918       else
919         {
920           while (list->file->file
921                  && list->file->linenum < list->line
922                  && !list->file->end_pending)
923             p = buffer_line (list->file, buffer, width);
924         }
925
926       list = list->next;
927     }
928   free (buffer);
929 }
930
931 void
932 listing_print (name)
933      char *name;
934 {
935   title = "";
936   subtitle = "";
937
938   if (listing & LISTING_NOFORM)
939     {
940       paper_height = 0;
941     }
942
943   if (listing & LISTING_LISTING)
944     {
945       listing_listing (name);
946
947     }
948   if (listing & LISTING_SYMBOLS)
949     {
950       list_symbol_table ();
951     }
952 }
953
954
955 void
956 listing_file (name)
957      const char *name;
958 {
959   fn = name;
960 }
961
962 void
963 listing_eject (ignore)
964      int ignore;
965 {
966   listing_tail->edict = EDICT_EJECT;
967 }
968
969 void
970 listing_flags (ignore)
971      int ignore;
972 {
973   while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
974     input_line_pointer++;
975
976 }
977
978 void
979 listing_list (on)
980      int on;
981 {
982   listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
983 }
984
985
986 void
987 listing_psize (ignore)
988      int ignore;
989 {
990   paper_height = get_absolute_expression ();
991
992   if (paper_height < 0 || paper_height > 1000)
993     {
994       paper_height = 0;
995       as_warn ("strange paper height, set to no form");
996     }
997   if (*input_line_pointer == ',')
998     {
999       input_line_pointer++;
1000       paper_width = get_absolute_expression ();
1001     }
1002 }
1003
1004
1005 void
1006 listing_title (depth)
1007      int depth;
1008 {
1009   char *start;
1010   char *ttl;
1011   unsigned int length;
1012
1013   SKIP_WHITESPACE ();
1014   if (*input_line_pointer == '\"')
1015     {
1016       input_line_pointer++;
1017       start = input_line_pointer;
1018
1019       while (*input_line_pointer)
1020         {
1021           if (*input_line_pointer == '\"')
1022             {
1023               length = input_line_pointer - start;
1024               ttl = xmalloc (length + 1);
1025               memcpy (ttl, start, length);
1026               ttl[length] = 0;
1027               listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1028               listing_tail->edict_arg = ttl;
1029               input_line_pointer++;
1030               demand_empty_rest_of_line ();
1031               return;
1032             }
1033           else if (*input_line_pointer == '\n')
1034             {
1035               as_bad ("New line in title");
1036               demand_empty_rest_of_line ();
1037               return;
1038             }
1039           else
1040             {
1041               input_line_pointer++;
1042             }
1043         }
1044     }
1045   else
1046     {
1047       as_bad ("expecting title in quotes");
1048     }
1049 }
1050
1051
1052
1053 void
1054 listing_source_line (line)
1055      unsigned int line;
1056 {
1057   new_frag ();
1058   listing_tail->hll_line = line;
1059   new_frag ();
1060
1061 }
1062
1063 void
1064 listing_source_file (file)
1065      const char *file;
1066 {
1067   if (listing_tail)
1068     listing_tail->hll_file = file_info (file);
1069 }
1070
1071
1072
1073 #else
1074
1075
1076 /* Dummy functions for when compiled without listing enabled */
1077
1078 void
1079 listing_flags (ignore)
1080      int ignore;
1081 {
1082   s_ignore (0);
1083 }
1084
1085 void 
1086 listing_list (on)
1087      int on;
1088 {
1089   s_ignore (0);
1090 }
1091
1092 void 
1093 listing_eject (ignore)
1094      int ignore;
1095 {
1096   s_ignore (0);
1097 }
1098
1099 void 
1100 listing_psize (ignore)
1101      int ignore;
1102 {
1103   s_ignore (0);
1104 }
1105
1106 void 
1107 listing_title (depth)
1108      int depth;
1109 {
1110   s_ignore (0);
1111 }
1112
1113 void
1114 listing_file (name)
1115      const char *name;
1116 {
1117
1118 }
1119
1120 void 
1121 listing_newline (name)
1122      char *name;
1123 {
1124
1125 }
1126
1127 void 
1128 listing_source_line (n)
1129      unsigned int n;
1130 {
1131
1132 }
1133 void 
1134 listing_source_file (n)
1135      const char *n;
1136 {
1137
1138 }
1139
1140 #endif