/* Handle set and show GDB commands.

   Copyright (c) 2000-2003, 2007-2012 Free Software Foundation, Inc.

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

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

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "readline/tilde.h"
#include "value.h"
#include <ctype.h>
#include "gdb_string.h"
#include "arch-utils.h"

#include "ui-out.h"

#include "cli/cli-decode.h"
#include "cli/cli-cmds.h"
#include "cli/cli-setshow.h"

/* Prototypes for local functions.  */

static int parse_binary_operation (char *);


static enum auto_boolean
parse_auto_binary_operation (const char *arg)
{
  if (arg != NULL && *arg != '\0')
    {
      int length = strlen (arg);

      while (isspace (arg[length - 1]) && length > 0)
	length--;
      if (strncmp (arg, "on", length) == 0
	  || strncmp (arg, "1", length) == 0
	  || strncmp (arg, "yes", length) == 0
	  || strncmp (arg, "enable", length) == 0)
	return AUTO_BOOLEAN_TRUE;
      else if (strncmp (arg, "off", length) == 0
	       || strncmp (arg, "0", length) == 0
	       || strncmp (arg, "no", length) == 0
	       || strncmp (arg, "disable", length) == 0)
	return AUTO_BOOLEAN_FALSE;
      else if (strncmp (arg, "auto", length) == 0
	       || (strncmp (arg, "-1", length) == 0 && length > 1))
	return AUTO_BOOLEAN_AUTO;
    }
  error (_("\"on\", \"off\" or \"auto\" expected."));
  return AUTO_BOOLEAN_AUTO; /* Pacify GCC.  */
}

static int
parse_binary_operation (char *arg)
{
  int length;

  if (!arg || !*arg)
    return 1;

  length = strlen (arg);

  while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
    length--;

  if (strncmp (arg, "on", length) == 0
      || strncmp (arg, "1", length) == 0
      || strncmp (arg, "yes", length) == 0
      || strncmp (arg, "enable", length) == 0)
    return 1;
  else if (strncmp (arg, "off", length) == 0
	   || strncmp (arg, "0", length) == 0
	   || strncmp (arg, "no", length) == 0
	   || strncmp (arg, "disable", length) == 0)
    return 0;
  else
    {
      error (_("\"on\" or \"off\" expected."));
      return 0;
    }
}

void
deprecated_show_value_hack (struct ui_file *ignore_file,
			    int ignore_from_tty,
			    struct cmd_list_element *c,
			    const char *value)
{
  /* If there's no command or value, don't try to print it out.  */
  if (c == NULL || value == NULL)
    return;
  /* Print doc minus "show" at start.  */
  print_doc_line (gdb_stdout, c->doc + 5);
  switch (c->var_type)
    {
    case var_string:
    case var_string_noescape:
    case var_optional_filename:
    case var_filename:
    case var_enum:
      printf_filtered ((" is \"%s\".\n"), value);
      break;
    default:
      printf_filtered ((" is %s.\n"), value);
      break;
    }
}

/* Do a "set" or "show" command.  ARG is NULL if no argument, or the
   text of the argument, and FROM_TTY is nonzero if this command is
   being entered directly by the user (i.e. these are just like any
   other command).  C is the command list element for the command.  */

