/* MD reader for GCC.
   Copyright (C) 1987-2021 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 */


/* 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 FILE_LOC.  */

void
md_reader::set_md_ptr_loc (const void *ptr, file_location file_loc)
{
  struct ptr_loc *loc;

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

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

const md_reader::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->loc);
}

/* 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->loc.lineno, loc->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;

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

  file_location loc = get_current_location ();
  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, loc);
  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;
  unsigned int cur_value;
  struct md_name name, value;
  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;
    }

  cur_value = def->num_values;
  require_char_ws ('[');

  while ((c = read_skip_spaces ()) != ']')
    {
      if (c == EOF)
	{
	  error_at (loc, "unterminated construct");
	  exit (1);
	}
      if (c == '(')
	{
	  read_name (&name);
	  read_name (&value);
	  require_char_ws (')');
	  cur_value = atoi (value.string);
	}
      else
	{
	  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 (cur_value), def);

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

/* 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);
}
