/* Simple BBC News ticker client
 * (c) Darren Salt
 * GPL applies
 * $Id: main.c,v 1.4 2007/04/25 14:11:15 ds Exp $
 */

/* System includes */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <swis.h>

/* Program includes */

#include "globals.h"

#include "configure.h"
#include "fetch.h"
#include "save.h"
#include "wimp.h"

#ifdef SYSREGDUMP
# include <setjmp.h>
# include <signal.h>
static jmp_buf jump;
static _kernel_oserror sigerr;

static void
sighandler (int sig)
{
  sigerr = *_kernel_last_oserror ();
  longjmp (jump, sig);
#ifdef FORTIFY
  Fortify_LeaveScope ();
#endif
  exit (2);
}
#endif


/* Startup & main loop */

int
main (int argc, const char **argv)
{
#ifdef FORTIFY
  Fortify_EnterScope ();
#endif
#ifdef SYSREGDUMP
  switch (setjmp (jump))
  {
  case 0:
    break;
  case SIGINT:
    report_error ("Escape");
    exit (2);
  default:
    {
      int *regdump, *os_regdump;
      const char *msg = 0;
      _swix (OS_ChangeEnvironment, _INR (0, 3) | _OUT (3), 7, 0, 0, 0,
	     &regdump);
      _swix (OS_ChangeEnvironment, _INR (0, 3) | _OUT (1), 13, 0, 0, 0,
	     &os_regdump);
      if (regdump && os_regdump)
	memcpy (os_regdump, regdump, 64);
      switch (sigerr.errnum & 0xFFFFFF)
      {
      case 0:
	msg = "Illegal instruction";
	break;
      case 1:
	msg = "Prefetch abort";
	break;
      case 2:
	msg = "Data abort";
	break;
      case 3:
	msg = "Address exception";
	break;
      case 5:
	msg = "Branch through zero";
	break;
      }
      if (msg)
      {
	static _kernel_oserror e = { 0 };
	sprintf (e.errmess, "Internal error: %s at &%08X", msg, regdump[15]);
	report_oserror (&e);
      }
      else
	report_oserror (&sigerr);
#ifdef FORTIFY
      Fortify_LeaveScope ();
#endif
      exit (2);
    }
  }

  signal (SIGFPE, sighandler);
  signal (SIGILL, sighandler);
  signal (SIGINT, sighandler);
  signal (SIGSEGV, sighandler);
  signal (SIGSTAK, sighandler);
  signal (SIGOSERROR, sighandler);
#endif

  {
    _kernel_oserror *e = _swix (OS_Byte, _INR (0, 1), 0, 0);
    char *p = strchr (e->errmess, '(');
    if (!p)
      p = e->errmess + strlen (e->errmess) + 1;
    osversion = malloc (p - e->errmess);
    if (!osversion)
      osversion = "RISC OS";
    else
    {
      osversion[p - e->errmess - 1] = '\0';
      strncpy (osversion, e->errmess, p - e->errmess - 1);
    }
  }

  read_servers (0);
  load_config (&opt);

  if (argc >= 2)
  {
    if (!strcmp (argv[1], "-h") || !strcmp (argv[1], "--html") ||
	!strcmp (argv[1], "-t") || !strcmp (argv[1], "--text"))
    {
      int p = 2;
      if (argv[2] && (!strcmp (argv[2], "-a") || !strcmp (argv[2], "--all")))
        /* ignore (backward compatibility) */
        p++;
      if (argv[p])
      {
	int i = find_server (argv[p]);
	if (i != -1)
	  strcpy (opt.selected_server, argv[p]);
      }
      fetch_ticker (1);
      if (argv[1][1] == 'h' || argv[1][2] == 'h')
	ticker_html (0);
      else
	ticker_text (0);
      goto finish;
    }
    else
      testmode = argc == 2 && (!strcmp (argv[1], "-T")
			       || !strcmp (argv[1], "--test"));
  }
  wimp_init ();
  while (!poll ())
    ;
  wimp_quit ();

finish:
  free (osversion);
  free_old_data ();
#ifdef FORTIFY
  Fortify_LeaveScope ();
#endif
  return 0;
}
