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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gas/] [listing.c] - Blame information for rev 853

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

Line No. Rev Author Line
1 205 julius
/* 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 "obstack.h"
94
#include "safe-ctype.h"
95
#include "input-file.h"
96
#include "subsegs.h"
97
#include "bfdver.h"
98
#include <time.h>
99
#include <stdarg.h>
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
110
#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE))
111
#endif
112
#ifndef LISTING_LHS_WIDTH_SECOND
113
#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH
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
121
#define MAX_DATELEN 30
122
 
123
/* This structure remembers which .s were used.  */
124
typedef struct file_info_struct
125
{
126
  struct file_info_struct * next;
127
  char *                    filename;
128
  long                      pos;
129
  unsigned int              linenum;
130
  int                       at_end;
131
} file_info_type;
132
 
133
enum 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
 
145
/* This structure remembers which line from which file goes into which
146
   frag.  */
147
struct list_info_struct
148
{
149
  /* Frag which this line of source is nearest to.  */
150
  fragS *frag;
151
 
152
  /* The actual line in the source file.  */
153
  unsigned int line;
154
 
155
  /* Pointer to the file info struct for the file which this line
156
     belongs to.  */
157
  file_info_type *file;
158
 
159
  /* The expanded text of any macro that may have been executing.  */
160
  char *line_contents;
161
 
162
  /* Next in list.  */
163
  struct list_info_struct *next;
164
 
165
  /* Pointer to the file info struct for the high level language
166
     source line that belongs here.  */
167
  file_info_type *hll_file;
168
 
169
  /* High level language source line.  */
170
  unsigned int hll_line;
171
 
172
  /* Pointer to any error message associated with this line.  */
173
  char *message;
174
 
175
  enum edict_enum edict;
176
  char *edict_arg;
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
 
184
typedef struct list_info_struct list_info_type;
185
 
186
int listing_lhs_width        = LISTING_LHS_WIDTH;
187
int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND;
188
int listing_lhs_cont_lines   = LISTING_LHS_CONT_LINES;
189
int listing_rhs_width        = LISTING_RHS_WIDTH;
190
 
191
struct list_info_struct *        listing_tail;
192
 
193
static file_info_type *          file_info_head;
194
static file_info_type *          last_open_file_info;
195
static FILE *                    last_open_file;
196
static struct list_info_struct * head;
197
static int                       paper_width = 200;
198
static int                       paper_height = 60;
199
 
200
extern int                       listing;
201
 
202
/* File to output listings to.  */
203
static FILE *list_file;
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
 
214
static char *data_buffer;
215
 
216
/* Prototypes.  */
217
static void listing_message (const char *, const char *);
218
static file_info_type *file_info (const char *);
219
static void new_frag (void);
220
static void listing_page (list_info_type *);
221
static unsigned int calc_hex (list_info_type *);
222
static void print_lines (list_info_type *, unsigned int, char *, unsigned int);
223
static void list_symbol_table (void);
224
static int debugging_pseudo (list_info_type *, const char *);
225
static void listing_listing (char *);
226
 
227
static void
228
listing_message (const char *name, const char *message)
229
{
230
  if (listing_tail != (list_info_type *) NULL)
231
    {
232
      unsigned int l = strlen (name) + strlen (message) + 1;
233
      char *n = (char *) xmalloc (l);
234
      strcpy (n, name);
235
      strcat (n, message);
236
      listing_tail->message = n;
237
    }
238
}
239
 
240
void
241
listing_warning (const char *message)
242
{
243
  listing_message (_("Warning:"), message);
244
}
245
 
246
void
247
listing_error (const char *message)
248
{
249
  listing_message (_("Error:"), message);
250
}
251
 
252
static file_info_type *
253
file_info (const char *file_name)
254
{
255
  /* Find an entry with this file name.  */
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
 
265
  /* Make new entry.  */
266
  p = (file_info_type *) xmalloc (sizeof (file_info_type));
267
  p->next = file_info_head;
268
  file_info_head = p;
269
  p->filename = xstrdup (file_name);
270
  p->pos = 0;
271
  p->linenum = 0;
272
  p->at_end = 0;
273
 
274
  return p;
275
}
276
 
277
static void
278
new_frag (void)
279
{
280
  frag_wane (frag_now);
281
  frag_new (0);
282
}
283
 
284
void
285
listing_newline (char *ps)
286
{
287
  char *file;
288
  unsigned int line;
289
  static unsigned int last_line = 0xffff;
290
  static char *last_file = NULL;
291
  list_info_type *new_i = NULL;
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
    {
320
      if (line == last_line
321
          && !(last_file && file && strcmp (file, last_file)))
322
        return;
323
 
324
      new_i = (list_info_type *) xmalloc (sizeof (list_info_type));
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
 
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.  */
337
      if (strcmp (file, _("{standard input}")) == 0
338
          && input_line_pointer != NULL)
339
        {
340
          char *copy;
341
          int len;
342
          int seen_quote = 0;
343
          int seen_slash = 0;
344
 
345
          for (copy = input_line_pointer - 1;
346
               *copy && (seen_quote
347
                         || is_end_of_line [(unsigned char) *copy] != 1);
348
               copy++)
349
            {
350
              if (*copy == '\\')
351
                seen_slash = ! seen_slash;
352
              else if (*copy == '"' && seen_slash)
353
                seen_quote = ! seen_quote;
354
            }
355
 
356
          len = (copy - input_line_pointer) + 2;
357
 
358
          copy = (char *) xmalloc (len);
359
 
360
          if (copy != NULL)
361
            {
362
              char *src = input_line_pointer - 1;
363
              char *dest = copy;
364
 
365
              while (--len)
366
                {
367
                  unsigned char c = *src++;
368
 
369
                  /* Omit control characters in the listing.  */
370
                  if (!ISCNTRL (c))
371
                    *dest++ = c;
372
                }
373
 
374
              *dest = 0;
375
            }
376
 
377
          new_i->line_contents = copy;
378
        }
379
      else
380
        new_i->line_contents = NULL;
381
    }
382
  else
383
    {
384
      new_i = (list_info_type *) xmalloc (sizeof (list_info_type));
385
      new_i->line_contents = ps;
386
    }
387
 
388
  last_line = line;
389
  last_file = file;
390
 
391
  new_frag ();
392
 
393
  if (listing_tail)
394
    listing_tail->next = new_i;
395
  else
396
    head = new_i;
397
 
398
  listing_tail = new_i;
399
 
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;
409
 
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)
422
        new_i->debugging = 1;
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
 
433
void
434
listing_prev_line (void)
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
 
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
458
   file to make using the returned buffer simpler.  */
459
 
460
static char *
461
buffer_line (file_info_type *file, char *line, unsigned int size)
462
{
463
  unsigned int count = 0;
464
  int c;
465
  char *p = line;
466
 
467
  /* If we couldn't open the file, return an empty line.  */
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
 
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.  */
482
      last_open_file_info = file;
483
      last_open_file = fopen (file->filename, FOPEN_RB);
484
      if (last_open_file == NULL)
485
        {
486
          file->at_end = 1;
487
          return "";
488
        }
489
 
490
      /* Seek to where we were last time this file was open.  */
491
      if (file->pos)
492
        fseek (last_open_file, file->pos, SEEK_SET);
493
    }
494
 
495
  /* Leave room for null.  */
496
  size -= 1;
497
 
498
  c = fgetc (last_open_file);
499
 
500
  while (c != EOF && c != '\n' && c != '\r')
501
    {
502
      if (count < size)
503
        *p++ = c;
504
      count++;
505
 
506
      c = fgetc (last_open_file);
507
    }
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);
514
 
