listing.c revision 104834
133965Sjdp/* listing.c - mainting assembly listings 277298Sobrien Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 3104834Sobrien 2001, 2002 438889Sjdp Free Software Foundation, Inc. 533965Sjdp 633965SjdpThis file is part of GAS, the GNU Assembler. 733965Sjdp 833965SjdpGAS is free software; you can redistribute it and/or modify 933965Sjdpit under the terms of the GNU General Public License as published by 1033965Sjdpthe Free Software Foundation; either version 2, or (at your option) 1133965Sjdpany later version. 1233965Sjdp 1333965SjdpGAS is distributed in the hope that it will be useful, 1433965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1533965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965SjdpGNU General Public License for more details. 1733965Sjdp 1833965SjdpYou should have received a copy of the GNU General Public License 1933965Sjdpalong with GAS; see the file COPYING. If not, write to the Free 2033965SjdpSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2177298Sobrien02111-1307, USA. */ 2233965Sjdp 2333965Sjdp/* 2477298Sobrien Contributed by Steve Chamberlain <sac@cygnus.com> 2533965Sjdp 2633965Sjdp A listing page looks like: 2733965Sjdp 2833965Sjdp LISTING_HEADER sourcefilename pagenumber 2933965Sjdp TITLE LINE 3033965Sjdp SUBTITLE LINE 3133965Sjdp linenumber address data source 3233965Sjdp linenumber address data source 3333965Sjdp linenumber address data source 3433965Sjdp linenumber address data source 3533965Sjdp 3633965Sjdp If not overridden, the listing commands are: 3733965Sjdp 3833965Sjdp .title "stuff" 3933965Sjdp Put "stuff" onto the title line 4033965Sjdp .sbttl "stuff" 4133965Sjdp Put stuff onto the subtitle line 4233965Sjdp 4333965Sjdp If these commands come within 10 lines of the top of the page, they 4433965Sjdp will affect the page they are on, as well as any subsequent page 4533965Sjdp 4633965Sjdp .eject 4733965Sjdp Thow a page 4833965Sjdp .list 4933965Sjdp Increment the enable listing counter 5033965Sjdp .nolist 5133965Sjdp Decrement the enable listing counter 5233965Sjdp 5333965Sjdp .psize Y[,X] 5433965Sjdp Set the paper size to X wide and Y high. Setting a psize Y of 5533965Sjdp zero will suppress form feeds except where demanded by .eject 5633965Sjdp 5733965Sjdp If the counter goes below zero, listing is suppressed. 5833965Sjdp 5933965Sjdp Listings are a maintained by read calling various listing_<foo> 6033965Sjdp functions. What happens most is that the macro NO_LISTING is not 6133965Sjdp defined (from the Makefile), then the macro LISTING_NEWLINE expands 6233965Sjdp into a call to listing_newline. The call is done from read.c, every 6333965Sjdp time it sees a newline, and -l is on the command line. 6433965Sjdp 6533965Sjdp The function listing_newline remembers the frag associated with the 6633965Sjdp newline, and creates a new frag - note that this is wasteful, but not 6733965Sjdp a big deal, since listing slows things down a lot anyway. The 6833965Sjdp function also rememebers when the filename changes. 6933965Sjdp 7033965Sjdp When all the input has finished, and gas has had a chance to settle 7133965Sjdp down, the listing is output. This is done by running down the list of 7233965Sjdp frag/source file records, and opening the files as needed and printing 7333965Sjdp out the bytes and chars associated with them. 7433965Sjdp 7533965Sjdp The only things which the architecture can change about the listing 7633965Sjdp are defined in these macros: 7733965Sjdp 7833965Sjdp LISTING_HEADER The name of the architecture 7933965Sjdp LISTING_WORD_SIZE The make of the number of bytes in a word, this determines 8033965Sjdp the clumping of the output data. eg a value of 8133965Sjdp 2 makes words look like 1234 5678, whilst 1 8233965Sjdp would make the same value look like 12 34 56 8333965Sjdp 78 8433965Sjdp LISTING_LHS_WIDTH Number of words of above size for the lhs 8533965Sjdp 8633965Sjdp LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs 8733965Sjdp for the second line 8833965Sjdp 8933965Sjdp LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation 9033965Sjdp LISTING_RHS_WIDTH Number of chars from the input file to print 9133965Sjdp on a line 9233965Sjdp*/ 9333965Sjdp 9433965Sjdp#include "as.h" 95104834Sobrien#include "obstack.h" 9689857Sobrien#include "safe-ctype.h" 9733965Sjdp#include "input-file.h" 9833965Sjdp#include "subsegs.h" 9933965Sjdp 10033965Sjdp#ifndef NO_LISTING 10138889Sjdp 10233965Sjdp#ifndef LISTING_HEADER 10333965Sjdp#define LISTING_HEADER "GAS LISTING" 10433965Sjdp#endif 10533965Sjdp#ifndef LISTING_WORD_SIZE 10633965Sjdp#define LISTING_WORD_SIZE 4 10733965Sjdp#endif 10833965Sjdp#ifndef LISTING_LHS_WIDTH 10960484Sobrien#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE)) 11033965Sjdp#endif 11133965Sjdp#ifndef LISTING_LHS_WIDTH_SECOND 11260484Sobrien#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH 11333965Sjdp#endif 11433965Sjdp#ifndef LISTING_RHS_WIDTH 11533965Sjdp#define LISTING_RHS_WIDTH 100 11633965Sjdp#endif 11733965Sjdp#ifndef LISTING_LHS_CONT_LINES 11833965Sjdp#define LISTING_LHS_CONT_LINES 4 11933965Sjdp#endif 12033965Sjdp 12177298Sobrien/* This structure remembers which .s were used. */ 12277298Sobrientypedef struct file_info_struct { 12360484Sobrien struct file_info_struct * next; 12460484Sobrien char * filename; 12560484Sobrien long pos; 12660484Sobrien unsigned int linenum; 12760484Sobrien int at_end; 12877298Sobrien} file_info_type; 12933965Sjdp 13060484Sobrien/* This structure rememebrs which line from which file goes into which 13177298Sobrien frag. */ 13277298Sobrienstruct list_info_struct { 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; 13833965Sjdp /* Pointer to the file info struct for the file which this line 13977298Sobrien belongs to. */ 14077298Sobrien file_info_type *file; 14133965Sjdp 14238889Sjdp /* The expanded text of any macro that may have been executing. */ 14377298Sobrien char *line_contents; 14438889Sjdp 14577298Sobrien /* Next in list. */ 14677298Sobrien struct list_info_struct *next; 14733965Sjdp 14833965Sjdp /* Pointer to the file info struct for the high level language 14977298Sobrien source line that belongs here. */ 15077298Sobrien file_info_type *hll_file; 15177298Sobrien /* High level language source line. */ 15238889Sjdp unsigned int hll_line; 15333965Sjdp 15477298Sobrien /* Pointer to any error message associated with this line. */ 15577298Sobrien char *message; 15633965Sjdp 15777298Sobrien enum { 15877298Sobrien EDICT_NONE, 15977298Sobrien EDICT_SBTTL, 16077298Sobrien EDICT_TITLE, 16177298Sobrien EDICT_NOLIST, 16277298Sobrien EDICT_LIST, 16377298Sobrien EDICT_NOLIST_NEXT, 16477298Sobrien EDICT_EJECT 16577298Sobrien } edict; 16677298Sobrien char *edict_arg; 16733965Sjdp 16838889Sjdp /* Nonzero if this line is to be omitted because it contains 16938889Sjdp debugging information. This can become a flags field if we come 17038889Sjdp up with more information to store here. */ 17138889Sjdp int debugging; 17238889Sjdp}; 17333965Sjdp 17438889Sjdptypedef struct list_info_struct list_info_type; 17533965Sjdp 17660484Sobrienint listing_lhs_width = LISTING_LHS_WIDTH; 17760484Sobrienint listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND; 17860484Sobrienint listing_lhs_cont_lines = LISTING_LHS_CONT_LINES; 17960484Sobrienint listing_rhs_width = LISTING_RHS_WIDTH; 18033965Sjdp 18160484Sobrienstruct list_info_struct * listing_tail; 18260484Sobrien 18360484Sobrienstatic file_info_type * file_info_head; 18460484Sobrienstatic file_info_type * last_open_file_info; 18560484Sobrienstatic FILE * last_open_file; 18660484Sobrienstatic struct list_info_struct * head; 18760484Sobrienstatic int paper_width = 200; 18860484Sobrienstatic int paper_height = 60; 18960484Sobrien 19060484Sobrienextern int listing; 19160484Sobrien 19233965Sjdp/* File to output listings to. */ 19377298Sobrienstatic FILE *list_file; 19433965Sjdp 19538889Sjdp/* This static array is used to keep the text of data to be printed 19638889Sjdp before the start of the line. */ 19733965Sjdp 19838889Sjdp#define MAX_BYTES \ 19938889Sjdp (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \ 20038889Sjdp + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \ 20138889Sjdp * listing_lhs_cont_lines) \ 20238889Sjdp + 20) 20333965Sjdp 20477298Sobrienstatic char *data_buffer; 20533965Sjdp 20633965Sjdp/* Prototypes. */ 20733965Sjdpstatic void listing_message PARAMS ((const char *name, const char *message)); 20877298Sobrienstatic file_info_type *file_info PARAMS ((const char *file_name)); 20933965Sjdpstatic void new_frag PARAMS ((void)); 21077298Sobrienstatic char *buffer_line PARAMS ((file_info_type *file, 21133965Sjdp char *line, unsigned int size)); 21233965Sjdpstatic void listing_page PARAMS ((list_info_type *list)); 21333965Sjdpstatic unsigned int calc_hex PARAMS ((list_info_type *list)); 21433965Sjdpstatic void print_lines PARAMS ((list_info_type *, unsigned int, 21533965Sjdp char *, unsigned int)); 21633965Sjdpstatic void list_symbol_table PARAMS ((void)); 21733965Sjdpstatic void print_source PARAMS ((file_info_type *current_file, 21833965Sjdp list_info_type *list, 21933965Sjdp char *buffer, 22033965Sjdp unsigned int width)); 22138889Sjdpstatic int debugging_pseudo PARAMS ((list_info_type *, const char *)); 22233965Sjdpstatic void listing_listing PARAMS ((char *name)); 22333965Sjdp 22433965Sjdpstatic void 22533965Sjdplisting_message (name, message) 22633965Sjdp const char *name; 22733965Sjdp const char *message; 22833965Sjdp{ 22933965Sjdp if (listing_tail != (list_info_type *) NULL) 23033965Sjdp { 23177298Sobrien unsigned int l = strlen (name) + strlen (message) + 1; 23277298Sobrien char *n = (char *) xmalloc (l); 23377298Sobrien strcpy (n, name); 23477298Sobrien strcat (n, message); 23533965Sjdp listing_tail->message = n; 23633965Sjdp } 23733965Sjdp} 23833965Sjdp 23933965Sjdpvoid 24033965Sjdplisting_warning (message) 24133965Sjdp const char *message; 24233965Sjdp{ 24360484Sobrien listing_message (_("Warning:"), message); 24433965Sjdp} 24533965Sjdp 24633965Sjdpvoid 24733965Sjdplisting_error (message) 24833965Sjdp const char *message; 24933965Sjdp{ 25060484Sobrien listing_message (_("Error:"), message); 25133965Sjdp} 25233965Sjdp 25333965Sjdpstatic file_info_type * 25433965Sjdpfile_info (file_name) 25533965Sjdp const char *file_name; 25633965Sjdp{ 25777298Sobrien /* Find an entry with this file name. */ 25833965Sjdp file_info_type *p = file_info_head; 25933965Sjdp 26033965Sjdp while (p != (file_info_type *) NULL) 26133965Sjdp { 26233965Sjdp if (strcmp (p->filename, file_name) == 0) 26333965Sjdp return p; 26433965Sjdp p = p->next; 26533965Sjdp } 26633965Sjdp 26777298Sobrien /* Make new entry. */ 26833965Sjdp 26933965Sjdp p = (file_info_type *) xmalloc (sizeof (file_info_type)); 27033965Sjdp p->next = file_info_head; 27133965Sjdp file_info_head = p; 272104834Sobrien p->filename = xstrdup (file_name); 27338889Sjdp p->pos = 0; 27433965Sjdp p->linenum = 0; 27533965Sjdp p->at_end = 0; 27633965Sjdp 27733965Sjdp return p; 27833965Sjdp} 27933965Sjdp 28033965Sjdpstatic void 28133965Sjdpnew_frag () 28233965Sjdp{ 28333965Sjdp 28433965Sjdp frag_wane (frag_now); 28533965Sjdp frag_new (0); 28633965Sjdp 28733965Sjdp} 28833965Sjdp 28933965Sjdpvoid 29033965Sjdplisting_newline (ps) 29133965Sjdp char *ps; 29233965Sjdp{ 29333965Sjdp char *file; 29433965Sjdp unsigned int line; 29533965Sjdp static unsigned int last_line = 0xffff; 29633965Sjdp static char *last_file = NULL; 29738889Sjdp list_info_type *new = NULL; 29833965Sjdp 29933965Sjdp if (listing == 0) 30033965Sjdp return; 30133965Sjdp 30233965Sjdp if (now_seg == absolute_section) 30333965Sjdp return; 30433965Sjdp 30538889Sjdp#ifdef OBJ_ELF 30638889Sjdp /* In ELF, anything in a section beginning with .debug or .line is 30738889Sjdp considered to be debugging information. This includes the 30838889Sjdp statement which switches us into the debugging section, which we 30938889Sjdp can only set after we are already in the debugging section. */ 31038889Sjdp if ((listing & LISTING_NODEBUG) != 0 31138889Sjdp && listing_tail != NULL 31238889Sjdp && ! listing_tail->debugging) 31338889Sjdp { 31438889Sjdp const char *segname; 31538889Sjdp 31638889Sjdp segname = segment_name (now_seg); 31738889Sjdp if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 31838889Sjdp || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 31938889Sjdp listing_tail->debugging = 1; 32038889Sjdp } 32138889Sjdp#endif 32238889Sjdp 32333965Sjdp as_where (&file, &line); 32438889Sjdp if (ps == NULL) 32533965Sjdp { 32677298Sobrien if (line == last_line 32777298Sobrien && !(last_file && file && strcmp (file, last_file))) 32838889Sjdp return; 32933965Sjdp 33033965Sjdp new = (list_info_type *) xmalloc (sizeof (list_info_type)); 33160484Sobrien 33260484Sobrien /* Detect if we are reading from stdin by examining the file 33360484Sobrien name returned by as_where(). 33460484Sobrien 33560484Sobrien [FIXME: We rely upon the name in the strcmp below being the 33660484Sobrien same as the one used by input_scrub_new_file(), if that is 33760484Sobrien not true, then this code will fail]. 33860484Sobrien 33977298Sobrien If we are reading from stdin, then we need to save each input 34077298Sobrien line here (assuming of course that we actually have a line of 34177298Sobrien input to read), so that it can be displayed in the listing 34277298Sobrien that is produced at the end of the assembly. */ 34360484Sobrien if (strcmp (file, _("{standard input}")) == 0 34460484Sobrien && input_line_pointer != NULL) 34560484Sobrien { 34677298Sobrien char *copy; 34760484Sobrien int len; 34860484Sobrien int seen_quote = 0; 34960484Sobrien 35060484Sobrien for (copy = input_line_pointer - 1; 35177298Sobrien *copy && (seen_quote 35277298Sobrien || (! is_end_of_line [(unsigned char) *copy])); 35377298Sobrien copy++) 35477298Sobrien if (*copy == '"' && copy[-1] != '\\') 35560484Sobrien seen_quote = ! seen_quote; 35660484Sobrien 35760484Sobrien len = (copy - input_line_pointer) + 2; 35860484Sobrien 35960484Sobrien copy = xmalloc (len); 36060484Sobrien 36160484Sobrien if (copy != NULL) 36260484Sobrien { 36377298Sobrien char *src = input_line_pointer - 1; 36477298Sobrien char *dest = copy; 36577298Sobrien 36660484Sobrien while (--len) 36760484Sobrien { 36877298Sobrien unsigned char c = *src++; 36960484Sobrien 37060484Sobrien /* Omit control characters in the listing. */ 37189857Sobrien if (!ISCNTRL (c)) 37277298Sobrien *dest++ = c; 37360484Sobrien } 37477298Sobrien 37560484Sobrien *dest = 0; 37660484Sobrien } 37777298Sobrien 37860484Sobrien new->line_contents = copy; 37960484Sobrien } 38060484Sobrien else 38160484Sobrien new->line_contents = NULL; 38238889Sjdp } 38338889Sjdp else 38438889Sjdp { 38538889Sjdp new = (list_info_type *) xmalloc (sizeof (list_info_type)); 38638889Sjdp new->line_contents = ps; 38738889Sjdp } 38833965Sjdp 38938889Sjdp last_line = line; 39038889Sjdp last_file = file; 39177298Sobrien 39238889Sjdp new_frag (); 39338889Sjdp 39438889Sjdp if (listing_tail) 39560484Sobrien listing_tail->next = new; 39638889Sjdp else 39760484Sobrien head = new; 39877298Sobrien 39938889Sjdp listing_tail = new; 40038889Sjdp 40138889Sjdp new->frag = frag_now; 40238889Sjdp new->line = line; 40338889Sjdp new->file = file_info (file); 40438889Sjdp new->next = (list_info_type *) NULL; 40538889Sjdp new->message = (char *) NULL; 40638889Sjdp new->edict = EDICT_NONE; 40738889Sjdp new->hll_file = (file_info_type *) NULL; 40838889Sjdp new->hll_line = 0; 40938889Sjdp new->debugging = 0; 41077298Sobrien 41138889Sjdp new_frag (); 41238889Sjdp 41338889Sjdp#ifdef OBJ_ELF 41438889Sjdp /* In ELF, anything in a section beginning with .debug or .line is 41538889Sjdp considered to be debugging information. */ 41638889Sjdp if ((listing & LISTING_NODEBUG) != 0) 41738889Sjdp { 41838889Sjdp const char *segname; 41938889Sjdp 42038889Sjdp segname = segment_name (now_seg); 42138889Sjdp if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 42238889Sjdp || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 42338889Sjdp new->debugging = 1; 42438889Sjdp } 42538889Sjdp#endif 42633965Sjdp} 42733965Sjdp 42833965Sjdp/* Attach all current frags to the previous line instead of the 42933965Sjdp current line. This is called by the MIPS backend when it discovers 43033965Sjdp that it needs to add some NOP instructions; the added NOP 43133965Sjdp instructions should go with the instruction that has the delay, not 43233965Sjdp with the new instruction. */ 43333965Sjdp 43433965Sjdpvoid 43533965Sjdplisting_prev_line () 43633965Sjdp{ 43733965Sjdp list_info_type *l; 43833965Sjdp fragS *f; 43933965Sjdp 44033965Sjdp if (head == (list_info_type *) NULL 44133965Sjdp || head == listing_tail) 44233965Sjdp return; 44333965Sjdp 44433965Sjdp new_frag (); 44533965Sjdp 44633965Sjdp for (l = head; l->next != listing_tail; l = l->next) 44733965Sjdp ; 44833965Sjdp 44933965Sjdp for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next) 45033965Sjdp if (f->line == listing_tail) 45133965Sjdp f->line = l; 45233965Sjdp 45333965Sjdp listing_tail->frag = frag_now; 45433965Sjdp new_frag (); 45533965Sjdp} 45633965Sjdp 45777298Sobrien/* This function returns the next source line from the file supplied, 45877298Sobrien truncated to size. It appends a fake line to the end of each input 45977298Sobrien file to make. */ 46033965Sjdp 46133965Sjdpstatic char * 46233965Sjdpbuffer_line (file, line, size) 46377298Sobrien file_info_type *file; 46433965Sjdp char *line; 46533965Sjdp unsigned int size; 46633965Sjdp{ 46733965Sjdp unsigned int count = 0; 46833965Sjdp int c; 46933965Sjdp 47033965Sjdp char *p = line; 47133965Sjdp 47277298Sobrien /* If we couldn't open the file, return an empty line. */ 47338889Sjdp if (file->at_end) 47438889Sjdp return ""; 47538889Sjdp 47638889Sjdp /* Check the cache and see if we last used this file. */ 47738889Sjdp if (!last_open_file_info || file != last_open_file_info) 47833965Sjdp { 47938889Sjdp if (last_open_file) 48038889Sjdp { 48138889Sjdp last_open_file_info->pos = ftell (last_open_file); 48238889Sjdp fclose (last_open_file); 48338889Sjdp } 48438889Sjdp 48538889Sjdp last_open_file_info = file; 48689857Sobrien last_open_file = fopen (file->filename, FOPEN_RT); 48738889Sjdp if (last_open_file == NULL) 48838889Sjdp { 48938889Sjdp file->at_end = 1; 49038889Sjdp return ""; 49138889Sjdp } 49277298Sobrien 49338889Sjdp /* Seek to where we were last time this file was open. */ 49438889Sjdp if (file->pos) 49577298Sobrien fseek (last_open_file, file->pos, SEEK_SET); 49633965Sjdp } 49733965Sjdp 49838889Sjdp c = fgetc (last_open_file); 49933965Sjdp 50077298Sobrien /* Leave room for null. */ 50177298Sobrien size -= 1; 50233965Sjdp 50333965Sjdp while (c != EOF && c != '\n') 50433965Sjdp { 50533965Sjdp if (count < size) 50633965Sjdp *p++ = c; 50733965Sjdp count++; 50833965Sjdp 50938889Sjdp c = fgetc (last_open_file); 51033965Sjdp 51133965Sjdp } 51233965Sjdp if (c == EOF) 51333965Sjdp { 51433965Sjdp file->at_end = 1; 51589857Sobrien if (count + 2 < size) 51689857Sobrien { 51789857Sobrien *p++ = '.'; 51889857Sobrien *p++ = '.'; 51989857Sobrien *p++ = '.'; 52089857Sobrien } 52133965Sjdp } 52233965Sjdp file->linenum++; 52333965Sjdp *p++ = 0; 52433965Sjdp return line; 52533965Sjdp} 52633965Sjdp 52733965Sjdpstatic const char *fn; 52833965Sjdp 52933965Sjdpstatic unsigned int eject; /* Eject pending */ 53033965Sjdpstatic unsigned int page; /* Current page number */ 53177298Sobrienstatic char *title; /* Current title */ 53277298Sobrienstatic char *subtitle; /* Current subtitle */ 53377298Sobrienstatic unsigned int on_page; /* Number of lines printed on current page */ 53433965Sjdp 53533965Sjdpstatic void 53633965Sjdplisting_page (list) 53733965Sjdp list_info_type *list; 53833965Sjdp{ 53933965Sjdp /* Grope around, see if we can see a title or subtitle edict coming up 54077298Sobrien soon. (we look down 10 lines of the page and see if it's there) */ 54177298Sobrien if ((eject || (on_page >= (unsigned int) paper_height)) 54277298Sobrien && paper_height != 0) 54333965Sjdp { 54433965Sjdp unsigned int c = 10; 54533965Sjdp int had_title = 0; 54633965Sjdp int had_subtitle = 0; 54733965Sjdp 54833965Sjdp page++; 54933965Sjdp 55033965Sjdp while (c != 0 && list) 55133965Sjdp { 55233965Sjdp if (list->edict == EDICT_SBTTL && !had_subtitle) 55333965Sjdp { 55433965Sjdp had_subtitle = 1; 55533965Sjdp subtitle = list->edict_arg; 55633965Sjdp } 55733965Sjdp if (list->edict == EDICT_TITLE && !had_title) 55833965Sjdp { 55933965Sjdp had_title = 1; 56033965Sjdp title = list->edict_arg; 56133965Sjdp } 56233965Sjdp list = list->next; 56333965Sjdp c--; 56433965Sjdp } 56533965Sjdp 56633965Sjdp if (page > 1) 56733965Sjdp { 56833965Sjdp fprintf (list_file, "\f"); 56933965Sjdp } 57033965Sjdp 57133965Sjdp fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); 57233965Sjdp fprintf (list_file, "%s\n", title); 57333965Sjdp fprintf (list_file, "%s\n", subtitle); 57433965Sjdp on_page = 3; 57533965Sjdp eject = 0; 57633965Sjdp } 57733965Sjdp} 57833965Sjdp 57933965Sjdpstatic unsigned int 58033965Sjdpcalc_hex (list) 58177298Sobrien list_info_type *list; 58233965Sjdp{ 58338889Sjdp int data_buffer_size; 58433965Sjdp list_info_type *first = list; 58577298Sobrien unsigned int address = ~(unsigned int) 0; 58633965Sjdp fragS *frag; 58733965Sjdp fragS *frag_ptr; 58860484Sobrien unsigned int octet_in_frag; 58933965Sjdp 59077298Sobrien /* Find first frag which says it belongs to this line. */ 59133965Sjdp frag = list->frag; 59233965Sjdp while (frag && frag->line != list) 59333965Sjdp frag = frag->fr_next; 59433965Sjdp 59533965Sjdp frag_ptr = frag; 59633965Sjdp 59733965Sjdp data_buffer_size = 0; 59833965Sjdp 59977298Sobrien /* Dump all the frags which belong to this line. */ 60033965Sjdp while (frag_ptr != (fragS *) NULL && frag_ptr->line == first) 60133965Sjdp { 60277298Sobrien /* Print as many bytes from the fixed part as is sensible. */ 60360484Sobrien octet_in_frag = 0; 60460484Sobrien while ((offsetT) octet_in_frag < frag_ptr->fr_fix 60538889Sjdp && data_buffer_size < MAX_BYTES - 3) 60633965Sjdp { 60777298Sobrien if (address == ~(unsigned int) 0) 60833965Sjdp { 60960484Sobrien address = frag_ptr->fr_address / OCTETS_PER_BYTE; 61033965Sjdp } 61133965Sjdp 61233965Sjdp sprintf (data_buffer + data_buffer_size, 61333965Sjdp "%02X", 61460484Sobrien (frag_ptr->fr_literal[octet_in_frag]) & 0xff); 61533965Sjdp data_buffer_size += 2; 61660484Sobrien octet_in_frag++; 61733965Sjdp } 618104834Sobrien if (frag_ptr->fr_type == rs_fill) 619104834Sobrien { 620104834Sobrien unsigned int var_rep_max = octet_in_frag; 621104834Sobrien unsigned int var_rep_idx = octet_in_frag; 62233965Sjdp 623104834Sobrien /* Print as many bytes from the variable part as is sensible. */ 624104834Sobrien while (((offsetT) octet_in_frag 625104834Sobrien < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)) 626104834Sobrien && data_buffer_size < MAX_BYTES - 3) 627104834Sobrien { 628104834Sobrien if (address == ~(unsigned int) 0) 629104834Sobrien { 630104834Sobrien address = frag_ptr->fr_address / OCTETS_PER_BYTE; 631104834Sobrien } 632104834Sobrien sprintf (data_buffer + data_buffer_size, 633104834Sobrien "%02X", 634104834Sobrien (frag_ptr->fr_literal[var_rep_idx]) & 0xff); 63533965Sjdp#if 0 636104834Sobrien data_buffer[data_buffer_size++] = '*'; 637104834Sobrien data_buffer[data_buffer_size++] = '*'; 63833965Sjdp#endif 639104834Sobrien data_buffer_size += 2; 64033965Sjdp 641104834Sobrien var_rep_idx++; 642104834Sobrien octet_in_frag++; 64333965Sjdp 644104834Sobrien if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var) 645104834Sobrien var_rep_idx = var_rep_max; 646104834Sobrien } 647104834Sobrien } 64833965Sjdp 64933965Sjdp frag_ptr = frag_ptr->fr_next; 65033965Sjdp } 65138889Sjdp data_buffer[data_buffer_size] = '\0'; 65233965Sjdp return address; 65333965Sjdp} 65433965Sjdp 65533965Sjdpstatic void 65633965Sjdpprint_lines (list, lineno, string, address) 65733965Sjdp list_info_type *list; 65833965Sjdp unsigned int lineno; 65933965Sjdp char *string; 66033965Sjdp unsigned int address; 66133965Sjdp{ 66233965Sjdp unsigned int idx; 66333965Sjdp unsigned int nchars; 66433965Sjdp unsigned int lines; 66560484Sobrien unsigned int octet_in_word = 0; 66633965Sjdp char *src = data_buffer; 66760484Sobrien int cur; 66833965Sjdp 66977298Sobrien /* Print the stuff on the first line. */ 67033965Sjdp listing_page (list); 67138889Sjdp nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width; 67277298Sobrien 67377298Sobrien /* Print the hex for the first line. */ 67477298Sobrien if (address == ~(unsigned int) 0) 67533965Sjdp { 67633965Sjdp fprintf (list_file, "% 4d ", lineno); 67733965Sjdp for (idx = 0; idx < nchars; idx++) 67833965Sjdp fprintf (list_file, " "); 67933965Sjdp 68033965Sjdp fprintf (list_file, "\t%s\n", string ? string : ""); 68177298Sobrien 68277298Sobrien on_page++; 68377298Sobrien 68433965Sjdp listing_page (0); 68533965Sjdp 68660484Sobrien return; 68733965Sjdp } 68860484Sobrien 68960484Sobrien if (had_errors ()) 69060484Sobrien fprintf (list_file, "% 4d ???? ", lineno); 69133965Sjdp else 69260484Sobrien fprintf (list_file, "% 4d %04x ", lineno, address); 69360484Sobrien 69477298Sobrien /* And the data to go along with it. */ 69560484Sobrien idx = 0; 69660484Sobrien cur = 0; 69760484Sobrien while (src[cur] && idx < nchars) 69833965Sjdp { 69960484Sobrien int offset; 70060484Sobrien offset = cur; 70177298Sobrien fprintf (list_file, "%c%c", src[offset], src[offset + 1]); 70260484Sobrien cur += 2; 70360484Sobrien octet_in_word++; 70477298Sobrien 70560484Sobrien if (octet_in_word == LISTING_WORD_SIZE) 70633965Sjdp { 70760484Sobrien fprintf (list_file, " "); 70860484Sobrien idx++; 70960484Sobrien octet_in_word = 0; 71033965Sjdp } 71177298Sobrien 71260484Sobrien idx += 2; 71360484Sobrien } 71477298Sobrien 71560484Sobrien for (; idx < nchars; idx++) 71660484Sobrien fprintf (list_file, " "); 71777298Sobrien 71860484Sobrien fprintf (list_file, "\t%s\n", string ? string : ""); 71960484Sobrien on_page++; 72060484Sobrien listing_page (list); 72177298Sobrien 72260484Sobrien if (list->message) 72360484Sobrien { 72460484Sobrien fprintf (list_file, "**** %s\n", list->message); 72560484Sobrien listing_page (list); 72660484Sobrien on_page++; 72760484Sobrien } 72877298Sobrien 72960484Sobrien for (lines = 0; 73060484Sobrien lines < (unsigned int) listing_lhs_cont_lines 73160484Sobrien && src[cur]; 73277298Sobrien lines++) 73360484Sobrien { 73477298Sobrien nchars = ((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second - 1; 73533965Sjdp idx = 0; 73677298Sobrien 73777298Sobrien /* Print any more lines of data, but more compactly. */ 73860484Sobrien fprintf (list_file, "% 4d ", lineno); 73977298Sobrien 74060484Sobrien while (src[cur] && idx < nchars) 74133965Sjdp { 74277298Sobrien int offset; 74377298Sobrien offset = cur; 74477298Sobrien fprintf (list_file, "%c%c", src[offset], src[offset + 1]); 74560484Sobrien cur += 2; 74660484Sobrien idx += 2; 74760484Sobrien octet_in_word++; 74877298Sobrien 74960484Sobrien if (octet_in_word == LISTING_WORD_SIZE) 75033965Sjdp { 75133965Sjdp fprintf (list_file, " "); 75233965Sjdp idx++; 75360484Sobrien octet_in_word = 0; 75433965Sjdp } 75533965Sjdp } 75677298Sobrien 75760484Sobrien fprintf (list_file, "\n"); 75877298Sobrien on_page++; 75933965Sjdp listing_page (list); 76033965Sjdp } 76133965Sjdp} 76233965Sjdp 76333965Sjdpstatic void 76433965Sjdplist_symbol_table () 76533965Sjdp{ 76633965Sjdp extern symbolS *symbol_rootP; 76733965Sjdp int got_some = 0; 76833965Sjdp 76933965Sjdp symbolS *ptr; 77033965Sjdp eject = 1; 77133965Sjdp listing_page (0); 77233965Sjdp 77333965Sjdp for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 77433965Sjdp { 77538889Sjdp if (SEG_NORMAL (S_GET_SEGMENT (ptr)) 77638889Sjdp || S_GET_SEGMENT (ptr) == absolute_section) 77733965Sjdp { 77838889Sjdp#ifdef BFD_ASSEMBLER 77938889Sjdp /* Don't report section symbols. They are not interesting. */ 78060484Sobrien if (symbol_section_p (ptr)) 78138889Sjdp continue; 78238889Sjdp#endif 78333965Sjdp if (S_GET_NAME (ptr)) 78433965Sjdp { 78533965Sjdp char buf[30], fmt[8]; 78633965Sjdp valueT val = S_GET_VALUE (ptr); 78733965Sjdp 78833965Sjdp /* @@ Note that this is dependent on the compilation options, 78933965Sjdp not solely on the target characteristics. */ 79033965Sjdp if (sizeof (val) == 4 && sizeof (int) == 4) 79133965Sjdp sprintf (buf, "%08lx", (unsigned long) val); 79233965Sjdp else if (sizeof (val) <= sizeof (unsigned long)) 79333965Sjdp { 79433965Sjdp sprintf (fmt, "%%0%lulx", 79533965Sjdp (unsigned long) (sizeof (val) * 2)); 79633965Sjdp sprintf (buf, fmt, (unsigned long) val); 79733965Sjdp } 79833965Sjdp#if defined (BFD64) 79933965Sjdp else if (sizeof (val) > 4) 80033965Sjdp sprintf_vma (buf, val); 80133965Sjdp#endif 80233965Sjdp else 80333965Sjdp abort (); 80433965Sjdp 80533965Sjdp if (!got_some) 80633965Sjdp { 80733965Sjdp fprintf (list_file, "DEFINED SYMBOLS\n"); 80833965Sjdp on_page++; 80933965Sjdp got_some = 1; 81033965Sjdp } 81133965Sjdp 81260484Sobrien if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line) 81338889Sjdp { 81438889Sjdp fprintf (list_file, "%20s:%-5d %s:%s %s\n", 81560484Sobrien symbol_get_frag (ptr)->line->file->filename, 81660484Sobrien symbol_get_frag (ptr)->line->line, 81738889Sjdp segment_name (S_GET_SEGMENT (ptr)), 81838889Sjdp buf, S_GET_NAME (ptr)); 81938889Sjdp } 82038889Sjdp else 82138889Sjdp { 82238889Sjdp fprintf (list_file, "%33s:%s %s\n", 82338889Sjdp segment_name (S_GET_SEGMENT (ptr)), 82438889Sjdp buf, S_GET_NAME (ptr)); 82538889Sjdp } 82633965Sjdp 82777298Sobrien on_page++; 82833965Sjdp listing_page (0); 82933965Sjdp } 83033965Sjdp } 83133965Sjdp 83233965Sjdp } 83333965Sjdp if (!got_some) 83433965Sjdp { 83533965Sjdp fprintf (list_file, "NO DEFINED SYMBOLS\n"); 83633965Sjdp on_page++; 83733965Sjdp } 83833965Sjdp fprintf (list_file, "\n"); 83933965Sjdp on_page++; 84033965Sjdp listing_page (0); 84133965Sjdp 84233965Sjdp got_some = 0; 84333965Sjdp 84433965Sjdp for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 84533965Sjdp { 84633965Sjdp if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0) 84733965Sjdp { 84838889Sjdp if (S_GET_SEGMENT (ptr) == undefined_section) 84933965Sjdp { 85033965Sjdp if (!got_some) 85133965Sjdp { 85233965Sjdp got_some = 1; 85333965Sjdp fprintf (list_file, "UNDEFINED SYMBOLS\n"); 85433965Sjdp on_page++; 85533965Sjdp listing_page (0); 85633965Sjdp } 85733965Sjdp fprintf (list_file, "%s\n", S_GET_NAME (ptr)); 85833965Sjdp on_page++; 85933965Sjdp listing_page (0); 86033965Sjdp } 86133965Sjdp } 86233965Sjdp } 86333965Sjdp if (!got_some) 86433965Sjdp { 86533965Sjdp fprintf (list_file, "NO UNDEFINED SYMBOLS\n"); 86633965Sjdp on_page++; 86733965Sjdp listing_page (0); 86833965Sjdp } 86933965Sjdp} 87033965Sjdp 87133965Sjdpstatic void 87233965Sjdpprint_source (current_file, list, buffer, width) 87333965Sjdp file_info_type *current_file; 87433965Sjdp list_info_type *list; 87533965Sjdp char *buffer; 87633965Sjdp unsigned int width; 87733965Sjdp{ 87838889Sjdp if (!current_file->at_end) 87933965Sjdp { 88033965Sjdp while (current_file->linenum < list->hll_line 88133965Sjdp && !current_file->at_end) 88233965Sjdp { 88333965Sjdp char *p = buffer_line (current_file, buffer, width); 88438889Sjdp fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum, 88533965Sjdp current_file->filename, p); 88633965Sjdp on_page++; 88733965Sjdp listing_page (list); 88833965Sjdp } 88933965Sjdp } 89033965Sjdp} 89133965Sjdp 89233965Sjdp/* Sometimes the user doesn't want to be bothered by the debugging 89338889Sjdp records inserted by the compiler, see if the line is suspicious. */ 89433965Sjdp 89533965Sjdpstatic int 89638889Sjdpdebugging_pseudo (list, line) 89738889Sjdp list_info_type *list; 89838889Sjdp const char *line; 89933965Sjdp{ 90038889Sjdp static int in_debug; 90138889Sjdp int was_debug; 90238889Sjdp 90338889Sjdp if (list->debugging) 90438889Sjdp { 90538889Sjdp in_debug = 1; 90638889Sjdp return 1; 90738889Sjdp } 90838889Sjdp 90938889Sjdp was_debug = in_debug; 91038889Sjdp in_debug = 0; 91138889Sjdp 91289857Sobrien while (ISSPACE (*line)) 91333965Sjdp line++; 91433965Sjdp 91533965Sjdp if (*line != '.') 91638889Sjdp { 91738889Sjdp#ifdef OBJ_ELF 91838889Sjdp /* The ELF compiler sometimes emits blank lines after switching 91938889Sjdp out of a debugging section. If the next line drops us back 92038889Sjdp into debugging information, then don't print the blank line. 92138889Sjdp This is a hack for a particular compiler behaviour, not a 92238889Sjdp general case. */ 92338889Sjdp if (was_debug 92438889Sjdp && *line == '\0' 92538889Sjdp && list->next != NULL 92638889Sjdp && list->next->debugging) 92738889Sjdp { 92838889Sjdp in_debug = 1; 92938889Sjdp return 1; 93038889Sjdp } 93138889Sjdp#endif 93233965Sjdp 93338889Sjdp return 0; 93438889Sjdp } 93538889Sjdp 93633965Sjdp line++; 93733965Sjdp 93833965Sjdp if (strncmp (line, "def", 3) == 0) 93933965Sjdp return 1; 94033965Sjdp if (strncmp (line, "val", 3) == 0) 94133965Sjdp return 1; 94233965Sjdp if (strncmp (line, "scl", 3) == 0) 94333965Sjdp return 1; 94433965Sjdp if (strncmp (line, "line", 4) == 0) 94533965Sjdp return 1; 94633965Sjdp if (strncmp (line, "endef", 5) == 0) 94733965Sjdp return 1; 94833965Sjdp if (strncmp (line, "ln", 2) == 0) 94933965Sjdp return 1; 95033965Sjdp if (strncmp (line, "type", 4) == 0) 95133965Sjdp return 1; 95233965Sjdp if (strncmp (line, "size", 4) == 0) 95333965Sjdp return 1; 95433965Sjdp if (strncmp (line, "dim", 3) == 0) 95533965Sjdp return 1; 95633965Sjdp if (strncmp (line, "tag", 3) == 0) 95733965Sjdp return 1; 95833965Sjdp 95933965Sjdp if (strncmp (line, "stabs", 5) == 0) 96033965Sjdp return 1; 96133965Sjdp if (strncmp (line, "stabn", 5) == 0) 96233965Sjdp return 1; 96333965Sjdp 96433965Sjdp return 0; 96533965Sjdp} 96633965Sjdp 96733965Sjdpstatic void 96833965Sjdplisting_listing (name) 96960484Sobrien char *name ATTRIBUTE_UNUSED; 97033965Sjdp{ 97133965Sjdp list_info_type *list = head; 97233965Sjdp file_info_type *current_hll_file = (file_info_type *) NULL; 97333965Sjdp char *message; 97433965Sjdp char *buffer; 97533965Sjdp char *p; 97633965Sjdp int show_listing = 1; 97733965Sjdp unsigned int width; 97833965Sjdp 97938889Sjdp buffer = xmalloc (listing_rhs_width); 98038889Sjdp data_buffer = xmalloc (MAX_BYTES); 98133965Sjdp eject = 1; 98233965Sjdp list = head; 98333965Sjdp 98433965Sjdp while (list != (list_info_type *) NULL && 0) 98533965Sjdp { 98633965Sjdp if (list->next) 98733965Sjdp list->frag = list->next->frag; 98833965Sjdp list = list->next; 98933965Sjdp 99033965Sjdp } 99133965Sjdp 99233965Sjdp list = head->next; 99333965Sjdp 99433965Sjdp while (list) 99533965Sjdp { 99660484Sobrien unsigned int list_line; 99760484Sobrien 99838889Sjdp width = listing_rhs_width > paper_width ? paper_width : 99938889Sjdp listing_rhs_width; 100033965Sjdp 100160484Sobrien list_line = list->line; 100233965Sjdp switch (list->edict) 100333965Sjdp { 100433965Sjdp case EDICT_LIST: 100560484Sobrien /* Skip all lines up to the current. */ 100660484Sobrien list_line--; 100733965Sjdp break; 100833965Sjdp case EDICT_NOLIST: 100933965Sjdp show_listing--; 101033965Sjdp break; 101133965Sjdp case EDICT_NOLIST_NEXT: 101277298Sobrien if (show_listing == 0) 101377298Sobrien list_line--; 101433965Sjdp break; 101533965Sjdp case EDICT_EJECT: 101633965Sjdp break; 101733965Sjdp case EDICT_NONE: 101833965Sjdp break; 101933965Sjdp case EDICT_TITLE: 102033965Sjdp title = list->edict_arg; 102133965Sjdp break; 102233965Sjdp case EDICT_SBTTL: 102333965Sjdp subtitle = list->edict_arg; 102433965Sjdp break; 102533965Sjdp default: 102633965Sjdp abort (); 102733965Sjdp } 102833965Sjdp 102960484Sobrien if (show_listing <= 0) 103060484Sobrien { 103160484Sobrien while (list->file->linenum < list_line 103260484Sobrien && !list->file->at_end) 103360484Sobrien p = buffer_line (list->file, buffer, width); 103460484Sobrien } 103560484Sobrien 103677298Sobrien if (list->edict == EDICT_LIST 103777298Sobrien || (list->edict == EDICT_NOLIST_NEXT && show_listing == 0)) 103860484Sobrien { 103960484Sobrien /* Enable listing for the single line that caused the enable. */ 104060484Sobrien list_line++; 104160484Sobrien show_listing++; 104260484Sobrien } 104360484Sobrien 104433965Sjdp if (show_listing > 0) 104533965Sjdp { 104633965Sjdp /* Scan down the list and print all the stuff which can be done 104733965Sjdp with this line (or lines). */ 104833965Sjdp message = 0; 104933965Sjdp 105033965Sjdp if (list->hll_file) 105133965Sjdp { 105233965Sjdp current_hll_file = list->hll_file; 105333965Sjdp } 105433965Sjdp 105538889Sjdp if (current_hll_file && list->hll_line && (listing & LISTING_HLL)) 105633965Sjdp { 105733965Sjdp print_source (current_hll_file, list, buffer, width); 105833965Sjdp } 105933965Sjdp 106038889Sjdp if (list->line_contents) 106133965Sjdp { 106238889Sjdp if (!((listing & LISTING_NODEBUG) 106338889Sjdp && debugging_pseudo (list, list->line_contents))) 106438889Sjdp { 1065104834Sobrien print_lines (list, 106660484Sobrien list->file->linenum == 0 ? list->line : list->file->linenum, 106738889Sjdp list->line_contents, calc_hex (list)); 106838889Sjdp } 106960484Sobrien free (list->line_contents); 107060484Sobrien list->line_contents = NULL; 107138889Sjdp } 107238889Sjdp else 107338889Sjdp { 107460484Sobrien while (list->file->linenum < list_line 107538889Sjdp && !list->file->at_end) 107638889Sjdp { 107738889Sjdp unsigned int address; 107833965Sjdp 107938889Sjdp p = buffer_line (list->file, buffer, width); 108033965Sjdp 108160484Sobrien if (list->file->linenum < list_line) 108277298Sobrien address = ~(unsigned int) 0; 108338889Sjdp else 108438889Sjdp address = calc_hex (list); 108533965Sjdp 108638889Sjdp if (!((listing & LISTING_NODEBUG) 108738889Sjdp && debugging_pseudo (list, p))) 108838889Sjdp print_lines (list, list->file->linenum, p, address); 108938889Sjdp } 109033965Sjdp } 109133965Sjdp 109233965Sjdp if (list->edict == EDICT_EJECT) 109333965Sjdp { 109433965Sjdp eject = 1; 109533965Sjdp } 109633965Sjdp } 109733965Sjdp 109877298Sobrien if (list->edict == EDICT_NOLIST_NEXT && show_listing == 1) 109933965Sjdp --show_listing; 110033965Sjdp 110133965Sjdp list = list->next; 110233965Sjdp } 110338889Sjdp 110433965Sjdp free (buffer); 110538889Sjdp free (data_buffer); 110638889Sjdp data_buffer = NULL; 110733965Sjdp} 110833965Sjdp 110933965Sjdpvoid 111033965Sjdplisting_print (name) 111133965Sjdp char *name; 111233965Sjdp{ 111333965Sjdp int using_stdout; 111477298Sobrien 111533965Sjdp title = ""; 111633965Sjdp subtitle = ""; 111733965Sjdp 111833965Sjdp if (name == NULL) 111933965Sjdp { 112033965Sjdp list_file = stdout; 112133965Sjdp using_stdout = 1; 112233965Sjdp } 112333965Sjdp else 112433965Sjdp { 112589857Sobrien list_file = fopen (name, FOPEN_WT); 112633965Sjdp if (list_file != NULL) 112733965Sjdp using_stdout = 0; 112833965Sjdp else 112933965Sjdp { 113060484Sobrien as_perror (_("can't open list file: %s"), name); 113133965Sjdp list_file = stdout; 113233965Sjdp using_stdout = 1; 113333965Sjdp } 113433965Sjdp } 113533965Sjdp 113633965Sjdp if (listing & LISTING_NOFORM) 113733965Sjdp { 113833965Sjdp paper_height = 0; 113933965Sjdp } 114033965Sjdp 114133965Sjdp if (listing & LISTING_LISTING) 114233965Sjdp { 114333965Sjdp listing_listing (name); 114433965Sjdp } 114533965Sjdp 114633965Sjdp if (listing & LISTING_SYMBOLS) 114733965Sjdp { 114833965Sjdp list_symbol_table (); 114933965Sjdp } 115033965Sjdp 115133965Sjdp if (! using_stdout) 115233965Sjdp { 115333965Sjdp if (fclose (list_file) == EOF) 115460484Sobrien as_perror (_("error closing list file: %s"), name); 115533965Sjdp } 115633965Sjdp 115738889Sjdp if (last_open_file) 115833965Sjdp { 115938889Sjdp fclose (last_open_file); 116033965Sjdp } 116133965Sjdp} 116233965Sjdp 116333965Sjdpvoid 116433965Sjdplisting_file (name) 116533965Sjdp const char *name; 116633965Sjdp{ 116733965Sjdp fn = name; 116833965Sjdp} 116933965Sjdp 117033965Sjdpvoid 117133965Sjdplisting_eject (ignore) 117260484Sobrien int ignore ATTRIBUTE_UNUSED; 117333965Sjdp{ 117433965Sjdp if (listing) 117533965Sjdp listing_tail->edict = EDICT_EJECT; 117633965Sjdp} 117733965Sjdp 117833965Sjdpvoid 117933965Sjdplisting_flags (ignore) 118060484Sobrien int ignore ATTRIBUTE_UNUSED; 118133965Sjdp{ 118233965Sjdp while ((*input_line_pointer++) && (*input_line_pointer != '\n')) 118333965Sjdp input_line_pointer++; 118433965Sjdp 118533965Sjdp} 118633965Sjdp 118733965Sjdp/* Turn listing on or off. An argument of 0 means to turn off 118833965Sjdp listing. An argument of 1 means to turn on listing. An argument 118933965Sjdp of 2 means to turn off listing, but as of the next line; that is, 119033965Sjdp the current line should be listed, but the next line should not. */ 119133965Sjdp 119233965Sjdpvoid 119333965Sjdplisting_list (on) 119433965Sjdp int on; 119533965Sjdp{ 119633965Sjdp if (listing) 119733965Sjdp { 119833965Sjdp switch (on) 119933965Sjdp { 120033965Sjdp case 0: 120133965Sjdp if (listing_tail->edict == EDICT_LIST) 120233965Sjdp listing_tail->edict = EDICT_NONE; 120333965Sjdp else 120433965Sjdp listing_tail->edict = EDICT_NOLIST; 120533965Sjdp break; 120633965Sjdp case 1: 120733965Sjdp if (listing_tail->edict == EDICT_NOLIST 120833965Sjdp || listing_tail->edict == EDICT_NOLIST_NEXT) 120933965Sjdp listing_tail->edict = EDICT_NONE; 121033965Sjdp else 121133965Sjdp listing_tail->edict = EDICT_LIST; 121233965Sjdp break; 121333965Sjdp case 2: 121433965Sjdp listing_tail->edict = EDICT_NOLIST_NEXT; 121533965Sjdp break; 121633965Sjdp default: 121733965Sjdp abort (); 121833965Sjdp } 121933965Sjdp } 122033965Sjdp} 122133965Sjdp 122233965Sjdpvoid 122333965Sjdplisting_psize (width_only) 122433965Sjdp int width_only; 122533965Sjdp{ 122633965Sjdp if (! width_only) 122733965Sjdp { 122833965Sjdp paper_height = get_absolute_expression (); 122933965Sjdp 123033965Sjdp if (paper_height < 0 || paper_height > 1000) 123133965Sjdp { 123233965Sjdp paper_height = 0; 123360484Sobrien as_warn (_("strange paper height, set to no form")); 123433965Sjdp } 123533965Sjdp 123633965Sjdp if (*input_line_pointer != ',') 123733965Sjdp { 123833965Sjdp demand_empty_rest_of_line (); 123933965Sjdp return; 124033965Sjdp } 124133965Sjdp 124233965Sjdp ++input_line_pointer; 124333965Sjdp } 124433965Sjdp 124533965Sjdp paper_width = get_absolute_expression (); 124633965Sjdp 124733965Sjdp demand_empty_rest_of_line (); 124833965Sjdp} 124933965Sjdp 125033965Sjdpvoid 125133965Sjdplisting_nopage (ignore) 125260484Sobrien int ignore ATTRIBUTE_UNUSED; 125333965Sjdp{ 125433965Sjdp paper_height = 0; 125533965Sjdp} 125633965Sjdp 125733965Sjdpvoid 125833965Sjdplisting_title (depth) 125933965Sjdp int depth; 126033965Sjdp{ 126133965Sjdp int quoted; 126233965Sjdp char *start; 126333965Sjdp char *ttl; 126433965Sjdp unsigned int length; 126533965Sjdp 126633965Sjdp SKIP_WHITESPACE (); 126733965Sjdp if (*input_line_pointer != '\"') 126833965Sjdp quoted = 0; 126933965Sjdp else 127033965Sjdp { 127133965Sjdp quoted = 1; 127233965Sjdp ++input_line_pointer; 127333965Sjdp } 127433965Sjdp 127533965Sjdp start = input_line_pointer; 127633965Sjdp 127733965Sjdp while (*input_line_pointer) 127833965Sjdp { 127933965Sjdp if (quoted 128033965Sjdp ? *input_line_pointer == '\"' 128133965Sjdp : is_end_of_line[(unsigned char) *input_line_pointer]) 128233965Sjdp { 128333965Sjdp if (listing) 128433965Sjdp { 128533965Sjdp length = input_line_pointer - start; 128633965Sjdp ttl = xmalloc (length + 1); 128733965Sjdp memcpy (ttl, start, length); 128833965Sjdp ttl[length] = 0; 128933965Sjdp listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; 129033965Sjdp listing_tail->edict_arg = ttl; 129133965Sjdp } 129233965Sjdp if (quoted) 129333965Sjdp input_line_pointer++; 129433965Sjdp demand_empty_rest_of_line (); 129533965Sjdp return; 129633965Sjdp } 129733965Sjdp else if (*input_line_pointer == '\n') 129833965Sjdp { 129989857Sobrien as_bad (_("new line in title")); 130033965Sjdp demand_empty_rest_of_line (); 130133965Sjdp return; 130233965Sjdp } 130333965Sjdp else 130433965Sjdp { 130533965Sjdp input_line_pointer++; 130633965Sjdp } 130733965Sjdp } 130833965Sjdp} 130933965Sjdp 131033965Sjdpvoid 131133965Sjdplisting_source_line (line) 131233965Sjdp unsigned int line; 131333965Sjdp{ 131433965Sjdp if (listing) 131533965Sjdp { 131633965Sjdp new_frag (); 131733965Sjdp listing_tail->hll_line = line; 131833965Sjdp new_frag (); 131933965Sjdp } 132033965Sjdp} 132133965Sjdp 132233965Sjdpvoid 132333965Sjdplisting_source_file (file) 132433965Sjdp const char *file; 132533965Sjdp{ 132633965Sjdp if (listing) 132733965Sjdp listing_tail->hll_file = file_info (file); 132833965Sjdp} 132933965Sjdp 133033965Sjdp#else 133133965Sjdp 133277298Sobrien/* Dummy functions for when compiled without listing enabled. */ 133333965Sjdp 133433965Sjdpvoid 133533965Sjdplisting_flags (ignore) 133633965Sjdp int ignore; 133733965Sjdp{ 133833965Sjdp s_ignore (0); 133933965Sjdp} 134033965Sjdp 134177298Sobrienvoid 134233965Sjdplisting_list (on) 134333965Sjdp int on; 134433965Sjdp{ 134533965Sjdp s_ignore (0); 134633965Sjdp} 134733965Sjdp 134877298Sobrienvoid 134933965Sjdplisting_eject (ignore) 135033965Sjdp int ignore; 135133965Sjdp{ 135233965Sjdp s_ignore (0); 135333965Sjdp} 135433965Sjdp 135577298Sobrienvoid 135633965Sjdplisting_psize (ignore) 135733965Sjdp int ignore; 135833965Sjdp{ 135933965Sjdp s_ignore (0); 136033965Sjdp} 136133965Sjdp 136233965Sjdpvoid 136333965Sjdplisting_nopage (ignore) 136433965Sjdp int ignore; 136533965Sjdp{ 136633965Sjdp s_ignore (0); 136733965Sjdp} 136833965Sjdp 136977298Sobrienvoid 137033965Sjdplisting_title (depth) 137133965Sjdp int depth; 137233965Sjdp{ 137333965Sjdp s_ignore (0); 137433965Sjdp} 137533965Sjdp 137633965Sjdpvoid 137733965Sjdplisting_file (name) 137833965Sjdp const char *name; 137933965Sjdp{ 138033965Sjdp 138133965Sjdp} 138233965Sjdp 138377298Sobrienvoid 138433965Sjdplisting_newline (name) 138533965Sjdp char *name; 138633965Sjdp{ 138733965Sjdp 138833965Sjdp} 138933965Sjdp 139077298Sobrienvoid 139133965Sjdplisting_source_line (n) 139233965Sjdp unsigned int n; 139333965Sjdp{ 139433965Sjdp 139533965Sjdp} 139677298Sobrien 139777298Sobrienvoid 139833965Sjdplisting_source_file (n) 139933965Sjdp const char *n; 140033965Sjdp{ 140133965Sjdp 140233965Sjdp} 140333965Sjdp 140433965Sjdp#endif 1405