OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [listing.c] - Blame information for rev 179

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 147 khays
/* listing.c - maintain assembly listings
2
   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GAS, the GNU Assembler.
7
 
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
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
 
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.
17
 
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
20
   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21
   02110-1301, USA.  */
22
 
23
/* Contributed by Steve Chamberlain <sac@cygnus.com>
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
 
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
67
 function also remembers when the filename changes.
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
 
88
 LISTING_LHS_CONT_LINES Max number of lines to use up for a continuation
89
 LISTING_RHS_WIDTH      Number of chars from the input file to print
90
                        on a line.  */
91
 
92
#include "as.h"
93
#include "filenames.h"
94
#include "obstack.h"
95
#include "safe-ctype.h"
96
#include "input-file.h"
97
#include "subsegs.h"
98
#include "bfdver.h"
99
#include <time.h>
100
#include <stdarg.h>
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
111
#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
112
#endif
113
#ifndef LISTING_LHS_WIDTH_SECOND
114
#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
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
122
#define MAX_DATELEN 30
123
 
124
/* This structure remembers which .s were used.  */
125
typedef struct file_info_struct
126
{
127
  struct file_info_struct * next;
128
  char *                    filename;
129
  long                      pos;
130
  unsigned int              linenum;
131
  int                       at_end;
132
} file_info_type;
133
 
134
enum 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
 
146
/* This structure remembers which line from which file goes into which
147
   frag.  */
