/* MI Command Set - varobj commands.
   Copyright (C) 2000-2017 Free Software Foundation, Inc.

   Contributed by Cygnus Solutions (a Red Hat company).

   This file is part of GDB.

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

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

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

#include "defs.h"
#include "mi-cmds.h"
#include "mi-main.h"
#include "ui-out.h"
#include "mi-out.h"
#include "varobj.h"
#include "language.h"
#include "value.h"
#include <ctype.h>
#include "mi-getopt.h"
#include "gdbthread.h"
#include "mi-parse.h"
#include "common/gdb_optional.h"

extern unsigned int varobjdebug;		/* defined in varobj.c.  */

static void varobj_update_one (struct varobj *var,
			       enum print_values print_values,
			       bool is_explicit);

static int mi_print_value_p (struct varobj *var,
			     enum print_values print_values);

/* Print variable object VAR.  The PRINT_VALUES parameter controls
   if the value should be printed.  The PRINT_EXPRESSION parameter
   controls if the expression should be printed.  */

static void 
print_varobj (struct varobj *var, enum print_values print_values,
	      int print_expression)
{
  struct ui_out *uiout = current_uiout;
  int thread_id;

  uiout->field_string ("name", varobj_get_objname (var));
  if (print_expression)
    {
      std::string exp = varobj_get_expression (var);

      uiout->field_string ("exp", exp.c_str ());
    }
  uiout->field_int ("numchild", varobj_get_num_children (var));
  
  if (mi_print_value_p (var, print_values))
    {
      std::string val = varobj_get_value (var);

      uiout->field_string ("value", val.c_str ());
    }

  std::string type = varobj_get_type (var);
  if (!type.empty ())
    uiout->field_string ("type", type.c_str ());

  thread_id = varobj_get_thread_id (var);
  if (thread_id > 0)
    uiout->field_int ("thread-id", thread_id);

  if (varobj_get_frozen (var))
    uiout->field_int ("frozen", 1);

  gdb::unique_xmalloc_ptr<char> display_hint = varobj_get_display_hint (var);
  if (display_hint)
    uiout->field_string ("displayhint", display_hint.get ());

  if (varobj_is_dynamic_p (var))
    uiout->field_int ("dynamic", 1);
}

/* VAROBJ operations */

void
mi_cmd_var_create (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  CORE_ADDR frameaddr = 0;
  struct varobj *var;
  char *frame;
  char *expr;
  enum varobj_type var_type;

  if (argc != 3)
    error (_("-var-create: Usage: NAME FRAME EXPRESSION."));

  frame = argv[1];
  expr = argv[2];

  const char *name = argv[0];
  std::string gen_name;
  if (strcmp (name, "-") == 0)
    {
      gen_name = varobj_gen_name ();
      name = gen_name.c_str ();
    }
  else if (!isalpha (name[0]))
    error (_("-var-create: name of object must begin with a letter"));

  if (strcmp (frame, "*") == 0)
    var_type = USE_CURRENT_FRAME;
  else if (strcmp (frame, "@") == 0)
    var_type = USE_SELECTED_FRAME;  
  else
    {
      var_type = USE_SPECIFIED_FRAME;
      frameaddr = string_to_core_addr (frame);
    }

  if (varobjdebug)
    fprintf_unfiltered (gdb_stdlog,
			"Name=\"%s\", Frame=\"%s\" (%s), Expression=\"%s\"\n",
			name, frame, hex_string (frameaddr), expr);

  var = varobj_create (name, expr, frameaddr, var_type);

  if (var == NULL)
    error (_("-var-create: unable to create variable object"));

  print_varobj (var, PRINT_ALL_VALUES, 0 /* don't print expression */);

  uiout->field_int ("has_more", varobj_has_more (var, 0));
}

