/* The IGEN simulator generator for GDB, the GNU Debugger.

   Copyright 2002-2013 Free Software Foundation, Inc.

   Contributed by Andrew Cagney.

   This file is part of GDB.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */


/* Read a table, line by line, from a file.

   A table line has several forms:

   Field line:

       <text> { ":" <text> }
       type == table_colon_entry

       Fields points to a NULL terminated list of pointers.

   Tab indented block:

     <tab> <text> <nl> { <tab> <text> <nl> }
     type == table_code_entry

     The leading tab at the start of each line is discarded.
     fields[i] is the i'th line with the <nl> discarded.
     

   Code block:

     "{" <ignore-text> <nl> { <text> <nl> } "}" <ignore-text> <nl>
     type == table_code_entry

     The leading/trailing {/} lines are discarded.
     Lines containing two leading spaces have those spaces striped.
     fields[i] is the i'th line with the <nl> discarded.

   In addition, the table parser reconises and handles internally the
   following (when not in a code block):

     "#" <line-nr> '"' <file> '"'

     As per CPP/CC, treat following lines as if they were taken from
     <file> starting at <line-nr>

   No support for CPP's "#if/#else/#endif" style conditions are
   planned. */

typedef struct _table table;

typedef enum
{
  table_colon_entry,
  table_code_entry,
}
table_entry_type;


typedef struct _table_entry table_entry;
struct _table_entry
{
  table *file;
  line_ref *line;
  table_entry_type type;
  int nr_fields;
  char **field;
};

/* List of directories to search when opening a pushed file.  Current
   directory is always searched first */
typedef struct _table_include table_include;
struct _table_include
{
  char *dir;
  table_include *next;
};


/* Open/read a table file.  Since the file is read once during open
   (and then closed immediatly) there is no close method. */

extern table *table_open (const char *file_name);

extern table_entry *table_read (table *file);


/* Push the the state of the current file and open FILE_NAME.  When
   the end of FILE_NAME is reached, return to the pushed file */

extern void table_push
  (table *file, line_ref *line, table_include *search, const char *file_name);


/* Expand the specified field_nr using the internal expansion table.
   A field is only expanded when explicitly specified.  */

extern void table_expand_field (table_entry *entry, int field_nr);


/* Given a code entry, write the code to FILE.  Since any
   leading/trailing braces were striped as part of the read, they are
   not written. */

extern void table_print_code (lf *file, table_entry *entry);


/* Debugging */

extern void dump_line_ref
  (lf *file, char *prefix, const line_ref *line, char *suffix);

extern void dump_table_entry
  (lf *file, char *prefix, const table_entry *entry, char *suffix);



/* Utilities for skipping around text */

extern char *skip_digits (char *chp);

extern char *skip_spaces (char *chp);

extern char *skip_to_separator (char *chp, char *separators);

extern char *back_spaces (char *start, char *chp);