148
struct list_info_struct
149
{
150
  /* Frag which this line of source is nearest to.  */
151
  fragS *frag;
152
 
153
  /* The actual line in the source file.  */
154
  unsigned int line;
155
 
156
  /* Pointer to the file info struct for the file which this line
157
     belongs to.  */
158
  file_info_type *file;
159
 
160
  /* The expanded text of any macro that may have been executing.  */
161
  char *line_contents;
162
 
163
  /* Next in list.  */
164
  struct list_info_struct *next;
165
 
166
  /* Pointer to the file info struct for the high level language
167
     source line that belongs here.  */
168
  file_info_type *hll_file;
169
 
170
  /* High level language source line.  */
171
  unsigned int hll_line;
172
 
173
  /* Pointer to any error message associated with this line.  */
174
  char *message;
175
 
176
  enum edict_enum edict;
177
  char *edict_arg;
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
 
185
typedef struct list_info_struct list_info_type;
186
 
187
int listing_lhs_width        = LISTING_LHS_WIDTH;
188
int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
189
int listing_lhs_cont_lines   = LISTING_LHS_CONT_LINES;
190
int listing_rhs_width        = LISTING_RHS_WIDTH;
191
 
192
struct list_info_struct *        listing_tail;
193
 
194
static file_info_type *          file_info_head;
195
static file_info_type *          last_open_file_info;
196
static FILE *                    last_open_file;
197
static struct list_info_struct * head;
198
static int                       paper_width = 200;
199
static int                       paper_height = 60;
200
 
201
extern int                       listing;
202
 
203
/* File to output listings to.  */
204
static FILE *list_file;
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
 
215
static char *data_buffer;
216
 
217
/* Prototypes.  */
218
static void listing_message (const char *, const char *);
219
static file_info_type *file_info (const char *);
220
static void new_frag (void);
221
static void listing_page (list_info_type *);
222
static unsigned int calc_hex (list_info_type *);
223
static void print_lines (list_info_type *, unsigned int, char *, unsigned int);
224
static void list_symbol_table (void);
225
static int debugging_pseudo (list_info_type *, const char *);
226
static void listing_listing (char *);
227
 
228
static void
229
listing_message (const char *name, const char *message)
230
{
231
  if (listing_tail != (list_info_type *) NULL)
232
    {
233
      unsigned int l = strlen (name) + strlen (message) + 1;
234
      char *n = (char *) xmalloc (l);
235
      strcpy (n, name);
236
      strcat (n, message);
237
      listing_tail->message = n;
238
    }
239
}
240
 
241
void
242
listing_warning (const char *message)
243
{
244
  listing_message (_("Warning:"), message);
245
}
246
 
247
void
248
listing_error (const char *message)
249
{
250
  listing_message (_("Error:"), message);
251
}
252
 
253
static file_info_type *
254
file_info (const char *file_name)
255
{
256
  /* Find an entry with this file name.  */
257
  file_info_type *p = file_info_head;
258
 
259
  while (p != (file_info_type *) NULL)
260
    {
261
      if (filename_cmp (p->filename, file_name) == 0)
262
        return p;
263
      p = p->next;
264
    }
265
 
266
  /* Make new entry.  */
267
  p = (file_info_type *) xmalloc (sizeof (file_info_type));
268
  p->next = file_info_head;
269
  file_info_head = p;
270
  p->filename = xstrdup (file_name);
271
  p->pos = 0;
272
  p->linenum = 0;
273
  p->at_end = 0;
274
 
275
  return p;
276
}
277
 
278
static void
279
new_frag (void)
280
{
281
  frag_wane (frag_now);
282
  frag_new (0);
283
}
284
 
285
void
286
listing_newline (char *ps)
287
{
288
  char *file;
289
  unsigned int line;
290
  static unsigned int last_line = 0xffff;
291
  static char *last_file = NULL;
292
  list_info_type *new_i = NULL;
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
    {
321
      if (line == last_line
322
          && !(last_file && file && filename_cmp (file, last_file)))
323
        return;
324
 
325
      new_i = (list_info_type *) xmalloc (sizeof (list_info_type));
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
 
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.  */
338
      if (strcmp (file, _("{standard input}")) == 0
339
          && input_line_pointer != NULL)
340
        {
341
          char *copy;
342
          int len;
343
          int seen_quote = 0;
344
          int seen_slash = 0;
345
 
346
          for (copy = input_line_pointer;
347
               *copy && (seen_quote
348
                         || is_end_of_line [(unsigned char) *copy] != 1);
349
               copy++)
350
            {
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;
357
            }
358
 
359
          len = copy - input_line_pointer + 1;
360
 
361
          copy = (char *) xmalloc (len);
362
 
363
          if (copy != NULL)
364
            {
365
              char *src = input_line_pointer;
366
              char *dest = copy;
367
 
368
              while (--len)
369
                {
370
                  unsigned char c = *src++;
371
 
372
                  /* Omit control characters in the listing.  */
373
                  if (!ISCNTRL (c))
374
                    *dest++ = c;
375
                }
376
 
377
              *dest = 0;
378
            }
379
 
380
          new_i->line_contents = copy;
381
        }
382
      else
383
        new_i->line_contents = NULL;
384
    }
385
  else
386
    {
387
      new_i = (list_info_type *) xmalloc (sizeof (list_info_type));
388
      new_i->line_contents = ps;
389
    }
390
 
391
  last_line = line;
392
  last_file = file;
393
 
394
  new_frag ();
395
 
396
  if (listing_tail)
397
    listing_tail->next = new_i;
398
  else
399
    head = new_i;
400
 
401
  listing_tail = new_i;
402
 
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;
412
 
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)
425
        new_i->debugging = 1;
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
 
436
void
437
listing_prev_line (void)
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
 
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
461
   file to make using the returned buffer simpler.  */
462
 
463
static char *
464
buffer_line (file_info_type *file, char *line, unsigned int size)
465
{
466
  unsigned int count = 0;
467
  int c;
468
  char *p = line;
469
 
470
  /* If we couldn't open the file, return an empty line.  */
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
 
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.  */
485
      last_open_file_info = file;
486
      last_open_file = fopen (file->filename, FOPEN_RB);
487
      if (last_open_file == NULL)
488
        {
489
          file->at_end = 1;
490
          return "";
491
        }
492
 
493
      /* Seek to where we were last time this file was open.  */
494
      if (file->pos)
495
        fseek (last_open_file, file->pos, SEEK_SET);
496
    }
497
 
498
  /* Leave room for null.  */
499
  size -= 1;
500
 
501
  c = fgetc (last_open_file);
502
 
503
  while (c != EOF && c != '\n' && c != '\r')
504
    {
505
      if (count < size)
506
        *p++ = c;
507
      count++;
508
 
509
      c = fgetc (last_open_file);
510
    }
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);
517
 
518
      if ((c == '\r' && next != '\n')
519
          || (c == '\n' && next != '\r'))
520
        ungetc (next, last_open_file);
521
    }
522
 
523
  if (c == EOF)
524
    {
525
      file->at_end = 1;
526
      if (count + 2 < size)
527
        {
528
          *p++ = '.';
529
          *p++ = '.';
530
          *p++ = '.';
531
        }
532
    }
533
  file->linenum++;
534
  *p++ = 0;
535
  return line;
536
}
537
 
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
 
543
static char *
544
rebuffer_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
 
649
static const char *fn;
650
 
651
static unsigned int eject;      /* Eject pending */
652
static unsigned int page;       /* Current page number */
653
static char *title;             /* Current title */
654
static char *subtitle;          /* Current subtitle */
655
static unsigned int on_page;    /* Number of lines printed on current page */
656
 
