/************************************************************
 *      basic.c: Lambda Beta CAST builder: AUXILIARY FUNCTIONS
 ************************************************************/
/***********************************
   (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   TOPO General Public License (see file LICENSE)
 ***********************************
 $Log: basic.c,v $
 * Revision 1.4  1994/01/26  19:13:09  lotos
 * PC does not support filenames stating with aux, prn, etc.
 * son aux.c has been renamed into basic.c
 *
 * Revision 1.3  1993/01/18  18:13:04  lotos
 * distribution issues
 *
 * Revision 1.2  1992/09/11  16:48:21  lotos
 * bug fixing
 *
 * Revision 1.1  1992/09/02  16:07:33  lotos
 * Initial revision
 *
 ***********************************/

#ifndef lint
static char rcsid[]= "$Id: basic.c,v 1.4 1994/01/26 19:13:09 lotos Exp $";
#endif

# include "swbus.h"

PUBLIC TNODE*
do_node (type, class)
  int type, class;
{
  TNODE *anode = NULL;

  anode = new_node (type);
  anode->value0 = (CLR_TYPE)IAT_IT_add (gl, omgrnl);     /* grn */
  anode->value1 = (CLR_TYPE)class;                     /* class */
  return anode;
}

PUBLIC void
set_grn_type (p, ptype, grn)
  TNODE *p;
  int   ptype, grn;
{
  for (; p!= NULL; p = p->brothers) {
    p->type = ptype;
    initgl;
    putgrn (grn);                        /* set grn for this node */
    p->value0 = (CLR_TYPE)IAT_IT_add (gl, omgrnl);
    if (p->sons != NULL)
      set_grn_type (p->sons, ptype, grn);
  }
}

PUBLIC TNODE*
chain_brothers (olds, youngs)
  TNODE *olds, *youngs;
{
  TNODE *aux;

  if (olds == NULL)
    return youngs;
  for (aux = olds; aux->brothers != NULL; aux = gt_rb (aux))
    ;
  aux->brothers = youngs;
  return olds;
}

/* it returns f(L1, f(L2, f(L3, ..., f(Ln, init)...))) */
/* it also ensures that the colour attr is evaluated   */
/* L1,..,Ln is a list of TNODE* brothers               */
/* L is the first brother of them                      */
/* init is the initial value                           */
/* f() is a funtion                                    */

PUBLIC CLR_TYPE
reduce (f, L, attr, init, nrs)
   REDUCER f;
   TNODE*   L;
   int      attr;
   CLR_TYPE init;
   int      nrs; /* just for error reporting */
{
  if (L == NULL) return init;
  if (L->brothers == NULL)
    return f (fdclr (attr, L, nrs), init);
  return f (fdclr (attr, L, nrs), reduce (f, L->brothers, attr, init, nrs));
}

PUBLIC void
fatal_error (error, nfile, nline)
  char *error, *nfile;
  int  nline;
{
  (void)fprintf (stderr, "%s: %s in file %s at line %d\n",
		 progname, error, nfile, nline);
  exit (1);
}

/* This function builds an _annotation_list node. It is */
/* supposed that first and last are NOT NULL. first and */
/* last will become the sons of it. It is not checked   */
/* the type of the sons (they should be _annotations).  */
PUBLIC TNODE*
mk_annot_list (first)
  TNODE *first;
{
  TNODE *aux = NULL;

  initgl;
  putgrn (_annotation_list_1);            /* grnl for this node */
  aux = do_node (tannotation_list, 1);
  if (!lnsons (aux, first))
    fatal_error ("cannot link sons", __FILE__, __LINE__);
  return aux;
}
