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