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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [language.c] - Diff between revs 105 and 1765

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

Rev 105 Rev 1765
/* Multiple source language support for GDB.
/* Multiple source language support for GDB.
   Copyright 1991, 1992, 2000 Free Software Foundation, Inc.
   Copyright 1991, 1992, 2000 Free Software Foundation, Inc.
   Contributed by the Department of Computer Science at the State University
   Contributed by the Department of Computer Science at the State University
   of New York at Buffalo.
   of New York at Buffalo.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License 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 this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */
   Boston, MA 02111-1307, USA.  */
 
 
/* This file contains functions that return things that are specific
/* This file contains functions that return things that are specific
   to languages.  Each function should examine current_language if necessary,
   to languages.  Each function should examine current_language if necessary,
   and return the appropriate result. */
   and return the appropriate result. */
 
 
/* FIXME:  Most of these would be better organized as macros which
/* FIXME:  Most of these would be better organized as macros which
   return data out of a "language-specific" struct pointer that is set
   return data out of a "language-specific" struct pointer that is set
   whenever the working language changes.  That would be a lot faster.  */
   whenever the working language changes.  That would be a lot faster.  */
 
 
#include "defs.h"
#include "defs.h"
#include <ctype.h>
#include <ctype.h>
#include "gdb_string.h"
#include "gdb_string.h"
 
 
#include "symtab.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbtypes.h"
#include "value.h"
#include "value.h"
#include "gdbcmd.h"
#include "gdbcmd.h"
#include "frame.h"
#include "frame.h"
#include "expression.h"
#include "expression.h"
#include "language.h"
#include "language.h"
#include "target.h"
#include "target.h"
#include "parser-defs.h"
#include "parser-defs.h"
 
 
extern void _initialize_language PARAMS ((void));
extern void _initialize_language PARAMS ((void));
 
 
static void
static void
show_language_command PARAMS ((char *, int));
show_language_command PARAMS ((char *, int));
 
 
static void
static void
set_language_command PARAMS ((char *, int));
set_language_command PARAMS ((char *, int));
 
 
static void
static void
show_type_command PARAMS ((char *, int));
show_type_command PARAMS ((char *, int));
 
 
static void
static void
set_type_command PARAMS ((char *, int));
set_type_command PARAMS ((char *, int));
 
 
static void
static void
show_range_command PARAMS ((char *, int));
show_range_command PARAMS ((char *, int));
 
 
static void
static void
set_range_command PARAMS ((char *, int));
set_range_command PARAMS ((char *, int));
 
 
static void
static void
set_range_str PARAMS ((void));
set_range_str PARAMS ((void));
 
 
static void
static void
set_type_str PARAMS ((void));
set_type_str PARAMS ((void));
 
 
static void
static void
set_lang_str PARAMS ((void));
set_lang_str PARAMS ((void));
 
 
static void
static void
unk_lang_error PARAMS ((char *));
unk_lang_error PARAMS ((char *));
 
 
static int
static int
unk_lang_parser PARAMS ((void));
unk_lang_parser PARAMS ((void));
 
 
static void
static void
show_check PARAMS ((char *, int));
show_check PARAMS ((char *, int));
 
 
static void
static void
set_check PARAMS ((char *, int));
set_check PARAMS ((char *, int));
 
 
static void
static void
set_type_range PARAMS ((void));
set_type_range PARAMS ((void));
 
 
static void unk_lang_emit_char (int c, struct ui_file *stream, int quoter);
static void unk_lang_emit_char (int c, struct ui_file *stream, int quoter);
 
 
static void unk_lang_printchar (int c, struct ui_file *stream);
static void unk_lang_printchar (int c, struct ui_file *stream);
 
 
static void unk_lang_printstr (struct ui_file * stream, char *string,
static void unk_lang_printstr (struct ui_file * stream, char *string,
                               unsigned int length, int width,
                               unsigned int length, int width,
                               int force_ellipses);
                               int force_ellipses);
 
 
static struct type *
static struct type *
  unk_lang_create_fundamental_type PARAMS ((struct objfile *, int));
  unk_lang_create_fundamental_type PARAMS ((struct objfile *, int));
 
 
static void unk_lang_print_type (struct type *, char *, struct ui_file *,
static void unk_lang_print_type (struct type *, char *, struct ui_file *,
                                 int, int);
                                 int, int);
 
 
static int unk_lang_val_print (struct type *, char *, int, CORE_ADDR,
static int unk_lang_val_print (struct type *, char *, int, CORE_ADDR,
                               struct ui_file *, int, int, int,
                               struct ui_file *, int, int, int,
                               enum val_prettyprint);
                               enum val_prettyprint);
 
 
static int unk_lang_value_print (value_ptr, struct ui_file *, int, enum val_prettyprint);
static int unk_lang_value_print (value_ptr, struct ui_file *, int, enum val_prettyprint);
 
 
/* Forward declaration */
/* Forward declaration */
extern const struct language_defn unknown_language_defn;
extern const struct language_defn unknown_language_defn;
extern char *warning_pre_print;
extern char *warning_pre_print;
 
 
/* The current (default at startup) state of type and range checking.
/* The current (default at startup) state of type and range checking.
   (If the modes are set to "auto", though, these are changed based
   (If the modes are set to "auto", though, these are changed based
   on the default language at startup, and then again based on the
   on the default language at startup, and then again based on the
   language of the first source file.  */
   language of the first source file.  */
 
 
enum range_mode range_mode = range_mode_auto;
enum range_mode range_mode = range_mode_auto;
enum range_check range_check = range_check_off;
enum range_check range_check = range_check_off;
enum type_mode type_mode = type_mode_auto;
enum type_mode type_mode = type_mode_auto;
enum type_check type_check = type_check_off;
enum type_check type_check = type_check_off;
 
 
/* The current language and language_mode (see language.h) */
/* The current language and language_mode (see language.h) */
 
 
const struct language_defn *current_language = &unknown_language_defn;
const struct language_defn *current_language = &unknown_language_defn;
enum language_mode language_mode = language_mode_auto;
enum language_mode language_mode = language_mode_auto;
 
 
/* The language that the user expects to be typing in (the language
/* The language that the user expects to be typing in (the language
   of main(), or the last language we notified them about, or C).  */
   of main(), or the last language we notified them about, or C).  */
 
 
const struct language_defn *expected_language;
const struct language_defn *expected_language;
 
 
/* The list of supported languages.  The list itself is malloc'd.  */
/* The list of supported languages.  The list itself is malloc'd.  */
 
 
static const struct language_defn **languages;
static const struct language_defn **languages;
static unsigned languages_size;
static unsigned languages_size;
static unsigned languages_allocsize;
static unsigned languages_allocsize;
#define DEFAULT_ALLOCSIZE 4
#define DEFAULT_ALLOCSIZE 4
 
 
/* The "set language/type/range" commands all put stuff in these
/* The "set language/type/range" commands all put stuff in these
   buffers.  This is to make them work as set/show commands.  The
   buffers.  This is to make them work as set/show commands.  The
   user's string is copied here, then the set_* commands look at
   user's string is copied here, then the set_* commands look at
   them and update them to something that looks nice when it is
   them and update them to something that looks nice when it is
   printed out. */
   printed out. */
 
 
static char *language;
static char *language;
static char *type;
static char *type;
static char *range;
static char *range;
 
 
/* Warning issued when current_language and the language of the current
/* Warning issued when current_language and the language of the current
   frame do not match. */
   frame do not match. */
char lang_frame_mismatch_warn[] =
char lang_frame_mismatch_warn[] =
"Warning: the current language does not match this frame.";
"Warning: the current language does not match this frame.";


 
 
/* This page contains the functions corresponding to GDB commands
/* This page contains the functions corresponding to GDB commands
   and their helpers. */
   and their helpers. */
 
 
/* Show command.  Display a warning if the language set
/* Show command.  Display a warning if the language set
   does not match the frame. */
   does not match the frame. */
static void
static void
show_language_command (ignore, from_tty)
show_language_command (ignore, from_tty)
     char *ignore;
     char *ignore;
     int from_tty;
     int from_tty;
{
{
  enum language flang;          /* The language of the current frame */
  enum language flang;          /* The language of the current frame */
 
 
  flang = get_frame_language ();
  flang = get_frame_language ();
  if (flang != language_unknown &&
  if (flang != language_unknown &&
      language_mode == language_mode_manual &&
      language_mode == language_mode_manual &&
      current_language->la_language != flang)
      current_language->la_language != flang)
    printf_filtered ("%s\n", lang_frame_mismatch_warn);
    printf_filtered ("%s\n", lang_frame_mismatch_warn);
}
}
 
 
/* Set command.  Change the current working language. */
/* Set command.  Change the current working language. */
static void
static void
set_language_command (ignore, from_tty)
set_language_command (ignore, from_tty)
     char *ignore;
     char *ignore;
     int from_tty;
     int from_tty;
{
{
  int i;
  int i;
  enum language flang;
  enum language flang;
  char *err_lang;
  char *err_lang;
 
 
  if (!language || !language[0])
  if (!language || !language[0])
    {
    {
      printf_unfiltered ("The currently understood settings are:\n\n");
      printf_unfiltered ("The currently understood settings are:\n\n");
      printf_unfiltered ("local or auto    Automatic setting based on source file\n");
      printf_unfiltered ("local or auto    Automatic setting based on source file\n");
 
 
      for (i = 0; i < languages_size; ++i)
      for (i = 0; i < languages_size; ++i)
        {
        {
          /* Already dealt with these above.  */
          /* Already dealt with these above.  */
          if (languages[i]->la_language == language_unknown
          if (languages[i]->la_language == language_unknown
              || languages[i]->la_language == language_auto)
              || languages[i]->la_language == language_auto)
            continue;
            continue;
 
 
          /* FIXME for now assume that the human-readable name is just
          /* FIXME for now assume that the human-readable name is just
             a capitalization of the internal name.  */
             a capitalization of the internal name.  */
          printf_unfiltered ("%-16s Use the %c%s language\n",
          printf_unfiltered ("%-16s Use the %c%s language\n",
                             languages[i]->la_name,
                             languages[i]->la_name,
          /* Capitalize first letter of language
          /* Capitalize first letter of language
             name.  */
             name.  */
                             toupper (languages[i]->la_name[0]),
                             toupper (languages[i]->la_name[0]),
                             languages[i]->la_name + 1);
                             languages[i]->la_name + 1);
        }
        }
      /* Restore the silly string. */
      /* Restore the silly string. */
      set_language (current_language->la_language);
      set_language (current_language->la_language);
      return;
      return;
    }
    }
 
 
  /* Search the list of languages for a match.  */
  /* Search the list of languages for a match.  */
  for (i = 0; i < languages_size; i++)
  for (i = 0; i < languages_size; i++)
    {
    {
      if (STREQ (languages[i]->la_name, language))
      if (STREQ (languages[i]->la_name, language))
        {
        {
          /* Found it!  Go into manual mode, and use this language.  */
          /* Found it!  Go into manual mode, and use this language.  */
          if (languages[i]->la_language == language_auto)
          if (languages[i]->la_language == language_auto)
            {
            {
              /* Enter auto mode.  Set to the current frame's language, if known.  */
              /* Enter auto mode.  Set to the current frame's language, if known.  */
              language_mode = language_mode_auto;
              language_mode = language_mode_auto;
              flang = get_frame_language ();
              flang = get_frame_language ();
              if (flang != language_unknown)
              if (flang != language_unknown)
                set_language (flang);
                set_language (flang);
              expected_language = current_language;
              expected_language = current_language;
              return;
              return;
            }
            }
          else
          else
            {
            {
              /* Enter manual mode.  Set the specified language.  */
              /* Enter manual mode.  Set the specified language.  */
              language_mode = language_mode_manual;
              language_mode = language_mode_manual;
              current_language = languages[i];
              current_language = languages[i];
              set_type_range ();
              set_type_range ();
              set_lang_str ();
              set_lang_str ();
              expected_language = current_language;
              expected_language = current_language;
              return;
              return;
            }
            }
        }
        }
    }
    }
 
 
  /* Reset the language (esp. the global string "language") to the
  /* Reset the language (esp. the global string "language") to the
     correct values. */
     correct values. */
  err_lang = savestring (language, strlen (language));
  err_lang = savestring (language, strlen (language));
  make_cleanup (free, err_lang);        /* Free it after error */
  make_cleanup (free, err_lang);        /* Free it after error */
  set_language (current_language->la_language);
  set_language (current_language->la_language);
  error ("Unknown language `%s'.", err_lang);
  error ("Unknown language `%s'.", err_lang);
}
}
 
 
/* Show command.  Display a warning if the type setting does
/* Show command.  Display a warning if the type setting does
   not match the current language. */
   not match the current language. */
