/* MD reader for GCC.
   Copyright (C) 1987-2018 Free Software Foundation, Inc.

This file is part of GCC.

GCC 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 3, or (at your option) any later
version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* This file is compiled twice: once for the generator programs
   once for the compiler.  */
#ifdef GENERATOR_FILE
#include "bconfig.h"
#else
#include "config.h"
#endif
#include "system.h"
#include "coretypes.h"
#ifdef GENERATOR_FILE
#include "errors.h"
#endif /* #ifdef GENERATOR_FILE */
#include "statistics.h"
#include "vec.h"
#include "read-md.h"

#ifndef GENERATOR_FILE

/* Minimal reimplementation of errors.c for use by RTL frontend
   within cc1.  */

int have_error = 0;

#endif /* #ifndef GENERATOR_FILE */


/* Associates PTR (which can be a string, etc.) with the file location
   specified by FILENAME and LINENO.  */
struct ptr_loc {
  const void *ptr;
  const char *filename;
  int lineno;
};

/* This callback will be invoked whenever an md include directive is
   processed.  To be used for creation of the dependency file.  */
void (*include_callback) (const char *);

/* Global singleton.  */

md_reader *md_reader_ptr;

/* Given an object that starts with a char * name field, return a hash
   code for its name.  */

hashval_t
leading_string_hash (const void *def)
{
  return htab_hash_string (*(const char *const *) def);
}

/* Given two objects that start with char * name fields, return true if
   they have the same name.  */

int
leading_string_eq_p (const void *def1, const void *def2)
{
  return strcmp (*(const char *const *) def1,
		 *(const char *const *) def2) == 0;
}

/* Return a hash value for the pointer pointed to by DEF.  */

static hashval_t
leading_ptr_hash (const void *def)
{
  return htab_hash_pointer (*(const void *const *) def);
}

/* Return true if DEF1 and DEF2 are pointers to the same pointer.  */

static int
leading_ptr_eq_p (const void *def1, const void *def2)
{
  return *(const void *const *) def1 == *(const void *const *) def2;
}

/* Associate PTR with the file position given by FILENAME and LINENO.  */

void
md_reader::set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
{
  struct ptr_loc *loc;

  loc = (struct ptr_loc *) obstack_alloc (&m_ptr_loc_obstack,
					  sizeof (struct ptr_loc));
  loc->ptr = ptr;
  loc->filename = filename;
  loc->lineno = lineno;
  *htab_find_slot (m_ptr_locs, loc, INSERT) = loc;
}

/* Return the position associated with pointer PTR.  Return null if no
   position was set.  */

const struct ptr_loc *
md_reader::get_md_ptr_loc (const void *ptr)
{
  return (const struct ptr_loc *) htab_find (m_ptr_locs, &ptr);
}

/* Associate NEW_PTR with the same file position as OLD_PTR.  */

void
md_reader::copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
{
  const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
  if (loc != 0)
    set_md_ptr_loc (new_ptr, loc->filename, loc->lineno);
}

/* If PTR is associated with a known file position, print a #line
   directive for it to OUTF.  */

void
md_reader::fprint_md_ptr_loc (FILE *outf, const void *ptr)
{
  const struct ptr_loc *loc = get_md_ptr_loc (ptr);
  if (loc != 0)
    fprintf (outf, "#line %d \"%s\"\n", loc->lineno, loc->filename);
}

/* Special fprint_md_ptr_loc for writing to STDOUT.  */
void
md_reader::print_md_ptr_loc (const void *ptr)
{
  fprint_md_ptr_loc (stdout, ptr);
}

/* Return a condition that satisfies both COND1 and COND2.  Either string
   may be null or empty.  */

const char *
md_reader::join_c_conditions (const char *cond1, const char *cond2)
{
  char *result;
  const void **entry;

  if (cond1 == 0 || cond1[0] == 0)
    return cond2;

  if (cond2 == 0 || cond2[0] == 0)
    return cond1;

  if (strcmp (cond1, cond2) == 0)
    return cond1;

  result = concat ("(", cond1, ") && (", cond2, ")", NULL);
  obstack_ptr_grow (&m_joined_conditions_obstack, result);
  obstack_ptr_grow (&m_joined_conditions_obstack, cond1);
  obstack_ptr_grow (&m_joined_conditions_obstack, cond2);
  entry = XOBFINISH (&m_joined_conditions_obstack, const void **);
  *htab_find_slot (m_joined_conditions, entry, INSERT) = entry;
  return result;
}

