diff options
Diffstat (limited to 'contrib/binutils/gas/listing.c')
-rw-r--r-- | contrib/binutils/gas/listing.c | 360 |
1 files changed, 214 insertions, 146 deletions
diff --git a/contrib/binutils/gas/listing.c b/contrib/binutils/gas/listing.c index 2fa8ae91ddc4..cecf2450bac1 100644 --- a/contrib/binutils/gas/listing.c +++ b/contrib/binutils/gas/listing.c @@ -1,5 +1,5 @@ /* listing.c - mainting assembly listings - Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. @@ -109,10 +109,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define LISTING_WORD_SIZE 4 #endif #ifndef LISTING_LHS_WIDTH -#define LISTING_LHS_WIDTH 1 +#define LISTING_LHS_WIDTH ((LISTING_WORD_SIZE) > 4 ? 1 : 4 / (LISTING_WORD_SIZE)) #endif #ifndef LISTING_LHS_WIDTH_SECOND -#define LISTING_LHS_WIDTH_SECOND 1 +#define LISTING_LHS_WIDTH_SECOND LISTING_LHS_WIDTH #endif #ifndef LISTING_RHS_WIDTH #define LISTING_RHS_WIDTH 100 @@ -124,42 +124,41 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA /* This structure remembers which .s were used */ typedef struct file_info_struct { - struct file_info_struct *next; - char *filename; - long pos; - unsigned int linenum; - int at_end; + struct file_info_struct * next; + char * filename; + long pos; + unsigned int linenum; + int at_end; } file_info_type; - -/* this structure rememebrs which line from which file goes into which +/* This structure rememebrs which line from which file goes into which frag */ struct list_info_struct { /* Frag which this line of source is nearest to */ - fragS *frag; + fragS * frag; /* The actual line in the source file */ unsigned int line; /* Pointer to the file info struct for the file which this line belongs to */ - file_info_type *file; + file_info_type * file; /* The expanded text of any macro that may have been executing. */ - char *line_contents; + char * line_contents; /* Next in list */ - struct list_info_struct *next; + struct list_info_struct * next; /* Pointer to the file info struct for the high level language source line that belongs here */ - file_info_type *hll_file; + file_info_type * hll_file; /* High level language source line */ unsigned int hll_line; /* Pointer to any error message associated with this line */ - char *message; + char * message; enum { @@ -171,7 +170,7 @@ struct list_info_struct EDICT_NOLIST_NEXT, EDICT_EJECT } edict; - char *edict_arg; + char * edict_arg; /* Nonzero if this line is to be omitted because it contains debugging information. This can become a flags field if we come @@ -181,15 +180,25 @@ struct list_info_struct typedef struct list_info_struct list_info_type; -static struct list_info_struct *head; -struct list_info_struct *listing_tail; -extern int listing; -static int paper_width = 200; -static int paper_height = 60; +int listing_lhs_width = LISTING_LHS_WIDTH; +int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND; +int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES; +int listing_rhs_width = LISTING_RHS_WIDTH; + +struct list_info_struct * listing_tail; + +static file_info_type * file_info_head; +static file_info_type * last_open_file_info; +static FILE * last_open_file; +static struct list_info_struct * head; +static int paper_width = 200; +static int paper_height = 60; + +extern int listing; /* File to output listings to. */ -static FILE *list_file; +static FILE * list_file; /* This static array is used to keep the text of data to be printed before the start of the line. */ @@ -200,13 +209,13 @@ static FILE *list_file; * listing_lhs_cont_lines) \ + 20) -static char *data_buffer; +static char * data_buffer; /* Prototypes. */ static void listing_message PARAMS ((const char *name, const char *message)); -static file_info_type *file_info PARAMS ((const char *file_name)); +static file_info_type * file_info PARAMS ((const char *file_name)); static void new_frag PARAMS ((void)); -static char *buffer_line PARAMS ((file_info_type *file, +static char * buffer_line PARAMS ((file_info_type *file, char *line, unsigned int size)); static void listing_page PARAMS ((list_info_type *list)); static unsigned int calc_hex PARAMS ((list_info_type *list)); @@ -240,27 +249,16 @@ void listing_warning (message) const char *message; { - listing_message ("Warning:", message); + listing_message (_("Warning:"), message); } void listing_error (message) const char *message; { - listing_message ("Error:", message); + listing_message (_("Error:"), message); } - -int listing_lhs_width = LISTING_LHS_WIDTH; -int listing_lhs_width_second = LISTING_LHS_WIDTH_SECOND; -int listing_lhs_cont_lines = LISTING_LHS_CONT_LINES; -int listing_rhs_width = LISTING_RHS_WIDTH; - - -static file_info_type *file_info_head; -static file_info_type *last_open_file_info; -static FILE *last_open_file; - static file_info_type * file_info (file_name) const char *file_name; @@ -336,11 +334,61 @@ listing_newline (ps) as_where (&file, &line); if (ps == NULL) { - if (line == last_line && !(last_file && file && strcmp(file, last_file))) + if (line == last_line && !(last_file && file && strcmp (file, last_file))) return; new = (list_info_type *) xmalloc (sizeof (list_info_type)); - new->line_contents = NULL; + + /* Detect if we are reading from stdin by examining the file + name returned by as_where(). + + [FIXME: We rely upon the name in the strcmp below being the + same as the one used by input_scrub_new_file(), if that is + not true, then this code will fail]. + + If we are reading from stdin, then we need to save each input line + here (assuming of course that we actually have a line of input to read), + so that it can be displayed in the listing that is produced at the end + of the assembly. */ + if (strcmp (file, _("{standard input}")) == 0 + && input_line_pointer != NULL) + { + char * copy; + int len; + int seen_quote = 0; + + for (copy = input_line_pointer - 1; + * copy && (seen_quote + || (! is_end_of_line [(unsigned char) * copy])); + copy ++) + if (* copy == '"' && copy[-1] != '\\') + seen_quote = ! seen_quote; + + len = (copy - input_line_pointer) + 2; + + copy = xmalloc (len); + + if (copy != NULL) + { + char * src = input_line_pointer - 1; + char * dest = copy; + + while (--len) + { + unsigned char c = * src ++; + + /* Omit control characters in the listing. */ + if (isascii (c) && ! iscntrl (c)) + * dest ++ = c; + } + + *dest = 0; + } + + new->line_contents = copy; + } + else + new->line_contents = NULL; } else { @@ -350,16 +398,14 @@ listing_newline (ps) last_line = line; last_file = file; + new_frag (); if (listing_tail) - { - listing_tail->next = new; - } + listing_tail->next = new; else - { - head = new; - } + head = new; + listing_tail = new; new->frag = frag_now; @@ -371,6 +417,7 @@ listing_newline (ps) new->hll_file = (file_info_type *) NULL; new->hll_line = 0; new->debugging = 0; + new_frag (); #ifdef OBJ_ELF @@ -454,7 +501,7 @@ buffer_line (file, line, size) file->at_end = 1; return ""; } - + /* Seek to where we were last time this file was open. */ if (file->pos) fseek(last_open_file, file->pos, SEEK_SET); @@ -549,7 +596,7 @@ calc_hex (list) unsigned int address = ~ (unsigned int) 0; fragS *frag; fragS *frag_ptr; - unsigned int byte_in_frag; + unsigned int octet_in_frag; /* Find first frag which says it belongs to this line */ frag = list->frag; @@ -564,33 +611,33 @@ calc_hex (list) while (frag_ptr != (fragS *) NULL && frag_ptr->line == first) { /* Print as many bytes from the fixed part as is sensible */ - byte_in_frag = 0; - while ((offsetT) byte_in_frag < frag_ptr->fr_fix + octet_in_frag = 0; + while ((offsetT) octet_in_frag < frag_ptr->fr_fix && data_buffer_size < MAX_BYTES - 3) { if (address == ~ (unsigned int) 0) { - address = frag_ptr->fr_address; + address = frag_ptr->fr_address / OCTETS_PER_BYTE; } sprintf (data_buffer + data_buffer_size, "%02X", - (frag_ptr->fr_literal[byte_in_frag]) & 0xff); + (frag_ptr->fr_literal[octet_in_frag]) & 0xff); data_buffer_size += 2; - byte_in_frag++; + octet_in_frag++; } { - unsigned int var_rep_max = byte_in_frag; - unsigned int var_rep_idx = byte_in_frag; + unsigned int var_rep_max = octet_in_frag; + unsigned int var_rep_idx = octet_in_frag; /* Print as many bytes from the variable part as is sensible */ - while (((offsetT) byte_in_frag - < frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset) + while (((offsetT) octet_in_frag + < (frag_ptr->fr_fix + frag_ptr->fr_var * frag_ptr->fr_offset)) && data_buffer_size < MAX_BYTES - 3) { if (address == ~ (unsigned int) 0) { - address = frag_ptr->fr_address; + address = frag_ptr->fr_address / OCTETS_PER_BYTE; } sprintf (data_buffer + data_buffer_size, "%02X", @@ -602,7 +649,7 @@ calc_hex (list) data_buffer_size += 2; var_rep_idx++; - byte_in_frag++; + octet_in_frag++; if ((offsetT) var_rep_idx >= frag_ptr->fr_fix + frag_ptr->fr_var) var_rep_idx = var_rep_max; @@ -630,12 +677,14 @@ print_lines (list, lineno, string, address) unsigned int idx; unsigned int nchars; unsigned int lines; - unsigned int byte_in_word = 0; + unsigned int octet_in_word = 0; char *src = data_buffer; + int cur; /* Print the stuff on the first line */ listing_page (list); nchars = (LISTING_WORD_SIZE * 2 + 1) * listing_lhs_width; + /* Print the hex for the first line */ if (address == ~ (unsigned int) 0) { @@ -644,82 +693,86 @@ print_lines (list, lineno, string, address) fprintf (list_file, " "); fprintf (list_file, "\t%s\n", string ? string : ""); - on_page++; + + on_page ++; + listing_page (0); + return; } + + if (had_errors ()) + fprintf (list_file, "% 4d ???? ", lineno); else + fprintf (list_file, "% 4d %04x ", lineno, address); + + /* And the data to go along with it */ + idx = 0; + cur = 0; + while (src[cur] && idx < nchars) { - if (had_errors ()) - { - fprintf (list_file, "% 4d ???? ", lineno); - } - else + int offset; + offset = cur; + fprintf (list_file, "%c%c", src[offset], src[offset+1]); + cur += 2; + octet_in_word++; + + if (octet_in_word == LISTING_WORD_SIZE) { - fprintf (list_file, "% 4d %04x ", lineno, address); + fprintf (list_file, " "); + idx++; + octet_in_word = 0; } - - /* And the data to go along with it */ + + idx += 2; + } + + for (; idx < nchars; idx++) + fprintf (list_file, " "); + + fprintf (list_file, "\t%s\n", string ? string : ""); + on_page++; + listing_page (list); + + if (list->message) + { + fprintf (list_file, "**** %s\n", list->message); + listing_page (list); + on_page++; + } + + for (lines = 0; + lines < (unsigned int) listing_lhs_cont_lines + && src[cur]; + lines ++) + { + nchars = ((LISTING_WORD_SIZE * 2) + 1) + * listing_lhs_width_second - 1; idx = 0; - - while (*src && idx < nchars) + + /* Print any more lines of data, but more compactly */ + fprintf (list_file, "% 4d ", lineno); + + while (src[cur] && idx < nchars) { - fprintf (list_file, "%c%c", src[0], src[1]); - src += 2; - byte_in_word++; - if (byte_in_word == LISTING_WORD_SIZE) + int offset; + offset = cur; + fprintf (list_file, "%c%c", src[offset], src[offset+1]); + cur += 2; + idx += 2; + octet_in_word++; + + if (octet_in_word == LISTING_WORD_SIZE) { fprintf (list_file, " "); idx++; - byte_in_word = 0; + octet_in_word = 0; } - idx += 2; } - - for (; idx < nchars; idx++) - fprintf (list_file, " "); - - fprintf (list_file, "\t%s\n", string ? string : ""); - on_page++; + + fprintf (list_file, "\n"); + on_page ++; listing_page (list); - if (list->message) - { - fprintf (list_file, "**** %s\n", list->message); - listing_page (list); - on_page++; - } - - for (lines = 0; - lines < (unsigned int) listing_lhs_cont_lines && *src; - lines++) - { - nchars = (((LISTING_WORD_SIZE * 2) + 1) - * listing_lhs_width_second - 1); - idx = 0; - /* Print any more lines of data, but more compactly */ - fprintf (list_file, "% 4d ", lineno); - - while (*src && idx < nchars) - { - fprintf (list_file, "%c%c", src[0], src[1]); - src += 2; - idx += 2; - byte_in_word++; - if (byte_in_word == LISTING_WORD_SIZE) - { - fprintf (list_file, " "); - idx++; - byte_in_word = 0; - } - } - - fprintf (list_file, "\n"); - on_page++; - listing_page (list); - - } - - } } @@ -741,7 +794,7 @@ list_symbol_table () { #ifdef BFD_ASSEMBLER /* Don't report section symbols. They are not interesting. */ - if (ptr->bsym->flags & BSF_SECTION_SYM) + if (symbol_section_p (ptr)) continue; #endif if (S_GET_NAME (ptr)) @@ -773,11 +826,11 @@ list_symbol_table () got_some = 1; } - if (ptr->sy_frag && ptr->sy_frag->line) + if (symbol_get_frag (ptr) && symbol_get_frag (ptr)->line) { fprintf (list_file, "%20s:%-5d %s:%s %s\n", - ptr->sy_frag->line->file->filename, - ptr->sy_frag->line->line, + symbol_get_frag (ptr)->line->file->filename, + symbol_get_frag (ptr)->line->line, segment_name (S_GET_SEGMENT (ptr)), buf, S_GET_NAME (ptr)); } @@ -788,7 +841,7 @@ list_symbol_table () buf, S_GET_NAME (ptr)); } - on_page++; + on_page ++; listing_page (0); } } @@ -930,7 +983,7 @@ debugging_pseudo (list, line) static void listing_listing (name) - char *name; + char *name ATTRIBUTE_UNUSED; { list_info_type *list = head; file_info_type *current_hll_file = (file_info_type *) NULL; @@ -958,13 +1011,17 @@ listing_listing (name) while (list) { + unsigned int list_line; + width = listing_rhs_width > paper_width ? paper_width : listing_rhs_width; + list_line = list->line; switch (list->edict) { case EDICT_LIST: - show_listing++; + /* Skip all lines up to the current. */ + list_line--; break; case EDICT_NOLIST: show_listing--; @@ -985,6 +1042,20 @@ listing_listing (name) abort (); } + if (show_listing <= 0) + { + while (list->file->linenum < list_line + && !list->file->at_end) + p = buffer_line (list->file, buffer, width); + } + + if (list->edict == EDICT_LIST) + { + /* Enable listing for the single line that caused the enable. */ + list_line++; + show_listing++; + } + if (show_listing > 0) { /* Scan down the list and print all the stuff which can be done @@ -1006,20 +1077,23 @@ listing_listing (name) if (!((listing & LISTING_NODEBUG) && debugging_pseudo (list, list->line_contents))) { - print_lines (list, list->file->linenum, + print_lines (list, + list->file->linenum == 0 ? list->line : list->file->linenum, list->line_contents, calc_hex (list)); } + free (list->line_contents); + list->line_contents = NULL; } else { - while (list->file->linenum < list->line + while (list->file->linenum < list_line && !list->file->at_end) { unsigned int address; p = buffer_line (list->file, buffer, width); - if (list->file->linenum < list->line) + if (list->file->linenum < list_line) address = ~ (unsigned int) 0; else address = calc_hex (list); @@ -1035,12 +1109,6 @@ listing_listing (name) eject = 1; } } - else - { - while (list->file->linenum < list->line - && !list->file->at_end) - p = buffer_line (list->file, buffer, width); - } if (list->edict == EDICT_NOLIST_NEXT) --show_listing; @@ -1058,7 +1126,7 @@ listing_print (name) char *name; { int using_stdout; - + title = ""; subtitle = ""; @@ -1074,7 +1142,7 @@ listing_print (name) using_stdout = 0; else { - as_perror ("can't open list file: %s", name); + as_perror (_("can't open list file: %s"), name); list_file = stdout; using_stdout = 1; } @@ -1098,7 +1166,7 @@ listing_print (name) if (! using_stdout) { if (fclose (list_file) == EOF) - as_perror ("error closing list file: %s", name); + as_perror (_("error closing list file: %s"), name); } if (last_open_file) @@ -1117,7 +1185,7 @@ listing_file (name) void listing_eject (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { if (listing) listing_tail->edict = EDICT_EJECT; @@ -1125,7 +1193,7 @@ listing_eject (ignore) void listing_flags (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { while ((*input_line_pointer++) && (*input_line_pointer != '\n')) input_line_pointer++; @@ -1179,7 +1247,7 @@ listing_psize (width_only) if (paper_height < 0 || paper_height > 1000) { paper_height = 0; - as_warn ("strange paper height, set to no form"); + as_warn (_("strange paper height, set to no form")); } if (*input_line_pointer != ',') @@ -1198,7 +1266,7 @@ listing_psize (width_only) void listing_nopage (ignore) - int ignore; + int ignore ATTRIBUTE_UNUSED; { paper_height = 0; } @@ -1245,7 +1313,7 @@ listing_title (depth) } else if (*input_line_pointer == '\n') { - as_bad ("New line in title"); + as_bad (_("New line in title")); demand_empty_rest_of_line (); return; } |