OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [tree-browser.c] - Diff between revs 38 and 154

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 38 Rev 154
/* Tree browser.
/* Tree browser.
   Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
   Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
   Contributed by Sebastian Pop <s.pop@laposte.net>
   Contributed by Sebastian Pop <s.pop@laposte.net>
 
 
This file is part of GCC.
This file is part of GCC.
 
 
GCC is free software; you can redistribute it and/or modify it under
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
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
Software Foundation; either version 3, or (at your option) any later
version.
version.
 
 
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.
for more details.
 
 
You should have received a copy of the GNU General Public License
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
<http://www.gnu.org/licenses/>.  */
 
 
#include "config.h"
#include "config.h"
#include "system.h"
#include "system.h"
#include "coretypes.h"
#include "coretypes.h"
#include "tm.h"
#include "tm.h"
#include "tree.h"
#include "tree.h"
#include "tree-inline.h"
#include "tree-inline.h"
#include "diagnostic.h"
#include "diagnostic.h"
#include "hashtab.h"
#include "hashtab.h"
 
 
 
 
#define TB_OUT_FILE stdout
#define TB_OUT_FILE stdout
#define TB_IN_FILE stdin
#define TB_IN_FILE stdin
#define TB_NIY fprintf (TB_OUT_FILE, "Sorry this command is not yet implemented.\n")
#define TB_NIY fprintf (TB_OUT_FILE, "Sorry this command is not yet implemented.\n")
#define TB_WF fprintf (TB_OUT_FILE, "Warning, this command failed.\n")
#define TB_WF fprintf (TB_OUT_FILE, "Warning, this command failed.\n")
 
 
 
 
/* Structures for handling Tree Browser's commands.  */
/* Structures for handling Tree Browser's commands.  */
#define DEFTBCODE(COMMAND, STRING, HELP)   COMMAND,
#define DEFTBCODE(COMMAND, STRING, HELP)   COMMAND,
enum TB_Comm_code {
enum TB_Comm_code {
#include "tree-browser.def"
#include "tree-browser.def"
  TB_UNUSED_COMMAND
  TB_UNUSED_COMMAND
};
};
#undef DEFTBCODE
#undef DEFTBCODE
typedef enum TB_Comm_code TB_CODE;
typedef enum TB_Comm_code TB_CODE;
 
 
struct tb_command {
struct tb_command {
  const char *help_msg;
  const char *help_msg;
  const char *comm_text;
  const char *comm_text;
  size_t comm_len;
  size_t comm_len;
  TB_CODE comm_code;
  TB_CODE comm_code;
};
};
 
 
#define DEFTBCODE(code, str, help) { help, str, sizeof(str) - 1, code },
#define DEFTBCODE(code, str, help) { help, str, sizeof(str) - 1, code },
static const struct tb_command tb_commands[] =
static const struct tb_command tb_commands[] =
{
{
#include "tree-browser.def"
#include "tree-browser.def"
};
};
#undef DEFTBCODE
#undef DEFTBCODE
 
 
#define TB_COMMAND_LEN(N) (tb_commands[N].comm_len)
#define TB_COMMAND_LEN(N) (tb_commands[N].comm_len)
#define TB_COMMAND_TEXT(N) (tb_commands[N].comm_text)
#define TB_COMMAND_TEXT(N) (tb_commands[N].comm_text)
#define TB_COMMAND_CODE(N) (tb_commands[N].comm_code)
#define TB_COMMAND_CODE(N) (tb_commands[N].comm_code)
#define TB_COMMAND_HELP(N) (tb_commands[N].help_msg)
#define TB_COMMAND_HELP(N) (tb_commands[N].help_msg)
 
 
 
 
/* Next structure is for parsing TREE_CODEs.  */
/* Next structure is for parsing TREE_CODEs.  */
struct tb_tree_code {
struct tb_tree_code {
  enum tree_code code;
  enum tree_code code;
  const char *code_string;
  const char *code_string;
  size_t code_string_len;
  size_t code_string_len;
};
};
 
 
#define DEFTREECODE(SYM, STRING, TYPE, NARGS) { SYM, STRING, sizeof (STRING) - 1 },
#define DEFTREECODE(SYM, STRING, TYPE, NARGS) { SYM, STRING, sizeof (STRING) - 1 },
static const struct tb_tree_code tb_tree_codes[] =
static const struct tb_tree_code tb_tree_codes[] =
{
{
#include "tree.def"
#include "tree.def"
};
};
#undef DEFTREECODE
#undef DEFTREECODE
 
 
#define TB_TREE_CODE(N) (tb_tree_codes[N].code)
#define TB_TREE_CODE(N) (tb_tree_codes[N].code)
#define TB_TREE_CODE_TEXT(N) (tb_tree_codes[N].code_string)
#define TB_TREE_CODE_TEXT(N) (tb_tree_codes[N].code_string)
#define TB_TREE_CODE_LEN(N) (tb_tree_codes[N].code_string_len)
#define TB_TREE_CODE_LEN(N) (tb_tree_codes[N].code_string_len)
 
 
 
 
/* Function declarations.  */
/* Function declarations.  */
 
 
static long TB_getline (char **, long *, FILE *);
static long TB_getline (char **, long *, FILE *);
static TB_CODE TB_get_command (char *);
static TB_CODE TB_get_command (char *);
static enum tree_code TB_get_tree_code (char *);
static enum tree_code TB_get_tree_code (char *);
static tree find_node_with_code (tree *, int *, void *);
static tree find_node_with_code (tree *, int *, void *);
static tree store_child_info (tree *, int *, void *);
static tree store_child_info (tree *, int *, void *);
static void TB_update_up (tree);
static void TB_update_up (tree);
static tree TB_current_chain_node (tree);
static tree TB_current_chain_node (tree);
static tree TB_prev_expr (tree);
static tree TB_prev_expr (tree);
static tree TB_next_expr (tree);
static tree TB_next_expr (tree);
static tree TB_up_expr (tree);
static tree TB_up_expr (tree);
static tree TB_first_in_bind (tree);
static tree TB_first_in_bind (tree);
static tree TB_last_in_bind (tree);
static tree TB_last_in_bind (tree);
static int  TB_parent_eq (const void *, const void *);
static int  TB_parent_eq (const void *, const void *);
static tree TB_history_prev (void);
static tree TB_history_prev (void);
 
 
/* FIXME: To be declared in a .h file.  */
/* FIXME: To be declared in a .h file.  */
void browse_tree (tree);
void browse_tree (tree);
 
 
/* Static variables.  */
/* Static variables.  */
static htab_t TB_up_ht;
static htab_t TB_up_ht;
static tree TB_history_stack = NULL_TREE;
static tree TB_history_stack = NULL_TREE;
static int TB_verbose = 1;
static int TB_verbose = 1;
 
 
 
 
/* Entry point in the Tree Browser.  */
/* Entry point in the Tree Browser.  */
 
 
void
void
browse_tree (tree begin)
browse_tree (tree begin)
{
{
  tree head;
  tree head;
  TB_CODE tbc = TB_UNUSED_COMMAND;
  TB_CODE tbc = TB_UNUSED_COMMAND;
  ssize_t rd;
  ssize_t rd;
  char *input = NULL;
  char *input = NULL;
  long input_size = 0;
  long input_size = 0;
 
 
  fprintf (TB_OUT_FILE, "\nTree Browser\n");
  fprintf (TB_OUT_FILE, "\nTree Browser\n");
 
 
#define TB_SET_HEAD(N) do {                                           \
#define TB_SET_HEAD(N) do {                                           \
  TB_history_stack = tree_cons (NULL_TREE, (N), TB_history_stack);    \
  TB_history_stack = tree_cons (NULL_TREE, (N), TB_history_stack);    \
  head = N;                                                           \
  head = N;                                                           \
  if (TB_verbose)                                                     \
  if (TB_verbose)                                                     \
    if (head)                                                         \
    if (head)                                                         \
      {                                                               \
      {                                                               \
        print_generic_expr (TB_OUT_FILE, head, 0);                    \
        print_generic_expr (TB_OUT_FILE, head, 0);                    \
        fprintf (TB_OUT_FILE, "\n");                                  \
        fprintf (TB_OUT_FILE, "\n");                                  \
      }                                                               \
      }                                                               \
} while (0)
} while (0)
 
 
  TB_SET_HEAD (begin);
  TB_SET_HEAD (begin);
 
 
  /* Store in a hashtable information about previous and upper statements.  */
  /* Store in a hashtable information about previous and upper statements.  */
  {
  {
    TB_up_ht = htab_create (1023, htab_hash_pointer, &TB_parent_eq, NULL);
    TB_up_ht = htab_create (1023, htab_hash_pointer, &TB_parent_eq, NULL);
    TB_update_up (head);
    TB_update_up (head);
  }
  }
 
 
  while (24)
  while (24)
    {
    {
      fprintf (TB_OUT_FILE, "TB> ");
      fprintf (TB_OUT_FILE, "TB> ");
      rd = TB_getline (&input, &input_size, TB_IN_FILE);
      rd = TB_getline (&input, &input_size, TB_IN_FILE);
 
 
      if (rd == -1)
      if (rd == -1)
        /* EOF.  */
        /* EOF.  */
        goto ret;
        goto ret;
 
 
      if (rd != 1)
      if (rd != 1)
        /* Get a new command.  Otherwise the user just pressed enter, and thus
        /* Get a new command.  Otherwise the user just pressed enter, and thus
           she expects the last command to be reexecuted.  */
           she expects the last command to be reexecuted.  */
        tbc = TB_get_command (input);
        tbc = TB_get_command (input);
 
 
      switch (tbc)
      switch (tbc)
        {
        {
        case TB_UPDATE_UP:
        case TB_UPDATE_UP:
          TB_update_up (head);
          TB_update_up (head);
          break;
          break;
 
 
        case TB_MAX:
        case TB_MAX:
          if (head && (INTEGRAL_TYPE_P (head)
          if (head && (INTEGRAL_TYPE_P (head)
                       || TREE_CODE (head) == REAL_TYPE))
                       || TREE_CODE (head) == REAL_TYPE))
            TB_SET_HEAD (TYPE_MAX_VALUE (head));
            TB_SET_HEAD (TYPE_MAX_VALUE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_MIN:
        case TB_MIN:
          if (head && (INTEGRAL_TYPE_P (head)
          if (head && (INTEGRAL_TYPE_P (head)
                       || TREE_CODE (head) == REAL_TYPE))
                       || TREE_CODE (head) == REAL_TYPE))
            TB_SET_HEAD (TYPE_MIN_VALUE (head));
            TB_SET_HEAD (TYPE_MIN_VALUE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_ELT:
        case TB_ELT:
          if (head && TREE_CODE (head) == TREE_VEC)
          if (head && TREE_CODE (head) == TREE_VEC)
            {
            {
              /* This command takes another argument: the element number:
              /* This command takes another argument: the element number:
                 for example "elt 1".  */
                 for example "elt 1".  */
              TB_NIY;
              TB_NIY;
            }
            }
          else if (head && TREE_CODE (head) == VECTOR_CST)
          else if (head && TREE_CODE (head) == VECTOR_CST)
            {
            {
              /* This command takes another argument: the element number:
              /* This command takes another argument: the element number:
                 for example "elt 1".  */
                 for example "elt 1".  */
              TB_NIY;
              TB_NIY;
            }
            }
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_VALUE:
        case TB_VALUE:
          if (head && TREE_CODE (head) == TREE_LIST)
          if (head && TREE_CODE (head) == TREE_LIST)
            TB_SET_HEAD (TREE_VALUE (head));
            TB_SET_HEAD (TREE_VALUE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_PURPOSE:
        case TB_PURPOSE:
          if (head && TREE_CODE (head) == TREE_LIST)
          if (head && TREE_CODE (head) == TREE_LIST)
            TB_SET_HEAD (TREE_PURPOSE (head));
            TB_SET_HEAD (TREE_PURPOSE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_IMAG:
        case TB_IMAG:
          if (head && TREE_CODE (head) == COMPLEX_CST)
          if (head && TREE_CODE (head) == COMPLEX_CST)
            TB_SET_HEAD (TREE_IMAGPART (head));
            TB_SET_HEAD (TREE_IMAGPART (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_REAL:
        case TB_REAL:
          if (head && TREE_CODE (head) == COMPLEX_CST)
          if (head && TREE_CODE (head) == COMPLEX_CST)
            TB_SET_HEAD (TREE_REALPART (head));
            TB_SET_HEAD (TREE_REALPART (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_BLOCK:
        case TB_BLOCK:
          if (head && TREE_CODE (head) == BIND_EXPR)
          if (head && TREE_CODE (head) == BIND_EXPR)
            TB_SET_HEAD (TREE_OPERAND (head, 2));
            TB_SET_HEAD (TREE_OPERAND (head, 2));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_SUBBLOCKS:
        case TB_SUBBLOCKS:
          if (head && TREE_CODE (head) == BLOCK)
          if (head && TREE_CODE (head) == BLOCK)
            TB_SET_HEAD (BLOCK_SUBBLOCKS (head));
            TB_SET_HEAD (BLOCK_SUBBLOCKS (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_SUPERCONTEXT:
        case TB_SUPERCONTEXT:
          if (head && TREE_CODE (head) == BLOCK)
          if (head && TREE_CODE (head) == BLOCK)
            TB_SET_HEAD (BLOCK_SUPERCONTEXT (head));
            TB_SET_HEAD (BLOCK_SUPERCONTEXT (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_VARS:
        case TB_VARS:
          if (head && TREE_CODE (head) == BLOCK)
          if (head && TREE_CODE (head) == BLOCK)
            TB_SET_HEAD (BLOCK_VARS (head));
            TB_SET_HEAD (BLOCK_VARS (head));
          else if (head && TREE_CODE (head) == BIND_EXPR)
          else if (head && TREE_CODE (head) == BIND_EXPR)
            TB_SET_HEAD (TREE_OPERAND (head, 0));
            TB_SET_HEAD (TREE_OPERAND (head, 0));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_REFERENCE_TO_THIS:
        case TB_REFERENCE_TO_THIS:
          if (head && TYPE_P (head))
          if (head && TYPE_P (head))
            TB_SET_HEAD (TYPE_REFERENCE_TO (head));
            TB_SET_HEAD (TYPE_REFERENCE_TO (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_POINTER_TO_THIS:
        case TB_POINTER_TO_THIS:
          if (head && TYPE_P (head))
          if (head && TYPE_P (head))
            TB_SET_HEAD (TYPE_POINTER_TO (head));
            TB_SET_HEAD (TYPE_POINTER_TO (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_BASETYPE:
        case TB_BASETYPE:
          if (head && TREE_CODE (head) == OFFSET_TYPE)
          if (head && TREE_CODE (head) == OFFSET_TYPE)
            TB_SET_HEAD (TYPE_OFFSET_BASETYPE (head));
            TB_SET_HEAD (TYPE_OFFSET_BASETYPE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_ARG_TYPES:
        case TB_ARG_TYPES:
          if (head && (TREE_CODE (head) == FUNCTION_TYPE
          if (head && (TREE_CODE (head) == FUNCTION_TYPE
                       || TREE_CODE (head) == METHOD_TYPE))
                       || TREE_CODE (head) == METHOD_TYPE))
            TB_SET_HEAD (TYPE_ARG_TYPES (head));
            TB_SET_HEAD (TYPE_ARG_TYPES (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_METHOD_BASE_TYPE:
        case TB_METHOD_BASE_TYPE:
          if (head && (TREE_CODE (head) == FUNCTION_TYPE
          if (head && (TREE_CODE (head) == FUNCTION_TYPE
                       || TREE_CODE (head) == METHOD_TYPE)
                       || TREE_CODE (head) == METHOD_TYPE)
              && TYPE_METHOD_BASETYPE (head))
              && TYPE_METHOD_BASETYPE (head))
            TB_SET_HEAD (TYPE_METHOD_BASETYPE (head));
            TB_SET_HEAD (TYPE_METHOD_BASETYPE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_FIELDS:
        case TB_FIELDS:
          if (head && (TREE_CODE (head) == RECORD_TYPE
          if (head && (TREE_CODE (head) == RECORD_TYPE
                       || TREE_CODE (head) == UNION_TYPE
                       || TREE_CODE (head) == UNION_TYPE
                       || TREE_CODE (head) == QUAL_UNION_TYPE))
                       || TREE_CODE (head) == QUAL_UNION_TYPE))
            TB_SET_HEAD (TYPE_FIELDS (head));
            TB_SET_HEAD (TYPE_FIELDS (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_DOMAIN:
        case TB_DOMAIN:
          if (head && TREE_CODE (head) == ARRAY_TYPE)
          if (head && TREE_CODE (head) == ARRAY_TYPE)
            TB_SET_HEAD (TYPE_DOMAIN (head));
            TB_SET_HEAD (TYPE_DOMAIN (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_VALUES:
        case TB_VALUES:
          if (head && TREE_CODE (head) == ENUMERAL_TYPE)
          if (head && TREE_CODE (head) == ENUMERAL_TYPE)
            TB_SET_HEAD (TYPE_VALUES (head));
            TB_SET_HEAD (TYPE_VALUES (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_ARG_TYPE:
        case TB_ARG_TYPE:
          if (head && TREE_CODE (head) == PARM_DECL)
          if (head && TREE_CODE (head) == PARM_DECL)
            TB_SET_HEAD (DECL_ARG_TYPE (head));
            TB_SET_HEAD (DECL_ARG_TYPE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_INITIAL:
        case TB_INITIAL:
          if (head && DECL_P (head))
          if (head && DECL_P (head))
            TB_SET_HEAD (DECL_INITIAL (head));
            TB_SET_HEAD (DECL_INITIAL (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_RESULT:
        case TB_RESULT:
          if (head && DECL_P (head))
          if (head && DECL_P (head))
            TB_SET_HEAD (DECL_RESULT_FLD (head));
            TB_SET_HEAD (DECL_RESULT_FLD (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_ARGUMENTS:
        case TB_ARGUMENTS:
          if (head && DECL_P (head))
          if (head && DECL_P (head))
            TB_SET_HEAD (DECL_ARGUMENTS (head));
            TB_SET_HEAD (DECL_ARGUMENTS (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_ABSTRACT_ORIGIN:
        case TB_ABSTRACT_ORIGIN:
          if (head && DECL_P (head))
          if (head && DECL_P (head))
            TB_SET_HEAD (DECL_ABSTRACT_ORIGIN (head));
            TB_SET_HEAD (DECL_ABSTRACT_ORIGIN (head));
          else if (head && TREE_CODE (head) == BLOCK)
          else if (head && TREE_CODE (head) == BLOCK)
            TB_SET_HEAD (BLOCK_ABSTRACT_ORIGIN (head));
            TB_SET_HEAD (BLOCK_ABSTRACT_ORIGIN (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_ATTRIBUTES:
        case TB_ATTRIBUTES:
          if (head && DECL_P (head))
          if (head && DECL_P (head))
            TB_SET_HEAD (DECL_ATTRIBUTES (head));
            TB_SET_HEAD (DECL_ATTRIBUTES (head));
          else if (head && TYPE_P (head))
          else if (head && TYPE_P (head))
            TB_SET_HEAD (TYPE_ATTRIBUTES (head));
            TB_SET_HEAD (TYPE_ATTRIBUTES (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_CONTEXT:
        case TB_CONTEXT:
          if (head && DECL_P (head))
          if (head && DECL_P (head))
            TB_SET_HEAD (DECL_CONTEXT (head));
            TB_SET_HEAD (DECL_CONTEXT (head));
          else if (head && TYPE_P (head)
          else if (head && TYPE_P (head)
                   && TYPE_CONTEXT (head))
                   && TYPE_CONTEXT (head))
            TB_SET_HEAD (TYPE_CONTEXT (head));
            TB_SET_HEAD (TYPE_CONTEXT (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_OFFSET:
        case TB_OFFSET:
          if (head && TREE_CODE (head) == FIELD_DECL)
          if (head && TREE_CODE (head) == FIELD_DECL)
            TB_SET_HEAD (DECL_FIELD_OFFSET (head));
            TB_SET_HEAD (DECL_FIELD_OFFSET (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_BIT_OFFSET:
        case TB_BIT_OFFSET:
          if (head && TREE_CODE (head) == FIELD_DECL)
          if (head && TREE_CODE (head) == FIELD_DECL)
            TB_SET_HEAD (DECL_FIELD_BIT_OFFSET (head));
            TB_SET_HEAD (DECL_FIELD_BIT_OFFSET (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_UNIT_SIZE:
        case TB_UNIT_SIZE:
          if (head && DECL_P (head))
          if (head && DECL_P (head))
            TB_SET_HEAD (DECL_SIZE_UNIT (head));
            TB_SET_HEAD (DECL_SIZE_UNIT (head));
          else if (head && TYPE_P (head))
          else if (head && TYPE_P (head))
            TB_SET_HEAD (TYPE_SIZE_UNIT (head));
            TB_SET_HEAD (TYPE_SIZE_UNIT (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_SIZE:
        case TB_SIZE:
          if (head && DECL_P (head))
          if (head && DECL_P (head))
            TB_SET_HEAD (DECL_SIZE (head));
            TB_SET_HEAD (DECL_SIZE (head));
          else if (head && TYPE_P (head))
          else if (head && TYPE_P (head))
            TB_SET_HEAD (TYPE_SIZE (head));
            TB_SET_HEAD (TYPE_SIZE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_TYPE:
        case TB_TYPE:
          if (head && TREE_TYPE (head))
          if (head && TREE_TYPE (head))
            TB_SET_HEAD (TREE_TYPE (head));
            TB_SET_HEAD (TREE_TYPE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_DECL_SAVED_TREE:
        case TB_DECL_SAVED_TREE:
          if (head && TREE_CODE (head) == FUNCTION_DECL
          if (head && TREE_CODE (head) == FUNCTION_DECL
              && DECL_SAVED_TREE (head))
              && DECL_SAVED_TREE (head))
            TB_SET_HEAD (DECL_SAVED_TREE (head));
            TB_SET_HEAD (DECL_SAVED_TREE (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_BODY:
        case TB_BODY:
          if (head && TREE_CODE (head) == BIND_EXPR)
          if (head && TREE_CODE (head) == BIND_EXPR)
            TB_SET_HEAD (TREE_OPERAND (head, 1));
            TB_SET_HEAD (TREE_OPERAND (head, 1));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_CHILD_0:
        case TB_CHILD_0:
          if (head && EXPR_P (head) && TREE_OPERAND (head, 0))
          if (head && EXPR_P (head) && TREE_OPERAND (head, 0))
            TB_SET_HEAD (TREE_OPERAND (head, 0));
            TB_SET_HEAD (TREE_OPERAND (head, 0));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_CHILD_1:
        case TB_CHILD_1:
          if (head && EXPR_P (head) && TREE_OPERAND (head, 1))
          if (head && EXPR_P (head) && TREE_OPERAND (head, 1))
            TB_SET_HEAD (TREE_OPERAND (head, 1));
            TB_SET_HEAD (TREE_OPERAND (head, 1));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_CHILD_2:
        case TB_CHILD_2:
          if (head && EXPR_P (head) && TREE_OPERAND (head, 2))
          if (head && EXPR_P (head) && TREE_OPERAND (head, 2))
            TB_SET_HEAD (TREE_OPERAND (head, 2));
            TB_SET_HEAD (TREE_OPERAND (head, 2));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_CHILD_3:
        case TB_CHILD_3:
          if (head && EXPR_P (head) && TREE_OPERAND (head, 3))
          if (head && EXPR_P (head) && TREE_OPERAND (head, 3))
            TB_SET_HEAD (TREE_OPERAND (head, 3));
            TB_SET_HEAD (TREE_OPERAND (head, 3));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_PRINT:
        case TB_PRINT:
          if (head)
          if (head)
            debug_tree (head);
            debug_tree (head);
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_PRETTY_PRINT:
        case TB_PRETTY_PRINT:
          if (head)
          if (head)
            {
            {
              print_generic_stmt (TB_OUT_FILE, head, 0);
              print_generic_stmt (TB_OUT_FILE, head, 0);
              fprintf (TB_OUT_FILE, "\n");
              fprintf (TB_OUT_FILE, "\n");
            }
            }
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_SEARCH_NAME:
        case TB_SEARCH_NAME:
 
 
          break;
          break;
 
 
        case TB_SEARCH_CODE:
        case TB_SEARCH_CODE:
          {
          {
            enum tree_code code;
            enum tree_code code;
            char *arg_text;
            char *arg_text;
 
 
            arg_text = strchr (input, ' ');
            arg_text = strchr (input, ' ');
            if (arg_text == NULL)
            if (arg_text == NULL)
              {
              {
                fprintf (TB_OUT_FILE, "First argument is missing.  This isn't a valid search command.  \n");
                fprintf (TB_OUT_FILE, "First argument is missing.  This isn't a valid search command.  \n");
                break;
                break;
              }
              }
            code = TB_get_tree_code (arg_text + 1);
            code = TB_get_tree_code (arg_text + 1);
 
 
            /* Search in the subtree a node with the given code.  */
            /* Search in the subtree a node with the given code.  */
            {
            {
              tree res;
              tree res;
 
 
              res = walk_tree (&head, find_node_with_code, &code, NULL);
              res = walk_tree (&head, find_node_with_code, &code, NULL);
              if (res == NULL_TREE)
              if (res == NULL_TREE)
                {
                {
                  fprintf (TB_OUT_FILE, "There's no node with this code (reachable via the walk_tree function from this node).\n");
                  fprintf (TB_OUT_FILE, "There's no node with this code (reachable via the walk_tree function from this node).\n");
                }
                }
              else
              else
                {
                {
                  fprintf (TB_OUT_FILE, "Achoo!  I got this node in the tree.\n");
                  fprintf (TB_OUT_FILE, "Achoo!  I got this node in the tree.\n");
                  TB_SET_HEAD (res);
                  TB_SET_HEAD (res);
                }
                }
            }
            }
            break;
            break;
          }
          }
 
 
#define TB_MOVE_HEAD(FCT) do {       \
#define TB_MOVE_HEAD(FCT) do {       \
  if (head)                          \
  if (head)                          \
    {                                \
    {                                \
      tree t;                        \
      tree t;                        \
      t = FCT (head);                \
      t = FCT (head);                \
      if (t)                         \
      if (t)                         \
        TB_SET_HEAD (t);             \
        TB_SET_HEAD (t);             \
      else                           \
      else                           \
        TB_WF;                       \
        TB_WF;                       \
    }                                \
    }                                \
  else                               \
  else                               \
    TB_WF;                           \
    TB_WF;                           \
} while (0)
} while (0)
 
 
        case TB_FIRST:
        case TB_FIRST:
          TB_MOVE_HEAD (TB_first_in_bind);
          TB_MOVE_HEAD (TB_first_in_bind);
          break;
          break;
 
 
        case TB_LAST:
        case TB_LAST:
          TB_MOVE_HEAD (TB_last_in_bind);
          TB_MOVE_HEAD (TB_last_in_bind);
          break;
          break;
 
 
        case TB_UP:
        case TB_UP:
          TB_MOVE_HEAD (TB_up_expr);
          TB_MOVE_HEAD (TB_up_expr);
          break;
          break;
 
 
        case TB_PREV:
        case TB_PREV:
          TB_MOVE_HEAD (TB_prev_expr);
          TB_MOVE_HEAD (TB_prev_expr);
          break;
          break;
 
 
        case TB_NEXT:
        case TB_NEXT:
          TB_MOVE_HEAD (TB_next_expr);
          TB_MOVE_HEAD (TB_next_expr);
          break;
          break;
 
 
        case TB_HPREV:
        case TB_HPREV:
          /* This command is a little bit special, since it deals with history
          /* This command is a little bit special, since it deals with history
             stack.  For this reason it should keep the "head = ..." statement
             stack.  For this reason it should keep the "head = ..." statement
             and not use TB_MOVE_HEAD.  */
             and not use TB_MOVE_HEAD.  */
          if (head)
          if (head)
            {
            {
              tree t;
              tree t;
              t = TB_history_prev ();
              t = TB_history_prev ();
              if (t)
              if (t)
                {
                {
                  head = t;
                  head = t;
                  if (TB_verbose)
                  if (TB_verbose)
                    {
                    {
                      print_generic_expr (TB_OUT_FILE, head, 0);
                      print_generic_expr (TB_OUT_FILE, head, 0);
                      fprintf (TB_OUT_FILE, "\n");
                      fprintf (TB_OUT_FILE, "\n");
                    }
                    }
                }
                }
              else
              else
                TB_WF;
                TB_WF;
            }
            }
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_CHAIN:
        case TB_CHAIN:
          /* Don't go further if it's the last node in this chain.  */
          /* Don't go further if it's the last node in this chain.  */
          if (head && TREE_CODE (head) == BLOCK)
          if (head && TREE_CODE (head) == BLOCK)
            TB_SET_HEAD (BLOCK_CHAIN (head));
            TB_SET_HEAD (BLOCK_CHAIN (head));
          else if (head && TREE_CHAIN (head))
          else if (head && TREE_CHAIN (head))
            TB_SET_HEAD (TREE_CHAIN (head));
            TB_SET_HEAD (TREE_CHAIN (head));
          else
          else
            TB_WF;
            TB_WF;
          break;
          break;
 
 
        case TB_FUN:
        case TB_FUN:
          /* Go up to the current function declaration.  */
          /* Go up to the current function declaration.  */
          TB_SET_HEAD (current_function_decl);
          TB_SET_HEAD (current_function_decl);
          fprintf (TB_OUT_FILE, "Current function declaration.\n");
          fprintf (TB_OUT_FILE, "Current function declaration.\n");
          break;
          break;
 
 
        case TB_HELP:
        case TB_HELP:
          /* Display a help message.  */
          /* Display a help message.  */
          {
          {
            int i;
            int i;
            fprintf (TB_OUT_FILE, "Possible commands are:\n\n");
            fprintf (TB_OUT_FILE, "Possible commands are:\n\n");
            for (i = 0; i < TB_UNUSED_COMMAND; i++)
            for (i = 0; i < TB_UNUSED_COMMAND; i++)
              {
              {
                fprintf (TB_OUT_FILE, "%20s  -  %s\n", TB_COMMAND_TEXT (i), TB_COMMAND_HELP (i));
                fprintf (TB_OUT_FILE, "%20s  -  %s\n", TB_COMMAND_TEXT (i), TB_COMMAND_HELP (i));
              }
              }
          }
          }
          break;
          break;
 
 
        case TB_VERBOSE:
        case TB_VERBOSE:
          if (TB_verbose == 0)
          if (TB_verbose == 0)
            {
            {
              TB_verbose = 1;
              TB_verbose = 1;
              fprintf (TB_OUT_FILE, "Verbose on.\n");
              fprintf (TB_OUT_FILE, "Verbose on.\n");
            }
            }
          else
          else
            {
            {
              TB_verbose = 0;
              TB_verbose = 0;
              fprintf (TB_OUT_FILE, "Verbose off.\n");
              fprintf (TB_OUT_FILE, "Verbose off.\n");
            }
            }
          break;
          break;
 
 
        case TB_EXIT:
        case TB_EXIT:
        case TB_QUIT:
        case TB_QUIT:
          /* Just exit from this function.  */
          /* Just exit from this function.  */
          goto ret;
          goto ret;
 
 
        default:
        default:
          TB_NIY;
          TB_NIY;
        }
        }
    }
    }
 
 
 ret:;
 ret:;
  htab_delete (TB_up_ht);
  htab_delete (TB_up_ht);
  return;
  return;
}
}
 
 
 
 
/* Search the first node in this BIND_EXPR.  */
/* Search the first node in this BIND_EXPR.  */
 
 
static tree
static tree
TB_first_in_bind (tree node)
TB_first_in_bind (tree node)
{
{
  tree t;
  tree t;
 
 
  if (node == NULL_TREE)
  if (node == NULL_TREE)
    return NULL_TREE;
    return NULL_TREE;
 
 
  while ((t = TB_prev_expr (node)))
  while ((t = TB_prev_expr (node)))
    node = t;
    node = t;
 
 
  return node;
  return node;
}
}
 
 
/* Search the last node in this BIND_EXPR.  */
/* Search the last node in this BIND_EXPR.  */
 
 
static tree
static tree
TB_last_in_bind (tree node)
TB_last_in_bind (tree node)
{
{
  tree t;
  tree t;
 
 
  if (node == NULL_TREE)
  if (node == NULL_TREE)
    return NULL_TREE;
    return NULL_TREE;
 
 
  while ((t = TB_next_expr (node)))
  while ((t = TB_next_expr (node)))
    node = t;
    node = t;
 
 
  return node;
  return node;
}
}
 
 
/* Search the parent expression for this node.  */
/* Search the parent expression for this node.  */
 
 
static tree
static tree
TB_up_expr (tree node)
TB_up_expr (tree node)
{
{
  tree res;
  tree res;
  if (node == NULL_TREE)
  if (node == NULL_TREE)
    return NULL_TREE;
    return NULL_TREE;
 
 
  res = (tree) htab_find (TB_up_ht, node);
  res = (tree) htab_find (TB_up_ht, node);
  return res;
  return res;
}
}
 
 
/* Search the previous expression in this BIND_EXPR.  */
/* Search the previous expression in this BIND_EXPR.  */
 
 
static tree
static tree
TB_prev_expr (tree node)
TB_prev_expr (tree node)
{
{
  node = TB_current_chain_node (node);
  node = TB_current_chain_node (node);
 
 
  if (node == NULL_TREE)
  if (node == NULL_TREE)
    return NULL_TREE;
    return NULL_TREE;
 
 
  node = TB_up_expr (node);
  node = TB_up_expr (node);
  if (node && TREE_CODE (node) == COMPOUND_EXPR)
  if (node && TREE_CODE (node) == COMPOUND_EXPR)
    return node;
    return node;
  else
  else
    return NULL_TREE;
    return NULL_TREE;
}
}
 
 
/* Search the next expression in this BIND_EXPR.  */
/* Search the next expression in this BIND_EXPR.  */
 
 
static tree
static tree
TB_next_expr (tree node)
TB_next_expr (tree node)
{
{
  node = TB_current_chain_node (node);
  node = TB_current_chain_node (node);
 
 
  if (node == NULL_TREE)
  if (node == NULL_TREE)
    return NULL_TREE;
    return NULL_TREE;
 
 
  node = TREE_OPERAND (node, 1);
  node = TREE_OPERAND (node, 1);
  return node;
  return node;
}
}
 
 
static tree
static tree
TB_current_chain_node (tree node)
TB_current_chain_node (tree node)
{
{
  if (node == NULL_TREE)
  if (node == NULL_TREE)
    return NULL_TREE;
    return NULL_TREE;
 
 
  if (TREE_CODE (node) == COMPOUND_EXPR)
  if (TREE_CODE (node) == COMPOUND_EXPR)
    return node;
    return node;
 
 
  node = TB_up_expr (node);
  node = TB_up_expr (node);
  if (node)
  if (node)
    {
    {
      if (TREE_CODE (node) == COMPOUND_EXPR)
      if (TREE_CODE (node) == COMPOUND_EXPR)
        return node;
        return node;
 
 
      node = TB_up_expr (node);
      node = TB_up_expr (node);
      if (TREE_CODE (node) == COMPOUND_EXPR)
      if (TREE_CODE (node) == COMPOUND_EXPR)
        return node;
        return node;
    }
    }
 
 
  return NULL_TREE;
  return NULL_TREE;
}
}
 
 
/* For each node store in its children nodes that the current node is their
/* For each node store in its children nodes that the current node is their
   parent.  This function is used by walk_tree.  */
   parent.  This function is used by walk_tree.  */
 
 
static tree
static tree
store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
store_child_info (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
                  void *data ATTRIBUTE_UNUSED)
                  void *data ATTRIBUTE_UNUSED)
{
{
  tree node;
  tree node;
  void **slot;
  void **slot;
 
 
  node = *tp;
  node = *tp;
 
 
  /* 'node' is the parent of 'TREE_OPERAND (node, *)'.  */
  /* 'node' is the parent of 'TREE_OPERAND (node, *)'.  */
  if (EXPRESSION_CLASS_P (node))
  if (EXPRESSION_CLASS_P (node))
    {
    {
 
 
#define STORE_CHILD(N) do {                                                \
#define STORE_CHILD(N) do {                                                \
  tree op = TREE_OPERAND (node, N);                                        \
  tree op = TREE_OPERAND (node, N);                                        \
  slot = htab_find_slot (TB_up_ht, op, INSERT);                               \
  slot = htab_find_slot (TB_up_ht, op, INSERT);                               \
  *slot = (void *) node;                                                   \
  *slot = (void *) node;                                                   \
} while (0)
} while (0)
 
 
      switch (TREE_CODE_LENGTH (TREE_CODE (node)))
      switch (TREE_CODE_LENGTH (TREE_CODE (node)))
        {
        {
        case 4:
        case 4:
          STORE_CHILD (0);
          STORE_CHILD (0);
          STORE_CHILD (1);
          STORE_CHILD (1);
          STORE_CHILD (2);
          STORE_CHILD (2);
          STORE_CHILD (3);
          STORE_CHILD (3);
          break;
          break;
 
 
        case 3:
        case 3:
          STORE_CHILD (0);
          STORE_CHILD (0);
          STORE_CHILD (1);
          STORE_CHILD (1);
          STORE_CHILD (2);
          STORE_CHILD (2);
          break;
          break;
 
 
        case 2:
        case 2:
          STORE_CHILD (0);
          STORE_CHILD (0);
          STORE_CHILD (1);
          STORE_CHILD (1);
          break;
          break;
 
 
        case 1:
        case 1:
          STORE_CHILD (0);
          STORE_CHILD (0);
          break;
          break;
 
 
        case 0:
        case 0:
        default:
        default:
          /* No children: nothing to do.  */
          /* No children: nothing to do.  */
          break;
          break;
        }
        }
#undef STORE_CHILD
#undef STORE_CHILD
    }
    }
 
 
  /* Never stop walk_tree.  */
  /* Never stop walk_tree.  */
  return NULL_TREE;
  return NULL_TREE;
}
}
 
 
/* Function used in TB_up_ht.  */
/* Function used in TB_up_ht.  */
 
 
static int
static int
TB_parent_eq (const void *p1, const void *p2)
TB_parent_eq (const void *p1, const void *p2)
{
{
  tree node, parent;
  tree node, parent;
  node = (tree) p2;
  node = (tree) p2;
  parent = (tree) p1;
  parent = (tree) p1;
 
 
  if (p1 == NULL || p2 == NULL)
  if (p1 == NULL || p2 == NULL)
    return 0;
    return 0;
 
 
  if (EXPRESSION_CLASS_P (parent))
  if (EXPRESSION_CLASS_P (parent))
    {
    {
 
 
#define TEST_CHILD(N) do {               \
#define TEST_CHILD(N) do {               \
  if (node == TREE_OPERAND (parent, N))  \
  if (node == TREE_OPERAND (parent, N))  \
    return 1;                            \
    return 1;                            \
} while (0)
} while (0)
 
 
    switch (TREE_CODE_LENGTH (TREE_CODE (parent)))
    switch (TREE_CODE_LENGTH (TREE_CODE (parent)))
      {
      {
      case 4:
      case 4:
        TEST_CHILD (0);
        TEST_CHILD (0);
        TEST_CHILD (1);
        TEST_CHILD (1);
        TEST_CHILD (2);
        TEST_CHILD (2);
        TEST_CHILD (3);
        TEST_CHILD (3);
        break;
        break;
 
 
      case 3:
      case 3:
        TEST_CHILD (0);
        TEST_CHILD (0);
        TEST_CHILD (1);
        TEST_CHILD (1);
        TEST_CHILD (2);
        TEST_CHILD (2);
        break;
        break;
 
 
      case 2:
      case 2:
        TEST_CHILD (0);
        TEST_CHILD (0);
        TEST_CHILD (1);
        TEST_CHILD (1);
        break;
        break;
 
 
      case 1:
      case 1:
        TEST_CHILD (0);
        TEST_CHILD (0);
        break;
        break;
 
 
      case 0:
      case 0:
      default:
      default:
        /* No children: nothing to do.  */
        /* No children: nothing to do.  */
        break;
        break;
      }
      }
#undef TEST_CHILD
#undef TEST_CHILD
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Update information about upper expressions in the hash table.  */
/* Update information about upper expressions in the hash table.  */
 
 
static void
static void
TB_update_up (tree node)
TB_update_up (tree node)
{
{
  while (node)
  while (node)
    {
    {
      walk_tree (&node, store_child_info, NULL, NULL);
      walk_tree (&node, store_child_info, NULL, NULL);
 
 
      /* Walk function's body.  */
      /* Walk function's body.  */
      if (TREE_CODE (node) == FUNCTION_DECL)
      if (TREE_CODE (node) == FUNCTION_DECL)
        if (DECL_SAVED_TREE (node))
        if (DECL_SAVED_TREE (node))
          walk_tree (&DECL_SAVED_TREE (node), store_child_info, NULL, NULL);
          walk_tree (&DECL_SAVED_TREE (node), store_child_info, NULL, NULL);
 
 
      /* Walk rest of the chain.  */
      /* Walk rest of the chain.  */
      node = TREE_CHAIN (node);
      node = TREE_CHAIN (node);
    }
    }
  fprintf (TB_OUT_FILE, "Up/prev expressions updated.\n");
  fprintf (TB_OUT_FILE, "Up/prev expressions updated.\n");
}
}
 
 
/* Parse the input string for determining the command the user asked for.  */
/* Parse the input string for determining the command the user asked for.  */
 
 
static TB_CODE
static TB_CODE
TB_get_command (char *input)
TB_get_command (char *input)
{
{
  unsigned int mn, size_tok;
  unsigned int mn, size_tok;
  int comp;
  int comp;
  char *space;
  char *space;
 
 
  space = strchr (input, ' ');
  space = strchr (input, ' ');
  if (space != NULL)
  if (space != NULL)
    size_tok = strlen (input) - strlen (space);
    size_tok = strlen (input) - strlen (space);
  else
  else
    size_tok = strlen (input) - 1;
    size_tok = strlen (input) - 1;
 
 
  for (mn = 0; mn < TB_UNUSED_COMMAND; mn++)
  for (mn = 0; mn < TB_UNUSED_COMMAND; mn++)
    {
    {
      if (size_tok != TB_COMMAND_LEN (mn))
      if (size_tok != TB_COMMAND_LEN (mn))
        continue;
        continue;
 
 
      comp = memcmp (input, TB_COMMAND_TEXT (mn), TB_COMMAND_LEN (mn));
      comp = memcmp (input, TB_COMMAND_TEXT (mn), TB_COMMAND_LEN (mn));
      if (comp == 0)
      if (comp == 0)
        /* Here we just determined the command.  If this command takes
        /* Here we just determined the command.  If this command takes
           an argument, then the argument is determined later.  */
           an argument, then the argument is determined later.  */
        return TB_COMMAND_CODE (mn);
        return TB_COMMAND_CODE (mn);
    }
    }
 
 
  /* Not a valid command.  */
  /* Not a valid command.  */
  return TB_UNUSED_COMMAND;
  return TB_UNUSED_COMMAND;
}
}
 
 
/* Parse the input string for determining the tree code.  */
/* Parse the input string for determining the tree code.  */
 
 
static enum tree_code
static enum tree_code
TB_get_tree_code (char *input)
TB_get_tree_code (char *input)
{
{
  unsigned int mn, size_tok;
  unsigned int mn, size_tok;
  int comp;
  int comp;
  char *space;
  char *space;
 
 
  space = strchr (input, ' ');
  space = strchr (input, ' ');
  if (space != NULL)
  if (space != NULL)
    size_tok = strlen (input) - strlen (space);
    size_tok = strlen (input) - strlen (space);
  else
  else
    size_tok = strlen (input) - 1;
    size_tok = strlen (input) - 1;
 
 
  for (mn = 0; mn < LAST_AND_UNUSED_TREE_CODE; mn++)
  for (mn = 0; mn < LAST_AND_UNUSED_TREE_CODE; mn++)
    {
    {
      if (size_tok != TB_TREE_CODE_LEN (mn))
      if (size_tok != TB_TREE_CODE_LEN (mn))
        continue;
        continue;
 
 
      comp = memcmp (input, TB_TREE_CODE_TEXT (mn), TB_TREE_CODE_LEN (mn));
      comp = memcmp (input, TB_TREE_CODE_TEXT (mn), TB_TREE_CODE_LEN (mn));
      if (comp == 0)
      if (comp == 0)
        {
        {
          fprintf (TB_OUT_FILE, "%s\n", TB_TREE_CODE_TEXT (mn));
          fprintf (TB_OUT_FILE, "%s\n", TB_TREE_CODE_TEXT (mn));
          return TB_TREE_CODE (mn);
          return TB_TREE_CODE (mn);
        }
        }
    }
    }
 
 
  /* This isn't a valid code.  */
  /* This isn't a valid code.  */
  return LAST_AND_UNUSED_TREE_CODE;
  return LAST_AND_UNUSED_TREE_CODE;
}
}
 
 
/* Find a node with a given code.  This function is used as an argument to
/* Find a node with a given code.  This function is used as an argument to
   walk_tree.  */
   walk_tree.  */
 
 
static tree
static tree
find_node_with_code (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
find_node_with_code (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
                     void *data)
                     void *data)
{
{
  enum tree_code *code;
  enum tree_code *code;
  code = (enum tree_code *) data;
  code = (enum tree_code *) data;
  if (*code == TREE_CODE (*tp))
  if (*code == TREE_CODE (*tp))
    return *tp;
    return *tp;
 
 
  return NULL_TREE;
  return NULL_TREE;
}
}
 
 
/* Returns a pointer to the last visited node.  */
/* Returns a pointer to the last visited node.  */
 
 
static tree
static tree
TB_history_prev (void)
TB_history_prev (void)
{
{
  if (TB_history_stack)
  if (TB_history_stack)
    {
    {
      TB_history_stack = TREE_CHAIN (TB_history_stack);
      TB_history_stack = TREE_CHAIN (TB_history_stack);
      if (TB_history_stack)
      if (TB_history_stack)
        return TREE_VALUE (TB_history_stack);
        return TREE_VALUE (TB_history_stack);
    }
    }
  return NULL_TREE;
  return NULL_TREE;
}
}
 
 
/* Read up to (and including) a '\n' from STREAM into *LINEPTR
/* Read up to (and including) a '\n' from STREAM into *LINEPTR
   (and null-terminate it). *LINEPTR is a pointer returned from malloc
   (and null-terminate it). *LINEPTR is a pointer returned from malloc
   (or NULL), pointing to *N characters of space.  It is realloc'd as
   (or NULL), pointing to *N characters of space.  It is realloc'd as
   necessary.  Returns the number of characters read (not including the
   necessary.  Returns the number of characters read (not including the
   null terminator), or -1 on error or EOF.
   null terminator), or -1 on error or EOF.
   This function comes from sed (and is supposed to be a portable version
   This function comes from sed (and is supposed to be a portable version
   of getline).  */
   of getline).  */
 
 
static long
static long
TB_getline (char **lineptr, long *n, FILE *stream)
TB_getline (char **lineptr, long *n, FILE *stream)
{
{
  char *line, *p;
  char *line, *p;
  long size, copy;
  long size, copy;
 
 
  if (lineptr == NULL || n == NULL)
  if (lineptr == NULL || n == NULL)
    {
    {
      errno = EINVAL;
      errno = EINVAL;
      return -1;
      return -1;
    }
    }
 
 
  if (ferror (stream))
  if (ferror (stream))
    return -1;
    return -1;
 
 
  /* Make sure we have a line buffer to start with.  */
  /* Make sure we have a line buffer to start with.  */
  if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars.  */
  if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars.  */
    {
    {
#ifndef MAX_CANON
#ifndef MAX_CANON
#define MAX_CANON       256
#define MAX_CANON       256
#endif
#endif
      line = (char *) xrealloc (*lineptr, MAX_CANON);
      line = (char *) xrealloc (*lineptr, MAX_CANON);
      if (line == NULL)
      if (line == NULL)
        return -1;
        return -1;
      *lineptr = line;
      *lineptr = line;
      *n = MAX_CANON;
      *n = MAX_CANON;
    }
    }
 
 
  line = *lineptr;
  line = *lineptr;
  size = *n;
  size = *n;
 
 
  copy = size;
  copy = size;
  p = line;
  p = line;
 
 
  while (1)
  while (1)
    {
    {
      long len;
      long len;
 
 
      while (--copy > 0)
      while (--copy > 0)
        {
        {
          register int c = getc (stream);
          register int c = getc (stream);
          if (c == EOF)
          if (c == EOF)
            goto lose;
            goto lose;
          else if ((*p++ = c) == '\n')
          else if ((*p++ = c) == '\n')
            goto win;
            goto win;
        }
        }
 
 
      /* Need to enlarge the line buffer.  */
      /* Need to enlarge the line buffer.  */
      len = p - line;
      len = p - line;
      size *= 2;
      size *= 2;
      line = (char *) xrealloc (line, size);
      line = (char *) xrealloc (line, size);
      if (line == NULL)
      if (line == NULL)
        goto lose;
        goto lose;
      *lineptr = line;
      *lineptr = line;
      *n = size;
      *n = size;
      p = line + len;
      p = line + len;
      copy = size - len;
      copy = size - len;
    }
    }
 
 
 lose:
 lose:
  if (p == *lineptr)
  if (p == *lineptr)
    return -1;
    return -1;
 
 
  /* Return a partial line since we got an error in the middle.  */
  /* Return a partial line since we got an error in the middle.  */
 win:
 win:
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(MSDOS)
#if defined(WIN32) || defined(_WIN32) || defined(__CYGWIN__) || defined(MSDOS)
  if (p - 2 >= *lineptr && p[-2] == '\r')
  if (p - 2 >= *lineptr && p[-2] == '\r')
    p[-2] = p[-1], --p;
    p[-2] = p[-1], --p;
#endif
#endif
  *p = '\0';
  *p = '\0';
  return p - *lineptr;
  return p - *lineptr;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.