/* Generic support for remote debugging interfaces.

   Copyright (C) 1993, 1994, 1995, 1996, 1998, 2000, 2001
   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 2 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, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.  */

/*  This file actually contains two distinct logical "packages".  They
   are packaged together in this one file because they are typically
   used together.

   The first package is an addition to the serial package.  The
   addition provides reading and writing with debugging output and
   timeouts based on user settable variables.  These routines are
   intended to support serial port based remote backends.  These
   functions are prefixed with sr_.

   The second package is a collection of more or less generic
   functions for use by remote backends.  They support user settable
   variables for debugging, retries, and the like.  

   Todo:

   * a pass through mode a la kermit or telnet.
   * autobaud.
   * ask remote to change his baud rate.
 */

#include <ctype.h>

#include "defs.h"
#include "gdb_string.h"
#include "gdbcmd.h"
#include "target.h"
#include "serial.h"
#include "gdbcore.h"		/* for exec_bfd */
#include "inferior.h"		/* for generic_mourn_inferior */
#include "remote-utils.h"
#include "regcache.h"


void _initialize_sr_support (void);

struct _sr_settings sr_settings =
{
  4,				/* timeout:
				   remote-hms.c had 2
				   remote-bug.c had "with a timeout of 2, we time out waiting for
				   the prompt after an s-record dump."

				   remote.c had (2): This was 5 seconds, which is a long time to
				   sit and wait. Unless this is going though some terminal server
				   or multiplexer or other form of hairy serial connection, I
				   would think 2 seconds would be plenty.
				 */

  10,				/* retries */
  NULL,				/* device */
  NULL,				/* descriptor */
};

struct gr_settings *gr_settings = NULL;

static void usage (char *, char *);
static void sr_com (char *, int);

static void
usage (char *proto, char *junk)
{
  if (junk != NULL)
    fprintf_unfiltered (gdb_stderr, "Unrecognized arguments: `%s'.\n", junk);

  error (_("Usage: target %s [DEVICE [SPEED [DEBUG]]]\n\
where DEVICE is the name of a device or HOST:PORT"), proto);

  return;
}

#define CHECKDONE(p, q) \
{ \
  if (q == p) \
    { \
      if (*p == '\0') \
	return; \
      else \
	usage(proto, p); \
    } \
}

void
sr_scan_args (char *proto, char *args)
{
  int n;
  char *p, *q;

  /* if no args, then nothing to do. */
  if (args == NULL || *args == '\0')
    return;

  /* scan off white space.  */
  for (p = args; isspace (*p); ++p);;

  /* find end of device name.  */
  for (q = p; *q != '\0' && !isspace (*q); ++q);;

  /* check for missing or empty device name.  */
  CHECKDONE (p, q);
  sr_set_device (savestring (p, q - p));

  /* look for baud rate.  */
  n = strtol (q, &p, 10);

  /* check for missing or empty baud rate.  */
  CHECKDONE (p, q);
  baud_rate = n;

  /* look for debug value.  */
  n = strtol (p, &q, 10);

  /* check for missing or empty debug value.  */
  CHECKDONE (p, q);
  sr_set_debug (n);

  /* scan off remaining white space.  */
  for (p = q; isspace (*p); ++p);;

  /* if not end of string, then there's unrecognized junk. */
  if (*p != '\0')
    usage (proto, p);

  return;
}

void
gr_generic_checkin (void)
{
  sr_write_cr ("");
  gr_expect_prompt ();
}

void
gr_open (char *args, int from_tty, struct gr_settings *gr)
{
  target_preopen (from_tty);
  sr_scan_args (gr->ops->to_shortname, args);
  unpush_target (gr->ops);

  gr_settings = gr;

  if (sr_get_desc () != NULL)
    gr_close (0);

  /* If no args are specified, then we use the device specified by a
     previous command or "set remotedevice".  But if there is no
     device, better stop now, not dump core.  */

  if (sr_get_device () == NULL)
    usage (gr->ops->to_shortname, NULL);

  sr_set_desc (serial_open (sr_get_device ()));
  if (!sr_get_desc ())
    perror_with_name ((char *) sr_get_device ());

  if (baud_rate != -1)
    {
      if (serial_setbaudrate (sr_get_desc (), baud_rate) != 0)
	{
	  serial_close (sr_get_desc ());
	  perror_with_name (sr_get_device ());
	}
    }

  serial_raw (sr_get_desc ());

  /* If there is something sitting in the buffer we might take it as a
     response to a command, which would be bad.  */
  serial_flush_input (sr_get_desc ());

  /* default retries */
  if (sr_get_retries () == 0)
    sr_set_retries (1);

  /* default clear breakpoint function */
  if (gr_settings->clear_all_breakpoints == NULL)
    gr_settings->clear_all_breakpoints = remove_breakpoints;

  if (from_tty)
    {
      printf_filtered ("Remote debugging using `%s'", sr_get_device ());
      if (baud_rate != -1)
	printf_filtered (" at baud rate of %d",
			 baud_rate);
      printf_filtered ("\n");
    }

  push_target (gr->ops);
  gr_checkin ();
  gr_clear_all_breakpoints ();
  return;
}