static void
static void
show_type_command (ignore, from_tty)
show_type_command (ignore, from_tty)
     char *ignore;
     char *ignore;
     int from_tty;
     int from_tty;
{
{
  if (type_check != current_language->la_type_check)
  if (type_check != current_language->la_type_check)
    printf_unfiltered (
    printf_unfiltered (
                        "Warning: the current type check setting does not match the language.\n");
                        "Warning: the current type check setting does not match the language.\n");
}
}
 
 
/* Set command.  Change the setting for type checking. */
/* Set command.  Change the setting for type checking. */
static void
static void
set_type_command (ignore, from_tty)
set_type_command (ignore, from_tty)
     char *ignore;
     char *ignore;
     int from_tty;
     int from_tty;
{
{
  if (STREQ (type, "on"))
  if (STREQ (type, "on"))
    {
    {
      type_check = type_check_on;
      type_check = type_check_on;
      type_mode = type_mode_manual;
      type_mode = type_mode_manual;
    }
    }
  else if (STREQ (type, "warn"))
  else if (STREQ (type, "warn"))
    {
    {
      type_check = type_check_warn;
      type_check = type_check_warn;
      type_mode = type_mode_manual;
      type_mode = type_mode_manual;
    }
    }
  else if (STREQ (type, "off"))
  else if (STREQ (type, "off"))
    {
    {
      type_check = type_check_off;
      type_check = type_check_off;
      type_mode = type_mode_manual;
      type_mode = type_mode_manual;
    }
    }
  else if (STREQ (type, "auto"))
  else if (STREQ (type, "auto"))
    {
    {
      type_mode = type_mode_auto;
      type_mode = type_mode_auto;
      set_type_range ();
      set_type_range ();
      /* Avoid hitting the set_type_str call below.  We
      /* Avoid hitting the set_type_str call below.  We
         did it in set_type_range. */
         did it in set_type_range. */
      return;
      return;
    }
    }
  else
  else
    {
    {
      warning ("Unrecognized type check setting: \"%s\"", type);
      warning ("Unrecognized type check setting: \"%s\"", type);
    }
    }
  set_type_str ();
  set_type_str ();
  show_type_command ((char *) NULL, from_tty);
  show_type_command ((char *) NULL, from_tty);
}
}
 
 
/* Show command.  Display a warning if the range setting does
/* Show command.  Display a warning if the range setting does
   not match the current language. */
   not match the current language. */
static void
static void
show_range_command (ignore, from_tty)
show_range_command (ignore, from_tty)
     char *ignore;
     char *ignore;
     int from_tty;
     int from_tty;
{
{
 
 
  if (range_check != current_language->la_range_check)
  if (range_check != current_language->la_range_check)
    printf_unfiltered (
    printf_unfiltered (
                        "Warning: the current range check setting does not match the language.\n");
                        "Warning: the current range check setting does not match the language.\n");
}
}
 
 
/* Set command.  Change the setting for range checking. */
/* Set command.  Change the setting for range checking. */
static void
static void
set_range_command (ignore, from_tty)
set_range_command (ignore, from_tty)
     char *ignore;
     char *ignore;
     int from_tty;
     int from_tty;
{
{
  if (STREQ (range, "on"))
  if (STREQ (range, "on"))
    {
    {
      range_check = range_check_on;
      range_check = range_check_on;
      range_mode = range_mode_manual;
      range_mode = range_mode_manual;
    }
    }
  else if (STREQ (range, "warn"))
  else if (STREQ (range, "warn"))
    {
    {
      range_check = range_check_warn;
      range_check = range_check_warn;
      range_mode = range_mode_manual;
      range_mode = range_mode_manual;
    }
    }
  else if (STREQ (range, "off"))
  else if (STREQ (range, "off"))
    {
    {
      range_check = range_check_off;
      range_check = range_check_off;
      range_mode = range_mode_manual;
      range_mode = range_mode_manual;
    }
    }
  else if (STREQ (range, "auto"))
  else if (STREQ (range, "auto"))
    {
    {
      range_mode = range_mode_auto;
      range_mode = range_mode_auto;
      set_type_range ();
      set_type_range ();
      /* Avoid hitting the set_range_str call below.  We
      /* Avoid hitting the set_range_str call below.  We
         did it in set_type_range. */
         did it in set_type_range. */
      return;
      return;
    }
    }
  else
  else
    {
    {
      warning ("Unrecognized range check setting: \"%s\"", range);
      warning ("Unrecognized range check setting: \"%s\"", range);
    }
    }
  set_range_str ();
  set_range_str ();
  show_range_command ((char *) 0, from_tty);
  show_range_command ((char *) 0, from_tty);
}
}
 
 
/* Set the status of range and type checking based on
/* Set the status of range and type checking based on
   the current modes and the current language.
   the current modes and the current language.
   If SHOW is non-zero, then print out the current language,
   If SHOW is non-zero, then print out the current language,
   type and range checking status. */
   type and range checking status. */
static void
static void
set_type_range ()
set_type_range ()
{
{
 
 
  if (range_mode == range_mode_auto)
  if (range_mode == range_mode_auto)
    range_check = current_language->la_range_check;
    range_check = current_language->la_range_check;
 
 
  if (type_mode == type_mode_auto)
  if (type_mode == type_mode_auto)
    type_check = current_language->la_type_check;
    type_check = current_language->la_type_check;
 
 
  set_type_str ();
  set_type_str ();
  set_range_str ();
  set_range_str ();
}
}
 
 
/* Set current language to (enum language) LANG.  Returns previous language. */
/* Set current language to (enum language) LANG.  Returns previous language. */
 
 
enum language
enum language
set_language (lang)
set_language (lang)
     enum language lang;
     enum language lang;
{
{
  int i;
  int i;
  enum language prev_language;
  enum language prev_language;
 
 
  prev_language = current_language->la_language;
  prev_language = current_language->la_language;
 
 
  for (i = 0; i < languages_size; i++)
  for (i = 0; i < languages_size; i++)
    {
    {
      if (languages[i]->la_language == lang)
      if (languages[i]->la_language == lang)
        {
        {
          current_language = languages[i];
          current_language = languages[i];
          set_type_range ();
          set_type_range ();
          set_lang_str ();
          set_lang_str ();
          break;
          break;
        }
        }
    }
    }
 
 
  return prev_language;
  return prev_language;
}
}


/* This page contains functions that update the global vars
/* This page contains functions that update the global vars
   language, type and range. */
   language, type and range. */
static void
static void
set_lang_str ()
set_lang_str ()
{
{
  char *prefix = "";
  char *prefix = "";
 
 
  if (language)
  if (language)
    free (language);
    free (language);
  if (language_mode == language_mode_auto)
  if (language_mode == language_mode_auto)
    prefix = "auto; currently ";
    prefix = "auto; currently ";
 
 
  language = concat (prefix, current_language->la_name, NULL);
  language = concat (prefix, current_language->la_name, NULL);
}
}
 
 
static void
static void
set_type_str ()
set_type_str ()
{
{
  char *tmp = NULL, *prefix = "";
  char *tmp = NULL, *prefix = "";
 
 
  if (type)
  if (type)
    free (type);
    free (type);
  if (type_mode == type_mode_auto)
  if (type_mode == type_mode_auto)
    prefix = "auto; currently ";
    prefix = "auto; currently ";
 
 
  switch (type_check)
  switch (type_check)
    {
    {
    case type_check_on:
    case type_check_on:
      tmp = "on";
      tmp = "on";
      break;
      break;
    case type_check_off:
    case type_check_off:
      tmp = "off";
      tmp = "off";
      break;
      break;
    case type_check_warn:
    case type_check_warn:
      tmp = "warn";
      tmp = "warn";
      break;
      break;
    default:
    default:
      error ("Unrecognized type check setting.");
      error ("Unrecognized type check setting.");
    }
    }
 
 
  type = concat (prefix, tmp, NULL);
  type = concat (prefix, tmp, NULL);
}
}
 
 
static void
static void
set_range_str ()
set_range_str ()
{
{
  char *tmp, *pref = "";
  char *tmp, *pref = "";
 
 
  if (range_mode == range_mode_auto)
  if (range_mode == range_mode_auto)
    pref = "auto; currently ";
    pref = "auto; currently ";
 
 
  switch (range_check)
  switch (range_check)
    {
    {
    case range_check_on:
    case range_check_on:
      tmp = "on";
      tmp = "on";
      break;
      break;
    case range_check_off:
    case range_check_off:
      tmp = "off";
      tmp = "off";
      break;
      break;
    case range_check_warn:
    case range_check_warn:
      tmp = "warn";
      tmp = "warn";
      break;
      break;
    default:
    default:
      error ("Unrecognized range check setting.");
      error ("Unrecognized range check setting.");
    }
    }
 
 
  if (range)
  if (range)
    free (range);
    free (range);
  range = concat (pref, tmp, NULL);
  range = concat (pref, tmp, NULL);
}
}
 
 
 
 
/* Print out the current language settings: language, range and
/* Print out the current language settings: language, range and
   type checking.  If QUIETLY, print only what has changed.  */
   type checking.  If QUIETLY, print only what has changed.  */
 
 
