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