515
      if ((c == '\r' && next != '\n')
516
          || (c == '\n' && next != '\r'))
517
        ungetc (next, last_open_file);
518
    }
519
 
520
  if (c == EOF)
521
    {
522
      file->at_end = 1;
523
      if (count + 2 < size)
524
        {
525
          *p++ = '.';
526
          *p++ = '.';
527
          *p++ = '.';
528
        }
529
    }
530
  file->linenum++;
531
  *p++ = 0;
532
  return line;
533
}
534
 
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
 
540
static char *
541
rebuffer_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
 
646
static const char *fn;
647
 
648
static unsigned int eject;      /* Eject pending */
649
static unsigned int page;       /* Current page number */
650
static char *title;             /* Current title */
651
static char *subtitle;          /* Current subtitle */
652
static unsigned int on_page;    /* Number of lines printed on current page */
653
 
654
static void
655
listing_page (list_info_type *list)
656
{
657
  /* Grope around, see if we can see a title or subtitle edict coming up
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)
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
 
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
 
697
/* Print a line into the list_file.  Update the line count
698
   and if necessary start a new page.  */
699
 
700
static void
701
emit_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
 
714
static unsigned int
715
calc_hex (list_info_type *list)
716
{
717
  int data_buffer_size;
718
  list_info_type *first = list;
719
  unsigned int address = ~(unsigned int) 0;
720
  fragS *frag;
721
  fragS *frag_ptr;
722
  unsigned int octet_in_frag;
723
 
724
  /* Find first frag which says it belongs to this line.  */
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
 
733
  /* Dump all the frags which belong to this line.  */
734
  while (frag_ptr != (fragS *) NULL && frag_ptr->line == first)
735
    {
736
      /* Print as many bytes from the fixed part as is sensible.  */
737
      octet_in_frag = 0;
738
      while ((offsetT) octet_in_frag < frag_ptr->fr_fix
739
             && data_buffer_size < MAX_BYTES - 3)
740
        {
741
          if (address == ~(unsigned int) 0)
742
            address = frag_ptr->fr_address / OCTETS_PER_BYTE;
743
 
744
          sprintf (data_buffer + data_buffer_size,
745
                   "%02X",
746
                   (frag_ptr->fr_literal[octet_in_frag]) & 0xff);
747
          data_buffer_size += 2;
748
          octet_in_frag++;
749
        }
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)
761
                address = frag_ptr->fr_address / OCTETS_PER_BYTE;
762
 
763
              sprintf (data_buffer + data_buffer_size,
764
                       "%02X",
765
                       (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
766
              data_buffer_size += 2;
767
 
768
              var_rep_idx++;
769
              octet_in_frag++;
770
 
771
              if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var)
772
                var_rep_idx = var_rep_max;
773
            }
774
        }
775
 
776
      frag_ptr = frag_ptr->fr_next;
777
    }