void
void
language_info (quietly)
language_info (quietly)
     int quietly;
     int quietly;
{
{
  if (quietly && expected_language == current_language)
  if (quietly && expected_language == current_language)
    return;
    return;
 
 
  expected_language = current_language;
  expected_language = current_language;
  printf_unfiltered ("Current language:  %s\n", language);
  printf_unfiltered ("Current language:  %s\n", language);
  show_language_command ((char *) 0, 1);
  show_language_command ((char *) 0, 1);
 
 
  if (!quietly)
  if (!quietly)
    {
    {
      printf_unfiltered ("Type checking:     %s\n", type);
      printf_unfiltered ("Type checking:     %s\n", type);
      show_type_command ((char *) 0, 1);
      show_type_command ((char *) 0, 1);
      printf_unfiltered ("Range checking:    %s\n", range);
      printf_unfiltered ("Range checking:    %s\n", range);
      show_range_command ((char *) 0, 1);
      show_range_command ((char *) 0, 1);
    }
    }
}
}


/* Return the result of a binary operation. */
/* Return the result of a binary operation. */
 
 
#if 0                           /* Currently unused */
#if 0                           /* Currently unused */
 
 
struct type *
struct type *
binop_result_type (v1, v2)
binop_result_type (v1, v2)
     value_ptr v1, v2;
     value_ptr v1, v2;
{
{
  int size, uns;
  int size, uns;
  struct type *t1 = check_typedef (VALUE_TYPE (v1));
  struct type *t1 = check_typedef (VALUE_TYPE (v1));
  struct type *t2 = check_typedef (VALUE_TYPE (v2));
  struct type *t2 = check_typedef (VALUE_TYPE (v2));
 
 
  int l1 = TYPE_LENGTH (t1);
  int l1 = TYPE_LENGTH (t1);
  int l2 = TYPE_LENGTH (t2);
  int l2 = TYPE_LENGTH (t2);
 
 
  switch (current_language->la_language)
  switch (current_language->la_language)
    {
    {
    case language_c:
    case language_c:
    case language_cplus:
    case language_cplus:
      if (TYPE_CODE (t1) == TYPE_CODE_FLT)
      if (TYPE_CODE (t1) == TYPE_CODE_FLT)
        return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ?
        return TYPE_CODE (t2) == TYPE_CODE_FLT && l2 > l1 ?
          VALUE_TYPE (v2) : VALUE_TYPE (v1);
          VALUE_TYPE (v2) : VALUE_TYPE (v1);
      else if (TYPE_CODE (t2) == TYPE_CODE_FLT)
      else if (TYPE_CODE (t2) == TYPE_CODE_FLT)
        return TYPE_CODE (t1) == TYPE_CODE_FLT && l1 > l2 ?
        return TYPE_CODE (t1) == TYPE_CODE_FLT && l1 > l2 ?
          VALUE_TYPE (v1) : VALUE_TYPE (v2);
          VALUE_TYPE (v1) : VALUE_TYPE (v2);
      else if (TYPE_UNSIGNED (t1) && l1 > l2)
      else if (TYPE_UNSIGNED (t1) && l1 > l2)
        return VALUE_TYPE (v1);
        return VALUE_TYPE (v1);
      else if (TYPE_UNSIGNED (t2) && l2 > l1)
      else if (TYPE_UNSIGNED (t2) && l2 > l1)
        return VALUE_TYPE (v2);
        return VALUE_TYPE (v2);
      else                      /* Both are signed.  Result is the longer type */
      else                      /* Both are signed.  Result is the longer type */
        return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
        return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
      break;
      break;
    case language_m2:
    case language_m2:
      /* If we are doing type-checking, l1 should equal l2, so this is
      /* If we are doing type-checking, l1 should equal l2, so this is
         not needed. */
         not needed. */
      return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
      return l1 > l2 ? VALUE_TYPE (v1) : VALUE_TYPE (v2);
      break;
      break;
    case language_chill:
    case language_chill:
      error ("Missing Chill support in function binop_result_check.");  /*FIXME */
      error ("Missing Chill support in function binop_result_check.");  /*FIXME */
    }
    }
  abort ();
  abort ();
  return (struct type *) 0;      /* For lint */
  return (struct type *) 0;      /* For lint */
}
}
 
 
#endif /* 0 */
#endif /* 0 */


 
 
/* This page contains functions that return format strings for
/* This page contains functions that return format strings for
   printf for printing out numbers in different formats */
   printf for printing out numbers in different formats */
 
 
/* Returns the appropriate printf format for hexadecimal
/* Returns the appropriate printf format for hexadecimal
   numbers. */
   numbers. */
char *
char *
local_hex_format_custom (pre)
local_hex_format_custom (pre)
     char *pre;
     char *pre;
{
{
  static char form[50];
  static char form[50];
 
 
  strcpy (form, local_hex_format_prefix ());
  strcpy (form, local_hex_format_prefix ());
  strcat (form, "%");
  strcat (form, "%");
  strcat (form, pre);
  strcat (form, pre);
  strcat (form, local_hex_format_specifier ());
  strcat (form, local_hex_format_specifier ());
  strcat (form, local_hex_format_suffix ());
  strcat (form, local_hex_format_suffix ());
  return form;
  return form;
}
}
 
 
#if 0
#if 0
/* FIXME: cagney/2000-03-04: This function does not appear to be used.
/* FIXME: cagney/2000-03-04: This function does not appear to be used.
   It can be deleted once 5.0 has been released. */
   It can be deleted once 5.0 has been released. */
/* FIXME: cagney/2000-03-04: This code assumes that the compiler
/* FIXME: cagney/2000-03-04: This code assumes that the compiler
   supports ``long long''. */
   supports ``long long''. */
/* Converts a number to hexadecimal (without leading "0x") and stores it in a
/* Converts a number to hexadecimal (without leading "0x") and stores it in a
   static string.  Returns a pointer to this string. */
   static string.  Returns a pointer to this string. */
 
 
char *
char *
longest_raw_hex_string (num)
longest_raw_hex_string (num)
     LONGEST num;
     LONGEST num;
{
{
  static char res_longest_raw_hex_string[50];
  static char res_longest_raw_hex_string[50];
  long long ll = num;           /* MERGEBUG ?? see below */
  long long ll = num;           /* MERGEBUG ?? see below */
  res_longest_raw_hex_string[0] = 0;
  res_longest_raw_hex_string[0] = 0;
  /* MERGEBUG ?? As a quick fix I am replacing this with sprintf
  /* MERGEBUG ?? As a quick fix I am replacing this with sprintf
     strcat_address_numeric (num, 0, res_longest_raw_hex_string, 50);
     strcat_address_numeric (num, 0, res_longest_raw_hex_string, 50);
   */
   */
 
 
  sprintf (res_longest_raw_hex_string, "%llx", ll);
  sprintf (res_longest_raw_hex_string, "%llx", ll);
  return res_longest_raw_hex_string;
  return res_longest_raw_hex_string;
}
}
#endif
#endif
 
 
/* Converts a number to hexadecimal and stores it in a static
/* Converts a number to hexadecimal and stores it in a static
   string.  Returns a pointer to this string. */
   string.  Returns a pointer to this string. */
char *
char *
local_hex_string (num)
local_hex_string (num)
     unsigned long num;
     unsigned long num;
{
{
  static char res[50];
  static char res[50];
 
 
  sprintf (res, local_hex_format (), num);
  sprintf (res, local_hex_format (), num);
  return res;
  return res;
}
}
 
 
/* Converts a LONGEST number to hexadecimal and stores it in a static
/* Converts a LONGEST number to hexadecimal and stores it in a static
   string.  Returns a pointer to this string. */
   string.  Returns a pointer to this string. */
char *
char *
longest_local_hex_string (num)
longest_local_hex_string (num)
     LONGEST num;
     LONGEST num;
{
{
  return longest_local_hex_string_custom (num, "l");
  return longest_local_hex_string_custom (num, "l");
}
}
 
 
/* Converts a number to custom hexadecimal and stores it in a static
/* Converts a number to custom hexadecimal and stores it in a static
   string.  Returns a pointer to this string. */
   string.  Returns a pointer to this string. */
char *
char *
local_hex_string_custom (num, pre)
local_hex_string_custom (num, pre)
     unsigned long num;
     unsigned long num;
     char *pre;
     char *pre;
{
{
  static char res[50];
  static char res[50];
 
 
  sprintf (res, local_hex_format_custom (pre), num);
  sprintf (res, local_hex_format_custom (pre), num);
  return res;
  return res;
}
}
 
 
/* Converts a LONGEST number to custom hexadecimal and stores it in a static
/* Converts a LONGEST number to custom hexadecimal and stores it in a static
   string.  Returns a pointer to this string. Note that the width parameter
   string.  Returns a pointer to this string. Note that the width parameter
   should end with "l", e.g. "08l" as with calls to local_hex_string_custom */
   should end with "l", e.g. "08l" as with calls to local_hex_string_custom */
 
 