657
static void
658
listing_page (list_info_type *list)
659
{
660
  /* Grope around, see if we can see a title or subtitle edict coming up
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)
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
 
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
 
700
/* Print a line into the list_file.  Update the line count
701
   and if necessary start a new page.  */
702
 
703
static void
704
emit_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
 
717
static unsigned int
718
calc_hex (list_info_type *list)
719
{
720
  int data_buffer_size;
721
  list_info_type *first = list;
722
  unsigned int address = ~(unsigned int) 0;
723
  fragS *frag;
724
  fragS *frag_ptr;
725
  unsigned int octet_in_frag;
726
 
727
  /* Find first frag which says it belongs to this line.  */
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
 
736
  /* Dump all the frags which belong to this line.  */
737
  while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
738
    {
739
      /* Print as many bytes from the fixed part as is sensible.  */
740
      octet_in_frag = 0;
741
      while ((offsetT) octet_in_frag < frag_ptr->fr_fix
742
             && data_buffer_size < MAX_BYTES - 3)
743
        {
744
          if (address == ~(unsigned int) 0)
745
            address = frag_ptr->fr_address / OCTETS_PER_BYTE;
746
 
747
          sprintf (data_buffer + data_buffer_size,
748
                   "%02X",
749
                   (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
750
          data_buffer_size += 2;
751
          octet_in_frag++;
752
        }
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)
764
                address = frag_ptr->fr_address / OCTETS_PER_BYTE;
765
 
766
              sprintf (data_buffer + data_buffer_size,
767
                       "%02X",
768
                       (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
769
              data_buffer_size += 2;
770
 
771
              var_rep_idx++;
772
              octet_in_frag++;
773
 
774
              if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
775
                var_rep_idx = var_rep_max;
776
            }
777
        }
778
 
779
      frag_ptr = frag_ptr->fr_next;
780
    }
781
  data_buffer[data_buffer_size] = '\0';
782
  return address;
783
}
784
 
785
static void
786
print_lines (list_info_type *list, unsigned int lineno,
787
             char *string, unsigned int address)
788
{
789
  unsigned int idx;
790
  unsigned int nchars;
791
  unsigned int lines;
792
  unsigned int octet_in_word = 0;
793
  char *src = data_buffer;
794
  int cur;
795
 
796
  /* Print the stuff on the first line.  */
797
  listing_page (list);
798
  nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
799
 
800
  /* Print the hex for the first line.  */
801
  if (address == ~(unsigned int) 0)
802
    {
803
      fprintf (list_file, "% 4d     ", lineno);
804
      for (idx = 0; idx < nchars; idx++)
805
        fprintf (list_file, " ");
806
 
807
      emit_line (NULL, "\t%s\n", string ? string : "");
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
 
816
  /* And the data to go along with it.  */
817
  idx = 0;
818
  cur = 0;
819
  while (src[cur] && idx < nchars)
820
    {
821
      int offset;
822
      offset = cur;
823
      fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
824
      cur += 2;
825
      octet_in_word++;
826
 
827
      if (octet_in_word == LISTING_WORD_SIZE)
828
        {
829
          fprintf (list_file, " ");
830
          idx++;
831
          octet_in_word = 0;
832
        }
833
 
834
      idx += 2;
835
    }
836
 
837
  for (; idx < nchars; idx++)
838
    fprintf (list_file, " ");
839
 
840
  emit_line (list, "\t%s\n", string ? string : "");
841
 
842
  if (list->message)
843
    emit_line (list, "****  %s\n", list->message);
844
 
845
  for (lines = 0;
846
       lines < (unsigned int) listing_lhs_cont_lines
847
         && src[cur];
848
       lines++)
849
    {
850
      nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
851
      idx = 0;
852
 
853
      /* Print any more lines of data, but more compactly.  */
854
      fprintf (list_file, "% 4d      ", lineno);
855
 
856
      while (src[cur] && idx < nchars)
857
        {
858
          int offset;
859
          offset = cur;
860
          fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
861
          cur += 2;
862
          idx += 2;
863
          octet_in_word++;
864
 
865
          if (octet_in_word == LISTING_WORD_SIZE)
866
            {
867
              fprintf (list_file, " ");
868
              idx++;
869
              octet_in_word = 0;
870
            }
871
        }
872
 
873
      emit_line (list, "\n");
874
    }
875
}
876
 
877
static void
878
list_symbol_table (void)
879
{
880
  extern symbolS *symbol_rootP;
881
  int got_some = 0;
882
 
883
  symbolS *ptr;
884
  eject = 1;
885
  listing_page (NULL);
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
        {
892
          /* Don't report section symbols.  They are not interesting.  */
893
          if (symbol_section_p (ptr))
894
            continue;
895
 
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
 
925
              if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
926
                {
927
                  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
928
                           symbol_get_frag (ptr)->line->file->filename,
929
                           symbol_get_frag (ptr)->line->line,
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
 
940
              on_page++;
941
              listing_page (NULL);
942
            }
943
        }
944
 
945
    }
946
  if (!got_some)
947
    {
948
      fprintf (list_file, "NO DEFINED SYMBOLS\n");
949
      on_page++;
950
    }
951
  emit_line (NULL, "\n");
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;
964
 
965
                  emit_line (NULL, "UNDEFINED SYMBOLS\n");
966
                }
967
 
968
              emit_line (NULL, "%s\n", S_GET_NAME (ptr));
969
            }
970
        }