/* Print condition COND to OUTF, wrapped in brackets.  If COND was created
   by join_c_conditions, recursively invoke this function for the original
   conditions and join the result with "&&".  Otherwise print a #line
   directive for COND if its original file position is known.  */

void
md_reader::fprint_c_condition (FILE *outf, const char *cond)
{
  const char **halves = (const char **) htab_find (m_joined_conditions, &cond);
  if (halves != 0)
    {
      fprintf (outf, "(");
      fprint_c_condition (outf, halves[1]);
      fprintf (outf, " && ");
      fprint_c_condition (outf, halves[2]);
      fprintf (outf, ")");
    }
  else
    {
      fputc ('\n', outf);
      fprint_md_ptr_loc (outf, cond);
      fprintf (outf, "(%s)", cond);
    }
}

/* Special fprint_c_condition for writing to STDOUT.  */

void
md_reader::print_c_condition (const char *cond)
{
  fprint_c_condition (stdout, cond);
}

/* A vfprintf-like function for reporting an error against line LINENO
   of the current MD file.  */

static void ATTRIBUTE_PRINTF(2,0)
message_at_1 (file_location loc, const char *msg, va_list ap)
{
  fprintf (stderr, "%s:%d:%d: ", loc.filename, loc.lineno, loc.colno);
  vfprintf (stderr, msg, ap);
  fputc ('\n', stderr);
}

/* A printf-like function for reporting a message against location LOC.  */

void
message_at (file_location loc, const char *msg, ...)
{
  va_list ap;

  va_start (ap, msg);
  message_at_1 (loc, msg, ap);
  va_end (ap);
}

/* Like message_at, but treat the condition as an error.  */

void
error_at (file_location loc, const char *msg, ...)
{
  va_list ap;

  va_start (ap, msg);
  message_at_1 (loc, msg, ap);
  va_end (ap);
  have_error = 1;
}

/* Like message_at, but treat the condition as a fatal error.  */

void
fatal_at (file_location loc, const char *msg, ...)
{
  va_list ap;

  va_start (ap, msg);
  message_at_1 (loc, msg, ap);
  va_end (ap);
  exit (1);
}

/* A printf-like function for reporting an error against the current
   position in the MD file.  */

void
fatal_with_file_and_line (const char *msg, ...)
{
  char context[64];
  size_t i;
  int c;
  va_list ap;

  va_start (ap, msg);

  fprintf (stderr, "%s:%d:%d: error: ", md_reader_ptr->get_filename (),
	   md_reader_ptr->get_lineno (),
	   md_reader_ptr->get_colno ());
  vfprintf (stderr, msg, ap);
  putc ('\n', stderr);

  /* Gather some following context.  */
  for (i = 0; i < sizeof (context)-1; ++i)
    {
      c = read_char ();
      if (c == EOF)
	break;
      if (c == '\r' || c == '\n')
	{
	  unread_char (c);
	  break;
	}
      context[i] = c;
    }
  context[i] = '\0';

  fprintf (stderr, "%s:%d:%d: note: following context is `%s'\n",
	   md_reader_ptr->get_filename (),
	   md_reader_ptr->get_lineno (),
	   md_reader_ptr->get_colno (), context);

  va_end (ap);
  exit (1);
}

/* Report that we found character ACTUAL when we expected to find
   character EXPECTED.  */

void
fatal_expected_char (int expected, int actual)
{
  if (actual == EOF)
    fatal_with_file_and_line ("expected character `%c', found EOF",
			      expected);
  else
    fatal_with_file_and_line ("expected character `%c', found `%c'",
			      expected, actual);
}

/* Read chars from the MD file until a non-whitespace char and return that.
   Comments, both Lisp style and C style, are treated as whitespace.  */