778
  data_buffer[data_buffer_size] = '\0';
779
  return address;
780
}
781
 
782
static void
783
print_lines (list_info_type *list, unsigned int lineno,
784
             char *string, unsigned int address)
785
{
786
  unsigned int idx;
787
  unsigned int nchars;
788
  unsigned int lines;
789
  unsigned int octet_in_word = 0;
790
  char *src = data_buffer;
791
  int cur;
792
 
793
  /* Print the stuff on the first line.  */
794
  listing_page (list);
795
  nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width;
796
 
797
  /* Print the hex for the first line.  */
798
  if (address == ~(unsigned int) 0)
799
    {
800
      fprintf (list_file, "% 4d     ", lineno);
801
      for (idx = 0; idx < nchars; idx++)
802
        fprintf (list_file, " ");
803
 
804
      emit_line (NULL, "\t%s\n", string ? string : "");
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
 
813
  /* And the data to go along with it.  */
814
  idx = 0;
815
  cur = 0;
816
  while (src[cur] && idx < nchars)
817
    {
818
      int offset;
819
      offset = cur;
820
      fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
821
      cur += 2;
822
      octet_in_word++;
823
 
824
      if (octet_in_word == LISTING_WORD_SIZE)
825
        {
826
          fprintf (list_file, " ");
827
          idx++;
828
          octet_in_word = 0;
829
        }
830
 
831
      idx += 2;
832
    }
833
 
834
  for (; idx < nchars; idx++)
835
    fprintf (list_file, " ");
836
 
837
  emit_line (list, "\t%s\n", string ? string : "");
838
 
839
  if (list->message)
840
    emit_line (list, "****  %s\n", list->message);
841
 
842
  for (lines = 0;
843
       lines < (unsigned int) listing_lhs_cont_lines
844
         && src[cur];
845
       lines++)
846
    {
847
      nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1;
848
      idx = 0;
849
 
850
      /* Print any more lines of data, but more compactly.  */
851
      fprintf (list_file, "% 4d      ", lineno);
852
 
853
      while (src[cur] && idx < nchars)
854
        {
855
          int offset;
856
          offset = cur;
857
          fprintf (list_file, "%c%c", src[offset], src[offset + 1]);
858
          cur += 2;
859
          idx += 2;
860
          octet_in_word++;
861
 
862
          if (octet_in_word == LISTING_WORD_SIZE)
863
            {
864
              fprintf (list_file, " ");
865
              idx++;
866
              octet_in_word = 0;
867
            }
868
        }
869
 
870
      emit_line (list, "\n");
871
    }
872
}
873
 
874
static void
875
list_symbol_table (void)
876
{
877
  extern symbolS *symbol_rootP;
878
  int got_some = 0;
879
 
880
  symbolS *ptr;
881
  eject = 1;
882
  listing_page (NULL);
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
        {
889
          /* Don't report section symbols.  They are not interesting.  */
890
          if (symbol_section_p (ptr))
891
            continue;
892
 
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
 
922
              if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line)
923
                {
924
                  fprintf (list_file, "%20s:%-5d  %s:%s %s\n",
925
                           symbol_get_frag (ptr)->line->file->filename,
926
                           symbol_get_frag (ptr)->line->line,
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
 
937
              on_page++;
938
              listing_page (NULL);
939
            }
940
        }
941
 
942
    }
943
  if (!got_some)
944
    {
945
      fprintf (list_file, "NO DEFINED SYMBOLS\n");
946
      on_page++;
947
    }
948
  emit_line (NULL, "\n");
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;
961
 
962
                  emit_line (NULL, "UNDEFINED SYMBOLS\n");
963
                }
