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