char *
char *
longest_local_hex_string_custom (num, width)
longest_local_hex_string_custom (num, width)
     LONGEST num;
     LONGEST num;
     char *width;
     char *width;
{
{
#define RESULT_BUF_LEN 50
#define RESULT_BUF_LEN 50
  static char res2[RESULT_BUF_LEN];
  static char res2[RESULT_BUF_LEN];
  char format[RESULT_BUF_LEN];
  char format[RESULT_BUF_LEN];
#if !defined (PRINTF_HAS_LONG_LONG)
#if !defined (PRINTF_HAS_LONG_LONG)
  int field_width;
  int field_width;
  int num_len;
  int num_len;
  int num_pad_chars;
  int num_pad_chars;
  char *pad_char;               /* string with one character */
  char *pad_char;               /* string with one character */
  int pad_on_left;
  int pad_on_left;
  char *parse_ptr;
  char *parse_ptr;
  char temp_nbr_buf[RESULT_BUF_LEN];
  char temp_nbr_buf[RESULT_BUF_LEN];
#endif
#endif
 
 
#ifndef CC_HAS_LONG_LONG
#ifndef CC_HAS_LONG_LONG
  /* If there is no long long, then LONGEST should be just long and we
  /* If there is no long long, then LONGEST should be just long and we
     can use local_hex_string_custom
     can use local_hex_string_custom
   */
   */
  return local_hex_string_custom ((unsigned long) num, width);
  return local_hex_string_custom ((unsigned long) num, width);
#elif defined (PRINTF_HAS_LONG_LONG)
#elif defined (PRINTF_HAS_LONG_LONG)
  /* Just use printf.  */
  /* Just use printf.  */
  strcpy (format, local_hex_format_prefix ());  /* 0x */
  strcpy (format, local_hex_format_prefix ());  /* 0x */
  strcat (format, "%");
  strcat (format, "%");
  strcat (format, width);       /* e.g. "08l" */
  strcat (format, width);       /* e.g. "08l" */
  strcat (format, "l");         /* need "ll" for long long */
  strcat (format, "l");         /* need "ll" for long long */
  strcat (format, local_hex_format_specifier ());       /* "x" */
  strcat (format, local_hex_format_specifier ());       /* "x" */
  strcat (format, local_hex_format_suffix ());  /* "" */
  strcat (format, local_hex_format_suffix ());  /* "" */
  sprintf (res2, format, num);
  sprintf (res2, format, num);
  return res2;
  return res2;
#else /* !defined (PRINTF_HAS_LONG_LONG) */
#else /* !defined (PRINTF_HAS_LONG_LONG) */
  /* Use strcat_address_numeric to print the number into a string, then
  /* Use strcat_address_numeric to print the number into a string, then
     build the result string from local_hex_format_prefix, padding and
     build the result string from local_hex_format_prefix, padding and
     the hex representation as indicated by "width".  */
     the hex representation as indicated by "width".  */
 
 
  temp_nbr_buf[0] = 0;
  temp_nbr_buf[0] = 0;
  /* With use_local == 0, we don't get the leading "0x" prefix. */
  /* With use_local == 0, we don't get the leading "0x" prefix. */
  /* MERGEBUG ?? As a quick fix I am replacing this call to
  /* MERGEBUG ?? As a quick fix I am replacing this call to
     strcat_address_numeric with sprintf
     strcat_address_numeric with sprintf
     strcat_address_numeric(num, 0, temp_nbr_buf, RESULT_BUF_LEN);
     strcat_address_numeric(num, 0, temp_nbr_buf, RESULT_BUF_LEN);
   */
   */
 
 
  {
  {
    long long ll = num;
    long long ll = num;
    sprintf (temp_nbr_buf, "%llx", ll);
    sprintf (temp_nbr_buf, "%llx", ll);
  }
  }
  /* parse width */
  /* parse width */
  parse_ptr = width;
  parse_ptr = width;
  pad_on_left = 1;
  pad_on_left = 1;
  pad_char = " ";
  pad_char = " ";
  if (*parse_ptr == '-')
  if (*parse_ptr == '-')
    {
    {
      parse_ptr++;
      parse_ptr++;
      pad_on_left = 0;
      pad_on_left = 0;
    }
    }
  if (*parse_ptr == '0')
  if (*parse_ptr == '0')
    {
    {
      parse_ptr++;
      parse_ptr++;
      if (pad_on_left)
      if (pad_on_left)
        pad_char = "0";          /* If padding is on the right, it is blank */
        pad_char = "0";          /* If padding is on the right, it is blank */
    }
    }
  field_width = atoi (parse_ptr);
  field_width = atoi (parse_ptr);
  num_len = strlen (temp_nbr_buf);
  num_len = strlen (temp_nbr_buf);
  num_pad_chars = field_width - strlen (temp_nbr_buf);  /* possibly negative */
  num_pad_chars = field_width - strlen (temp_nbr_buf);  /* possibly negative */
 
 
  if (strlen (local_hex_format_prefix ()) + num_len + num_pad_chars
  if (strlen (local_hex_format_prefix ()) + num_len + num_pad_chars
      < RESULT_BUF_LEN)         /* paranoia */
      < RESULT_BUF_LEN)         /* paranoia */
    internal_error ("longest_local_hex_string_custom: insufficient space to store result");
    internal_error ("longest_local_hex_string_custom: insufficient space to store result");
 
 
  strcpy (res2, local_hex_format_prefix ());
  strcpy (res2, local_hex_format_prefix ());
  if (pad_on_left)
  if (pad_on_left)
    {
    {
      while (num_pad_chars > 0)
      while (num_pad_chars > 0)
        {
        {
          strcat (res2, pad_char);
          strcat (res2, pad_char);
          num_pad_chars--;
          num_pad_chars--;
        }
        }
    }
    }
  strcat (res2, temp_nbr_buf);
  strcat (res2, temp_nbr_buf);
  if (!pad_on_left)
  if (!pad_on_left)
    {
    {
      while (num_pad_chars > 0)
      while (num_pad_chars > 0)
        {
        {
          strcat (res2, pad_char);
          strcat (res2, pad_char);
          num_pad_chars--;
          num_pad_chars--;
        }
        }
    }
    }
  return res2;
  return res2;
#endif
#endif
 
 
}                               /* longest_local_hex_string_custom */
}                               /* longest_local_hex_string_custom */
 
 
/* Returns the appropriate printf format for octal
/* Returns the appropriate printf format for octal
   numbers. */
   numbers. */
char *
char *
local_octal_format_custom (pre)
local_octal_format_custom (pre)
     char *pre;
     char *pre;
{
{
  static char form[50];
  static char form[50];
 
 
  strcpy (form, local_octal_format_prefix ());
  strcpy (form, local_octal_format_prefix ());
  strcat (form, "%");
  strcat (form, "%");
  strcat (form, pre);
  strcat (form, pre);
  strcat (form, local_octal_format_specifier ());
  strcat (form, local_octal_format_specifier ());
  strcat (form, local_octal_format_suffix ());
  strcat (form, local_octal_format_suffix ());
  return form;
  return form;
}
}
 
 
/* Returns the appropriate printf format for decimal numbers. */
/* Returns the appropriate printf format for decimal numbers. */
char *
char *
local_decimal_format_custom (pre)
local_decimal_format_custom (pre)
     char *pre;
     char *pre;
{
{
  static char form[50];
  static char form[50];
 
 
  strcpy (form, local_decimal_format_prefix ());
  strcpy (form, local_decimal_format_prefix ());
  strcat (form, "%");
  strcat (form, "%");
  strcat (form, pre);
  strcat (form, pre);
  strcat (form, local_decimal_format_specifier ());
  strcat (form, local_decimal_format_specifier ());
  strcat (form, local_decimal_format_suffix ());
  strcat (form, local_decimal_format_suffix ());
  return form;
  return form;
}
}


#if 0
#if 0
/* This page contains functions that are used in type/range checking.
/* This page contains functions that are used in type/range checking.
   They all return zero if the type/range check fails.
   They all return zero if the type/range check fails.
 
 
   It is hoped that these will make extending GDB to parse different
   It is hoped that these will make extending GDB to parse different
   languages a little easier.  These are primarily used in eval.c when
   languages a little easier.  These are primarily used in eval.c when
   evaluating expressions and making sure that their types are correct.
   evaluating expressions and making sure that their types are correct.
   Instead of having a mess of conjucted/disjuncted expressions in an "if",
   Instead of having a mess of conjucted/disjuncted expressions in an "if",
   the ideas of type can be wrapped up in the following functions.
   the ideas of type can be wrapped up in the following functions.
 
 
   Note that some of them are not currently dependent upon which language
   Note that some of them are not currently dependent upon which language
   is currently being parsed.  For example, floats are the same in
   is currently being parsed.  For example, floats are the same in
   C and Modula-2 (ie. the only floating point type has TYPE_CODE of
   C and Modula-2 (ie. the only floating point type has TYPE_CODE of
   TYPE_CODE_FLT), while booleans are different. */
   TYPE_CODE_FLT), while booleans are different. */
 
 
/* Returns non-zero if its argument is a simple type.  This is the same for
/* Returns non-zero if its argument is a simple type.  This is the same for
   both Modula-2 and for C.  In the C case, TYPE_CODE_CHAR will never occur,
   both Modula-2 and for C.  In the C case, TYPE_CODE_CHAR will never occur,
   and thus will never cause the failure of the test. */
   and thus will never cause the failure of the test. */
int
int
simple_type (type)
simple_type (type)
     struct type *type;
     struct type *type;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  switch (TYPE_CODE (type))
  switch (TYPE_CODE (type))
    {
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_FLT:
    case TYPE_CODE_FLT:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_BOOL:
      return 1;
      return 1;
 
 
    default:
    default:
      return 0;
      return 0;
    }
    }
}
}
 
 
/* Returns non-zero if its argument is of an ordered type.
/* Returns non-zero if its argument is of an ordered type.
   An ordered type is one in which the elements can be tested for the
   An ordered type is one in which the elements can be tested for the
   properties of "greater than", "less than", etc, or for which the
   properties of "greater than", "less than", etc, or for which the
   operations "increment" or "decrement" make sense. */
   operations "increment" or "decrement" make sense. */
