133965Sjdp/* input_file.c - Deal with Input Files - 2218822Sdim Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001, 3218822Sdim 2002, 2003, 2005, 2006 460484Sobrien 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 1960484Sobrien 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 2389857Sobrien/* Confines all details of reading source bytes to this module. 2489857Sobrien All O/S specific crocks should live here. 2589857Sobrien What we lose in "efficiency" we gain in modularity. 2689857Sobrien Note we don't need to #include the "as.h" file. No common coupling! */ 2733965Sjdp 2833965Sjdp#include "as.h" 2933965Sjdp#include "input-file.h" 3089857Sobrien#include "safe-ctype.h" 3133965Sjdp 32130561Sobrienstatic int input_file_get (char *, int); 3333965Sjdp 3433965Sjdp/* This variable is non-zero if the file currently being read should be 3589857Sobrien preprocessed by app. It is zero if the file can be read straight in. */ 3633965Sjdpint preprocess = 0; 3733965Sjdp 3889857Sobrien/* This code opens a file, then delivers BUFFER_SIZE character 3989857Sobrien chunks of the file on demand. 4089857Sobrien BUFFER_SIZE is supposed to be a number chosen for speed. 4189857Sobrien The caller only asks once what BUFFER_SIZE is, and asks before 4289857Sobrien the nature of the input files (if any) is known. */ 4333965Sjdp 4433965Sjdp#define BUFFER_SIZE (32 * 1024) 4533965Sjdp 4689857Sobrien/* We use static data: the data area is not sharable. */ 4733965Sjdp 4833965Sjdpstatic FILE *f_in; 4933965Sjdpstatic char *file_name; 5033965Sjdp 5133965Sjdp/* Struct for saving the state of this module for file includes. */ 5289857Sobrienstruct saved_file 5389857Sobrien { 5489857Sobrien FILE * f_in; 5589857Sobrien char * file_name; 5689857Sobrien int preprocess; 5789857Sobrien char * app_save; 5889857Sobrien }; 5933965Sjdp 60130561Sobrien/* These hooks accommodate most operating systems. */ 6133965Sjdp 6277298Sobrienvoid 63130561Sobrieninput_file_begin (void) 6433965Sjdp{ 6533965Sjdp f_in = (FILE *) 0; 6633965Sjdp} 6733965Sjdp 6877298Sobrienvoid 69130561Sobrieninput_file_end (void) 7033965Sjdp{ 7133965Sjdp} 7233965Sjdp 7377298Sobrien/* Return BUFFER_SIZE. */ 7477298Sobrienunsigned int 75130561Sobrieninput_file_buffer_size (void) 7633965Sjdp{ 7733965Sjdp return (BUFFER_SIZE); 7833965Sjdp} 7933965Sjdp 8033965Sjdp/* Push the state of our input, returning a pointer to saved info that 8133965Sjdp can be restored with input_file_pop (). */ 8289857Sobrien 8333965Sjdpchar * 84130561Sobrieninput_file_push (void) 8533965Sjdp{ 8633965Sjdp register struct saved_file *saved; 8733965Sjdp 8833965Sjdp saved = (struct saved_file *) xmalloc (sizeof *saved); 8933965Sjdp 9033965Sjdp saved->f_in = f_in; 9133965Sjdp saved->file_name = file_name; 9233965Sjdp saved->preprocess = preprocess; 9333965Sjdp if (preprocess) 9433965Sjdp saved->app_save = app_push (); 9533965Sjdp 9689857Sobrien /* Initialize for new file. */ 9789857Sobrien input_file_begin (); 9833965Sjdp 9933965Sjdp return (char *) saved; 10033965Sjdp} 10133965Sjdp 10233965Sjdpvoid 103130561Sobrieninput_file_pop (char *arg) 10433965Sjdp{ 10533965Sjdp register struct saved_file *saved = (struct saved_file *) arg; 10633965Sjdp 10789857Sobrien input_file_end (); /* Close out old file. */ 10833965Sjdp 10933965Sjdp f_in = saved->f_in; 11033965Sjdp file_name = saved->file_name; 11133965Sjdp preprocess = saved->preprocess; 11233965Sjdp if (preprocess) 11333965Sjdp app_pop (saved->app_save); 11433965Sjdp 11533965Sjdp free (arg); 11633965Sjdp} 11733965Sjdp 11833965Sjdpvoid 119130561Sobrieninput_file_open (char *filename, /* "" means use stdin. Must not be 0. */ 120130561Sobrien int pre) 12133965Sjdp{ 12233965Sjdp int c; 12333965Sjdp char buf[80]; 12433965Sjdp 12533965Sjdp preprocess = pre; 12633965Sjdp 12777298Sobrien assert (filename != 0); /* Filename may not be NULL. */ 12833965Sjdp if (filename[0]) 129130561Sobrien { 13089857Sobrien f_in = fopen (filename, FOPEN_RT); 13133965Sjdp file_name = filename; 13233965Sjdp } 13333965Sjdp else 134130561Sobrien { 135130561Sobrien /* Use stdin for the input file. */ 13633965Sjdp f_in = stdin; 137130561Sobrien /* For error messages. */ 138130561Sobrien file_name = _("{standard input}"); 13933965Sjdp } 140130561Sobrien 141218822Sdim if (f_in == NULL) 142218822Sdim { 143218822Sdim as_bad (_("can't open %s for reading: %s"), 144218822Sdim file_name, xstrerror (errno)); 145218822Sdim return; 146218822Sdim } 147130561Sobrien 148218822Sdim c = getc (f_in); 149218822Sdim 150218822Sdim if (ferror (f_in)) 15133965Sjdp { 152218822Sdim as_bad (_("can't read from %s: %s"), 153218822Sdim file_name, xstrerror (errno)); 154130561Sobrien 155218822Sdim fclose (f_in); 156218822Sdim f_in = NULL; 15733965Sjdp return; 15833965Sjdp } 15933965Sjdp 16033965Sjdp if (c == '#') 16189857Sobrien { 16289857Sobrien /* Begins with comment, may not want to preprocess. */ 16333965Sjdp c = getc (f_in); 16433965Sjdp if (c == 'N') 165104834Sobrien { 166218822Sdim if (fgets (buf, sizeof (buf), f_in) 167218822Sdim && !strncmp (buf, "O_APP", 5) && ISSPACE (buf[5])) 168104834Sobrien preprocess = 0; 169104834Sobrien if (!strchr (buf, '\n')) 170104834Sobrien ungetc ('#', f_in); /* It was longer. */ 171104834Sobrien else 172104834Sobrien ungetc ('\n', f_in); 173104834Sobrien } 17489857Sobrien else if (c == 'A') 175104834Sobrien { 176218822Sdim if (fgets (buf, sizeof (buf), f_in) 177218822Sdim && !strncmp (buf, "PP", 2) && ISSPACE (buf[2])) 178104834Sobrien preprocess = 1; 179104834Sobrien if (!strchr (buf, '\n')) 180104834Sobrien ungetc ('#', f_in); 181104834Sobrien else 182104834Sobrien ungetc ('\n', f_in); 183104834Sobrien } 18433965Sjdp else if (c == '\n') 185104834Sobrien ungetc ('\n', f_in); 18633965Sjdp else 187104834Sobrien ungetc ('#', f_in); 18833965Sjdp } 18933965Sjdp else 19033965Sjdp ungetc (c, f_in); 19133965Sjdp} 19233965Sjdp 19333965Sjdp/* Close input file. */ 19489857Sobrien 19577298Sobrienvoid 196130561Sobrieninput_file_close (void) 19733965Sjdp{ 19889857Sobrien /* Don't close a null file pointer. */ 19933965Sjdp if (f_in != NULL) 20089857Sobrien fclose (f_in); 20189857Sobrien 20233965Sjdp f_in = 0; 20377298Sobrien} 20433965Sjdp 20533965Sjdp/* This function is passed to do_scrub_chars. */ 20633965Sjdp 20733965Sjdpstatic int 208130561Sobrieninput_file_get (char *buf, int buflen) 20933965Sjdp{ 21033965Sjdp int size; 21133965Sjdp 21260484Sobrien size = fread (buf, sizeof (char), buflen, f_in); 21333965Sjdp if (size < 0) 21433965Sjdp { 215218822Sdim as_bad (_("can't read from %s: %s"), file_name, xstrerror (errno)); 21633965Sjdp size = 0; 21733965Sjdp } 21833965Sjdp return size; 21933965Sjdp} 22033965Sjdp 22133965Sjdp/* Read a buffer from the input file. */ 22233965Sjdp 22333965Sjdpchar * 224130561Sobrieninput_file_give_next_buffer (char *where /* Where to place 1st character of new buffer. */) 22533965Sjdp{ 22677298Sobrien char *return_value; /* -> Last char of what we read, + 1. */ 22733965Sjdp register int size; 22833965Sjdp 22933965Sjdp if (f_in == (FILE *) 0) 23033965Sjdp return 0; 23189857Sobrien /* fflush (stdin); could be done here if you want to synchronise 23289857Sobrien stdin and stdout, for the case where our input file is stdin. 23389857Sobrien Since the assembler shouldn't do any output to stdout, we 23489857Sobrien don't bother to synch output and input. */ 23533965Sjdp if (preprocess) 23633965Sjdp size = do_scrub_chars (input_file_get, where, BUFFER_SIZE); 23733965Sjdp else 23833965Sjdp size = fread (where, sizeof (char), BUFFER_SIZE, f_in); 23933965Sjdp if (size < 0) 24033965Sjdp { 241218822Sdim as_bad (_("can't read from %s: %s"), file_name, xstrerror (errno)); 24233965Sjdp size = 0; 24333965Sjdp } 24433965Sjdp if (size) 24533965Sjdp return_value = where + size; 24633965Sjdp else 24733965Sjdp { 24833965Sjdp if (fclose (f_in)) 249218822Sdim as_warn (_("can't close %s: %s"), file_name, xstrerror (errno)); 250218822Sdim 25133965Sjdp f_in = (FILE *) 0; 25233965Sjdp return_value = 0; 25333965Sjdp } 25489857Sobrien 25589857Sobrien return return_value; 25633965Sjdp} 257