void
do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c)
{
  struct ui_out *uiout = current_uiout;

  if (c->type == set_cmd)
    {
      switch (c->var_type)
	{
	case var_string:
	  {
	    char *new;
	    char *p;
	    char *q;
	    int ch;

	    if (arg == NULL)
	      arg = "";
	    new = (char *) xmalloc (strlen (arg) + 2);
	    p = arg;
	    q = new;
	    while ((ch = *p++) != '\000')
	      {
		if (ch == '\\')
		  {
		    /* \ at end of argument is used after spaces
		       so they won't be lost.  */
		    /* This is obsolete now that we no longer strip
		       trailing whitespace and actually, the backslash
		       didn't get here in my test, readline or
		       something did something funky with a backslash
		       right before a newline.  */
		    if (*p == 0)
		      break;
		    ch = parse_escape (get_current_arch (), &p);
		    if (ch == 0)
		      break;	/* C loses */
		    else if (ch > 0)
		      *q++ = ch;
		  }
		else
		  *q++ = ch;
	      }
#if 0
	    if (*(p - 1) != '\\')
	      *q++ = ' ';
#endif
	    *q++ = '\0';
	    new = (char *) xrealloc (new, q - new);
	    if (*(char **) c->var != NULL)
	      xfree (*(char **) c->var);
	    *(char **) c->var = new;
	  }
	  break;
	case var_string_noescape:
	  if (arg == NULL)
	    arg = "";
	  if (*(char **) c->var != NULL)
	    xfree (*(char **) c->var);
	  *(char **) c->var = xstrdup (arg);
	  break;
	case var_optional_filename:
	  if (arg == NULL)
	    arg = "";
	  if (*(char **) c->var != NULL)
	    xfree (*(char **) c->var);
	  *(char **) c->var = xstrdup (arg);
	  break;
	case var_filename:
	  if (arg == NULL)
	    error_no_arg (_("filename to set it to."));
	  if (*(char **) c->var != NULL)
	    xfree (*(char **) c->var);
	  {
	    /* Clear trailing whitespace of filename.  */
	    char *ptr = arg + strlen (arg) - 1;

	    while (ptr >= arg && (*ptr == ' ' || *ptr == '\t'))
	      ptr--;
	    *(ptr + 1) = '\0';
	  }
	  *(char **) c->var = tilde_expand (arg);
	  break;
	case var_boolean:
	  *(int *) c->var = parse_binary_operation (arg);
	  break;
	case var_auto_boolean:
	  *(enum auto_boolean *) c->var = parse_auto_binary_operation (arg);
	  break;
	case var_uinteger:
	  if (arg == NULL)
	    error_no_arg (_("integer to set it to."));
	  *(unsigned int *) c->var = parse_and_eval_long (arg);
	  if (*(unsigned int *) c->var == 0)
	    *(unsigned int *) c->var = UINT_MAX;
	  break;
	case var_integer:
	  {
	    unsigned int val;

	    if (arg == NULL)
	      error_no_arg (_("integer to set it to."));
	    val = parse_and_eval_long (arg);
	    if (val == 0)
	      *(int *) c->var = INT_MAX;
	    else if (val >= INT_MAX)
	      error (_("integer %u out of range"), val);
	    else
	      *(int *) c->var = val;
	    break;
	  }
	case var_zinteger:
	  if (arg == NULL)
	    error_no_arg (_("integer to set it to."));
	  *(int *) c->var = parse_and_eval_long (arg);
	  break;
	case var_zuinteger:
	  if (arg == NULL)
	    error_no_arg (_("integer to set it to."));
	  *(unsigned int *) c->var = parse_and_eval_long (arg);
	  break;
	case var_enum:
	  {
	    int i;
	    int len;
	    int nmatches;
	    const char *match = NULL;
	    char *p;

	    /* If no argument was supplied, print an informative error
	       message.  */
	    if (arg == NULL)
	      {
		char *msg;
		int msg_len = 0;

		for (i = 0; c->enums[i]; i++)
		  msg_len += strlen (c->enums[i]) + 2;

		msg = xmalloc (msg_len);
		*msg = '\0';
		make_cleanup (xfree, msg);
		
		for (i = 0; c->enums[i]; i++)
		  {
		    if (i != 0)
		      strcat (msg, ", ");
		    strcat (msg, c->enums[i]);
		  }
		error (_("Requires an argument. Valid arguments are %s."), 
		       msg);
	      }

	    p = strchr (arg, ' ');

	    if (p)
	      len = p - arg;
	    else
	      len = strlen (arg);

	    nmatches = 0;
	    for (i = 0; c->enums[i]; i++)
	      if (strncmp (arg, c->enums[i], len) == 0)
		{
		  if (c->enums[i][len] == '\0')
		    {
		      match = c->enums[i];
		      nmatches = 1;
		      break; /* Exact match.  */
		    }
		  else
		    {
		      match = c->enums[i];
		      nmatches++;
		    }
		}

	    if (nmatches <= 0)
	      error (_("Undefined item: \"%s\"."), arg);

	    if (nmatches > 1)
	      error (_("Ambiguous item \"%s\"."), arg);

	    *(const char **) c->var = match;
	  }
	  break;
	default:
	  error (_("gdb internal error: bad var_type in do_setshow_command"));
	}
    }
  else if (c->type == show_cmd)
    {
      struct cleanup *old_chain;
      struct ui_stream *stb;

      stb = ui_out_stream_new (uiout);
      old_chain = make_cleanup_ui_out_stream_delete (stb);

      /* Possibly call the pre hook.  */
      if (c->pre_show_hook)
	(c->pre_show_hook) (c);

      switch (c->var_type)
	{
	case var_string:
	  if (*(char **) c->var)
	    fputstr_filtered (*(char **) c->var, '"', stb->stream);
	  break;
	case var_string_noescape:
	case var_optional_filename:
	case var_filename:
	case var_enum:
	  if (*(char **) c->var)
	    fputs_filtered (*(char **) c->var, stb->stream);
	  break;
	case var_boolean:
	  fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream);
	  break;
	case var_auto_boolean:
	  switch (*(enum auto_boolean*) c->var)
	    {
	    case AUTO_BOOLEAN_TRUE:
	      fputs_filtered ("on", stb->stream);
	      break;
	    case AUTO_BOOLEAN_FALSE:
	      fputs_filtered ("off", stb->stream);
	      break;
	    case AUTO_BOOLEAN_AUTO:
	      fputs_filtered ("auto", stb->stream);
	      break;
	    default:
	      internal_error (__FILE__, __LINE__,
			      _("do_setshow_command: "
				"invalid var_auto_boolean"));
	      break;
	    }
	  break;
	case var_uinteger:
	case var_zuinteger:
	  if (c->var_type == var_uinteger
	      && *(unsigned int *) c->var == UINT_MAX)
	    fputs_filtered ("unlimited", stb->stream);
	  else
	    fprintf_filtered (stb->stream, "%u", *(unsigned int *) c->var);
	  break;
	case var_integer:
	case var_zinteger:
	  if (c->var_type == var_integer
	      && *(int *) c->var == INT_MAX)
	    fputs_filtered ("unlimited", stb->stream);
	  else
	    fprintf_filtered (stb->stream, "%d", *(int *) c->var);
	  break;

	default:
	  error (_("gdb internal error: bad var_type in do_setshow_command"));
	}


      /* FIXME: cagney/2005-02-10: Need to split this in half: code to
	 convert the value into a string (esentially the above); and
	 code to print the value out.  For the latter there should be
	 MI and CLI specific versions.  */

      if (ui_out_is_mi_like_p (uiout))
	ui_out_field_stream (uiout, "value", stb);
      else
	{
	  char *value = ui_file_xstrdup (stb->stream, NULL);

	  make_cleanup (xfree, value);
	  if (c->show_value_func != NULL)
	    c->show_value_func (gdb_stdout, from_tty, c, value);
	  else
	    deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
	}
      do_cleanups (old_chain);
    }
  else
    error (_("gdb internal error: bad cmd_type in do_setshow_command"));
  c->func (c, NULL, from_tty);
  if (c->type == set_cmd && deprecated_set_hook)
    deprecated_set_hook (c);
}

