* app.c: MRI compatibility - allow single quote to start a string.
[binutils-gdb.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 "as.h"
95 #include <obstack.h>
96 #include "input-file.h"
97 #include "targ-cpu.h"
98
99 #ifndef NO_LISTING
100 #ifndef LISTING_HEADER
101 #define LISTING_HEADER "GAS LISTING"
102 #endif
103 #ifndef LISTING_WORD_SIZE
104 #define LISTING_WORD_SIZE 4
105 #endif
106 #ifndef LISTING_LHS_WIDTH
107 #define LISTING_LHS_WIDTH 1
108 #endif
109 #ifndef LISTING_LHS_WIDTH_SECOND
110 #define LISTING_LHS_WIDTH_SECOND 1
111 #endif
112 #ifndef LISTING_RHS_WIDTH
113 #define LISTING_RHS_WIDTH 100
114 #endif
115 #ifndef LISTING_LHS_CONT_LINES
116 #define LISTING_LHS_CONT_LINES 4
117 #endif
118
119
120
121
122 /* This structure remembers which .s were used */
123 typedef struct file_info_struct
124 {
125 char *filename;
126 int linenum;
127 FILE *file;
128 struct file_info_struct *next;
129 int end_pending;
130
131 } file_info_type ;
132
133
134 /* this structure rememebrs which line from which file goes into which
135 frag */
136 typedef struct list_info_struct
137 {
138 /* Frag which this line of source is nearest to */
139 fragS *frag;
140 /* The actual line in the source file */
141 unsigned int line;
142 /* Pointer to the file info struct for the file which this line
143 belongs to */
144 file_info_type *file;
145
146 /* Next in list */
147 struct list_info_struct *next;
148
149
150 /* Pointer to the file info struct for the high level language
151 source line that belongs here */
152 file_info_type *hll_file;
153
154 /* High level language source line */
155 int hll_line;
156
157
158 /* Pointer to any error message associated with this line */
159 char *message;
160
161 enum
162 {
163 EDICT_NONE,
164 EDICT_SBTTL,
165 EDICT_TITLE,
166 EDICT_NOLIST,
167 EDICT_LIST,
168 EDICT_EJECT
169 } edict;
170 char *edict_arg;
171
172 } list_info_type;
173
174
175 static struct list_info_struct *head;
176 struct list_info_struct *listing_tail;
177 extern int listing;
178 extern unsigned int physical_input_line;
179 extern fragS *frag_now;
180
181
182 static int paper_width = 200;
183 static int paper_height = 60;
184
185
186 /* this static array is used to keep the text of data to be printed
187 before the start of the line.
188 It is stored so we can give a bit more info on the next line. To much, and large
189 initialized arrays will use up lots of paper.
190 */
191
192 static char data_buffer[100];
193 static unsigned int data_buffer_size;
194
195
196 static void
197 DEFUN(listing_message,(name, message),
198 char *name AND
199 char *message)
200 {
201 unsigned int l = strlen(name) + strlen(message)+1;
202 char *n = malloc(l);
203 strcpy(n,name);
204 strcat(n,message);
205 if(listing_tail != (list_info_type *)NULL)
206 {
207 listing_tail->message = n;
208 }
209
210 }
211
212
213
214
215 void
216 DEFUN(listing_warning,(message),
217 char *message)
218 {
219 listing_message("Warning:", message);
220 }
221
222 void
223 DEFUN(listing_error,(message),
224 char *message)
225 {
226 listing_message("Error:", message);
227 }
228
229
230
231
232 static file_info_type *file_info_head;
233
234 static file_info_type *
235 DEFUN(file_info, (file_name),
236 char *file_name)
237 {
238 /* Find an entry with this file name */
239 file_info_type *p = file_info_head;
240
241 while (p != (file_info_type *)NULL)
242 {
243 if (strcmp(p->filename, file_name) == 0)
244 return p;
245 p = p->next;
246 }
247
248 /* Make new entry */
249
250 p = (file_info_type *)xmalloc(sizeof(file_info_type));
251 p->next = file_info_head;
252 file_info_head = p;
253 p->filename = xmalloc(strlen(file_name)+1);
254 strcpy(p->filename, file_name);
255 p->linenum = 0;
256 p->end_pending = 0;
257
258 p->file = fopen(p->filename,"r");
259 return p;
260
261 }
262
263
264 static void
265 DEFUN_VOID(new_frag)
266 {
267
268 frag_wane(frag_now);
269 frag_new(0);
270
271 }
272
273 void
274 DEFUN(listing_newline,(ps),
275 char *ps)
276 {
277 char *s = ps;
278 extern char *file_name;
279 static unsigned int last_line =0xffff ;
280
281
282 list_info_type *new;
283 if (physical_input_line != last_line)
284 {
285 last_line = physical_input_line;
286 new_frag();
287
288 new = (list_info_type *)malloc(sizeof(list_info_type));
289 new->frag = frag_now;
290 new->line = physical_input_line ;
291 new->file = file_info(file_name);
292
293 if (listing_tail)
294 {
295 listing_tail->next = new;
296 }
297 else
298 {
299 head = new;
300 }
301 listing_tail = new;
302 new->next = (list_info_type *)NULL;
303 new->message = (char *)NULL;
304 new->edict = EDICT_NONE;
305 new->hll_file = (file_info_type*)NULL;
306 new->hll_line = 0;
307 new_frag();
308 }
309 }
310
311
312 /*
313 This function returns the next source line from the file supplied,
314 truncated to size. It appends a fake line to the end of each input
315 file to make
316 */
317
318 static char *
319 DEFUN(buffer_line,(file, line, size),
320 file_info_type *file AND
321 char *line AND
322 unsigned int size)
323 {
324 unsigned int count = 0;
325 int c;
326
327 char *p = line;
328
329 /* If we couldn't open the file, return an empty line */
330 if (file->file == (FILE*)NULL)
331 {
332 return "";
333 }
334
335 if (file->end_pending == 10) {
336 *p ++ = '\n';
337 rewind(file->file);
338 file->linenum = 0;
339 file->end_pending = 0;
340 }
341 c = fgetc(file->file);
342 size -= 1; /* leave room for null */
343
344 while (c != EOF && c != '\n')
345 {
346 if (count < size)
347 *p++ = c;
348 count++;
349
350 c= fgetc(file->file);
351 }
352 if (c == EOF)
353 {
354 file->end_pending ++;
355 *p++ = 'E';
356 *p++ = 'O';
357 *p++ = 'F';
358 }
359 file->linenum++;
360 *p++ = 0;
361 return line;
362 }
363
364
365 static char *fn;
366
367 static unsigned int eject; /* Eject pending */
368 static unsigned int page; /* Current page number */
369 static char *title; /* current title */
370 static char *subtitle; /* current subtitle */
371 static unsigned int on_page; /* number of lines printed on current page */
372
373
374 static void
375 DEFUN(listing_page,(list),
376 list_info_type *list)
377 {
378 /* Grope around, see if we can see a title or subtitle edict coming up
379 soon (we look down 10 lines of the page and see if it's there)*/
380 if ((eject || (on_page >= paper_height)) && paper_height != 0)
381 {
382 unsigned int c = 10;
383 int had_title = 0;
384 int had_subtitle = 0;
385
386 page++;
387
388 while (c != 0 && list)
389 {
390 if (list->edict == EDICT_SBTTL && !had_subtitle)
391 {
392 had_subtitle = 1;
393 subtitle = list->edict_arg;
394 }
395 if (list->edict == EDICT_TITLE && !had_title)
396 {
397 had_title = 1;
398 title = list->edict_arg;
399 }
400 list = list->next;
401 c--;
402 }
403
404
405 if (page > 1)
406 {
407 printf("\f");
408 }
409
410 printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
411 printf("%s\n", title);
412 printf("%s\n", subtitle);
413 on_page = 3;
414 eject = 0;
415 }
416 }
417
418
419 static unsigned int
420 DEFUN(calc_hex,(list),
421 list_info_type *list)
422 {
423 list_info_type *first = list;
424 list_info_type *last = first;
425 unsigned int address = ~0;
426
427 fragS *frag;
428 fragS *frag_ptr;
429
430 unsigned int byte_in_frag = 0;
431
432 int anything = 0;
433
434 /* Find first frag which says it belongs to this line */
435 frag = list->frag;
436 while (frag && frag->line != list)
437 frag = frag->fr_next;
438
439 frag_ptr = frag;
440
441 data_buffer_size = 0;
442
443 /* Dump all the frags which belong to this line */
444 while (frag_ptr != (fragS *)NULL && frag_ptr->line == first)
445 {
446 /* Print as many bytes from the fixed part as is sensible */
447 while(byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10)
448 {
449 if (address == ~0)
450 {
451 address = frag_ptr->fr_address;
452 }
453
454 sprintf(data_buffer + data_buffer_size,
455 "%02X",
456 (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
457 data_buffer_size += 2;
458 byte_in_frag++;
459 }
460 {
461 unsigned int var_rep_max = byte_in_frag;
462 unsigned int var_rep_idx = byte_in_frag;
463
464 /* Print as many bytes from the variable part as is sensible */
465 while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
466 && data_buffer_size < sizeof(data_buffer)-10)
467 {
468 if (address == ~0)
469 {
470 address = frag_ptr->fr_address;
471 }
472 sprintf(data_buffer + data_buffer_size,
473 "%02X",
474 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
475 #if 0
476 data_buffer[data_buffer_size++] = '*';
477 data_buffer[data_buffer_size++] = '*';
478 #endif
479 data_buffer_size +=2;
480
481 var_rep_idx ++;
482 byte_in_frag++;
483
484 if (var_rep_idx >= frag_ptr->fr_var)
485 var_rep_idx = var_rep_max;
486 }
487 }
488
489 frag_ptr = frag_ptr->fr_next;
490 }
491 data_buffer[data_buffer_size++] = 0;
492 return address;
493 }
494
495
496
497
498
499
500 static void
501 DEFUN(print_lines,(list, string, address),
502 list_info_type *list AND
503 char *string AND
504 unsigned int address)
505 {
506 unsigned int idx;
507 unsigned int nchars;
508 unsigned int lines;
509 unsigned int byte_in_word =0;
510 char *src = data_buffer;
511
512 /* Print the stuff on the first line */
513 listing_page(list);
514 nchars = (LISTING_WORD_SIZE*2 +1) * LISTING_LHS_WIDTH ;
515 /* Print the hex for the first line */
516 if (address == ~0)
517 {
518 printf("% 4d ", list->line);
519 for (idx = 0; idx < nchars; idx++)
520 printf(" ");
521
522 printf("\t%s\n", string ? string : "");
523 on_page++;
524 listing_page(0);
525
526 }
527 else
528 {
529 if (had_errors())
530 {
531 printf("% 4d ???? ", list->line);
532 }
533 else
534 {
535 printf("% 4d %04x ", list->line, address);
536 }
537
538 /* And the data to go along with it */
539 idx = 0;
540
541 while (*src && idx < nchars)
542 {
543 printf("%c%c", src[0], src[1]);
544 src += 2;
545 byte_in_word++;
546 if (byte_in_word == LISTING_WORD_SIZE)
547 {
548 printf(" ");
549 idx++;
550 byte_in_word = 0;
551 }
552 idx+=2;
553 }
554
555 for (;idx < nchars; idx++)
556 printf(" ");
557
558 printf("\t%s\n", string ? string : "");
559 on_page++;
560 listing_page(list);
561 if (list->message)
562 {
563 printf("**** %s\n",list->message);
564 listing_page(list);
565 on_page++;
566 }
567
568 for (lines = 0;
569 lines < LISTING_LHS_CONT_LINES
570 && *src;
571 lines++) {
572 nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1;
573 idx = 0;
574 /* Print any more lines of data, but more compactly */
575 printf("% 4d ", list->line);
576
577 while (*src && idx < nchars)
578 {
579 printf("%c%c", src[0], src[1]);
580 src+=2;
581 idx+=2;
582 byte_in_word++;
583 if (byte_in_word == LISTING_WORD_SIZE)
584 {
585 printf(" ");
586 idx++;
587 byte_in_word = 0;
588 }
589 }
590
591 printf("\n");
592 on_page++;
593 listing_page(list);
594
595 }
596
597
598 }
599 }
600
601
602
603
604
605
606 static void
607 DEFUN_VOID(list_symbol_table)
608 {
609 extern symbolS *symbol_rootP;
610
611 symbolS *ptr ;
612 eject = 1;
613 listing_page(0);
614 printf("DEFINED SYMBOLS\n");
615 on_page++;
616
617 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
618 {
619 if (ptr->sy_frag->line)
620 {
621 if (strlen(S_GET_NAME(ptr)))
622 {
623 printf("%20s:%-5d %2d:%08x %s \n",
624 ptr->sy_frag->line->file->filename,
625 ptr->sy_frag->line->line,
626 S_GET_SEGMENT(ptr),
627 S_GET_VALUE(ptr),
628 S_GET_NAME(ptr));
629
630 on_page++;
631 listing_page(0);
632 }
633 }
634
635 }
636 printf("\n");
637 on_page++;
638 listing_page(0);
639 printf("UNDEFINED SYMBOLS\n");
640 on_page++;
641 listing_page(0);
642
643 for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
644 {
645 if (ptr && strlen(S_GET_NAME(ptr)) != 0)
646 {
647 if (ptr->sy_frag->line == 0)
648 {
649 printf("%s\n", S_GET_NAME(ptr));
650 on_page++;
651 listing_page(0);
652 }
653 }
654 }
655 }
656
657 void
658 DEFUN(print_source,(current_file, list, buffer, width),
659 file_info_type *current_file AND
660 list_info_type *list AND
661 char *buffer AND
662 unsigned int width)
663 {
664 if (current_file->file) {
665 while (current_file->linenum < list->hll_line)
666 {
667 char * p = buffer_line(current_file, buffer, width);
668 printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
669 on_page++;
670 listing_page(list);
671 }
672 }
673 }
674
675 /* Sometimes the user doesn't want to be bothered by the debugging
676 records inserted by the compiler, see if the line is suspicioous */
677
678 static int
679 DEFUN(debugging_pseudo,(line),
680 char *line)
681 {
682 while (isspace(*line))
683 line++;
684
685 if(*line != '.') return 0;
686
687 line++;
688
689 if (strncmp(line, "def",3) == 0) return 1;
690 if (strncmp(line, "val",3) == 0) return 1;
691 if (strncmp(line, "scl",3) == 0) return 1;
692 if (strncmp(line, "line",4) == 0) return 1;
693 if (strncmp(line, "endef",5) == 0) return 1;
694 if (strncmp(line, "ln",2) ==0) return 1;
695 if (strncmp(line, "type",4) ==0) return 1;
696 if (strncmp(line, "size",4) == 0) return 1;
697 if (strncmp(line, "dim",3) ==0) return 1;
698 if (strncmp(line, "tag",3) == 0) return 1;
699
700 return 0;
701
702 }
703
704 void
705 DEFUN(listing_listing,(name),
706 char *name)
707 {
708 list_info_type *list = head;
709 file_info_type *current_hll_file = (file_info_type *)NULL;
710
711 unsigned int page= 1;
712 unsigned int prev = 0;
713 char *message;
714 char *buffer;
715 char *p;
716 unsigned int addr = 0;
717 int on_page = 0;
718 int show_listing = 1;
719 unsigned int width;
720
721 buffer = malloc(LISTING_RHS_WIDTH);
722 eject = 1;
723 list = head;
724
725 while (list != (list_info_type *)NULL && 0)
726 {
727 if (list->next)
728 list->frag = list->next->frag;
729 list = list->next;
730
731 }
732
733 list = head->next;
734
735
736 while ( list)
737 {
738 width = LISTING_RHS_WIDTH > paper_width ? paper_width :
739 LISTING_RHS_WIDTH;
740
741 switch (list->edict) {
742 case EDICT_LIST:
743 show_listing++;
744 break;
745 case EDICT_NOLIST:
746 show_listing--;
747 break;
748 case EDICT_EJECT:
749 break;
750 case EDICT_NONE:
751 break;
752 case EDICT_TITLE:
753 title = list->edict_arg;
754 break;
755 case EDICT_SBTTL:
756 subtitle = list->edict_arg;
757 break;
758 default:
759 abort();
760 }
761
762 if (show_listing > 0)
763 {
764 /* Scan down the list and print all the stuff which can be done
765 with this line (or lines) */
766 message = 0;
767
768 if (list->hll_file)
769 {
770 current_hll_file = list->hll_file;
771 }
772
773 if (current_hll_file && list->hll_line && listing & LISTING_HLL)
774 {
775 print_source(current_hll_file, list, buffer, width);
776 }
777
778 p = buffer_line(list->file, buffer, width);
779
780 if (! ((listing & LISTING_NODEBUG) && debugging_pseudo(p)))
781 {
782 print_lines(list, p, calc_hex(list));
783 }
784
785 if (list->edict == EDICT_EJECT)
786 {
787 eject = 1;
788 }
789 }
790 else
791 {
792
793 p = buffer_line(list->file, buffer, width);
794 }
795
796 list = list->next;
797 }
798 free(buffer);
799 }
800
801 void
802 DEFUN(listing_print,(name),
803 char *name)
804 {
805 title = "";
806 subtitle = "";
807
808 if (listing & LISTING_NOFORM)
809 {
810 paper_height = 0;
811 }
812
813 if (listing & LISTING_LISTING)
814 {
815 listing_listing(name);
816
817 }
818 if (listing & LISTING_SYMBOLS)
819 {
820 list_symbol_table();
821 }
822 }
823
824
825 void
826 DEFUN(listing_file,(name),
827 char *name)
828 {
829 fn = name;
830 }
831
832 void
833 DEFUN_VOID(listing_eject)
834 {
835 listing_tail->edict = EDICT_EJECT;
836 }
837
838 void
839 DEFUN_VOID(listing_flags)
840 {
841
842 }
843 void
844 DEFUN(listing_list,(on),
845 unsigned int on)
846 {
847 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
848 }
849
850
851 void
852 DEFUN_VOID(listing_psize)
853 {
854 paper_height = get_absolute_expression();
855
856 if (paper_height < 0 || paper_height > 1000)
857 {
858 paper_height = 0;
859 as_warn("strantge paper height, set to no form");
860 }
861 if (*input_line_pointer == ',')
862 {
863 input_line_pointer++;
864 paper_width = get_absolute_expression();
865 }
866 }
867
868
869 void
870 DEFUN(listing_title,(depth),
871 unsigned int depth)
872 {
873 char *start;
874 char *title;
875 unsigned int length;
876
877 SKIP_WHITESPACE();
878 if (*input_line_pointer=='\"') {
879 input_line_pointer++;
880 start = input_line_pointer;
881
882 while (*input_line_pointer)
883 {
884 if (*input_line_pointer == '\"')
885 {
886 length = input_line_pointer - start;
887 title = malloc(length + 1);
888 memcpy(title, start, length);
889 title[length] = 0;
890 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
891 listing_tail->edict_arg = title;
892 input_line_pointer++;
893 demand_empty_rest_of_line();
894 return;
895 }
896 else if (*input_line_pointer == '\n')
897 {
898 as_bad("New line in title");
899 demand_empty_rest_of_line();
900 return;
901 }
902 else
903 {
904 input_line_pointer++;
905 }
906 }
907 }
908 else
909 {
910 as_bad("expecting title in quotes");
911 }
912 }
913
914
915
916 void
917 DEFUN(listing_source_line,(line),
918 unsigned int line)
919 {
920 new_frag();
921 listing_tail->hll_line = line;
922 new_frag();
923
924 }
925
926 void
927 DEFUN(listing_source_file,(file),
928 char *file)
929 {
930 listing_tail->hll_file = file_info(file);
931 }
932
933
934
935 #else
936
937
938 /* Dummy functions for when compiled without listing enabled */
939
940 void
941 DEFUN_VOID(listing_flags)
942 {
943 s_ignore();
944 }
945
946 void DEFUN_VOID(listing_list)
947 {
948 s_ignore();
949 }
950
951 void DEFUN_VOID(listing_eject)
952 {
953 s_ignore();
954 }
955 void DEFUN(listing_psize)
956 {
957 s_ignore();
958 }
959
960 void DEFUN(listing_title, (depth),
961 unsigned int depth)
962 {
963 s_ignore();
964 }
965 void
966 DEFUN(listing_file,(name),
967 char *name)
968 {
969
970 }
971
972 void DEFUN(listing_newline,(name),
973 char *name)
974 {
975
976 }
977
978 void DEFUN(listing_source_line,(n),
979 unsigned int n)
980 {
981
982 }
983 void DEFUN(listing_source_file, (n),
984 char *n)
985 {
986
987 }
988
989
990
991 #endif
992