input-scrub.c revision 218822
1119418Sobrien/* input_scrub.c - Break up input buffers into whole numbers of lines. 2119418Sobrien Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 393746Sjulian 2000, 2001, 2003, 2006, 2007 493746Sjulian Free Software Foundation, Inc. 593746Sjulian 693746Sjulian This file is part of GAS, the GNU Assembler. 793746Sjulian 893746Sjulian GAS is free software; you can redistribute it and/or modify 993746Sjulian it under the terms of the GNU General Public License as published by 1093746Sjulian the Free Software Foundation; either version 2, or (at your option) 1193746Sjulian any later version. 1293746Sjulian 1393746Sjulian GAS is distributed in the hope that it will be useful, 1493746Sjulian but WITHOUT ANY WARRANTY; without even the implied warranty of 1593746Sjulian MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1693746Sjulian GNU General Public License for more details. 1793746Sjulian 1893746Sjulian You should have received a copy of the GNU General Public License 1993746Sjulian along with GAS; see the file COPYING. If not, write to the Free 2093746Sjulian Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 2193746Sjulian 02110-1301, USA. */ 2293746Sjulian 2393746Sjulian#include "as.h" 2493746Sjulian#include "input-file.h" 2593746Sjulian#include "sb.h" 2693746Sjulian#include "listing.h" 27119418Sobrien 2893746Sjulian/* 29113038Sobrien * O/S independent module to supply buffers of sanitised source code 30113038Sobrien * to rest of assembler. We get sanitised input data of arbitrary length. 31113038Sobrien * We break these buffers on line boundaries, recombine pieces that 32113038Sobrien * were broken across buffers, and return a buffer of full lines to 3393746Sjulian * the caller. 3493746Sjulian * The last partial line begins the next buffer we build and return to caller. 3593746Sjulian * The buffer returned to caller is preceded by BEFORE_STRING and followed 3693746Sjulian * by AFTER_STRING, as sentinels. The last character before AFTER_STRING 3793746Sjulian * is a newline. 3893746Sjulian * Also looks after line numbers, for e.g. error messages. 3993746Sjulian */ 4093746Sjulian 4193746Sjulian/* 4293746Sjulian * We don't care how filthy our buffers are, but our callers assume 4393746Sjulian * that the following sanitation has already been done. 4495807Sjulian * 4595807Sjulian * No comments, reduce a comment to a space. 4693746Sjulian * Reduce a tab to a space unless it is 1st char of line. 4793746Sjulian * All multiple tabs and spaces collapsed into 1 char. Tab only 4893746Sjulian * legal if 1st char of line. 4993746Sjulian * # line file statements converted to .line x;.file y; statements. 5093746Sjulian * Escaped newlines at end of line: remove them but add as many newlines 5193746Sjulian * to end of statement as you removed in the middle, to synch line numbers. 5293746Sjulian */ 53147256Sbrooks 5493746Sjulian#define BEFORE_STRING ("\n") 5593746Sjulian#define AFTER_STRING ("\0") /* memcpy of 0 chars might choke. */ 5693746Sjulian#define BEFORE_SIZE (1) 5793746Sjulian#define AFTER_SIZE (1) 5893746Sjulian 5993746Sjulian#ifndef TC_EOL_IN_INSN 6093746Sjulian#define TC_EOL_IN_INSN(P) 0 6193746Sjulian#endif 6293746Sjulian 6393746Sjulianstatic char *buffer_start; /*->1st char of full buffer area. */ 64119285Simpstatic char *partial_where; /*->after last full line in buffer. */ 65119285Simpstatic int partial_size; /* >=0. Number of chars in partial line in buffer. */ 6693746Sjulian 6793746Sjulian/* Because we need AFTER_STRING just after last full line, it clobbers 6893746Sjulian 1st part of partial line. So we preserve 1st part of partial line 6993746Sjulian here. */ 7093746Sjulianstatic char save_source[AFTER_SIZE]; 7193746Sjulian 7293746Sjulian/* What is the largest size buffer that input_file_give_next_buffer() 73153084Sru could return to us? */ 7494904Sjulianstatic unsigned int buffer_length; 7594904Sjulian 7693746Sjulian/* The index into an sb structure we are reading from. -1 if none. */ 7794904Sjulianstatic int sb_index = -1; 7894904Sjulian 7993746Sjulian/* If we are reading from an sb structure, this is it. */ 8093746Sjulianstatic sb from_sb; 8193746Sjulian 8293746Sjulian/* Should we do a conditional check on from_sb? */ 8393746Sjulianstatic int from_sb_is_expansion = 1; 8493746Sjulian 8593746Sjulian/* The number of nested sb structures we have included. */ 86119285Simpint macro_nest; 8793746Sjulian 8893746Sjulian/* We can have more than one source file open at once, though the info for all 8993746Sjulian but the latest one are saved off in a struct input_save. These files remain 9093746Sjulian open, so we are limited by the number of open files allowed by the 9193746Sjulian underlying OS. We may also sequentially read more than one source file in an 9293746Sjulian assembly. */ 9393746Sjulian 9493746Sjulian/* We must track the physical file and line number for error messages. We also 9593746Sjulian track a "logical" file and line number corresponding to (C?) compiler 9693746Sjulian source line numbers. Whenever we open a file we must fill in 9793746Sjulian physical_input_file. So if it is NULL we have not opened any files yet. */ 9893746Sjulian 9993746Sjulianstatic char *physical_input_file; 10093746Sjulianstatic char *logical_input_file; 10193746Sjulian 10293746Sjuliantypedef unsigned int line_numberT; /* 1-origin line number in a source file. */ 10393746Sjulian/* A line ends in '\n' or eof. */ 10493746Sjulian 10593746Sjulianstatic line_numberT physical_input_line; 10693746Sjulianstatic int logical_input_line; 10793746Sjulian 10893746Sjulian/* Struct used to save the state of the input handler during include files */ 10993746Sjulianstruct input_save { 11093746Sjulian char * buffer_start; 11193746Sjulian char * partial_where; 11293746Sjulian int partial_size; 11393746Sjulian char save_source[AFTER_SIZE]; 11493746Sjulian unsigned int buffer_length; 11593746Sjulian char * physical_input_file; 11693746Sjulian char * logical_input_file; 11793746Sjulian line_numberT physical_input_line; 11893746Sjulian int logical_input_line; 11993746Sjulian int sb_index; 12093746Sjulian sb from_sb; 12193746Sjulian int from_sb_is_expansion; /* Should we do a conditional check? */ 12293746Sjulian struct input_save * next_saved_file; /* Chain of input_saves. */ 12393746Sjulian char * input_file_save; /* Saved state of input routines. */ 124149151Sjhb char * saved_position; /* Caller's saved position in buf. */ 12593746Sjulian}; 12693746Sjulian 127149151Sjhbstatic struct input_save *input_scrub_push (char *saved_position); 12893746Sjulianstatic char *input_scrub_pop (struct input_save *arg); 12993746Sjulian 130188172Simp/* Saved information about the file that .include'd this one. When we hit EOF, 13193746Sjulian we automatically pop to that file. */ 13293746Sjulian 13393746Sjulianstatic struct input_save *next_saved_file; 13493746Sjulian 13593746Sjulian/* Push the state of input reading and scrubbing so that we can #include. 13693746Sjulian The return value is a 'void *' (fudged for old compilers) to a save 13793746Sjulian area, which can be restored by passing it to input_scrub_pop(). */ 13893746Sjulian 13993746Sjulianstatic struct input_save * 14093746Sjulianinput_scrub_push (char *saved_position) 14193746Sjulian{ 14293746Sjulian register struct input_save *saved; 14393746Sjulian 14493746Sjulian saved = (struct input_save *) xmalloc (sizeof *saved); 14593746Sjulian 146106696Salfred saved->saved_position = saved_position; 147106696Salfred saved->buffer_start = buffer_start; 14893746Sjulian saved->partial_where = partial_where; 14993746Sjulian saved->partial_size = partial_size; 15093746Sjulian saved->buffer_length = buffer_length; 15193746Sjulian saved->physical_input_file = physical_input_file; 15293746Sjulian saved->logical_input_file = logical_input_file; 15393746Sjulian saved->physical_input_line = physical_input_line; 15493746Sjulian saved->logical_input_line = logical_input_line; 15593746Sjulian saved->sb_index = sb_index; 15693746Sjulian saved->from_sb = from_sb; 15793746Sjulian saved->from_sb_is_expansion = from_sb_is_expansion; 15893746Sjulian memcpy (saved->save_source, save_source, sizeof (save_source)); 15993746Sjulian saved->next_saved_file = next_saved_file; 16093746Sjulian saved->input_file_save = input_file_push (); 16193746Sjulian 16293746Sjulian input_file_begin (); /* Reinitialize! */ 16393746Sjulian logical_input_line = -1; 16493746Sjulian logical_input_file = (char *) NULL; 16593746Sjulian buffer_length = input_file_buffer_size (); 16693746Sjulian sb_index = -1; 167113506Smdodd 168113506Smdodd buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); 169113506Smdodd memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); 17093746Sjulian 17193746Sjulian return saved; 17293746Sjulian} 17393746Sjulian 17493746Sjulianstatic char * 17593746Sjulianinput_scrub_pop (struct input_save *saved) 17693746Sjulian{ 17793746Sjulian char *saved_position; 178149151Sjhb 17993746Sjulian input_scrub_end (); /* Finish off old buffer */ 18093746Sjulian 18193746Sjulian input_file_pop (saved->input_file_save); 18293746Sjulian saved_position = saved->saved_position; 18393746Sjulian buffer_start = saved->buffer_start; 18493746Sjulian buffer_length = saved->buffer_length; 18593746Sjulian physical_input_file = saved->physical_input_file; 18693746Sjulian logical_input_file = saved->logical_input_file; 18793746Sjulian physical_input_line = saved->physical_input_line; 18893746Sjulian logical_input_line = saved->logical_input_line; 18993746Sjulian sb_index = saved->sb_index; 19093746Sjulian from_sb = saved->from_sb; 19193746Sjulian from_sb_is_expansion = saved->from_sb_is_expansion; 19293746Sjulian partial_where = saved->partial_where; 19393746Sjulian partial_size = saved->partial_size; 19493746Sjulian next_saved_file = saved->next_saved_file; 19593746Sjulian memcpy (save_source, saved->save_source, sizeof (save_source)); 19693746Sjulian 19793746Sjulian free (saved); 19893746Sjulian return saved_position; 19993746Sjulian} 20093746Sjulian 20193746Sjulianvoid 20293746Sjulianinput_scrub_begin (void) 20393746Sjulian{ 20493746Sjulian know (strlen (BEFORE_STRING) == BEFORE_SIZE); 20593746Sjulian know (strlen (AFTER_STRING) == AFTER_SIZE 20693746Sjulian || (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1)); 20793746Sjulian 20893746Sjulian input_file_begin (); 20993746Sjulian 21093746Sjulian buffer_length = input_file_buffer_size (); 21193746Sjulian 21293746Sjulian buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); 21393746Sjulian memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); 21493746Sjulian 21593746Sjulian /* Line number things. */ 21693746Sjulian logical_input_line = -1; 21793746Sjulian logical_input_file = (char *) NULL; 21893746Sjulian physical_input_file = NULL; /* No file read yet. */ 21993746Sjulian next_saved_file = NULL; /* At EOF, don't pop to any other file */ 22093746Sjulian do_scrub_begin (flag_m68k_mri); 22193746Sjulian} 22293746Sjulian 22393746Sjulianvoid 224148945Sjhbinput_scrub_end (void) 22593746Sjulian{ 22693746Sjulian if (buffer_start) 22793746Sjulian { 22893746Sjulian free (buffer_start); 22993746Sjulian buffer_start = 0; 230149151Sjhb input_file_end (); 23193746Sjulian } 23293746Sjulian} 23393746Sjulian 23493746Sjulian/* Start reading input from a new file. 23593746Sjulian Return start of caller's part of buffer. */ 23693746Sjulian 23793746Sjulianchar * 23893746Sjulianinput_scrub_new_file (char *filename) 23993746Sjulian{ 24093746Sjulian input_file_open (filename, !flag_no_comments); 24193746Sjulian physical_input_file = filename[0] ? filename : _("{standard input}"); 24293746Sjulian physical_input_line = 0; 24393746Sjulian 24493746Sjulian partial_size = 0; 24593746Sjulian return (buffer_start + BEFORE_SIZE); 24693746Sjulian} 24793746Sjulian 24893746Sjulian/* Include a file from the current file. Save our state, cause it to 24993746Sjulian be restored on EOF, and begin handling a new file. Same result as 25093746Sjulian input_scrub_new_file. */ 25193746Sjulian 25293746Sjulianchar * 25393746Sjulianinput_scrub_include_file (char *filename, char *position) 25493746Sjulian{ 25593746Sjulian next_saved_file = input_scrub_push (position); 25693746Sjulian return input_scrub_new_file (filename); 25793746Sjulian} 25893746Sjulian 25993746Sjulian/* Start getting input from an sb structure. This is used when 26093746Sjulian expanding a macro. */ 26193746Sjulian 26293746Sjulianvoid 26393746Sjulianinput_scrub_include_sb (sb *from, char *position, int is_expansion) 26493746Sjulian{ 26593746Sjulian if (macro_nest > max_macro_nest) 26693746Sjulian as_fatal (_("macros nested too deeply")); 26793746Sjulian ++macro_nest; 26893746Sjulian 26993746Sjulian#ifdef md_macro_start 27093746Sjulian if (is_expansion) 27193746Sjulian { 27293746Sjulian md_macro_start (); 27393746Sjulian } 274149151Sjhb#endif 27593746Sjulian 27693746Sjulian next_saved_file = input_scrub_push (position); 27793746Sjulian 27893746Sjulian sb_new (&from_sb); 27993746Sjulian from_sb_is_expansion = is_expansion; 28093746Sjulian if (from->len >= 1 && from->ptr[0] != '\n') 28193746Sjulian { 28293746Sjulian /* Add the sentinel required by read.c. */ 28393746Sjulian sb_add_char (&from_sb, '\n'); 28493746Sjulian } 28593746Sjulian sb_scrub_and_add_sb (&from_sb, from); 28693746Sjulian sb_index = 1; 28793746Sjulian 28893746Sjulian /* These variables are reset by input_scrub_push. Restore them 28993746Sjulian since we are, after all, still at the same point in the file. */ 29093746Sjulian logical_input_line = next_saved_file->logical_input_line; 29193746Sjulian logical_input_file = next_saved_file->logical_input_file; 29293746Sjulian} 29393746Sjulian 29493746Sjulianvoid 29593746Sjulianinput_scrub_close (void) 29693746Sjulian{ 29793746Sjulian input_file_close (); 29893746Sjulian} 29993746Sjulian 30093746Sjulianchar * 30193746Sjulianinput_scrub_next_buffer (char **bufp) 30293746Sjulian{ 30393746Sjulian register char *limit; /*->just after last char of buffer. */ 30493746Sjulian 30593746Sjulian if (sb_index >= 0) 30693746Sjulian { 30793746Sjulian if (sb_index >= from_sb.len) 30893746Sjulian { 30993746Sjulian sb_kill (&from_sb); 31093746Sjulian if (from_sb_is_expansion 31193746Sjulian ) 31293746Sjulian { 31393746Sjulian cond_finish_check (macro_nest); 31493746Sjulian#ifdef md_macro_end 31593746Sjulian /* Allow the target to clean up per-macro expansion 31693746Sjulian data. */ 31793746Sjulian md_macro_end (); 31893746Sjulian#endif 31993746Sjulian } 32093746Sjulian --macro_nest; 321149151Sjhb partial_where = NULL; 32293746Sjulian if (next_saved_file != NULL) 323147256Sbrooks *bufp = input_scrub_pop (next_saved_file); 32493746Sjulian return partial_where; 32593746Sjulian } 32693746Sjulian 32793746Sjulian partial_where = from_sb.ptr + from_sb.len; 32893746Sjulian partial_size = 0; 32993746Sjulian *bufp = from_sb.ptr + sb_index; 33093746Sjulian sb_index = from_sb.len; 33193746Sjulian return partial_where; 33293746Sjulian } 33393746Sjulian 33493746Sjulian *bufp = buffer_start + BEFORE_SIZE; 33593746Sjulian 33693746Sjulian if (partial_size) 33793746Sjulian { 33893746Sjulian memcpy (buffer_start + BEFORE_SIZE, partial_where, 33993746Sjulian (unsigned int) partial_size); 340148654Srwatson memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE); 34193746Sjulian } 34293746Sjulian limit = input_file_give_next_buffer (buffer_start 34393746Sjulian + BEFORE_SIZE 344130270Snaddy + partial_size); 345130270Snaddy if (limit) 34693746Sjulian { 34793746Sjulian register char *p; /* Find last newline. */ 34893746Sjulian /* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */ 34993746Sjulian *limit = '\0'; 35093746Sjulian for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p) 35193746Sjulian ; 352148654Srwatson ++p; 35393746Sjulian 35493746Sjulian while (p <= buffer_start + BEFORE_SIZE) 35593746Sjulian { 35693746Sjulian int limoff; 35793746Sjulian 35893746Sjulian limoff = limit - buffer_start; 35993746Sjulian buffer_length += input_file_buffer_size (); 36093746Sjulian buffer_start = xrealloc (buffer_start, 36193746Sjulian (BEFORE_SIZE 36293746Sjulian + 2 * buffer_length 36393746Sjulian + AFTER_SIZE)); 36493746Sjulian *bufp = buffer_start + BEFORE_SIZE; 36593746Sjulian limit = input_file_give_next_buffer (buffer_start + limoff); 36693746Sjulian 36793746Sjulian if (limit == NULL) 36893746Sjulian { 36993746Sjulian as_warn (_("partial line at end of file ignored")); 37093746Sjulian partial_where = NULL; 37193746Sjulian if (next_saved_file) 372149151Sjhb *bufp = input_scrub_pop (next_saved_file); 37393746Sjulian return NULL; 37493746Sjulian } 37593746Sjulian 37693746Sjulian /* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */ 37793746Sjulian *limit = '\0'; 37893746Sjulian for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p) 37993746Sjulian ; 38093746Sjulian ++p; 38193746Sjulian } 38293746Sjulian 38393746Sjulian partial_where = p; 38493746Sjulian partial_size = limit - p; 38593746Sjulian memcpy (save_source, partial_where, (int) AFTER_SIZE); 38693746Sjulian memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE); 38793746Sjulian } 38893746Sjulian else 38993746Sjulian { 39093746Sjulian partial_where = 0; 39193746Sjulian if (partial_size > 0) 39293746Sjulian { 39393746Sjulian as_warn (_("partial line at end of file ignored")); 39493746Sjulian } 39593746Sjulian 39693746Sjulian /* Tell the listing we've finished the file. */ 397149151Sjhb LISTING_EOF (); 39893746Sjulian 39993746Sjulian /* If we should pop to another file at EOF, do it. */ 400147256Sbrooks if (next_saved_file) 40193746Sjulian { 40293746Sjulian *bufp = input_scrub_pop (next_saved_file); /* Pop state */ 40393746Sjulian /* partial_where is now correct to return, since we popped it. */ 40493746Sjulian } 40593746Sjulian } 40693746Sjulian return (partial_where); 40793746Sjulian} 40893746Sjulian 40993746Sjulian/* The remaining part of this file deals with line numbers, error 41093746Sjulian messages and so on. Return TRUE if we opened any file. */ 41193746Sjulian 412162321Sglebiusint 413162321Sglebiusseen_at_least_1_file (void) 41493746Sjulian{ 41593746Sjulian return (physical_input_file != NULL); 41693746Sjulian} 41793746Sjulian 41893746Sjulianvoid 41993746Sjulianbump_line_counters (void) 42093746Sjulian{ 42193746Sjulian if (sb_index < 0) 42293746Sjulian { 42393746Sjulian ++physical_input_line; 42493746Sjulian if (logical_input_line >= 0) 42593746Sjulian ++logical_input_line; 42693746Sjulian } 42793746Sjulian} 42893746Sjulian 42993746Sjulian/* Tells us what the new logical line number and file are. 43093746Sjulian If the line_number is -1, we don't change the current logical line 43193746Sjulian number. If it is -2, we decrement the logical line number (this is 43293746Sjulian to support the .appfile pseudo-op inserted into the stream by 43393746Sjulian do_scrub_chars). 43493746Sjulian If the fname is NULL, we don't change the current logical file name. 43593746Sjulian Returns nonzero if the filename actually changes. */ 43693746Sjulian 43793746Sjulianint 43893746Sjuliannew_logical_line_flags (char *fname, /* DON'T destroy it! We point to it! */ 43993746Sjulian int line_number, 44093746Sjulian int flags) 44193746Sjulian{ 44293746Sjulian switch (flags) 44393746Sjulian { 44493746Sjulian case 0: 44593746Sjulian break; 44693746Sjulian case 1: 44793746Sjulian if (line_number != -1) 44893746Sjulian abort (); 44993746Sjulian break; 45093746Sjulian case 1 << 1: 451162321Sglebius case 1 << 2: 45293746Sjulian /* FIXME: we could check that include nesting is correct. */ 45393746Sjulian break; 45493746Sjulian default: 45593746Sjulian abort (); 45693746Sjulian } 457162321Sglebius 45893746Sjulian if (line_number >= 0) 45993746Sjulian logical_input_line = line_number; 46093746Sjulian else if (line_number == -1 && fname && !*fname && (flags & (1 << 2))) 461162321Sglebius { 46293746Sjulian logical_input_file = physical_input_file; 46393746Sjulian logical_input_line = physical_input_line; 46493746Sjulian fname = NULL; 46593746Sjulian } 46693746Sjulian 46793746Sjulian if (fname 46893746Sjulian && (logical_input_file == NULL 469162321Sglebius || strcmp (logical_input_file, fname))) 47093746Sjulian { 47193746Sjulian logical_input_file = fname; 47293746Sjulian return 1; 47393746Sjulian } 47493746Sjulian else 47593746Sjulian return 0; 47693746Sjulian} 47793746Sjulian 47893746Sjulianint 47993746Sjuliannew_logical_line (char *fname, int line_number) 48093746Sjulian{ 48195673Sphk return new_logical_line_flags (fname, line_number, 0); 48293746Sjulian} 48393746Sjulian 48493746Sjulian 48593746Sjulian/* Return the current file name and line number. 48693746Sjulian namep should be char * const *, but there are compilers which screw 48793746Sjulian up declarations like that, and it's easier to avoid it. */ 48893746Sjulian 48993746Sjulianvoid 49093746Sjulianas_where (char **namep, unsigned int *linep) 49193746Sjulian{ 49293746Sjulian if (logical_input_file != NULL 49393746Sjulian && (linep == NULL || logical_input_line >= 0)) 49495673Sphk { 49593746Sjulian *namep = logical_input_file; 49693746Sjulian if (linep != NULL) 49793746Sjulian *linep = logical_input_line; 49893746Sjulian } 49993746Sjulian else if (physical_input_file != NULL) 50093746Sjulian { 50193746Sjulian *namep = physical_input_file; 50293746Sjulian if (linep != NULL) 50393746Sjulian *linep = physical_input_line; 50493746Sjulian } 50593746Sjulian else 50693746Sjulian { 50793746Sjulian *namep = 0; 50893746Sjulian if (linep != NULL) 50993746Sjulian *linep = 0; 51093746Sjulian } 51193746Sjulian} 51293746Sjulian