* listing.c (list_symbol_table): Don't print register symbols as undefined.
[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
135 file_info_type;
136
137
138 /* this structure rememebrs which line from which file goes into which
139    frag */
140 typedef struct list_info_struct
141 {
142   /* Frag which this line of source is nearest to */
143   fragS *frag;
144   /* The actual line in the source file */
145   unsigned int line;
146   /* Pointer to the file info struct for the file which this line
147      belongs to */
148   file_info_type *file;
149
150   /* Next in list */
151   struct list_info_struct *next;
152
153
154   /* Pointer to the file info struct for the high level language
155      source line that belongs here */
156   file_info_type *hll_file;
157
158   /* High level language source line */
159   int hll_line;
160
161
162   /* Pointer to any error message associated with this line */
163   char *message;
164
165   enum
166     {
167       EDICT_NONE,
168       EDICT_SBTTL,
169       EDICT_TITLE,
170       EDICT_NOLIST,
171       EDICT_LIST,
172       EDICT_EJECT
173     } edict;
174   char *edict_arg;
175
176 }
177
178 list_info_type;
179
180
181 static struct list_info_struct *head;
182 struct list_info_struct *listing_tail;
183 extern int listing;
184 extern fragS *frag_now;
185
186
187 static int paper_width = 200;
188 static int paper_height = 60;
189
190
191 /* this static array is used to keep the text of data to be printed
192    before the start of the line.
193     It is stored so we can give a bit more info on the next line.  To much, and large
194    initialized arrays will use up lots of paper.
195  */
196
197 static char data_buffer[100];
198 static unsigned int data_buffer_size;
199
200
201 /* Prototypes.  */
202 static void listing_message PARAMS ((const char *name, const char *message));
203 static file_info_type *file_info PARAMS ((const char *file_name));
204 static void new_frag PARAMS ((void));
205 static char *buffer_line PARAMS ((file_info_type *file,
206                                   char *line, unsigned int size));
207 static void listing_page PARAMS ((list_info_type *list));
208 static unsigned int calc_hex PARAMS ((list_info_type *list));
209 static void print_lines PARAMS ((list_info_type *list,
210                                  char *string,
211                                  unsigned int address));
212 static void list_symbol_table PARAMS ((void));
213 static void print_source PARAMS ((file_info_type *current_file,
214                                   list_info_type *list,
215                                   char *buffer,
216                                   unsigned int width));
217 static int debugging_pseudo PARAMS ((char *line));
218 static void listing_listing PARAMS ((char *name));
219
220
221 static void
222 listing_message (name, message)
223      const char *name;
224      const char *message;
225 {
226   unsigned int l = strlen (name) + strlen (message) + 1;
227   char *n = (char *) xmalloc (l);
228   strcpy (n, name);
229   strcat (n, message);
230   if (listing_tail != (list_info_type *) NULL)
231     {
232       listing_tail->message = n;
233     }
234
235 }
236
237
238
239
240 void
241 listing_warning (message)
242      const char *message;
243 {
244   listing_message ("Warning:", message);
245 }
246
247 void
248 listing_error (message)
249      const char *message;
250 {
251   listing_message ("Error:", message);
252 }
253
254
255
256
257 static file_info_type *file_info_head;
258
259 static file_info_type *
260 file_info (file_name)
261      const char *file_name;
262 {
263   /* Find an entry with this file name */
264   file_info_type *p = file_info_head;
265
266   while (p != (file_info_type *) NULL)
267     {
268       if (strcmp (p->filename, file_name) == 0)
269         return p;
270       p = p->next;
271     }
272
273   /* Make new entry */
274
275   p = (file_info_type *) xmalloc (sizeof (file_info_type));
276   p->next = file_info_head;
277   file_info_head = p;
278   p->filename = xmalloc ((unsigned long) strlen (file_name) + 1);
279   strcpy (p->filename, file_name);
280   p->linenum = 0;
281   p->end_pending = 0;
282
283   /* Do we really prefer binary mode for this??  */
284   p->file = fopen (p->filename, FOPEN_RB);
285   if (p->file)
286     fgetc (p->file);
287
288   return p;
289 }
290
291
292 static void
293 new_frag ()
294 {
295
296   frag_wane (frag_now);
297   frag_new (0);
298
299 }
300
301 void
302 listing_newline (ps)
303      char *ps;
304 {
305   char *file;
306   unsigned int line;
307   static unsigned int last_line = 0xffff;
308   list_info_type *new;
309
310   as_where (&file, &line);
311   if (line != last_line)
312     {
313       last_line = line;
314       new_frag ();
315
316       new = (list_info_type *) xmalloc (sizeof (list_info_type));
317       new->frag = frag_now;
318       new->line = line;
319       new->file = file_info (file);
320
321       if (listing_tail)
322         {
323           listing_tail->next = new;
324         }
325       else
326         {
327           head = new;
328         }
329       listing_tail = new;
330       new->next = (list_info_type *) NULL;
331       new->message = (char *) NULL;
332       new->edict = EDICT_NONE;
333       new->hll_file = (file_info_type *) NULL;
334       new->hll_line = 0;
335       new_frag ();
336     }
337 }
338
339 /* Attach all current frags to the previous line instead of the
340    current line.  This is called by the MIPS backend when it discovers
341    that it needs to add some NOP instructions; the added NOP
342    instructions should go with the instruction that has the delay, not
343    with the new instruction.  */
344
345 void
346 listing_prev_line ()
347 {
348   list_info_type *l;
349   fragS *f;
350
351   if (head == (list_info_type *) NULL
352       || head == listing_tail)
353     return;
354
355   new_frag ();
356
357   for (l = head; l->next != listing_tail; l = l->next)
358     ;
359
360   for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
361     if (f->line == listing_tail)
362       f->line = l;
363
364   listing_tail->frag = frag_now;
365   new_frag ();
366 }
367
368 /*
369  This function returns the next source line from the file supplied,
370  truncated to size.  It appends a fake line to the end of each input
371  file to make
372 */
373
374 static char *
375 buffer_line (file, line, size)
376      file_info_type * file;
377      char *line;
378      unsigned int size;
379 {
380   unsigned int count = 0;
381   int c;
382
383   char *p = line;
384
385   /* If we couldn't open the file, return an empty line */
386   if (file->file == (FILE *) NULL)
387     {
388       return "";
389     }
390
391   if (file->linenum == 0)
392     rewind (file->file);
393
394   if (file->end_pending == 10)
395     {
396       *p++ = '\n';
397       fseek (file->file, 0, 0);
398       file->linenum = 0;
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
670   symbolS *ptr;
671   eject = 1;
672   listing_page (0);
673   printf ("DEFINED SYMBOLS\n");
674   on_page++;
675
676   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
677     {
678       if (ptr->sy_frag->line)
679         {
680           if (S_GET_NAME (ptr))
681             {
682               char buf[30];
683               valueT val = S_GET_VALUE (ptr);
684
685               /* @@ Note that this is dependent on the compilation options,
686                  not solely on the target characteristics.  */
687               if (sizeof (val) == 4 && sizeof (int) == 4)
688                 sprintf (buf, "%08lx", (unsigned long) val);
689 #if defined (BFD_ASSEMBLER) && defined (BFD64)
690               else if (sizeof (val) > 4)
691                 {
692                   char buf1[30];
693                   sprintf_vma (buf1, val);
694                   strcpy (buf, "00000000");
695                   strcpy (buf + 8 - strlen (buf1), buf1);
696                 }
697 #endif
698               else
699                 abort ();
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   printf ("\n");
714   on_page++;
715   listing_page (0);
716   printf ("UNDEFINED SYMBOLS\n");
717   on_page++;
718   listing_page (0);
719
720   for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
721     {
722       if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
723         {
724           if (ptr->sy_frag->line == 0
725               && S_GET_SEGMENT (ptr) != reg_section)
726             {
727               printf ("%s\n", S_GET_NAME (ptr));
728               on_page++;
729               listing_page (0);
730             }
731         }
732     }
733 }
734
735 static void
736 print_source (current_file, list, buffer, width)
737      file_info_type *current_file;
738      list_info_type *list;
739      char *buffer;
740      unsigned int width;
741 {
742   if (current_file->file)
743     {
744       while (current_file->linenum < list->hll_line)
745         {
746           char *p = buffer_line (current_file, buffer, width);
747           printf ("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
748           on_page++;
749           listing_page (list);
750         }
751     }
752 }
753
754 /* Sometimes the user doesn't want to be bothered by the debugging
755    records inserted by the compiler, see if the line is suspicious */
756
757 static int
758 debugging_pseudo (line)
759      char *line;
760 {
761   while (isspace (*line))
762     line++;
763
764   if (*line != '.')
765     return 0;
766
767   line++;
768
769   if (strncmp (line, "def", 3) == 0)
770     return 1;
771   if (strncmp (line, "val", 3) == 0)
772     return 1;
773   if (strncmp (line, "scl", 3) == 0)
774     return 1;
775   if (strncmp (line, "line", 4) == 0)
776     return 1;
777   if (strncmp (line, "endef", 5) == 0)
778     return 1;
779   if (strncmp (line, "ln", 2) == 0)
780     return 1;
781   if (strncmp (line, "type", 4) == 0)
782     return 1;
783   if (strncmp (line, "size", 4) == 0)
784     return 1;
785   if (strncmp (line, "dim", 3) == 0)
786     return 1;
787   if (strncmp (line, "tag", 3) == 0)
788     return 1;
789
790   if (strncmp (line, "stabs", 5) == 0)
791     return 1;
792   if (strncmp (line, "stabn", 5) == 0)
793     return 1;
794
795   return 0;
796
797 }
798
799 static void
800 listing_listing (name)
801      char *name;
802 {
803   list_info_type *list = head;
804   file_info_type *current_hll_file = (file_info_type *) NULL;
805   char *message;
806   char *buffer;
807   char *p;
808   int show_listing = 1;
809   unsigned int width;
810
811   buffer = xmalloc (LISTING_RHS_WIDTH);
812   eject = 1;
813   list = head;
814
815   while (list != (list_info_type *) NULL && 0)
816     {
817       if (list->next)
818         list->frag = list->next->frag;
819       list = list->next;
820
821     }
822
823   list = head->next;
824
825
826   while (list)
827     {
828       width = LISTING_RHS_WIDTH > paper_width ? paper_width :
829         LISTING_RHS_WIDTH;
830
831       switch (list->edict)
832         {
833         case EDICT_LIST:
834           show_listing++;
835           break;
836         case EDICT_NOLIST:
837           show_listing--;
838           break;
839         case EDICT_EJECT:
840           break;
841         case EDICT_NONE:
842           break;
843         case EDICT_TITLE:
844           title = list->edict_arg;
845           break;
846         case EDICT_SBTTL:
847           subtitle = list->edict_arg;
848           break;
849         default:
850           abort ();
851         }
852
853       if (show_listing > 0)
854         {
855           /* Scan down the list and print all the stuff which can be done
856              with this line (or lines).  */
857           message = 0;
858
859           if (list->hll_file)
860             {
861               current_hll_file = list->hll_file;
862             }
863
864           if (current_hll_file && list->hll_line && listing & LISTING_HLL)
865             {
866               print_source (current_hll_file, list, buffer, width);
867             }
868
869           p = buffer_line (list->file, buffer, width);
870
871           if (!((listing & LISTING_NODEBUG) && debugging_pseudo (p)))
872             {
873               print_lines (list, p, calc_hex (list));
874             }
875
876           if (list->edict == EDICT_EJECT)
877             {
878               eject = 1;
879             }
880         }
881       else
882         {
883
884           p = buffer_line (list->file, buffer, width);
885         }
886
887       list = list->next;
888     }
889   free (buffer);
890 }
891
892 void
893 listing_print (name)
894      char *name;
895 {
896   title = "";
897   subtitle = "";
898
899   if (listing & LISTING_NOFORM)
900     {
901       paper_height = 0;
902     }
903
904   if (listing & LISTING_LISTING)
905     {
906       listing_listing (name);
907
908     }
909   if (listing & LISTING_SYMBOLS)
910     {
911       list_symbol_table ();
912     }
913 }
914
915
916 void
917 listing_file (name)
918      const char *name;
919 {
920   fn = name;
921 }
922
923 void
924 listing_eject (ignore)
925      int ignore;
926 {
927   listing_tail->edict = EDICT_EJECT;
928 }
929
930 void
931 listing_flags (ignore)
932      int ignore;
933 {
934   while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
935     input_line_pointer++;
936
937 }
938
939 void
940 listing_list (on)
941      int on;
942 {
943   listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
944 }
945
946
947 void
948 listing_psize (ignore)
949      int ignore;
950 {
951   paper_height = get_absolute_expression ();
952
953   if (paper_height < 0 || paper_height > 1000)
954     {
955       paper_height = 0;
956       as_warn ("strange paper height, set to no form");
957     }
958   if (*input_line_pointer == ',')
959     {
960       input_line_pointer++;
961       paper_width = get_absolute_expression ();
962     }
963 }
964
965
966 void
967 listing_title (depth)
968      int depth;
969 {
970   char *start;
971   char *ttl;
972   unsigned int length;
973
974   SKIP_WHITESPACE ();
975   if (*input_line_pointer == '\"')
976     {
977       input_line_pointer++;
978       start = input_line_pointer;
979
980       while (*input_line_pointer)
981         {
982           if (*input_line_pointer == '\"')
983             {
984               length = input_line_pointer - start;
985               ttl = xmalloc (length + 1);
986               memcpy (ttl, start, length);
987               ttl[length] = 0;
988               listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
989               listing_tail->edict_arg = ttl;
990               input_line_pointer++;
991               demand_empty_rest_of_line ();
992               return;
993             }
994           else if (*input_line_pointer == '\n')
995             {
996               as_bad ("New line in title");
997               demand_empty_rest_of_line ();
998               return;
999             }
1000           else
1001             {
1002               input_line_pointer++;
1003             }
1004         }
1005     }
1006   else
1007     {
1008       as_bad ("expecting title in quotes");
1009     }
1010 }
1011
1012
1013
1014 void
1015 listing_source_line (line)
1016      unsigned int line;
1017 {
1018   new_frag ();
1019   listing_tail->hll_line = line;
1020   new_frag ();
1021
1022 }
1023
1024 void
1025 listing_source_file (file)
1026      const char *file;
1027 {
1028   if (listing_tail)
1029     listing_tail->hll_file = file_info (file);
1030 }
1031
1032
1033
1034 #else
1035
1036
1037 /* Dummy functions for when compiled without listing enabled */
1038
1039 void
1040 listing_flags (ignore)
1041      int ignore;
1042 {
1043   s_ignore (0);
1044 }
1045
1046 void 
1047 listing_list (on)
1048      int on;
1049 {
1050   s_ignore (0);
1051 }
1052
1053 void 
1054 listing_eject (ignore)
1055      int ignore;
1056 {
1057   s_ignore (0);
1058 }
1059
1060 void 
1061 listing_psize (ignore)
1062      int ignore;
1063 {
1064   s_ignore (0);
1065 }
1066
1067 void 
1068 listing_title (depth)
1069      int depth;
1070 {
1071   s_ignore (0);
1072 }
1073
1074 void
1075 listing_file (name)
1076      const char *name;
1077 {
1078
1079 }
1080
1081 void 
1082 listing_newline (name)
1083      char *name;
1084 {
1085
1086 }
1087
1088 void 
1089 listing_source_line (n)
1090      unsigned int n;
1091 {
1092
1093 }
1094 void 
1095 listing_source_file (n)
1096      const char *n;
1097 {
1098
1099 }
1100
1101 #endif