int
int
ordered_type (type)
ordered_type (type)
     struct type *type;
     struct type *type;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  switch (TYPE_CODE (type))
  switch (TYPE_CODE (type))
    {
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_FLT:
    case TYPE_CODE_FLT:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_RANGE:
      return 1;
      return 1;
 
 
    default:
    default:
      return 0;
      return 0;
    }
    }
}
}
 
 
/* Returns non-zero if the two types are the same */
/* Returns non-zero if the two types are the same */
int
int
same_type (arg1, arg2)
same_type (arg1, arg2)
     struct type *arg1, *arg2;
     struct type *arg1, *arg2;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  if (structured_type (arg1) ? !structured_type (arg2) : structured_type (arg2))
  if (structured_type (arg1) ? !structured_type (arg2) : structured_type (arg2))
    /* One is structured and one isn't */
    /* One is structured and one isn't */
    return 0;
    return 0;
  else if (structured_type (arg1) && structured_type (arg2))
  else if (structured_type (arg1) && structured_type (arg2))
    return arg1 == arg2;
    return arg1 == arg2;
  else if (numeric_type (arg1) && numeric_type (arg2))
  else if (numeric_type (arg1) && numeric_type (arg2))
    return (TYPE_CODE (arg2) == TYPE_CODE (arg1)) &&
    return (TYPE_CODE (arg2) == TYPE_CODE (arg1)) &&
      (TYPE_UNSIGNED (arg1) == TYPE_UNSIGNED (arg2))
      (TYPE_UNSIGNED (arg1) == TYPE_UNSIGNED (arg2))
      ? 1 : 0;
      ? 1 : 0;
  else
  else
    return arg1 == arg2;
    return arg1 == arg2;
}
}
 
 
/* Returns non-zero if the type is integral */
/* Returns non-zero if the type is integral */
int
int
integral_type (type)
integral_type (type)
     struct type *type;
     struct type *type;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  switch (current_language->la_language)
  switch (current_language->la_language)
    {
    {
    case language_c:
    case language_c:
    case language_cplus:
    case language_cplus:
      return (TYPE_CODE (type) != TYPE_CODE_INT) &&
      return (TYPE_CODE (type) != TYPE_CODE_INT) &&
        (TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1;
        (TYPE_CODE (type) != TYPE_CODE_ENUM) ? 0 : 1;
    case language_m2:
    case language_m2:
      return TYPE_CODE (type) != TYPE_CODE_INT ? 0 : 1;
      return TYPE_CODE (type) != TYPE_CODE_INT ? 0 : 1;
    case language_chill:
    case language_chill:
      error ("Missing Chill support in function integral_type.");       /*FIXME */
      error ("Missing Chill support in function integral_type.");       /*FIXME */
    default:
    default:
      error ("Language not supported.");
      error ("Language not supported.");
    }
    }
}
}
 
 
/* Returns non-zero if the value is numeric */
/* Returns non-zero if the value is numeric */
int
int
numeric_type (type)
numeric_type (type)
     struct type *type;
     struct type *type;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  switch (TYPE_CODE (type))
  switch (TYPE_CODE (type))
    {
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_INT:
    case TYPE_CODE_FLT:
    case TYPE_CODE_FLT:
      return 1;
      return 1;
 
 
    default:
    default:
      return 0;
      return 0;
    }
    }
}
}
 
 
/* Returns non-zero if the value is a character type */
/* Returns non-zero if the value is a character type */
int
int
character_type (type)
character_type (type)
     struct type *type;
     struct type *type;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  switch (current_language->la_language)
  switch (current_language->la_language)
    {
    {
    case language_chill:
    case language_chill:
    case language_m2:
    case language_m2:
      return TYPE_CODE (type) != TYPE_CODE_CHAR ? 0 : 1;
      return TYPE_CODE (type) != TYPE_CODE_CHAR ? 0 : 1;
 
 
    case language_c:
    case language_c:
    case language_cplus:
    case language_cplus:
      return (TYPE_CODE (type) == TYPE_CODE_INT) &&
      return (TYPE_CODE (type) == TYPE_CODE_INT) &&
        TYPE_LENGTH (type) == sizeof (char)
        TYPE_LENGTH (type) == sizeof (char)
      ? 1 : 0;
      ? 1 : 0;
    default:
    default:
      return (0);
      return (0);
    }
    }
}
}
 
 
/* Returns non-zero if the value is a string type */
/* Returns non-zero if the value is a string type */
int
int
string_type (type)
string_type (type)
     struct type *type;
     struct type *type;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  switch (current_language->la_language)
  switch (current_language->la_language)
    {
    {
    case language_chill:
    case language_chill:
    case language_m2:
    case language_m2:
      return TYPE_CODE (type) != TYPE_CODE_STRING ? 0 : 1;
      return TYPE_CODE (type) != TYPE_CODE_STRING ? 0 : 1;
 
 
    case language_c:
    case language_c:
    case language_cplus:
    case language_cplus:
      /* C does not have distinct string type. */
      /* C does not have distinct string type. */
      return (0);
      return (0);
    default:
    default:
      return (0);
      return (0);
    }
    }
}
}
 
 
/* Returns non-zero if the value is a boolean type */
/* Returns non-zero if the value is a boolean type */
int
int
boolean_type (type)
boolean_type (type)
     struct type *type;
     struct type *type;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  if (TYPE_CODE (type) == TYPE_CODE_BOOL)
  if (TYPE_CODE (type) == TYPE_CODE_BOOL)
    return 1;
    return 1;
  switch (current_language->la_language)
  switch (current_language->la_language)
    {
    {
    case language_c:
    case language_c:
    case language_cplus:
    case language_cplus:
      /* Might be more cleanly handled by having a TYPE_CODE_INT_NOT_BOOL
      /* Might be more cleanly handled by having a TYPE_CODE_INT_NOT_BOOL
         for CHILL and such languages, or a TYPE_CODE_INT_OR_BOOL for C.  */
         for CHILL and such languages, or a TYPE_CODE_INT_OR_BOOL for C.  */
      if (TYPE_CODE (type) == TYPE_CODE_INT)
      if (TYPE_CODE (type) == TYPE_CODE_INT)
        return 1;
        return 1;
    default:
    default:
      break;
      break;
    }
    }
  return 0;
  return 0;
}
}
 
 
/* Returns non-zero if the value is a floating-point type */
/* Returns non-zero if the value is a floating-point type */
int
int
float_type (type)
float_type (type)
     struct type *type;
     struct type *type;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  return TYPE_CODE (type) == TYPE_CODE_FLT;
  return TYPE_CODE (type) == TYPE_CODE_FLT;
}
}
 
 
/* Returns non-zero if the value is a pointer type */
/* Returns non-zero if the value is a pointer type */
int
int
pointer_type (type)
pointer_type (type)
     struct type *type;
     struct type *type;
{
{
  return TYPE_CODE (type) == TYPE_CODE_PTR ||
  return TYPE_CODE (type) == TYPE_CODE_PTR ||
    TYPE_CODE (type) == TYPE_CODE_REF;
    TYPE_CODE (type) == TYPE_CODE_REF;
}
}
 
 
/* Returns non-zero if the value is a structured type */
/* Returns non-zero if the value is a structured type */
int
int
structured_type (type)
structured_type (type)
     struct type *type;
     struct type *type;
{
{
  CHECK_TYPEDEF (type);
  CHECK_TYPEDEF (type);
  switch (current_language->la_language)
  switch (current_language->la_language)
    {
    {
    case language_c:
    case language_c:
    case language_cplus:
    case language_cplus:
      return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
      return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
        (TYPE_CODE (type) == TYPE_CODE_UNION) ||
        (TYPE_CODE (type) == TYPE_CODE_UNION) ||
        (TYPE_CODE (type) == TYPE_CODE_ARRAY);
        (TYPE_CODE (type) == TYPE_CODE_ARRAY);
    case language_m2:
    case language_m2:
      return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
      return (TYPE_CODE (type) == TYPE_CODE_STRUCT) ||
        (TYPE_CODE (type) == TYPE_CODE_SET) ||
        (TYPE_CODE (type) == TYPE_CODE_SET) ||
        (TYPE_CODE (type) == TYPE_CODE_ARRAY);
        (TYPE_CODE (type) == TYPE_CODE_ARRAY);
    case language_chill:
    case language_chill:
      error ("Missing Chill support in function structured_type.");     /*FIXME */
      error ("Missing Chill support in function structured_type.");     /*FIXME */
    default:
    default:
      return (0);
      return (0);
    }
    }
}
}
#endif
#endif


struct type *
struct type *
lang_bool_type ()
lang_bool_type ()
{
{
  struct symbol *sym;
  struct symbol *sym;
  struct type *type;
  struct type *type;
  switch (current_language->la_language)
  switch (current_language->la_language)
    {
    {
    case language_chill:
    case language_chill:
      return builtin_type_chill_bool;
      return builtin_type_chill_bool;
    case language_fortran:
    case language_fortran:
      sym = lookup_symbol ("logical", NULL, VAR_NAMESPACE, NULL, NULL);
      sym = lookup_symbol ("logical", NULL, VAR_NAMESPACE, NULL, NULL);
      if (sym)
      if (sym)
        {
        {
          type = SYMBOL_TYPE (sym);
          type = SYMBOL_TYPE (sym);
          if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
          if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
            return type;
            return type;
        }
        }
      return builtin_type_f_logical_s2;
      return builtin_type_f_logical_s2;
    case language_cplus:
    case language_cplus:
      sym = lookup_symbol ("bool", NULL, VAR_NAMESPACE, NULL, NULL);
      sym = lookup_symbol ("bool", NULL, VAR_NAMESPACE, NULL, NULL);
      if (sym)
      if (sym)
        {
        {
          type = SYMBOL_TYPE (sym);
          type = SYMBOL_TYPE (sym);
          if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
          if (type && TYPE_CODE (type) == TYPE_CODE_BOOL)
            return type;
            return type;
        }
        }
      return builtin_type_bool;
      return builtin_type_bool;
    default:
    default:
      return builtin_type_int;
      return builtin_type_int;
    }
    }
}
}


/* This page contains functions that return info about
/* This page contains functions that return info about
   (struct value) values used in GDB. */
   (struct value) values used in GDB. */
 
 
/* Returns non-zero if the value VAL represents a true value. */
/* Returns non-zero if the value VAL represents a true value. */
int
int
value_true (val)
value_true (val)
     value_ptr val;
     value_ptr val;
{
{
  /* It is possible that we should have some sort of error if a non-boolean
  /* It is possible that we should have some sort of error if a non-boolean
     value is used in this context.  Possibly dependent on some kind of
     value is used in this context.  Possibly dependent on some kind of
     "boolean-checking" option like range checking.  But it should probably
     "boolean-checking" option like range checking.  But it should probably
     not depend on the language except insofar as is necessary to identify
     not depend on the language except insofar as is necessary to identify
     a "boolean" value (i.e. in C using a float, pointer, etc., as a boolean
     a "boolean" value (i.e. in C using a float, pointer, etc., as a boolean
     should be an error, probably).  */
     should be an error, probably).  */
  return !value_logical_not (val);
  return !value_logical_not (val);
}
}


/* Returns non-zero if the operator OP is defined on
/* Returns non-zero if the operator OP is defined on
   the values ARG1 and ARG2. */
   the values ARG1 and ARG2. */
 
 
