/***********************************************
 (C) Copyright 1992-1993; dit/upm
   Distributed under the conditions stated in the
   EPS General Public License (see file LICENSE)
 ***********************************************
 $Log: asttrav.c,v $
 * Revision 2.3  1993/01/12  16:34:07  eps
 * portability issues
 *
 * Revision 2.2  1992/01/14  15:42:46  eps
 * distribution issues
 *
 * Revision 2.1  90/10/30  08:32:17  eps
 * hardwired colours added
 * new colours I2, IAT, AT
 * ! is no longer used as colour delimiter
 * still some bugs are known w.r.t. colour deallocation
 * 
 * Revision 1.3  90/03/16  15:41:25  eps
 * minor beautifying
 * 
 * Revision 1.2  90/01/29  14:51:35  eps
 * fixing license details
 * 
 * Revision 1.1  90/01/25  17:59:20  eps
 * Initial revision
 * 
 **********************************************/

#ifndef lint
static char rcsid[]= "$Id: asttrav.c,v 2.3 1993/01/12 16:34:07 eps Exp $";
#endif

/***********************************************************************
        Tomas P. de Miguel Moro
	Jose A. Manas
        dpt. Ingenieria Telematica
        E.T.S.I. Telecomunicacion
        Ciudad Universitaria
        E-28040  MADRID

        tmiguel@dit.upm.es
        jmanas@dit.upm.es
 **********************************************************************/

/* LINTLIBRARY */

# define cast_IMP
# include "cast.hh"

# include <stdio.h>

PUBLIC TNODE*
pred (nodep, tm)
        TNODE*          nodep;
        trav_mode       tm;
{
  if (nodep == NULL) return NULL;
  switch(tm)
  {
    case PREORDER  : if (t_fbrother(nodep))
                         return gt_ft(nodep);
                     else{
                            nodep = gt_lb(nodep);
                            if (nodep == NULL) return NULL;
                            while( nodep->sons != NULL )
                              nodep = gt_ls(nodep);
                            return nodep;
                         }
    case POSTORDER : if (! t_leaf(nodep))
                         return gt_ls(nodep);
                     else if (! t_fbrother(nodep))
                              return gt_lb(nodep);
                          else{
                                 nodep = gt_ft(nodep);
                                 while (t_fbrother(nodep))
                                 {
                                    nodep = gt_ft(nodep);
                                    if (nodep == NULL) return NULL;
                                 }
                                 return gt_lb(nodep);
                              }
  }
  return NULL;

} /* end of pred */

PUBLIC TNODE*
succ (nodep, tm)
        TNODE*          nodep;
        trav_mode       tm;
{
  if (nodep == NULL) return NULL;
  switch(tm)
  {
    case PREORDER  :
                     if (! t_leaf(nodep))
                         return gt_fs(nodep);
                     else{
                            if (nodep->brothers != NULL)
                                return gt_rb(nodep);
                            for (nodep = nodep->father; nodep != NULL;
                                  nodep = nodep->father)
                                if (nodep->brothers != NULL)
                                    return nodep->brothers;
                            return NULL;
                         }
    case POSTORDER : if (! t_brother(nodep))
                     {
                        nodep = gt_rb(nodep);
                        while (! t_leaf(nodep)) nodep = gt_fs(nodep);
                        return nodep;
                     }
                     else return gt_ft(nodep);
  }
  return NULL;

} /* end of succ */

PUBLIC TNODE*
lkpred (nodep, type, tm)
        TNODE*          nodep;
        int             type;
        trav_mode       tm;
{
  while ((nodep = pred (nodep, tm)) != NULL)
  {
    if (nodep->type == type) return nodep;
  }
  return NULL;

} /* end of lkpred */

PUBLIC TNODE*
lksucc (nodep, type, tm)
        TNODE*          nodep;
        int             type;
        trav_mode       tm;
{
  while ((nodep = succ (nodep, tm)) != NULL)
  {
    if (nodep->type == type) return nodep;
  }
  return NULL;

} /* end of lksucc */

PUBLIC TNODE*
lppred (nodep, predicate, tm)
        TNODE*          nodep;
        int             (*predicate) ();
        trav_mode       tm;
{
  while ((nodep = pred (nodep, tm)) != NULL)
  {
    if (predicate (nodep)) return nodep;
  }
  return NULL;

} /* end of lppred */

PUBLIC TNODE*
lpsucc (nodep, predicate, tm)
        TNODE*          nodep;
        int             (*predicate) ();
        trav_mode       tm;
{
  while ((nodep = succ (nodep, tm)) != NULL)
  {
    if (predicate (nodep)) return nodep;
  }
  return NULL;

} /* end of lpsucc */

