input-file.c revision 60484
133965Sjdp/* input_file.c - Deal with Input Files - 260484Sobrien Copyright (C) 1987, 90, 91, 92, 93, 94, 95, 98, 1999 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 2233965Sjdp/* 2333965Sjdp * Confines all details of reading source bytes to this module. 2433965Sjdp * All O/S specific crocks should live here. 2533965Sjdp * What we lose in "efficiency" we gain in modularity. 2633965Sjdp * Note we don't need to #include the "as.h" file. No common coupling! 2733965Sjdp */ 2833965Sjdp 2933965Sjdp#include <stdio.h> 3033965Sjdp#include <string.h> 3133965Sjdp 3233965Sjdp#include "as.h" 3333965Sjdp#include "input-file.h" 3433965Sjdp 3560484Sobrienstatic int input_file_get PARAMS ((char *, int)); 3633965Sjdp 3733965Sjdp/* This variable is non-zero if the file currently being read should be 3833965Sjdp preprocessed by app. It is zero if the file can be read straight in. 3933965Sjdp */ 4033965Sjdpint preprocess = 0; 4133965Sjdp 4233965Sjdp/* 4333965Sjdp * This code opens a file, then delivers BUFFER_SIZE character 4433965Sjdp * chunks of the file on demand. 4533965Sjdp * BUFFER_SIZE is supposed to be a number chosen for speed. 4633965Sjdp * The caller only asks once what BUFFER_SIZE is, and asks before 4733965Sjdp * the nature of the input files (if any) is known. 4833965Sjdp */ 4933965Sjdp 5033965Sjdp#define BUFFER_SIZE (32 * 1024) 5133965Sjdp 5233965Sjdp/* 5333965Sjdp * We use static data: the data area is not sharable. 5433965Sjdp */ 5533965Sjdp 5633965Sjdpstatic FILE *f_in; 5733965Sjdpstatic char *file_name; 5833965Sjdp 5933965Sjdp/* Struct for saving the state of this module for file includes. */ 6033965Sjdpstruct saved_file 6133965Sjdp { 6233965Sjdp FILE *f_in; 6333965Sjdp char *file_name; 6433965Sjdp int preprocess; 6533965Sjdp char *app_save; 6633965Sjdp }; 6733965Sjdp 6833965Sjdp/* These hooks accomodate most operating systems. */ 6933965Sjdp 7033965Sjdpvoid 7133965Sjdpinput_file_begin () 7233965Sjdp{ 7333965Sjdp f_in = (FILE *) 0; 7433965Sjdp} 7533965Sjdp 7633965Sjdpvoid 7733965Sjdpinput_file_end () 7833965Sjdp{ 7933965Sjdp} 8033965Sjdp 8133965Sjdp/* Return BUFFER_SIZE. */ 8233965Sjdpunsigned int 8333965Sjdpinput_file_buffer_size () 8433965Sjdp{ 8533965Sjdp return (BUFFER_SIZE); 8633965Sjdp} 8733965Sjdp 8833965Sjdpint 8933965Sjdpinput_file_is_open () 9033965Sjdp{ 9133965Sjdp return f_in != (FILE *) 0; 9233965Sjdp} 9333965Sjdp 9433965Sjdp/* Push the state of our input, returning a pointer to saved info that 9533965Sjdp can be restored with input_file_pop (). */ 9633965Sjdpchar * 9733965Sjdpinput_file_push () 9833965Sjdp{ 9933965Sjdp register struct saved_file *saved; 10033965Sjdp 10133965Sjdp saved = (struct saved_file *) xmalloc (sizeof *saved); 10233965Sjdp 10333965Sjdp saved->f_in = f_in; 10433965Sjdp saved->file_name = file_name; 10533965Sjdp saved->preprocess = preprocess; 10633965Sjdp if (preprocess) 10733965Sjdp saved->app_save = app_push (); 10833965Sjdp 10933965Sjdp input_file_begin (); /* Initialize for new file */ 11033965Sjdp 11133965Sjdp return (char *) saved; 11233965Sjdp} 11333965Sjdp 11433965Sjdpvoid 11533965Sjdpinput_file_pop (arg) 11633965Sjdp char *arg; 11733965Sjdp{ 11833965Sjdp register struct saved_file *saved = (struct saved_file *) arg; 11933965Sjdp 12033965Sjdp input_file_end (); /* Close out old file */ 12133965Sjdp 12233965Sjdp f_in = saved->f_in; 12333965Sjdp file_name = saved->file_name; 12433965Sjdp preprocess = saved->preprocess; 12533965Sjdp if (preprocess) 12633965Sjdp app_pop (saved->app_save); 12733965Sjdp 12833965Sjdp free (arg); 12933965Sjdp} 13033965Sjdp 13133965Sjdpvoid 13233965Sjdpinput_file_open (filename, pre) 13333965Sjdp char *filename; /* "" means use stdin. Must not be 0. */ 13433965Sjdp int pre; 13533965Sjdp{ 13633965Sjdp int c; 13733965Sjdp char buf[80]; 13833965Sjdp 13933965Sjdp preprocess = pre; 14033965Sjdp 14133965Sjdp assert (filename != 0); /* Filename may not be NULL. */ 14233965Sjdp if (filename[0]) 14333965Sjdp { /* We have a file name. Suck it and see. */ 14433965Sjdp f_in = fopen (filename, "r"); 14533965Sjdp file_name = filename; 14633965Sjdp } 14733965Sjdp else 14833965Sjdp { /* use stdin for the input file. */ 14933965Sjdp f_in = stdin; 15060484Sobrien file_name = _("{standard input}"); /* For error messages. */ 15133965Sjdp } 15233965Sjdp if (f_in == (FILE *) 0) 15333965Sjdp { 15460484Sobrien as_bad (_("Can't open %s for reading."), file_name); 15533965Sjdp as_perror ("%s", file_name); 15633965Sjdp return; 15733965Sjdp } 15833965Sjdp 15933965Sjdp c = getc (f_in); 16033965Sjdp if (c == '#') 16133965Sjdp { /* Begins with comment, may not want to preprocess */ 16233965Sjdp c = getc (f_in); 16333965Sjdp if (c == 'N') 16433965Sjdp { 16533965Sjdp fgets (buf, 80, f_in); 16633965Sjdp if (!strcmp (buf, "O_APP\n")) 16733965Sjdp preprocess = 0; 16833965Sjdp if (!strchr (buf, '\n')) 16933965Sjdp ungetc ('#', f_in); /* It was longer */ 17033965Sjdp else 17133965Sjdp ungetc ('\n', f_in); 17233965Sjdp } 17333965Sjdp else if (c == '\n') 17433965Sjdp ungetc ('\n', f_in); 17533965Sjdp else 17633965Sjdp ungetc ('#', f_in); 17733965Sjdp } 17833965Sjdp else 17933965Sjdp ungetc (c, f_in); 18033965Sjdp} 18133965Sjdp 18233965Sjdp/* Close input file. */ 18333965Sjdpvoid 18433965Sjdpinput_file_close () 18533965Sjdp{ 18633965Sjdp if (f_in != NULL) 18733965Sjdp { 18833965Sjdp fclose (f_in); 18933965Sjdp } /* don't close a null file pointer */ 19033965Sjdp f_in = 0; 19133965Sjdp} /* input_file_close() */ 19233965Sjdp 19333965Sjdp/* This function is passed to do_scrub_chars. */ 19433965Sjdp 19533965Sjdpstatic int 19660484Sobrieninput_file_get (buf, buflen) 19760484Sobrien char *buf; 19860484Sobrien int buflen; 19933965Sjdp{ 20033965Sjdp int size; 20133965Sjdp 20260484Sobrien size = fread (buf, sizeof (char), buflen, f_in); 20333965Sjdp if (size < 0) 20433965Sjdp { 20560484Sobrien as_perror (_("Can't read from %s"), file_name); 20633965Sjdp size = 0; 20733965Sjdp } 20833965Sjdp return size; 20933965Sjdp} 21033965Sjdp 21133965Sjdp/* Read a buffer from the input file. */ 21233965Sjdp 21333965Sjdpchar * 21433965Sjdpinput_file_give_next_buffer (where) 21533965Sjdp char *where; /* Where to place 1st character of new buffer. */ 21633965Sjdp{ 21733965Sjdp char *return_value; /* -> Last char of what we read, + 1. */ 21833965Sjdp register int size; 21933965Sjdp 22033965Sjdp if (f_in == (FILE *) 0) 22133965Sjdp return 0; 22233965Sjdp /* 22333965Sjdp * fflush (stdin); could be done here if you want to synchronise 22433965Sjdp * stdin and stdout, for the case where our input file is stdin. 22533965Sjdp * Since the assembler shouldn't do any output to stdout, we 22633965Sjdp * don't bother to synch output and input. 22733965Sjdp */ 22833965Sjdp if (preprocess) 22933965Sjdp size = do_scrub_chars (input_file_get, where, BUFFER_SIZE); 23033965Sjdp else 23133965Sjdp size = fread (where, sizeof (char), BUFFER_SIZE, f_in); 23233965Sjdp if (size < 0) 23333965Sjdp { 23460484Sobrien as_perror (_("Can't read from %s"), file_name); 23533965Sjdp size = 0; 23633965Sjdp } 23733965Sjdp if (size) 23833965Sjdp return_value = where + size; 23933965Sjdp else 24033965Sjdp { 24133965Sjdp if (fclose (f_in)) 24260484Sobrien as_perror (_("Can't close %s"), file_name); 24333965Sjdp f_in = (FILE *) 0; 24433965Sjdp return_value = 0; 24533965Sjdp } 24633965Sjdp return (return_value); 24733965Sjdp} 24833965Sjdp 24933965Sjdp/* end of input-file.c */ 250