964
 
965
              emit_line (NULL, "%s\n", S_GET_NAME (ptr));
966
            }
967
        }
968
    }
969
 
970
  if (!got_some)
971
    emit_line (NULL, "NO UNDEFINED SYMBOLS\n");
972
}
973
 
974
typedef struct cached_line
975
{
976
  file_info_type * file;
977
  unsigned int     line;
978
  char             buffer [LISTING_RHS_WIDTH];
979
} cached_line;
980
 
981
static void
982
print_source (file_info_type *  current_file,
983
              list_info_type *  list,
984
              unsigned int      width)
985
{
986
#define NUM_CACHE_LINES  3
987
  static cached_line cached_lines[NUM_CACHE_LINES];
988
  static int next_free_line = 0;
989
  cached_line * cache = NULL;
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
 
1039
  if (!current_file->at_end)
1040
    {
1041
      int num_lines_shown = 0;
1042
 
1043
      while (current_file->linenum < list->hll_line
1044
             && !current_file->at_end)
1045
        {
1046
          cached_line * cache = cached_lines + next_free_line;
1047
          char *p;
1048
 
1049
          cache->file = current_file;
1050
          cache->line = current_file->linenum + 1;
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
            }
1062
 
1063
          emit_line (list, "%4u:%-13s **** %s\n",
1064
                     cache->line, cache->file->filename, p);
1065
          num_lines_shown ++;
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
 
1073
static int
1074
debugging_pseudo (list_info_type *list, const char *line)
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
 
1088
  while (ISSPACE (*line))
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;
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
 
1142
static void
1143
listing_listing (char *name ATTRIBUTE_UNUSED)
1144
{
1145
  list_info_type *list = head;
1146
  file_info_type *current_hll_file = (file_info_type *) NULL;
1147
  char *buffer;
1148
  char *p;
1149
  int show_listing = 1;
1150
  unsigned int width;
1151
 
1152
  buffer = (char *) xmalloc (listing_rhs_width);
1153
  data_buffer = (char *) xmalloc (MAX_BYTES);
1154
  eject = 1;
1155
  list = head->next;
1156
 
1157
  while (list)
1158
    {
1159
      unsigned int list_line;
1160
 
1161
      width = listing_rhs_width > paper_width ? paper_width :
1162
        listing_rhs_width;
1163
 
1164
      list_line = list->line;
1165
      switch (list->edict)
1166
        {
1167
        case EDICT_LIST:
1168
          /* Skip all lines up to the current.  */
1169
          list_line--;
1170
          break;
1171
        case EDICT_NOLIST:
1172
          show_listing--;
1173
          break;
1174
        case EDICT_NOLIST_NEXT:
1175
          if (show_listing == 0)
1176
            list_line--;
1177
          break;
1178
        case EDICT_EJECT:
1179
          break;
1180
        case EDICT_NONE:
1181
          break;
1182
        case EDICT_TITLE:
1183
          title = list->edict_arg;
1184
          break;
1185
        case EDICT_SBTTL:
1186
          subtitle = list->edict_arg;
1187
          break;
1188
        default:
1189
          abort ();
1190
        }
1191
 
1192
      if (show_listing <= 0)
1193
        {
1194
          while (list->file->linenum < list_line
1195
                 && !list->file->at_end)
1196
            p = buffer_line (list->file, buffer, width);
1197
        }
1198
 
1199
      if (list->edict == EDICT_LIST
1200
          || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0))
1201
        {
1202
          /* Enable listing for the single line that caused the enable.  */
1203
          list_line++;
1204
          show_listing++;
1205
        }
1206
 
1207
      if (show_listing > 0)
1208
        {
1209
          /* Scan down the list and print all the stuff which can be done
1210
             with this line (or lines).  */
1211
          if (list->hll_file)
1212
            current_hll_file = list->hll_file;
1213
 
1214
          if (current_hll_file && list->hll_line && (listing & LISTING_HLL))
1215
            print_source (current_hll_file, list, width);
1216
 
1217
          if (list->line_contents)
1218
            {
1219
              if (!((listing & LISTING_NODEBUG)
1220
                    && debugging_pseudo (list, list->line_contents)))
1221
                print_lines (list,
1222
                             list->file->linenum == 0 ? list->line : list->file->linenum,
1223
                             list->line_contents, calc_hex (list));
1224
 
1225
              free (list->line_contents);
1226
              list->line_contents = NULL;
1227
            }
1228
          else
1229
            {
1230
              while (list->file->linenum < list_line
1231
                     && !list->file->at_end)
1232
                {
1233
                  unsigned int address;
1234
 
1235
                  p = buffer_line (list->file, buffer, width);
1236
 
1237
                  if (list->file->linenum < list_line)
1238
                    address = ~(unsigned int) 0;
1239
                  else
1240
                    address = calc_hex (list);
1241
 
1242
                  if (!((listing & LISTING_NODEBUG)
1243
                        && debugging_pseudo (list, p)))
1244
                    print_lines (list, list->file->linenum, p, address);
1245
                }
1246
            }
1247
 
1248
          if (list->edict == EDICT_EJECT)
1249
            eject = 1;
1250
        }
1251
 
1252
      if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1)
1253
        --show_listing;
1254
 
1255
      list = list->next;
1256
    }
1257
 
1258
  free (buffer);
1259
  free (data_buffer);
1260
  data_buffer = NULL;
1261
}
1262
 
