X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gas%2Finput-scrub.c;h=adae4d4dcd004b3ff0abaca61f80dcf247989547;hb=04ee5257d646209723f3ed11afd838529fe6e3a7;hp=ee5bdc894f87c23841daede030c859a467a42af8;hpb=7152f1dc4515cb14067fed4c5d5b5374f0d475b4;p=deliverable%2Fbinutils-gdb.git diff --git a/gas/input-scrub.c b/gas/input-scrub.c index ee5bdc894f..adae4d4dcd 100644 --- a/gas/input-scrub.c +++ b/gas/input-scrub.c @@ -1,12 +1,13 @@ /* input_scrub.c - Break up input buffers into whole numbers of lines. - Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 96, 97, 2000 + Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 2000, 2001, 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. This file is part of GAS, the GNU Assembler. GAS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) + the Free Software Foundation; either version 3, or (at your option) any later version. GAS is distributed in the hope that it will be useful, @@ -16,11 +17,11 @@ You should have received a copy of the GNU General Public License along with GAS; see the file COPYING. If not, write to the Free - Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA + 02110-1301, USA. */ -#include /* Need this to make errno declaration right */ #include "as.h" +#include "filenames.h" #include "input-file.h" #include "sb.h" #include "listing.h" @@ -32,7 +33,7 @@ * were broken across buffers, and return a buffer of full lines to * the caller. * The last partial line begins the next buffer we build and return to caller. - * The buffer returned to caller is preceeded by BEFORE_STRING and followed + * The buffer returned to caller is preceded by BEFORE_STRING and followed * by AFTER_STRING, as sentinels. The last character before AFTER_STRING * is a newline. * Also looks after line numbers, for e.g. error messages. @@ -56,6 +57,10 @@ #define BEFORE_SIZE (1) #define AFTER_SIZE (1) +#ifndef TC_EOL_IN_INSN +#define TC_EOL_IN_INSN(P) 0 +#endif + static char *buffer_start; /*->1st char of full buffer area. */ static char *partial_where; /*->after last full line in buffer. */ static int partial_size; /* >=0. Number of chars in partial line in buffer. */ @@ -70,7 +75,7 @@ static char save_source[AFTER_SIZE]; static unsigned int buffer_length; /* The index into an sb structure we are reading from. -1 if none. */ -static int sb_index = -1; +static size_t sb_index = -1; /* If we are reading from an sb structure, this is it. */ static sb from_sb; @@ -95,34 +100,32 @@ int macro_nest; static char *physical_input_file; static char *logical_input_file; -typedef unsigned int line_numberT; /* 1-origin line number in a source file. */ +/* 1-origin line number in a source file. */ /* A line ends in '\n' or eof. */ - -static line_numberT physical_input_line; +static unsigned int physical_input_line; static int logical_input_line; /* Struct used to save the state of the input handler during include files */ struct input_save { - char *buffer_start; - char *partial_where; - int partial_size; - char save_source[AFTER_SIZE]; - unsigned int buffer_length; - char *physical_input_file; - char *logical_input_file; - line_numberT physical_input_line; - int logical_input_line; - int sb_index; - sb from_sb; - int from_sb_is_expansion; /* Should we do a conditional check? */ - struct input_save *next_saved_file; /* Chain of input_saves */ - char *input_file_save; /* Saved state of input routines */ - char *saved_position; /* Caller's saved position in buf */ + char * buffer_start; + char * partial_where; + int partial_size; + char save_source[AFTER_SIZE]; + size_t buffer_length; + char * physical_input_file; + char * logical_input_file; + unsigned int physical_input_line; + int logical_input_line; + size_t sb_index; + sb from_sb; + int from_sb_is_expansion; /* Should we do a conditional check? */ + struct input_save * next_saved_file; /* Chain of input_saves. */ + char * input_file_save; /* Saved state of input routines. */ + char * saved_position; /* Caller's saved position in buf. */ }; -static struct input_save *input_scrub_push PARAMS ((char *saved_position)); -static char *input_scrub_pop PARAMS ((struct input_save *arg)); -static void as_1_char PARAMS ((unsigned int c, FILE * stream)); +static struct input_save *input_scrub_push (char *saved_position); +static char *input_scrub_pop (struct input_save *arg); /* Saved information about the file that .include'd this one. When we hit EOF, we automatically pop to that file. */ @@ -134,8 +137,7 @@ static struct input_save *next_saved_file; area, which can be restored by passing it to input_scrub_pop(). */ static struct input_save * -input_scrub_push (saved_position) - char *saved_position; +input_scrub_push (char *saved_position) { register struct input_save *saved; @@ -163,15 +165,15 @@ input_scrub_push (saved_position) buffer_length = input_file_buffer_size (); sb_index = -1; - buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); + buffer_start = (char *) xmalloc ((BEFORE_SIZE + buffer_length + + buffer_length + AFTER_SIZE)); memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); return saved; } static char * -input_scrub_pop (saved) - struct input_save *saved; +input_scrub_pop (struct input_save *saved) { char *saved_position; @@ -198,7 +200,7 @@ input_scrub_pop (saved) } void -input_scrub_begin () +input_scrub_begin (void) { know (strlen (BEFORE_STRING) == BEFORE_SIZE); know (strlen (AFTER_STRING) == AFTER_SIZE @@ -208,7 +210,8 @@ input_scrub_begin () buffer_length = input_file_buffer_size (); - buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); + buffer_start = (char *) xmalloc ((BEFORE_SIZE + buffer_length + + buffer_length + AFTER_SIZE)); memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); /* Line number things. */ @@ -220,7 +223,7 @@ input_scrub_begin () } void -input_scrub_end () +input_scrub_end (void) { if (buffer_start) { @@ -234,8 +237,7 @@ input_scrub_end () Return start of caller's part of buffer. */ char * -input_scrub_new_file (filename) - char *filename; +input_scrub_new_file (char *filename) { input_file_open (filename, !flag_no_comments); physical_input_file = filename[0] ? filename : _("{standard input}"); @@ -250,9 +252,7 @@ input_scrub_new_file (filename) input_scrub_new_file. */ char * -input_scrub_include_file (filename, position) - char *filename; - char *position; +input_scrub_include_file (char *filename, char *position) { next_saved_file = input_scrub_push (position); return input_scrub_new_file (filename); @@ -262,11 +262,10 @@ input_scrub_include_file (filename, position) expanding a macro. */ void -input_scrub_include_sb (from, position, is_expansion) - sb *from; - char *position; - int is_expansion; +input_scrub_include_sb (sb *from, char *position, int is_expansion) { + int newline; + if (macro_nest > max_macro_nest) as_fatal (_("macros nested too deeply")); ++macro_nest; @@ -280,14 +279,21 @@ input_scrub_include_sb (from, position, is_expansion) next_saved_file = input_scrub_push (position); - sb_new (&from_sb); + /* Allocate sufficient space: from->len + optional newline. */ + newline = from->len >= 1 && from->ptr[0] != '\n'; + sb_build (&from_sb, from->len + newline); from_sb_is_expansion = is_expansion; - if (from->len >= 1 && from->ptr[0] != '\n') + if (newline) { /* Add the sentinel required by read.c. */ sb_add_char (&from_sb, '\n'); } - sb_add_sb (&from_sb, from); + sb_scrub_and_add_sb (&from_sb, from); + + /* Make sure the parser looks at defined contents when it scans for + e.g. end-of-line at the end of a macro. */ + sb_terminate (&from_sb); + sb_index = 1; /* These variables are reset by input_scrub_push. Restore them @@ -297,24 +303,24 @@ input_scrub_include_sb (from, position, is_expansion) } void -input_scrub_close () +input_scrub_close (void) { input_file_close (); + physical_input_line = 0; + logical_input_line = -1; } char * -input_scrub_next_buffer (bufp) - char **bufp; +input_scrub_next_buffer (char **bufp) { register char *limit; /*->just after last char of buffer. */ - if (sb_index >= 0) + if (sb_index != (size_t) -1) { if (sb_index >= from_sb.len) { sb_kill (&from_sb); - if (from_sb_is_expansion - ) + if (from_sb_is_expansion) { cond_finish_check (macro_nest); #ifdef md_macro_end @@ -341,8 +347,8 @@ input_scrub_next_buffer (bufp) if (partial_size) { - memcpy (buffer_start + BEFORE_SIZE, partial_where, - (unsigned int) partial_size); + memmove (buffer_start + BEFORE_SIZE, partial_where, + (unsigned int) partial_size); memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE); } limit = input_file_give_next_buffer (buffer_start @@ -351,8 +357,9 @@ input_scrub_next_buffer (bufp) if (limit) { register char *p; /* Find last newline. */ - - for (p = limit - 1; *p != '\n'; --p) + /* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */ + *limit = '\0'; + for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p) ; ++p; @@ -362,10 +369,10 @@ input_scrub_next_buffer (bufp) limoff = limit - buffer_start; buffer_length += input_file_buffer_size (); - buffer_start = xrealloc (buffer_start, - (BEFORE_SIZE - + 2 * buffer_length - + AFTER_SIZE)); + buffer_start = (char *) xrealloc (buffer_start, + (BEFORE_SIZE + + 2 * buffer_length + + AFTER_SIZE)); *bufp = buffer_start + BEFORE_SIZE; limit = input_file_give_next_buffer (buffer_start + limoff); @@ -378,7 +385,9 @@ input_scrub_next_buffer (bufp) return NULL; } - for (p = limit - 1; *p != '\n'; --p) + /* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */ + *limit = '\0'; + for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p) ; ++p; } @@ -393,7 +402,7 @@ input_scrub_next_buffer (bufp) partial_where = 0; if (partial_size > 0) { - as_warn (_("Partial line at end of file ignored")); + as_warn (_("partial line at end of file ignored")); } /* Tell the listing we've finished the file. */ @@ -413,15 +422,15 @@ input_scrub_next_buffer (bufp) messages and so on. Return TRUE if we opened any file. */ int -seen_at_least_1_file () +seen_at_least_1_file (void) { return (physical_input_file != NULL); } void -bump_line_counters () +bump_line_counters (void) { - if (sb_index < 0) + if (sb_index == (size_t) -1) { ++physical_input_line; if (logical_input_line >= 0) @@ -438,18 +447,38 @@ bump_line_counters () Returns nonzero if the filename actually changes. */ int -new_logical_line (fname, line_number) - char *fname; /* DON'T destroy it! We point to it! */ - int line_number; +new_logical_line_flags (char *fname, /* DON'T destroy it! We point to it! */ + int line_number, + int flags) { + switch (flags) + { + case 0: + break; + case 1: + if (line_number != -1) + abort (); + break; + case 1 << 1: + case 1 << 2: + /* FIXME: we could check that include nesting is correct. */ + break; + default: + abort (); + } + if (line_number >= 0) logical_input_line = line_number; - else if (line_number == -2 && logical_input_line > 0) - --logical_input_line; + else if (line_number == -1 && fname && !*fname && (flags & (1 << 2))) + { + logical_input_file = physical_input_file; + logical_input_line = physical_input_line; + fname = NULL; + } if (fname && (logical_input_file == NULL - || strcmp (logical_input_file, fname))) + || filename_cmp (logical_input_file, fname))) { logical_input_file = fname; return 1; @@ -457,15 +486,20 @@ new_logical_line (fname, line_number) else return 0; } + +int +new_logical_line (char *fname, int line_number) +{ + return new_logical_line_flags (fname, line_number, 0); +} + /* Return the current file name and line number. namep should be char * const *, but there are compilers which screw up declarations like that, and it's easier to avoid it. */ void -as_where (namep, linep) - char **namep; - unsigned int *linep; +as_where (char **namep, unsigned int *linep) { if (logical_input_file != NULL && (linep == NULL || logical_input_line >= 0)) @@ -487,42 +521,3 @@ as_where (namep, linep) *linep = 0; } } - -/* Output to given stream how much of line we have scanned so far. - Assumes we have scanned up to and including input_line_pointer. - No free '\n' at end of line. */ - -void -as_howmuch (stream) - FILE *stream; /* Opened for write please. */ -{ - register char *p; /* Scan input line. */ - - for (p = input_line_pointer - 1; *p != '\n'; --p) - { - } - ++p; /* p->1st char of line. */ - for (; p <= input_line_pointer; p++) - { - /* Assume ASCII. EBCDIC & other micro-computer char sets ignored. */ - as_1_char ((unsigned char) *p, stream); - } -} - -static void -as_1_char (c, stream) - unsigned int c; - FILE *stream; -{ - if (c > 127) - { - (void) putc ('%', stream); - c -= 128; - } - if (c < 32) - { - (void) putc ('^', stream); - c += '@'; - } - (void) putc (c, stream); -}