int
read_skip_spaces (void)
{
  int c;

  while (1)
    {
      c = read_char ();
      switch (c)
	{
	case ' ': case '\t': case '\f': case '\r': case '\n':
	  break;

	case ';':
	  do
	    c = read_char ();
	  while (c != '\n' && c != EOF);
	  break;

	case '/':
	  {
	    int prevc;
	    c = read_char ();
	    if (c != '*')
	      {
		unread_char (c);
		fatal_with_file_and_line ("stray '/' in file");
	      }

	    prevc = 0;
	    while ((c = read_char ()) && c != EOF)
	      {
		if (prevc == '*' && c == '/')
		  break;
	        prevc = c;
	      }
	  }
	  break;

	default:
	  return c;
	}
    }
}

/* Consume the next character, issuing a fatal error if it is not
   EXPECTED.  */

void
md_reader::require_char (char expected)
{
  int ch = read_char ();
  if (ch != expected)
    fatal_expected_char (expected, ch);
}

/* Consume any whitespace, then consume the next non-whitespace
   character, issuing a fatal error if it is not EXPECTED.  */

void
md_reader::require_char_ws (char expected)
{
  int ch = read_skip_spaces ();
  if (ch != expected)
    fatal_expected_char (expected, ch);
}

/* Consume any whitespace, then consume the next word (as per read_name),
   issuing a fatal error if it is not EXPECTED.  */

void
md_reader::require_word_ws (const char *expected)
{
  struct md_name name;
  read_name (&name);
  if (strcmp (name.string, expected))
    fatal_with_file_and_line ("missing '%s'", expected);
}

/* Read the next character from the file.  */

int
md_reader::read_char (void)
{
  int ch;

  ch = getc (m_read_md_file);
  if (ch == '\n')
    {
      m_read_md_lineno++;
      m_last_line_colno = m_read_md_colno;
      m_read_md_colno = 0;
    }
  else
    m_read_md_colno++;

  /* If we're filtering lines, treat everything before the range of
     interest as a space, and as EOF for everything after.  */
  if (m_first_line && m_last_line)
    {
      if (m_read_md_lineno < m_first_line)
	return ' ';
      if (m_read_md_lineno > m_last_line)
	return EOF;
    }

  return ch;
}

/* Put back CH, which was the last character read from the file.  */

void
md_reader::unread_char (int ch)
{
  if (ch == '\n')
    {
      m_read_md_lineno--;
      m_read_md_colno = m_last_line_colno;
    }
  else
    m_read_md_colno--;
  ungetc (ch, m_read_md_file);
}

/* Peek at the next character from the file without consuming it.  */

int
md_reader::peek_char (void)
{
  int ch = read_char ();
  unread_char (ch);
  return ch;
}

/* Read an rtx code name into NAME.  It is terminated by any of the
   punctuation chars of rtx printed syntax.  */

bool
md_reader::read_name_1 (struct md_name *name, file_location *out_loc)
{
  int c;
  size_t i;
  int angle_bracket_depth;

  c = read_skip_spaces ();

  *out_loc = get_current_location ();

  i = 0;
  angle_bracket_depth = 0;
  while (1)
    {
      if (c == '<')
	angle_bracket_depth++;

      if ((c == '>') && (angle_bracket_depth > 0))
	  angle_bracket_depth--;

      if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r'
	  || c == EOF)
	break;
      if (angle_bracket_depth == 0)
	{
	  if (c == ':' || c == ')' || c == ']'
	      || c == '"' || c == '/' || c == '(' || c == '[')
	    {
	      unread_char (c);
	      break;
	    }
	}

      if (i == sizeof (name->buffer) - 1)
	fatal_with_file_and_line ("name too long");
      name->buffer[i++] = c;

      c = read_char ();
    }

  if (i == 0)
    return false;

  name->buffer[i] = 0;
  name->string = name->buffer;

  if (m_md_constants)
    {
      /* Do constant expansion.  */
      struct md_constant *def;

      do
	{
	  struct md_constant tmp_def;

	  tmp_def.name = name->string;
	  def = (struct md_constant *) htab_find (m_md_constants, &tmp_def);
	  if (def)
	    name->string = def->value;
	}
      while (def);
    }

  return true;
}

