listing.c revision 38889
133965Sjdp/* listing.c - mainting assembly listings 238889Sjdp Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 338889Sjdp Free Software Foundation, Inc. 433965Sjdp 533965SjdpThis file is part of GAS, the GNU Assembler. 633965Sjdp 733965SjdpGAS is free software; you can redistribute it and/or modify 833965Sjdpit under the terms of the GNU General Public License as published by 933965Sjdpthe Free Software Foundation; either version 2, or (at your option) 1033965Sjdpany later version. 1133965Sjdp 1233965SjdpGAS is distributed in the hope that it will be useful, 1333965Sjdpbut WITHOUT ANY WARRANTY; without even the implied warranty of 1433965SjdpMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965SjdpGNU General Public License for more details. 1633965Sjdp 1733965SjdpYou should have received a copy of the GNU General Public License 1833965Sjdpalong with GAS; see the file COPYING. If not, write to the Free 1933965SjdpSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2033965Sjdp02111-1307, USA. */ 2133965Sjdp 2233965Sjdp/* 2333965Sjdp Contributed by Steve Chamberlain 2433965Sjdp sac@cygnus.com 2533965Sjdp 2633965Sjdp 2733965Sjdp A listing page looks like: 2833965Sjdp 2933965Sjdp LISTING_HEADER sourcefilename pagenumber 3033965Sjdp TITLE LINE 3133965Sjdp SUBTITLE LINE 3233965Sjdp linenumber address data source 3333965Sjdp linenumber address data source 3433965Sjdp linenumber address data source 3533965Sjdp linenumber address data source 3633965Sjdp 3733965Sjdp If not overridden, the listing commands are: 3833965Sjdp 3933965Sjdp .title "stuff" 4033965Sjdp Put "stuff" onto the title line 4133965Sjdp .sbttl "stuff" 4233965Sjdp Put stuff onto the subtitle line 4333965Sjdp 4433965Sjdp If these commands come within 10 lines of the top of the page, they 4533965Sjdp will affect the page they are on, as well as any subsequent page 4633965Sjdp 4733965Sjdp .eject 4833965Sjdp Thow a page 4933965Sjdp .list 5033965Sjdp Increment the enable listing counter 5133965Sjdp .nolist 5233965Sjdp Decrement the enable listing counter 5333965Sjdp 5433965Sjdp .psize Y[,X] 5533965Sjdp Set the paper size to X wide and Y high. Setting a psize Y of 5633965Sjdp zero will suppress form feeds except where demanded by .eject 5733965Sjdp 5833965Sjdp If the counter goes below zero, listing is suppressed. 5933965Sjdp 6033965Sjdp 6133965Sjdp Listings are a maintained by read calling various listing_<foo> 6233965Sjdp functions. What happens most is that the macro NO_LISTING is not 6333965Sjdp defined (from the Makefile), then the macro LISTING_NEWLINE expands 6433965Sjdp into a call to listing_newline. The call is done from read.c, every 6533965Sjdp time it sees a newline, and -l is on the command line. 6633965Sjdp 6733965Sjdp The function listing_newline remembers the frag associated with the 6833965Sjdp newline, and creates a new frag - note that this is wasteful, but not 6933965Sjdp a big deal, since listing slows things down a lot anyway. The 7033965Sjdp function also rememebers when the filename changes. 7133965Sjdp 7233965Sjdp When all the input has finished, and gas has had a chance to settle 7333965Sjdp down, the listing is output. This is done by running down the list of 7433965Sjdp frag/source file records, and opening the files as needed and printing 7533965Sjdp out the bytes and chars associated with them. 7633965Sjdp 7733965Sjdp The only things which the architecture can change about the listing 7833965Sjdp are defined in these macros: 7933965Sjdp 8033965Sjdp LISTING_HEADER The name of the architecture 8133965Sjdp LISTING_WORD_SIZE The make of the number of bytes in a word, this determines 8233965Sjdp the clumping of the output data. eg a value of 8333965Sjdp 2 makes words look like 1234 5678, whilst 1 8433965Sjdp would make the same value look like 12 34 56 8533965Sjdp 78 8633965Sjdp LISTING_LHS_WIDTH Number of words of above size for the lhs 8733965Sjdp 8833965Sjdp LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs 8933965Sjdp for the second line 9033965Sjdp 9133965Sjdp LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation 9233965Sjdp LISTING_RHS_WIDTH Number of chars from the input file to print 9333965Sjdp on a line 9433965Sjdp*/ 9533965Sjdp 9633965Sjdp#include <ctype.h> 9733965Sjdp 9833965Sjdp#include "as.h" 9933965Sjdp#include <obstack.h> 10033965Sjdp#include "input-file.h" 10133965Sjdp#include "subsegs.h" 10233965Sjdp 10333965Sjdp#ifndef NO_LISTING 10438889Sjdp 10533965Sjdp#ifndef LISTING_HEADER 10633965Sjdp#define LISTING_HEADER "GAS LISTING" 10733965Sjdp#endif 10833965Sjdp#ifndef LISTING_WORD_SIZE 10933965Sjdp#define LISTING_WORD_SIZE 4 11033965Sjdp#endif 11133965Sjdp#ifndef LISTING_LHS_WIDTH 11233965Sjdp#define LISTING_LHS_WIDTH 1 11333965Sjdp#endif 11433965Sjdp#ifndef LISTING_LHS_WIDTH_SECOND 11533965Sjdp#define LISTING_LHS_WIDTH_SECOND 1 11633965Sjdp#endif 11733965Sjdp#ifndef LISTING_RHS_WIDTH 11833965Sjdp#define LISTING_RHS_WIDTH 100 11933965Sjdp#endif 12033965Sjdp#ifndef LISTING_LHS_CONT_LINES 12133965Sjdp#define LISTING_LHS_CONT_LINES 4 12233965Sjdp#endif 12333965Sjdp 12433965Sjdp/* This structure remembers which .s were used */ 12533965Sjdptypedef struct file_info_struct 12633965Sjdp{ 12738889Sjdp struct file_info_struct *next; 12833965Sjdp char *filename; 12938889Sjdp long pos; 13038889Sjdp unsigned int linenum; 13133965Sjdp int at_end; 13233965Sjdp} 13333965Sjdpfile_info_type; 13433965Sjdp 13533965Sjdp 13633965Sjdp/* this structure rememebrs which line from which file goes into which 13733965Sjdp frag */ 13838889Sjdpstruct list_info_struct 13933965Sjdp{ 14033965Sjdp /* Frag which this line of source is nearest to */ 14133965Sjdp fragS *frag; 14238889Sjdp 14333965Sjdp /* The actual line in the source file */ 14433965Sjdp unsigned int line; 14533965Sjdp /* Pointer to the file info struct for the file which this line 14633965Sjdp belongs to */ 14733965Sjdp file_info_type *file; 14833965Sjdp 14938889Sjdp /* The expanded text of any macro that may have been executing. */ 15038889Sjdp char *line_contents; 15138889Sjdp 15233965Sjdp /* Next in list */ 15333965Sjdp struct list_info_struct *next; 15433965Sjdp 15533965Sjdp /* Pointer to the file info struct for the high level language 15633965Sjdp source line that belongs here */ 15733965Sjdp file_info_type *hll_file; 15833965Sjdp /* High level language source line */ 15938889Sjdp unsigned int hll_line; 16033965Sjdp 16133965Sjdp /* Pointer to any error message associated with this line */ 16233965Sjdp char *message; 16333965Sjdp 16433965Sjdp enum 16533965Sjdp { 16633965Sjdp EDICT_NONE, 16733965Sjdp EDICT_SBTTL, 16833965Sjdp EDICT_TITLE, 16933965Sjdp EDICT_NOLIST, 17033965Sjdp EDICT_LIST, 17133965Sjdp EDICT_NOLIST_NEXT, 17233965Sjdp EDICT_EJECT 17333965Sjdp } edict; 17433965Sjdp char *edict_arg; 17533965Sjdp 17638889Sjdp /* Nonzero if this line is to be omitted because it contains 17738889Sjdp debugging information. This can become a flags field if we come 17838889Sjdp up with more information to store here. */ 17938889Sjdp int debugging; 18038889Sjdp}; 18133965Sjdp 18238889Sjdptypedef struct list_info_struct list_info_type; 18333965Sjdp 18433965Sjdpstatic struct list_info_struct *head; 18533965Sjdpstruct list_info_struct *listing_tail; 18633965Sjdpextern int listing; 18733965Sjdp 18833965Sjdpstatic int paper_width = 200; 18933965Sjdpstatic int paper_height = 60; 19033965Sjdp 19133965Sjdp/* File to output listings to. */ 19233965Sjdpstatic FILE *list_file; 19333965Sjdp 19438889Sjdp/* This static array is used to keep the text of data to be printed 19538889Sjdp before the start of the line. */ 19633965Sjdp 19738889Sjdp#define MAX_BYTES \ 19838889Sjdp (((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width \ 19938889Sjdp + ((((LISTING_WORD_SIZE * 2) + 1) * listing_lhs_width_second) \ 20038889Sjdp * listing_lhs_cont_lines) \ 20138889Sjdp + 20) 20233965Sjdp 20338889Sjdpstatic char *data_buffer; 20433965Sjdp 20533965Sjdp/* Prototypes. */ 20633965Sjdpstatic void listing_message PARAMS ((const char *name, const char *message)); 20733965Sjdpstatic file_info_type *file_info PARAMS ((const char *file_name)); 20833965Sjdpstatic void new_frag PARAMS ((void)); 20933965Sjdpstatic char *buffer_line PARAMS ((file_info_type *file, 21033965Sjdp char *line, unsigned int size)); 21133965Sjdpstatic void listing_page PARAMS ((list_info_type *list)); 21233965Sjdpstatic unsigned int calc_hex PARAMS ((list_info_type *list)); 21333965Sjdpstatic void print_lines PARAMS ((list_info_type *, unsigned int, 21433965Sjdp char *, unsigned int)); 21533965Sjdpstatic void list_symbol_table PARAMS ((void)); 21633965Sjdpstatic void print_source PARAMS ((file_info_type *current_file, 21733965Sjdp list_info_type *list, 21833965Sjdp char *buffer, 21933965Sjdp unsigned int width)); 22038889Sjdpstatic int debugging_pseudo PARAMS ((list_info_type *, const char *)); 22133965Sjdpstatic void listing_listing PARAMS ((char *name)); 22233965Sjdp 22333965Sjdp 22433965Sjdpstatic void 22533965Sjdplisting_message (name, message) 22633965Sjdp const char *name; 22733965Sjdp const char *message; 22833965Sjdp{ 22933965Sjdp unsigned int l = strlen (name) + strlen (message) + 1; 23033965Sjdp char *n = (char *) xmalloc (l); 23133965Sjdp strcpy (n, name); 23233965Sjdp strcat (n, message); 23333965Sjdp if (listing_tail != (list_info_type *) NULL) 23433965Sjdp { 23533965Sjdp listing_tail->message = n; 23633965Sjdp } 23733965Sjdp} 23833965Sjdp 23933965Sjdpvoid 24033965Sjdplisting_warning (message) 24133965Sjdp const char *message; 24233965Sjdp{ 24333965Sjdp listing_message ("Warning:", message); 24433965Sjdp} 24533965Sjdp 24633965Sjdpvoid 24733965Sjdplisting_error (message) 24833965Sjdp const char *message; 24933965Sjdp{ 25033965Sjdp listing_message ("Error:", message); 25133965Sjdp} 25233965Sjdp 25333965Sjdp 25438889Sjdpint listing_lhs_width = LISTING_LHS_WIDTH; 25538889Sjdpint listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND; 25638889Sjdpint listing_lhs_cont_lines = LISTING_LHS_CONT_LINES; 25738889Sjdpint listing_rhs_width = LISTING_RHS_WIDTH; 25833965Sjdp 25933965Sjdp 26033965Sjdpstatic file_info_type *file_info_head; 26138889Sjdpstatic file_info_type *last_open_file_info; 26238889Sjdpstatic FILE *last_open_file; 26333965Sjdp 26433965Sjdpstatic file_info_type * 26533965Sjdpfile_info (file_name) 26633965Sjdp const char *file_name; 26733965Sjdp{ 26833965Sjdp /* Find an entry with this file name */ 26933965Sjdp file_info_type *p = file_info_head; 27033965Sjdp 27133965Sjdp while (p != (file_info_type *) NULL) 27233965Sjdp { 27333965Sjdp if (strcmp (p->filename, file_name) == 0) 27433965Sjdp return p; 27533965Sjdp p = p->next; 27633965Sjdp } 27733965Sjdp 27833965Sjdp /* Make new entry */ 27933965Sjdp 28033965Sjdp p = (file_info_type *) xmalloc (sizeof (file_info_type)); 28133965Sjdp p->next = file_info_head; 28233965Sjdp file_info_head = p; 28333965Sjdp p->filename = xmalloc ((unsigned long) strlen (file_name) + 1); 28433965Sjdp strcpy (p->filename, file_name); 28538889Sjdp p->pos = 0; 28633965Sjdp p->linenum = 0; 28733965Sjdp p->at_end = 0; 28833965Sjdp 28933965Sjdp return p; 29033965Sjdp} 29133965Sjdp 29233965Sjdp 29333965Sjdpstatic void 29433965Sjdpnew_frag () 29533965Sjdp{ 29633965Sjdp 29733965Sjdp frag_wane (frag_now); 29833965Sjdp frag_new (0); 29933965Sjdp 30033965Sjdp} 30133965Sjdp 30233965Sjdpvoid 30333965Sjdplisting_newline (ps) 30433965Sjdp char *ps; 30533965Sjdp{ 30633965Sjdp char *file; 30733965Sjdp unsigned int line; 30833965Sjdp static unsigned int last_line = 0xffff; 30933965Sjdp static char *last_file = NULL; 31038889Sjdp list_info_type *new = NULL; 31133965Sjdp 31233965Sjdp if (listing == 0) 31333965Sjdp return; 31433965Sjdp 31533965Sjdp if (now_seg == absolute_section) 31633965Sjdp return; 31733965Sjdp 31838889Sjdp#ifdef OBJ_ELF 31938889Sjdp /* In ELF, anything in a section beginning with .debug or .line is 32038889Sjdp considered to be debugging information. This includes the 32138889Sjdp statement which switches us into the debugging section, which we 32238889Sjdp can only set after we are already in the debugging section. */ 32338889Sjdp if ((listing & LISTING_NODEBUG) != 0 32438889Sjdp && listing_tail != NULL 32538889Sjdp && ! listing_tail->debugging) 32638889Sjdp { 32738889Sjdp const char *segname; 32838889Sjdp 32938889Sjdp segname = segment_name (now_seg); 33038889Sjdp if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 33138889Sjdp || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 33238889Sjdp listing_tail->debugging = 1; 33338889Sjdp } 33438889Sjdp#endif 33538889Sjdp 33633965Sjdp as_where (&file, &line); 33738889Sjdp if (ps == NULL) 33833965Sjdp { 33938889Sjdp if (line == last_line && !(last_file && file && strcmp(file, last_file))) 34038889Sjdp return; 34133965Sjdp 34233965Sjdp new = (list_info_type *) xmalloc (sizeof (list_info_type)); 34338889Sjdp new->line_contents = NULL; 34438889Sjdp } 34538889Sjdp else 34638889Sjdp { 34738889Sjdp new = (list_info_type *) xmalloc (sizeof (list_info_type)); 34838889Sjdp new->line_contents = ps; 34938889Sjdp } 35033965Sjdp 35138889Sjdp last_line = line; 35238889Sjdp last_file = file; 35338889Sjdp new_frag (); 35438889Sjdp 35538889Sjdp if (listing_tail) 35638889Sjdp { 35738889Sjdp listing_tail->next = new; 35833965Sjdp } 35938889Sjdp else 36038889Sjdp { 36138889Sjdp head = new; 36238889Sjdp } 36338889Sjdp listing_tail = new; 36438889Sjdp 36538889Sjdp new->frag = frag_now; 36638889Sjdp new->line = line; 36738889Sjdp new->file = file_info (file); 36838889Sjdp new->next = (list_info_type *) NULL; 36938889Sjdp new->message = (char *) NULL; 37038889Sjdp new->edict = EDICT_NONE; 37138889Sjdp new->hll_file = (file_info_type *) NULL; 37238889Sjdp new->hll_line = 0; 37338889Sjdp new->debugging = 0; 37438889Sjdp new_frag (); 37538889Sjdp 37638889Sjdp#ifdef OBJ_ELF 37738889Sjdp /* In ELF, anything in a section beginning with .debug or .line is 37838889Sjdp considered to be debugging information. */ 37938889Sjdp if ((listing & LISTING_NODEBUG) != 0) 38038889Sjdp { 38138889Sjdp const char *segname; 38238889Sjdp 38338889Sjdp segname = segment_name (now_seg); 38438889Sjdp if (strncmp (segname, ".debug", sizeof ".debug" - 1) == 0 38538889Sjdp || strncmp (segname, ".line", sizeof ".line" - 1) == 0) 38638889Sjdp new->debugging = 1; 38738889Sjdp } 38838889Sjdp#endif 38933965Sjdp} 39033965Sjdp 39133965Sjdp/* Attach all current frags to the previous line instead of the 39233965Sjdp current line. This is called by the MIPS backend when it discovers 39333965Sjdp that it needs to add some NOP instructions; the added NOP 39433965Sjdp instructions should go with the instruction that has the delay, not 39533965Sjdp with the new instruction. */ 39633965Sjdp 39733965Sjdpvoid 39833965Sjdplisting_prev_line () 39933965Sjdp{ 40033965Sjdp list_info_type *l; 40133965Sjdp fragS *f; 40233965Sjdp 40333965Sjdp if (head == (list_info_type *) NULL 40433965Sjdp || head == listing_tail) 40533965Sjdp return; 40633965Sjdp 40733965Sjdp new_frag (); 40833965Sjdp 40933965Sjdp for (l = head; l->next != listing_tail; l = l->next) 41033965Sjdp ; 41133965Sjdp 41233965Sjdp for (f = frchain_now->frch_root; f != (fragS *) NULL; f = f->fr_next) 41333965Sjdp if (f->line == listing_tail) 41433965Sjdp f->line = l; 41533965Sjdp 41633965Sjdp listing_tail->frag = frag_now; 41733965Sjdp new_frag (); 41833965Sjdp} 41933965Sjdp 42033965Sjdp/* 42133965Sjdp This function returns the next source line from the file supplied, 42233965Sjdp truncated to size. It appends a fake line to the end of each input 42333965Sjdp file to make 42433965Sjdp*/ 42533965Sjdp 42633965Sjdpstatic char * 42733965Sjdpbuffer_line (file, line, size) 42833965Sjdp file_info_type * file; 42933965Sjdp char *line; 43033965Sjdp unsigned int size; 43133965Sjdp{ 43233965Sjdp unsigned int count = 0; 43333965Sjdp int c; 43433965Sjdp 43533965Sjdp char *p = line; 43633965Sjdp 43733965Sjdp /* If we couldn't open the file, return an empty line */ 43838889Sjdp if (file->at_end) 43938889Sjdp return ""; 44038889Sjdp 44138889Sjdp /* Check the cache and see if we last used this file. */ 44238889Sjdp if (!last_open_file_info || file != last_open_file_info) 44333965Sjdp { 44438889Sjdp if (last_open_file) 44538889Sjdp { 44638889Sjdp last_open_file_info->pos = ftell (last_open_file); 44738889Sjdp fclose (last_open_file); 44838889Sjdp } 44938889Sjdp 45038889Sjdp last_open_file_info = file; 45138889Sjdp last_open_file = fopen (file->filename, "r"); 45238889Sjdp if (last_open_file == NULL) 45338889Sjdp { 45438889Sjdp file->at_end = 1; 45538889Sjdp return ""; 45638889Sjdp } 45738889Sjdp 45838889Sjdp /* Seek to where we were last time this file was open. */ 45938889Sjdp if (file->pos) 46038889Sjdp fseek(last_open_file, file->pos, SEEK_SET); 46133965Sjdp } 46233965Sjdp 46338889Sjdp c = fgetc (last_open_file); 46433965Sjdp 46533965Sjdp size -= 1; /* leave room for null */ 46633965Sjdp 46733965Sjdp while (c != EOF && c != '\n') 46833965Sjdp { 46933965Sjdp if (count < size) 47033965Sjdp *p++ = c; 47133965Sjdp count++; 47233965Sjdp 47338889Sjdp c = fgetc (last_open_file); 47433965Sjdp 47533965Sjdp } 47633965Sjdp if (c == EOF) 47733965Sjdp { 47833965Sjdp file->at_end = 1; 47933965Sjdp *p++ = '.'; 48033965Sjdp *p++ = '.'; 48133965Sjdp *p++ = '.'; 48233965Sjdp } 48333965Sjdp file->linenum++; 48433965Sjdp *p++ = 0; 48533965Sjdp return line; 48633965Sjdp} 48733965Sjdp 48833965Sjdp 48933965Sjdpstatic const char *fn; 49033965Sjdp 49133965Sjdpstatic unsigned int eject; /* Eject pending */ 49233965Sjdpstatic unsigned int page; /* Current page number */ 49333965Sjdpstatic char *title; /* current title */ 49433965Sjdpstatic char *subtitle; /* current subtitle */ 49533965Sjdpstatic unsigned int on_page; /* number of lines printed on current page */ 49633965Sjdp 49733965Sjdp 49833965Sjdpstatic void 49933965Sjdplisting_page (list) 50033965Sjdp list_info_type *list; 50133965Sjdp{ 50233965Sjdp /* Grope around, see if we can see a title or subtitle edict coming up 50333965Sjdp soon (we look down 10 lines of the page and see if it's there)*/ 50438889Sjdp if ((eject || (on_page >= (unsigned int) paper_height)) && paper_height != 0) 50533965Sjdp { 50633965Sjdp unsigned int c = 10; 50733965Sjdp int had_title = 0; 50833965Sjdp int had_subtitle = 0; 50933965Sjdp 51033965Sjdp page++; 51133965Sjdp 51233965Sjdp while (c != 0 && list) 51333965Sjdp { 51433965Sjdp if (list->edict == EDICT_SBTTL && !had_subtitle) 51533965Sjdp { 51633965Sjdp had_subtitle = 1; 51733965Sjdp subtitle = list->edict_arg; 51833965Sjdp } 51933965Sjdp if (list->edict == EDICT_TITLE && !had_title) 52033965Sjdp { 52133965Sjdp had_title = 1; 52233965Sjdp title = list->edict_arg; 52333965Sjdp } 52433965Sjdp list = list->next; 52533965Sjdp c--; 52633965Sjdp } 52733965Sjdp 52833965Sjdp 52933965Sjdp if (page > 1) 53033965Sjdp { 53133965Sjdp fprintf (list_file, "\f"); 53233965Sjdp } 53333965Sjdp 53433965Sjdp fprintf (list_file, "%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page); 53533965Sjdp fprintf (list_file, "%s\n", title); 53633965Sjdp fprintf (list_file, "%s\n", subtitle); 53733965Sjdp on_page = 3; 53833965Sjdp eject = 0; 53933965Sjdp } 54033965Sjdp} 54133965Sjdp 54233965Sjdp 54333965Sjdpstatic unsigned int 54433965Sjdpcalc_hex (list) 54533965Sjdp list_info_type * list; 54633965Sjdp{ 54738889Sjdp int data_buffer_size; 54833965Sjdp list_info_type *first = list; 54938889Sjdp unsigned int address = ~ (unsigned int) 0; 55033965Sjdp fragS *frag; 55133965Sjdp fragS *frag_ptr; 55233965Sjdp unsigned int byte_in_frag; 55333965Sjdp 55433965Sjdp /* Find first frag which says it belongs to this line */ 55533965Sjdp frag = list->frag; 55633965Sjdp while (frag && frag->line != list) 55733965Sjdp frag = frag->fr_next; 55833965Sjdp 55933965Sjdp frag_ptr = frag; 56033965Sjdp 56133965Sjdp data_buffer_size = 0; 56233965Sjdp 56333965Sjdp /* Dump all the frags which belong to this line */ 56433965Sjdp while (frag_ptr != (fragS *) NULL && frag_ptr->line == first) 56533965Sjdp { 56633965Sjdp /* Print as many bytes from the fixed part as is sensible */ 56733965Sjdp byte_in_frag = 0; 56838889Sjdp while ((offsetT) byte_in_frag < frag_ptr->fr_fix 56938889Sjdp && data_buffer_size < MAX_BYTES - 3) 57033965Sjdp { 57138889Sjdp if (address == ~ (unsigned int) 0) 57233965Sjdp { 57333965Sjdp address = frag_ptr->fr_address; 57433965Sjdp } 57533965Sjdp 57633965Sjdp sprintf (data_buffer + data_buffer_size, 57733965Sjdp "%02X", 57833965Sjdp (frag_ptr->fr_literal[byte_in_frag]) & 0xff); 57933965Sjdp data_buffer_size += 2; 58033965Sjdp byte_in_frag++; 58133965Sjdp } 58233965Sjdp { 58333965Sjdp unsigned int var_rep_max = byte_in_frag; 58433965Sjdp unsigned int var_rep_idx = byte_in_frag; 58533965Sjdp 58633965Sjdp /* Print as many bytes from the variable part as is sensible */ 58738889Sjdp while (((offsetT) byte_in_frag 58833965Sjdp < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset) 58938889Sjdp && data_buffer_size < MAX_BYTES - 3) 59033965Sjdp { 59138889Sjdp if (address == ~ (unsigned int) 0) 59233965Sjdp { 59333965Sjdp address = frag_ptr->fr_address; 59433965Sjdp } 59533965Sjdp sprintf (data_buffer + data_buffer_size, 59633965Sjdp "%02X", 59733965Sjdp (frag_ptr->fr_literal[var_rep_idx]) & 0xff); 59833965Sjdp#if 0 59933965Sjdp data_buffer[data_buffer_size++] = '*'; 60033965Sjdp data_buffer[data_buffer_size++] = '*'; 60133965Sjdp#endif 60233965Sjdp data_buffer_size += 2; 60333965Sjdp 60433965Sjdp var_rep_idx++; 60533965Sjdp byte_in_frag++; 60633965Sjdp 60738889Sjdp if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var) 60833965Sjdp var_rep_idx = var_rep_max; 60933965Sjdp } 61033965Sjdp } 61133965Sjdp 61233965Sjdp frag_ptr = frag_ptr->fr_next; 61333965Sjdp } 61438889Sjdp data_buffer[data_buffer_size] = '\0'; 61533965Sjdp return address; 61633965Sjdp} 61733965Sjdp 61833965Sjdp 61933965Sjdp 62033965Sjdp 62133965Sjdp 62233965Sjdp 62333965Sjdpstatic void 62433965Sjdpprint_lines (list, lineno, string, address) 62533965Sjdp list_info_type *list; 62633965Sjdp unsigned int lineno; 62733965Sjdp char *string; 62833965Sjdp unsigned int address; 62933965Sjdp{ 63033965Sjdp unsigned int idx; 63133965Sjdp unsigned int nchars; 63233965Sjdp unsigned int lines; 63333965Sjdp unsigned int byte_in_word = 0; 63433965Sjdp char *src = data_buffer; 63533965Sjdp 63633965Sjdp /* Print the stuff on the first line */ 63733965Sjdp listing_page (list); 63838889Sjdp nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width; 63933965Sjdp /* Print the hex for the first line */ 64038889Sjdp if (address == ~ (unsigned int) 0) 64133965Sjdp { 64233965Sjdp fprintf (list_file, "% 4d ", lineno); 64333965Sjdp for (idx = 0; idx < nchars; idx++) 64433965Sjdp fprintf (list_file, " "); 64533965Sjdp 64633965Sjdp fprintf (list_file, "\t%s\n", string ? string : ""); 64733965Sjdp on_page++; 64833965Sjdp listing_page (0); 64933965Sjdp 65033965Sjdp } 65133965Sjdp else 65233965Sjdp { 65333965Sjdp if (had_errors ()) 65433965Sjdp { 65533965Sjdp fprintf (list_file, "% 4d ???? ", lineno); 65633965Sjdp } 65733965Sjdp else 65833965Sjdp { 65933965Sjdp fprintf (list_file, "% 4d %04x ", lineno, address); 66033965Sjdp } 66133965Sjdp 66233965Sjdp /* And the data to go along with it */ 66333965Sjdp idx = 0; 66433965Sjdp 66533965Sjdp while (*src && idx < nchars) 66633965Sjdp { 66733965Sjdp fprintf (list_file, "%c%c", src[0], src[1]); 66833965Sjdp src += 2; 66933965Sjdp byte_in_word++; 67033965Sjdp if (byte_in_word == LISTING_WORD_SIZE) 67133965Sjdp { 67233965Sjdp fprintf (list_file, " "); 67333965Sjdp idx++; 67433965Sjdp byte_in_word = 0; 67533965Sjdp } 67633965Sjdp idx += 2; 67733965Sjdp } 67833965Sjdp 67933965Sjdp for (; idx < nchars; idx++) 68033965Sjdp fprintf (list_file, " "); 68133965Sjdp 68233965Sjdp fprintf (list_file, "\t%s\n", string ? string : ""); 68333965Sjdp on_page++; 68433965Sjdp listing_page (list); 68533965Sjdp if (list->message) 68633965Sjdp { 68733965Sjdp fprintf (list_file, "**** %s\n", list->message); 68833965Sjdp listing_page (list); 68933965Sjdp on_page++; 69033965Sjdp } 69133965Sjdp 69233965Sjdp for (lines = 0; 69338889Sjdp lines < (unsigned int) listing_lhs_cont_lines && *src; 69433965Sjdp lines++) 69533965Sjdp { 69638889Sjdp nchars = (((LISTING_WORD_SIZE * 2) + 1) 69738889Sjdp * listing_lhs_width_second - 1); 69833965Sjdp idx = 0; 69933965Sjdp /* Print any more lines of data, but more compactly */ 70033965Sjdp fprintf (list_file, "% 4d ", lineno); 70133965Sjdp 70233965Sjdp while (*src && idx < nchars) 70333965Sjdp { 70433965Sjdp fprintf (list_file, "%c%c", src[0], src[1]); 70533965Sjdp src += 2; 70633965Sjdp idx += 2; 70733965Sjdp byte_in_word++; 70833965Sjdp if (byte_in_word == LISTING_WORD_SIZE) 70933965Sjdp { 71033965Sjdp fprintf (list_file, " "); 71133965Sjdp idx++; 71233965Sjdp byte_in_word = 0; 71333965Sjdp } 71433965Sjdp } 71533965Sjdp 71633965Sjdp fprintf (list_file, "\n"); 71733965Sjdp on_page++; 71833965Sjdp listing_page (list); 71933965Sjdp 72033965Sjdp } 72133965Sjdp 72233965Sjdp 72333965Sjdp } 72433965Sjdp} 72533965Sjdp 72633965Sjdp 72733965Sjdpstatic void 72833965Sjdplist_symbol_table () 72933965Sjdp{ 73033965Sjdp extern symbolS *symbol_rootP; 73133965Sjdp int got_some = 0; 73233965Sjdp 73333965Sjdp symbolS *ptr; 73433965Sjdp eject = 1; 73533965Sjdp listing_page (0); 73633965Sjdp 73733965Sjdp for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 73833965Sjdp { 73938889Sjdp if (SEG_NORMAL (S_GET_SEGMENT (ptr)) 74038889Sjdp || S_GET_SEGMENT (ptr) == absolute_section) 74133965Sjdp { 74238889Sjdp#ifdef BFD_ASSEMBLER 74338889Sjdp /* Don't report section symbols. They are not interesting. */ 74438889Sjdp if (ptr->bsym->flags & BSF_SECTION_SYM) 74538889Sjdp continue; 74638889Sjdp#endif 74733965Sjdp if (S_GET_NAME (ptr)) 74833965Sjdp { 74933965Sjdp char buf[30], fmt[8]; 75033965Sjdp valueT val = S_GET_VALUE (ptr); 75133965Sjdp 75233965Sjdp /* @@ Note that this is dependent on the compilation options, 75333965Sjdp not solely on the target characteristics. */ 75433965Sjdp if (sizeof (val) == 4 && sizeof (int) == 4) 75533965Sjdp sprintf (buf, "%08lx", (unsigned long) val); 75633965Sjdp else if (sizeof (val) <= sizeof (unsigned long)) 75733965Sjdp { 75833965Sjdp sprintf (fmt, "%%0%lulx", 75933965Sjdp (unsigned long) (sizeof (val) * 2)); 76033965Sjdp sprintf (buf, fmt, (unsigned long) val); 76133965Sjdp } 76233965Sjdp#if defined (BFD64) 76333965Sjdp else if (sizeof (val) > 4) 76433965Sjdp sprintf_vma (buf, val); 76533965Sjdp#endif 76633965Sjdp else 76733965Sjdp abort (); 76833965Sjdp 76933965Sjdp if (!got_some) 77033965Sjdp { 77133965Sjdp fprintf (list_file, "DEFINED SYMBOLS\n"); 77233965Sjdp on_page++; 77333965Sjdp got_some = 1; 77433965Sjdp } 77533965Sjdp 77638889Sjdp if (ptr->sy_frag && ptr->sy_frag->line) 77738889Sjdp { 77838889Sjdp fprintf (list_file, "%20s:%-5d %s:%s %s\n", 77938889Sjdp ptr->sy_frag->line->file->filename, 78038889Sjdp ptr->sy_frag->line->line, 78138889Sjdp segment_name (S_GET_SEGMENT (ptr)), 78238889Sjdp buf, S_GET_NAME (ptr)); 78338889Sjdp } 78438889Sjdp else 78538889Sjdp { 78638889Sjdp fprintf (list_file, "%33s:%s %s\n", 78738889Sjdp segment_name (S_GET_SEGMENT (ptr)), 78838889Sjdp buf, S_GET_NAME (ptr)); 78938889Sjdp } 79033965Sjdp 79133965Sjdp on_page++; 79233965Sjdp listing_page (0); 79333965Sjdp } 79433965Sjdp } 79533965Sjdp 79633965Sjdp } 79733965Sjdp if (!got_some) 79833965Sjdp { 79933965Sjdp fprintf (list_file, "NO DEFINED SYMBOLS\n"); 80033965Sjdp on_page++; 80133965Sjdp } 80233965Sjdp fprintf (list_file, "\n"); 80333965Sjdp on_page++; 80433965Sjdp listing_page (0); 80533965Sjdp 80633965Sjdp got_some = 0; 80733965Sjdp 80833965Sjdp for (ptr = symbol_rootP; ptr != (symbolS *) NULL; ptr = symbol_next (ptr)) 80933965Sjdp { 81033965Sjdp if (S_GET_NAME (ptr) && strlen (S_GET_NAME (ptr)) != 0) 81133965Sjdp { 81238889Sjdp if (S_GET_SEGMENT (ptr) == undefined_section) 81333965Sjdp { 81433965Sjdp if (!got_some) 81533965Sjdp { 81633965Sjdp got_some = 1; 81733965Sjdp fprintf (list_file, "UNDEFINED SYMBOLS\n"); 81833965Sjdp on_page++; 81933965Sjdp listing_page (0); 82033965Sjdp } 82133965Sjdp fprintf (list_file, "%s\n", S_GET_NAME (ptr)); 82233965Sjdp on_page++; 82333965Sjdp listing_page (0); 82433965Sjdp } 82533965Sjdp } 82633965Sjdp } 82733965Sjdp if (!got_some) 82833965Sjdp { 82933965Sjdp fprintf (list_file, "NO UNDEFINED SYMBOLS\n"); 83033965Sjdp on_page++; 83133965Sjdp listing_page (0); 83233965Sjdp } 83333965Sjdp} 83433965Sjdp 83533965Sjdpstatic void 83633965Sjdpprint_source (current_file, list, buffer, width) 83733965Sjdp file_info_type *current_file; 83833965Sjdp list_info_type *list; 83933965Sjdp char *buffer; 84033965Sjdp unsigned int width; 84133965Sjdp{ 84238889Sjdp if (!current_file->at_end) 84333965Sjdp { 84433965Sjdp while (current_file->linenum < list->hll_line 84533965Sjdp && !current_file->at_end) 84633965Sjdp { 84733965Sjdp char *p = buffer_line (current_file, buffer, width); 84838889Sjdp fprintf (list_file, "%4u:%-13s **** %s\n", current_file->linenum, 84933965Sjdp current_file->filename, p); 85033965Sjdp on_page++; 85133965Sjdp listing_page (list); 85233965Sjdp } 85333965Sjdp } 85433965Sjdp} 85533965Sjdp 85633965Sjdp/* Sometimes the user doesn't want to be bothered by the debugging 85738889Sjdp records inserted by the compiler, see if the line is suspicious. */ 85833965Sjdp 85933965Sjdpstatic int 86038889Sjdpdebugging_pseudo (list, line) 86138889Sjdp list_info_type *list; 86238889Sjdp const char *line; 86333965Sjdp{ 86438889Sjdp static int in_debug; 86538889Sjdp int was_debug; 86638889Sjdp 86738889Sjdp if (list->debugging) 86838889Sjdp { 86938889Sjdp in_debug = 1; 87038889Sjdp return 1; 87138889Sjdp } 87238889Sjdp 87338889Sjdp was_debug = in_debug; 87438889Sjdp in_debug = 0; 87538889Sjdp 87638889Sjdp while (isspace ((unsigned char) *line)) 87733965Sjdp line++; 87833965Sjdp 87933965Sjdp if (*line != '.') 88038889Sjdp { 88138889Sjdp#ifdef OBJ_ELF 88238889Sjdp /* The ELF compiler sometimes emits blank lines after switching 88338889Sjdp out of a debugging section. If the next line drops us back 88438889Sjdp into debugging information, then don't print the blank line. 88538889Sjdp This is a hack for a particular compiler behaviour, not a 88638889Sjdp general case. */ 88738889Sjdp if (was_debug 88838889Sjdp && *line == '\0' 88938889Sjdp && list->next != NULL 89038889Sjdp && list->next->debugging) 89138889Sjdp { 89238889Sjdp in_debug = 1; 89338889Sjdp return 1; 89438889Sjdp } 89538889Sjdp#endif 89633965Sjdp 89738889Sjdp return 0; 89838889Sjdp } 89938889Sjdp 90033965Sjdp line++; 90133965Sjdp 90233965Sjdp if (strncmp (line, "def", 3) == 0) 90333965Sjdp return 1; 90433965Sjdp if (strncmp (line, "val", 3) == 0) 90533965Sjdp return 1; 90633965Sjdp if (strncmp (line, "scl", 3) == 0) 90733965Sjdp return 1; 90833965Sjdp if (strncmp (line, "line", 4) == 0) 90933965Sjdp return 1; 91033965Sjdp if (strncmp (line, "endef", 5) == 0) 91133965Sjdp return 1; 91233965Sjdp if (strncmp (line, "ln", 2) == 0) 91333965Sjdp return 1; 91433965Sjdp if (strncmp (line, "type", 4) == 0) 91533965Sjdp return 1; 91633965Sjdp if (strncmp (line, "size", 4) == 0) 91733965Sjdp return 1; 91833965Sjdp if (strncmp (line, "dim", 3) == 0) 91933965Sjdp return 1; 92033965Sjdp if (strncmp (line, "tag", 3) == 0) 92133965Sjdp return 1; 92233965Sjdp 92333965Sjdp if (strncmp (line, "stabs", 5) == 0) 92433965Sjdp return 1; 92533965Sjdp if (strncmp (line, "stabn", 5) == 0) 92633965Sjdp return 1; 92733965Sjdp 92833965Sjdp return 0; 92933965Sjdp} 93033965Sjdp 93133965Sjdpstatic void 93233965Sjdplisting_listing (name) 93333965Sjdp char *name; 93433965Sjdp{ 93533965Sjdp list_info_type *list = head; 93633965Sjdp file_info_type *current_hll_file = (file_info_type *) NULL; 93733965Sjdp char *message; 93833965Sjdp char *buffer; 93933965Sjdp char *p; 94033965Sjdp int show_listing = 1; 94133965Sjdp unsigned int width; 94233965Sjdp 94338889Sjdp buffer = xmalloc (listing_rhs_width); 94438889Sjdp data_buffer = xmalloc (MAX_BYTES); 94533965Sjdp eject = 1; 94633965Sjdp list = head; 94733965Sjdp 94833965Sjdp while (list != (list_info_type *) NULL && 0) 94933965Sjdp { 95033965Sjdp if (list->next) 95133965Sjdp list->frag = list->next->frag; 95233965Sjdp list = list->next; 95333965Sjdp 95433965Sjdp } 95533965Sjdp 95633965Sjdp list = head->next; 95733965Sjdp 95833965Sjdp 95933965Sjdp while (list) 96033965Sjdp { 96138889Sjdp width = listing_rhs_width > paper_width ? paper_width : 96238889Sjdp listing_rhs_width; 96333965Sjdp 96433965Sjdp switch (list->edict) 96533965Sjdp { 96633965Sjdp case EDICT_LIST: 96733965Sjdp show_listing++; 96833965Sjdp break; 96933965Sjdp case EDICT_NOLIST: 97033965Sjdp show_listing--; 97133965Sjdp break; 97233965Sjdp case EDICT_NOLIST_NEXT: 97333965Sjdp break; 97433965Sjdp case EDICT_EJECT: 97533965Sjdp break; 97633965Sjdp case EDICT_NONE: 97733965Sjdp break; 97833965Sjdp case EDICT_TITLE: 97933965Sjdp title = list->edict_arg; 98033965Sjdp break; 98133965Sjdp case EDICT_SBTTL: 98233965Sjdp subtitle = list->edict_arg; 98333965Sjdp break; 98433965Sjdp default: 98533965Sjdp abort (); 98633965Sjdp } 98733965Sjdp 98833965Sjdp if (show_listing > 0) 98933965Sjdp { 99033965Sjdp /* Scan down the list and print all the stuff which can be done 99133965Sjdp with this line (or lines). */ 99233965Sjdp message = 0; 99333965Sjdp 99433965Sjdp if (list->hll_file) 99533965Sjdp { 99633965Sjdp current_hll_file = list->hll_file; 99733965Sjdp } 99833965Sjdp 99938889Sjdp if (current_hll_file && list->hll_line && (listing & LISTING_HLL)) 100033965Sjdp { 100133965Sjdp print_source (current_hll_file, list, buffer, width); 100233965Sjdp } 100333965Sjdp 100438889Sjdp if (list->line_contents) 100533965Sjdp { 100638889Sjdp if (!((listing & LISTING_NODEBUG) 100738889Sjdp && debugging_pseudo (list, list->line_contents))) 100838889Sjdp { 100938889Sjdp print_lines (list, list->file->linenum, 101038889Sjdp list->line_contents, calc_hex (list)); 101138889Sjdp } 101238889Sjdp } 101338889Sjdp else 101438889Sjdp { 101538889Sjdp while (list->file->linenum < list->line 101638889Sjdp && !list->file->at_end) 101738889Sjdp { 101838889Sjdp unsigned int address; 101933965Sjdp 102038889Sjdp p = buffer_line (list->file, buffer, width); 102133965Sjdp 102238889Sjdp if (list->file->linenum < list->line) 102338889Sjdp address = ~ (unsigned int) 0; 102438889Sjdp else 102538889Sjdp address = calc_hex (list); 102633965Sjdp 102738889Sjdp if (!((listing & LISTING_NODEBUG) 102838889Sjdp && debugging_pseudo (list, p))) 102938889Sjdp print_lines (list, list->file->linenum, p, address); 103038889Sjdp } 103133965Sjdp } 103233965Sjdp 103333965Sjdp if (list->edict == EDICT_EJECT) 103433965Sjdp { 103533965Sjdp eject = 1; 103633965Sjdp } 103733965Sjdp } 103833965Sjdp else 103933965Sjdp { 104038889Sjdp while (list->file->linenum < list->line 104133965Sjdp && !list->file->at_end) 104233965Sjdp p = buffer_line (list->file, buffer, width); 104333965Sjdp } 104433965Sjdp 104533965Sjdp if (list->edict == EDICT_NOLIST_NEXT) 104633965Sjdp --show_listing; 104733965Sjdp 104833965Sjdp list = list->next; 104933965Sjdp } 105038889Sjdp 105133965Sjdp free (buffer); 105238889Sjdp free (data_buffer); 105338889Sjdp data_buffer = NULL; 105433965Sjdp} 105533965Sjdp 105633965Sjdpvoid 105733965Sjdplisting_print (name) 105833965Sjdp char *name; 105933965Sjdp{ 106033965Sjdp int using_stdout; 106133965Sjdp 106233965Sjdp title = ""; 106333965Sjdp subtitle = ""; 106433965Sjdp 106533965Sjdp if (name == NULL) 106633965Sjdp { 106733965Sjdp list_file = stdout; 106833965Sjdp using_stdout = 1; 106933965Sjdp } 107033965Sjdp else 107133965Sjdp { 107233965Sjdp list_file = fopen (name, "w"); 107333965Sjdp if (list_file != NULL) 107433965Sjdp using_stdout = 0; 107533965Sjdp else 107633965Sjdp { 107733965Sjdp as_perror ("can't open list file: %s", name); 107833965Sjdp list_file = stdout; 107933965Sjdp using_stdout = 1; 108033965Sjdp } 108133965Sjdp } 108233965Sjdp 108333965Sjdp if (listing & LISTING_NOFORM) 108433965Sjdp { 108533965Sjdp paper_height = 0; 108633965Sjdp } 108733965Sjdp 108833965Sjdp if (listing & LISTING_LISTING) 108933965Sjdp { 109033965Sjdp listing_listing (name); 109133965Sjdp } 109233965Sjdp 109333965Sjdp if (listing & LISTING_SYMBOLS) 109433965Sjdp { 109533965Sjdp list_symbol_table (); 109633965Sjdp } 109733965Sjdp 109833965Sjdp if (! using_stdout) 109933965Sjdp { 110033965Sjdp if (fclose (list_file) == EOF) 110133965Sjdp as_perror ("error closing list file: %s", name); 110233965Sjdp } 110333965Sjdp 110438889Sjdp if (last_open_file) 110533965Sjdp { 110638889Sjdp fclose (last_open_file); 110733965Sjdp } 110833965Sjdp} 110933965Sjdp 111033965Sjdp 111133965Sjdpvoid 111233965Sjdplisting_file (name) 111333965Sjdp const char *name; 111433965Sjdp{ 111533965Sjdp fn = name; 111633965Sjdp} 111733965Sjdp 111833965Sjdpvoid 111933965Sjdplisting_eject (ignore) 112033965Sjdp int ignore; 112133965Sjdp{ 112233965Sjdp if (listing) 112333965Sjdp listing_tail->edict = EDICT_EJECT; 112433965Sjdp} 112533965Sjdp 112633965Sjdpvoid 112733965Sjdplisting_flags (ignore) 112833965Sjdp int ignore; 112933965Sjdp{ 113033965Sjdp while ((*input_line_pointer++) && (*input_line_pointer != '\n')) 113133965Sjdp input_line_pointer++; 113233965Sjdp 113333965Sjdp} 113433965Sjdp 113533965Sjdp/* Turn listing on or off. An argument of 0 means to turn off 113633965Sjdp listing. An argument of 1 means to turn on listing. An argument 113733965Sjdp of 2 means to turn off listing, but as of the next line; that is, 113833965Sjdp the current line should be listed, but the next line should not. */ 113933965Sjdp 114033965Sjdpvoid 114133965Sjdplisting_list (on) 114233965Sjdp int on; 114333965Sjdp{ 114433965Sjdp if (listing) 114533965Sjdp { 114633965Sjdp switch (on) 114733965Sjdp { 114833965Sjdp case 0: 114933965Sjdp if (listing_tail->edict == EDICT_LIST) 115033965Sjdp listing_tail->edict = EDICT_NONE; 115133965Sjdp else 115233965Sjdp listing_tail->edict = EDICT_NOLIST; 115333965Sjdp break; 115433965Sjdp case 1: 115533965Sjdp if (listing_tail->edict == EDICT_NOLIST 115633965Sjdp || listing_tail->edict == EDICT_NOLIST_NEXT) 115733965Sjdp listing_tail->edict = EDICT_NONE; 115833965Sjdp else 115933965Sjdp listing_tail->edict = EDICT_LIST; 116033965Sjdp break; 116133965Sjdp case 2: 116233965Sjdp listing_tail->edict = EDICT_NOLIST_NEXT; 116333965Sjdp break; 116433965Sjdp default: 116533965Sjdp abort (); 116633965Sjdp } 116733965Sjdp } 116833965Sjdp} 116933965Sjdp 117033965Sjdp 117133965Sjdpvoid 117233965Sjdplisting_psize (width_only) 117333965Sjdp int width_only; 117433965Sjdp{ 117533965Sjdp if (! width_only) 117633965Sjdp { 117733965Sjdp paper_height = get_absolute_expression (); 117833965Sjdp 117933965Sjdp if (paper_height < 0 || paper_height > 1000) 118033965Sjdp { 118133965Sjdp paper_height = 0; 118233965Sjdp as_warn ("strange paper height, set to no form"); 118333965Sjdp } 118433965Sjdp 118533965Sjdp if (*input_line_pointer != ',') 118633965Sjdp { 118733965Sjdp demand_empty_rest_of_line (); 118833965Sjdp return; 118933965Sjdp } 119033965Sjdp 119133965Sjdp ++input_line_pointer; 119233965Sjdp } 119333965Sjdp 119433965Sjdp paper_width = get_absolute_expression (); 119533965Sjdp 119633965Sjdp demand_empty_rest_of_line (); 119733965Sjdp} 119833965Sjdp 119933965Sjdpvoid 120033965Sjdplisting_nopage (ignore) 120133965Sjdp int ignore; 120233965Sjdp{ 120333965Sjdp paper_height = 0; 120433965Sjdp} 120533965Sjdp 120633965Sjdpvoid 120733965Sjdplisting_title (depth) 120833965Sjdp int depth; 120933965Sjdp{ 121033965Sjdp int quoted; 121133965Sjdp char *start; 121233965Sjdp char *ttl; 121333965Sjdp unsigned int length; 121433965Sjdp 121533965Sjdp SKIP_WHITESPACE (); 121633965Sjdp if (*input_line_pointer != '\"') 121733965Sjdp quoted = 0; 121833965Sjdp else 121933965Sjdp { 122033965Sjdp quoted = 1; 122133965Sjdp ++input_line_pointer; 122233965Sjdp } 122333965Sjdp 122433965Sjdp start = input_line_pointer; 122533965Sjdp 122633965Sjdp while (*input_line_pointer) 122733965Sjdp { 122833965Sjdp if (quoted 122933965Sjdp ? *input_line_pointer == '\"' 123033965Sjdp : is_end_of_line[(unsigned char) *input_line_pointer]) 123133965Sjdp { 123233965Sjdp if (listing) 123333965Sjdp { 123433965Sjdp length = input_line_pointer - start; 123533965Sjdp ttl = xmalloc (length + 1); 123633965Sjdp memcpy (ttl, start, length); 123733965Sjdp ttl[length] = 0; 123833965Sjdp listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE; 123933965Sjdp listing_tail->edict_arg = ttl; 124033965Sjdp } 124133965Sjdp if (quoted) 124233965Sjdp input_line_pointer++; 124333965Sjdp demand_empty_rest_of_line (); 124433965Sjdp return; 124533965Sjdp } 124633965Sjdp else if (*input_line_pointer == '\n') 124733965Sjdp { 124833965Sjdp as_bad ("New line in title"); 124933965Sjdp demand_empty_rest_of_line (); 125033965Sjdp return; 125133965Sjdp } 125233965Sjdp else 125333965Sjdp { 125433965Sjdp input_line_pointer++; 125533965Sjdp } 125633965Sjdp } 125733965Sjdp} 125833965Sjdp 125933965Sjdp 126033965Sjdp 126133965Sjdpvoid 126233965Sjdplisting_source_line (line) 126333965Sjdp unsigned int line; 126433965Sjdp{ 126533965Sjdp if (listing) 126633965Sjdp { 126733965Sjdp new_frag (); 126833965Sjdp listing_tail->hll_line = line; 126933965Sjdp new_frag (); 127033965Sjdp } 127133965Sjdp} 127233965Sjdp 127333965Sjdpvoid 127433965Sjdplisting_source_file (file) 127533965Sjdp const char *file; 127633965Sjdp{ 127733965Sjdp if (listing) 127833965Sjdp listing_tail->hll_file = file_info (file); 127933965Sjdp} 128033965Sjdp 128133965Sjdp 128233965Sjdp 128333965Sjdp#else 128433965Sjdp 128533965Sjdp 128633965Sjdp/* Dummy functions for when compiled without listing enabled */ 128733965Sjdp 128833965Sjdpvoid 128933965Sjdplisting_flags (ignore) 129033965Sjdp int ignore; 129133965Sjdp{ 129233965Sjdp s_ignore (0); 129333965Sjdp} 129433965Sjdp 129533965Sjdpvoid 129633965Sjdplisting_list (on) 129733965Sjdp int on; 129833965Sjdp{ 129933965Sjdp s_ignore (0); 130033965Sjdp} 130133965Sjdp 130233965Sjdpvoid 130333965Sjdplisting_eject (ignore) 130433965Sjdp int ignore; 130533965Sjdp{ 130633965Sjdp s_ignore (0); 130733965Sjdp} 130833965Sjdp 130933965Sjdpvoid 131033965Sjdplisting_psize (ignore) 131133965Sjdp int ignore; 131233965Sjdp{ 131333965Sjdp s_ignore (0); 131433965Sjdp} 131533965Sjdp 131633965Sjdpvoid 131733965Sjdplisting_nopage (ignore) 131833965Sjdp int ignore; 131933965Sjdp{ 132033965Sjdp s_ignore (0); 132133965Sjdp} 132233965Sjdp 132333965Sjdpvoid 132433965Sjdplisting_title (depth) 132533965Sjdp int depth; 132633965Sjdp{ 132733965Sjdp s_ignore (0); 132833965Sjdp} 132933965Sjdp 133033965Sjdpvoid 133133965Sjdplisting_file (name) 133233965Sjdp const char *name; 133333965Sjdp{ 133433965Sjdp 133533965Sjdp} 133633965Sjdp 133733965Sjdpvoid 133833965Sjdplisting_newline (name) 133933965Sjdp char *name; 134033965Sjdp{ 134133965Sjdp 134233965Sjdp} 134333965Sjdp 134433965Sjdpvoid 134533965Sjdplisting_source_line (n) 134633965Sjdp unsigned int n; 134733965Sjdp{ 134833965Sjdp 134933965Sjdp} 135033965Sjdpvoid 135133965Sjdplisting_source_file (n) 135233965Sjdp const char *n; 135333965Sjdp{ 135433965Sjdp 135533965Sjdp} 135633965Sjdp 135733965Sjdp#endif 1358