void
mi_cmd_var_delete (const char *command, char **argv, int argc)
{
  char *name;
  struct varobj *var;
  int numdel;
  int children_only_p = 0;
  struct ui_out *uiout = current_uiout;

  if (argc < 1 || argc > 2)
    error (_("-var-delete: Usage: [-c] EXPRESSION."));

  name = argv[0];

  /* If we have one single argument it cannot be '-c' or any string
     starting with '-'.  */
  if (argc == 1)
    {
      if (strcmp (name, "-c") == 0)
	error (_("-var-delete: Missing required "
		 "argument after '-c': variable object name"));
      if (*name == '-')
	error (_("-var-delete: Illegal variable object name"));
    }

  /* If we have 2 arguments they must be '-c' followed by a string
     which would be the variable name.  */
  if (argc == 2)
    {
      if (strcmp (name, "-c") != 0)
	error (_("-var-delete: Invalid option."));
      children_only_p = 1;
      name = argv[1];
    }

  /* If we didn't error out, now NAME contains the name of the
     variable.  */

  var = varobj_get_handle (name);

  numdel = varobj_delete (var, children_only_p);

  uiout->field_int ("ndeleted", numdel);
}

/* Parse a string argument into a format value.  */

static enum varobj_display_formats
mi_parse_format (const char *arg)
{
  if (arg != NULL)
    {
      int len;

      len = strlen (arg);

      if (strncmp (arg, "natural", len) == 0)
	return FORMAT_NATURAL;
      else if (strncmp (arg, "binary", len) == 0)
	return FORMAT_BINARY;
      else if (strncmp (arg, "decimal", len) == 0)
	return FORMAT_DECIMAL;
      else if (strncmp (arg, "hexadecimal", len) == 0)
	return FORMAT_HEXADECIMAL;
      else if (strncmp (arg, "octal", len) == 0)
	return FORMAT_OCTAL;
      else if (strncmp (arg, "zero-hexadecimal", len) == 0)
	return FORMAT_ZHEXADECIMAL;
    }

  error (_("Must specify the format as: \"natural\", "
	   "\"binary\", \"decimal\", \"hexadecimal\", \"octal\" or \"zero-hexadecimal\""));
}

void
mi_cmd_var_set_format (const char *command, char **argv, int argc)
{
  enum varobj_display_formats format;
  struct varobj *var;
  struct ui_out *uiout = current_uiout;

  if (argc != 2)
    error (_("-var-set-format: Usage: NAME FORMAT."));

  /* Get varobj handle, if a valid var obj name was specified.  */
  var = varobj_get_handle (argv[0]);

  format = mi_parse_format (argv[1]);
  
  /* Set the format of VAR to the given format.  */
  varobj_set_display_format (var, format);

  /* Report the new current format.  */
  uiout->field_string ("format", varobj_format_string[(int) format]);
 
  /* Report the value in the new format.  */
  std::string val = varobj_get_value (var);
  uiout->field_string ("value", val.c_str ());
}

void
mi_cmd_var_set_visualizer (const char *command, char **argv, int argc)
{
  struct varobj *var;

  if (argc != 2)
    error (_("Usage: NAME VISUALIZER_FUNCTION."));

  var = varobj_get_handle (argv[0]);

  if (var == NULL)
    error (_("Variable object not found"));

  varobj_set_visualizer (var, argv[1]);
}

void
mi_cmd_var_set_frozen (const char *command, char **argv, int argc)
{
  struct varobj *var;
  bool frozen;

  if (argc != 2)
    error (_("-var-set-format: Usage: NAME FROZEN_FLAG."));

  var = varobj_get_handle (argv[0]);

  if (strcmp (argv[1], "0") == 0)
    frozen = false;
  else if (strcmp (argv[1], "1") == 0)
    frozen = true;
  else
    error (_("Invalid flag value"));

  varobj_set_frozen (var, frozen);

  /* We don't automatically return the new value, or what varobjs got
     new values during unfreezing.  If this information is required,
     client should call -var-update explicitly.  */
}

void
mi_cmd_var_show_format (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  enum varobj_display_formats format;
  struct varobj *var;

  if (argc != 1)
    error (_("-var-show-format: Usage: NAME."));

  /* Get varobj handle, if a valid var obj name was specified.  */
  var = varobj_get_handle (argv[0]);

  format = varobj_get_display_format (var);

  /* Report the current format.  */
  uiout->field_string ("format", varobj_format_string[(int) format]);
}

void
mi_cmd_var_info_num_children (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  struct varobj *var;

  if (argc != 1)
    error (_("-var-info-num-children: Usage: NAME."));

  /* Get varobj handle, if a valid var obj name was specified.  */
  var = varobj_get_handle (argv[0]);

  uiout->field_int ("numchild", varobj_get_num_children (var));
}

