/* Generic support for remote debugging interfaces.

   Copyright 1993, 1994, 1998 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., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, 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"


void _initialize_sr_support PARAMS ((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 PARAMS ((char *, char *));
static void sr_com PARAMS ((char *, int));

static void
usage (proto, junk)
     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, proto);

  return;
}

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

void
sr_scan_args (proto, 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 ()
{
  sr_write_cr ("");
  gr_expect_prompt ();
}

void
gr_open (args, from_tty, gr)
     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;

  gr_set_dcache (dcache_init (gr->readfunc, gr->writefunc));

  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 ()
{
  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 ()
{
  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 (string)
     char *string;
{
  char *p = string;

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

void
sr_write (a, l)
     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 (s)
     char *s;
{
  sr_write (s, strlen (s));
  sr_write ("\r", 1);
  return;
}

int
sr_timed_read (buf, n)
     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 (ignore_space)
     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 (byt)
     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 ()
{
  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 (args, fromtty)
     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 (quitting)
     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 (args, from_tty)
     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 (ops)
     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 ()
{
  gr_clear_all_breakpoints ();
  unpush_target (gr_get_ops ());
  generic_mourn_inferior ();
}

void
gr_kill ()
{
  return;
}

/* This is called not only when we first attach, but also when the
   user types "run" after having attached.  */
void
gr_create_inferior (execfile, args, env)
     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 (list, passthrough)
     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 ()
{
  /* Do nothing, since we assume we can store individual regs */
}

/* Read a word from remote address ADDR and return it.
 * This goes through the data cache.
 */
int
gr_fetch_word (addr)
     CORE_ADDR addr;
{
  return dcache_fetch (gr_get_dcache (), addr);
}

/* Write a word WORD into remote address ADDR.
   This goes through the data cache.  */

void
gr_store_word (addr, word)
     CORE_ADDR addr;
     int word;
{
  dcache_poke (gr_get_dcache (), addr, word);
}

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

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

}
