
/* ###--------------------------------------------------------------### */
/*									*/
/* file		: pat_debug.c						*/
/* date		: Aug 17 1993						*/
/* version	: v104							*/
/* author	: Pirouz BAZARGAN SABET					*/
/* description	: high level function					*/
/*									*/
/* ###--------------------------------------------------------------### */

#include <stdio.h>
#include <stdlib.h>
#include PAT_H

struct typoin				/* structure used by pat_debug	*/
  {					/* to store its state		*/
  short  type;				/* code of the current structure*/
  short  mark;				/* stop mark			*/
  void  *data;				/* pointer of the structure	*/
  };

#define VHD_STKSIZ     200

#define VHD__errorDFN   -1
#define VHD__exitDFN     0
#define VHD__upDFN       1
#define VHD__topDFN      2
#define VHD__stopDFN     3
#define VHD__backDFN     4
#define VHD_paseqDFN     5
#define VHD_nextDFN      6
#define VHD_pagrpDFN     7
#define VHD_paiolDFN     8
#define VHD_papatDFN     9
#define VHD_pacomDFN    10
#define VHD_errflgDFN   11
#define VHD_savflgDFN   12
#define VHD_endflgDFN   13
#define VHD_iolnbrDFN   14
#define VHD_subseqDFN   15
#define VHD_nameDFN     16
#define VHD_lengthDFN   17
#define VHD_findexDFN   18
#define VHD_formatDFN   19
#define VHD_modeDFN     20
#define VHD_blankDFN    21
#define VHD_valueDFN    22
#define VHD_sigDFN      23
#define VHD_labelDFN    24
#define VHD_painiDFN    25
#define VHD_paevtDFN    26
#define VHD_lineDFN     27
#define VHD_indexDFN    28
#define VHD_usrvalDFN   29
#define VHD_simvalDFN   30
#define VHD_textDFN     31
#define VHD_positionDFN 32
#define VHD_actflagDFN  33
#define VHD_simflagDFN  34
#define VHD_deccomDFN   35
#define VHD_oldpatDFN   36
#define VHD_oldcomDFN   37
#define VHD_curpatDFN   38
#define VHD_curcomDFN   39
#define VHD_nxtpatDFN   40
#define VHD_MAXDFN      41

static int vhd_hash (str)

char *str;

  {
  int code = 0;

  while(*str != '\0')
    code =  code << 1 ^ *str++;

  return (code);
  }

static int vhd_getcmd (prvcmd)

char prvcmd[3][20];

  {
  char readstr[60];
  char comd0[20];
  char comd1[20];
  char comd2[20];
  int  code;

  printf ("\n\n\n COMMAND >> ");
  comd0[0] = '\0';
  comd1[0] = '\0';
  comd2[0] = '\0';
  gets   (readstr);
  sscanf (readstr,"%s%s%s",comd0,comd1,comd2);

  if (strcmp(comd0,"."))
    {
    strcpy (prvcmd[0], comd0);
    strcpy (prvcmd[1], comd1);
    strcpy (prvcmd[2], comd2);
    }
  code = vhd_hash (prvcmd[0]);

  printf ("\n\n\n\n\n");
  return (code);
  }

void pat_debug (head_pnt, stru_name)

