/*  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/>.
 
    */

/* This must come before any other includes.  */
#include "defs.h"

#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 "sim/callback.h"
#include "sim/sim.h"

#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>

#if !defined(O_NONBLOCK) || !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_NONBLOCK) && 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_NONBLOCK);
      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;
  }
}

/* Glue to use sim-fpu module.  */

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 * const *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;
  }
}
