/* Basic C++ demangling support for GDB.
   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
   Free Software Foundation, Inc.
   Written by Fred Fish at Cygnus Support.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */


/*  This file contains support code for C++ demangling that is common
   to a styles of demangling, and GDB specific. */

#include "defs.h"
#include "command.h"
#include "gdbcmd.h"
#include "demangle.h"
#include "gdb_string.h"

/* Select the default C++ demangling style to use.  The default is "auto",
   which allows gdb to attempt to pick an appropriate demangling style for
   the executable it has loaded.  It can be set to a specific style ("gnu",
   "lucid", "arm", "hp", etc.) in which case gdb will never attempt to do auto
   selection of the style unless you do an explicit "set demangle auto".
   To select one of these as the default, set DEFAULT_DEMANGLING_STYLE in
   the appropriate target configuration file. */

#ifndef DEFAULT_DEMANGLING_STYLE
#define DEFAULT_DEMANGLING_STYLE AUTO_DEMANGLING_STYLE_STRING
#endif

extern void _initialize_demangler (void);

/* String name for the current demangling style.  Set by the
   "set demangle-style" command, printed as part of the output by the
   "show demangle-style" command. */

static char *current_demangling_style_string;

/* The array of names of the known demanglyng styles.  Generated by
   _initialize_demangler from libiberty_demanglers[] array.  */

static const char **demangling_style_names;

static void set_demangling_command (char *, int, struct cmd_list_element *);

/* Set current demangling style.  Called by the "set demangle-style"
   command after it has updated the current_demangling_style_string to
   match what the user has entered.

   If the user has entered a string that matches a known demangling style
   name in the demanglers[] array then just leave the string alone and update
   the current_demangling_style enum value to match.

   If the user has entered a string that doesn't match, including an empty
   string, then print a list of the currently known styles and restore
   the current_demangling_style_string to match the current_demangling_style
   enum value.

   Note:  Assumes that current_demangling_style_string always points to
   a malloc'd string, even if it is a null-string. */

static void
set_demangling_command (char *ignore, int from_tty, struct cmd_list_element *c)
{
  const struct demangler_engine *dem;

  /*  First just try to match whatever style name the user supplied with
     one of the known ones.  Don't bother special casing for an empty
     name, we just treat it as any other style name that doesn't match.
     If we match, update the current demangling style enum. */

  for (dem = libiberty_demanglers; 
       dem->demangling_style != unknown_demangling; 
       dem++)
    {
      if (STREQ (current_demangling_style_string,
		 dem->demangling_style_name))
	{
	  current_demangling_style = dem->demangling_style;
	  break;
	}
    }

  /* Check to see if we found a match.  If not, gripe about any non-empty
     style name and supply a list of valid ones.  FIXME:  This should
     probably be done with some sort of completion and with help. */

  if (dem->demangling_style == unknown_demangling)
    {
      if (*current_demangling_style_string != '\0')
	{
	  printf_unfiltered ("Unknown demangling style `%s'.\n",
			     current_demangling_style_string);
	}
      printf_unfiltered ("The currently understood settings are:\n\n");
      for (dem = libiberty_demanglers; 
	   dem->demangling_style != unknown_demangling; 
	   dem++)
	{
	  printf_unfiltered ("%-10s %s\n", dem->demangling_style_name,
			     dem->demangling_style_doc);
	  if (dem->demangling_style == current_demangling_style)
	    {
	      xfree (current_demangling_style_string);
	      current_demangling_style_string =
		savestring (dem->demangling_style_name,
			    strlen (dem->demangling_style_name));
	    }
	}
      if (current_demangling_style == unknown_demangling)
	{
	  /* This can happen during initialization if gdb is compiled with
	     a DEMANGLING_STYLE value that is unknown, so pick the first
	     one as the default. */
	  current_demangling_style = libiberty_demanglers[0].demangling_style;
	  current_demangling_style_string =
	    savestring (
              libiberty_demanglers[0].demangling_style_name,
	      strlen (libiberty_demanglers[0].demangling_style_name));
	  warning ("`%s' style demangling chosen as the default.\n",
		   current_demangling_style_string);
	}
    }
}

/* Fake a "set demangle-style" command. */

void
set_demangling_style (char *style)
{
  if (current_demangling_style_string != NULL)
    {
      xfree (current_demangling_style_string);
    }
  current_demangling_style_string = savestring (style, strlen (style));
  set_demangling_command ((char *) NULL, 0, (struct cmd_list_element *) NULL);
}

/* G++ uses a special character to indicate certain internal names.  Which
   character it is depends on the platform:
   - Usually '$' on systems where the assembler will accept that
   - Usually '.' otherwise (this includes most sysv4-like systems and most
     ELF targets)
   - Occasionally '_' if neither of the above is usable

   We check '$' first because it is the safest, and '.' often has another
   meaning.  We don't currently try to handle '_' because the precise forms
   of the names are different on those targets.  */

static char cplus_markers[] = {'$', '.', '\0'};

int
is_cplus_marker (int c)
{
  return c && strchr (cplus_markers, c) != NULL;
}

void
_initialize_demangler (void)
{
  struct cmd_list_element *set, *show;
  int i, ndems;

  /* Fill the demangling_style_names[] array.  */
  for (ndems = 0;
       libiberty_demanglers[ndems].demangling_style != unknown_demangling; 
       ndems++)
    ;
  demangling_style_names = xcalloc (ndems + 1, sizeof (char *));
  for (i = 0;
       libiberty_demanglers[i].demangling_style != unknown_demangling; 
       i++)
    demangling_style_names[i] =
      xstrdup (libiberty_demanglers[i].demangling_style_name);

  set = add_set_enum_cmd ("demangle-style", class_support,
			  demangling_style_names,
			  (const char **) &current_demangling_style_string,
			  "Set the current C++ demangling style.\n\
Use `set demangle-style' without arguments for a list of demangling styles.",
			  &setlist);
  show = add_show_from_set (set, &showlist);
  set_cmd_sfunc (set, set_demangling_command);

  /* Set the default demangling style chosen at compilation time. */
  set_demangling_style (DEFAULT_DEMANGLING_STYLE);
}
