/* Input handling for G++.
   Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
   Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.

This file is part of GNU CC.

GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

/* G++ needs to do enough saving and re-parsing of text that it is
   necessary to abandon the simple FILE* model and use a mechanism where
   we can pre-empt one input stream with another derived from saved text;
   we may need to do this arbitrarily often, and cannot depend on having
   the GNU library available, so FILE objects just don't cut it.

   This file is written as a separate module, but can be included by
   lex.c for very minor efficiency gains (primarily in function
   inlining).  */

#include <stdio.h>

extern FILE *finput;

struct input_source {
  /* saved string */
  char *str;
  int length;
  /* current position, when reading as input */
  int offset;
  /* linked list maintenance */
  struct input_source *next;
  /* values to restore after reading all of current string */
  char *filename;
  int lineno;
  struct pending_input *input;
  int putback_char;
};

static struct input_source *input, *free_inputs;

extern char *input_filename;
extern int lineno;

#ifdef __GNUC__
#define inline __inline__
#else
#define inline
#endif

extern void feed_input PROTO((char *, int));
extern void put_input PROTO((int));
extern void put_back PROTO((int));
extern int getch PROTO((void));
extern int input_redirected PROTO((void));

static inline struct input_source * allocate_input PROTO((void));
static inline void free_input PROTO((struct input_source *));
static inline void end_input PROTO((void));
static inline int sub_getch PROTO((void));

static inline struct input_source *
allocate_input ()
{
  struct input_source *inp;
  if (free_inputs)
    {
      inp = free_inputs;
      free_inputs = inp->next;
      inp->next = 0;
      return inp;
    }
  inp = (struct input_source *) xmalloc (sizeof (struct input_source));
  inp->next = 0;
  return inp;
}

static inline void
free_input (inp)
     struct input_source *inp;
{
  inp->str = 0;
  inp->length = 0;
  inp->next = free_inputs;
  free_inputs = inp;
}

static int putback_char = -1;

/* Some of these external functions are declared inline in case this file
   is included in lex.c.  */

inline
void
feed_input (str, len)
     char *str;
     int len;
{
  struct input_source *inp = allocate_input ();

  /* This shouldn't be necessary.  */
  while (len && !str[len-1])
    len--;

  inp->str = str;
  inp->length = len;
  inp->offset = 0;
  inp->next = input;
  inp->filename = input_filename;
  inp->lineno = lineno;
  inp->input = save_pending_input ();
  inp->putback_char = putback_char;
  putback_char = -1;
  input = inp;
}

struct pending_input *to_be_restored; /* XXX */
extern int end_of_file;

static inline void
end_input ()
{
  struct input_source *inp = input;

  end_of_file = 0;
  input = inp->next;
  input_filename = inp->filename;
  lineno = inp->lineno;
  /* Get interface/implementation back in sync.  */
  extract_interface_info ();
  putback_char = inp->putback_char;
  restore_pending_input (inp->input);
  free_input (inp);
}

static inline int
sub_getch ()
{
  if (putback_char != -1)
    {
      int ch = putback_char;
      putback_char = -1;
      return ch;
    }
  if (input)
    {
      if (input->offset >= input->length)
	{
	  my_friendly_assert (putback_char == -1, 223);
	  ++(input->offset);
	  if (input->offset - input->length < 64)
	    return EOF;

	  /* We must be stuck in an error-handling rule; give up.  */
	  end_input ();
	  return getch ();
	}
      return (unsigned char)input->str[input->offset++];
    }
  return getc (finput);
}

inline
void
put_back (ch)
     int ch;
{
  if (ch != EOF)
    {
      my_friendly_assert (putback_char == -1, 224);
      putback_char = ch;
    }
}

extern int linemode;

int
getch ()
{
  int ch = sub_getch ();
  if (linemode && ch == '\n')
    {
      put_back (ch);
      ch = EOF;
    }
  return ch;
}

inline
int
input_redirected ()
{
  return input != 0;
}
