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

   Copyright (C) 2006-2012 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"
#include "gdb_assert.h"
#include "exceptions.h"

#include "gdb_string.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 = 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 = xml_find_attribute (attributes, "start")->value;
  length_p = xml_find_attribute (attributes, "length")->value;
  type_p = xml_find_attribute (attributes, "type")->value;

  mem_region_init (r);
  r->lo = *start_p;
  r->hi = r->lo + *length_p;
  r->attrib.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 = 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 = user_data;
  char *name;

  name = 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 = 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 = 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 */
