listing.c revision 130561
1130561Sobrien/* listing.c - maintain assembly listings 277298Sobrien Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3130561Sobrien 2001, 2002, 2003 438889Sjdp Free Software Foundation, Inc. 533965Sjdp 6130561Sobrien This file is part of GAS, the GNU Assembler. 733965Sjdp 8130561Sobrien GAS is free software; you can redistribute it and/or modify 9130561Sobrien it under the terms of the GNU General Public License as published by 10130561Sobrien the Free Software Foundation; either version 2, or (at your option) 11130561Sobrien any later version. 1233965Sjdp 13130561Sobrien GAS is distributed in the hope that it will be useful, 14130561Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 15130561Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16130561Sobrien GNU General Public License for more details. 1733965Sjdp 18130561Sobrien You should have received a copy of the GNU General Public License 19130561Sobrien along with GAS; see the file COPYING. If not, write to the Free 20130561Sobrien Software Foundation, 59 Temple Place - Suite 330, Boston, MA 21130561Sobrien 02111-1307, USA. */ 2233965Sjdp 23130561Sobrien/* Contributed by Steve Chamberlain <sac@cygnus.com> 2433965Sjdp 2533965Sjdp A listing page looks like: 2633965Sjdp 2733965Sjdp LISTING_HEADER sourcefilename pagenumber 2833965Sjdp TITLE LINE 2933965Sjdp SUBTITLE LINE 3033965Sjdp linenumber address data source 3133965Sjdp linenumber address data source 3233965Sjdp linenumber address data source 3333965Sjdp linenumber address data source 3433965Sjdp 3533965Sjdp If not overridden, the listing commands are: 3633965Sjdp 3733965Sjdp .title "stuff" 3833965Sjdp Put "stuff" onto the title line 3933965Sjdp .sbttl "stuff" 4033965Sjdp Put stuff onto the subtitle line 4133965Sjdp 4233965Sjdp If these commands come within 10 lines of the top of the page, they 4333965Sjdp will affect the page they are on, as well as any subsequent page 4433965Sjdp 4533965Sjdp .eject 4633965Sjdp Thow a page 4733965Sjdp .list 4833965Sjdp Increment the enable listing counter 4933965Sjdp .nolist 5033965Sjdp Decrement the enable listing counter 5133965Sjdp 5233965Sjdp .psize Y[,X] 5333965Sjdp Set the paper size to X wide and Y high. Setting a psize Y of 5433965Sjdp zero will suppress form feeds except where demanded by .eject 5533965Sjdp 5633965Sjdp If the counter goes below zero, listing is suppressed. 5733965Sjdp 5833965Sjdp Listings are a maintained by read calling various listing_<foo> 5933965Sjdp functions. What happens most is that the macro NO_LISTING is not 6033965Sjdp defined (from the Makefile), then the macro LISTING_NEWLINE expands 6133965Sjdp into a call to listing_newline. The call is done from read.c, every 6233965Sjdp time it sees a newline, and -l is on the command line. 6333965Sjdp 6433965Sjdp The function listing_newline remembers the frag associated with the 6533965Sjdp newline, and creates a new frag - note that this is wasteful, but not 6633965Sjdp a big deal, since listing slows things down a lot anyway. The 67130561Sobrien function also remembers when the filename changes. 6833965Sjdp 6933965Sjdp When all the input has finished, and gas has had a chance to settle 7033965Sjdp down, the listing is output. This is done by running down the list of 7133965Sjdp frag/source file records, and opening the files as needed and printing 7233965Sjdp out the bytes and chars associated with them. 7333965Sjdp 7433965Sjdp The only things which the architecture can change about the listing 7533965Sjdp are defined in these macros: 7633965Sjdp 7733965Sjdp LISTING_HEADER The name of the architecture 7833965Sjdp LISTING_WORD_SIZE The make of the number of bytes in a word, this determines 7933965Sjdp the clumping of the output data. eg a value of 8033965Sjdp 2 makes words look like 1234 5678, whilst 1 8133965Sjdp would make the same value look like 12 34 56 8233965Sjdp 78 8333965Sjdp LISTING_LHS_WIDTH Number of words of above size for the lhs 8433965Sjdp 8533965Sjdp LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs 8633965Sjdp for the second line 8733965Sjdp 88130561Sobrien LISTING_LHS_CONT_LINES Max number of lines to use up for a continuation 8933965Sjdp LISTING_RHS_WIDTH Number of chars from the input file to print 90130561Sobrien on a line. */ 9133965Sjdp 9233965Sjdp#include "as.h" 93104834Sobrien#include "obstack.h" 9489857Sobrien#include "safe-ctype.h" 9533965Sjdp#include "input-file.h" 9633965Sjdp#include "subsegs.h" 9733965Sjdp 9833965Sjdp#ifndef NO_LISTING 9938889Sjdp 10033965Sjdp#ifndef LISTING_HEADER 10133965Sjdp#define LISTING_HEADER "GAS LISTING" 10233965Sjdp#endif 10333965Sjdp#ifndef LISTING_WORD_SIZE 10433965Sjdp#define LISTING_WORD_SIZE 4 10533965Sjdp#endif 10633965Sjdp#ifndef LISTING_LHS_WIDTH 10760484Sobrien#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE)) 10833965Sjdp#endif 10933965Sjdp#ifndef LISTING_LHS_WIDTH_SECOND 11060484Sobrien#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH 11133965Sjdp#endif 11233965Sjdp#ifndef LISTING_RHS_WIDTH 11333965Sjdp#define LISTING_RHS_WIDTH 100 11433965Sjdp#endif 11533965Sjdp#ifndef LISTING_LHS_CONT_LINES 11633965Sjdp#define LISTING_LHS_CONT_LINES 4 11733965Sjdp#endif 11833965Sjdp 11977298Sobrien/* This structure remembers which .s were used. */ 120130561Sobrientypedef struct file_info_struct 121130561Sobrien{ 12260484Sobrien struct file_info_struct * next; 12360484Sobrien char * filename; 12460484Sobrien long pos; 12560484Sobrien unsigned int linenum; 12660484Sobrien int at_end; 12777298Sobrien} file_info_type; 12833965Sjdp 129130561Sobrien/* This structure remembers which line from which file goes into which 13077298Sobrien frag. */ 131130561Sobrienstruct list_info_struct 132130561Sobrien{ 13377298Sobrien /* Frag which this line of source is nearest to. */ 13477298Sobrien fragS *frag; 13538889Sjdp 13677298Sobrien /* The actual line in the source file. */ 13733965Sjdp unsigned int line; 138130561Sobrien 13933965Sjdp /* Pointer to the file info struct for the file which this line 14077298Sobrien belongs to. */ 14177298Sobrien file_info_type *file; 14233965Sjdp 14338889Sjdp /* The expanded text of any macro that may have been executing. */ 14477298Sobrien char *line_contents; 14538889Sjdp 14677298Sobrien /* Next in list. */ 14777298Sobrien struct list_info_struct *next; 14833965Sjdp 14933965Sjdp /* Pointer to the file info struct for the high level language 15077298Sobrien source line that belongs here. */ 15177298Sobrien file_info_type *hll_file; 152130561Sobrien 15377298Sobrien /* High level language source line. */ 15438889Sjdp unsigned int hll_line; 15533965Sjdp 15677298Sobrien /* Pointer to any error message associated with this line. */ 15777298Sobrien char *message; 15833965Sjdp 159130561Sobrien enum 160130561Sobrien { 161130561Sobrien EDICT_NONE, 162130561Sobrien EDICT_SBTTL, 163130561Sobrien EDICT_TITLE, 164130561Sobrien EDICT_NOLIST, 165130561Sobrien EDICT_LIST, 166130561Sobrien EDICT_NOLIST_NEXT, 167130561Sobrien EDICT_EJECT 168130561Sobrien } edict; 16977298Sobrien char *edict_arg; 17033965Sjdp 17138889Sjdp /* Nonzero if this line is to be omitted because it contains 17238889Sjdp debugging information. This can become a flags field if we come 17338889Sjdp up with more information to store here. */ 17438889Sjdp int debugging; 17538889Sjdp}; 17633965Sjdp 17738889Sjdptypedef struct list_info_struct list_info_type; 17833965Sjdp 17960484Sobrienint listing_lhs_width = LISTING_LHS_WIDTH; 18060484Sobrienint listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND; 18160484Sobrienint listing_lhs_cont_lines = LISTING_LHS_CONT_LINES; 18260484Sobrienint listing_rhs_width = LISTING_RHS_WIDTH; 18333965Sjdp 18460484Sobrienstruct list_info_struct * listing_tail; 18560484Sobrien 18660484Sobrienstatic file_info_type * file_info_head; 18760484Sobrienstatic file_info_type * last_open_file_info; 18860484Sobrienstatic FILE * last_open_file; 18960484Sobrienstatic struct list_info_struct * head; 19060484Sobrienstatic int paper_width = 200; 19160484Sobrienstatic int paper_height = 60; 19260484Sobrien 19360484Sobrienextern int listing; 19460484Sobrien 19533965Sjdp/* File to output listings to. */ 19677298Sobrienstatic FILE *list_file; 19733965Sjdp 19838889Sjdp/* This static array is used to keep the text of data to be printed 19938889Sjdp before the start of the line. */ 20033965Sjdp 20138889Sjdp#define MAX_BYTES \ 20238889Sjdp (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \ 20338889Sjdp + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \ 20438889Sjdp * listing_lhs_cont_lines) \ 20538889Sjdp + 20) 20633965Sjdp 20777298Sobrienstatic char *data_buffer; 20833965Sjdp 20933965Sjdp/* Prototypes. */ 210130561Sobrienstatic void listing_message (const char *, const char *); 211130561Sobrienstatic file_info_type *file_info (const char *); 212130561Sobrienstatic void new_frag (void); 213130561Sobrienstatic char *buffer_line (file_info_type *, char *, unsigned int); 214130561Sobrienstatic void listing_page (list_info_type *); 215130561Sobrienstatic unsigned int calc_hex (list_info_type *); 216130561Sobrienstatic void print_lines (list_info_type *, unsigned int, char *, unsigned int); 217130561Sobrienstatic void list_symbol_table (void); 218130561Sobrienstatic void print_source (file_info_type *, list_info_type *, char *, unsigned int); 219130561Sobrienstatic int debugging_pseudo (list_info_type *, const char *); 220130561Sobrienstatic void listing_listing (char *); 22133965Sjdp 22233965Sjdpstatic void 223130561Sobrienlisting_message (const char *name, const char *message) 22433965Sjdp{ 22533965Sjdp if (listing_tail != (list_info_type *) NULL) 22633965Sjdp { 22777298Sobrien unsigned int l = strlen (name) + strlen (message) + 1; 22877298Sobrien char *n = (char *) xmalloc (l); 22977298Sobrien strcpy (n, name); 23077298Sobrien strcat (n, message); 23133965Sjdp listing_tail->message = n; 23233965Sjdp } 23333965Sjdp} 23433965Sjdp 23533965Sjdpvoid 236130561Sobrienlisting_warning (const char *message) 23733965Sjdp{ 23860484Sobrien listing_message (_("Warning:"), message); 23933965Sjdp} 24033965Sjdp 24133965Sjdpvoid 242130561Sobrienlisting_error (const char *message) 24333965Sjdp{ 24460484Sobrien listing_message (_("Error:"), message); 24533965Sjdp} 24633965Sjdp 24733965Sjdpstatic file_info_type * 248130561Sobrienfile_info (const char *file_name) 24933965Sjdp{ 25077298Sobrien /* Find an entry with this file name. */ 25133965Sjdp file_info_type *p = file_info_head; 25233965Sjdp 25333965Sjdp while (p != (file_info_type *) NULL) 25433965Sjdp { 25533965Sjdp if (strcmp (p->filename, file_name) == 0) 25633965Sjdp return p; 25733965Sjdp p = p->next; 25833965Sjdp } 25933965Sjdp 26077298Sobrien /* Make new entry. */ 261130561Sobrien p = xmalloc (sizeof (file_info_type)); 26233965Sjdp p->next = file_info_head; 26333965Sjdp file_info_head = p; 264104834Sobrien p->filename = xstrdup (file_name); 26538889Sjdp p->pos = 0; 26633965Sjdp p->linenum = 0; 26733965Sjdp p->at_end = 0; 26833965Sjdp 26933965Sjdp return p; 27033965Sjdp} 27133965Sjdp 27233965Sjdpstatic void 273130561Sobriennew_frag (void) 27433965Sjdp{ 27533965Sjdp frag_wane (frag_now); 27633965Sjdp frag_new (0); 27733965Sjdp} 27833965Sjdp 27933965Sjdpvoid 280130561Sobrienlisting_newline (char *ps) 28133965Sjdp{ 28233965Sjdp char *file; 28333965Sjdp unsigned int line; 28433965Sjdp static unsigned int last_line = 0xffff; 28533965Sjdp static char *last_file = NULL; 28638889Sjdp list_info_type *new = NULL; 28733965Sjdp 28833965Sjdp if (listing == 0) 28933965Sjdp return; 29033965Sjdp 29133965Sjdp if (now_seg == absolute_section) 29233965Sjdp return; 29333965Sjdp 29438889Sjdp#ifdef OBJ_ELF 29538889Sjdp /* In ELF, anything in a section beginning with .debug or .line is 29638889Sjdp considered to be debugging information. This includes the 29738889Sjdp statement which switches us into the debugging section, which we 29838889Sjdp can only set after we are already in the debugging section. */ 29938889Sjdp if ((listing & LISTING_NODEBUG) != 0 30038889Sjdp && listing_tail != NULL 30138889Sjdp && ! listing_tail->debugging) 30238889Sjdp { 30338889Sjdp const char *segname; 30438889Sjdp 30538889Sjdp segname = segment_name (now_seg); 30638889Sjdp if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 30738889Sjdp || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 30838889Sjdp listing_tail->debugging = 1; 30938889Sjdp } 31038889Sjdp#endif 31138889Sjdp 31233965Sjdp as_where (&file, &line); 31338889Sjdp if (ps == NULL) 31433965Sjdp { 31577298Sobrien if (line == last_line 31677298Sobrien && !(last_file && file && strcmp (file, last_file))) 31738889Sjdp return; 31833965Sjdp 31933965Sjdp new = (list_info_type *) xmalloc (sizeof (list_info_type)); 32060484Sobrien 32160484Sobrien /* Detect if we are reading from stdin by examining the file 32260484Sobrien name returned by as_where(). 32360484Sobrien 32460484Sobrien [FIXME: We rely upon the name in the strcmp below being the 32560484Sobrien same as the one used by input_scrub_new_file(), if that is 32660484Sobrien not true, then this code will fail]. 32760484Sobrien 32877298Sobrien If we are reading from stdin, then we need to save each input 32977298Sobrien line here (assuming of course that we actually have a line of 33077298Sobrien input to read), so that it can be displayed in the listing 33177298Sobrien that is produced at the end of the assembly. */ 33260484Sobrien if (strcmp (file, _("{standard input}")) == 0 33360484Sobrien && input_line_pointer != NULL) 33460484Sobrien { 33577298Sobrien char *copy; 33660484Sobrien int len; 33760484Sobrien int seen_quote = 0; 33860484Sobrien 33960484Sobrien for (copy = input_line_pointer - 1; 34077298Sobrien *copy && (seen_quote 34177298Sobrien || (! is_end_of_line [(unsigned char) *copy])); 34277298Sobrien copy++) 34377298Sobrien if (*copy == '"' && copy[-1] != '\\') 34460484Sobrien seen_quote = ! seen_quote; 34560484Sobrien 34660484Sobrien len = (copy - input_line_pointer) + 2; 34760484Sobrien 34860484Sobrien copy = xmalloc (len); 34960484Sobrien 35060484Sobrien if (copy != NULL) 35160484Sobrien { 35277298Sobrien char *src = input_line_pointer - 1; 35377298Sobrien char *dest = copy; 35477298Sobrien 35560484Sobrien while (--len) 35660484Sobrien { 35777298Sobrien unsigned char c = *src++; 35860484Sobrien 35960484Sobrien /* Omit control characters in the listing. */ 36089857Sobrien if (!ISCNTRL (c)) 36177298Sobrien *dest++ = c; 36260484Sobrien } 36377298Sobrien 36460484Sobrien *dest = 0; 36560484Sobrien } 36677298Sobrien 36760484Sobrien new->line_contents = copy; 36860484Sobrien } 36960484Sobrien else 37060484Sobrien new->line_contents = NULL; 37138889Sjdp } 37238889Sjdp else 37338889Sjdp { 374130561Sobrien new = xmalloc (sizeof (list_info_type)); 37538889Sjdp new->line_contents = ps; 37638889Sjdp } 37733965Sjdp 37838889Sjdp last_line = line; 37938889Sjdp last_file = file; 38077298Sobrien 38138889Sjdp new_frag (); 38238889Sjdp 38338889Sjdp if (listing_tail) 38460484Sobrien listing_tail->next = new; 38538889Sjdp else 38660484Sobrien head = new; 38777298Sobrien 38838889Sjdp listing_tail = new; 38938889Sjdp 39038889Sjdp new->frag = frag_now; 39138889Sjdp new->line = line; 39238889Sjdp new->file = file_info (file); 39338889Sjdp new->next = (list_info_type *) NULL; 39438889Sjdp new->message = (char *) NULL; 39538889Sjdp new->edict = EDICT_NONE; 39638889Sjdp new->hll_file = (file_info_type *) NULL; 39738889Sjdp new->hll_line = 0; 39838889Sjdp new->debugging = 0; 39977298Sobrien 40038889Sjdp new_frag (); 40138889Sjdp 40238889Sjdp#ifdef OBJ_ELF 40338889Sjdp /* In ELF, anything in a section beginning with .debug or .line is 40438889Sjdp considered to be debugging information. */ 40538889Sjdp if ((listing & LISTING_NODEBUG) != 0) 40638889Sjdp { 40738889Sjdp const char *segname; 40838889Sjdp 40938889Sjdp segname = segment_name (now_seg); 41038889Sjdp if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 41138889Sjdp || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 41238889Sjdp new->debugging = 1; 41338889Sjdp } 41438889Sjdp#endif 41533965Sjdp} 41633965Sjdp 41733965Sjdp/* Attach all current frags to the previous line instead of the 41833965Sjdp current line. This is called by the MIPS backend when it discovers 41933965Sjdp that it needs to add some NOP instructions; the added NOP 42033965Sjdp instructions should go with the instruction that has the delay, not 42133965Sjdp with the new instruction. */ 42233965Sjdp 42333965Sjdpvoid 424130561Sobrienlisting_prev_line (void) 42533965Sjdp{ 42633965Sjdp list_info_type *l; 42733965Sjdp fragS *f; 42833965Sjdp 42933965Sjdp if (head == (list_info_type *) NULL 43033965Sjdp || head == listing_tail) 43133965Sjdp return; 43233965Sjdp 43333965Sjdp new_frag (); 43433965Sjdp 43533965Sjdp for (l = head; l->next != listing_tail; l = l->next) 43633965Sjdp ; 43733965Sjdp 43833965Sjdp for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next) 43933965Sjdp if (f->line == listing_tail) 44033965Sjdp f->line = l; 44133965Sjdp 44233965Sjdp listing_tail->frag = frag_now; 44333965Sjdp new_frag (); 44433965Sjdp} 44533965Sjdp 44677298Sobrien/* This function returns the next source line from the file supplied, 44777298Sobrien truncated to size. It appends a fake line to the end of each input 44877298Sobrien file to make. */ 44933965Sjdp 45033965Sjdpstatic char * 451130561Sobrienbuffer_line (file_info_type *file, char *line, unsigned int size) 45233965Sjdp{ 45333965Sjdp unsigned int count = 0; 45433965Sjdp int c; 45533965Sjdp 45633965Sjdp char *p = line; 45733965Sjdp 45877298Sobrien /* If we couldn't open the file, return an empty line. */ 45938889Sjdp if (file->at_end) 46038889Sjdp return ""; 46138889Sjdp 46238889Sjdp /* Check the cache and see if we last used this file. */ 46338889Sjdp if (!last_open_file_info || file != last_open_file_info) 46433965Sjdp { 46538889Sjdp if (last_open_file) 46638889Sjdp { 46738889Sjdp last_open_file_info->pos = ftell (last_open_file); 46838889Sjdp fclose (last_open_file); 46938889Sjdp } 47038889Sjdp 47138889Sjdp last_open_file_info = file; 47289857Sobrien last_open_file = fopen (file->filename, FOPEN_RT); 47338889Sjdp if (last_open_file == NULL) 47438889Sjdp { 47538889Sjdp file->at_end = 1; 47638889Sjdp return ""; 47738889Sjdp } 47877298Sobrien 47938889Sjdp /* Seek to where we were last time this file was open. */ 48038889Sjdp if (file->pos) 48177298Sobrien fseek (last_open_file, file->pos, SEEK_SET); 48233965Sjdp } 48333965Sjdp 48438889Sjdp c = fgetc (last_open_file); 48533965Sjdp 48677298Sobrien /* Leave room for null. */ 48777298Sobrien size -= 1; 48833965Sjdp 48933965Sjdp while (c != EOF && c != '\n') 49033965Sjdp { 49133965Sjdp if (count < size) 49233965Sjdp *p++ = c; 49333965Sjdp count++; 49433965Sjdp 49538889Sjdp c = fgetc (last_open_file); 49633965Sjdp 49733965Sjdp } 49833965Sjdp if (c == EOF) 49933965Sjdp { 50033965Sjdp file->at_end = 1; 50189857Sobrien if (count + 2 < size) 50289857Sobrien { 50389857Sobrien *p++ = '.'; 50489857Sobrien *p++ = '.'; 50589857Sobrien *p++ = '.'; 50689857Sobrien } 50733965Sjdp } 50833965Sjdp file->linenum++; 50933965Sjdp *p++ = 0; 51033965Sjdp return line; 51133965Sjdp} 51233965Sjdp 51333965Sjdpstatic const char *fn; 51433965Sjdp 51533965Sjdpstatic unsigned int eject; /* Eject pending */ 51633965Sjdpstatic unsigned int page; /* Current page number */ 51777298Sobrienstatic char *title; /* Current title */ 51877298Sobrienstatic char *subtitle; /* Current subtitle */ 51977298Sobrienstatic unsigned int on_page; /* Number of lines printed on current page */ 52033965Sjdp 52133965Sjdpstatic void 522130561Sobrienlisting_page (list_info_type *list) 52333965Sjdp{ 52433965Sjdp /* Grope around, see if we can see a title or subtitle edict coming up 52577298Sobrien soon. (we look down 10 lines of the page and see if it's there) */ 52677298Sobrien if ((eject || (on_page >= (unsigned int) paper_height)) 52777298Sobrien && paper_height != 0) 52833965Sjdp { 52933965Sjdp unsigned int c = 10; 53033965Sjdp int had_title = 0; 53133965Sjdp int had_subtitle = 0; 53233965Sjdp 53333965Sjdp page++; 53433965Sjdp 53533965Sjdp while (c != 0 && list) 53633965Sjdp { 53733965Sjdp if (list->edict == EDICT_SBTTL && !had_subtitle) 53833965Sjdp { 53933965Sjdp had_subtitle = 1; 54033965Sjdp subtitle = list->edict_arg; 54133965Sjdp } 54233965Sjdp if (list->edict == EDICT_TITLE && !had_title) 54333965Sjdp { 54433965Sjdp had_title = 1; 54533965Sjdp title = list->edict_arg; 54633965Sjdp } 54733965Sjdp list = list->next; 54833965Sjdp c--; 54933965Sjdp } 55033965Sjdp 55133965Sjdp if (page > 1) 55233965Sjdp { 55333965Sjdp fprintf (list_file, "\f"); 55433965Sjdp } 55533965Sjdp 55633965Sjdp fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); 55733965Sjdp fprintf (list_file, "%s\n", title); 55833965Sjdp fprintf (list_file, "%s\n", subtitle); 55933965Sjdp on_page = 3; 56033965Sjdp eject = 0; 56133965Sjdp } 56233965Sjdp} 56333965Sjdp 56433965Sjdpstatic unsigned int 565130561Sobriencalc_hex (list_info_type *list) 56633965Sjdp{ 56738889Sjdp int data_buffer_size; 56833965Sjdp list_info_type *first = list; 56977298Sobrien unsigned int address = ~(unsigned int) 0; 57033965Sjdp fragS *frag; 57133965Sjdp fragS *frag_ptr; 57260484Sobrien unsigned int octet_in_frag; 57333965Sjdp 57477298Sobrien /* Find first frag which says it belongs to this line. */ 57533965Sjdp frag = list->frag; 57633965Sjdp while (frag && frag->line != list) 57733965Sjdp frag = frag->fr_next; 57833965Sjdp 57933965Sjdp frag_ptr = frag; 58033965Sjdp 58133965Sjdp data_buffer_size = 0; 58233965Sjdp 58377298Sobrien /* Dump all the frags which belong to this line. */ 58433965Sjdp while (frag_ptr != (fragS *) NULL && frag_ptr->line == first) 58533965Sjdp { 58677298Sobrien /* Print as many bytes from the fixed part as is sensible. */ 58760484Sobrien octet_in_frag = 0; 58860484Sobrien while ((offsetT) octet_in_frag < frag_ptr->fr_fix 58938889Sjdp && data_buffer_size < MAX_BYTES - 3) 59033965Sjdp { 59177298Sobrien if (address == ~(unsigned int) 0) 592130561Sobrien address = frag_ptr->fr_address / OCTETS_PER_BYTE; 59333965Sjdp 59433965Sjdp sprintf (data_buffer + data_buffer_size, 59533965Sjdp "%02X", 59660484Sobrien (frag_ptr->fr_literal[octet_in_frag]) & 0xff); 59733965Sjdp data_buffer_size += 2; 59860484Sobrien octet_in_frag++; 59933965Sjdp } 600104834Sobrien if (frag_ptr->fr_type == rs_fill) 601104834Sobrien { 602104834Sobrien unsigned int var_rep_max = octet_in_frag; 603104834Sobrien unsigned int var_rep_idx = octet_in_frag; 60433965Sjdp 605104834Sobrien /* Print as many bytes from the variable part as is sensible. */ 606104834Sobrien while (((offsetT) octet_in_frag 607104834Sobrien < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)) 608104834Sobrien && data_buffer_size < MAX_BYTES - 3) 609104834Sobrien { 610104834Sobrien if (address == ~(unsigned int) 0) 611130561Sobrien address = frag_ptr->fr_address / OCTETS_PER_BYTE; 612130561Sobrien 613104834Sobrien sprintf (data_buffer + data_buffer_size, 614104834Sobrien "%02X", 615104834Sobrien (frag_ptr->fr_literal[var_rep_idx]) & 0xff); 61633965Sjdp#if 0 617104834Sobrien data_buffer[data_buffer_size++] = '*'; 618104834Sobrien data_buffer[data_buffer_size++] = '*'; 61933965Sjdp#endif 620104834Sobrien data_buffer_size += 2; 62133965Sjdp 622104834Sobrien var_rep_idx++; 623104834Sobrien octet_in_frag++; 62433965Sjdp 625104834Sobrien if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var) 626104834Sobrien var_rep_idx = var_rep_max; 627104834Sobrien } 628104834Sobrien } 62933965Sjdp 63033965Sjdp frag_ptr = frag_ptr->fr_next; 63133965Sjdp } 63238889Sjdp data_buffer[data_buffer_size] = '\0'; 63333965Sjdp return address; 63433965Sjdp} 63533965Sjdp 63633965Sjdpstatic void 637130561Sobrienprint_lines (list_info_type *list, unsigned int lineno, 638130561Sobrien char *string, unsigned int address) 63933965Sjdp{ 64033965Sjdp unsigned int idx; 64133965Sjdp unsigned int nchars; 64233965Sjdp unsigned int lines; 64360484Sobrien unsigned int octet_in_word = 0; 64433965Sjdp char *src = data_buffer; 64560484Sobrien int cur; 64633965Sjdp 64777298Sobrien /* Print the stuff on the first line. */ 64833965Sjdp listing_page (list); 64938889Sjdp nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width; 65077298Sobrien 65177298Sobrien /* Print the hex for the first line. */ 65277298Sobrien if (address == ~(unsigned int) 0) 65333965Sjdp { 65433965Sjdp fprintf (list_file, "% 4d ", lineno); 65533965Sjdp for (idx = 0; idx < nchars; idx++) 65633965Sjdp fprintf (list_file, " "); 65733965Sjdp 65833965Sjdp fprintf (list_file, "\t%s\n", string ? string : ""); 65977298Sobrien 66077298Sobrien on_page++; 66177298Sobrien 66233965Sjdp listing_page (0); 66333965Sjdp 66460484Sobrien return; 66533965Sjdp } 66660484Sobrien 66760484Sobrien if (had_errors ()) 66860484Sobrien fprintf (list_file, "% 4d ???? ", lineno); 66933965Sjdp else 67060484Sobrien fprintf (list_file, "% 4d %04x ", lineno, address); 67160484Sobrien 67277298Sobrien /* And the data to go along with it. */ 67360484Sobrien idx = 0; 67460484Sobrien cur = 0; 67560484Sobrien while (src[cur] && idx < nchars) 67633965Sjdp { 67760484Sobrien int offset; 67860484Sobrien offset = cur; 67977298Sobrien fprintf (list_file, "%c%c", src[offset], src[offset + 1]); 68060484Sobrien cur += 2; 68160484Sobrien octet_in_word++; 68277298Sobrien 68360484Sobrien if (octet_in_word == LISTING_WORD_SIZE) 68433965Sjdp { 68560484Sobrien fprintf (list_file, " "); 68660484Sobrien idx++; 68760484Sobrien octet_in_word = 0; 68833965Sjdp } 68977298Sobrien 69060484Sobrien idx += 2; 69160484Sobrien } 69277298Sobrien 69360484Sobrien for (; idx < nchars; idx++) 69460484Sobrien fprintf (list_file, " "); 69577298Sobrien 69660484Sobrien fprintf (list_file, "\t%s\n", string ? string : ""); 69760484Sobrien on_page++; 69860484Sobrien listing_page (list); 69977298Sobrien 70060484Sobrien if (list->message) 70160484Sobrien { 70260484Sobrien fprintf (list_file, "**** %s\n", list->message); 70360484Sobrien listing_page (list); 70460484Sobrien on_page++; 70560484Sobrien } 70677298Sobrien 70760484Sobrien for (lines = 0; 70860484Sobrien lines < (unsigned int) listing_lhs_cont_lines 70960484Sobrien && src[cur]; 71077298Sobrien lines++) 71160484Sobrien { 71277298Sobrien nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1; 71333965Sjdp idx = 0; 71477298Sobrien 71577298Sobrien /* Print any more lines of data, but more compactly. */ 71660484Sobrien fprintf (list_file, "% 4d ", lineno); 71777298Sobrien 71860484Sobrien while (src[cur] && idx < nchars) 71933965Sjdp { 72077298Sobrien int offset; 72177298Sobrien offset = cur; 72277298Sobrien fprintf (list_file, "%c%c", src[offset], src[offset + 1]); 72360484Sobrien cur += 2; 72460484Sobrien idx += 2; 72560484Sobrien octet_in_word++; 72677298Sobrien 72760484Sobrien if (octet_in_word == LISTING_WORD_SIZE) 72833965Sjdp { 72933965Sjdp fprintf (list_file, " "); 73033965Sjdp idx++; 73160484Sobrien octet_in_word = 0; 73233965Sjdp } 73333965Sjdp } 73477298Sobrien 73560484Sobrien fprintf (list_file, "\n"); 73677298Sobrien on_page++; 73733965Sjdp listing_page (list); 73833965Sjdp } 73933965Sjdp} 74033965Sjdp 74133965Sjdpstatic void 742130561Sobrienlist_symbol_table (void) 74333965Sjdp{ 74433965Sjdp extern symbolS *symbol_rootP; 74533965Sjdp int got_some = 0; 74633965Sjdp 74733965Sjdp symbolS *ptr; 74833965Sjdp eject = 1; 74933965Sjdp listing_page (0); 75033965Sjdp 75133965Sjdp for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 75233965Sjdp { 75338889Sjdp if (SEG_NORMAL (S_GET_SEGMENT (ptr)) 75438889Sjdp || S_GET_SEGMENT (ptr) == absolute_section) 75533965Sjdp { 75638889Sjdp#ifdef BFD_ASSEMBLER 75738889Sjdp /* Don't report section symbols. They are not interesting. */ 75860484Sobrien if (symbol_section_p (ptr)) 75938889Sjdp continue; 76038889Sjdp#endif 76133965Sjdp if (S_GET_NAME (ptr)) 76233965Sjdp { 76333965Sjdp char buf[30], fmt[8]; 76433965Sjdp valueT val = S_GET_VALUE (ptr); 76533965Sjdp 76633965Sjdp /* @@ Note that this is dependent on the compilation options, 76733965Sjdp not solely on the target characteristics. */ 76833965Sjdp if (sizeof (val) == 4 && sizeof (int) == 4) 76933965Sjdp sprintf (buf, "%08lx", (unsigned long) val); 77033965Sjdp else if (sizeof (val) <= sizeof (unsigned long)) 77133965Sjdp { 77233965Sjdp sprintf (fmt, "%%0%lulx", 77333965Sjdp (unsigned long) (sizeof (val) * 2)); 77433965Sjdp sprintf (buf, fmt, (unsigned long) val); 77533965Sjdp } 77633965Sjdp#if defined (BFD64) 77733965Sjdp else if (sizeof (val) > 4) 77833965Sjdp sprintf_vma (buf, val); 77933965Sjdp#endif 78033965Sjdp else 78133965Sjdp abort (); 78233965Sjdp 78333965Sjdp if (!got_some) 78433965Sjdp { 78533965Sjdp fprintf (list_file, "DEFINED SYMBOLS\n"); 78633965Sjdp on_page++; 78733965Sjdp got_some = 1; 78833965Sjdp } 78933965Sjdp 79060484Sobrien if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line) 79138889Sjdp { 79238889Sjdp fprintf (list_file, "%20s:%-5d %s:%s %s\n", 79360484Sobrien symbol_get_frag (ptr)->line->file->filename, 79460484Sobrien symbol_get_frag (ptr)->line->line, 79538889Sjdp segment_name (S_GET_SEGMENT (ptr)), 79638889Sjdp buf, S_GET_NAME (ptr)); 79738889Sjdp } 79838889Sjdp else 79938889Sjdp { 80038889Sjdp fprintf (list_file, "%33s:%s %s\n", 80138889Sjdp segment_name (S_GET_SEGMENT (ptr)), 80238889Sjdp buf, S_GET_NAME (ptr)); 80338889Sjdp } 80433965Sjdp 80577298Sobrien on_page++; 80633965Sjdp listing_page (0); 80733965Sjdp } 80833965Sjdp } 80933965Sjdp 81033965Sjdp } 81133965Sjdp if (!got_some) 81233965Sjdp { 81333965Sjdp fprintf (list_file, "NO DEFINED SYMBOLS\n"); 81433965Sjdp on_page++; 81533965Sjdp } 81633965Sjdp fprintf (list_file, "\n"); 81733965Sjdp on_page++; 81833965Sjdp listing_page (0); 81933965Sjdp 82033965Sjdp got_some = 0; 82133965Sjdp 82233965Sjdp for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 82333965Sjdp { 82433965Sjdp if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0) 82533965Sjdp { 82638889Sjdp if (S_GET_SEGMENT (ptr) == undefined_section) 82733965Sjdp { 82833965Sjdp if (!got_some) 82933965Sjdp { 83033965Sjdp got_some = 1; 83133965Sjdp fprintf (list_file, "UNDEFINED SYMBOLS\n"); 83233965Sjdp on_page++; 83333965Sjdp listing_page (0); 83433965Sjdp } 83533965Sjdp fprintf (list_file, "%s\n", S_GET_NAME (ptr)); 83633965Sjdp on_page++; 83733965Sjdp listing_page (0); 83833965Sjdp } 83933965Sjdp } 84033965Sjdp } 84133965Sjdp if (!got_some) 84233965Sjdp { 84333965Sjdp fprintf (list_file, "NO UNDEFINED SYMBOLS\n"); 84433965Sjdp on_page++; 84533965Sjdp listing_page (0); 84633965Sjdp } 84733965Sjdp} 84833965Sjdp 84933965Sjdpstatic void 850130561Sobrienprint_source (file_info_type *current_file, list_info_type *list, 851130561Sobrien char *buffer, unsigned int width) 85233965Sjdp{ 85338889Sjdp if (!current_file->at_end) 85433965Sjdp { 85533965Sjdp while (current_file->linenum < list->hll_line 85633965Sjdp && !current_file->at_end) 85733965Sjdp { 85833965Sjdp char *p = buffer_line (current_file, buffer, width); 859130561Sobrien 86038889Sjdp fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum, 86133965Sjdp current_file->filename, p); 86233965Sjdp on_page++; 86333965Sjdp listing_page (list); 86433965Sjdp } 86533965Sjdp } 86633965Sjdp} 86733965Sjdp 86833965Sjdp/* Sometimes the user doesn't want to be bothered by the debugging 86938889Sjdp records inserted by the compiler, see if the line is suspicious. */ 87033965Sjdp 87133965Sjdpstatic int 872130561Sobriendebugging_pseudo (list_info_type *list, const char *line) 87333965Sjdp{ 87438889Sjdp static int in_debug; 87538889Sjdp int was_debug; 87638889Sjdp 87738889Sjdp if (list->debugging) 87838889Sjdp { 87938889Sjdp in_debug = 1; 88038889Sjdp return 1; 88138889Sjdp } 88238889Sjdp 88338889Sjdp was_debug = in_debug; 88438889Sjdp in_debug = 0; 88538889Sjdp 88689857Sobrien while (ISSPACE (*line)) 88733965Sjdp line++; 88833965Sjdp 88933965Sjdp if (*line != '.') 89038889Sjdp { 89138889Sjdp#ifdef OBJ_ELF 89238889Sjdp /* The ELF compiler sometimes emits blank lines after switching 89338889Sjdp out of a debugging section. If the next line drops us back 89438889Sjdp into debugging information, then don't print the blank line. 89538889Sjdp This is a hack for a particular compiler behaviour, not a 89638889Sjdp general case. */ 89738889Sjdp if (was_debug 89838889Sjdp && *line == '\0' 89938889Sjdp && list->next != NULL 90038889Sjdp && list->next->debugging) 90138889Sjdp { 90238889Sjdp in_debug = 1; 90338889Sjdp return 1; 90438889Sjdp } 90538889Sjdp#endif 90633965Sjdp 90738889Sjdp return 0; 90838889Sjdp } 90938889Sjdp 91033965Sjdp line++; 91133965Sjdp 91233965Sjdp if (strncmp (line, "def", 3) == 0) 91333965Sjdp return 1; 91433965Sjdp if (strncmp (line, "val", 3) == 0) 91533965Sjdp return 1; 91633965Sjdp if (strncmp (line, "scl", 3) == 0) 91733965Sjdp return 1; 91833965Sjdp if (strncmp (line, "line", 4) == 0) 91933965Sjdp return 1; 92033965Sjdp if (strncmp (line, "endef", 5) == 0) 92133965Sjdp return 1; 92233965Sjdp if (strncmp (line, "ln", 2) == 0) 92333965Sjdp return 1; 92433965Sjdp if (strncmp (line, "type", 4) == 0) 92533965Sjdp return 1; 92633965Sjdp if (strncmp (line, "size", 4) == 0) 92733965Sjdp return 1; 92833965Sjdp if (strncmp (line, "dim", 3) == 0) 92933965Sjdp return 1; 93033965Sjdp if (strncmp (line, "tag", 3) == 0) 93133965Sjdp return 1; 93233965Sjdp if (strncmp (line, "stabs", 5) == 0) 93333965Sjdp return 1; 93433965Sjdp if (strncmp (line, "stabn", 5) == 0) 93533965Sjdp return 1; 93633965Sjdp 93733965Sjdp return 0; 93833965Sjdp} 93933965Sjdp 94033965Sjdpstatic void 941130561Sobrienlisting_listing (char *name ATTRIBUTE_UNUSED) 94233965Sjdp{ 94333965Sjdp list_info_type *list = head; 94433965Sjdp file_info_type *current_hll_file = (file_info_type *) NULL; 94533965Sjdp char *message; 94633965Sjdp char *buffer; 94733965Sjdp char *p; 94833965Sjdp int show_listing = 1; 94933965Sjdp unsigned int width; 95033965Sjdp 95138889Sjdp buffer = xmalloc (listing_rhs_width); 95238889Sjdp data_buffer = xmalloc (MAX_BYTES); 95333965Sjdp eject = 1; 95433965Sjdp list = head; 95533965Sjdp 95633965Sjdp while (list != (list_info_type *) NULL && 0) 95733965Sjdp { 95833965Sjdp if (list->next) 95933965Sjdp list->frag = list->next->frag; 96033965Sjdp list = list->next; 96133965Sjdp } 96233965Sjdp 96333965Sjdp list = head->next; 96433965Sjdp 96533965Sjdp while (list) 96633965Sjdp { 96760484Sobrien unsigned int list_line; 96860484Sobrien 96938889Sjdp width = listing_rhs_width > paper_width ? paper_width : 97038889Sjdp listing_rhs_width; 97133965Sjdp 97260484Sobrien list_line = list->line; 97333965Sjdp switch (list->edict) 97433965Sjdp { 97533965Sjdp case EDICT_LIST: 97660484Sobrien /* Skip all lines up to the current. */ 97760484Sobrien list_line--; 97833965Sjdp break; 97933965Sjdp case EDICT_NOLIST: 98033965Sjdp show_listing--; 98133965Sjdp break; 98233965Sjdp case EDICT_NOLIST_NEXT: 98377298Sobrien if (show_listing == 0) 98477298Sobrien list_line--; 98533965Sjdp break; 98633965Sjdp case EDICT_EJECT: 98733965Sjdp break; 98833965Sjdp case EDICT_NONE: 98933965Sjdp break; 99033965Sjdp case EDICT_TITLE: 99133965Sjdp title = list->edict_arg; 99233965Sjdp break; 99333965Sjdp case EDICT_SBTTL: 99433965Sjdp subtitle = list->edict_arg; 99533965Sjdp break; 99633965Sjdp default: 99733965Sjdp abort (); 99833965Sjdp } 99933965Sjdp 100060484Sobrien if (show_listing <= 0) 100160484Sobrien { 100260484Sobrien while (list->file->linenum < list_line 100360484Sobrien && !list->file->at_end) 100460484Sobrien p = buffer_line (list->file, buffer, width); 100560484Sobrien } 100660484Sobrien 100777298Sobrien if (list->edict == EDICT_LIST 100877298Sobrien || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0)) 100960484Sobrien { 101060484Sobrien /* Enable listing for the single line that caused the enable. */ 101160484Sobrien list_line++; 101260484Sobrien show_listing++; 101360484Sobrien } 101460484Sobrien 101533965Sjdp if (show_listing > 0) 101633965Sjdp { 101733965Sjdp /* Scan down the list and print all the stuff which can be done 101833965Sjdp with this line (or lines). */ 101933965Sjdp message = 0; 102033965Sjdp 102133965Sjdp if (list->hll_file) 1022130561Sobrien current_hll_file = list->hll_file; 102333965Sjdp 102438889Sjdp if (current_hll_file && list->hll_line && (listing & LISTING_HLL)) 1025130561Sobrien print_source (current_hll_file, list, buffer, width); 102633965Sjdp 102738889Sjdp if (list->line_contents) 102833965Sjdp { 102938889Sjdp if (!((listing & LISTING_NODEBUG) 103038889Sjdp && debugging_pseudo (list, list->line_contents))) 1031130561Sobrien print_lines (list, 1032130561Sobrien list->file->linenum == 0 ? list->line : list->file->linenum, 1033130561Sobrien list->line_contents, calc_hex (list)); 1034130561Sobrien 103560484Sobrien free (list->line_contents); 103660484Sobrien list->line_contents = NULL; 103738889Sjdp } 103838889Sjdp else 103938889Sjdp { 104060484Sobrien while (list->file->linenum < list_line 104138889Sjdp && !list->file->at_end) 104238889Sjdp { 104338889Sjdp unsigned int address; 104433965Sjdp 104538889Sjdp p = buffer_line (list->file, buffer, width); 104633965Sjdp 104760484Sobrien if (list->file->linenum < list_line) 104877298Sobrien address = ~(unsigned int) 0; 104938889Sjdp else 105038889Sjdp address = calc_hex (list); 105133965Sjdp 105238889Sjdp if (!((listing & LISTING_NODEBUG) 105338889Sjdp && debugging_pseudo (list, p))) 105438889Sjdp print_lines (list, list->file->linenum, p, address); 105538889Sjdp } 105633965Sjdp } 105733965Sjdp 105833965Sjdp if (list->edict == EDICT_EJECT) 1059130561Sobrien eject = 1; 106033965Sjdp } 106133965Sjdp 106277298Sobrien if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1) 106333965Sjdp --show_listing; 106433965Sjdp 106533965Sjdp list = list->next; 106633965Sjdp } 106738889Sjdp 106833965Sjdp free (buffer); 106938889Sjdp free (data_buffer); 107038889Sjdp data_buffer = NULL; 107133965Sjdp} 107233965Sjdp 107333965Sjdpvoid 1074130561Sobrienlisting_print (char *name) 107533965Sjdp{ 107633965Sjdp int using_stdout; 107777298Sobrien 107833965Sjdp title = ""; 107933965Sjdp subtitle = ""; 108033965Sjdp 108133965Sjdp if (name == NULL) 108233965Sjdp { 108333965Sjdp list_file = stdout; 108433965Sjdp using_stdout = 1; 108533965Sjdp } 108633965Sjdp else 108733965Sjdp { 108889857Sobrien list_file = fopen (name, FOPEN_WT); 108933965Sjdp if (list_file != NULL) 109033965Sjdp using_stdout = 0; 109133965Sjdp else 109233965Sjdp { 1093130561Sobrien#ifdef BFD_ASSEMBLER 1094130561Sobrien bfd_set_error (bfd_error_system_call); 1095130561Sobrien#endif 109660484Sobrien as_perror (_("can't open list file: %s"), name); 109733965Sjdp list_file = stdout; 109833965Sjdp using_stdout = 1; 109933965Sjdp } 110033965Sjdp } 110133965Sjdp 110233965Sjdp if (listing & LISTING_NOFORM) 1103130561Sobrien paper_height = 0; 110433965Sjdp 110533965Sjdp if (listing & LISTING_LISTING) 1106130561Sobrien listing_listing (name); 110733965Sjdp 110833965Sjdp if (listing & LISTING_SYMBOLS) 1109130561Sobrien list_symbol_table (); 111033965Sjdp 111133965Sjdp if (! using_stdout) 111233965Sjdp { 111333965Sjdp if (fclose (list_file) == EOF) 1114130561Sobrien { 1115130561Sobrien#ifdef BFD_ASSEMBLER 1116130561Sobrien bfd_set_error (bfd_error_system_call); 1117130561Sobrien#endif 1118130561Sobrien as_perror (_("error closing list file: %s"), name); 1119130561Sobrien } 112033965Sjdp } 112133965Sjdp 112238889Sjdp if (last_open_file) 1123130561Sobrien fclose (last_open_file); 112433965Sjdp} 112533965Sjdp 112633965Sjdpvoid 1127130561Sobrienlisting_file (const char *name) 112833965Sjdp{ 112933965Sjdp fn = name; 113033965Sjdp} 113133965Sjdp 113233965Sjdpvoid 1133130561Sobrienlisting_eject (int ignore ATTRIBUTE_UNUSED) 113433965Sjdp{ 113533965Sjdp if (listing) 113633965Sjdp listing_tail->edict = EDICT_EJECT; 113733965Sjdp} 113833965Sjdp 113933965Sjdpvoid 1140130561Sobrienlisting_flags (int ignore ATTRIBUTE_UNUSED) 114133965Sjdp{ 114233965Sjdp while ((*input_line_pointer++) && (*input_line_pointer != '\n')) 114333965Sjdp input_line_pointer++; 114433965Sjdp 114533965Sjdp} 114633965Sjdp 114733965Sjdp/* Turn listing on or off. An argument of 0 means to turn off 114833965Sjdp listing. An argument of 1 means to turn on listing. An argument 114933965Sjdp of 2 means to turn off listing, but as of the next line; that is, 115033965Sjdp the current line should be listed, but the next line should not. */ 115133965Sjdp 115233965Sjdpvoid 1153130561Sobrienlisting_list (int on) 115433965Sjdp{ 115533965Sjdp if (listing) 115633965Sjdp { 115733965Sjdp switch (on) 115833965Sjdp { 115933965Sjdp case 0: 116033965Sjdp if (listing_tail->edict == EDICT_LIST) 116133965Sjdp listing_tail->edict = EDICT_NONE; 116233965Sjdp else 116333965Sjdp listing_tail->edict = EDICT_NOLIST; 116433965Sjdp break; 116533965Sjdp case 1: 116633965Sjdp if (listing_tail->edict == EDICT_NOLIST 116733965Sjdp || listing_tail->edict == EDICT_NOLIST_NEXT) 116833965Sjdp listing_tail->edict = EDICT_NONE; 116933965Sjdp else 117033965Sjdp listing_tail->edict = EDICT_LIST; 117133965Sjdp break; 117233965Sjdp case 2: 117333965Sjdp listing_tail->edict = EDICT_NOLIST_NEXT; 117433965Sjdp break; 117533965Sjdp default: 117633965Sjdp abort (); 117733965Sjdp } 117833965Sjdp } 117933965Sjdp} 118033965Sjdp 118133965Sjdpvoid 1182130561Sobrienlisting_psize (int width_only) 118333965Sjdp{ 118433965Sjdp if (! width_only) 118533965Sjdp { 118633965Sjdp paper_height = get_absolute_expression (); 118733965Sjdp 118833965Sjdp if (paper_height < 0 || paper_height > 1000) 118933965Sjdp { 119033965Sjdp paper_height = 0; 119160484Sobrien as_warn (_("strange paper height, set to no form")); 119233965Sjdp } 119333965Sjdp 119433965Sjdp if (*input_line_pointer != ',') 119533965Sjdp { 119633965Sjdp demand_empty_rest_of_line (); 119733965Sjdp return; 119833965Sjdp } 119933965Sjdp 120033965Sjdp ++input_line_pointer; 120133965Sjdp } 120233965Sjdp 120333965Sjdp paper_width = get_absolute_expression (); 120433965Sjdp 120533965Sjdp demand_empty_rest_of_line (); 120633965Sjdp} 120733965Sjdp 120833965Sjdpvoid 1209130561Sobrienlisting_nopage (int ignore ATTRIBUTE_UNUSED) 121033965Sjdp{ 121133965Sjdp paper_height = 0; 121233965Sjdp} 121333965Sjdp 121433965Sjdpvoid 1215130561Sobrienlisting_title (int depth) 121633965Sjdp{ 121733965Sjdp int quoted; 121833965Sjdp char *start; 121933965Sjdp char *ttl; 122033965Sjdp unsigned int length; 122133965Sjdp 122233965Sjdp SKIP_WHITESPACE (); 122333965Sjdp if (*input_line_pointer != '\"') 122433965Sjdp quoted = 0; 122533965Sjdp else 122633965Sjdp { 122733965Sjdp quoted = 1; 122833965Sjdp ++input_line_pointer; 122933965Sjdp } 123033965Sjdp 123133965Sjdp start = input_line_pointer; 123233965Sjdp 123333965Sjdp while (*input_line_pointer) 123433965Sjdp { 123533965Sjdp if (quoted 123633965Sjdp ? *input_line_pointer == '\"' 123733965Sjdp : is_end_of_line[(unsigned char) *input_line_pointer]) 123833965Sjdp { 123933965Sjdp if (listing) 124033965Sjdp { 124133965Sjdp length = input_line_pointer - start; 124233965Sjdp ttl = xmalloc (length + 1); 124333965Sjdp memcpy (ttl, start, length); 124433965Sjdp ttl[length] = 0; 124533965Sjdp listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; 124633965Sjdp listing_tail->edict_arg = ttl; 124733965Sjdp } 124833965Sjdp if (quoted) 124933965Sjdp input_line_pointer++; 125033965Sjdp demand_empty_rest_of_line (); 125133965Sjdp return; 125233965Sjdp } 125333965Sjdp else if (*input_line_pointer == '\n') 125433965Sjdp { 125589857Sobrien as_bad (_("new line in title")); 125633965Sjdp demand_empty_rest_of_line (); 125733965Sjdp return; 125833965Sjdp } 125933965Sjdp else 126033965Sjdp { 126133965Sjdp input_line_pointer++; 126233965Sjdp } 126333965Sjdp } 126433965Sjdp} 126533965Sjdp 126633965Sjdpvoid 1267130561Sobrienlisting_source_line (unsigned int line) 126833965Sjdp{ 126933965Sjdp if (listing) 127033965Sjdp { 127133965Sjdp new_frag (); 127233965Sjdp listing_tail->hll_line = line; 127333965Sjdp new_frag (); 127433965Sjdp } 127533965Sjdp} 127633965Sjdp 127733965Sjdpvoid 1278130561Sobrienlisting_source_file (const char *file) 127933965Sjdp{ 128033965Sjdp if (listing) 128133965Sjdp listing_tail->hll_file = file_info (file); 128233965Sjdp} 128333965Sjdp 128433965Sjdp#else 128533965Sjdp 128677298Sobrien/* Dummy functions for when compiled without listing enabled. */ 128733965Sjdp 128833965Sjdpvoid 1289130561Sobrienlisting_flags (int ignore) 129033965Sjdp{ 129133965Sjdp s_ignore (0); 129233965Sjdp} 129333965Sjdp 129477298Sobrienvoid 1295130561Sobrienlisting_list (int on) 129633965Sjdp{ 129733965Sjdp s_ignore (0); 129833965Sjdp} 129933965Sjdp 130077298Sobrienvoid 1301130561Sobrienlisting_eject (int ignore) 130233965Sjdp{ 130333965Sjdp s_ignore (0); 130433965Sjdp} 130533965Sjdp 130677298Sobrienvoid 1307130561Sobrienlisting_psize (int ignore) 130833965Sjdp{ 130933965Sjdp s_ignore (0); 131033965Sjdp} 131133965Sjdp 131233965Sjdpvoid 1313130561Sobrienlisting_nopage (int ignore) 131433965Sjdp{ 131533965Sjdp s_ignore (0); 131633965Sjdp} 131733965Sjdp 131877298Sobrienvoid 1319130561Sobrienlisting_title (int depth) 132033965Sjdp{ 132133965Sjdp s_ignore (0); 132233965Sjdp} 132333965Sjdp 132433965Sjdpvoid 1325130561Sobrienlisting_file (const char *name) 132633965Sjdp{ 132733965Sjdp} 132833965Sjdp 132977298Sobrienvoid 1330130561Sobrienlisting_newline (char *name) 133133965Sjdp{ 133233965Sjdp} 133333965Sjdp 133477298Sobrienvoid 1335130561Sobrienlisting_source_line (unsigned int n) 133633965Sjdp{ 133733965Sjdp} 133877298Sobrien 133977298Sobrienvoid 1340130561Sobrienlisting_source_file (const char *n) 134133965Sjdp{ 134233965Sjdp} 134333965Sjdp 134433965Sjdp#endif 1345