input-file.c revision 60484
133965Sjdp/* input_file.c - Deal with Input Files - 233965Sjdp Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 98, 1999 3218822Sdim Free Software Foundation, Inc. 433965Sjdp 5218822Sdim This file is part of GAS, the GNU Assembler. 633965Sjdp 733965Sjdp GAS is free software; you can redistribute it and/or modify 8218822Sdim it under the terms of the GNU General Public License as published by 9218822Sdim the Free Software Foundation; either version 2, or (at your option) 10218822Sdim any later version. 1133965Sjdp 12218822Sdim GAS is distributed in the hope that it will be useful, 13218822Sdim but WITHOUT ANY WARRANTY; without even the implied warranty of 14218822Sdim MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15218822Sdim GNU General Public License for more details. 16218822Sdim 17218822Sdim You should have received a copy of the GNU General Public License 18218822Sdim along with GAS; see the file COPYING. If not, write to the Free 19218822Sdim Software Foundation, 59 Temple Place - Suite 330, Boston, MA 20218822Sdim 02111-1307, USA. */ 21218822Sdim 22218822Sdim/* 23218822Sdim * Confines all details of reading source bytes to this module. 24218822Sdim * All O/S specific crocks should live here. 25218822Sdim * What we lose in "efficiency" we gain in modularity. 26218822Sdim * Note we don't need to #include the "as.h" file. No common coupling! 27218822Sdim */ 28218822Sdim 29218822Sdim#include <stdio.h> 30218822Sdim#include <string.h> 31218822Sdim 32218822Sdim#include "as.h" 33218822Sdim#include "input-file.h" 34218822Sdim 35218822Sdimstatic int input_file_get PARAMS ((char *, int)); 36218822Sdim 37218822Sdim/* This variable is non-zero if the file currently being read should be 38218822Sdim preprocessed by app. It is zero if the file can be read straight in. 39218822Sdim */ 40218822Sdimint preprocess = 0; 41218822Sdim 42218822Sdim/* 43218822Sdim * This code opens a file, then delivers BUFFER_SIZE character 44218822Sdim * chunks of the file on demand. 45218822Sdim * BUFFER_SIZE is supposed to be a number chosen for speed. 46218822Sdim * The caller only asks once what BUFFER_SIZE is, and asks before 47218822Sdim * the nature of the input files (if any) is known. 48218822Sdim */ 49218822Sdim 50218822Sdim#define BUFFER_SIZE (32 * 1024) 51218822Sdim 52218822Sdim/* 53218822Sdim * We use static data: the data area is not sharable. 54218822Sdim */ 55218822Sdim 56218822Sdimstatic FILE *f_in; 57218822Sdimstatic char *file_name; 58218822Sdim 59218822Sdim/* Struct for saving the state of this module for file includes. */ 60218822Sdimstruct saved_file 61218822Sdim { 62218822Sdim FILE *f_in; 63218822Sdim char *file_name; 64218822Sdim int preprocess; 65218822Sdim char *app_save; 66218822Sdim }; 67218822Sdim 68218822Sdim/* These hooks accomodate most operating systems. */ 69218822Sdim 70218822Sdimvoid 71218822Sdiminput_file_begin () 72218822Sdim{ 73218822Sdim f_in = (FILE *) 0; 74218822Sdim} 75218822Sdim 76218822Sdimvoid 77218822Sdiminput_file_end () 78218822Sdim{ 79218822Sdim} 80218822Sdim 81218822Sdim/* Return BUFFER_SIZE. */ 82218822Sdimunsigned int 83218822Sdiminput_file_buffer_size () 84218822Sdim{ 85218822Sdim return (BUFFER_SIZE); 86218822Sdim} 87218822Sdim 88218822Sdimint 89218822Sdiminput_file_is_open () 90218822Sdim{ 91218822Sdim return f_in != (FILE *) 0; 92218822Sdim} 93218822Sdim 94218822Sdim/* Push the state of our input, returning a pointer to saved info that 95218822Sdim can be restored with input_file_pop (). */ 96218822Sdimchar * 97218822Sdiminput_file_push () 98218822Sdim{ 99218822Sdim register struct saved_file *saved; 100218822Sdim 101218822Sdim saved = (struct saved_file *) xmalloc (sizeof *saved); 102218822Sdim 103218822Sdim saved->f_in = f_in; 104218822Sdim saved->file_name = file_name; 105218822Sdim saved->preprocess = preprocess; 106218822Sdim if (preprocess) 107218822Sdim saved->app_save = app_push (); 108218822Sdim 109218822Sdim input_file_begin (); /* Initialize for new file */ 110218822Sdim 111218822Sdim return (char *) saved; 112218822Sdim} 113218822Sdim 114218822Sdimvoid 115218822Sdiminput_file_pop (arg) 116218822Sdim char *arg; 117218822Sdim{ 118218822Sdim register struct saved_file *saved = (struct saved_file *) arg; 119218822Sdim 120218822Sdim input_file_end (); /* Close out old file */ 121218822Sdim 122218822Sdim f_in = saved->f_in; 123218822Sdim file_name = saved->file_name; 124218822Sdim preprocess = saved->preprocess; 125218822Sdim if (preprocess) 126218822Sdim app_pop (saved->app_save); 127218822Sdim 128218822Sdim free (arg); 129218822Sdim} 130218822Sdim 131218822Sdimvoid 132218822Sdiminput_file_open (filename, pre) 133218822Sdim char *filename; /* "" means use stdin. Must not be 0. */ 134218822Sdim int pre; 135218822Sdim{ 136218822Sdim int c; 137218822Sdim char buf[80]; 138218822Sdim 139218822Sdim preprocess = pre; 140218822Sdim 141218822Sdim assert (filename != 0); /* Filename may not be NULL. */ 142218822Sdim if (filename[0]) 143218822Sdim { /* We have a file name. Suck it and see. */ 144218822Sdim f_in = fopen (filename, "r"); 145218822Sdim file_name = filename; 146218822Sdim } 147218822Sdim else 148218822Sdim { /* use stdin for the input file. */ 149218822Sdim f_in = stdin; 150218822Sdim file_name = _("{standard input}"); /* For error messages. */ 151218822Sdim } 152218822Sdim if (f_in == (FILE *) 0) 153218822Sdim { 154218822Sdim as_bad (_("Can't open %s for reading."), file_name); 155218822Sdim as_perror ("%s", file_name); 156218822Sdim return; 157218822Sdim } 158218822Sdim 159218822Sdim c = getc (f_in); 160218822Sdim if (c == '#') 161218822Sdim { /* Begins with comment, may not want to preprocess */ 162218822Sdim c = getc (f_in); 163218822Sdim if (c == 'N') 164218822Sdim { 165218822Sdim fgets (buf, 80, f_in); 166218822Sdim if (!strcmp (buf, "O_APP\n")) 167218822Sdim preprocess = 0; 168218822Sdim if (!strchr (buf, '\n')) 169218822Sdim ungetc ('#', f_in); /* It was longer */ 170218822Sdim else 171218822Sdim ungetc ('\n', f_in); 172218822Sdim } 173218822Sdim else if (c == '\n') 174218822Sdim ungetc ('\n', f_in); 175218822Sdim else 176218822Sdim ungetc ('#', f_in); 177218822Sdim } 178218822Sdim else 179218822Sdim ungetc (c, f_in); 180218822Sdim} 181218822Sdim 182218822Sdim/* Close input file. */ 183218822Sdimvoid 184218822Sdiminput_file_close () 185218822Sdim{ 186218822Sdim if (f_in != NULL) 187218822Sdim { 188218822Sdim fclose (f_in); 189218822Sdim } /* don't close a null file pointer */ 190218822Sdim f_in = 0; 191218822Sdim} /* input_file_close() */ 192218822Sdim 193218822Sdim/* This function is passed to do_scrub_chars. */ 194218822Sdim 195218822Sdimstatic int 196218822Sdiminput_file_get (buf, buflen) 197218822Sdim char *buf; 198218822Sdim int buflen; 199218822Sdim{ 200218822Sdim int size; 201218822Sdim 202218822Sdim size = fread (buf, sizeof (char), buflen, f_in); 203218822Sdim if (size < 0) 204218822Sdim { 205218822Sdim as_perror (_("Can't read from %s"), file_name); 206218822Sdim size = 0; 207218822Sdim } 208218822Sdim return size; 209218822Sdim} 210218822Sdim 211218822Sdim/* Read a buffer from the input file. */ 212218822Sdim 213218822Sdimchar * 214218822Sdiminput_file_give_next_buffer (where) 215218822Sdim char *where; /* Where to place 1st character of new buffer. */ 216218822Sdim{ 217218822Sdim char *return_value; /* -> Last char of what we read, + 1. */ 218218822Sdim register int size; 219218822Sdim 220218822Sdim if (f_in == (FILE *) 0) 221218822Sdim return 0; 222218822Sdim /* 223218822Sdim * fflush (stdin); could be done here if you want to synchronise 224218822Sdim * stdin and stdout, for the case where our input file is stdin. 225218822Sdim * Since the assembler shouldn't do any output to stdout, we 226218822Sdim * don't bother to synch output and input. 227218822Sdim */ 228218822Sdim if (preprocess) 229218822Sdim size = do_scrub_chars (input_file_get, where, BUFFER_SIZE); 230218822Sdim else 231218822Sdim size = fread (where, sizeof (char), BUFFER_SIZE, f_in); 232218822Sdim if (size < 0) 233218822Sdim { 234218822Sdim as_perror (_("Can't read from %s"), file_name); 235218822Sdim size = 0; 236218822Sdim } 237218822Sdim if (size) 238218822Sdim return_value = where + size; 239218822Sdim else 240218822Sdim { 241218822Sdim if (fclose (f_in)) 242218822Sdim as_perror (_("Can't close %s"), file_name); 243218822Sdim f_in = (FILE *) 0; 244218822Sdim return_value = 0; 245218822Sdim } 246218822Sdim return (return_value); 247218822Sdim} 248218822Sdim 249218822Sdim/* end of input-file.c */ 250218822Sdim