/* Return 1 if given the argument PRINT_VALUES we should display
   the varobj VAR.  */

static int
mi_print_value_p (struct varobj *var, enum print_values print_values)
{
  struct type *type;

  if (print_values == PRINT_NO_VALUES)
    return 0;

  if (print_values == PRINT_ALL_VALUES)
    return 1;

  if (varobj_is_dynamic_p (var))
    return 1;

  type = varobj_get_gdb_type (var);
  if (type == NULL)
    return 1;
  else
    {
      type = check_typedef (type);

      /* For PRINT_SIMPLE_VALUES, only print the value if it has a type
	 and that type is not a compound type.  */
      return (TYPE_CODE (type) != TYPE_CODE_ARRAY
	      && TYPE_CODE (type) != TYPE_CODE_STRUCT
	      && TYPE_CODE (type) != TYPE_CODE_UNION);
    }
}

void
mi_cmd_var_list_children (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  struct varobj *var;  
  enum print_values print_values;
  int from, to;

  if (argc < 1 || argc > 4)
    error (_("-var-list-children: Usage: "
	     "[PRINT_VALUES] NAME [FROM TO]"));

  /* Get varobj handle, if a valid var obj name was specified.  */
  if (argc == 1 || argc == 3)
    var = varobj_get_handle (argv[0]);
  else
    var = varobj_get_handle (argv[1]);

  if (argc > 2)
    {
      from = atoi (argv[argc - 2]);
      to = atoi (argv[argc - 1]);
    }
  else
    {
      from = -1;
      to = -1;
    }

  const std::vector<varobj *> &children
    = varobj_list_children (var, &from, &to);

  uiout->field_int ("numchild", to - from);
  if (argc == 2 || argc == 4)
    print_values = mi_parse_print_values (argv[0]);
  else
    print_values = PRINT_NO_VALUES;

  gdb::unique_xmalloc_ptr<char> display_hint = varobj_get_display_hint (var);
  if (display_hint)
    uiout->field_string ("displayhint", display_hint.get ());

  if (from < to)
    {
      /* For historical reasons this might emit a list or a tuple, so
	 we construct one or the other.  */
      gdb::optional<ui_out_emit_tuple> tuple_emitter;
      gdb::optional<ui_out_emit_list> list_emitter;

      if (mi_version (uiout) == 1)
	tuple_emitter.emplace (uiout, "children");
      else
	list_emitter.emplace (uiout, "children");
      for (int ix = from; ix < to && ix < children.size (); ix++)
	{
	  ui_out_emit_tuple child_emitter (uiout, "child");

	  print_varobj (children[ix], print_values, 1 /* print expression */);
	}
    }

  uiout->field_int ("has_more", varobj_has_more (var, to));
}

void
mi_cmd_var_info_type (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  struct varobj *var;

  if (argc != 1)
    error (_("-var-info-type: Usage: NAME."));

  /* Get varobj handle, if a valid var obj name was specified.  */
  var = varobj_get_handle (argv[0]);

  std::string type_name = varobj_get_type (var);
  uiout->field_string ("type", type_name.c_str ());
}

void
mi_cmd_var_info_path_expression (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  struct varobj *var;

  if (argc != 1)
    error (_("Usage: NAME."));

  /* Get varobj handle, if a valid var obj name was specified.  */
  var = varobj_get_handle (argv[0]);
  
  const char *path_expr = varobj_get_path_expr (var);

  uiout->field_string ("path_expr", path_expr);
}

void
mi_cmd_var_info_expression (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  const struct language_defn *lang;
  struct varobj *var;

  if (argc != 1)
    error (_("-var-info-expression: Usage: NAME."));

  /* Get varobj handle, if a valid var obj name was specified.  */
  var = varobj_get_handle (argv[0]);

  lang = varobj_get_language (var);

  uiout->field_string ("lang", lang->la_natural_name);

  std::string exp = varobj_get_expression (var);
  uiout->field_string ("exp", exp.c_str ());
}