void  *head_pnt;
char  *stru_name;

  {

  int		 i;
  int		 state;
  int		 newsta0;
  int		 readcmd = 0;
  char		 readtab[3][20];
  int		 stk_pnt = 0;
  int            type = VHD__exitDFN;

  struct typoin  current_pnt;
  struct typoin  stk[VHD_STKSIZ];

  char           empty[4];
  char           avail[12];

  int		 key[VHD_MAXDFN];
  char		*tab[VHD_MAXDFN];
  void		*nxt[VHD_MAXDFN];
  short		 typ[VHD_MAXDFN];

  struct paseq *paseq_pnt;
  struct pagrp *pagrp_pnt;
  struct paiol *paiol_pnt;
  struct papat *papat_pnt;
  struct pacom *pacom_pnt;
  struct paini *paini_pnt;
  struct paevt *paevt_pnt;

  key[VHD_paseqDFN]    = vhd_hash("paseq");
  key[VHD_nextDFN]     = vhd_hash("next");
  key[VHD_pagrpDFN]    = vhd_hash("pagrp");
  key[VHD_paiolDFN]    = vhd_hash("paiol");
  key[VHD_papatDFN]    = vhd_hash("papat");
  key[VHD_pacomDFN]    = vhd_hash("pacom");
  key[VHD_errflgDFN]   = vhd_hash("errflg");
  key[VHD_savflgDFN]   = vhd_hash("savflg");
  key[VHD_endflgDFN]   = vhd_hash("endflg");
  key[VHD_iolnbrDFN]   = vhd_hash("iolnbr");
  key[VHD_subseqDFN]   = vhd_hash("subseq");
  key[VHD_nameDFN]     = vhd_hash("name");
  key[VHD_lengthDFN]   = vhd_hash("length");
  key[VHD_findexDFN]   = vhd_hash("findex");
  key[VHD_formatDFN]   = vhd_hash("format");
  key[VHD_modeDFN]     = vhd_hash("mode");
  key[VHD_blankDFN]    = vhd_hash("blank");
  key[VHD_valueDFN]    = vhd_hash("value");
  key[VHD_sigDFN]      = vhd_hash("sig");
  key[VHD_labelDFN]    = vhd_hash("label");
  key[VHD_painiDFN]    = vhd_hash("paini");
  key[VHD_paevtDFN]    = vhd_hash("paevt");
  key[VHD_lineDFN]     = vhd_hash("line");
  key[VHD_indexDFN]    = vhd_hash("index");
  key[VHD_usrvalDFN]   = vhd_hash("usrval");
  key[VHD_simvalDFN]   = vhd_hash("simval");
  key[VHD_textDFN]     = vhd_hash("text");
  key[VHD_positionDFN] = vhd_hash("position");
  key[VHD_actflagDFN]  = vhd_hash("actflag");
  key[VHD_simflagDFN]  = vhd_hash("simflag");
  key[VHD_deccomDFN]   = vhd_hash("deccom");
  key[VHD_oldpatDFN]   = vhd_hash("oldpat");
  key[VHD_oldcomDFN]   = vhd_hash("oldcom");
  key[VHD_curpatDFN]   = vhd_hash("curpat");
  key[VHD_curcomDFN]   = vhd_hash("curcom");
  key[VHD_nxtpatDFN]   = vhd_hash("nxtpat");

	/* ###------------------------------------------------------### */
	/*    Set of predefined commands				*/
	/* ###------------------------------------------------------### */

  key[VHD__exitDFN] = vhd_hash ("_exit");
  key[VHD__upDFN]   = vhd_hash ("_up");
  key[VHD__topDFN]  = vhd_hash ("_top");
  key[VHD__stopDFN] = vhd_hash ("_stop");
  key[VHD__backDFN] = vhd_hash ("_back");

  strcpy (empty,"");
  strcpy (avail,"AVAILABLE");

  for (i=0 ; i<VHD_MAXDFN ; i++)
    typ[i] = i;

	/* ###------------------------------------------------------### */
	/*    Find the type of the head structure			*/
	/* ###------------------------------------------------------### */

  readcmd = vhd_hash (stru_name);
  for (i=0 ; i<VHD_MAXDFN ; i++)
    {
    if (readcmd == key[i])
      {
      type = typ[i];
      break;
      }
    }

	/* ###------------------------------------------------------### */
	/*    Exit if the head structure is empty			*/
	/* ###------------------------------------------------------### */

  if (head_pnt == NULL)
    type = VHD__exitDFN;

  current_pnt.data = head_pnt;
  current_pnt.type = type;
  state            = type;

  while (state != VHD__exitDFN)
    {
	/* ###------------------------------------------------------### */
	/*    Print structure's field until the exit command is read	*/
	/* ###------------------------------------------------------### */

    for (i=0 ; i<VHD_MAXDFN ; i++)
      {
      tab[i] = empty;
      nxt[i] = NULL;
      }

	/* ###------------------------------------------------------### */
	/*    _exit and _stop commands are allways available		*/
	/* ###------------------------------------------------------### */

    tab[VHD__exitDFN] = avail;
    tab[VHD__stopDFN] = avail;

	/* ###------------------------------------------------------### */
	/*    _up, _top, and _back commands are available only if the	*/
	/* stack is not empty						*/
	/* ###------------------------------------------------------### */

    if (stk_pnt != 0)
      {
      tab[VHD__upDFN] = avail;
      tab[VHD__topDFN] = avail;
      tab[VHD__backDFN] = avail;
      }

    switch (state)
      {

    case (VHD_paseqDFN):

		/* ###--------- paseq ---------### */

      paseq_pnt = (struct paseq *)(current_pnt.data);

      if (paseq_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)paseq_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_paseqDFN;
        }
      if (paseq_pnt->PAGRP != NULL)
        {
        tab[VHD_pagrpDFN] = avail;
        nxt[VHD_pagrpDFN] = (void *)paseq_pnt->PAGRP;
        typ[VHD_pagrpDFN] = VHD_pagrpDFN;
        }
      if (paseq_pnt->PAIOL != NULL)
        {
        tab[VHD_paiolDFN] = avail;
        nxt[VHD_paiolDFN] = (void *)paseq_pnt->PAIOL;
        typ[VHD_paiolDFN] = VHD_paiolDFN;
        }
      if (paseq_pnt->OLDPAT != NULL)
        {
        tab[VHD_oldpatDFN] = avail;
        nxt[VHD_oldpatDFN] = (void *)paseq_pnt->OLDPAT;
        typ[VHD_oldpatDFN] = VHD_papatDFN;
        }
      if (paseq_pnt->CURPAT != NULL)
        {
        tab[VHD_curpatDFN] = avail;
        nxt[VHD_curpatDFN] = (void *)paseq_pnt->CURPAT;
        typ[VHD_curpatDFN] = VHD_papatDFN;
        }
      if (paseq_pnt->NXTPAT != NULL)
        {
        tab[VHD_nxtpatDFN] = avail;
        nxt[VHD_nxtpatDFN] = (void *)paseq_pnt->NXTPAT;
        typ[VHD_nxtpatDFN] = VHD_papatDFN;
        }
      if (paseq_pnt->DECCOM != NULL)
        {
        tab[VHD_deccomDFN] = avail;
        nxt[VHD_deccomDFN] = (void *)paseq_pnt->DECCOM;
        typ[VHD_deccomDFN] = VHD_pacomDFN;
        }
      if (paseq_pnt->OLDCOM != NULL)
        {
        tab[VHD_oldcomDFN] = avail;
        nxt[VHD_oldcomDFN] = (void *)paseq_pnt->OLDCOM;
        typ[VHD_oldcomDFN] = VHD_pacomDFN;
        }
      if (paseq_pnt->CURCOM != NULL)
        {
        tab[VHD_curcomDFN] = avail;
        nxt[VHD_curcomDFN] = (void *)paseq_pnt->CURCOM;
        typ[VHD_curcomDFN] = VHD_pacomDFN;
        }

      printf ("-> next         : %s\n",tab[VHD_nextDFN]);
      printf ("-> pagrp        : %s\n",tab[VHD_pagrpDFN]);
      printf ("-> paiol        : %s\n",tab[VHD_paiolDFN]);
      printf ("-> deccom       : %s\n",tab[VHD_deccomDFN]);
      printf ("-> oldpat       : %s\n",tab[VHD_oldpatDFN]);
      printf ("-> odlcom       : %s\n",tab[VHD_oldcomDFN]);
      printf ("-> curpat       : %s\n",tab[VHD_curpatDFN]);
      printf ("-> curcom       : %s\n",tab[VHD_curcomDFN]);
      printf ("-> nxtpat       : %s\n",tab[VHD_nxtpatDFN]);
      printf ("   name         : %s\n",paseq_pnt->NAME);
      printf ("   patnbr       : %u\n",paseq_pnt->PATNBR);
      printf ("   iolnbr       : %u\n",paseq_pnt->IOLNBR);
      printf ("   lineno       : %u\n",paseq_pnt->LINENO);
      printf ("   subseq       : %u\n",paseq_pnt->SUBSEQ);
      printf ("   savflg       : %c\n",paseq_pnt->SAVFLG);
      printf ("   endflg       : %c\n",paseq_pnt->ENDFLG);
      printf ("   drvseq       : %u\n",paseq_pnt->DRVSEQ);
      printf ("   errflg       : %d\n",paseq_pnt->ERRFLG);

      break;

    case (VHD_pagrpDFN):

		/* ###--------- pagrp ---------### */

      pagrp_pnt = (struct pagrp *)(current_pnt.data);

      if (pagrp_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)pagrp_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_pagrpDFN;
        }
      printf ("-> next         : %s\n",tab[VHD_nextDFN]);
      printf ("   name         : %s\n",pagrp_pnt->NAME);
      printf ("   length       : %u\n",pagrp_pnt->LENGTH);
      printf ("   findex       : %u\n",pagrp_pnt->FINDEX);
      printf ("   flag         : %d\n",pagrp_pnt->FLAG);

      break;

    case (VHD_paiolDFN):

		/* ###--------- paiol ---------### */

      paiol_pnt = (struct paiol *)(current_pnt.data);

      if (paiol_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)paiol_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_paiolDFN;
        }
      printf ("-> next         : %s\n",tab[VHD_nextDFN]);
      printf ("   name         : %s\n",paiol_pnt->NAME);
      printf ("   format       : %c\n",paiol_pnt->FORMAT);
      printf ("   mode         : %c\n",paiol_pnt->MODE);
      printf ("   blank        : %u\n",paiol_pnt->BLANK);
      printf ("   value        : %c\n",paiol_pnt->VALUE);
      if (paiol_pnt->SIG != NULL)
        {
        tab[VHD_sigDFN] = empty;
        nxt[VHD_sigDFN] = (void *)paiol_pnt->SIG;
        }
      printf ("-> sig          : pas pret\n");

      break;

    case (VHD_papatDFN):

		/* ###--------- papat ---------### */

      papat_pnt = (struct papat *)(current_pnt.data);

      if (papat_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)papat_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_papatDFN;
        }
      printf ("-> next         : %s\n",tab[VHD_nextDFN]);
      printf ("   label        : %s\n",papat_pnt->LABEL);
      if (papat_pnt->PAINI != NULL)
        {
        tab[VHD_painiDFN] = avail;
        nxt[VHD_painiDFN] = (void *)papat_pnt->PAINI;
        typ[VHD_painiDFN] = VHD_painiDFN;
        }
      printf ("-> paini        : %s\n",tab[VHD_painiDFN]);
      if (papat_pnt->PAEVT != NULL)
        {
        tab[VHD_paevtDFN] = avail;
        nxt[VHD_paevtDFN] = (void *)papat_pnt->PAEVT;
        typ[VHD_paevtDFN] = VHD_paevtDFN;
        }
      printf ("-> paevt        : %s\n",tab[VHD_paevtDFN]);
      printf ("   line         : %u\n",papat_pnt->LINE);
      printf ("   blank        : %u\n",papat_pnt->BLANK);
      printf ("   actflag      : %c\n",papat_pnt->ACTFLAG);
      printf ("   simflag      : %c\n",papat_pnt->SIMFLAG);

      break;

    case (VHD_painiDFN):

		/* ###--------- paini ---------### */

      paini_pnt = (struct paini *)(current_pnt.data);

      if (paini_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)paini_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_painiDFN;
        }
      printf ("-> next         : %s\n",tab[VHD_nextDFN]);
      printf ("   name         : %s\n",paini_pnt->NAME);
      printf ("   value        : %c\n",paini_pnt->VALUE);

      break;

    case (VHD_paevtDFN):

		/* ###--------- paevt ---------### */

      paevt_pnt = (struct paevt *)(current_pnt.data);

      if (paevt_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)paevt_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_paevtDFN;
        }
      printf ("-> next         : %s\n",tab[VHD_nextDFN]);
      printf ("   index        : %u\n",paevt_pnt->INDEX);
      printf ("   usrval       : %c\n",paevt_pnt->USRVAL);
      printf ("   simval       : %c\n",paevt_pnt->SIMVAL);

      break;

    case (VHD_pacomDFN):

		/* ###--------- pacom ---------### */

      pacom_pnt = (struct pacom *)(current_pnt.data);

      if (pacom_pnt->NEXT != NULL)
        {
        tab[VHD_nextDFN] = avail;
        nxt[VHD_nextDFN] = (void *)pacom_pnt->NEXT;
        typ[VHD_nextDFN] = VHD_pacomDFN;
        }
      printf ("-> next         : %s\n"  , tab[VHD_nextDFN]);
      printf ("   text         : %s\n"  , pacom_pnt->TEXT);
      printf ("   position     : %u\n"  , pacom_pnt->POSITION);

      break;


      }

	/* ###------------------------------------------------------### */
	/*    Reading new command					*/
	/* ###------------------------------------------------------### */

    readcmd = vhd_getcmd (readtab);

    for (i=0 ; i<VHD_MAXDFN ; i++)
      {
      if (readcmd == key[i])
        break;
      }
    if ((i != VHD_MAXDFN+1) && (tab[i] == avail))
      newsta0 = i;
    else
      newsta0 = -1;

	/* ###------------------------------------------------------### */
	/*    Analysing new command					*/
	/* ###------------------------------------------------------### */

    switch (newsta0)
      {
      case (VHD__upDFN):
        current_pnt = stk[--stk_pnt] ;
        break;

      case (VHD__backDFN):
        while ((--stk_pnt != 0) && (stk[stk_pnt].mark != 1));
        current_pnt = stk[stk_pnt] ;
        break;

      case (VHD__stopDFN):
        current_pnt.mark = 1;
        break;

      case (VHD__topDFN):
        current_pnt = stk[0] ;
        stk_pnt     = 0 ;
        break;

      case (VHD__exitDFN):
        current_pnt.data = NULL;
        current_pnt.type = VHD__exitDFN;
        current_pnt.mark = 0;
        break;

      case (VHD__errorDFN):
        break;

      default:
        if (stk_pnt < VHD_STKSIZ)
          {
          stk[stk_pnt++]   = current_pnt;
          current_pnt.type = typ[newsta0];
          current_pnt.mark = 0;
          current_pnt.data = nxt[newsta0];
          }
        else
          printf ("==> STACK OVERFLOW -- STACK OVERFLOW <==\n");
        break;

      }

    state  = current_pnt.type;
    }
  }
