Enhance objdump so that it will use .got, .plt and .plt.got section symbols when...
[deliverable/binutils-gdb.git] / gas / listing.c
CommitLineData
436d9e46 1/* listing.c - maintain assembly listings
6f2750fe 2 Copyright (C) 1991-2016 Free Software Foundation, Inc.
252b5132 3
5a1964ec 4 This file is part of GAS, the GNU Assembler.
252b5132 5
5a1964ec
NC
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
ec2655a6 8 the Free Software Foundation; either version 3, or (at your option)
5a1964ec 9 any later version.
252b5132 10
5a1964ec
NC
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.
252b5132 15
5a1964ec
NC
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 the Free
4b4da160
NC
18 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
19 02110-1301, USA. */
252b5132 20
5a1964ec 21/* Contributed by Steve Chamberlain <sac@cygnus.com>
252b5132
RH
22
23 A listing page looks like:
24
25 LISTING_HEADER sourcefilename pagenumber
26 TITLE LINE
27 SUBTITLE LINE
28 linenumber address data source
29 linenumber address data source
30 linenumber address data source
31 linenumber address data source
32
33 If not overridden, the listing commands are:
34
35 .title "stuff"
36 Put "stuff" onto the title line
37 .sbttl "stuff"
38 Put stuff onto the subtitle line
39
40 If these commands come within 10 lines of the top of the page, they
41 will affect the page they are on, as well as any subsequent page
42
43 .eject
44 Thow a page
45 .list
46 Increment the enable listing counter
47 .nolist
48 Decrement the enable listing counter
49
50 .psize Y[,X]
51 Set the paper size to X wide and Y high. Setting a psize Y of
52 zero will suppress form feeds except where demanded by .eject
53
54 If the counter goes below zero, listing is suppressed.
55
252b5132
RH
56 Listings are a maintained by read calling various listing_<foo>
57 functions. What happens most is that the macro NO_LISTING is not
58 defined (from the Makefile), then the macro LISTING_NEWLINE expands
59 into a call to listing_newline. The call is done from read.c, every
60 time it sees a newline, and -l is on the command line.
61
62 The function listing_newline remembers the frag associated with the
63 newline, and creates a new frag - note that this is wasteful, but not
64 a big deal, since listing slows things down a lot anyway. The
47eebc20 65 function also remembers when the filename changes.
252b5132
RH
66
67 When all the input has finished, and gas has had a chance to settle
68 down, the listing is output. This is done by running down the list of
69 frag/source file records, and opening the files as needed and printing
70 out the bytes and chars associated with them.
71
72 The only things which the architecture can change about the listing
73 are defined in these macros:
74
75 LISTING_HEADER The name of the architecture
76 LISTING_WORD_SIZE The make of the number of bytes in a word, this determines
77 the clumping of the output data. eg a value of
78 2 makes words look like 1234 5678, whilst 1
79 would make the same value look like 12 34 56
80 78
81 LISTING_LHS_WIDTH Number of words of above size for the lhs
82
83 LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
84 for the second line
85
47eebc20 86 LISTING_LHS_CONT_LINES Max number of lines to use up for a continuation
252b5132 87 LISTING_RHS_WIDTH Number of chars from the input file to print
5a1964ec 88 on a line. */
252b5132 89
252b5132 90#include "as.h"
8b6efd89 91#include "filenames.h"
3882b010 92#include "safe-ctype.h"
252b5132
RH
93#include "input-file.h"
94#include "subsegs.h"
83f10cb2
NC
95#include "bfdver.h"
96#include <time.h>
752d5da4 97#include <stdarg.h>
252b5132
RH
98
99#ifndef NO_LISTING
100
101#ifndef LISTING_HEADER
102#define LISTING_HEADER "GAS LISTING"
103#endif
104#ifndef LISTING_WORD_SIZE
105#define LISTING_WORD_SIZE 4
106#endif
107#ifndef LISTING_LHS_WIDTH
224de7a5 108#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
252b5132
RH
109#endif
110#ifndef LISTING_LHS_WIDTH_SECOND
224de7a5 111#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
252b5132
RH
112#endif
113#ifndef LISTING_RHS_WIDTH
114#define LISTING_RHS_WIDTH 100
115#endif
116#ifndef LISTING_LHS_CONT_LINES
117#define LISTING_LHS_CONT_LINES 4
118#endif
83f10cb2 119#define MAX_DATELEN 30
252b5132 120
cf39a089 121/* This structure remembers which .s were used. */
5a1964ec
NC
122typedef struct file_info_struct
123{
252b5132
RH
124 struct file_info_struct * next;
125 char * filename;
126 long pos;
127 unsigned int linenum;
128 int at_end;
ef99799a 129} file_info_type;
252b5132 130
1e9cc1c2
NC
131enum edict_enum
132{
133 EDICT_NONE,
134 EDICT_SBTTL,
135 EDICT_TITLE,
136 EDICT_NOLIST,
137 EDICT_LIST,
138 EDICT_NOLIST_NEXT,
139 EDICT_EJECT
140};
141
142
c71bb85d
SB
143struct list_message
144{
145 char *message;
146 struct list_message *next;
147};
148
47eebc20 149/* This structure remembers which line from which file goes into which
cf39a089 150 frag. */
5a1964ec
NC
151struct list_info_struct
152{
cf39a089
KH
153 /* Frag which this line of source is nearest to. */
154 fragS *frag;
252b5132 155
cf39a089 156 /* The actual line in the source file. */
252b5132 157 unsigned int line;
5a1964ec 158
252b5132 159 /* Pointer to the file info struct for the file which this line
cf39a089
KH
160 belongs to. */
161 file_info_type *file;
252b5132
RH
162
163 /* The expanded text of any macro that may have been executing. */
cf39a089 164 char *line_contents;
252b5132 165
cf39a089
KH
166 /* Next in list. */
167 struct list_info_struct *next;
252b5132
RH
168
169 /* Pointer to the file info struct for the high level language
cf39a089
KH
170 source line that belongs here. */
171 file_info_type *hll_file;
5a1964ec 172
cf39a089 173 /* High level language source line. */
252b5132
RH
174 unsigned int hll_line;
175
c71bb85d
SB
176 /* Pointers to linked list of messages associated with this line. */
177 struct list_message *messages, *last_message;
252b5132 178
1e9cc1c2 179 enum edict_enum edict;
cf39a089 180 char *edict_arg;
252b5132
RH
181
182 /* Nonzero if this line is to be omitted because it contains
183 debugging information. This can become a flags field if we come
184 up with more information to store here. */
185 int debugging;
186};
187
188typedef struct list_info_struct list_info_type;
189
252b5132
RH
190int listing_lhs_width = LISTING_LHS_WIDTH;
191int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
192int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES;
193int listing_rhs_width = LISTING_RHS_WIDTH;
194
195struct list_info_struct * listing_tail;
196
197static file_info_type * file_info_head;
198static file_info_type * last_open_file_info;
199static FILE * last_open_file;
200static struct list_info_struct * head;
201static int paper_width = 200;
202static int paper_height = 60;
203
204extern int listing;
205
206/* File to output listings to. */
ef99799a 207static FILE *list_file;
252b5132
RH
208
209/* This static array is used to keep the text of data to be printed
210 before the start of the line. */
211
212#define MAX_BYTES \
213 (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \
214 + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \
215 * listing_lhs_cont_lines) \
216 + 20)
217
cf39a089 218static char *data_buffer;
252b5132
RH
219
220/* Prototypes. */
5a1964ec
NC
221static void listing_message (const char *, const char *);
222static file_info_type *file_info (const char *);
254d758c 223static void new_frag (void);
5a1964ec
NC
224static void listing_page (list_info_type *);
225static unsigned int calc_hex (list_info_type *);
cd0bbe6e
TS
226static void print_lines (list_info_type *, unsigned int, const char *,
227 unsigned int);
254d758c 228static void list_symbol_table (void);
254d758c 229static int debugging_pseudo (list_info_type *, const char *);
5a1964ec 230static void listing_listing (char *);
252b5132 231
252b5132 232static void
254d758c 233listing_message (const char *name, const char *message)
252b5132 234{
252b5132
RH
235 if (listing_tail != (list_info_type *) NULL)
236 {
29a2809e 237 char *n = concat (name, message, (char *) NULL);
8860a416 238 struct list_message *lm = XNEW (struct list_message);
c71bb85d
SB
239 lm->message = n;
240 lm->next = NULL;
241
242 if (listing_tail->last_message)
243 listing_tail->last_message->next = lm;
244 else
245 listing_tail->messages = lm;
246 listing_tail->last_message = lm;
252b5132
RH
247 }
248}
249
250void
254d758c 251listing_warning (const char *message)
252b5132 252{
b52855e7 253 listing_message (_("Warning: "), message);
252b5132
RH
254}
255
256void
254d758c 257listing_error (const char *message)
252b5132 258{
b52855e7 259 listing_message (_("Error: "), message);
252b5132
RH
260}
261
262static file_info_type *
254d758c 263file_info (const char *file_name)
252b5132 264{
cf39a089 265 /* Find an entry with this file name. */
252b5132
RH
266 file_info_type *p = file_info_head;
267
268 while (p != (file_info_type *) NULL)
269 {
8b6efd89 270 if (filename_cmp (p->filename, file_name) == 0)
252b5132
RH
271 return p;
272 p = p->next;
273 }
274
cf39a089 275 /* Make new entry. */
325801bd 276 p = XNEW (file_info_type);
252b5132
RH
277 p->next = file_info_head;
278 file_info_head = p;
a2c36061 279 p->filename = xstrdup (file_name);
252b5132
RH
280 p->pos = 0;
281 p->linenum = 0;
282 p->at_end = 0;
283
284 return p;
285}
286
252b5132 287static void
254d758c 288new_frag (void)
252b5132 289{
252b5132
RH
290 frag_wane (frag_now);
291 frag_new (0);
252b5132
RH
292}
293
294void
254d758c 295listing_newline (char *ps)
252b5132 296{
3b4dbbbf 297 const char *file;
252b5132
RH
298 unsigned int line;
299 static unsigned int last_line = 0xffff;
3b4dbbbf 300 static const char *last_file = NULL;
d3ce72d0 301 list_info_type *new_i = NULL;
252b5132
RH
302
303 if (listing == 0)
304 return;
305
306 if (now_seg == absolute_section)
307 return;
308
309#ifdef OBJ_ELF
310 /* In ELF, anything in a section beginning with .debug or .line is
311 considered to be debugging information. This includes the
312 statement which switches us into the debugging section, which we
313 can only set after we are already in the debugging section. */
314 if ((listing & LISTING_NODEBUG) != 0
315 && listing_tail != NULL
316 && ! listing_tail->debugging)
317 {
318 const char *segname;
319
320 segname = segment_name (now_seg);
321 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
322 || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
323 listing_tail->debugging = 1;
324 }
325#endif
326
3b4dbbbf 327 file = as_where (&line);
252b5132
RH
328 if (ps == NULL)
329 {
cf39a089 330 if (line == last_line
8b6efd89 331 && !(last_file && file && filename_cmp (file, last_file)))
252b5132
RH
332 return;
333
325801bd 334 new_i = XNEW (list_info_type);
252b5132
RH
335
336 /* Detect if we are reading from stdin by examining the file
337 name returned by as_where().
338
339 [FIXME: We rely upon the name in the strcmp below being the
340 same as the one used by input_scrub_new_file(), if that is
341 not true, then this code will fail].
342
cf39a089
KH
343 If we are reading from stdin, then we need to save each input
344 line here (assuming of course that we actually have a line of
345 input to read), so that it can be displayed in the listing
346 that is produced at the end of the assembly. */
252b5132
RH
347 if (strcmp (file, _("{standard input}")) == 0
348 && input_line_pointer != NULL)
349 {
add39d23 350 char *copy, *src, *dest;
252b5132
RH
351 int len;
352 int seen_quote = 0;
d67ffd56 353 int seen_slash = 0;
252b5132 354
f19df8f7 355 for (copy = input_line_pointer;
cf39a089 356 *copy && (seen_quote
d67ffd56 357 || is_end_of_line [(unsigned char) *copy] != 1);
cf39a089 358 copy++)
d67ffd56 359 {
4199fe12
AM
360 if (seen_slash)
361 seen_slash = 0;
362 else if (*copy == '\\')
363 seen_slash = 1;
364 else if (*copy == '"')
365 seen_quote = !seen_quote;
d67ffd56 366 }
252b5132 367
f19df8f7 368 len = copy - input_line_pointer + 1;
252b5132 369
add39d23 370 copy = XNEWVEC (char, len);
252b5132 371
add39d23
TS
372 src = input_line_pointer;
373 dest = copy;
252b5132 374
add39d23
TS
375 while (--len)
376 {
377 unsigned char c = *src++;
cf39a089 378
add39d23
TS
379 /* Omit control characters in the listing. */
380 if (!ISCNTRL (c))
381 *dest++ = c;
252b5132 382 }
cf39a089 383
add39d23
TS
384 *dest = 0;
385
d3ce72d0 386 new_i->line_contents = copy;
252b5132
RH
387 }
388 else
d3ce72d0 389 new_i->line_contents = NULL;
252b5132
RH
390 }
391 else
392 {
325801bd 393 new_i = XNEW (list_info_type);
d3ce72d0 394 new_i->line_contents = ps;
252b5132
RH
395 }
396
397 last_line = line;
398 last_file = file;
cf39a089 399
252b5132
RH
400 new_frag ();
401
402 if (listing_tail)
d3ce72d0 403 listing_tail->next = new_i;
252b5132 404 else
d3ce72d0 405 head = new_i;
cf39a089 406
d3ce72d0 407 listing_tail = new_i;
252b5132 408
d3ce72d0
NC
409 new_i->frag = frag_now;
410 new_i->line = line;
411 new_i->file = file_info (file);
412 new_i->next = (list_info_type *) NULL;
c71bb85d
SB
413 new_i->messages = NULL;
414 new_i->last_message = NULL;
d3ce72d0
NC
415 new_i->edict = EDICT_NONE;
416 new_i->hll_file = (file_info_type *) NULL;
417 new_i->hll_line = 0;
418 new_i->debugging = 0;
cf39a089 419
252b5132
RH
420 new_frag ();
421
422#ifdef OBJ_ELF
423 /* In ELF, anything in a section beginning with .debug or .line is
424 considered to be debugging information. */
425 if ((listing & LISTING_NODEBUG) != 0)
426 {
427 const char *segname;
428
429 segname = segment_name (now_seg);
430 if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0
431 || strncmp (segname, ".line", sizeof ".line" - 1) == 0)
d3ce72d0 432 new_i->debugging = 1;
252b5132
RH
433 }
434#endif
435}
436
437/* Attach all current frags to the previous line instead of the
438 current line. This is called by the MIPS backend when it discovers
439 that it needs to add some NOP instructions; the added NOP
440 instructions should go with the instruction that has the delay, not
441 with the new instruction. */
442
443void
254d758c 444listing_prev_line (void)
252b5132
RH
445{
446 list_info_type *l;
447 fragS *f;
448
449 if (head == (list_info_type *) NULL
450 || head == listing_tail)
451 return;
452
453 new_frag ();
454
455 for (l = head; l->next != listing_tail; l = l->next)
456 ;
457
458 for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next)
459 if (f->line == listing_tail)
460 f->line = l;
461
462 listing_tail->frag = frag_now;
463 new_frag ();
464}
465
cf39a089
KH
466/* This function returns the next source line from the file supplied,
467 truncated to size. It appends a fake line to the end of each input
752d5da4 468 file to make using the returned buffer simpler. */
252b5132 469
cd0bbe6e 470static const char *
254d758c 471buffer_line (file_info_type *file, char *line, unsigned int size)
252b5132
RH
472{
473 unsigned int count = 0;
474 int c;
252b5132
RH
475 char *p = line;
476
cf39a089 477 /* If we couldn't open the file, return an empty line. */
252b5132
RH
478 if (file->at_end)
479 return "";
480
481 /* Check the cache and see if we last used this file. */
482 if (!last_open_file_info || file != last_open_file_info)
483 {
484 if (last_open_file)
485 {
486 last_open_file_info->pos = ftell (last_open_file);
487 fclose (last_open_file);
488 }
489
7e66d8ac
KH
490 /* Open the file in the binary mode so that ftell above can
491 return a reliable value that we can feed to fseek below. */
252b5132 492 last_open_file_info = file;
7e66d8ac 493 last_open_file = fopen (file->filename, FOPEN_RB);
252b5132
RH
494 if (last_open_file == NULL)
495 {
496 file->at_end = 1;
497 return "";
498 }
cf39a089 499
252b5132
RH
500 /* Seek to where we were last time this file was open. */
501 if (file->pos)
cf39a089 502 fseek (last_open_file, file->pos, SEEK_SET);
252b5132
RH
503 }
504
cf39a089
KH
505 /* Leave room for null. */
506 size -= 1;
252b5132 507
752d5da4
NC
508 c = fgetc (last_open_file);
509
7e66d8ac 510 while (c != EOF && c != '\n' && c != '\r')
252b5132
RH
511 {
512 if (count < size)
513 *p++ = c;
514 count++;
515
516 c = fgetc (last_open_file);
252b5132 517 }
7e66d8ac
KH
518
519 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
520 is followed by '\r', swallow that as well. */
521 if (c == '\r' || c == '\n')
522 {
523 int next = fgetc (last_open_file);
752d5da4 524
7e66d8ac
KH
525 if ((c == '\r' && next != '\n')
526 || (c == '\n' && next != '\r'))
527 ungetc (next, last_open_file);
528 }
529
252b5132
RH
530 if (c == EOF)
531 {
532 file->at_end = 1;
97735a42
AM
533 if (count + 2 < size)
534 {
535 *p++ = '.';
536 *p++ = '.';
537 *p++ = '.';
538 }
252b5132
RH
539 }
540 file->linenum++;
541 *p++ = 0;
542 return line;
543}
544
752d5da4
NC
545
546/* This function rewinds the requested file back to the line requested,
547 reads it in again into the buffer provided and then restores the file
3d13c647 548 back to its original location. */
752d5da4 549
3d13c647 550static void
752d5da4
NC
551rebuffer_line (file_info_type * file,
552 unsigned int linenum,
553 char * buffer,
554 unsigned int size)
555{
556 unsigned int count = 0;
9b978282 557 unsigned int current_line;
752d5da4
NC
558 char * p = buffer;
559 long pos;
9b978282 560 long pos2;
752d5da4 561 int c;
9b978282 562 bfd_boolean found = FALSE;
752d5da4
NC
563
564 /* Sanity checks. */
9b978282 565 if (file == NULL || buffer == NULL || size <= 1 || file->linenum <= linenum)
3d13c647 566 return;
752d5da4
NC
567
568 /* Check the cache and see if we last used this file. */
569 if (last_open_file_info == NULL || file != last_open_file_info)
570 {
571 if (last_open_file)
572 {
573 last_open_file_info->pos = ftell (last_open_file);
574 fclose (last_open_file);
575 }
576
577 /* Open the file in the binary mode so that ftell above can
578 return a reliable value that we can feed to fseek below. */
579 last_open_file_info = file;
580 last_open_file = fopen (file->filename, FOPEN_RB);
581 if (last_open_file == NULL)
582 {
583 file->at_end = 1;
3d13c647 584 return;
752d5da4
NC
585 }
586
587 /* Seek to where we were last time this file was open. */
588 if (file->pos)
589 fseek (last_open_file, file->pos, SEEK_SET);
590 }
591
592 /* Remember where we are in the current file. */
9b978282
NC
593 pos2 = pos = ftell (last_open_file);
594 if (pos < 3)
3d13c647 595 return;
9b978282
NC
596 current_line = file->linenum;
597
598 /* Leave room for the nul at the end of the buffer. */
599 size -= 1;
600 buffer[size] = 0;
752d5da4 601
9b978282
NC
602 /* Increment the current line count by one.
603 This is to allow for the fact that we are searching for the
604 start of a previous line, but we do this by detecting end-of-line
605 character(s) not start-of-line characters. */
606 ++ current_line;
752d5da4 607
9b978282 608 while (pos2 > 0 && ! found)
752d5da4 609 {
9b978282
NC
610 char * ptr;
611
612 /* Move backwards through the file, looking for earlier lines. */
613 pos2 = (long) size > pos2 ? 0 : pos2 - size;
614 fseek (last_open_file, pos2, SEEK_SET);
615
616 /* Our caller has kindly provided us with a buffer, so we use it. */
617 if (fread (buffer, 1, size, last_open_file) != size)
752d5da4 618 {
9b978282 619 as_warn (_("unable to rebuffer file: %s\n"), file->filename);
3d13c647 620 return;
752d5da4 621 }
752d5da4 622
9b978282 623 for (ptr = buffer + size; ptr >= buffer; -- ptr)
752d5da4 624 {
9b978282
NC
625 if (*ptr == '\n')
626 {
627 -- current_line;
752d5da4 628
9b978282
NC
629 if (current_line == linenum)
630 {
631 /* We have found the start of the line we seek. */
632 found = TRUE;
633
634 /* FIXME: We could skip the read-in-the-line code
635 below if we know that we already have the whole
636 line in the buffer. */
637
638 /* Advance pos2 to the newline character we have just located. */
639 pos2 += (ptr - buffer);
640
641 /* Skip the newline and, if present, the carriage return. */
642 if (ptr + 1 == buffer + size)
643 {
644 ++pos2;
645 if (fgetc (last_open_file) == '\r')
646 ++ pos2;
647 }
648 else
649 pos2 += (ptr[1] == '\r' ? 2 : 1);
650
651 /* Move the file pointer to this location. */
652 fseek (last_open_file, pos2, SEEK_SET);
653 break;
654 }
655 }
752d5da4
NC
656 }
657 }
658
752d5da4
NC
659 /* Read in the line. */
660 c = fgetc (last_open_file);
661
662 while (c != EOF && c != '\n' && c != '\r')
663 {
664 if (count < size)
665 *p++ = c;
666 count++;
667
668 c = fgetc (last_open_file);
669 }
670
671 /* If '\r' is followed by '\n', swallow that. Likewise, if '\n'
672 is followed by '\r', swallow that as well. */
673 if (c == '\r' || c == '\n')
674 {
675 int next = fgetc (last_open_file);
676
677 if ((c == '\r' && next != '\n')
678 || (c == '\n' && next != '\r'))
679 ungetc (next, last_open_file);
680 }
681
682 /* Terminate the line. */
683 *p++ = 0;
684
685 /* Reset the file position. */
686 fseek (last_open_file, pos, SEEK_SET);
752d5da4
NC
687}
688
252b5132 689static const char *fn;
cd0bbe6e
TS
690static unsigned int eject; /* Eject pending. */
691static unsigned int page; /* Current page number. */
692static const char *title; /* Current title. */
693static const char *subtitle; /* Current subtitle. */
694static unsigned int on_page; /* Number of lines printed on current page. */
252b5132
RH
695
696static void
254d758c 697listing_page (list_info_type *list)
252b5132
RH
698{
699 /* Grope around, see if we can see a title or subtitle edict coming up
cf39a089
KH
700 soon. (we look down 10 lines of the page and see if it's there) */
701 if ((eject || (on_page >= (unsigned int) paper_height))
702 && paper_height != 0)
252b5132
RH
703 {
704 unsigned int c = 10;
705 int had_title = 0;
706 int had_subtitle = 0;
707
708 page++;
709
710 while (c != 0 && list)
711 {
712 if (list->edict == EDICT_SBTTL && !had_subtitle)
713 {
714 had_subtitle = 1;
715 subtitle = list->edict_arg;
716 }
717 if (list->edict == EDICT_TITLE && !had_title)
718 {
719 had_title = 1;
720 title = list->edict_arg;
721 }
722 list = list->next;
723 c--;
724 }
725
252b5132
RH
726 if (page > 1)
727 {
728 fprintf (list_file, "\f");
729 }
730
731 fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
732 fprintf (list_file, "%s\n", title);
733 fprintf (list_file, "%s\n", subtitle);
734 on_page = 3;
735 eject = 0;
736 }
737}
738
752d5da4
NC
739/* Print a line into the list_file. Update the line count
740 and if necessary start a new page. */
741
742static void
743emit_line (list_info_type * list, const char * format, ...)
744{
745 va_list args;
746
747 va_start (args, format);
748
749 vfprintf (list_file, format, args);
750 on_page++;
751 listing_page (list);
752
753 va_end (args);
754}
755
252b5132 756static unsigned int
254d758c 757calc_hex (list_info_type *list)
252b5132
RH
758{
759 int data_buffer_size;
760 list_info_type *first = list;
cf39a089 761 unsigned int address = ~(unsigned int) 0;
252b5132
RH
762 fragS *frag;
763 fragS *frag_ptr;
bea9907b 764 unsigned int octet_in_frag;
252b5132 765
cf39a089 766 /* Find first frag which says it belongs to this line. */
252b5132
RH
767 frag = list->frag;
768 while (frag && frag->line != list)
769 frag = frag->fr_next;
770
771 frag_ptr = frag;
772
773 data_buffer_size = 0;
774
cf39a089 775 /* Dump all the frags which belong to this line. */
252b5132
RH
776 while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
777 {
cf39a089 778 /* Print as many bytes from the fixed part as is sensible. */
bea9907b
TW
779 octet_in_frag = 0;
780 while ((offsetT) octet_in_frag < frag_ptr->fr_fix
252b5132
RH
781 && data_buffer_size < MAX_BYTES - 3)
782 {
cf39a089 783 if (address == ~(unsigned int) 0)
5a1964ec 784 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
252b5132
RH
785
786 sprintf (data_buffer + data_buffer_size,
787 "%02X",
bea9907b 788 (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
252b5132 789 data_buffer_size += 2;
bea9907b 790 octet_in_frag++;
252b5132 791 }
411863a4
KH
792 if (frag_ptr->fr_type == rs_fill)
793 {
794 unsigned int var_rep_max = octet_in_frag;
795 unsigned int var_rep_idx = octet_in_frag;
796
797 /* Print as many bytes from the variable part as is sensible. */
798 while (((offsetT) octet_in_frag
799 < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset))
800 && data_buffer_size < MAX_BYTES - 3)
801 {
802 if (address == ~(unsigned int) 0)
5a1964ec
NC
803 address = frag_ptr->fr_address / OCTETS_PER_BYTE;
804
411863a4
KH
805 sprintf (data_buffer + data_buffer_size,
806 "%02X",
807 (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
411863a4 808 data_buffer_size += 2;
252b5132 809
411863a4
KH
810 var_rep_idx++;
811 octet_in_frag++;
252b5132 812
411863a4
KH
813 if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
814 var_rep_idx = var_rep_max;
815 }
816 }
252b5132
RH
817
818 frag_ptr = frag_ptr->fr_next;
819 }
820 data_buffer[data_buffer_size] = '\0';
821 return address;
822}
823
252b5132 824static void
254d758c 825print_lines (list_info_type *list, unsigned int lineno,
cd0bbe6e 826 const char *string, unsigned int address)
252b5132
RH
827{
828 unsigned int idx;
829 unsigned int nchars;
830 unsigned int lines;
bea9907b 831 unsigned int octet_in_word = 0;
252b5132 832 char *src = data_buffer;
bea9907b 833 int cur;
c71bb85d 834 struct list_message *msg;
252b5132 835
cf39a089 836 /* Print the stuff on the first line. */
252b5132
RH
837 listing_page (list);
838 nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
cf39a089
KH
839
840 /* Print the hex for the first line. */
841 if (address == ~(unsigned int) 0)
252b5132
RH
842 {
843 fprintf (list_file, "% 4d ", lineno);
844 for (idx = 0; idx < nchars; idx++)
845 fprintf (list_file, " ");
846
752d5da4 847 emit_line (NULL, "\t%s\n", string ? string : "");
252b5132
RH
848 return;
849 }
850
851 if (had_errors ())
852 fprintf (list_file, "% 4d ???? ", lineno);
853 else
854 fprintf (list_file, "% 4d %04x ", lineno, address);
855
cf39a089 856 /* And the data to go along with it. */
252b5132 857 idx = 0;
bea9907b
TW
858 cur = 0;
859 while (src[cur] && idx < nchars)
252b5132 860 {
bea9907b 861 int offset;
bea9907b 862 offset = cur;
cf39a089 863 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
bea9907b
TW
864 cur += 2;
865 octet_in_word++;
cf39a089 866
bea9907b 867 if (octet_in_word == LISTING_WORD_SIZE)
252b5132
RH
868 {
869 fprintf (list_file, " ");
870 idx++;
bea9907b 871 octet_in_word = 0;
252b5132 872 }
cf39a089 873
252b5132
RH
874 idx += 2;
875 }
cf39a089 876
252b5132
RH
877 for (; idx < nchars; idx++)
878 fprintf (list_file, " ");
cf39a089 879
752d5da4 880 emit_line (list, "\t%s\n", string ? string : "");
cf39a089 881
c71bb85d
SB
882 for (msg = list->messages; msg; msg = msg->next)
883 emit_line (list, "**** %s\n", msg->message);
cf39a089 884
252b5132
RH
885 for (lines = 0;
886 lines < (unsigned int) listing_lhs_cont_lines
bea9907b 887 && src[cur];
cf39a089 888 lines++)
252b5132 889 {
cf39a089 890 nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
252b5132 891 idx = 0;
cf39a089
KH
892
893 /* Print any more lines of data, but more compactly. */
252b5132 894 fprintf (list_file, "% 4d ", lineno);
cf39a089 895
bea9907b 896 while (src[cur] && idx < nchars)
252b5132 897 {
cf39a089
KH
898 int offset;
899 offset = cur;
900 fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
bea9907b 901 cur += 2;
252b5132 902 idx += 2;
bea9907b 903 octet_in_word++;
cf39a089 904
bea9907b 905 if (octet_in_word == LISTING_WORD_SIZE)
252b5132
RH
906 {
907 fprintf (list_file, " ");
908 idx++;
bea9907b 909 octet_in_word = 0;
252b5132
RH
910 }
911 }
cf39a089 912
752d5da4 913 emit_line (list, "\n");
252b5132
RH
914 }
915}
916
252b5132 917static void
254d758c 918list_symbol_table (void)
252b5132
RH
919{
920 extern symbolS *symbol_rootP;
921 int got_some = 0;
922
923 symbolS *ptr;
924 eject = 1;
752d5da4 925 listing_page (NULL);
252b5132
RH
926
927 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
928 {
929 if (SEG_NORMAL (S_GET_SEGMENT (ptr))
930 || S_GET_SEGMENT (ptr) == absolute_section)
931 {
252b5132 932 /* Don't report section symbols. They are not interesting. */
49309057 933 if (symbol_section_p (ptr))
252b5132 934 continue;
7be1c489 935
252b5132
RH
936 if (S_GET_NAME (ptr))
937 {
938 char buf[30], fmt[8];
939 valueT val = S_GET_VALUE (ptr);
940
941 /* @@ Note that this is dependent on the compilation options,
942 not solely on the target characteristics. */
943 if (sizeof (val) == 4 && sizeof (int) == 4)
944 sprintf (buf, "%08lx", (unsigned long) val);
945 else if (sizeof (val) <= sizeof (unsigned long))
946 {
947 sprintf (fmt, "%%0%lulx",
948 (unsigned long) (sizeof (val) * 2));
949 sprintf (buf, fmt, (unsigned long) val);
950 }
951#if defined (BFD64)
952 else if (sizeof (val) > 4)
953 sprintf_vma (buf, val);
954#endif
955 else
956 abort ();
957
958 if (!got_some)
959 {
960 fprintf (list_file, "DEFINED SYMBOLS\n");
961 on_page++;
962 got_some = 1;
963 }
964
49309057 965 if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
252b5132
RH
966 {
967 fprintf (list_file, "%20s:%-5d %s:%s %s\n",
49309057
ILT
968 symbol_get_frag (ptr)->line->file->filename,
969 symbol_get_frag (ptr)->line->line,
252b5132
RH
970 segment_name (S_GET_SEGMENT (ptr)),
971 buf, S_GET_NAME (ptr));
972 }
973 else
974 {
975 fprintf (list_file, "%33s:%s %s\n",
976 segment_name (S_GET_SEGMENT (ptr)),
977 buf, S_GET_NAME (ptr));
978 }
979
cf39a089 980 on_page++;
752d5da4 981 listing_page (NULL);
252b5132
RH
982 }
983 }
984
985 }
986 if (!got_some)
987 {
988 fprintf (list_file, "NO DEFINED SYMBOLS\n");
989 on_page++;
990 }
752d5da4 991 emit_line (NULL, "\n");
252b5132
RH
992
993 got_some = 0;
994
995 for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr))
996 {
997 if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0)
998 {
999 if (S_GET_SEGMENT (ptr) == undefined_section)
1000 {
1001 if (!got_some)
1002 {
1003 got_some = 1;
752d5da4
NC
1004
1005 emit_line (NULL, "UNDEFINED SYMBOLS\n");
252b5132 1006 }
752d5da4
NC
1007
1008 emit_line (NULL, "%s\n", S_GET_NAME (ptr));
252b5132
RH
1009 }
1010 }
1011 }
752d5da4 1012
252b5132 1013 if (!got_some)
752d5da4 1014 emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
252b5132
RH
1015}
1016
752d5da4
NC
1017typedef struct cached_line
1018{
1019 file_info_type * file;
1020 unsigned int line;
1021 char buffer [LISTING_RHS_WIDTH];
1022} cached_line;
1023
252b5132 1024static void
752d5da4
NC
1025print_source (file_info_type * current_file,
1026 list_info_type * list,
1027 unsigned int width)
252b5132 1028{
752d5da4
NC
1029#define NUM_CACHE_LINES 3
1030 static cached_line cached_lines[NUM_CACHE_LINES];
1031 static int next_free_line = 0;
3726e6c5 1032 cached_line * cache = NULL;
752d5da4
NC
1033
1034 if (current_file->linenum > list->hll_line
1035 && list->hll_line > 0)
1036 {
1037 /* This can happen with modern optimizing compilers. The source
1038 lines from the high level language input program are split up
1039 and interleaved, meaning the line number we want to display
1040 (list->hll_line) can have already been displayed. We have
1041 three choices:
1042
1043 a. Do nothing, since we have already displayed the source
1044 line. This was the old behaviour.
1045
1046 b. Display the particular line requested again, but only
1047 that line. This is the new behaviour.
1048
1049 c. Display the particular line requested again and reset
1050 the current_file->line_num value so that we redisplay
1051 all the following lines as well the next time we
1052 encounter a larger line number. */
1053 int i;
1054
1055 /* Check the cache, maybe we already have the line saved. */
1056 for (i = 0; i < NUM_CACHE_LINES; i++)
1057 if (cached_lines[i].file == current_file
1058 && cached_lines[i].line == list->hll_line)
1059 {
1060 cache = cached_lines + i;
1061 break;
1062 }
1063
1064 if (i == NUM_CACHE_LINES)
1065 {
1066 cache = cached_lines + next_free_line;
1067 next_free_line ++;
1068 if (next_free_line == NUM_CACHE_LINES)
1069 next_free_line = 0;
1070
1071 cache->file = current_file;
1072 cache->line = list->hll_line;
1073 cache->buffer[0] = 0;
1074 rebuffer_line (current_file, cache->line, cache->buffer, width);
1075 }
1076
1077 emit_line (list, "%4u:%-13s **** %s\n",
1078 cache->line, cache->file->filename, cache->buffer);
1079 return;
1080 }
1081
252b5132
RH
1082 if (!current_file->at_end)
1083 {
752d5da4
NC
1084 int num_lines_shown = 0;
1085
252b5132
RH
1086 while (current_file->linenum < list->hll_line
1087 && !current_file->at_end)
1088 {
cd0bbe6e 1089 const char *p;
752d5da4 1090
91d6fa6a 1091 cache = cached_lines + next_free_line;
752d5da4 1092 cache->file = current_file;
cc761f75 1093 cache->line = current_file->linenum + 1;
752d5da4
NC
1094 cache->buffer[0] = 0;
1095 p = buffer_line (current_file, cache->buffer, width);
1096
1097 /* Cache optimization: If printing a group of lines
1098 cache the first and last lines in the group. */
1099 if (num_lines_shown == 0)
1100 {
1101 next_free_line ++;
1102 if (next_free_line == NUM_CACHE_LINES)
1103 next_free_line = 0;
1104 }
5a1964ec 1105
752d5da4
NC
1106 emit_line (list, "%4u:%-13s **** %s\n",
1107 cache->line, cache->file->filename, p);
1108 num_lines_shown ++;
252b5132
RH
1109 }
1110 }
1111}
1112
1113/* Sometimes the user doesn't want to be bothered by the debugging
1114 records inserted by the compiler, see if the line is suspicious. */
1115
1116static int
254d758c 1117debugging_pseudo (list_info_type *list, const char *line)
252b5132 1118{
87975d2a 1119#ifdef OBJ_ELF
252b5132
RH
1120 static int in_debug;
1121 int was_debug;
87975d2a 1122#endif
252b5132
RH
1123
1124 if (list->debugging)
1125 {
87975d2a 1126#ifdef OBJ_ELF
252b5132 1127 in_debug = 1;
87975d2a 1128#endif
252b5132
RH
1129 return 1;
1130 }
87975d2a 1131#ifdef OBJ_ELF
252b5132
RH
1132 was_debug = in_debug;
1133 in_debug = 0;
87975d2a 1134#endif
252b5132 1135
3882b010 1136 while (ISSPACE (*line))
252b5132
RH
1137 line++;
1138
1139 if (*line != '.')
1140 {
1141#ifdef OBJ_ELF
1142 /* The ELF compiler sometimes emits blank lines after switching
1143 out of a debugging section. If the next line drops us back
1144 into debugging information, then don't print the blank line.
1145 This is a hack for a particular compiler behaviour, not a
1146 general case. */
1147 if (was_debug
1148 && *line == '\0'
1149 && list->next != NULL
1150 && list->next->debugging)
1151 {
1152 in_debug = 1;
1153 return 1;
1154 }
1155#endif
1156
1157 return 0;
1158 }
1159
1160 line++;
1161
1162 if (strncmp (line, "def", 3) == 0)
1163 return 1;
1164 if (strncmp (line, "val", 3) == 0)
1165 return 1;
1166 if (strncmp (line, "scl", 3) == 0)
1167 return 1;
1168 if (strncmp (line, "line", 4) == 0)
1169 return 1;
1170 if (strncmp (line, "endef", 5) == 0)
1171 return 1;
1172 if (strncmp (line, "ln", 2) == 0)
1173 return 1;
1174 if (strncmp (line, "type", 4) == 0)
1175 return 1;
1176 if (strncmp (line, "size", 4) == 0)
1177 return 1;
1178 if (strncmp (line, "dim", 3) == 0)
1179 return 1;
1180 if (strncmp (line, "tag", 3) == 0)
1181 return 1;
252b5132
RH
1182 if (strncmp (line, "stabs", 5) == 0)
1183 return 1;
1184 if (strncmp (line, "stabn", 5) == 0)
1185 return 1;
1186
1187 return 0;
1188}
1189
1190static void
254d758c 1191listing_listing (char *name ATTRIBUTE_UNUSED)
252b5132
RH
1192{
1193 list_info_type *list = head;
1194 file_info_type *current_hll_file = (file_info_type *) NULL;
252b5132 1195 char *buffer;
cd0bbe6e 1196 const char *p;
252b5132
RH
1197 int show_listing = 1;
1198 unsigned int width;
1199
add39d23
TS
1200 buffer = XNEWVEC (char, listing_rhs_width);
1201 data_buffer = XNEWVEC (char, MAX_BYTES);
252b5132 1202 eject = 1;
252b5132
RH
1203 list = head->next;
1204
252b5132
RH
1205 while (list)
1206 {
ab9da554 1207 unsigned int list_line;
252b5132
RH
1208
1209 width = listing_rhs_width > paper_width ? paper_width :
1210 listing_rhs_width;
1211
1212 list_line = list->line;
1213 switch (list->edict)
1214 {
1215 case EDICT_LIST:
1216 /* Skip all lines up to the current. */
1217 list_line--;
1218 break;
1219 case EDICT_NOLIST:
1220 show_listing--;
1221 break;
1222 case EDICT_NOLIST_NEXT:
61b96bb4
AM
1223 if (show_listing == 0)
1224 list_line--;
252b5132
RH
1225 break;
1226 case EDICT_EJECT:
1227 break;
1228 case EDICT_NONE:
1229 break;
1230 case EDICT_TITLE:
1231 title = list->edict_arg;
1232 break;
1233 case EDICT_SBTTL:
1234 subtitle = list->edict_arg;
1235 break;
1236 default:
1237 abort ();
1238 }
1239
1240 if (show_listing <= 0)
1241 {
1242 while (list->file->linenum < list_line
1243 && !list->file->at_end)
1244 p = buffer_line (list->file, buffer, width);
1245 }
1246
61b96bb4
AM
1247 if (list->edict == EDICT_LIST
1248 || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
252b5132
RH
1249 {
1250 /* Enable listing for the single line that caused the enable. */
1251 list_line++;
1252 show_listing++;
1253 }
1254
1255 if (show_listing > 0)
1256 {
1257 /* Scan down the list and print all the stuff which can be done
1258 with this line (or lines). */
252b5132 1259 if (list->hll_file)
5a1964ec 1260 current_hll_file = list->hll_file;
252b5132
RH
1261
1262 if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
752d5da4 1263 print_source (current_hll_file, list, width);
252b5132
RH
1264
1265 if (list->line_contents)
1266 {
1267 if (!((listing & LISTING_NODEBUG)
1268 && debugging_pseudo (list, list->line_contents)))
5a1964ec
NC
1269 print_lines (list,
1270 list->file->linenum == 0 ? list->line : list->file->linenum,
1271 list->line_contents, calc_hex (list));
1272
252b5132
RH
1273 free (list->line_contents);
1274 list->line_contents = NULL;
1275 }
1276 else
1277 {
1278 while (list->file->linenum < list_line
1279 && !list->file->at_end)
1280 {
1281 unsigned int address;
1282
1283 p = buffer_line (list->file, buffer, width);
1284
1285 if (list->file->linenum < list_line)
cf39a089 1286 address = ~(unsigned int) 0;
252b5132
RH
1287 else
1288 address = calc_hex (list);
1289
1290 if (!((listing & LISTING_NODEBUG)
1291 && debugging_pseudo (list, p)))
1292 print_lines (list, list->file->linenum, p, address);
1293 }
1294 }
1295
1296 if (list->edict == EDICT_EJECT)
5a1964ec 1297 eject = 1;
252b5132
RH
1298 }
1299
61b96bb4 1300 if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
252b5132
RH
1301 --show_listing;
1302
1303 list = list->next;
1304 }
1305
1306 free (buffer);
1307 free (data_buffer);
1308 data_buffer = NULL;
1309}
1310
83f10cb2
NC
1311/* Print time stamp in ISO format: yyyy-mm-ddThh:mm:ss.ss+/-zzzz. */
1312
1313static void
1314print_timestamp (void)
1315{
1316 const time_t now = time (NULL);
d5a35a55 1317 struct tm * timestamp;
83f10cb2
NC
1318 char stampstr[MAX_DATELEN];
1319
1320 /* Any portable way to obtain subsecond values??? */
d5a35a55
NC
1321 timestamp = localtime (&now);
1322 strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
83f10cb2
NC
1323 fprintf (list_file, _("\n time stamp \t: %s\n\n"), stampstr);
1324}
1325
1326static void
1327print_single_option (char * opt, int *pos)
1328{
1329 int opt_len = strlen (opt);
1330
1331 if ((*pos + opt_len) < paper_width)
1332 {
1333 fprintf (list_file, _("%s "), opt);
1334 *pos = *pos + opt_len;
1335 }
1336 else
1337 {
1338 fprintf (list_file, _("\n\t%s "), opt);
1339 *pos = opt_len;
1340 }
1341}
1342
1343/* Print options passed to as. */
1344
1345static void
1346print_options (char ** argv)
1347{
1348 const char *field_name = _("\n options passed\t: ");
1349 int pos = strlen (field_name);
1350 char **p;
1351
ead47374 1352 fputs (field_name, list_file);
83f10cb2
NC
1353 for (p = &argv[1]; *p != NULL; p++)
1354 if (**p == '-')
1355 {
1356 /* Ignore these. */
1357 if (strcmp (*p, "-o") == 0)
1358 {
1359 if (p[1] != NULL)
1360 p++;
1361 continue;
1362 }
1363 if (strcmp (*p, "-v") == 0)
1364 continue;
1365
1366 print_single_option (*p, &pos);
1367 }
1368}
1369
1370/* Print a first section with basic info like file names, as version,
1371 options passed, target, and timestamp.
1372 The format of this section is as follows:
1373
1374 AS VERSION
1375
1376 fieldname TAB ':' fieldcontents
1377 { TAB fieldcontents-cont } */
1378
1379static void
1380listing_general_info (char ** argv)
1381{
1382 /* Print the stuff on the first line. */
1383 eject = 1;
752d5da4 1384 listing_page (NULL);
83f10cb2
NC
1385
1386 fprintf (list_file,
1387 _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1388 VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1389 print_options (argv);
1390 fprintf (list_file, _("\n input file \t: %s"), fn);
1391 fprintf (list_file, _("\n output file \t: %s"), out_file_name);
1392 fprintf (list_file, _("\n target \t: %s"), TARGET_CANONICAL);
1393 print_timestamp ();
1394}
1395
252b5132 1396void
83f10cb2 1397listing_print (char *name, char **argv)
252b5132
RH
1398{
1399 int using_stdout;
cf39a089 1400
252b5132
RH
1401 title = "";
1402 subtitle = "";
1403
1404 if (name == NULL)
1405 {
1406 list_file = stdout;
1407 using_stdout = 1;
1408 }
1409 else
1410 {
f740e790 1411 list_file = fopen (name, FOPEN_WT);
252b5132
RH
1412 if (list_file != NULL)
1413 using_stdout = 0;
1414 else
1415 {
885afe7b 1416 as_warn (_("can't open %s: %s"), name, xstrerror (errno));
252b5132
RH
1417 list_file = stdout;
1418 using_stdout = 1;
1419 }
1420 }
1421
1422 if (listing & LISTING_NOFORM)
5a1964ec 1423 paper_height = 0;
252b5132 1424
83f10cb2
NC
1425 if (listing & LISTING_GENERAL)
1426 listing_general_info (argv);
1427
252b5132 1428 if (listing & LISTING_LISTING)
5a1964ec 1429 listing_listing (name);
252b5132
RH
1430
1431 if (listing & LISTING_SYMBOLS)
5a1964ec 1432 list_symbol_table ();
252b5132
RH
1433
1434 if (! using_stdout)
1435 {
1436 if (fclose (list_file) == EOF)
885afe7b 1437 as_warn (_("can't close %s: %s"), name, xstrerror (errno));
252b5132
RH
1438 }
1439
1440 if (last_open_file)
5a1964ec 1441 fclose (last_open_file);
252b5132
RH
1442}
1443
252b5132 1444void
254d758c 1445listing_file (const char *name)
252b5132
RH
1446{
1447 fn = name;
1448}
1449
1450void
254d758c 1451listing_eject (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1452{
1453 if (listing)
1454 listing_tail->edict = EDICT_EJECT;
1455}
1456
252b5132
RH
1457/* Turn listing on or off. An argument of 0 means to turn off
1458 listing. An argument of 1 means to turn on listing. An argument
1459 of 2 means to turn off listing, but as of the next line; that is,
1460 the current line should be listed, but the next line should not. */
1461
1462void
254d758c 1463listing_list (int on)
252b5132
RH
1464{
1465 if (listing)
1466 {
1467 switch (on)
1468 {
1469 case 0:
1470 if (listing_tail->edict == EDICT_LIST)
1471 listing_tail->edict = EDICT_NONE;
1472 else
1473 listing_tail->edict = EDICT_NOLIST;
1474 break;
1475 case 1:
1476 if (listing_tail->edict == EDICT_NOLIST
1477 || listing_tail->edict == EDICT_NOLIST_NEXT)
1478 listing_tail->edict = EDICT_NONE;
1479 else
1480 listing_tail->edict = EDICT_LIST;
1481 break;
1482 case 2:
1483 listing_tail->edict = EDICT_NOLIST_NEXT;
1484 break;
1485 default:
1486 abort ();
1487 }
1488 }
1489}
1490
252b5132 1491void
254d758c 1492listing_psize (int width_only)
252b5132
RH
1493{
1494 if (! width_only)
1495 {
1496 paper_height = get_absolute_expression ();
1497
1498 if (paper_height < 0 || paper_height > 1000)
1499 {
1500 paper_height = 0;
1501 as_warn (_("strange paper height, set to no form"));
1502 }
1503
1504 if (*input_line_pointer != ',')
1505 {
1506 demand_empty_rest_of_line ();
1507 return;
1508 }
1509
1510 ++input_line_pointer;
1511 }
1512
1513 paper_width = get_absolute_expression ();
1514
1515 demand_empty_rest_of_line ();
1516}
1517
1518void
254d758c 1519listing_nopage (int ignore ATTRIBUTE_UNUSED)
252b5132
RH
1520{
1521 paper_height = 0;
1522}
1523
1524void
254d758c 1525listing_title (int depth)
252b5132
RH
1526{
1527 int quoted;
1528 char *start;
1529 char *ttl;
1530 unsigned int length;
1531
1532 SKIP_WHITESPACE ();
1533 if (*input_line_pointer != '\"')
1534 quoted = 0;
1535 else
1536 {
1537 quoted = 1;
1538 ++input_line_pointer;
1539 }
1540
1541 start = input_line_pointer;
1542
1543 while (*input_line_pointer)
1544 {
1545 if (quoted
1546 ? *input_line_pointer == '\"'
1547 : is_end_of_line[(unsigned char) *input_line_pointer])
1548 {
1549 if (listing)
1550 {
1551 length = input_line_pointer - start;
29a2809e 1552 ttl = xmemdup0 (start, length);
252b5132
RH
1553 listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
1554 listing_tail->edict_arg = ttl;
1555 }
1556 if (quoted)
1557 input_line_pointer++;
1558 demand_empty_rest_of_line ();
1559 return;
1560 }
1561 else if (*input_line_pointer == '\n')
1562 {
0e389e77 1563 as_bad (_("new line in title"));
252b5132
RH
1564 demand_empty_rest_of_line ();
1565 return;
1566 }
1567 else
1568 {
1569 input_line_pointer++;
1570 }
1571 }
1572}
1573
252b5132 1574void
254d758c 1575listing_source_line (unsigned int line)
252b5132
RH
1576{
1577 if (listing)
1578 {
1579 new_frag ();
1580 listing_tail->hll_line = line;
1581 new_frag ();
1582 }
1583}
1584
1585void
254d758c 1586listing_source_file (const char *file)
252b5132
RH
1587{
1588 if (listing)
1589 listing_tail->hll_file = file_info (file);
1590}
1591
252b5132
RH
1592#else
1593
cf39a089 1594/* Dummy functions for when compiled without listing enabled. */
252b5132 1595
cf39a089 1596void
254d758c 1597listing_list (int on)
252b5132
RH
1598{
1599 s_ignore (0);
1600}
1601
cf39a089 1602void
254d758c 1603listing_eject (int ignore)
252b5132
RH
1604{
1605 s_ignore (0);
1606}
1607
cf39a089 1608void
254d758c 1609listing_psize (int ignore)
252b5132
RH
1610{
1611 s_ignore (0);
1612}
1613
1614void
254d758c 1615listing_nopage (int ignore)
252b5132
RH
1616{
1617 s_ignore (0);
1618}
1619
cf39a089 1620void
254d758c 1621listing_title (int depth)
252b5132
RH
1622{
1623 s_ignore (0);
1624}
1625
1626void
254d758c 1627listing_file (const char *name)
252b5132 1628{
252b5132
RH
1629}
1630
cf39a089 1631void
254d758c 1632listing_newline (char *name)
252b5132 1633{
252b5132
RH
1634}
1635
cf39a089 1636void
254d758c 1637listing_source_line (unsigned int n)
252b5132 1638{
252b5132 1639}
cf39a089
KH
1640
1641void
254d758c 1642listing_source_file (const char *n)
252b5132 1643{
252b5132
RH
1644}
1645
1646#endif
This page took 0.812709 seconds and 4 git commands to generate.