/* Read an rtx code name into NAME.  It is terminated by any of the
   punctuation chars of rtx printed syntax.  */

file_location
md_reader::read_name (struct md_name *name)
{
  file_location loc;
  if (!read_name_1 (name, &loc))
    fatal_with_file_and_line ("missing name or number");
  return loc;
}

file_location
md_reader::read_name_or_nil (struct md_name *name)
{
  file_location loc;
  if (!read_name_1 (name, &loc))
    {
      file_location loc = get_current_location ();
      read_skip_construct (0, loc);
      /* Skip the ')'.  */
      read_char ();
      name->buffer[0] = 0;
      name->string = name->buffer;
    }
  return loc;
}

/* Subroutine of the string readers.  Handles backslash escapes.
   Caller has read the backslash, but not placed it into the obstack.  */

void
md_reader::read_escape ()
{
  int c = read_char ();

  switch (c)
    {
      /* Backslash-newline is replaced by nothing, as in C.  */
    case '\n':
      return;

      /* \" \' \\ are replaced by the second character.  */
    case '\\':
    case '"':
    case '\'':
      break;

      /* Standard C string escapes:
	 \a \b \f \n \r \t \v
	 \[0-7] \x
	 all are passed through to the output string unmolested.
	 In normal use these wind up in a string constant processed
	 by the C compiler, which will translate them appropriately.
	 We do not bother checking that \[0-7] are followed by up to
	 two octal digits, or that \x is followed by N hex digits.
	 \? \u \U are left out because they are not in traditional C.  */
    case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
    case '7': case 'x':
      obstack_1grow (&m_string_obstack, '\\');
      break;

      /* \; makes stuff for a C string constant containing
	 newline and tab.  */
    case ';':
      obstack_grow (&m_string_obstack, "\\n\\t", 4);
      return;

      /* pass anything else through, but issue a warning.  */
    default:
      fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
	       get_filename (), get_lineno (),
	       c);
      obstack_1grow (&m_string_obstack, '\\');
      break;
    }

  obstack_1grow (&m_string_obstack, c);
}

/* Read a double-quoted string onto the obstack.  Caller has scanned
   the leading quote.  */

char *
md_reader::read_quoted_string ()
{
  int c;

  while (1)
    {
      c = read_char (); /* Read the string  */
      if (c == '\\')
	{
	  read_escape ();
	  continue;
	}
      else if (c == '"' || c == EOF)
	break;

      obstack_1grow (&m_string_obstack, c);
    }

  obstack_1grow (&m_string_obstack, 0);
  return XOBFINISH (&m_string_obstack, char *);
}

/* Read a braced string (a la Tcl) onto the string obstack.  Caller
   has scanned the leading brace.  Note that unlike quoted strings,
   the outermost braces _are_ included in the string constant.  */

char *
md_reader::read_braced_string ()
{
  int c;
  int brace_depth = 1;  /* caller-processed */
  unsigned long starting_read_md_lineno = get_lineno ();

  obstack_1grow (&m_string_obstack, '{');
  while (brace_depth)
    {
      c = read_char (); /* Read the string  */

      if (c == '{')
	brace_depth++;
      else if (c == '}')
	brace_depth--;
      else if (c == '\\')
	{
	  read_escape ();
	  continue;
	}
      else if (c == EOF)
	fatal_with_file_and_line
	  ("missing closing } for opening brace on line %lu",
	   starting_read_md_lineno);

      obstack_1grow (&m_string_obstack, c);
    }

  obstack_1grow (&m_string_obstack, 0);
  return XOBFINISH (&m_string_obstack, char *);
}

/* Read some kind of string constant.  This is the high-level routine
   used by read_rtx.  It handles surrounding parentheses, leading star,
   and dispatch to the appropriate string constant reader.  */