971
    }
972
 
973
  if (!got_some)
974
    emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
975
}
976
 
977
typedef struct cached_line
978
{
979
  file_info_type * file;
980
  unsigned int     line;
981
  char             buffer [LISTING_RHS_WIDTH];
982
} cached_line;
983
 
984
static void
985
print_source (file_info_type *  current_file,
986
              list_info_type *  list,
987
              unsigned int      width)
988
{
989
#define NUM_CACHE_LINES  3
990
  static cached_line cached_lines[NUM_CACHE_LINES];
991
  static int next_free_line = 0;
992
  cached_line * cache = NULL;
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
 
1042
  if (!current_file->at_end)
1043
    {
1044
      int num_lines_shown = 0;
1045
 
1046
      while (current_file->linenum < list->hll_line
1047
             && !current_file->at_end)
1048
        {
1049
          char *p;
1050
 
1051
          cache = cached_lines + next_free_line;
1052
          cache->file = current_file;
1053
          cache->line = current_file->linenum + 1;
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
            }
1065
 
1066
          emit_line (list, "%4u:%-13s **** %s\n",
1067
                     cache->line, cache->file->filename, p);
1068
          num_lines_shown ++;
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
 
1076
static int
1077
debugging_pseudo (list_info_type *list, const char *line)
1078
{
1079
#ifdef OBJ_ELF
1080
  static int in_debug;
1081
  int was_debug;
1082
#endif
1083
 
1084
  if (list->debugging)
1085
    {
1086
#ifdef OBJ_ELF
1087
      in_debug = 1;
1088
#endif
1089
      return 1;
1090
    }
1091
#ifdef OBJ_ELF
1092
  was_debug = in_debug;
1093
  in_debug = 0;
1094
#endif
1095
 
1096
  while (ISSPACE (*line))
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;
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
 
1150
static void
1151
listing_listing (char *name ATTRIBUTE_UNUSED)
1152
{
1153
  list_info_type *list = head;
1154
  file_info_type *current_hll_file = (file_info_type *) NULL;
1155
  char *buffer;
1156
  char *p;
1157
  int show_listing = 1;
1158
  unsigned int width;
1159
 
1160
  buffer = (char *) xmalloc (listing_rhs_width);
1161
  data_buffer = (char *) xmalloc (MAX_BYTES);
1162
  eject = 1;
1163
  list = head->next;
1164
 
1165
  while (list)
1166
    {
1167
      unsigned int list_line;
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:
1183
          if (show_listing == 0)
1184
            list_line--;
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
 
1207
      if (list->edict == EDICT_LIST
1208
          || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
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).  */
1219
          if (list->hll_file)
1220
            current_hll_file = list->hll_file;
1221
 
1222
          if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1223
            print_source (current_hll_file, list, width);
1224
 
1225
          if (list->line_contents)
1226
            {
1227
              if (!((listing & LISTING_NODEBUG)
1228
                    && debugging_pseudo (list, list->line_contents)))
1229
                print_lines (list,
1230
                             list->file->linenum == 0 ? list->line : list->file->linenum,
1231
                             list->line_contents, calc_hex (list));
1232
 
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)
1246
                    address = ~(unsigned int) 0;
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)
1257
            eject = 1;
1258
        }
1259
 
1260
      if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1261
        --show_listing;
1262
 
1263
      list = list->next;
1264
    }
1265
 
1266
  free (buffer);
1267
  free (data_buffer);
1268
  data_buffer = NULL;
1269
}
1270
 
1271
/* Print time stamp in ISO format:  yyyy-mm-ddThh:mm:ss.ss+/-zzzz.  */
1272
 
1273
static void
1274
print_timestamp (void)
1275
{
1276
  const time_t now = time (NULL);
1277
  struct tm * timestamp;
1278
  char stampstr[MAX_DATELEN];
1279
 
1280
  /* Any portable way to obtain subsecond values???  */
1281
  timestamp = localtime (&now);
1282
  strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1283
  fprintf (list_file, _("\n time stamp    \t: %s\n\n"), stampstr);
1284
}
1285
 
1286
static void
1287
print_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
 
1305
static void
1306
print_options (char ** argv)
1307
{
1308
  const char *field_name = _("\n options passed\t: ");
1309
  int pos = strlen (field_name);
1310
  char **p;
1311
 
1312
  fputs (field_name, list_file);
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
 
1339
static void
1340
listing_general_info (char ** argv)
1341
{
1342
  /* Print the stuff on the first line.  */
1343
  eject = 1;
1344
  listing_page (NULL);
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
 
1356
void
1357
listing_print (char *name, char **argv)
1358
{
1359
  int using_stdout;
1360
 
1361
  title = "";
1362
  subtitle = "";
1363
 
1364
  if (name == NULL)
1365
    {
1366
      list_file = stdout;
1367
      using_stdout = 1;
1368
    }
1369
  else
1370
    {
1371
      list_file = fopen (name, FOPEN_WT);
1372
      if (list_file != NULL)
1373
        using_stdout = 0;
1374
      else
1375
        {
1376
          as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1377
          list_file = stdout;
1378
          using_stdout = 1;
1379
        }
1380
    }
1381
 
1382
  if (listing & LISTING_NOFORM)
1383
    paper_height = 0;
1384
 
1385
  if (listing & LISTING_GENERAL)
1386
    listing_general_info (argv);
1387
 
1388
  if (listing & LISTING_LISTING)
1389
    listing_listing (name);
1390
 
1391
  if (listing & LISTING_SYMBOLS)
1392
    list_symbol_table ();
1393
 
1394
  if (! using_stdout)
1395
    {
1396
      if (fclose (list_file) == EOF)
1397
        as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1398
    }
1399
 
1400
  if (last_open_file)
1401
    fclose (last_open_file);
1402
}
1403
 
1404
void
1405
listing_file (const char *name)
1406
{
1407
  fn = name;
1408
}
1409
 
1410
void
1411
listing_eject (int ignore ATTRIBUTE_UNUSED)
1412
{
1413
  if (listing)
1414
    listing_tail->edict = EDICT_EJECT;
1415
}
1416
 
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
 
1422
void
1423
listing_list (int on)
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
 
1451
void
1452
listing_psize (int width_only)
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
 
1478
void
1479
listing_nopage (int ignore ATTRIBUTE_UNUSED)
1480
{
1481
  paper_height = 0;
1482
}
1483
 
1484
void
1485
listing_title (int depth)
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;
1512
              ttl = (char *) xmalloc (length + 1);
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
        {
1525
          as_bad (_("new line in title"));
1526
          demand_empty_rest_of_line ();
1527
          return;
1528
        }
1529
      else
1530
        {
1531
          input_line_pointer++;
1532
        }
1533
    }
1534
}
1535
 
1536
void
1537
listing_source_line (unsigned int line)
1538
{
1539
  if (listing)
1540
    {
1541
      new_frag ();
1542
      listing_tail->hll_line = line;
1543
      new_frag ();
1544
    }
1545
}
1546
 
1547
void
1548
listing_source_file (const char *file)
1549
{
1550
  if (listing)
1551
    listing_tail->hll_file = file_info (file);
1552
}
1553
 
1554
#else
1555
 
1556
/* Dummy functions for when compiled without listing enabled.  */
1557
 
1558
void
1559
listing_list (int on)
1560
{
1561
  s_ignore (0);
1562
}
1563
 
1564
void
1565
listing_eject (int ignore)
1566
{
1567
  s_ignore (0);
1568
}
1569
 
1570
void
1571
listing_psize (int ignore)
1572
{
1573
  s_ignore (0);
1574
}
1575
 
1576
void
1577
listing_nopage (int ignore)
1578
{
1579
  s_ignore (0);
1580
}
1581
 
1582
void
1583
listing_title (int depth)
1584
{
1585
  s_ignore (0);
1586
}
1587
 
1588
void
1589
listing_file (const char *name)
1590
{
1591
}
1592
 
1593
void
1594
listing_newline (char *name)
1595
{
1596
}
1597
 
1598
void
1599
listing_source_line (unsigned int n)
1600
{
1601
}
1602
 
1603
void
1604
listing_source_file (const char *n)
1605
{
1606
}
1607
 
1608
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.