void
mi_cmd_var_show_attributes (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  int attr;
  const char *attstr;
  struct varobj *var;

  if (argc != 1)
    error (_("-var-show-attributes: Usage: NAME."));

  /* Get varobj handle, if a valid var obj name was specified */
  var = varobj_get_handle (argv[0]);

  attr = varobj_get_attributes (var);
  /* FIXME: define masks for attributes */
  if (attr & 0x00000001)
    attstr = "editable";
  else
    attstr = "noneditable";

  uiout->field_string ("attr", attstr);
}

void
mi_cmd_var_evaluate_expression (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  struct varobj *var;

  enum varobj_display_formats format;
  int formatFound;
  int oind;
  char *oarg;
    
  enum opt
  {
    OP_FORMAT
  };
  static const struct mi_opt opts[] =
    {
      {"f", OP_FORMAT, 1},
      { 0, 0, 0 }
    };

  /* Parse arguments.  */
  format = FORMAT_NATURAL;
  formatFound = 0;
  oind = 0;
  while (1)
    {
      int opt = mi_getopt ("-var-evaluate-expression", argc, argv,
			   opts, &oind, &oarg);

      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case OP_FORMAT:
	  if (formatFound)
	    error (_("Cannot specify format more than once"));
   
	  format = mi_parse_format (oarg);
	  formatFound = 1;
	  break;
	}
    }

  if (oind >= argc)
    error (_("Usage: [-f FORMAT] NAME"));
   
  if (oind < argc - 1)
    error (_("Garbage at end of command"));
 
  /* Get varobj handle, if a valid var obj name was specified.  */
  var = varobj_get_handle (argv[oind]);
   
  if (formatFound)
    {
      std::string val = varobj_get_formatted_value (var, format);

      uiout->field_string ("value", val.c_str ());
    }
  else
    {
      std::string val = varobj_get_value (var);

      uiout->field_string ("value", val.c_str ());
    }
}

void
mi_cmd_var_assign (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  struct varobj *var;

  if (argc != 2)
    error (_("-var-assign: Usage: NAME EXPRESSION."));

  /* Get varobj handle, if a valid var obj name was specified.  */
  var = varobj_get_handle (argv[0]);

  if (!varobj_editable_p (var))
    error (_("-var-assign: Variable object is not editable"));

  const char *expression = argv[1];

  /* MI command '-var-assign' may write memory, so suppress memory
     changed notification if it does.  */
  scoped_restore save_suppress
    = make_scoped_restore (&mi_suppress_notification.memory, 1);

  if (!varobj_set_value (var, expression))
    error (_("-var-assign: Could not assign "
	     "expression to variable object"));

  std::string val = varobj_get_value (var);
  uiout->field_string ("value", val.c_str ());
}

/* Type used for parameters passing to mi_cmd_var_update_iter.  */

struct mi_cmd_var_update
  {
    int only_floating;
    enum print_values print_values;
  };

/* Helper for mi_cmd_var_update - update each VAR.  */

static void
mi_cmd_var_update_iter (struct varobj *var, void *data_pointer)
{
  struct mi_cmd_var_update *data = (struct mi_cmd_var_update *) data_pointer;
  int thread_id, thread_stopped;

  thread_id = varobj_get_thread_id (var);

  if (thread_id == -1
      && (ptid_equal (inferior_ptid, null_ptid)
	  || is_stopped (inferior_ptid)))
    thread_stopped = 1;
  else
    {
      struct thread_info *tp = find_thread_global_id (thread_id);

      if (tp)
	thread_stopped = is_stopped (tp->ptid);
      else
	thread_stopped = 1;
    }

  if (thread_stopped
      && (!data->only_floating || varobj_floating_p (var)))
    varobj_update_one (var, data->print_values, false /* implicit */);
}