char *
md_reader::read_string (int star_if_braced)
{
  char *stringbuf;
  int saw_paren = 0;
  int c, old_lineno;

  c = read_skip_spaces ();
  if (c == '(')
    {
      saw_paren = 1;
      c = read_skip_spaces ();
    }

  old_lineno = get_lineno ();
  if (c == '"')
    stringbuf = read_quoted_string ();
  else if (c == '{')
    {
      if (star_if_braced)
	obstack_1grow (&m_string_obstack, '*');
      stringbuf = read_braced_string ();
    }
  else if (saw_paren && c == 'n')
    {
      /* Handle (nil) by returning NULL.  */
      require_char ('i');
      require_char ('l');
      require_char_ws (')');
      return NULL;
    }
  else
    fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);

  if (saw_paren)
    require_char_ws (')');

  set_md_ptr_loc (stringbuf, get_filename (), old_lineno);
  return stringbuf;
}

/* Skip the rest of a construct that started at line LINENO and that
   is currently nested by DEPTH levels of parentheses.  */

void
md_reader::read_skip_construct (int depth, file_location loc)
{
  struct md_name name;
  int c;

  do
    {
      c = read_skip_spaces ();
      if (c == EOF)
	{
	  error_at (loc, "unterminated construct");
	  exit (1);
	}
      switch (c)
	{
	case '(':
	  depth++;
	  break;

	case ')':
	  depth--;
	  break;

	case ':':
	case '[':
	case ']':
	case '/':
	  break;

	case '\"':
	case '{':
	  unread_char (c);
	  read_string (false);
	  break;

	default:
	  unread_char (c);
	  read_name (&name);
	  break;
	}
    }
  while (depth > 0);
  unread_char (c);
}

/* Given a string, return the number of comma-separated elements in it.
   Return 0 for the null string.  */

int
n_comma_elts (const char *s)
{
  int n;

  if (*s == '\0')
    return 0;

  for (n = 1; *s; s++)
    if (*s == ',')
      n++;

  return n;
}

/* Given a pointer to a (char *), return a pointer to the beginning of the
   next comma-separated element in the string.  Advance the pointer given
   to the end of that element.  Return NULL if at end of string.  Caller
   is responsible for copying the string if necessary.  White space between
   a comma and an element is ignored.  */

const char *
scan_comma_elt (const char **pstr)
{
  const char *start;
  const char *p = *pstr;

  if (*p == ',')
    p++;
  while (ISSPACE (*p))
    p++;

  if (*p == '\0')
    return NULL;

  start = p;

  while (*p != ',' && *p != '\0')
    p++;

  *pstr = p;
  return start;
}

/* Convert STRING to uppercase.  */

void
upcase_string (char *string)
{
  int i;

  for (i = 0; string[i]; i++)
    string[i] = TOUPPER (string[i]);
}

/* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
   where both NAME and VALUE are malloc()ed strings.  PARENT_ENUM is the
   enum to which NAME belongs, or null if NAME is a stand-alone constant.  */

static struct md_constant *
add_constant (htab_t defs, char *name, char *value,
	      struct enum_type *parent_enum)
{
  struct md_constant *def, tmp_def;
  void **entry_ptr;

  tmp_def.name = name;
  entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
  if (*entry_ptr)
    {
      def = (struct md_constant *) *entry_ptr;
      if (strcmp (def->value, value) != 0)
	fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
				  def->name, def->value, value);
      else if (parent_enum || def->parent_enum)
	fatal_with_file_and_line ("redefinition of `%s'", def->name);
      free (name);
      free (value);
    }
  else
    {
      def = XNEW (struct md_constant);
      def->name = name;
      def->value = value;
      def->parent_enum = parent_enum;
      *entry_ptr = def;
    }
  return def;
}

/* Process a define_constants directive, starting with the optional space
   after the "define_constants".  */

void
md_reader::handle_constants ()
{
  int c;
  htab_t defs;

  require_char_ws ('[');

  /* Disable constant expansion during definition processing.  */
  defs = m_md_constants;
  m_md_constants = 0;
  while ( (c = read_skip_spaces ()) != ']')
    {
      struct md_name name, value;

      if (c != '(')
	fatal_expected_char ('(', c);

      read_name (&name);
      read_name (&value);
      add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);

      require_char_ws (')');
    }
  m_md_constants = defs;
}

/* For every constant definition, call CALLBACK with two arguments:
   a pointer a pointer to the constant definition and INFO.
   Stop when CALLBACK returns zero.  */

void
md_reader::traverse_md_constants (htab_trav callback, void *info)
{
  htab_traverse (get_md_constants (), callback, info);
}

