/* MD reader for GCC.
   Copyright (C) 1987-2019 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),
  m_first_overload (NULL),
  m_next_overload_ptr (&m_first_overload),
  m_overloads_htab (NULL)
{
  /* 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);
}
