/*
 * Gestion des trappes
 * (c)1991 par Denis GOUNELLE
 */

#include "aroff.h"
#define REAL_LINE( x ) ((x <= 0) ? (PageLen + x) : x)

struct Trp
{
  struct Noeud t_Node ;
  char	       t_Macro[3] ;
  long	       t_Ligne ;
  long	       t_Relat ;
} ;

extern long PageLen, ArgLen ;
extern struct TeteListe TTrp, TMac ;
extern struct Macro *CurrentMacro, *FindVar() ;

/************************************************************************/

struct Trp *FindTrp( lig )
long lig ;
{
  register struct Trp *t ;

  for ( t = (struct Trp *)TTrp.tl_Premier ;
	t ;
	t = (struct Trp *)t->t_Node.el_Suivant )
    if ( t->t_Ligne == lig ) break ;

  return( t ) ;
}

/************************************************************************/

void SetTrp( val , mac )
long val ;
char *mac ;

{
  long k ;
  struct Trp *t ;

  k = REAL_LINE( val ) ;
  t = FindTrp( k ) ;
  if ( ! t )
  {
    t = (struct Trp *)myalloc( sizeof(struct Trp) , 0 ) ;
    InsereTete( &TTrp , t ) ;
  }

  strcpy( t->t_Macro , mac ) ;
  t->t_Ligne = k ;
  t->t_Relat = val ;
}

/************************************************************************/

void RemTrp( val )
long val ;

{
  long k ;
  struct Trp *t ;

  k = REAL_LINE( val ) ;
  t = FindTrp( k ) ;
  if (  t )
  {
    EnleveElem( &TTrp , t ) ;
    free( t ) ;
  }
}

/************************************************************************/

void UpdateTrp()
{
  register struct Trp *t ;

  for ( t = (struct Trp *)TTrp.tl_Premier ;
	t ;
	t = (struct Trp *)t->t_Node.el_Suivant )
    if ( t->t_Relat < 0 ) t->t_Ligne = REAL_LINE( t->t_Relat ) ;
}

/************************************************************************/

long TestTrp( lig )
long lig ;

{
  register struct Trp *t ;

  for ( t = (struct Trp *)TTrp.tl_Premier ;
	t ;
	t = (struct Trp *)t->t_Node.el_Suivant )
    if ( t->t_Ligne == lig ) break ;

  if ( ! t ) return( 0 ) ;
  if ( CurrentMacro == FindVar( &TMac , t->t_Macro ) ) return( 0 ) ;

  ArgLen = 0 ;
  ExecCmd( t->t_Macro ) ;
  return( 1 ) ;
}