/* Return a malloc()ed decimal string that represents number NUMBER.  */

static char *
md_decimal_string (int number)
{
  /* A safe overestimate.  +1 for sign, +1 for null terminator.  */
  char buffer[sizeof (int) * CHAR_BIT + 1 + 1];

  sprintf (buffer, "%d", number);
  return xstrdup (buffer);
}

/* Process a define_enum or define_c_enum directive, starting with
   the optional space after the "define_enum".  LINENO is the line
   number on which the directive started and MD_P is true if the
   directive is a define_enum rather than a define_c_enum.  */

void
md_reader::handle_enum (file_location loc, bool md_p)
{
  char *enum_name, *value_name;
  struct md_name name;
  struct enum_type *def;
  struct enum_value *ev;
  void **slot;
  int c;

  enum_name = read_string (false);
  slot = htab_find_slot (m_enum_types, &enum_name, INSERT);
  if (*slot)
    {
      def = (struct enum_type *) *slot;
      if (def->md_p != md_p)
	error_at (loc, "redefining `%s' as a different type of enum",
		  enum_name);
    }
  else
    {
      def = XNEW (struct enum_type);
      def->name = enum_name;
      def->md_p = md_p;
      def->values = 0;
      def->tail_ptr = &def->values;
      def->num_values = 0;
      *slot = def;
    }

  require_char_ws ('[');

  while ((c = read_skip_spaces ()) != ']')
    {
      if (c == EOF)
	{
	  error_at (loc, "unterminated construct");
	  exit (1);
	}
      unread_char (c);
      read_name (&name);

      ev = XNEW (struct enum_value);
      ev->next = 0;
      if (md_p)
	{
	  value_name = concat (def->name, "_", name.string, NULL);
	  upcase_string (value_name);
	  ev->name = xstrdup (name.string);
	}
      else
	{
	  value_name = xstrdup (name.string);
	  ev->name = value_name;
	}
      ev->def = add_constant (get_md_constants (), value_name,
			      md_decimal_string (def->num_values), def);

      *def->tail_ptr = ev;
      def->tail_ptr = &ev->next;
      def->num_values++;
    }
}

/* Try to find the definition of the given enum.  Return null on failure.  */

struct enum_type *
md_reader::lookup_enum_type (const char *name)
{
  return (struct enum_type *) htab_find (m_enum_types, &name);
}

/* For every enum definition, call CALLBACK with two arguments:
   a pointer to the constant definition and INFO.  Stop when CALLBACK
   returns zero.  */

void
md_reader::traverse_enum_types (htab_trav callback, void *info)
{
  htab_traverse (m_enum_types, callback, info);
}


/* Constructor for md_reader.  */

md_reader::md_reader (bool compact)
: m_compact (compact),
  m_toplevel_fname (NULL),
  m_base_dir (NULL),
  m_read_md_file (NULL),
  m_read_md_filename (NULL),
  m_read_md_lineno (0),
  m_read_md_colno (0),
  m_first_dir_md_include (NULL),
  m_last_dir_md_include_ptr (&m_first_dir_md_include),
  m_first_line (0),
  m_last_line (0)
{
  /* Set the global singleton pointer.  */
  md_reader_ptr = this;

  obstack_init (&m_string_obstack);

  m_ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
  obstack_init (&m_ptr_loc_obstack);

  m_joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
  obstack_init (&m_joined_conditions_obstack);

  m_md_constants = htab_create (31, leading_string_hash,
				leading_string_eq_p, (htab_del) 0);

  m_enum_types = htab_create (31, leading_string_hash,
			      leading_string_eq_p, (htab_del) 0);

  /* Unlock the stdio streams.  */
  unlock_std_streams ();
}

/* md_reader's destructor.  */

md_reader::~md_reader ()
{
  free (m_base_dir);

  htab_delete (m_enum_types);

  htab_delete (m_md_constants);

  obstack_free (&m_joined_conditions_obstack, NULL);
  htab_delete (m_joined_conditions);

  obstack_free (&m_ptr_loc_obstack, NULL);
  htab_delete (m_ptr_locs);

  obstack_free (&m_string_obstack, NULL);

  /* Clear the global singleton pointer.  */
  md_reader_ptr = NULL;
}