void
mi_cmd_var_update (const char *command, char **argv, int argc)
{
  struct ui_out *uiout = current_uiout;
  char *name;
  enum print_values print_values;

  if (argc != 1 && argc != 2)
    error (_("-var-update: Usage: [PRINT_VALUES] NAME."));

  if (argc == 1)
    name = argv[0];
  else
    name = argv[1];

  if (argc == 2)
    print_values = mi_parse_print_values (argv[0]);
  else
    print_values = PRINT_NO_VALUES;

  /* For historical reasons this might emit a list or a tuple, so we
     construct one or the other.  */
  gdb::optional<ui_out_emit_tuple> tuple_emitter;
  gdb::optional<ui_out_emit_list> list_emitter;

  if (mi_version (uiout) <= 1)
    tuple_emitter.emplace (uiout, "changelist");
  else
    list_emitter.emplace (uiout, "changelist");

  /* Check if the parameter is a "*", which means that we want to
     update all variables.  */

  if ((*name == '*' || *name == '@') && (*(name + 1) == '\0'))
    {
      struct mi_cmd_var_update data;

      data.only_floating = (*name == '@');
      data.print_values = print_values;

      /* varobj_update_one automatically updates all the children of
	 VAROBJ.  Therefore update each VAROBJ only once by iterating
	 only the root VAROBJs.  */

      all_root_varobjs (mi_cmd_var_update_iter, &data);
    }
  else
    {
      /* Get varobj handle, if a valid var obj name was specified.  */
      struct varobj *var = varobj_get_handle (name);

      varobj_update_one (var, print_values, true /* explicit */);
    }
}

/* Helper for mi_cmd_var_update().  */

static void
varobj_update_one (struct varobj *var, enum print_values print_values,
		   bool is_explicit)
{
  struct ui_out *uiout = current_uiout;

  std::vector<varobj_update_result> changes = varobj_update (&var, is_explicit);
  
  for (const varobj_update_result &r : changes)
    {
      int from, to;

      gdb::optional<ui_out_emit_tuple> tuple_emitter;
      if (mi_version (uiout) > 1)
	tuple_emitter.emplace (uiout, nullptr);
      uiout->field_string ("name", varobj_get_objname (r.varobj));

      switch (r.status)
	{
	case VAROBJ_IN_SCOPE:
	  if (mi_print_value_p (r.varobj, print_values))
	    {
	      std::string val = varobj_get_value (r.varobj);

	      uiout->field_string ("value", val.c_str ());
	    }
	  uiout->field_string ("in_scope", "true");
	  break;
        case VAROBJ_NOT_IN_SCOPE:
          uiout->field_string ("in_scope", "false");
	  break;
        case VAROBJ_INVALID:
          uiout->field_string ("in_scope", "invalid");
 	  break;
	}

      if (r.status != VAROBJ_INVALID)
	{
	  if (r.type_changed)
	    uiout->field_string ("type_changed", "true");
	  else
	    uiout->field_string ("type_changed", "false");
	}

      if (r.type_changed)
	{
	  std::string type_name = varobj_get_type (r.varobj);

	  uiout->field_string ("new_type", type_name.c_str ());
	}

      if (r.type_changed || r.children_changed)
	uiout->field_int ("new_num_children",
			  varobj_get_num_children (r.varobj));

      gdb::unique_xmalloc_ptr<char> display_hint
	= varobj_get_display_hint (r.varobj);
      if (display_hint)
	uiout->field_string ("displayhint", display_hint.get ());

      if (varobj_is_dynamic_p (r.varobj))
	uiout->field_int ("dynamic", 1);

      varobj_get_child_range (r.varobj, &from, &to);
      uiout->field_int ("has_more", varobj_has_more (r.varobj, to));

      if (!r.newobj.empty ())
	{
	  ui_out_emit_list list_emitter (uiout, "new_children");

	  for (varobj *child : r.newobj)
	    {
	      ui_out_emit_tuple tuple_emitter (uiout, NULL);
	      print_varobj (child, print_values, 1 /* print_expression */);
	    }
	}
    }
}

void
mi_cmd_enable_pretty_printing (const char *command, char **argv, int argc)
{
  if (argc != 0)
    error (_("-enable-pretty-printing: no arguments allowed"));

  varobj_enable_pretty_printing ();
}

void
mi_cmd_var_set_update_range (const char *command, char **argv, int argc)
{
  struct varobj *var;
  int from, to;

  if (argc != 3)
    error (_("-var-set-update-range: Usage: VAROBJ FROM TO"));
  
  var = varobj_get_handle (argv[0]);
  from = atoi (argv[1]);
  to = atoi (argv[2]);

  varobj_set_child_range (var, from, to);
}
