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