/* Process an "include" directive, starting with the optional space
   after the "include".  Read in the file and use HANDLE_DIRECTIVE
   to process each unknown directive.  LINENO is the line number on
   which the "include" occurred.  */

void
md_reader::handle_include (file_location loc)
{
  const char *filename;
  const char *old_filename;
  int old_lineno, old_colno;
  char *pathname;
  FILE *input_file, *old_file;

  filename = read_string (false);
  input_file = NULL;

  /* If the specified file name is absolute, skip the include stack.  */
  if (!IS_ABSOLUTE_PATH (filename))
    {
      struct file_name_list *stackp;

      /* Search the directory path, trying to open the file.  */
      for (stackp = m_first_dir_md_include; stackp; stackp = stackp->next)
	{
	  static const char sep[2] = { DIR_SEPARATOR, '\0' };

	  pathname = concat (stackp->fname, sep, filename, NULL);
	  input_file = fopen (pathname, "r");
	  if (input_file != NULL)
	    break;
	  free (pathname);
	}
    }

  /* If we haven't managed to open the file yet, try combining the
     filename with BASE_DIR.  */
  if (input_file == NULL)
    {
      if (m_base_dir)
	pathname = concat (m_base_dir, filename, NULL);
      else
	pathname = xstrdup (filename);
      input_file = fopen (pathname, "r");
    }

  if (input_file == NULL)
    {
      free (pathname);
      error_at (loc, "include file `%s' not found", filename);
      return;
    }

  /* Save the old cursor.  Note that the LINENO argument to this
     function is the beginning of the include statement, while
     read_md_lineno has already been advanced.  */
  old_file = m_read_md_file;
  old_filename = m_read_md_filename;
  old_lineno = m_read_md_lineno;
  old_colno = m_read_md_colno;

  if (include_callback)
    include_callback (pathname);

  m_read_md_file = input_file;
  m_read_md_filename = pathname;

  handle_file ();

  /* Restore the old cursor.  */
  m_read_md_file = old_file;
  m_read_md_filename = old_filename;
  m_read_md_lineno = old_lineno;
  m_read_md_colno = old_colno;

  /* Do not free the pathname.  It is attached to the various rtx
     queue elements.  */
}

/* Process the current file, assuming that read_md_file and
   read_md_filename are valid.  Use HANDLE_DIRECTIVE to handle
   unknown directives.  */

void
md_reader::handle_file ()
{
  struct md_name directive;
  int c;

  m_read_md_lineno = 1;
  m_read_md_colno = 0;
  while ((c = read_skip_spaces ()) != EOF)
    {
      file_location loc = get_current_location ();
      if (c != '(')
	fatal_expected_char ('(', c);

      read_name (&directive);
      if (strcmp (directive.string, "define_constants") == 0)
	handle_constants ();
      else if (strcmp (directive.string, "define_enum") == 0)
	handle_enum (loc, true);
      else if (strcmp (directive.string, "define_c_enum") == 0)
	handle_enum (loc, false);
      else if (strcmp (directive.string, "include") == 0)
	handle_include (loc);
      else
	handle_unknown_directive (loc, directive.string);

      require_char_ws (')');
    }
  fclose (m_read_md_file);
}

/* Like handle_file, but for top-level files.  Set up m_toplevel_fname
   and m_base_dir accordingly.  */

void
md_reader::handle_toplevel_file ()
{
  const char *base;

  m_toplevel_fname = m_read_md_filename;
  base = lbasename (m_toplevel_fname);
  if (base == m_toplevel_fname)
    m_base_dir = NULL;
  else
    m_base_dir = xstrndup (m_toplevel_fname, base - m_toplevel_fname);

  handle_file ();
}

file_location
md_reader::get_current_location () const
{
  return file_location (m_read_md_filename, m_read_md_lineno, m_read_md_colno);
}

/* Parse a -I option with argument ARG.  */

