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