#if 0                           /* Currently unused */
#if 0                           /* Currently unused */
 
 
void
void
binop_type_check (arg1, arg2, op)
binop_type_check (arg1, arg2, op)
     value_ptr arg1, arg2;
     value_ptr arg1, arg2;
     int op;
     int op;
{
{
  struct type *t1, *t2;
  struct type *t1, *t2;
 
 
  /* If we're not checking types, always return success. */
  /* If we're not checking types, always return success. */
  if (!STRICT_TYPE)
  if (!STRICT_TYPE)
    return;
    return;
 
 
  t1 = VALUE_TYPE (arg1);
  t1 = VALUE_TYPE (arg1);
  if (arg2 != NULL)
  if (arg2 != NULL)
    t2 = VALUE_TYPE (arg2);
    t2 = VALUE_TYPE (arg2);
  else
  else
    t2 = NULL;
    t2 = NULL;
 
 
  switch (op)
  switch (op)
    {
    {
    case BINOP_ADD:
    case BINOP_ADD:
    case BINOP_SUB:
    case BINOP_SUB:
      if ((numeric_type (t1) && pointer_type (t2)) ||
      if ((numeric_type (t1) && pointer_type (t2)) ||
          (pointer_type (t1) && numeric_type (t2)))
          (pointer_type (t1) && numeric_type (t2)))
        {
        {
          warning ("combining pointer and integer.\n");
          warning ("combining pointer and integer.\n");
          break;
          break;
        }
        }
    case BINOP_MUL:
    case BINOP_MUL:
    case BINOP_LSH:
    case BINOP_LSH:
    case BINOP_RSH:
    case BINOP_RSH:
      if (!numeric_type (t1) || !numeric_type (t2))
      if (!numeric_type (t1) || !numeric_type (t2))
        type_op_error ("Arguments to %s must be numbers.", op);
        type_op_error ("Arguments to %s must be numbers.", op);
      else if (!same_type (t1, t2))
      else if (!same_type (t1, t2))
        type_op_error ("Arguments to %s must be of the same type.", op);
        type_op_error ("Arguments to %s must be of the same type.", op);
      break;
      break;
 
 
    case BINOP_LOGICAL_AND:
    case BINOP_LOGICAL_AND:
    case BINOP_LOGICAL_OR:
    case BINOP_LOGICAL_OR:
      if (!boolean_type (t1) || !boolean_type (t2))
      if (!boolean_type (t1) || !boolean_type (t2))
        type_op_error ("Arguments to %s must be of boolean type.", op);
        type_op_error ("Arguments to %s must be of boolean type.", op);
      break;
      break;
 
 
    case BINOP_EQUAL:
    case BINOP_EQUAL:
      if ((pointer_type (t1) && !(pointer_type (t2) || integral_type (t2))) ||
      if ((pointer_type (t1) && !(pointer_type (t2) || integral_type (t2))) ||
          (pointer_type (t2) && !(pointer_type (t1) || integral_type (t1))))
          (pointer_type (t2) && !(pointer_type (t1) || integral_type (t1))))
        type_op_error ("A pointer can only be compared to an integer or pointer.", op);
        type_op_error ("A pointer can only be compared to an integer or pointer.", op);
      else if ((pointer_type (t1) && integral_type (t2)) ||
      else if ((pointer_type (t1) && integral_type (t2)) ||
               (integral_type (t1) && pointer_type (t2)))
               (integral_type (t1) && pointer_type (t2)))
        {
        {
          warning ("combining integer and pointer.\n");
          warning ("combining integer and pointer.\n");
          break;
          break;
        }
        }
      else if (!simple_type (t1) || !simple_type (t2))
      else if (!simple_type (t1) || !simple_type (t2))
        type_op_error ("Arguments to %s must be of simple type.", op);
        type_op_error ("Arguments to %s must be of simple type.", op);
      else if (!same_type (t1, t2))
      else if (!same_type (t1, t2))
        type_op_error ("Arguments to %s must be of the same type.", op);
        type_op_error ("Arguments to %s must be of the same type.", op);
      break;
      break;
 
 
    case BINOP_REM:
    case BINOP_REM:
    case BINOP_MOD:
    case BINOP_MOD:
      if (!integral_type (t1) || !integral_type (t2))
      if (!integral_type (t1) || !integral_type (t2))
        type_op_error ("Arguments to %s must be of integral type.", op);
        type_op_error ("Arguments to %s must be of integral type.", op);
      break;
      break;
 
 
    case BINOP_LESS:
    case BINOP_LESS:
    case BINOP_GTR:
    case BINOP_GTR:
    case BINOP_LEQ:
    case BINOP_LEQ:
    case BINOP_GEQ:
    case BINOP_GEQ:
      if (!ordered_type (t1) || !ordered_type (t2))
      if (!ordered_type (t1) || !ordered_type (t2))
        type_op_error ("Arguments to %s must be of ordered type.", op);
        type_op_error ("Arguments to %s must be of ordered type.", op);
      else if (!same_type (t1, t2))
      else if (!same_type (t1, t2))
        type_op_error ("Arguments to %s must be of the same type.", op);
        type_op_error ("Arguments to %s must be of the same type.", op);
      break;
      break;
 
 
    case BINOP_ASSIGN:
    case BINOP_ASSIGN:
      if (pointer_type (t1) && !integral_type (t2))
      if (pointer_type (t1) && !integral_type (t2))
        type_op_error ("A pointer can only be assigned an integer.", op);
        type_op_error ("A pointer can only be assigned an integer.", op);
      else if (pointer_type (t1) && integral_type (t2))
      else if (pointer_type (t1) && integral_type (t2))
        {
        {
          warning ("combining integer and pointer.");
          warning ("combining integer and pointer.");
          break;
          break;
        }
        }
      else if (!simple_type (t1) || !simple_type (t2))
      else if (!simple_type (t1) || !simple_type (t2))
        type_op_error ("Arguments to %s must be of simple type.", op);
        type_op_error ("Arguments to %s must be of simple type.", op);
      else if (!same_type (t1, t2))
      else if (!same_type (t1, t2))
        type_op_error ("Arguments to %s must be of the same type.", op);
        type_op_error ("Arguments to %s must be of the same type.", op);
      break;
      break;
 
 
    case BINOP_CONCAT:
    case BINOP_CONCAT:
      /* FIXME:  Needs to handle bitstrings as well. */
      /* FIXME:  Needs to handle bitstrings as well. */
      if (!(string_type (t1) || character_type (t1) || integral_type (t1))
      if (!(string_type (t1) || character_type (t1) || integral_type (t1))
        || !(string_type (t2) || character_type (t2) || integral_type (t2)))
        || !(string_type (t2) || character_type (t2) || integral_type (t2)))
        type_op_error ("Arguments to %s must be strings or characters.", op);
        type_op_error ("Arguments to %s must be strings or characters.", op);
      break;
      break;
 
 
      /* Unary checks -- arg2 is null */
      /* Unary checks -- arg2 is null */
 
 
    case UNOP_LOGICAL_NOT:
    case UNOP_LOGICAL_NOT:
      if (!boolean_type (t1))
      if (!boolean_type (t1))
        type_op_error ("Argument to %s must be of boolean type.", op);
        type_op_error ("Argument to %s must be of boolean type.", op);
      break;
      break;
 
 
    case UNOP_PLUS:
    case UNOP_PLUS:
    case UNOP_NEG:
    case UNOP_NEG:
      if (!numeric_type (t1))
      if (!numeric_type (t1))
        type_op_error ("Argument to %s must be of numeric type.", op);
        type_op_error ("Argument to %s must be of numeric type.", op);
      break;
      break;
 
 
    case UNOP_IND:
    case UNOP_IND:
      if (integral_type (t1))
      if (integral_type (t1))
        {
        {
          warning ("combining pointer and integer.\n");
          warning ("combining pointer and integer.\n");
          break;
          break;
        }
        }
      else if (!pointer_type (t1))
      else if (!pointer_type (t1))
        type_op_error ("Argument to %s must be a pointer.", op);
        type_op_error ("Argument to %s must be a pointer.", op);
      break;
      break;
 
 
    case UNOP_PREINCREMENT:
    case UNOP_PREINCREMENT:
    case UNOP_POSTINCREMENT:
    case UNOP_POSTINCREMENT:
    case UNOP_PREDECREMENT:
    case UNOP_PREDECREMENT:
    case UNOP_POSTDECREMENT:
    case UNOP_POSTDECREMENT:
      if (!ordered_type (t1))
      if (!ordered_type (t1))
        type_op_error ("Argument to %s must be of an ordered type.", op);
        type_op_error ("Argument to %s must be of an ordered type.", op);
      break;
      break;
 
 
    default:
    default:
      /* Ok.  The following operators have different meanings in
      /* Ok.  The following operators have different meanings in
         different languages. */
         different languages. */
      switch (current_language->la_language)
      switch (current_language->la_language)
        {
        {
#ifdef _LANG_c
#ifdef _LANG_c
        case language_c:
        case language_c:
        case language_cplus:
        case language_cplus:
          switch (op)
          switch (op)
            {
            {
            case BINOP_DIV:
            case BINOP_DIV:
              if (!numeric_type (t1) || !numeric_type (t2))
              if (!numeric_type (t1) || !numeric_type (t2))
                type_op_error ("Arguments to %s must be numbers.", op);
                type_op_error ("Arguments to %s must be numbers.", op);
              break;
              break;
            }
            }
          break;
          break;
#endif
#endif
 
 
#ifdef _LANG_m2
#ifdef _LANG_m2
        case language_m2:
        case language_m2:
          switch (op)
          switch (op)
            {
            {
            case BINOP_DIV:
            case BINOP_DIV:
              if (!float_type (t1) || !float_type (t2))
              if (!float_type (t1) || !float_type (t2))
                type_op_error ("Arguments to %s must be floating point numbers.", op);
                type_op_error ("Arguments to %s must be floating point numbers.", op);
              break;
              break;
            case BINOP_INTDIV:
            case BINOP_INTDIV:
              if (!integral_type (t1) || !integral_type (t2))
              if (!integral_type (t1) || !integral_type (t2))
                type_op_error ("Arguments to %s must be of integral type.", op);
                type_op_error ("Arguments to %s must be of integral type.", op);
              break;
              break;
            }
            }
#endif
#endif
 
 
#ifdef _LANG_chill
#ifdef _LANG_chill
        case language_chill:
        case language_chill:
          error ("Missing Chill support in function binop_type_check.");        /*FIXME */
          error ("Missing Chill support in function binop_type_check.");        /*FIXME */
#endif
#endif
 
 
        }
        }
    }
    }
}
}
 
 
#endif /* 0 */
#endif /* 0 */


 
 
/* This page contains functions for the printing out of
/* This page contains functions for the printing out of
   error messages that occur during type- and range-
   error messages that occur during type- and range-
   checking. */
   checking. */
 
 
/* Prints the format string FMT with the operator as a string
/* Prints the format string FMT with the operator as a string
   corresponding to the opcode OP.  If FATAL is non-zero, then
   corresponding to the opcode OP.  If FATAL is non-zero, then
   this is an error and error () is called.  Otherwise, it is
   this is an error and error () is called.  Otherwise, it is
   a warning and printf() is called. */
   a warning and printf() is called. */
void
void
op_error (fmt, op, fatal)
op_error (fmt, op, fatal)
     char *fmt;
     char *fmt;
     enum exp_opcode op;
     enum exp_opcode op;
     int fatal;
     int fatal;
{
{
  if (fatal)
  if (fatal)
    error (fmt, op_string (op));
    error (fmt, op_string (op));
  else
  else
    {
    {
      warning (fmt, op_string (op));
      warning (fmt, op_string (op));
    }
    }
}
}
 
 
/* These are called when a language fails a type- or range-check.
/* These are called when a language fails a type- or range-check.
   The first argument should be a printf()-style format string, and
   The first argument should be a printf()-style format string, and
   the rest of the arguments should be its arguments.  If
   the rest of the arguments should be its arguments.  If
   [type|range]_check is [type|range]_check_on, then return_to_top_level()
   [type|range]_check is [type|range]_check_on, then return_to_top_level()
   is called in the style of error ().  Otherwise, the message is prefixed
   is called in the style of error ().  Otherwise, the message is prefixed
   by the value of warning_pre_print and we do not return to the top level. */
   by the value of warning_pre_print and we do not return to the top level. */
 
 
