/* Hardware ports.
   Copyright (C) 1998-2016 Free Software Foundation, Inc.
   Contributed by Andrew Cagney and Cygnus Solutions.

This file is part of GDB, the GNU debugger.

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 "hw-main.h"
#include "hw-base.h"

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif

#include <ctype.h>


struct hw_port_edge
{
  int my_port;
  struct hw *dest;
  int dest_port;
  struct hw_port_edge *next;
  object_disposition disposition;
};

struct hw_port_data
{
  hw_port_event_method *to_port_event;
  const struct hw_port_descriptor *ports;
  struct hw_port_edge *edges;
};

const struct hw_port_descriptor empty_hw_ports[] =
{
  { NULL, 0, 0, 0 },
};

static void
panic_hw_port_event (struct hw *me,
		     int my_port,
		     struct hw *source,
		     int source_port,
		     int level)
{
  hw_abort (me, "no port method");
}

void
create_hw_port_data (struct hw *me)
{
  me->ports_of_hw = HW_ZALLOC (me, struct hw_port_data);
  set_hw_port_event (me, panic_hw_port_event);
  set_hw_ports (me, empty_hw_ports);
}

void
delete_hw_port_data (struct hw *me)
{
  hw_free (me, me->ports_of_hw);
  me->ports_of_hw = NULL;
}

void
set_hw_ports (struct hw *me,
	      const struct hw_port_descriptor ports[])
{
  me->ports_of_hw->ports = ports;
}

void
set_hw_port_event (struct hw *me,
		   hw_port_event_method *port_event)
{
  me->ports_of_hw->to_port_event = port_event;
}


static void
attach_hw_port_edge (struct hw *me,
		     struct hw_port_edge **list,
		     int my_port,
		     struct hw *dest,
		     int dest_port,
		     object_disposition disposition)
{
  struct hw_port_edge *new_edge = HW_ZALLOC (me, struct hw_port_edge);
  new_edge->my_port = my_port;
  new_edge->dest = dest;
  new_edge->dest_port = dest_port;
  new_edge->next = *list;
  new_edge->disposition = disposition;
  *list = new_edge;
}


static void
detach_hw_port_edge (struct hw *me,
		     struct hw_port_edge **list,
		     int my_port,
		     struct hw *dest,
		     int dest_port)
{
  while (*list != NULL)
    {
      struct hw_port_edge *old_edge = *list;
      if (old_edge->dest == dest
	  && old_edge->dest_port == dest_port
	  && old_edge->my_port == my_port)
	{
	  if (old_edge->disposition == permenant_object)
	    hw_abort (me, "attempt to delete permenant port edge");
	  *list = old_edge->next;
	  hw_free (me, old_edge);
	  return;
	}
    }
  hw_abort (me, "attempt to delete unattached port");
}


#if 0
static void
clean_hw_port_edges (struct hw_port_edge **list)
{
  while (*list != NULL)
    {
      struct hw_port_edge *old_edge = *list;
      switch (old_edge->disposition)
	{
	case permenant_object:
	  list = &old_edge->next;
	  break;
	case temporary_object:
	  *list = old_edge->next;
	  hw_free (me, old_edge);
	  break;
	}
    }
}
#endif


/* Ports: */

void
hw_port_event (struct hw *me,
	       int my_port,
	       int level)
{
  int found_an_edge = 0;
  struct hw_port_edge *edge;
  /* device's lines directly connected */
  for (edge = me->ports_of_hw->edges;
       edge != NULL;
       edge = edge->next)
    {
      if (edge->my_port == my_port)
	{
	  edge->dest->ports_of_hw->to_port_event (edge->dest,
						  edge->dest_port,
						  me,
						  my_port,
						  level);
	  found_an_edge = 1;
	}
    }
  if (!found_an_edge)
    hw_abort (me, "No edge for port %d", my_port);
}


void
hw_port_attach (struct hw *me,
		int my_port,
		struct hw *dest,
		int dest_port,
		object_disposition disposition)
{
  attach_hw_port_edge (me,
		       &me->ports_of_hw->edges,
		       my_port,
		       dest,
		       dest_port,
		       disposition);
}


void
hw_port_detach (struct hw *me,
		int my_port,
		struct hw *dest,
		int dest_port)
{
  detach_hw_port_edge (me,
		       &me->ports_of_hw->edges,
		       my_port,
		       dest,
		       dest_port);
}


void
hw_port_traverse (struct hw *me,
		  hw_port_traverse_function *handler,
		  void *data)
{
  struct hw_port_edge *port_edge;
  for (port_edge = me->ports_of_hw->edges;
       port_edge != NULL;
       port_edge = port_edge->next)
    {
      handler (me, port_edge->my_port,
	       port_edge->dest, port_edge->dest_port,
	       data);
    }
}


int
hw_port_decode (struct hw *me,
		const char *port_name,
		port_direction direction)
{
  if (port_name == NULL || port_name[0] == '\0')
    return 0;
  if (isdigit (port_name[0]))
    {
      return strtoul (port_name, NULL, 0);
    }
  else
    {
      const struct hw_port_descriptor *ports =
	me->ports_of_hw->ports;
      if (ports != NULL)
	{
	  while (ports->name != NULL)
	    {
	      if (ports->direction == bidirect_port
		  || ports->direction == direction)
		{
		  if (ports->nr_ports > 0)
		    {
		      int len = strlen (ports->name);
		      if (strncmp (port_name, ports->name, len) == 0)
			{
			  if (port_name[len] == '\0')
			    return ports->number;
			  else if (isdigit (port_name[len]))
			    {
			      int port = (ports->number
					  + strtoul (&port_name[len], NULL, 0));
			      if (port >= ports->number + ports->nr_ports)
				hw_abort (me,
					  "Port %s out of range",
					  port_name);
			      return port;
			    }
			}
		    }
		  else if (strcmp (port_name, ports->name) == 0)
		    return ports->number;
		}
	      ports++;
	    }
	}
    }
  hw_abort (me, "Unrecognized port %s", port_name);
  return 0;
}


int
hw_port_encode (struct hw *me,
		int port_number,
		char *buf,
		int sizeof_buf,
		port_direction direction)
{
  const struct hw_port_descriptor *ports = NULL;
  ports = me->ports_of_hw->ports;
  if (ports != NULL) {
    while (ports->name != NULL)
      {
	if (ports->direction == bidirect_port
	    || ports->direction == direction)
	  {
	    if (ports->nr_ports > 0)
	      {
		if (port_number >= ports->number
		    && port_number < ports->number + ports->nr_ports)
		  {
		    strcpy (buf, ports->name);
		    sprintf (buf + strlen (buf), "%d", port_number - ports->number);
		    if (strlen (buf) >= sizeof_buf)
		      hw_abort (me, "hw_port_encode: buffer overflow");
		    return strlen (buf);
		  }
	      }
	    else
	      {
		if (ports->number == port_number)
		  {
		    if (strlen (ports->name) >= sizeof_buf)
		      hw_abort (me, "hw_port_encode: buffer overflow");
		    strcpy (buf, ports->name);
		    return strlen (buf);
		  }
	      }
	  }
	ports++;
      }
  }
  sprintf (buf, "%d", port_number);
  if (strlen (buf) >= sizeof_buf)
    hw_abort (me, "hw_port_encode: buffer overflow");
  return strlen (buf);
}
