133965Sjdp/* input_scrub.c - Break up input buffers into whole numbers of lines. 278828Sobrien Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3218822Sdim 2000, 2001, 2003, 2006, 2007 433965Sjdp Free Software Foundation, Inc. 533965Sjdp 633965Sjdp This file is part of GAS, the GNU Assembler. 733965Sjdp 833965Sjdp GAS is free software; you can redistribute it and/or modify 933965Sjdp it under the terms of the GNU General Public License as published by 1033965Sjdp the Free Software Foundation; either version 2, or (at your option) 1133965Sjdp any later version. 1233965Sjdp 1333965Sjdp GAS is distributed in the hope that it will be useful, 1433965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1533965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1633965Sjdp GNU General Public License for more details. 1733965Sjdp 1833965Sjdp You should have received a copy of the GNU General Public License 1933965Sjdp along with GAS; see the file COPYING. If not, write to the Free 20218822Sdim Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 21218822Sdim 02110-1301, USA. */ 2233965Sjdp 2333965Sjdp#include "as.h" 2433965Sjdp#include "input-file.h" 2533965Sjdp#include "sb.h" 2660484Sobrien#include "listing.h" 2733965Sjdp 2833965Sjdp/* 2933965Sjdp * O/S independent module to supply buffers of sanitised source code 3033965Sjdp * to rest of assembler. We get sanitised input data of arbitrary length. 3133965Sjdp * We break these buffers on line boundaries, recombine pieces that 3233965Sjdp * were broken across buffers, and return a buffer of full lines to 3333965Sjdp * the caller. 3433965Sjdp * The last partial line begins the next buffer we build and return to caller. 35130561Sobrien * The buffer returned to caller is preceded by BEFORE_STRING and followed 3633965Sjdp * by AFTER_STRING, as sentinels. The last character before AFTER_STRING 3733965Sjdp * is a newline. 3833965Sjdp * Also looks after line numbers, for e.g. error messages. 3933965Sjdp */ 4033965Sjdp 4133965Sjdp/* 4233965Sjdp * We don't care how filthy our buffers are, but our callers assume 4333965Sjdp * that the following sanitation has already been done. 4433965Sjdp * 4533965Sjdp * No comments, reduce a comment to a space. 4633965Sjdp * Reduce a tab to a space unless it is 1st char of line. 4733965Sjdp * All multiple tabs and spaces collapsed into 1 char. Tab only 4833965Sjdp * legal if 1st char of line. 4933965Sjdp * # line file statements converted to .line x;.file y; statements. 5033965Sjdp * Escaped newlines at end of line: remove them but add as many newlines 5133965Sjdp * to end of statement as you removed in the middle, to synch line numbers. 5233965Sjdp */ 5333965Sjdp 5433965Sjdp#define BEFORE_STRING ("\n") 5577298Sobrien#define AFTER_STRING ("\0") /* memcpy of 0 chars might choke. */ 5633965Sjdp#define BEFORE_SIZE (1) 5733965Sjdp#define AFTER_SIZE (1) 5833965Sjdp 59218822Sdim#ifndef TC_EOL_IN_INSN 60218822Sdim#define TC_EOL_IN_INSN(P) 0 61218822Sdim#endif 62218822Sdim 6377298Sobrienstatic char *buffer_start; /*->1st char of full buffer area. */ 6477298Sobrienstatic char *partial_where; /*->after last full line in buffer. */ 6577298Sobrienstatic int partial_size; /* >=0. Number of chars in partial line in buffer. */ 6677298Sobrien 6777298Sobrien/* Because we need AFTER_STRING just after last full line, it clobbers 6877298Sobrien 1st part of partial line. So we preserve 1st part of partial line 6977298Sobrien here. */ 7033965Sjdpstatic char save_source[AFTER_SIZE]; 7133965Sjdp 7277298Sobrien/* What is the largest size buffer that input_file_give_next_buffer() 7377298Sobrien could return to us? */ 7477298Sobrienstatic unsigned int buffer_length; 7577298Sobrien 7633965Sjdp/* The index into an sb structure we are reading from. -1 if none. */ 7733965Sjdpstatic int sb_index = -1; 7833965Sjdp 7933965Sjdp/* If we are reading from an sb structure, this is it. */ 8033965Sjdpstatic sb from_sb; 8133965Sjdp 8260484Sobrien/* Should we do a conditional check on from_sb? */ 8360484Sobrienstatic int from_sb_is_expansion = 1; 8460484Sobrien 8533965Sjdp/* The number of nested sb structures we have included. */ 8633965Sjdpint macro_nest; 8733965Sjdp 8833965Sjdp/* We can have more than one source file open at once, though the info for all 8933965Sjdp but the latest one are saved off in a struct input_save. These files remain 9033965Sjdp open, so we are limited by the number of open files allowed by the 9133965Sjdp underlying OS. We may also sequentially read more than one source file in an 9277298Sobrien assembly. */ 9333965Sjdp 9433965Sjdp/* We must track the physical file and line number for error messages. We also 9533965Sjdp track a "logical" file and line number corresponding to (C?) compiler 9633965Sjdp source line numbers. Whenever we open a file we must fill in 9777298Sobrien physical_input_file. So if it is NULL we have not opened any files yet. */ 9833965Sjdp 9933965Sjdpstatic char *physical_input_file; 10033965Sjdpstatic char *logical_input_file; 10133965Sjdp 10277298Sobrientypedef unsigned int line_numberT; /* 1-origin line number in a source file. */ 10377298Sobrien/* A line ends in '\n' or eof. */ 10433965Sjdp 10533965Sjdpstatic line_numberT physical_input_line; 10633965Sjdpstatic int logical_input_line; 10733965Sjdp 10833965Sjdp/* Struct used to save the state of the input handler during include files */ 10977298Sobrienstruct input_save { 11077298Sobrien char * buffer_start; 11177298Sobrien char * partial_where; 11277298Sobrien int partial_size; 11377298Sobrien char save_source[AFTER_SIZE]; 11477298Sobrien unsigned int buffer_length; 11577298Sobrien char * physical_input_file; 11677298Sobrien char * logical_input_file; 11777298Sobrien line_numberT physical_input_line; 11877298Sobrien int logical_input_line; 11977298Sobrien int sb_index; 12077298Sobrien sb from_sb; 12177298Sobrien int from_sb_is_expansion; /* Should we do a conditional check? */ 12277298Sobrien struct input_save * next_saved_file; /* Chain of input_saves. */ 12377298Sobrien char * input_file_save; /* Saved state of input routines. */ 12477298Sobrien char * saved_position; /* Caller's saved position in buf. */ 12577298Sobrien}; 12633965Sjdp 127130561Sobrienstatic struct input_save *input_scrub_push (char *saved_position); 128130561Sobrienstatic char *input_scrub_pop (struct input_save *arg); 12933965Sjdp 13033965Sjdp/* Saved information about the file that .include'd this one. When we hit EOF, 13177298Sobrien we automatically pop to that file. */ 13233965Sjdp 13333965Sjdpstatic struct input_save *next_saved_file; 13433965Sjdp 13533965Sjdp/* Push the state of input reading and scrubbing so that we can #include. 13633965Sjdp The return value is a 'void *' (fudged for old compilers) to a save 13777298Sobrien area, which can be restored by passing it to input_scrub_pop(). */ 13877298Sobrien 13933965Sjdpstatic struct input_save * 140130561Sobrieninput_scrub_push (char *saved_position) 14133965Sjdp{ 14233965Sjdp register struct input_save *saved; 14333965Sjdp 14433965Sjdp saved = (struct input_save *) xmalloc (sizeof *saved); 14533965Sjdp 14633965Sjdp saved->saved_position = saved_position; 14733965Sjdp saved->buffer_start = buffer_start; 14833965Sjdp saved->partial_where = partial_where; 14933965Sjdp saved->partial_size = partial_size; 15033965Sjdp saved->buffer_length = buffer_length; 15133965Sjdp saved->physical_input_file = physical_input_file; 15233965Sjdp saved->logical_input_file = logical_input_file; 15333965Sjdp saved->physical_input_line = physical_input_line; 15433965Sjdp saved->logical_input_line = logical_input_line; 15533965Sjdp saved->sb_index = sb_index; 15633965Sjdp saved->from_sb = from_sb; 15760484Sobrien saved->from_sb_is_expansion = from_sb_is_expansion; 15833965Sjdp memcpy (saved->save_source, save_source, sizeof (save_source)); 15933965Sjdp saved->next_saved_file = next_saved_file; 16033965Sjdp saved->input_file_save = input_file_push (); 16133965Sjdp 16233965Sjdp input_file_begin (); /* Reinitialize! */ 16333965Sjdp logical_input_line = -1; 16433965Sjdp logical_input_file = (char *) NULL; 16533965Sjdp buffer_length = input_file_buffer_size (); 16633965Sjdp sb_index = -1; 16733965Sjdp 16833965Sjdp buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); 16933965Sjdp memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); 17033965Sjdp 17133965Sjdp return saved; 17277298Sobrien} 17333965Sjdp 17433965Sjdpstatic char * 175130561Sobrieninput_scrub_pop (struct input_save *saved) 17633965Sjdp{ 17733965Sjdp char *saved_position; 17833965Sjdp 17933965Sjdp input_scrub_end (); /* Finish off old buffer */ 18033965Sjdp 18133965Sjdp input_file_pop (saved->input_file_save); 18233965Sjdp saved_position = saved->saved_position; 18333965Sjdp buffer_start = saved->buffer_start; 18433965Sjdp buffer_length = saved->buffer_length; 18533965Sjdp physical_input_file = saved->physical_input_file; 18633965Sjdp logical_input_file = saved->logical_input_file; 18733965Sjdp physical_input_line = saved->physical_input_line; 18833965Sjdp logical_input_line = saved->logical_input_line; 18933965Sjdp sb_index = saved->sb_index; 19033965Sjdp from_sb = saved->from_sb; 19160484Sobrien from_sb_is_expansion = saved->from_sb_is_expansion; 19233965Sjdp partial_where = saved->partial_where; 19333965Sjdp partial_size = saved->partial_size; 19433965Sjdp next_saved_file = saved->next_saved_file; 19533965Sjdp memcpy (save_source, saved->save_source, sizeof (save_source)); 19633965Sjdp 19733965Sjdp free (saved); 19833965Sjdp return saved_position; 19933965Sjdp} 20033965Sjdp 20133965Sjdpvoid 202130561Sobrieninput_scrub_begin (void) 20333965Sjdp{ 20433965Sjdp know (strlen (BEFORE_STRING) == BEFORE_SIZE); 20577298Sobrien know (strlen (AFTER_STRING) == AFTER_SIZE 20677298Sobrien || (AFTER_STRING[0] == '\0' && AFTER_SIZE == 1)); 20733965Sjdp 20833965Sjdp input_file_begin (); 20933965Sjdp 21033965Sjdp buffer_length = input_file_buffer_size (); 21133965Sjdp 21233965Sjdp buffer_start = xmalloc ((BEFORE_SIZE + buffer_length + buffer_length + AFTER_SIZE)); 21333965Sjdp memcpy (buffer_start, BEFORE_STRING, (int) BEFORE_SIZE); 21433965Sjdp 21577298Sobrien /* Line number things. */ 21633965Sjdp logical_input_line = -1; 21733965Sjdp logical_input_file = (char *) NULL; 21877298Sobrien physical_input_file = NULL; /* No file read yet. */ 21933965Sjdp next_saved_file = NULL; /* At EOF, don't pop to any other file */ 22033965Sjdp do_scrub_begin (flag_m68k_mri); 22133965Sjdp} 22233965Sjdp 22333965Sjdpvoid 224130561Sobrieninput_scrub_end (void) 22533965Sjdp{ 22633965Sjdp if (buffer_start) 22733965Sjdp { 22833965Sjdp free (buffer_start); 22933965Sjdp buffer_start = 0; 23033965Sjdp input_file_end (); 23133965Sjdp } 23233965Sjdp} 23333965Sjdp 23477298Sobrien/* Start reading input from a new file. 23577298Sobrien Return start of caller's part of buffer. */ 23633965Sjdp 23777298Sobrienchar * 238130561Sobrieninput_scrub_new_file (char *filename) 23933965Sjdp{ 24033965Sjdp input_file_open (filename, !flag_no_comments); 24160484Sobrien physical_input_file = filename[0] ? filename : _("{standard input}"); 24233965Sjdp physical_input_line = 0; 24333965Sjdp 24433965Sjdp partial_size = 0; 24533965Sjdp return (buffer_start + BEFORE_SIZE); 24633965Sjdp} 24733965Sjdp 24833965Sjdp/* Include a file from the current file. Save our state, cause it to 24933965Sjdp be restored on EOF, and begin handling a new file. Same result as 25077298Sobrien input_scrub_new_file. */ 25133965Sjdp 25233965Sjdpchar * 253130561Sobrieninput_scrub_include_file (char *filename, char *position) 25433965Sjdp{ 25533965Sjdp next_saved_file = input_scrub_push (position); 25633965Sjdp return input_scrub_new_file (filename); 25733965Sjdp} 25833965Sjdp 25933965Sjdp/* Start getting input from an sb structure. This is used when 26033965Sjdp expanding a macro. */ 26133965Sjdp 26233965Sjdpvoid 263130561Sobrieninput_scrub_include_sb (sb *from, char *position, int is_expansion) 26433965Sjdp{ 26533965Sjdp if (macro_nest > max_macro_nest) 26677298Sobrien as_fatal (_("macros nested too deeply")); 26733965Sjdp ++macro_nest; 26833965Sjdp 26960484Sobrien#ifdef md_macro_start 27060484Sobrien if (is_expansion) 27160484Sobrien { 27260484Sobrien md_macro_start (); 27360484Sobrien } 27460484Sobrien#endif 27560484Sobrien 27633965Sjdp next_saved_file = input_scrub_push (position); 27733965Sjdp 27833965Sjdp sb_new (&from_sb); 27960484Sobrien from_sb_is_expansion = is_expansion; 28038889Sjdp if (from->len >= 1 && from->ptr[0] != '\n') 28138889Sjdp { 28238889Sjdp /* Add the sentinel required by read.c. */ 28338889Sjdp sb_add_char (&from_sb, '\n'); 28438889Sjdp } 285218822Sdim sb_scrub_and_add_sb (&from_sb, from); 28633965Sjdp sb_index = 1; 28733965Sjdp 28833965Sjdp /* These variables are reset by input_scrub_push. Restore them 28933965Sjdp since we are, after all, still at the same point in the file. */ 29033965Sjdp logical_input_line = next_saved_file->logical_input_line; 29133965Sjdp logical_input_file = next_saved_file->logical_input_file; 29233965Sjdp} 29333965Sjdp 29433965Sjdpvoid 295130561Sobrieninput_scrub_close (void) 29633965Sjdp{ 29733965Sjdp input_file_close (); 29833965Sjdp} 29933965Sjdp 30033965Sjdpchar * 301130561Sobrieninput_scrub_next_buffer (char **bufp) 30233965Sjdp{ 30377298Sobrien register char *limit; /*->just after last char of buffer. */ 30433965Sjdp 30533965Sjdp if (sb_index >= 0) 30633965Sjdp { 30733965Sjdp if (sb_index >= from_sb.len) 30833965Sjdp { 30933965Sjdp sb_kill (&from_sb); 31077298Sobrien if (from_sb_is_expansion 31177298Sobrien ) 31277298Sobrien { 31377298Sobrien cond_finish_check (macro_nest); 31460484Sobrien#ifdef md_macro_end 31577298Sobrien /* Allow the target to clean up per-macro expansion 31677298Sobrien data. */ 31777298Sobrien md_macro_end (); 31860484Sobrien#endif 31977298Sobrien } 32077298Sobrien --macro_nest; 32133965Sjdp partial_where = NULL; 32233965Sjdp if (next_saved_file != NULL) 32333965Sjdp *bufp = input_scrub_pop (next_saved_file); 32433965Sjdp return partial_where; 32533965Sjdp } 32633965Sjdp 32733965Sjdp partial_where = from_sb.ptr + from_sb.len; 32833965Sjdp partial_size = 0; 32933965Sjdp *bufp = from_sb.ptr + sb_index; 33033965Sjdp sb_index = from_sb.len; 33133965Sjdp return partial_where; 33233965Sjdp } 33333965Sjdp 33433965Sjdp *bufp = buffer_start + BEFORE_SIZE; 33533965Sjdp 33633965Sjdp if (partial_size) 33733965Sjdp { 338276228Spfg memmove (buffer_start + BEFORE_SIZE, partial_where, 33933965Sjdp (unsigned int) partial_size); 34033965Sjdp memcpy (buffer_start + BEFORE_SIZE, save_source, AFTER_SIZE); 34133965Sjdp } 34233965Sjdp limit = input_file_give_next_buffer (buffer_start 34333965Sjdp + BEFORE_SIZE 34433965Sjdp + partial_size); 34533965Sjdp if (limit) 34633965Sjdp { 34777298Sobrien register char *p; /* Find last newline. */ 348218822Sdim /* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */ 349218822Sdim *limit = '\0'; 350218822Sdim for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p) 35133965Sjdp ; 35233965Sjdp ++p; 35333965Sjdp 35433965Sjdp while (p <= buffer_start + BEFORE_SIZE) 35533965Sjdp { 35633965Sjdp int limoff; 35733965Sjdp 35833965Sjdp limoff = limit - buffer_start; 35933965Sjdp buffer_length += input_file_buffer_size (); 36033965Sjdp buffer_start = xrealloc (buffer_start, 36133965Sjdp (BEFORE_SIZE 36233965Sjdp + 2 * buffer_length 36333965Sjdp + AFTER_SIZE)); 36433965Sjdp *bufp = buffer_start + BEFORE_SIZE; 36533965Sjdp limit = input_file_give_next_buffer (buffer_start + limoff); 36633965Sjdp 36733965Sjdp if (limit == NULL) 36833965Sjdp { 36960484Sobrien as_warn (_("partial line at end of file ignored")); 37033965Sjdp partial_where = NULL; 37133965Sjdp if (next_saved_file) 37233965Sjdp *bufp = input_scrub_pop (next_saved_file); 37333965Sjdp return NULL; 37433965Sjdp } 37533965Sjdp 376218822Sdim /* Terminate the buffer to avoid confusing TC_EOL_IN_INSN. */ 377218822Sdim *limit = '\0'; 378218822Sdim for (p = limit - 1; *p != '\n' || TC_EOL_IN_INSN (p); --p) 37933965Sjdp ; 38033965Sjdp ++p; 38133965Sjdp } 38233965Sjdp 38333965Sjdp partial_where = p; 38433965Sjdp partial_size = limit - p; 38533965Sjdp memcpy (save_source, partial_where, (int) AFTER_SIZE); 38633965Sjdp memcpy (partial_where, AFTER_STRING, (int) AFTER_SIZE); 38733965Sjdp } 38833965Sjdp else 38933965Sjdp { 39033965Sjdp partial_where = 0; 39133965Sjdp if (partial_size > 0) 39233965Sjdp { 39389857Sobrien as_warn (_("partial line at end of file ignored")); 39433965Sjdp } 39560484Sobrien 39660484Sobrien /* Tell the listing we've finished the file. */ 39760484Sobrien LISTING_EOF (); 39860484Sobrien 39977298Sobrien /* If we should pop to another file at EOF, do it. */ 40033965Sjdp if (next_saved_file) 40133965Sjdp { 40233965Sjdp *bufp = input_scrub_pop (next_saved_file); /* Pop state */ 40377298Sobrien /* partial_where is now correct to return, since we popped it. */ 40433965Sjdp } 40533965Sjdp } 40633965Sjdp return (partial_where); 40777298Sobrien} 40833965Sjdp 40977298Sobrien/* The remaining part of this file deals with line numbers, error 41077298Sobrien messages and so on. Return TRUE if we opened any file. */ 41133965Sjdp 41233965Sjdpint 413130561Sobrienseen_at_least_1_file (void) 41433965Sjdp{ 41533965Sjdp return (physical_input_file != NULL); 41633965Sjdp} 41733965Sjdp 41833965Sjdpvoid 419130561Sobrienbump_line_counters (void) 42033965Sjdp{ 42133965Sjdp if (sb_index < 0) 42233965Sjdp { 42333965Sjdp ++physical_input_line; 42433965Sjdp if (logical_input_line >= 0) 42533965Sjdp ++logical_input_line; 42633965Sjdp } 42733965Sjdp} 42833965Sjdp 42977298Sobrien/* Tells us what the new logical line number and file are. 43077298Sobrien If the line_number is -1, we don't change the current logical line 43177298Sobrien number. If it is -2, we decrement the logical line number (this is 43277298Sobrien to support the .appfile pseudo-op inserted into the stream by 43377298Sobrien do_scrub_chars). 43477298Sobrien If the fname is NULL, we don't change the current logical file name. 43577298Sobrien Returns nonzero if the filename actually changes. */ 43677298Sobrien 43738889Sjdpint 438218822Sdimnew_logical_line_flags (char *fname, /* DON'T destroy it! We point to it! */ 439218822Sdim int line_number, 440218822Sdim int flags) 44133965Sjdp{ 442218822Sdim switch (flags) 443218822Sdim { 444218822Sdim case 0: 445218822Sdim break; 446218822Sdim case 1: 447218822Sdim if (line_number != -1) 448218822Sdim abort (); 449218822Sdim break; 450218822Sdim case 1 << 1: 451218822Sdim case 1 << 2: 452218822Sdim /* FIXME: we could check that include nesting is correct. */ 453218822Sdim break; 454218822Sdim default: 455218822Sdim abort (); 456218822Sdim } 457218822Sdim 45833965Sjdp if (line_number >= 0) 45933965Sjdp logical_input_line = line_number; 460218822Sdim else if (line_number == -1 && fname && !*fname && (flags & (1 << 2))) 461218822Sdim { 462218822Sdim logical_input_file = physical_input_file; 463218822Sdim logical_input_line = physical_input_line; 464218822Sdim fname = NULL; 465218822Sdim } 46638889Sjdp 46738889Sjdp if (fname 46838889Sjdp && (logical_input_file == NULL 46938889Sjdp || strcmp (logical_input_file, fname))) 47038889Sjdp { 47138889Sjdp logical_input_file = fname; 47238889Sjdp return 1; 47338889Sjdp } 47438889Sjdp else 47538889Sjdp return 0; 47677298Sobrien} 477218822Sdim 478218822Sdimint 479218822Sdimnew_logical_line (char *fname, int line_number) 480218822Sdim{ 481218822Sdim return new_logical_line_flags (fname, line_number, 0); 482218822Sdim} 483218822Sdim 48433965Sjdp 48577298Sobrien/* Return the current file name and line number. 48677298Sobrien namep should be char * const *, but there are compilers which screw 48777298Sobrien up declarations like that, and it's easier to avoid it. */ 48877298Sobrien 48977298Sobrienvoid 490130561Sobrienas_where (char **namep, unsigned int *linep) 49133965Sjdp{ 49233965Sjdp if (logical_input_file != NULL 49333965Sjdp && (linep == NULL || logical_input_line >= 0)) 49433965Sjdp { 49533965Sjdp *namep = logical_input_file; 49633965Sjdp if (linep != NULL) 49733965Sjdp *linep = logical_input_line; 49833965Sjdp } 49933965Sjdp else if (physical_input_file != NULL) 50033965Sjdp { 50133965Sjdp *namep = physical_input_file; 50233965Sjdp if (linep != NULL) 50333965Sjdp *linep = physical_input_line; 50433965Sjdp } 50533965Sjdp else 50633965Sjdp { 50733965Sjdp *namep = 0; 50833965Sjdp if (linep != NULL) 50933965Sjdp *linep = 0; 51033965Sjdp } 51177298Sobrien} 512