/* Routines for handling XML memory maps provided by target.

   Copyright (C) 2006-2016 Free Software Foundation, Inc.

   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 "memory-map.h"

#if !defined(HAVE_LIBEXPAT)

VEC(mem_region_s) *
parse_memory_map (const char *memory_map)
{
  static int have_warned;

  if (!have_warned)
    {
      have_warned = 1;
      warning (_("Can not parse XML memory map; XML support was disabled "
		 "at compile time"));
    }

  return NULL;
}

#else /* HAVE_LIBEXPAT */

#include "xml-support.h"

/* Internal parsing data passed to all XML callbacks.  */
struct memory_map_parsing_data
  {
    VEC(mem_region_s) **memory_map;
    char property_name[32];
  };

/* Handle the start of a <memory> element.  */

static void
memory_map_start_memory (struct gdb_xml_parser *parser,
			 const struct gdb_xml_element *element,
			 void *user_data, VEC(gdb_xml_value_s) *attributes)
{
  struct memory_map_parsing_data *data
    = (struct memory_map_parsing_data *) user_data;
  struct mem_region *r = VEC_safe_push (mem_region_s, *data->memory_map, NULL);
  ULONGEST *start_p, *length_p, *type_p;

  start_p
    = (ULONGEST *) xml_find_attribute (attributes, "start")->value;
  length_p
    = (ULONGEST *) xml_find_attribute (attributes, "length")->value;
  type_p
    = (ULONGEST *) xml_find_attribute (attributes, "type")->value;

  mem_region_init (r);
  r->lo = *start_p;
  r->hi = r->lo + *length_p;
  r->attrib.mode = (enum mem_access_mode) *type_p;
  r->attrib.blocksize = -1;
}

/* Handle the end of a <memory> element.  Verify that any necessary
   children were present.  */

static void
memory_map_end_memory (struct gdb_xml_parser *parser,
		       const struct gdb_xml_element *element,
		       void *user_data, const char *body_text)
{
  struct memory_map_parsing_data *data
    = (struct memory_map_parsing_data *) user_data;
  struct mem_region *r = VEC_last (mem_region_s, *data->memory_map);

  if (r->attrib.mode == MEM_FLASH && r->attrib.blocksize == -1)
    gdb_xml_error (parser, _("Flash block size is not set"));
}

/* Handle the start of a <property> element by saving the name
   attribute for later.  */

static void
memory_map_start_property (struct gdb_xml_parser *parser,
			   const struct gdb_xml_element *element,
			   void *user_data, VEC(gdb_xml_value_s) *attributes)
{
  struct memory_map_parsing_data *data
    = (struct memory_map_parsing_data *) user_data;
  char *name;

  name = (char *) xml_find_attribute (attributes, "name")->value;
  snprintf (data->property_name, sizeof (data->property_name), "%s", name);
}

/* Handle the end of a <property> element and its value.  */

static void
memory_map_end_property (struct gdb_xml_parser *parser,
			 const struct gdb_xml_element *element,
			 void *user_data, const char *body_text)
{
  struct memory_map_parsing_data *data
    = (struct memory_map_parsing_data *) user_data;
  char *name = data->property_name;

  if (strcmp (name, "blocksize") == 0)
    {
      struct mem_region *r = VEC_last (mem_region_s, *data->memory_map);

      r->attrib.blocksize = gdb_xml_parse_ulongest (parser, body_text);
    }
  else
    gdb_xml_debug (parser, _("Unknown property \"%s\""), name);
}

/* Discard the constructed memory map (if an error occurs).  */

static void
clear_result (void *p)
{
  VEC(mem_region_s) **result = (VEC(mem_region_s) **) p;
  VEC_free (mem_region_s, *result);
  *result = NULL;
}

/* The allowed elements and attributes for an XML memory map.  */

const struct gdb_xml_attribute property_attributes[] = {
  { "name", GDB_XML_AF_NONE, NULL, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

const struct gdb_xml_element memory_children[] = {
  { "property", property_attributes, NULL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    memory_map_start_property, memory_map_end_property },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

const struct gdb_xml_enum memory_type_enum[] = {
  { "ram", MEM_RW },
  { "rom", MEM_RO },
  { "flash", MEM_FLASH },
  { NULL, 0 }
};

const struct gdb_xml_attribute memory_attributes[] = {
  { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "length", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum, &memory_type_enum },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

const struct gdb_xml_element memory_map_children[] = {
  { "memory", memory_attributes, memory_children, GDB_XML_EF_REPEATABLE,
    memory_map_start_memory, memory_map_end_memory },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

const struct gdb_xml_element memory_map_elements[] = {
  { "memory-map", NULL, memory_map_children, GDB_XML_EF_NONE,
    NULL, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

VEC(mem_region_s) *
parse_memory_map (const char *memory_map)
{
  VEC(mem_region_s) *result = NULL;
  struct cleanup *back_to;
  struct memory_map_parsing_data data = { NULL };

  data.memory_map = &result;
  back_to = make_cleanup (clear_result, &result);
  if (gdb_xml_parse_quick (_("target memory map"), NULL, memory_map_elements,
			   memory_map, &data) == 0)
    {
      /* Parsed successfully, keep the result.  */
      discard_cleanups (back_to);
      return result;
    }

  do_cleanups (back_to);
  return NULL;
}

#endif /* HAVE_LIBEXPAT */