/* Read a character from the remote system masking it down to 7 bits
   and doing all the fancy timeout stuff.  */

int
sr_readchar (void)
{
  int buf;

  buf = serial_readchar (sr_get_desc (), sr_get_timeout ());

  if (buf == SERIAL_TIMEOUT)
    error (_("Timeout reading from remote system."));

  if (sr_get_debug () > 0)
    printf_unfiltered ("%c", buf);

  return buf & 0x7f;
}

int
sr_pollchar (void)
{
  int buf;

  buf = serial_readchar (sr_get_desc (), 0);
  if (buf == SERIAL_TIMEOUT)
    buf = 0;
  if (sr_get_debug () > 0)
    {
      if (buf)
	printf_unfiltered ("%c", buf);
      else
	printf_unfiltered ("<empty character poll>");
    }

  return buf & 0x7f;
}

/* Keep discarding input from the remote system, until STRING is found.
   Let the user break out immediately.  */
void
sr_expect (char *string)
{
  char *p = string;

  immediate_quit++;
  while (1)
    {
      if (sr_readchar () == *p)
	{
	  p++;
	  if (*p == '\0')
	    {
	      immediate_quit--;
	      return;
	    }
	}
      else
	p = string;
    }
}

void
sr_write (char *a, int l)
{
  int i;

  if (serial_write (sr_get_desc (), a, l) != 0)
    perror_with_name (_("sr_write: Error writing to remote"));

  if (sr_get_debug () > 0)
    for (i = 0; i < l; i++)
      printf_unfiltered ("%c", a[i]);

  return;
}

void
sr_write_cr (char *s)
{
  sr_write (s, strlen (s));
  sr_write ("\r", 1);
  return;
}

int
sr_timed_read (char *buf, int n)
{
  int i;
  char c;

  i = 0;
  while (i < n)
    {
      c = sr_readchar ();

      if (c == 0)
	return i;
      buf[i] = c;
      i++;

    }
  return i;
}

/* Get a hex digit from the remote system & return its value. If
   ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */

int
sr_get_hex_digit (int ignore_space)
{
  int ch;

  while (1)
    {
      ch = sr_readchar ();
      if (ch >= '0' && ch <= '9')
	return ch - '0';
      else if (ch >= 'A' && ch <= 'F')
	return ch - 'A' + 10;
      else if (ch >= 'a' && ch <= 'f')
	return ch - 'a' + 10;
      else if (ch != ' ' || !ignore_space)
	{
	  gr_expect_prompt ();
	  error (_("Invalid hex digit from remote system."));
	}
    }
}

/* Get a byte from the remote and put it in *BYT.  Accept any number
   leading spaces.  */
void
sr_get_hex_byte (char *byt)
{
  int val;

  val = sr_get_hex_digit (1) << 4;
  val |= sr_get_hex_digit (0);
  *byt = val;
}

/* Read a 32-bit hex word from the remote, preceded by a space  */
long
sr_get_hex_word (void)
{
  long val;
  int j;

  val = 0;
  for (j = 0; j < 8; j++)
    val = (val << 4) + sr_get_hex_digit (j == 0);
  return val;
}

/* Put a command string, in args, out to the remote.  The remote is assumed to
   be in raw mode, all writing/reading done through desc.
   Ouput from the remote is placed on the users terminal until the
   prompt from the remote is seen.
   FIXME: Can't handle commands that take input.  */

static void
sr_com (char *args, int fromtty)
{
  sr_check_open ();

  if (!args)
    return;

  /* Clear all input so only command relative output is displayed */

  sr_write_cr (args);
  sr_write ("\030", 1);
  registers_changed ();
  gr_expect_prompt ();
}

void
gr_close (int quitting)
{
  gr_clear_all_breakpoints ();

  if (sr_is_open ())
    {
      serial_close (sr_get_desc ());
      sr_set_desc (NULL);
    }

  return;
}

/* gr_detach()
   takes a program previously attached to and detaches it.
   We better not have left any breakpoints
   in the program or it'll die when it hits one.
   Close the open connection to the remote debugger.
   Use this when you want to detach and do something else
   with your gdb.  */

void
gr_detach (char *args, int from_tty)
{
  if (args)
    error (_("Argument given to \"detach\" when remotely debugging."));

  if (sr_is_open ())
    gr_clear_all_breakpoints ();

  pop_target ();
  if (from_tty)
    puts_filtered ("Ending remote debugging.\n");

  return;
}