void
void
type_error (char *string,...)
type_error (char *string,...)
{
{
  va_list args;
  va_list args;
  va_start (args, string);
  va_start (args, string);
 
 
  if (type_check == type_check_warn)
  if (type_check == type_check_warn)
    fprintf_filtered (gdb_stderr, warning_pre_print);
    fprintf_filtered (gdb_stderr, warning_pre_print);
  else
  else
    error_begin ();
    error_begin ();
 
 
  vfprintf_filtered (gdb_stderr, string, args);
  vfprintf_filtered (gdb_stderr, string, args);
  fprintf_filtered (gdb_stderr, "\n");
  fprintf_filtered (gdb_stderr, "\n");
  va_end (args);
  va_end (args);
  if (type_check == type_check_on)
  if (type_check == type_check_on)
    return_to_top_level (RETURN_ERROR);
    return_to_top_level (RETURN_ERROR);
}
}
 
 
void
void
range_error (char *string,...)
range_error (char *string,...)
{
{
  va_list args;
  va_list args;
  va_start (args, string);
  va_start (args, string);
 
 
  if (range_check == range_check_warn)
  if (range_check == range_check_warn)
    fprintf_filtered (gdb_stderr, warning_pre_print);
    fprintf_filtered (gdb_stderr, warning_pre_print);
  else
  else
    error_begin ();
    error_begin ();
 
 
  vfprintf_filtered (gdb_stderr, string, args);
  vfprintf_filtered (gdb_stderr, string, args);
  fprintf_filtered (gdb_stderr, "\n");
  fprintf_filtered (gdb_stderr, "\n");
  va_end (args);
  va_end (args);
  if (range_check == range_check_on)
  if (range_check == range_check_on)
    return_to_top_level (RETURN_ERROR);
    return_to_top_level (RETURN_ERROR);
}
}


 
 
/* This page contains miscellaneous functions */
/* This page contains miscellaneous functions */
 
 
/* Return the language enum for a given language string. */
/* Return the language enum for a given language string. */
 
 
enum language
enum language
language_enum (str)
language_enum (str)
     char *str;
     char *str;
{
{
  int i;
  int i;
 
 
  for (i = 0; i < languages_size; i++)
  for (i = 0; i < languages_size; i++)
    if (STREQ (languages[i]->la_name, str))
    if (STREQ (languages[i]->la_name, str))
      return languages[i]->la_language;
      return languages[i]->la_language;
 
 
  return language_unknown;
  return language_unknown;
}
}
 
 
/* Return the language struct for a given language enum. */
/* Return the language struct for a given language enum. */
 
 
const struct language_defn *
const struct language_defn *
language_def (lang)
language_def (lang)
     enum language lang;
     enum language lang;
{
{
  int i;
  int i;
 
 
  for (i = 0; i < languages_size; i++)
  for (i = 0; i < languages_size; i++)
    {
    {
      if (languages[i]->la_language == lang)
      if (languages[i]->la_language == lang)
        {
        {
          return languages[i];
          return languages[i];
        }
        }
    }
    }
  return NULL;
  return NULL;
}
}
 
 
/* Return the language as a string */
/* Return the language as a string */
char *
char *
language_str (lang)
language_str (lang)
     enum language lang;
     enum language lang;
{
{
  int i;
  int i;
 
 
  for (i = 0; i < languages_size; i++)
  for (i = 0; i < languages_size; i++)
    {
    {
      if (languages[i]->la_language == lang)
      if (languages[i]->la_language == lang)
        {
        {
          return languages[i]->la_name;
          return languages[i]->la_name;
        }
        }
    }
    }
  return "Unknown";
  return "Unknown";
}
}
 
 
static void
static void
set_check (ignore, from_tty)
set_check (ignore, from_tty)
     char *ignore;
     char *ignore;
     int from_tty;
     int from_tty;
{
{
  printf_unfiltered (
  printf_unfiltered (
     "\"set check\" must be followed by the name of a check subcommand.\n");
     "\"set check\" must be followed by the name of a check subcommand.\n");
  help_list (setchecklist, "set check ", -1, gdb_stdout);
  help_list (setchecklist, "set check ", -1, gdb_stdout);
}
}
 
 
static void
static void
show_check (ignore, from_tty)
show_check (ignore, from_tty)
     char *ignore;
     char *ignore;
     int from_tty;
     int from_tty;
{
{
  cmd_show_list (showchecklist, from_tty, "");
  cmd_show_list (showchecklist, from_tty, "");
}
}