1263
/* Print time stamp in ISO format:  yyyy-mm-ddThh:mm:ss.ss+/-zzzz.  */
1264
 
1265
static void
1266
print_timestamp (void)
1267
{
1268
  const time_t now = time (NULL);
1269
  struct tm * timestamp;
1270
  char stampstr[MAX_DATELEN];
1271
 
1272
  /* Any portable way to obtain subsecond values???  */
1273
  timestamp = localtime (&now);
1274
  strftime (stampstr, MAX_DATELEN, "%Y-%m-%dT%H:%M:%S.000%z", timestamp);
1275
  fprintf (list_file, _("\n time stamp    \t: %s\n\n"), stampstr);
1276
}
1277
 
1278
static void
1279
print_single_option (char * opt, int *pos)
1280
{
1281
  int opt_len = strlen (opt);
1282
 
1283
   if ((*pos + opt_len) < paper_width)
1284
     {
1285
        fprintf (list_file, _("%s "), opt);
1286
        *pos = *pos + opt_len;
1287
     }
1288
   else
1289
     {
1290
        fprintf (list_file, _("\n\t%s "), opt);
1291
        *pos = opt_len;
1292
     }
1293
}
1294
 
1295
/* Print options passed to as.  */
1296
 
1297
static void
1298
print_options (char ** argv)
1299
{
1300
  const char *field_name = _("\n options passed\t: ");
1301
  int pos = strlen (field_name);
1302
  char **p;
1303
 
1304
  fputs (field_name, list_file);
1305
  for (p = &argv[1]; *p != NULL; p++)
1306
    if (**p == '-')
1307
      {
1308
        /* Ignore these.  */
1309
        if (strcmp (*p, "-o") == 0)
1310
          {
1311
            if (p[1] != NULL)
1312
              p++;
1313
            continue;
1314
          }
1315
        if (strcmp (*p, "-v") == 0)
1316
          continue;
1317
 
1318
        print_single_option (*p, &pos);
1319
      }
1320
}
1321
 