void
gr_files_info (struct target_ops *ops)
{
#ifdef __GO32__
  printf_filtered ("\tAttached to DOS asynctsr\n");
#else
  printf_filtered ("\tAttached to %s", sr_get_device ());
  if (baud_rate != -1)
    printf_filtered ("at %d baud", baud_rate);
  printf_filtered ("\n");
#endif

  if (exec_bfd)
    {
      printf_filtered ("\tand running program %s\n",
		       bfd_get_filename (exec_bfd));
    }
  printf_filtered ("\tusing the %s protocol.\n", ops->to_shortname);
}

void
gr_mourn (void)
{
  gr_clear_all_breakpoints ();
  unpush_target (gr_get_ops ());
  generic_mourn_inferior ();
}

void
gr_kill (void)
{
  return;
}

/* This is called not only when we first attach, but also when the
   user types "run" after having attached.  */
void
gr_create_inferior (char *execfile, char *args, char **env)
{
  int entry_pt;

  if (args && *args)
    error (_("Can't pass arguments to remote process."));

  if (execfile == 0 || exec_bfd == 0)
    error (_("No executable file specified"));

  entry_pt = (int) bfd_get_start_address (exec_bfd);
  sr_check_open ();

  gr_kill ();
  gr_clear_all_breakpoints ();

  init_wait_for_inferior ();
  gr_checkin ();

  insert_breakpoints ();	/* Needed to get correct instruction in cache */
  proceed (entry_pt, -1, 0);
}

/* Given a null terminated list of strings LIST, read the input until we find one of
   them.  Return the index of the string found or -1 on error.  '?' means match
   any single character. Note that with the algorithm we use, the initial
   character of the string cannot recur in the string, or we will not find some
   cases of the string in the input.  If PASSTHROUGH is non-zero, then
   pass non-matching data on.  */

int
gr_multi_scan (char *list[], int passthrough)
{
  char *swallowed = NULL;	/* holding area */
  char *swallowed_p = swallowed;	/* Current position in swallowed.  */
  int ch;
  int ch_handled;
  int i;
  int string_count;
  int max_length;
  char **plist;

  /* Look through the strings.  Count them.  Find the largest one so we can
     allocate a holding area.  */

  for (max_length = string_count = i = 0;
       list[i] != NULL;
       ++i, ++string_count)
    {
      int length = strlen (list[i]);

      if (length > max_length)
	max_length = length;
    }

  /* if we have no strings, then something is wrong. */
  if (string_count == 0)
    return (-1);

  /* otherwise, we will need a holding area big enough to hold almost two
     copies of our largest string.  */
  swallowed_p = swallowed = alloca (max_length << 1);

  /* and a list of pointers to current scan points. */
  plist = (char **) alloca (string_count * sizeof (*plist));

  /* and initialize */
  for (i = 0; i < string_count; ++i)
    plist[i] = list[i];

  for (ch = sr_readchar (); /* loop forever */ ; ch = sr_readchar ())
    {
      QUIT;			/* Let user quit and leave process running */
      ch_handled = 0;

      for (i = 0; i < string_count; ++i)
	{
	  if (ch == *plist[i] || *plist[i] == '?')
	    {
	      ++plist[i];
	      if (*plist[i] == '\0')
		return (i);

	      if (!ch_handled)
		*swallowed_p++ = ch;

	      ch_handled = 1;
	    }
	  else
	    plist[i] = list[i];
	}

      if (!ch_handled)
	{
	  char *p;

	  /* Print out any characters which have been swallowed.  */
	  if (passthrough)
	    {
	      for (p = swallowed; p < swallowed_p; ++p)
		fputc_unfiltered (*p, gdb_stdout);

	      fputc_unfiltered (ch, gdb_stdout);
	    }

	  swallowed_p = swallowed;
	}
    }
#if 0
  /* Never reached.  */
  return (-1);
#endif
}

/* Get ready to modify the registers array.  On machines which store
   individual registers, this doesn't need to do anything.  On machines
   which store all the registers in one fell swoop, this makes sure
   that registers contains all the registers from the program being
   debugged.  */

void
gr_prepare_to_store (void)
{
  /* Do nothing, since we assume we can store individual regs */
}

void
_initialize_sr_support (void)
{
  /* FIXME-now: if target is open... */
  add_setshow_filename_cmd ("remotedevice", no_class, &sr_settings.device, _("\
Set device for remote serial I/O."), _("\
Show device for remote serial I/O."), _("\
This device is used as the serial port when debugging using remote targets."),
			    NULL,
			    NULL, /* FIXME: i18n: */
			    &setlist, &showlist);

  add_com ("remote", class_obscure, sr_com,
	   _("Send a command to the remote monitor."));

}
