(PCINDEX): New macro.
[deliverable/binutils-gdb.git] / gas / listing.c
CommitLineData
5d9f0ecf
SC
1/* listing.c - mainting assembly listings
2 Copyright (C) 1991, 1992 Free Software Foundation, Inc.
c593cf41
SC
3
4This file is part of GAS, the GNU Assembler.
5
6GAS is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GAS is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GAS; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
5d9f0ecf
SC
19
20/*
c593cf41
SC
21 Contributed by Steve Chamberlain
22 sac@cygnus.com
23
24
25 A listing page looks like:
58d4951d 26
c593cf41
SC
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
58d4951d
ILT
37 .title "stuff"
38 Put "stuff" onto the title line
c593cf41
SC
39 .sbttl "stuff"
40 Put stuff onto the subtitle line
41
5d9f0ecf
SC
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
c593cf41
SC
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
58d4951d 56 If the counter goes below zero, listing is suppressed.
c593cf41
SC
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*/
5d9f0ecf 93
58d4951d
ILT
94#include <ctype.h>
95
5d9f0ecf
SC
96#include "as.h"
97#include <obstack.h>
98#include "input-file.h"
e860dfd0 99#include "subsegs.h"
7143f43c 100
5d9f0ecf
SC
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
58d4951d 117#ifndef LISTING_LHS_CONT_LINES
5d9f0ecf
SC
118#define LISTING_LHS_CONT_LINES 4
119#endif
120
121
c593cf41
SC
122
123
b3ca913f 124/* This structure remembers which .s were used */
58d4951d 125typedef struct file_info_struct
c593cf41
SC
126{
127 char *filename;
128 int linenum;
129 FILE *file;
130 struct file_info_struct *next;
131 int end_pending;
58d4951d
ILT
132}
133
134file_info_type;
135
136
c593cf41
SC
137/* this structure rememebrs which line from which file goes into which
138 frag */
139typedef 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;
a39116f1 151
c593cf41
SC
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;
58d4951d 156
c593cf41
SC
157 /* High level language source line */
158 int hll_line;
58d4951d 159
c593cf41
SC
160
161 /* Pointer to any error message associated with this line */
162 char *message;
58d4951d
ILT
163
164 enum
165 {
166 EDICT_NONE,
167 EDICT_SBTTL,
168 EDICT_TITLE,
169 EDICT_NOLIST,
170 EDICT_LIST,
171 EDICT_EJECT
172 } edict;
c593cf41 173 char *edict_arg;
58d4951d
ILT
174
175}
176
177list_info_type;
5d9f0ecf 178
c593cf41 179
5d9f0ecf
SC
180static struct list_info_struct *head;
181struct list_info_struct *listing_tail;
182extern int listing;
5d9f0ecf
SC
183extern fragS *frag_now;
184
c593cf41 185
5d9f0ecf
SC
186static int paper_width = 200;
187static int paper_height = 60;
188
c593cf41 189
5d9f0ecf 190/* this static array is used to keep the text of data to be printed
c593cf41
SC
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 */
5d9f0ecf
SC
195
196static char data_buffer[100];
197static unsigned int data_buffer_size;
198
58d4951d
ILT
199
200/* Prototypes. */
201static void listing_message PARAMS ((const char *name, const char *message));
202static file_info_type *file_info PARAMS ((const char *file_name));
203static void new_frag PARAMS ((void));
204static char *buffer_line PARAMS ((file_info_type *file,
205 char *line, unsigned int size));
206static void listing_page PARAMS ((list_info_type *list));
207static unsigned int calc_hex PARAMS ((list_info_type *list));
208static void print_lines PARAMS ((list_info_type *list,
209 char *string,
210 unsigned int address));
211static void list_symbol_table PARAMS ((void));
212static void print_source PARAMS ((file_info_type *current_file,
213 list_info_type *list,
214 char *buffer,
215 unsigned int width));
216static int debugging_pseudo PARAMS ((char *line));
217static void listing_listing PARAMS ((char *name));
218
219
5d9f0ecf 220static void
58d4951d
ILT
221listing_message (name, message)
222 const char *name;
223 const char *message;
c593cf41 224{
58d4951d
ILT
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 }
c593cf41
SC
233}
234
58d4951d
ILT
235void
236listing_warning (message)
237 const char *message;
5d9f0ecf 238{
58d4951d 239 listing_message ("Warning:", message);
5d9f0ecf
SC
240}
241
58d4951d
ILT
242void
243listing_error (message)
244 const char *message;
5d9f0ecf 245{
58d4951d 246 listing_message ("Error:", message);
5d9f0ecf
SC
247}
248
c593cf41
SC
249
250
251
5d9f0ecf
SC
252static file_info_type *file_info_head;
253
254static file_info_type *
58d4951d
ILT
255file_info (file_name)
256 const char *file_name;
5d9f0ecf 257{
c593cf41
SC
258 /* Find an entry with this file name */
259 file_info_type *p = file_info_head;
58d4951d
ILT
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 }
c593cf41
SC
267
268 /* Make new entry */
269
58d4951d 270 p = (file_info_type *) xmalloc (sizeof (file_info_type));
c593cf41
SC
271 p->next = file_info_head;
272 file_info_head = p;
e860dfd0 273 p->filename = xmalloc ((unsigned long) strlen (file_name) + 1);
58d4951d 274 strcpy (p->filename, file_name);
c593cf41
SC
275 p->linenum = 0;
276 p->end_pending = 0;
7143f43c 277
f949f7b8 278 p->file = fopen (p->filename, "r");
58d4951d
ILT
279 if (p->file)
280 fgetc (p->file);
7143f43c 281
c593cf41 282 return p;
c593cf41 283}
5d9f0ecf
SC
284
285
58d4951d
ILT
286static void
287new_frag ()
b3ca913f 288{
58d4951d
ILT
289
290 frag_wane (frag_now);
291 frag_new (0);
c593cf41 292
b3ca913f
SC
293}
294
58d4951d
ILT
295void
296listing_newline (ps)
297 char *ps;
5d9f0ecf 298{
e860dfd0
KR
299 char *file;
300 unsigned int line;
58d4951d 301 static unsigned int last_line = 0xffff;
f949f7b8 302 static char *last_file = NULL;
c593cf41 303 list_info_type *new;
e860dfd0
KR
304
305 as_where (&file, &line);
f949f7b8 306 if (line != last_line || last_file && file && strcmp(file, last_file))
c593cf41 307 {
e860dfd0 308 last_line = line;
f949f7b8 309 last_file = file;
58d4951d
ILT
310 new_frag ();
311
312 new = (list_info_type *) xmalloc (sizeof (list_info_type));
313 new->frag = frag_now;
e860dfd0
KR
314 new->line = line;
315 new->file = file_info (file);
58d4951d
ILT
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 ();
c593cf41 332 }
c593cf41 333}
5d9f0ecf 334
e860dfd0
KR
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
341void
342listing_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}
3340f7e5 363
58d4951d 364/*
c593cf41
SC
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*/
5d9f0ecf
SC
369
370static char *
58d4951d
ILT
371buffer_line (file, line, size)
372 file_info_type * file;
373 char *line;
374 unsigned int size;
5d9f0ecf 375{
c593cf41
SC
376 unsigned int count = 0;
377 int c;
58d4951d 378
c593cf41
SC
379 char *p = line;
380
381 /* If we couldn't open the file, return an empty line */
58d4951d
ILT
382 if (file->file == (FILE *) NULL)
383 {
384 return "";
385 }
c593cf41 386
ab737e51 387 if (file->linenum == 0)
58d4951d 388 rewind (file->file);
ab737e51 389
58d4951d
ILT
390 if (file->end_pending == 10)
391 {
392 *p++ = '\n';
f949f7b8 393#if 1
58d4951d 394 fseek (file->file, 0, 0);
c593cf41 395 file->linenum = 0;
f949f7b8
KR
396#else
397 file->linenum = 9999999;
398#endif
c593cf41 399 file->end_pending = 0;
58d4951d
ILT
400 }
401 c = fgetc (file->file);
402
7143f43c 403
c593cf41
SC
404 size -= 1; /* leave room for null */
405
58d4951d
ILT
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++;
c593cf41
SC
423 *p++ = 0;
424 return line;
425}
426
5d9f0ecf 427
58d4951d 428static const char *fn;
5d9f0ecf
SC
429
430static unsigned int eject; /* Eject pending */
58d4951d
ILT
431static unsigned int page; /* Current page number */
432static char *title; /* current title */
5d9f0ecf 433static char *subtitle; /* current subtitle */
58d4951d 434static unsigned int on_page; /* number of lines printed on current page */
5d9f0ecf 435
3340f7e5 436
c593cf41 437static void
58d4951d
ILT
438listing_page (list)
439 list_info_type *list;
c593cf41
SC
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)*/
58d4951d 443 if ((eject || (on_page >= paper_height)) && paper_height != 0)
c593cf41 444 {
58d4951d
ILT
445 unsigned int c = 10;
446 int had_title = 0;
447 int had_subtitle = 0;
c593cf41 448
58d4951d
ILT
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;
c593cf41 478 }
c593cf41 479}
5d9f0ecf
SC
480
481
58d4951d
ILT
482static unsigned int
483calc_hex (list)
484 list_info_type * list;
5d9f0ecf 485{
c593cf41 486 list_info_type *first = list;
e860dfd0 487 unsigned int address = (unsigned int) ~0;
58d4951d 488
c593cf41
SC
489 fragS *frag;
490 fragS *frag_ptr;
491
e860dfd0 492 unsigned int byte_in_frag;
58d4951d 493
c593cf41
SC
494
495 /* Find first frag which says it belongs to this line */
58d4951d
ILT
496 frag = list->frag;
497 while (frag && frag->line != list)
498 frag = frag->fr_next;
c593cf41
SC
499
500 frag_ptr = frag;
501
502 data_buffer_size = 0;
58d4951d 503
c593cf41 504 /* Dump all the frags which belong to this line */
58d4951d 505 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
c593cf41 506 {
58d4951d 507 /* Print as many bytes from the fixed part as is sensible */
e860dfd0 508 byte_in_frag = 0;
58d4951d
ILT
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 }
c593cf41 522 {
58d4951d
ILT
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++] = '*';
c593cf41 540#endif
58d4951d
ILT
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;
c593cf41 552 }
c593cf41
SC
553 data_buffer[data_buffer_size++] = 0;
554 return address;
555}
556
557
558
559
560
5d9f0ecf
SC
561
562static void
58d4951d
ILT
563print_lines (list, string, address)
564 list_info_type *list;
565 char *string;
566 unsigned int address;
c593cf41
SC
567{
568 unsigned int idx;
569 unsigned int nchars;
570 unsigned int lines;
58d4951d 571 unsigned int byte_in_word = 0;
c593cf41 572 char *src = data_buffer;
58d4951d 573
c593cf41 574 /* Print the stuff on the first line */
58d4951d
ILT
575 listing_page (list);
576 nchars = (LISTING_WORD_SIZE * 2 + 1) * LISTING_LHS_WIDTH;
c593cf41 577 /* Print the hex for the first line */
58d4951d 578 if (address == ~0)
c593cf41 579 {
58d4951d
ILT
580 printf ("% 4d ", list->line);
581 for (idx = 0; idx < nchars; idx++)
582 printf (" ");
583
584 printf ("\t%s\n", string ? string : "");
c593cf41 585 on_page++;
58d4951d
ILT
586 listing_page (0);
587
c593cf41 588 }
58d4951d
ILT
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 }
c593cf41 599
58d4951d
ILT
600 /* And the data to go along with it */
601 idx = 0;
602
603 while (*src && idx < nchars)
c593cf41 604 {
58d4951d
ILT
605 printf ("%c%c", src[0], src[1]);
606 src += 2;
c593cf41 607 byte_in_word++;
58d4951d
ILT
608 if (byte_in_word == LISTING_WORD_SIZE)
609 {
610 printf (" ");
611 idx++;
612 byte_in_word = 0;
613 }
614 idx += 2;
c593cf41 615 }
c593cf41 616
58d4951d
ILT
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 }
c593cf41 629
58d4951d
ILT
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}
5d9f0ecf
SC
663
664
665static void
58d4951d 666list_symbol_table ()
5d9f0ecf 667{
c593cf41 668 extern symbolS *symbol_rootP;
f949f7b8 669 int got_some = 0;
58d4951d
ILT
670
671 symbolS *ptr;
c593cf41 672 eject = 1;
58d4951d 673 listing_page (0);
58d4951d
ILT
674
675 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
c593cf41 676 {
58d4951d
ILT
677 if (ptr->sy_frag->line)
678 {
679 if (S_GET_NAME (ptr))
680 {
f949f7b8 681 char buf[30], fmt[8];
58d4951d
ILT
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);
f949f7b8
KR
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)
58d4951d
ILT
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
f949f7b8
KR
705 if (!got_some)
706 {
707 printf ("DEFINED SYMBOLS\n");
708 on_page++;
709 got_some = 1;
710 }
711
58d4951d
ILT
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 }
c593cf41 722
c593cf41 723 }
f949f7b8
KR
724 if (!got_some)
725 {
726 printf ("NO DEFINED SYMBOLS\n");
727 on_page++;
728 }
58d4951d 729 printf ("\n");
c593cf41 730 on_page++;
58d4951d 731 listing_page (0);
f949f7b8
KR
732
733 got_some = 0;
58d4951d
ILT
734
735 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
c593cf41 736 {
58d4951d
ILT
737 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
738 {
e860dfd0 739 if (ptr->sy_frag->line == 0
f949f7b8
KR
740#ifdef S_IS_REGISTER
741 && !S_IS_REGISTER (ptr)
742#endif
e860dfd0 743 && S_GET_SEGMENT (ptr) != reg_section)
58d4951d 744 {
f949f7b8
KR
745 if (!got_some)
746 {
747 got_some = 1;
748 printf ("UNDEFINED SYMBOLS\n");
749 on_page++;
750 listing_page (0);
751 }
58d4951d
ILT
752 printf ("%s\n", S_GET_NAME (ptr));
753 on_page++;
754 listing_page (0);
755 }
756 }
c593cf41 757 }
f949f7b8
KR
758 if (!got_some)
759 {
760 printf ("NO UNDEFINED SYMBOLS\n");
761 on_page++;
762 listing_page (0);
763 }
c593cf41 764}
5d9f0ecf 765
58d4951d
ILT
766static void
767print_source (current_file, list, buffer, width)
768 file_info_type *current_file;
769 list_info_type *list;
770 char *buffer;
771 unsigned int width;
c593cf41 772{
58d4951d
ILT
773 if (current_file->file)
774 {
f949f7b8
KR
775 while (current_file->linenum < list->hll_line
776 && current_file->end_pending == 0)
58d4951d
ILT
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 }
c593cf41
SC
783 }
784}
b3ca913f 785
a39116f1 786/* Sometimes the user doesn't want to be bothered by the debugging
58d4951d 787 records inserted by the compiler, see if the line is suspicious */
5d9f0ecf 788
a39116f1 789static int
58d4951d
ILT
790debugging_pseudo (line)
791 char *line;
a39116f1 792{
58d4951d
ILT
793 while (isspace (*line))
794 line++;
795
796 if (*line != '.')
797 return 0;
c593cf41 798
c593cf41
SC
799 line++;
800
58d4951d
ILT
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
c593cf41
SC
827 return 0;
828
829}
5d9f0ecf 830
58d4951d
ILT
831static void
832listing_listing (name)
833 char *name;
c593cf41
SC
834{
835 list_info_type *list = head;
58d4951d 836 file_info_type *current_hll_file = (file_info_type *) NULL;
c593cf41
SC
837 char *message;
838 char *buffer;
839 char *p;
c593cf41
SC
840 int show_listing = 1;
841 unsigned int width;
58d4951d
ILT
842
843 buffer = xmalloc (LISTING_RHS_WIDTH);
c593cf41
SC
844 eject = 1;
845 list = head;
846
58d4951d
ILT
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 }
c593cf41 854
c593cf41
SC
855 list = head->next;
856
857
58d4951d 858 while (list)
c593cf41 859 {
58d4951d
ILT
860 width = LISTING_RHS_WIDTH > paper_width ? paper_width :
861 LISTING_RHS_WIDTH;
c593cf41 862
58d4951d
ILT
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 }
c593cf41 884
58d4951d
ILT
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
f949f7b8
KR
901 while (list->file->file
902 && list->file->linenum < list->line
903 && !list->file->end_pending)
58d4951d 904 {
f949f7b8
KR
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 }
58d4951d
ILT
911 }
912
913 if (list->edict == EDICT_EJECT)
914 {
915 eject = 1;
916 }
917 }
918 else
919 {
f949f7b8
KR
920 while (list->file->file
921 && list->file->linenum < list->line
922 && !list->file->end_pending)
923 p = buffer_line (list->file, buffer, width);
58d4951d 924 }
c593cf41 925
58d4951d 926 list = list->next;
c593cf41 927 }
58d4951d 928 free (buffer);
c593cf41 929}
5d9f0ecf 930
58d4951d
ILT
931void
932listing_print (name)
933 char *name;
5d9f0ecf 934{
c593cf41 935 title = "";
58d4951d
ILT
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}
5d9f0ecf
SC
953
954
955void
58d4951d
ILT
956listing_file (name)
957 const char *name;
5d9f0ecf 958{
58d4951d 959 fn = name;
5d9f0ecf
SC
960}
961
58d4951d 962void
e860dfd0
KR
963listing_eject (ignore)
964 int ignore;
5d9f0ecf 965{
58d4951d 966 listing_tail->edict = EDICT_EJECT;
5d9f0ecf
SC
967}
968
969void
e860dfd0
KR
970listing_flags (ignore)
971 int ignore;
5d9f0ecf 972{
58d4951d
ILT
973 while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
974 input_line_pointer++;
975
c593cf41 976}
58d4951d 977
c593cf41 978void
58d4951d 979listing_list (on)
e860dfd0 980 int on;
c593cf41
SC
981{
982 listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
5d9f0ecf 983}
3340f7e5 984
c593cf41 985
5d9f0ecf 986void
e860dfd0
KR
987listing_psize (ignore)
988 int ignore;
5d9f0ecf 989{
58d4951d 990 paper_height = get_absolute_expression ();
c593cf41 991
58d4951d
ILT
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 }
5d9f0ecf
SC
1002}
1003
1004
1005void
58d4951d 1006listing_title (depth)
e860dfd0 1007 int depth;
a39116f1 1008{
c593cf41 1009 char *start;
e860dfd0 1010 char *ttl;
c593cf41 1011 unsigned int length;
58d4951d
ILT
1012
1013 SKIP_WHITESPACE ();
1014 if (*input_line_pointer == '\"')
1015 {
c593cf41
SC
1016 input_line_pointer++;
1017 start = input_line_pointer;
58d4951d
ILT
1018
1019 while (*input_line_pointer)
c593cf41 1020 {
58d4951d
ILT
1021 if (*input_line_pointer == '\"')
1022 {
1023 length = input_line_pointer - start;
e860dfd0
KR
1024 ttl = xmalloc (length + 1);
1025 memcpy (ttl, start, length);
1026 ttl[length] = 0;
58d4951d 1027 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
e860dfd0 1028 listing_tail->edict_arg = ttl;
58d4951d
ILT
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 }
c593cf41 1043 }
c593cf41 1044 }
58d4951d
ILT
1045 else
1046 {
1047 as_bad ("expecting title in quotes");
1048 }
c593cf41
SC
1049}
1050
5d9f0ecf
SC
1051
1052
1053void
58d4951d
ILT
1054listing_source_line (line)
1055 unsigned int line;
5d9f0ecf 1056{
58d4951d 1057 new_frag ();
c593cf41 1058 listing_tail->hll_line = line;
58d4951d
ILT
1059 new_frag ();
1060
c593cf41 1061}
5d9f0ecf 1062
c593cf41 1063void
58d4951d
ILT
1064listing_source_file (file)
1065 const char *file;
c593cf41 1066{
e860dfd0
KR
1067 if (listing_tail)
1068 listing_tail->hll_file = file_info (file);
c593cf41 1069}
5d9f0ecf 1070
b3ca913f 1071
58d4951d 1072
c593cf41
SC
1073#else
1074
1075
1076/* Dummy functions for when compiled without listing enabled */
1077
58d4951d 1078void
e860dfd0
KR
1079listing_flags (ignore)
1080 int ignore;
c593cf41 1081{
58d4951d 1082 s_ignore (0);
c593cf41
SC
1083}
1084
58d4951d
ILT
1085void
1086listing_list (on)
e860dfd0 1087 int on;
b3ca913f 1088{
58d4951d 1089 s_ignore (0);
c593cf41
SC
1090}
1091
58d4951d 1092void
e860dfd0
KR
1093listing_eject (ignore)
1094 int ignore;
c593cf41 1095{
58d4951d 1096 s_ignore (0);
c593cf41 1097}
58d4951d
ILT
1098
1099void
e860dfd0
KR
1100listing_psize (ignore)
1101 int ignore;
c593cf41 1102{
58d4951d 1103 s_ignore (0);
c593cf41 1104}
b3ca913f 1105
58d4951d
ILT
1106void
1107listing_title (depth)
e860dfd0 1108 int depth;
c593cf41 1109{
58d4951d 1110 s_ignore (0);
c593cf41 1111}
58d4951d 1112
b3ca913f 1113void
58d4951d
ILT
1114listing_file (name)
1115 const char *name;
b3ca913f 1116{
c593cf41
SC
1117
1118}
1119
58d4951d
ILT
1120void
1121listing_newline (name)
1122 char *name;
c593cf41 1123{
58d4951d 1124
b3ca913f
SC
1125}
1126
58d4951d
ILT
1127void
1128listing_source_line (n)
1129 unsigned int n;
c593cf41 1130{
58d4951d 1131
c593cf41 1132}
58d4951d
ILT
1133void
1134listing_source_file (n)
1135 const char *n;
c593cf41 1136{
c593cf41 1137
58d4951d 1138}
c593cf41
SC
1139
1140#endif
This page took 0.204011 seconds and 4 git commands to generate.