/*
 * Gestion des macros, chaines, et registres
 * (c)1991 par Denis GOUNELLE
 */

#include "aroff.h"

struct Reg
{
  struct Noeud v_Node ;
  char	       v_Name[3] ;
  long	       v_Val ;
  long	       v_Inc ;
} ;

struct Str
{
  struct Noeud v_Node ;
  char	       v_Name[3] ;
  char	      *v_Val ;
} ;

extern struct Macro *CurrentMacro ;
extern struct TeteListe TStr, TReg, TMac ;

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

struct Reg *FindVar( tete , var )
struct TeteListe *tete ;
char *var ;

{
  register struct Reg *v ;

  for ( v = (struct Reg *)tete->tl_Premier ;
	v ;
	v = (struct Reg *)v->v_Node.el_Suivant )
    if (! strcmp( v->v_Name , var )) break ;

  return( v ) ;
}

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

void SetStr( var , val )
char *var , *val ;

{
  struct Str *v ;

  v = (struct Str *)FindVar( &TStr , var ) ;
  if ( ! v )
  {
    v = (struct Str *) myalloc( sizeof(struct Str) , 0 ) ;
    InsereTete( &TStr , v ) ;
    strcpy( v->v_Name , var ) ;
  }
  else free( v->v_Val ) ;

  v->v_Val = (char *)myalloc( strlen(val)+1 , 0 ) ;
  strcpy( v->v_Val , val ) ;
}

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

void SetReg( reg , val , inc )
char *reg ;
long val ;

{
  struct Reg *v ;

  v = (struct Reg *)FindVar( &TReg , reg ) ;
  if ( ! v )
  {
    v = (struct Reg *) myalloc( sizeof(struct Reg) , 0 ) ;
    InsereTete( &TReg , v ) ;
    strcpy( v->v_Name , reg ) ;
  }

  v->v_Val = val ;
  v->v_Inc = inc ;
}

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

void GetStr( name , val )
char *name, *val ;

{
  struct Str *v ;

  v = (struct Str *) FindVar( &TStr , name ) ;
  if ( v ) strcpy( val , v->v_Val ) ;
      else *val = '\0' ;
}

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

void GetReg( name , val )
char *name , *val ;

{
  struct Reg *v ;

  v = (struct Reg *) FindVar( &TReg , name ) ;
  sprintf( val , "%d" , ( v ) ? v->v_Val : 0 ) ;
}

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

void RemStr( name )
char *name ;

{
  struct Str *v ;

  v = (struct Str *) FindVar( &TStr , name ) ;
  if ( v ) EnleveElem( &TStr , v ) ;
}

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

void RemReg( name )
char *name ;

{
  struct Reg *v ;

  v = (struct Reg *) FindVar( &TReg , name ) ;
  if ( v ) EnleveElem( &TReg , v ) ;
}

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

void IncReg( name , op )
char *name, op ;

{
  struct Reg *v ;

  v = (struct Reg *) FindVar( &TReg , name ) ;
  if ( ! v ) return ;
  if ( op == '+' ) v->v_Val += v->v_Inc ;
	     else v->v_Val -= v->v_Inc ;
}

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

void SetMac( name )
char *name ;

{
  struct Macro *m ;

  m = (struct Macro *)FindVar( &TMac , name ) ;
  if ( ! m )
  {
    m = (struct Macro *)myalloc( sizeof(struct Macro) , 1 ) ;
    strcpy( m->m_Name , name ) ;
    InitListe( &(m->m_Def) ) ;
    InsereTete( &TMac , m ) ;
  }
  else VideListe( &(m->m_Def) ) ;

  CurrentMacro = m ;
}

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

void RemMac( name )
char *name ;

{
  struct Macro *m ;

  m = (struct Macro *) FindVar( &TMac , name ) ;
  if ( m )
  {
    VideListe( &(m->m_Def) ) ;
    EnleveElem( &TMac , m ) ;
  }
}