/* Add a language to the set of known languages.  */
/* Add a language to the set of known languages.  */
 
 
void
void
add_language (lang)
add_language (lang)
     const struct language_defn *lang;
     const struct language_defn *lang;
{
{
  if (lang->la_magic != LANG_MAGIC)
  if (lang->la_magic != LANG_MAGIC)
    {
    {
      fprintf_unfiltered (gdb_stderr, "Magic number of %s language struct wrong\n",
      fprintf_unfiltered (gdb_stderr, "Magic number of %s language struct wrong\n",
                          lang->la_name);
                          lang->la_name);
      abort ();
      abort ();
    }
    }
 
 
  if (!languages)
  if (!languages)
    {
    {
      languages_allocsize = DEFAULT_ALLOCSIZE;
      languages_allocsize = DEFAULT_ALLOCSIZE;
      languages = (const struct language_defn **) xmalloc
      languages = (const struct language_defn **) xmalloc
        (languages_allocsize * sizeof (*languages));
        (languages_allocsize * sizeof (*languages));
    }
    }
  if (languages_size >= languages_allocsize)
  if (languages_size >= languages_allocsize)
    {
    {
      languages_allocsize *= 2;
      languages_allocsize *= 2;
      languages = (const struct language_defn **) xrealloc ((char *) languages,
      languages = (const struct language_defn **) xrealloc ((char *) languages,
                                 languages_allocsize * sizeof (*languages));
                                 languages_allocsize * sizeof (*languages));
    }
    }
  languages[languages_size++] = lang;
  languages[languages_size++] = lang;
}
}
 
 
/* Define the language that is no language.  */
/* Define the language that is no language.  */
 
 
static int
static int
unk_lang_parser ()
unk_lang_parser ()
{
{
  return 1;
  return 1;
}
}
 
 
static void
static void
unk_lang_error (msg)
unk_lang_error (msg)
     char *msg;
     char *msg;
{
{
  error ("Attempted to parse an expression with unknown language");
  error ("Attempted to parse an expression with unknown language");
}
}
 
 
static void
static void
unk_lang_emit_char (c, stream, quoter)
unk_lang_emit_char (c, stream, quoter)
     register int c;
     register int c;
     struct ui_file *stream;
     struct ui_file *stream;
     int quoter;
     int quoter;
{
{
  error ("internal error - unimplemented function unk_lang_emit_char called.");
  error ("internal error - unimplemented function unk_lang_emit_char called.");
}
}
 
 
static void
static void
unk_lang_printchar (c, stream)
unk_lang_printchar (c, stream)
     register int c;
     register int c;
     struct ui_file *stream;
     struct ui_file *stream;
{
{
  error ("internal error - unimplemented function unk_lang_printchar called.");
  error ("internal error - unimplemented function unk_lang_printchar called.");
}
}
 
 
static void
static void
unk_lang_printstr (stream, string, length, width, force_ellipses)
unk_lang_printstr (stream, string, length, width, force_ellipses)
     struct ui_file *stream;
     struct ui_file *stream;
     char *string;
     char *string;
     unsigned int length;
     unsigned int length;
     int width;
     int width;
     int force_ellipses;
     int force_ellipses;
{
{
  error ("internal error - unimplemented function unk_lang_printstr called.");
  error ("internal error - unimplemented function unk_lang_printstr called.");
}
}
 
 
static struct type *
static struct type *
unk_lang_create_fundamental_type (objfile, typeid)
unk_lang_create_fundamental_type (objfile, typeid)
     struct objfile *objfile;
     struct objfile *objfile;
     int typeid;
     int typeid;
{
{
  error ("internal error - unimplemented function unk_lang_create_fundamental_type called.");
  error ("internal error - unimplemented function unk_lang_create_fundamental_type called.");
}
}
 
 
static void
static void
unk_lang_print_type (type, varstring, stream, show, level)
unk_lang_print_type (type, varstring, stream, show, level)
     struct type *type;
     struct type *type;
     char *varstring;
     char *varstring;
     struct ui_file *stream;
     struct ui_file *stream;
     int show;
     int show;
     int level;
     int level;
{
{
  error ("internal error - unimplemented function unk_lang_print_type called.");
  error ("internal error - unimplemented function unk_lang_print_type called.");
}
}
 
 
static int
static int
unk_lang_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
unk_lang_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref,
                    recurse, pretty)
                    recurse, pretty)
     struct type *type;
     struct type *type;
     char *valaddr;
     char *valaddr;
     int embedded_offset;
     int embedded_offset;
     CORE_ADDR address;
     CORE_ADDR address;
     struct ui_file *stream;
     struct ui_file *stream;
     int format;
     int format;
     int deref_ref;
     int deref_ref;
     int recurse;
     int recurse;
     enum val_prettyprint pretty;
     enum val_prettyprint pretty;
{
{
  error ("internal error - unimplemented function unk_lang_val_print called.");
  error ("internal error - unimplemented function unk_lang_val_print called.");
}
}
 
 
static int
static int
unk_lang_value_print (val, stream, format, pretty)
unk_lang_value_print (val, stream, format, pretty)
     value_ptr val;
     value_ptr val;
     struct ui_file *stream;
     struct ui_file *stream;
     int format;
     int format;
     enum val_prettyprint pretty;
     enum val_prettyprint pretty;
{
{
  error ("internal error - unimplemented function unk_lang_value_print called.");
  error ("internal error - unimplemented function unk_lang_value_print called.");
}
}
 
 
static struct type **CONST_PTR (unknown_builtin_types[]) =
static struct type **CONST_PTR (unknown_builtin_types[]) =
{
{
  0
  0
};
};
static const struct op_print unk_op_print_tab[] =
static const struct op_print unk_op_print_tab[] =
{
{
  {NULL, OP_NULL, PREC_NULL, 0}
  {NULL, OP_NULL, PREC_NULL, 0}
};
};
 
 
const struct language_defn unknown_language_defn =
const struct language_defn unknown_language_defn =
{
{
  "unknown",
  "unknown",
  language_unknown,
  language_unknown,
  &unknown_builtin_types[0],
  &unknown_builtin_types[0],
  range_check_off,
  range_check_off,
  type_check_off,
  type_check_off,
  unk_lang_parser,
  unk_lang_parser,
  unk_lang_error,
  unk_lang_error,
  evaluate_subexp_standard,
  evaluate_subexp_standard,
  unk_lang_printchar,           /* Print character constant */
  unk_lang_printchar,           /* Print character constant */
  unk_lang_printstr,
  unk_lang_printstr,
  unk_lang_emit_char,
  unk_lang_emit_char,
  unk_lang_create_fundamental_type,
  unk_lang_create_fundamental_type,
  unk_lang_print_type,          /* Print a type using appropriate syntax */
  unk_lang_print_type,          /* Print a type using appropriate syntax */
  unk_lang_val_print,           /* Print a value using appropriate syntax */
  unk_lang_val_print,           /* Print a value using appropriate syntax */
  unk_lang_value_print,         /* Print a top-level value */
  unk_lang_value_print,         /* Print a top-level value */
  {"", "", "", ""},             /* Binary format info */
  {"", "", "", ""},             /* Binary format info */
  {"0%lo", "0", "o", ""},        /* Octal format info */
  {"0%lo", "0", "o", ""},        /* Octal format info */
  {"%ld", "", "d", ""},         /* Decimal format info */
  {"%ld", "", "d", ""},         /* Decimal format info */
  {"0x%lx", "0x", "x", ""},     /* Hex format info */
  {"0x%lx", "0x", "x", ""},     /* Hex format info */
  unk_op_print_tab,             /* expression operators for printing */
  unk_op_print_tab,             /* expression operators for printing */
  1,                            /* c-style arrays */
  1,                            /* c-style arrays */
  0,                             /* String lower bound */
  0,                             /* String lower bound */
  &builtin_type_char,           /* Type of string elements */
  &builtin_type_char,           /* Type of string elements */
  LANG_MAGIC
  LANG_MAGIC
};
};
 
 
/* These two structs define fake entries for the "local" and "auto" options. */
/* These two structs define fake entries for the "local" and "auto" options. */
const struct language_defn auto_language_defn =
const struct language_defn auto_language_defn =
{
{
  "auto",
  "auto",
  language_auto,
  language_auto,
  &unknown_builtin_types[0],
  &unknown_builtin_types[0],
  range_check_off,
  range_check_off,
  type_check_off,
  type_check_off,
  unk_lang_parser,
  unk_lang_parser,
  unk_lang_error,
  unk_lang_error,
  evaluate_subexp_standard,
  evaluate_subexp_standard,
  unk_lang_printchar,           /* Print character constant */
  unk_lang_printchar,           /* Print character constant */
  unk_lang_printstr,
  unk_lang_printstr,
  unk_lang_emit_char,
  unk_lang_emit_char,
  unk_lang_create_fundamental_type,
  unk_lang_create_fundamental_type,
  unk_lang_print_type,          /* Print a type using appropriate syntax */
  unk_lang_print_type,          /* Print a type using appropriate syntax */
  unk_lang_val_print,           /* Print a value using appropriate syntax */
  unk_lang_val_print,           /* Print a value using appropriate syntax */
  unk_lang_value_print,         /* Print a top-level value */
  unk_lang_value_print,         /* Print a top-level value */
  {"", "", "", ""},             /* Binary format info */
  {"", "", "", ""},             /* Binary format info */
  {"0%lo", "0", "o", ""},        /* Octal format info */
  {"0%lo", "0", "o", ""},        /* Octal format info */
  {"%ld", "", "d", ""},         /* Decimal format info */
  {"%ld", "", "d", ""},         /* Decimal format info */
  {"0x%lx", "0x", "x", ""},     /* Hex format info */
  {"0x%lx", "0x", "x", ""},     /* Hex format info */
  unk_op_print_tab,             /* expression operators for printing */
  unk_op_print_tab,             /* expression operators for printing */
  1,                            /* c-style arrays */
  1,                            /* c-style arrays */
  0,                             /* String lower bound */
  0,                             /* String lower bound */
  &builtin_type_char,           /* Type of string elements */
  &builtin_type_char,           /* Type of string elements */
  LANG_MAGIC
  LANG_MAGIC
};
};
 
 
const struct language_defn local_language_defn =
const struct language_defn local_language_defn =
{
{
  "local",
  "local",
  language_auto,
  language_auto,
  &unknown_builtin_types[0],
  &unknown_builtin_types[0],
  range_check_off,
  range_check_off,
  type_check_off,
  type_check_off,
  unk_lang_parser,
  unk_lang_parser,
  unk_lang_error,
  unk_lang_error,
  evaluate_subexp_standard,
  evaluate_subexp_standard,
  unk_lang_printchar,           /* Print character constant */
  unk_lang_printchar,           /* Print character constant */
  unk_lang_printstr,
  unk_lang_printstr,
  unk_lang_emit_char,
  unk_lang_emit_char,
  unk_lang_create_fundamental_type,
  unk_lang_create_fundamental_type,
  unk_lang_print_type,          /* Print a type using appropriate syntax */
  unk_lang_print_type,          /* Print a type using appropriate syntax */
  unk_lang_val_print,           /* Print a value using appropriate syntax */
  unk_lang_val_print,           /* Print a value using appropriate syntax */
  unk_lang_value_print,         /* Print a top-level value */
  unk_lang_value_print,         /* Print a top-level value */
  {"", "", "", ""},             /* Binary format info */
  {"", "", "", ""},             /* Binary format info */
  {"0%lo", "0", "o", ""},        /* Octal format info */
  {"0%lo", "0", "o", ""},        /* Octal format info */
  {"%ld", "", "d", ""},         /* Decimal format info */
  {"%ld", "", "d", ""},         /* Decimal format info */
  {"0x%lx", "0x", "x", ""},     /* Hex format info */
  {"0x%lx", "0x", "x", ""},     /* Hex format info */
  unk_op_print_tab,             /* expression operators for printing */
  unk_op_print_tab,             /* expression operators for printing */
  1,                            /* c-style arrays */
  1,                            /* c-style arrays */
  0,                             /* String lower bound */
  0,                             /* String lower bound */
  &builtin_type_char,           /* Type of string elements */
  &builtin_type_char,           /* Type of string elements */
  LANG_MAGIC
  LANG_MAGIC
};
};


/* Initialize the language routines */
/* Initialize the language routines */
 
 
void
void
_initialize_language ()
_initialize_language ()
{
{
  struct cmd_list_element *set, *show;
  struct cmd_list_element *set, *show;
 
 
  /* GDB commands for language specific stuff */
  /* GDB commands for language specific stuff */
 
 
  set = add_set_cmd ("language", class_support, var_string_noescape,
  set = add_set_cmd ("language", class_support, var_string_noescape,
                     (char *) &language,
                     (char *) &language,
                     "Set the current source language.",
                     "Set the current source language.",
                     &setlist);
                     &setlist);
  show = add_show_from_set (set, &showlist);
  show = add_show_from_set (set, &showlist);
  set->function.cfunc = set_language_command;
  set->function.cfunc = set_language_command;
  show->function.cfunc = show_language_command;
  show->function.cfunc = show_language_command;
 
 
  add_prefix_cmd ("check", no_class, set_check,
  add_prefix_cmd ("check", no_class, set_check,
                  "Set the status of the type/range checker",
                  "Set the status of the type/range checker",
                  &setchecklist, "set check ", 0, &setlist);
                  &setchecklist, "set check ", 0, &setlist);
  add_alias_cmd ("c", "check", no_class, 1, &setlist);
  add_alias_cmd ("c", "check", no_class, 1, &setlist);
  add_alias_cmd ("ch", "check", no_class, 1, &setlist);
  add_alias_cmd ("ch", "check", no_class, 1, &setlist);
 
 
  add_prefix_cmd ("check", no_class, show_check,
  add_prefix_cmd ("check", no_class, show_check,
                  "Show the status of the type/range checker",
                  "Show the status of the type/range checker",
                  &showchecklist, "show check ", 0, &showlist);
                  &showchecklist, "show check ", 0, &showlist);
  add_alias_cmd ("c", "check", no_class, 1, &showlist);
  add_alias_cmd ("c", "check", no_class, 1, &showlist);
  add_alias_cmd ("ch", "check", no_class, 1, &showlist);
  add_alias_cmd ("ch", "check", no_class, 1, &showlist);
 
 
  set = add_set_cmd ("type", class_support, var_string_noescape,
  set = add_set_cmd ("type", class_support, var_string_noescape,
                     (char *) &type,
                     (char *) &type,
                     "Set type checking.  (on/warn/off/auto)",
                     "Set type checking.  (on/warn/off/auto)",
                     &setchecklist);
                     &setchecklist);
  show = add_show_from_set (set, &showchecklist);
  show = add_show_from_set (set, &showchecklist);
  set->function.cfunc = set_type_command;
  set->function.cfunc = set_type_command;
  show->function.cfunc = show_type_command;
  show->function.cfunc = show_type_command;
 
 
  set = add_set_cmd ("range", class_support, var_string_noescape,
  set = add_set_cmd ("range", class_support, var_string_noescape,
                     (char *) &range,
                     (char *) &range,
                     "Set range checking.  (on/warn/off/auto)",
                     "Set range checking.  (on/warn/off/auto)",
                     &setchecklist);
                     &setchecklist);
  show = add_show_from_set (set, &showchecklist);
  show = add_show_from_set (set, &showchecklist);
  set->function.cfunc = set_range_command;
  set->function.cfunc = set_range_command;
  show->function.cfunc = show_range_command;
  show->function.cfunc = show_range_command;
 
 
  add_language (&unknown_language_defn);
  add_language (&unknown_language_defn);
  add_language (&local_language_defn);
  add_language (&local_language_defn);
  add_language (&auto_language_defn);
  add_language (&auto_language_defn);
 
 
  language = savestring ("auto", strlen ("auto"));
  language = savestring ("auto", strlen ("auto"));
  set_language_command (language, 0);
  set_language_command (language, 0);
 
 
  type = savestring ("auto", strlen ("auto"));
  type = savestring ("auto", strlen ("auto"));
  set_type_command (NULL, 0);
  set_type_command (NULL, 0);
 
 
  range = savestring ("auto", strlen ("auto"));
  range = savestring ("auto", strlen ("auto"));
  set_range_command (NULL, 0);
  set_range_command (NULL, 0);
}
}
 
 

powered by: WebSVN 2.1.0

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