/*  This file is part of the program psim.

    Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>

    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 <stdarg.h>
#include <stdio.h>
#include <fcntl.h>

#include <signal.h>

#include "psim.h"
#include "options.h"
#include "device.h" /* FIXME: psim should provide the interface */
#include "events.h" /* FIXME: psim should provide the interface */

#include "bfd.h"
#include "gdb/callback.h"
#include "gdb/remote-sim.h"

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

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

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

#include <errno.h>

#if !defined(O_NDELAY) || !defined(F_GETFL) || !defined(F_SETFL)
#undef WITH_STDIO
#define WITH_STDIO DO_USE_STDIO
#endif


extern char **environ;

static psim *simulation = NULL;


void
sim_io_poll_quit (void)
{
  /* nothing to do */
}

void
sim_io_printf_filtered(const char *msg, ...)
{
  va_list ap;
  va_start(ap, msg);
  vprintf(msg, ap);
  va_end(ap);
}

void
error (const char *msg, ...)
{
  va_list ap;
  va_start(ap, msg);
  vprintf(msg, ap);
  printf("\n");
  va_end(ap);

  /* any final clean up */
  if (ppc_trace[trace_print_info] && simulation != NULL)
    psim_print_info (simulation, ppc_trace[trace_print_info]);

  exit (1);
}

int
sim_io_write_stdout(const char *buf,
		    int sizeof_buf)
{
  switch (CURRENT_STDIO) {
  case DO_USE_STDIO:
    {
      int i;
      for (i = 0; i < sizeof_buf; i++) {
	putchar(buf[i]);
      }
      return i;
    }
    break;
  case DONT_USE_STDIO:
    return write(1, buf, sizeof_buf);
    break;
  default:
    error("sim_io_write_stdout: invalid switch\n");
  }
  return 0;
}

int
sim_io_write_stderr(const char *buf,
		    int sizeof_buf)
{
  switch (CURRENT_STDIO) {
  case DO_USE_STDIO:
    {
      int i;
      for (i = 0; i < sizeof_buf; i++) {
	fputc(buf[i], stderr);
      }
      return i;
    }
    break;
  case DONT_USE_STDIO:
    return write(2, buf, sizeof_buf);
    break;
  default:
    error("sim_io_write_stdout: invalid switch\n");
  }
  return 0;
}

int
sim_io_read_stdin(char *buf,
		  int sizeof_buf)
{
  switch (CURRENT_STDIO) {
  case DO_USE_STDIO:
    if (sizeof_buf > 1) {
      if (fgets(buf, sizeof_buf, stdin) != NULL)
	return strlen(buf);
    }
    else if (sizeof_buf == 1) {
      char b[2];
      if (fgets(b, sizeof(b), stdin) != NULL) {
	memcpy(buf, b, strlen(b));
	return strlen(b);
      }
    }
    else if (sizeof_buf == 0)
      return 0;
    return sim_io_eof;
    break;
  case DONT_USE_STDIO:
#if defined(O_NDELAY) && defined(F_GETFL) && defined(F_SETFL)
    {
      /* check for input */
      int flags;
      int status;
      int nr_read;
      int result;
      /* get the old status */
      flags = fcntl(0, F_GETFL, 0);
      if (flags == -1) {
	perror("sim_io_read_stdin");
	return sim_io_eof;
      }
      /* temp, disable blocking IO */
      status = fcntl(0, F_SETFL, flags | O_NDELAY);
      if (status == -1) {
	perror("sim_io_read_stdin");
	return sim_io_eof;
      }
      /* try for input */
      nr_read = read(0, buf, sizeof_buf);
      if (nr_read > 0
	  || (nr_read == 0 && sizeof_buf == 0))
	result = nr_read;
      else if (nr_read == 0)
	result = sim_io_eof;
      else { /* nr_read < 0 */
	if (errno == EAGAIN)
	  result = sim_io_not_ready;
	else 
	  result = sim_io_eof;
      }
      /* return to regular vewing */
      status = fcntl(0, F_SETFL, flags);
      if (status == -1) {
	perror("sim_io_read_stdin");
	return sim_io_eof;
      }
      return result;
    }
    break;
#endif
  default:
    error("sim_io_read_stdin: invalid switch\n");
    break;
  }
  return 0;
}

void
sim_io_flush_stdoutput(void)
{
  switch (CURRENT_STDIO) {
  case DO_USE_STDIO:
    fflush (stdout);
    break;
  case DONT_USE_STDIO:
    break;
  default:
    error("sim_io_flush_stdoutput: invalid switch\n");
    break;
  }
}

void
sim_io_error (SIM_DESC sd, const char *msg, ...)
{
  va_list ap;
  va_start(ap, msg);
  vprintf(msg, ap);
  printf("\n");
  va_end(ap);

  /* any final clean up */
  if (ppc_trace[trace_print_info] && simulation != NULL)
    psim_print_info (simulation, ppc_trace[trace_print_info]);

  exit (1);
}


void *
zalloc(long size)
{
  void *memory = malloc(size);
  if (memory == NULL)
    error("zalloc failed\n");
  memset(memory, 0, size);
  return memory;
}

/* When a CNTRL-C occures, queue an event to shut down the simulation */

static RETSIGTYPE
cntrl_c(int sig)
{
  psim_stop (simulation);
}


int
main(int argc, char **argv)
{
  const char *name_of_file;
  char *arg_;
  psim_status status;
  device *root = psim_tree();

  /* parse the arguments */
  argv = psim_options (root, argv + 1, SIM_OPEN_STANDALONE);
  if (argv[0] == NULL) {
    if (ppc_trace[trace_opts]) {
      print_options ();
      return 0;
    } else {
      psim_usage (0, 0, SIM_OPEN_STANDALONE);
    }
  }
  name_of_file = argv[0];

  if (ppc_trace[trace_opts])
    print_options ();

  /* create the simulator */
  simulation = psim_create(name_of_file, root);

  /* fudge the environment so that _=prog-name */
  arg_ = (char*)zalloc(strlen(argv[0]) + strlen("_=") + 1);
  strcpy(arg_, "_=");
  strcat(arg_, argv[0]);
  putenv(arg_);

  /* initialize it */
  psim_init(simulation);
  psim_stack(simulation, argv, environ);

  {
    RETSIGTYPE (*prev) ();
    prev = signal(SIGINT, cntrl_c);
    psim_run(simulation);
    signal(SIGINT, prev);
  }

  /* any final clean up */
  if (ppc_trace[trace_print_info])
    psim_print_info (simulation, ppc_trace[trace_print_info]);

  /* why did we stop */
  status = psim_get_status(simulation);
  switch (status.reason) {
  case was_continuing:
    error("psim: continuing while stopped!\n");
    return 0;
  case was_trap:
    error("psim: no trap insn\n");
    return 0;
  case was_exited:
    return status.signal;
  case was_signalled:
    printf ("%s: Caught signal %d at address 0x%lx\n",
 	    name_of_file, (int)status.signal,
 	    (long)status.program_counter);
    return status.signal;
  default:
    error("unknown halt condition\n");
    return 0;
  }
}
