/* $Id: c,v.throwback 7.2 1998/09/01 19:52:27 stoklund Exp $ */
/* throwback.c: Support for throwback in TeX, MF and MP

   Copyright (C) 1998 Jakob Stoklund Olesen

   This library is free software; you can redistribute it and / or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with this library; if not ,write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 -
   1307, USA. */

#include "config.h"
#include "kernel.h"
#include "kpathsea:riscos.h"
#include "riscos.h"

#define DDEUtils_ThrowbackStart 0x42587
#define DDEUtils_ThrowbackSend 0x42588
#define DDEUtils_ThrowbackEnd 0x42589

/* Is throwback enabled? */
extern boolean throwback_flag = false;

/* Should printed output go to the throwback buffer? */
extern boolean throwback_selector = false;

/* The current line being built */
extern char throwback_line[THROWBACK_MAX + 1] = "";

/* index into throwback_line */
extern int throwback_pos = 0;

/* The full name of the primary input file */
static string primary_file = NULL;

/* The current status of the trowback protocol */
static enum
  {
    not_started, started, not_available
  }
status = not_started;

static
void
Throwback_Processing (string file)
{
  _kernel_swi_regs regs;

  regs.r[0] = 0;		/* ReasonProcessing */
  regs.r[2] = (unsigned) file;
  _kernel_swi (DDEUtils_ThrowbackSend, &regs, &regs);
}

/* Set the name of the primary input file */
extern void
throwbackprimary (const_string filename)
{
  string name = riscos_ensure_prefix (filename);

  /* maybe we started before setting the primary file? */
  /* call Throwback_ReasonProcessing */
  if (status == started)
    Throwback_Processing (name);

  if (primary_file)
    free (primary_file);

  primary_file = name;
}

/* Stop the throwback session. */
static void
tb_end ()
{
  _kernel_swi_regs regs;
  _kernel_swi (DDEUtils_ThrowbackEnd, &regs, &regs);
}

void
throwback_send (const_string filename, int lineno)
{
  _kernel_swi_regs regs;
  string full_name;

  printf ("throwback_send(\"%s\", %d):", filename, lineno);

  switch (status)
    {
    case not_available:	/* don't try another initialise */
      return;
    case not_started:		/* Try a startup */
      if (_kernel_swi (DDEUtils_ThrowbackStart, &regs, &regs))
	{
	  status = not_available;	/* some error */
	  return;
	}
      status = started;
      atexit (tb_end);
      /* Set the primary filename --- Throwback_ReasonProcessing */
      if (primary_file)
	Throwback_Processing (primary_file);
      /* fall through */
    case started:
      if (throwback_pos <= 0)
	return;			/* no message??? */
      throwback_line[throwback_pos] = '\0';
      puts (throwback_line);
      full_name = riscos_ensure_prefix (filename);
      regs.r[0] = 1;		/* Throwback_ReasonErrorDetails */
      regs.r[2] = (unsigned) full_name;
      regs.r[3] = lineno;
      regs.r[4] = 1;		/* severity: error */
      regs.r[5] = (unsigned) throwback_line;
      _kernel_swi (DDEUtils_ThrowbackSend, &regs, &regs);
      /* This is reset by throwback_start, but to be sure... */
      throwback_pos = 0;
      free (full_name);
      break;
    }
}