void
md_reader::add_include_path (const char *arg)
{
  struct file_name_list *dirtmp;

  dirtmp = XNEW (struct file_name_list);
  dirtmp->next = 0;
  dirtmp->fname = arg;
  *m_last_dir_md_include_ptr = dirtmp;
  m_last_dir_md_include_ptr = &dirtmp->next;
}

#ifdef GENERATOR_FILE

/* The main routine for reading .md files.  Try to process all the .md
   files specified on the command line and return true if no error occurred.

   ARGC and ARGV are the arguments to main.

   PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
   It should return true if it recognizes the argument or false if a
   generic error should be reported.  */

bool
md_reader::read_md_files (int argc, const char **argv,
			  bool (*parse_opt) (const char *))
{
  int i;
  bool no_more_options;
  bool already_read_stdin;
  int num_files;

  /* First we loop over all the options.  */
  for (i = 1; i < argc; i++)
    if (argv[i][0] == '-')
      {
	/* An argument consisting of exactly one dash is a request to
	   read stdin.  This will be handled in the second loop.  */
	if (argv[i][1] == '\0')
	  continue;

	/* An argument consisting of just two dashes causes option
	   parsing to cease.  */
	if (argv[i][1] == '-' && argv[i][2] == '\0')
	  break;

	if (argv[i][1] == 'I')
	  {
	    if (argv[i][2] != '\0')
	      add_include_path (argv[i] + 2);
	    else if (++i < argc)
	      add_include_path (argv[i]);
	    else
	      fatal ("directory name missing after -I option");
	    continue;
	  }

	/* The program may have provided a callback so it can
	   accept its own options.  */
	if (parse_opt && parse_opt (argv[i]))
	  continue;

	fatal ("invalid option `%s'", argv[i]);
      }

  /* Now loop over all input files.  */
  num_files = 0;
  no_more_options = false;
  already_read_stdin = false;
  for (i = 1; i < argc; i++)
    {
      if (argv[i][0] == '-')
	{
	  if (argv[i][1] == '\0')
	    {
	      /* Read stdin.  */
	      if (already_read_stdin)
		fatal ("cannot read standard input twice");

	      m_read_md_file = stdin;
	      m_read_md_filename = "<stdin>";
	      handle_toplevel_file ();
	      already_read_stdin = true;
	      continue;
	    }
	  else if (argv[i][1] == '-' && argv[i][2] == '\0')
	    {
	      /* No further arguments are to be treated as options.  */
	      no_more_options = true;
	      continue;
	    }
	  else if (!no_more_options)
	    continue;
	}

      /* If we get here we are looking at a non-option argument, i.e.
	 a file to be processed.  */
      m_read_md_filename = argv[i];
      m_read_md_file = fopen (m_read_md_filename, "r");
      if (m_read_md_file == 0)
	{
	  perror (m_read_md_filename);
	  return false;
	}
      handle_toplevel_file ();
      num_files++;
    }

  /* If we get to this point without having seen any files to process,
     read the standard input now.  */
  if (num_files == 0 && !already_read_stdin)
    {
      m_read_md_file = stdin;
      m_read_md_filename = "<stdin>";
      handle_toplevel_file ();
    }

  return !have_error;
}

#endif /* #ifdef GENERATOR_FILE */

/* Read FILENAME.  */

bool
md_reader::read_file (const char *filename)
{
  m_read_md_filename = filename;
  m_read_md_file = fopen (m_read_md_filename, "r");
  if (m_read_md_file == 0)
    {
      perror (m_read_md_filename);
      return false;
    }
  handle_toplevel_file ();
  return !have_error;
}

/* Read FILENAME, filtering to just the given lines.  */

bool
md_reader::read_file_fragment (const char *filename,
			       int first_line,
			       int last_line)
{
  m_read_md_filename = filename;
  m_read_md_file = fopen (m_read_md_filename, "r");
  if (m_read_md_file == 0)
    {
      perror (m_read_md_filename);
      return false;
    }
  m_first_line = first_line;
  m_last_line = last_line;
  handle_toplevel_file ();
  return !have_error;
}

/* class noop_reader : public md_reader */

/* A dummy implementation which skips unknown directives.  */
void
noop_reader::handle_unknown_directive (file_location loc, const char *)
{
  read_skip_construct (1, loc);
}