/* Show all the settings in a list of show commands.  */

void
cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
{
  struct cleanup *showlist_chain;
  struct ui_out *uiout = current_uiout;

  showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist");
  for (; list != NULL; list = list->next)
    {
      /* If we find a prefix, run its list, prefixing our output by its
         prefix (with "show " skipped).  */
      if (list->prefixlist && !list->abbrev_flag)
	{
	  struct cleanup *optionlist_chain
	    = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist");
	  char *new_prefix = strstr (list->prefixname, "show ") + 5;

	  if (ui_out_is_mi_like_p (uiout))
	    ui_out_field_string (uiout, "prefix", new_prefix);
	  cmd_show_list (*list->prefixlist, from_tty, new_prefix);
	  /* Close the tuple.  */
	  do_cleanups (optionlist_chain);
	}
      else
	{
	  if (list->class != no_set_class)
	    {
	      struct cleanup *option_chain
		= make_cleanup_ui_out_tuple_begin_end (uiout, "option");

	      ui_out_text (uiout, prefix);
	      ui_out_field_string (uiout, "name", list->name);
	      ui_out_text (uiout, ":  ");
	      if (list->type == show_cmd)
		do_setshow_command ((char *) NULL, from_tty, list);
	      else
		cmd_func (list, NULL, from_tty);
	      /* Close the tuple.  */
	      do_cleanups (option_chain);
	    }
	}
    }
  /* Close the tuple.  */
  do_cleanups (showlist_chain);
}

