input-file.c revision 89857
133965Sjdp/* input_file.c - Deal with Input Files - 289857Sobrien Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2000, 2001 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> 2933965Sjdp#include "as.h" 3033965Sjdp#include "input-file.h" 3189857Sobrien#include "safe-ctype.h" 3233965Sjdp 3360484Sobrienstatic int input_file_get PARAMS ((char *, int)); 3433965Sjdp 3533965Sjdp/* This variable is non-zero if the file currently being read should be 3689857Sobrien preprocessed by app. It is zero if the file can be read straight in. */ 3733965Sjdpint preprocess = 0; 3833965Sjdp 3989857Sobrien/* This code opens a file, then delivers BUFFER_SIZE character 4089857Sobrien chunks of the file on demand. 4189857Sobrien BUFFER_SIZE is supposed to be a number chosen for speed. 4289857Sobrien The caller only asks once what BUFFER_SIZE is, and asks before 4389857Sobrien the nature of the input files (if any) is known. */ 4433965Sjdp 4533965Sjdp#define BUFFER_SIZE (32 * 1024) 4633965Sjdp 4789857Sobrien/* We use static data: the data area is not sharable. */ 4833965Sjdp 4933965Sjdpstatic FILE *f_in; 5033965Sjdpstatic char *file_name; 5133965Sjdp 5233965Sjdp/* Struct for saving the state of this module for file includes. */ 5389857Sobrienstruct saved_file 5489857Sobrien { 5589857Sobrien FILE * f_in; 5689857Sobrien char * file_name; 5789857Sobrien int preprocess; 5889857Sobrien char * app_save; 5989857Sobrien }; 6033965Sjdp 6177298Sobrien/* These hooks accomodate most operating systems. */ 6233965Sjdp 6377298Sobrienvoid 6433965Sjdpinput_file_begin () 6533965Sjdp{ 6633965Sjdp f_in = (FILE *) 0; 6733965Sjdp} 6833965Sjdp 6977298Sobrienvoid 7033965Sjdpinput_file_end () 7133965Sjdp{ 7233965Sjdp} 7333965Sjdp 7477298Sobrien/* Return BUFFER_SIZE. */ 7577298Sobrienunsigned int 7633965Sjdpinput_file_buffer_size () 7733965Sjdp{ 7833965Sjdp return (BUFFER_SIZE); 7933965Sjdp} 8033965Sjdp 8177298Sobrienint 8233965Sjdpinput_file_is_open () 8333965Sjdp{ 8433965Sjdp return f_in != (FILE *) 0; 8533965Sjdp} 8633965Sjdp 8733965Sjdp/* Push the state of our input, returning a pointer to saved info that 8833965Sjdp can be restored with input_file_pop (). */ 8989857Sobrien 9033965Sjdpchar * 9133965Sjdpinput_file_push () 9233965Sjdp{ 9333965Sjdp register struct saved_file *saved; 9433965Sjdp 9533965Sjdp saved = (struct saved_file *) xmalloc (sizeof *saved); 9633965Sjdp 9733965Sjdp saved->f_in = f_in; 9833965Sjdp saved->file_name = file_name; 9933965Sjdp saved->preprocess = preprocess; 10033965Sjdp if (preprocess) 10133965Sjdp saved->app_save = app_push (); 10233965Sjdp 10389857Sobrien /* Initialize for new file. */ 10489857Sobrien input_file_begin (); 10533965Sjdp 10633965Sjdp return (char *) saved; 10733965Sjdp} 10833965Sjdp 10933965Sjdpvoid 11033965Sjdpinput_file_pop (arg) 11133965Sjdp 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 12733965Sjdpinput_file_open (filename, pre) 12877298Sobrien char *filename; /* "" means use stdin. Must not be 0. */ 12933965Sjdp int pre; 13033965Sjdp{ 13133965Sjdp int c; 13233965Sjdp char buf[80]; 13333965Sjdp 13433965Sjdp preprocess = pre; 13533965Sjdp 13677298Sobrien assert (filename != 0); /* Filename may not be NULL. */ 13733965Sjdp if (filename[0]) 13877298Sobrien { /* We have a file name. Suck it and see. */ 13989857Sobrien f_in = fopen (filename, FOPEN_RT); 14033965Sjdp file_name = filename; 14133965Sjdp } 14233965Sjdp else 14377298Sobrien { /* use stdin for the input file. */ 14433965Sjdp f_in = stdin; 14577298Sobrien file_name = _("{standard input}"); /* For error messages. */ 14633965Sjdp } 14733965Sjdp if (f_in == (FILE *) 0) 14833965Sjdp { 14989857Sobrien as_bad (_("can't open %s for reading"), file_name); 15033965Sjdp as_perror ("%s", file_name); 15133965Sjdp return; 15233965Sjdp } 15333965Sjdp 15433965Sjdp c = getc (f_in); 15533965Sjdp if (c == '#') 15689857Sobrien { 15789857Sobrien /* Begins with comment, may not want to preprocess. */ 15833965Sjdp c = getc (f_in); 15933965Sjdp if (c == 'N') 16089857Sobrien { 16189857Sobrien fgets (buf, 80, f_in); 16289857Sobrien if (!strncmp (buf, "O_APP", 5) && ISSPACE (buf[5])) 16389857Sobrien preprocess = 0; 16489857Sobrien if (!strchr (buf, '\n')) 16589857Sobrien ungetc ('#', f_in); /* It was longer. */ 16689857Sobrien else 16789857Sobrien ungetc ('\n', f_in); 16889857Sobrien } 16989857Sobrien else if (c == 'A') 17089857Sobrien { 17189857Sobrien fgets (buf, 80, f_in); 17289857Sobrien if (!strncmp (buf, "PP", 2) && ISSPACE (buf[2])) 17389857Sobrien preprocess = 1; 17489857Sobrien if (!strchr (buf, '\n')) 17589857Sobrien ungetc ('#', f_in); 17689857Sobrien else 17789857Sobrien ungetc ('\n', f_in); 17889857Sobrien } 17933965Sjdp else if (c == '\n') 18089857Sobrien ungetc ('\n', f_in); 18133965Sjdp else 18289857Sobrien ungetc ('#', f_in); 18333965Sjdp } 18433965Sjdp else 18533965Sjdp ungetc (c, f_in); 18633965Sjdp} 18733965Sjdp 18833965Sjdp/* Close input file. */ 18989857Sobrien 19077298Sobrienvoid 19133965Sjdpinput_file_close () 19233965Sjdp{ 19389857Sobrien /* Don't close a null file pointer. */ 19433965Sjdp if (f_in != NULL) 19589857Sobrien fclose (f_in); 19689857Sobrien 19733965Sjdp f_in = 0; 19877298Sobrien} 19933965Sjdp 20033965Sjdp/* This function is passed to do_scrub_chars. */ 20133965Sjdp 20233965Sjdpstatic int 20360484Sobrieninput_file_get (buf, buflen) 20460484Sobrien char *buf; 20560484Sobrien int buflen; 20633965Sjdp{ 20733965Sjdp int size; 20833965Sjdp 20960484Sobrien size = fread (buf, sizeof (char), buflen, f_in); 21033965Sjdp if (size < 0) 21133965Sjdp { 21260484Sobrien as_perror (_("Can't read from %s"), file_name); 21333965Sjdp size = 0; 21433965Sjdp } 21533965Sjdp return size; 21633965Sjdp} 21733965Sjdp 21833965Sjdp/* Read a buffer from the input file. */ 21933965Sjdp 22033965Sjdpchar * 22133965Sjdpinput_file_give_next_buffer (where) 22277298Sobrien char *where; /* Where to place 1st character of new buffer. */ 22333965Sjdp{ 22477298Sobrien char *return_value; /* -> Last char of what we read, + 1. */ 22533965Sjdp register int size; 22633965Sjdp 22733965Sjdp if (f_in == (FILE *) 0) 22833965Sjdp return 0; 22989857Sobrien /* fflush (stdin); could be done here if you want to synchronise 23089857Sobrien stdin and stdout, for the case where our input file is stdin. 23189857Sobrien Since the assembler shouldn't do any output to stdout, we 23289857Sobrien don't bother to synch output and input. */ 23333965Sjdp if (preprocess) 23433965Sjdp size = do_scrub_chars (input_file_get, where, BUFFER_SIZE); 23533965Sjdp else 23633965Sjdp size = fread (where, sizeof (char), BUFFER_SIZE, f_in); 23733965Sjdp if (size < 0) 23833965Sjdp { 23960484Sobrien as_perror (_("Can't read from %s"), file_name); 24033965Sjdp size = 0; 24133965Sjdp } 24233965Sjdp if (size) 24333965Sjdp return_value = where + size; 24433965Sjdp else 24533965Sjdp { 24633965Sjdp if (fclose (f_in)) 24760484Sobrien as_perror (_("Can't close %s"), file_name); 24833965Sjdp f_in = (FILE *) 0; 24933965Sjdp return_value = 0; 25033965Sjdp } 25189857Sobrien 25289857Sobrien return return_value; 25333965Sjdp} 254