input-file.c revision 130561
133965Sjdp/* input_file.c - Deal with Input Files - 2130561Sobrien Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 2003 360484Sobrien Free Software Foundation, Inc. 433965Sjdp 533965Sjdp This file is part of GAS, the GNU Assembler. 633965Sjdp 733965Sjdp GAS is free software; you can redistribute it and/or modify 833965Sjdp it under the terms of the GNU General Public License as published by 933965Sjdp the Free Software Foundation; either version 2, or (at your option) 1033965Sjdp any later version. 1133965Sjdp 1233965Sjdp GAS is distributed in the hope that it will be useful, 1333965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1433965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965Sjdp GNU General Public License for more details. 1633965Sjdp 1733965Sjdp You should have received a copy of the GNU General Public License 1860484Sobrien along with GAS; see the file COPYING. If not, write to the Free 1960484Sobrien Software Foundation, 59 Temple Place - Suite 330, Boston, MA 2060484Sobrien 02111-1307, USA. */ 2133965Sjdp 2289857Sobrien/* Confines all details of reading source bytes to this module. 2389857Sobrien All O/S specific crocks should live here. 2489857Sobrien What we lose in "efficiency" we gain in modularity. 2589857Sobrien Note we don't need to #include the "as.h" file. No common coupling! */ 2633965Sjdp 2733965Sjdp#include <stdio.h> 2833965Sjdp#include <string.h> 29130561Sobrien#include <errno.h> 3033965Sjdp#include "as.h" 3133965Sjdp#include "input-file.h" 3289857Sobrien#include "safe-ctype.h" 3333965Sjdp 34130561Sobrienstatic int input_file_get (char *, int); 3533965Sjdp 3633965Sjdp/* This variable is non-zero if the file currently being read should be 3789857Sobrien preprocessed by app. It is zero if the file can be read straight in. */ 3833965Sjdpint preprocess = 0; 3933965Sjdp 4089857Sobrien/* This code opens a file, then delivers BUFFER_SIZE character 4189857Sobrien chunks of the file on demand. 4289857Sobrien BUFFER_SIZE is supposed to be a number chosen for speed. 4389857Sobrien The caller only asks once what BUFFER_SIZE is, and asks before 4489857Sobrien the nature of the input files (if any) is known. */ 4533965Sjdp 4633965Sjdp#define BUFFER_SIZE (32 * 1024) 4733965Sjdp 4889857Sobrien/* We use static data: the data area is not sharable. */ 4933965Sjdp 5033965Sjdpstatic FILE *f_in; 5133965Sjdpstatic char *file_name; 5233965Sjdp 5333965Sjdp/* Struct for saving the state of this module for file includes. */ 5489857Sobrienstruct saved_file 5589857Sobrien { 5689857Sobrien FILE * f_in; 5789857Sobrien char * file_name; 5889857Sobrien int preprocess; 5989857Sobrien char * app_save; 6089857Sobrien }; 6133965Sjdp 62130561Sobrien/* These hooks accommodate most operating systems. */ 6333965Sjdp 6477298Sobrienvoid 65130561Sobrieninput_file_begin (void) 6633965Sjdp{ 6733965Sjdp f_in = (FILE *) 0; 6833965Sjdp} 6933965Sjdp 7077298Sobrienvoid 71130561Sobrieninput_file_end (void) 7233965Sjdp{ 7333965Sjdp} 7433965Sjdp 7577298Sobrien/* Return BUFFER_SIZE. */ 7677298Sobrienunsigned int 77130561Sobrieninput_file_buffer_size (void) 7833965Sjdp{ 7933965Sjdp return (BUFFER_SIZE); 8033965Sjdp} 8133965Sjdp 8277298Sobrienint 83130561Sobrieninput_file_is_open (void) 8433965Sjdp{ 8533965Sjdp return f_in != (FILE *) 0; 8633965Sjdp} 8733965Sjdp 8833965Sjdp/* Push the state of our input, returning a pointer to saved info that 8933965Sjdp can be restored with input_file_pop (). */ 9089857Sobrien 9133965Sjdpchar * 92130561Sobrieninput_file_push (void) 9333965Sjdp{ 9433965Sjdp register struct saved_file *saved; 9533965Sjdp 9633965Sjdp saved = (struct saved_file *) xmalloc (sizeof *saved); 9733965Sjdp 9833965Sjdp saved->f_in = f_in; 9933965Sjdp saved->file_name = file_name; 10033965Sjdp saved->preprocess = preprocess; 10133965Sjdp if (preprocess) 10233965Sjdp saved->app_save = app_push (); 10333965Sjdp 10489857Sobrien /* Initialize for new file. */ 10589857Sobrien input_file_begin (); 10633965Sjdp 10733965Sjdp return (char *) saved; 10833965Sjdp} 10933965Sjdp 11033965Sjdpvoid 111130561Sobrieninput_file_pop (char *arg) 11233965Sjdp{ 11333965Sjdp register struct saved_file *saved = (struct saved_file *) arg; 11433965Sjdp 11589857Sobrien input_file_end (); /* Close out old file. */ 11633965Sjdp 11733965Sjdp f_in = saved->f_in; 11833965Sjdp file_name = saved->file_name; 11933965Sjdp preprocess = saved->preprocess; 12033965Sjdp if (preprocess) 12133965Sjdp app_pop (saved->app_save); 12233965Sjdp 12333965Sjdp free (arg); 12433965Sjdp} 12533965Sjdp 12633965Sjdpvoid 127130561Sobrieninput_file_open (char *filename, /* "" means use stdin. Must not be 0. */ 128130561Sobrien int pre) 12933965Sjdp{ 13033965Sjdp int c; 13133965Sjdp char buf[80]; 13233965Sjdp 13333965Sjdp preprocess = pre; 13433965Sjdp 13577298Sobrien assert (filename != 0); /* Filename may not be NULL. */ 13633965Sjdp if (filename[0]) 137130561Sobrien { 13889857Sobrien f_in = fopen (filename, FOPEN_RT); 13933965Sjdp file_name = filename; 14033965Sjdp } 14133965Sjdp else 142130561Sobrien { 143130561Sobrien /* Use stdin for the input file. */ 14433965Sjdp f_in = stdin; 145130561Sobrien /* For error messages. */ 146130561Sobrien file_name = _("{standard input}"); 14733965Sjdp } 148130561Sobrien 149130561Sobrien if (f_in) 150130561Sobrien c = getc (f_in); 151130561Sobrien 152130561Sobrien if (f_in == NULL || ferror (f_in)) 15333965Sjdp { 154130561Sobrien#ifdef BFD_ASSEMBLER 155130561Sobrien bfd_set_error (bfd_error_system_call); 156130561Sobrien#endif 157130561Sobrien as_perror (_("Can't open %s for reading"), file_name); 158130561Sobrien 159130561Sobrien if (f_in) 160130561Sobrien { 161130561Sobrien fclose (f_in); 162130561Sobrien f_in = NULL; 163130561Sobrien } 16433965Sjdp return; 16533965Sjdp } 16633965Sjdp 16733965Sjdp if (c == '#') 16889857Sobrien { 16989857Sobrien /* Begins with comment, may not want to preprocess. */ 17033965Sjdp c = getc (f_in); 17133965Sjdp if (c == 'N') 172104834Sobrien { 173104834Sobrien fgets (buf, 80, f_in); 174104834Sobrien if (!strncmp (buf, "O_APP", 5) && ISSPACE (buf[5])) 175104834Sobrien preprocess = 0; 176104834Sobrien if (!strchr (buf, '\n')) 177104834Sobrien ungetc ('#', f_in); /* It was longer. */ 178104834Sobrien else 179104834Sobrien ungetc ('\n', f_in); 180104834Sobrien } 18189857Sobrien else if (c == 'A') 182104834Sobrien { 183104834Sobrien fgets (buf, 80, f_in); 184104834Sobrien if (!strncmp (buf, "PP", 2) && ISSPACE (buf[2])) 185104834Sobrien preprocess = 1; 186104834Sobrien if (!strchr (buf, '\n')) 187104834Sobrien ungetc ('#', f_in); 188104834Sobrien else 189104834Sobrien ungetc ('\n', f_in); 190104834Sobrien } 19133965Sjdp else if (c == '\n') 192104834Sobrien ungetc ('\n', f_in); 19333965Sjdp else 194104834Sobrien ungetc ('#', f_in); 19533965Sjdp } 19633965Sjdp else 19733965Sjdp ungetc (c, f_in); 19833965Sjdp} 19933965Sjdp 20033965Sjdp/* Close input file. */ 20189857Sobrien 20277298Sobrienvoid 203130561Sobrieninput_file_close (void) 20433965Sjdp{ 20589857Sobrien /* Don't close a null file pointer. */ 20633965Sjdp if (f_in != NULL) 20789857Sobrien fclose (f_in); 20889857Sobrien 20933965Sjdp f_in = 0; 21077298Sobrien} 21133965Sjdp 21233965Sjdp/* This function is passed to do_scrub_chars. */ 21333965Sjdp 21433965Sjdpstatic int 215130561Sobrieninput_file_get (char *buf, int buflen) 21633965Sjdp{ 21733965Sjdp int size; 21833965Sjdp 21960484Sobrien size = fread (buf, sizeof (char), buflen, f_in); 22033965Sjdp if (size < 0) 22133965Sjdp { 222130561Sobrien#ifdef BFD_ASSEMBLER 223130561Sobrien bfd_set_error (bfd_error_system_call); 224130561Sobrien#endif 22560484Sobrien as_perror (_("Can't read from %s"), file_name); 22633965Sjdp size = 0; 22733965Sjdp } 22833965Sjdp return size; 22933965Sjdp} 23033965Sjdp 23133965Sjdp/* Read a buffer from the input file. */ 23233965Sjdp 23333965Sjdpchar * 234130561Sobrieninput_file_give_next_buffer (char *where /* Where to place 1st character of new buffer. */) 23533965Sjdp{ 23677298Sobrien char *return_value; /* -> Last char of what we read, + 1. */ 23733965Sjdp register int size; 23833965Sjdp 23933965Sjdp if (f_in == (FILE *) 0) 24033965Sjdp return 0; 24189857Sobrien /* fflush (stdin); could be done here if you want to synchronise 24289857Sobrien stdin and stdout, for the case where our input file is stdin. 24389857Sobrien Since the assembler shouldn't do any output to stdout, we 24489857Sobrien don't bother to synch output and input. */ 24533965Sjdp if (preprocess) 24633965Sjdp size = do_scrub_chars (input_file_get, where, BUFFER_SIZE); 24733965Sjdp else 24833965Sjdp size = fread (where, sizeof (char), BUFFER_SIZE, f_in); 24933965Sjdp if (size < 0) 25033965Sjdp { 251130561Sobrien#ifdef BFD_ASSEMBLER 252130561Sobrien bfd_set_error (bfd_error_system_call); 253130561Sobrien#endif 25460484Sobrien as_perror (_("Can't read from %s"), file_name); 25533965Sjdp size = 0; 25633965Sjdp } 25733965Sjdp if (size) 25833965Sjdp return_value = where + size; 25933965Sjdp else 26033965Sjdp { 26133965Sjdp if (fclose (f_in)) 262130561Sobrien { 263130561Sobrien#ifdef BFD_ASSEMBLER 264130561Sobrien bfd_set_error (bfd_error_system_call); 265130561Sobrien#endif 266130561Sobrien as_perror (_("Can't close %s"), file_name); 267130561Sobrien } 26833965Sjdp f_in = (FILE *) 0; 26933965Sjdp return_value = 0; 27033965Sjdp } 27189857Sobrien 27289857Sobrien return return_value; 27333965Sjdp} 274