1322
/* Print a first section with basic info like file names, as version,
1323
   options passed, target, and timestamp.
1324
   The format of this section is as follows:
1325
 
1326
   AS VERSION
1327
 
1328
   fieldname TAB ':' fieldcontents
1329
  { TAB fieldcontents-cont }  */
1330
 
1331
static void
1332
listing_general_info (char ** argv)
1333
{
1334
  /* Print the stuff on the first line.  */
1335
  eject = 1;
1336
  listing_page (NULL);
1337
 
1338
  fprintf (list_file,
1339
           _(" GNU assembler version %s (%s)\n\t using BFD version %s."),
1340
           VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
1341
  print_options (argv);
1342
  fprintf (list_file, _("\n input file    \t: %s"), fn);
1343
  fprintf (list_file, _("\n output file   \t: %s"), out_file_name);
1344
  fprintf (list_file, _("\n target        \t: %s"), TARGET_CANONICAL);
1345
  print_timestamp ();
1346
}
1347
 
1348
void
1349
listing_print (char *name, char **argv)
1350
{
1351
  int using_stdout;
1352
 
1353
  title = "";
1354
  subtitle = "";
1355
 
1356
  if (name == NULL)
1357
    {
1358
      list_file = stdout;
1359
      using_stdout = 1;
1360
    }
1361
  else
1362
    {
1363
      list_file = fopen (name, FOPEN_WT);
1364
      if (list_file != NULL)
1365
        using_stdout = 0;
1366
      else
1367
        {
1368
          as_warn (_("can't open %s: %s"), name, xstrerror (errno));
1369
          list_file = stdout;
1370
          using_stdout = 1;
1371
        }
1372
    }
1373
 
1374
  if (listing & LISTING_NOFORM)
1375
    paper_height = 0;
1376
 
1377
  if (listing & LISTING_GENERAL)
1378
    listing_general_info (argv);
1379
 
1380
  if (listing & LISTING_LISTING)
1381
    listing_listing (name);
1382
 
1383
  if (listing & LISTING_SYMBOLS)
1384
    list_symbol_table ();
1385
 
1386
  if (! using_stdout)
1387
    {
1388
      if (fclose (list_file) == EOF)
1389
        as_warn (_("can't close %s: %s"), name, xstrerror (errno));
1390
    }
1391
 
1392
  if (last_open_file)
1393
    fclose (last_open_file);
1394
}
1395
 
1396
void
1397
listing_file (const char *name)
1398
{
1399
  fn = name;
1400
}
1401
 
1402
void
1403
listing_eject (int ignore ATTRIBUTE_UNUSED)
1404
{
1405
  if (listing)
1406
    listing_tail->edict = EDICT_EJECT;
1407
}
1408
 
1409
void
1410
listing_flags (int ignore ATTRIBUTE_UNUSED)
1411
{
1412
  while ((*input_line_pointer++) && (*input_line_pointer != '\n'))
1413
    input_line_pointer++;
1414
 
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_flags (int ignore)
1560
{
1561
  s_ignore (0);
1562
}
1563
 
1564
void
1565
listing_list (int on)
1566
{
1567
  s_ignore (0);
1568
}
1569
 
1570
void
1571
listing_eject (int ignore)
1572
{
1573
  s_ignore (0);
1574
}
1575
 
1576
void
1577
listing_psize (int ignore)
1578
{
1579
  s_ignore (0);
1580
}
1581
 
1582
void
1583
listing_nopage (int ignore)
1584
{
1585
  s_ignore (0);
1586
}
1587
 
1588
void
1589
listing_title (int depth)
1590
{
1591
  s_ignore (0);
1592
}
1593
 
1594
void
1595
listing_file (const char *name)
1596
{
1597
}
1598
 
1599
void
1600
listing_newline (char *name)
1601
{
1602
}
1603
 
1604
void
1605
listing_source_line (unsigned int n)
1606
{
1607
}
1608
 
1609
void
1610
listing_source_file (const char *n)
1611
{
1612
}
1613
 
1614
#endif

powered by: WebSVN 2.1.0

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