/*******************************************************************************
Copyright by Telesoft Europe AB 1990, 1991.
Copyright by Telelogic Malmoe AB 1991, 1992, 1993, 1994.
Copyright by Telelogic AB 1994 - 2002.
This Program is owned by Telelogic and is protected by national
copyright laws and international copyright treaties. Telelogic
grants you the right to use this Program on one computer or in
one local computer network at any one time.
Under this License you may only modify the source code for the purpose
of adapting it to your environment. You must reproduce and include
any copyright and trademark notices on all copies of the source code.
You may not use, copy, merge, modify or transfer the Program except as
provided in this License.
Telelogic does not warrant that the Program will meet your
requirements or that the operation of the Program will be
uninterrupted and error free. You are solely responsible that the
selection of the Program and the modification of the source code
will achieve your intended results and that the results are actually
obtained.
*******************************************************************************/

/*
# clearcase sctutil.c@@/main/119 : 2002/05/03 jk
*/

/*---+---------------------------------------------------------------
     Include Files
-------------------------------------------------------------------*/

#include "scttypes.h"

#ifdef XVALIDATOR_LIB
#include "valutil.h"
#else
#include "sctlocal.h"
#endif


/*---+---------------------------------------------------------------
     Macros
-------------------------------------------------------------------*/
#ifdef XVALIDATOR_LIB

#ifndef XSYSD
#define XSYSD
#endif

#define XPRS_PARENT(PRS)       PRS->Parent
#define XPRS_OFFSPRING(PRS)    PRS->Offspring
#define XPRS_SENDER(PRS)       PRS->Sender
#define XPRS_NEXT_REC_SIG(PRS) PRS->Signal

#define XSIGNAL_SENDER(SIG)    SIG->Sender
#define XSIGNAL_IDNODE(SIG)    SIG->NameNode
#define XIS_STARTUP_SIGNAL(SIG) (SIG->NameNode->EC == xStartUpSignalEC)
#define XIS_CONT_SIGNAL(SIG)   (SIG->NameNode == xContSigId)
#define XCONT_SIG_PRIO(SIG)    SIG->Prio

#define XBEGIN_INPUTPORT_LOOP(PRS, SIGNAL_VAR) \
   for (SIGNAL_VAR = PRS->InputPort.Suc; \
        SIGNAL_VAR != (xSignalNode)&PRS->InputPort; \
        SIGNAL_VAR = SIGNAL_VAR->Suc) {
#define XEND_INPUTPORT_LOOP \
   }

#define XNOTINCLUDEFILE (CommandFile->File == NULL)

#else

#define XNOTINCLUDEFILE (XSYSD CommandFile == NULL)

#endif

#define XPRS_SELF(PRS)         PRS->Self

/************************ XREADANDWRITEF ***************************/
#ifdef XREADANDWRITEF

/*---+---------------------------------------------------------------
     xEntityString
-------------------------------------------------------------------*/
char * xEntityString[] = {
  /* xRemoteVarEC */      "Remote variable",
  /* xRemotePrdEC */      "Remote procedure",
  /* xSignalrouteEC */    "Signalroute",
  /* xStateEC */          "State",
  /* xTimerEC */          "Timer",
  /* xFormalParEC */      "Formal parameter",
  /* xLiteralEC */        "Literal",
  /* xVariableEC */       "Variable",
  /* xBlocksubstEC */     "Substructure",
  /* xPackageEC */        "Package",
  /* xProcedureEC */      "Procedure",
  /* xOperatorEC */       "Operator",
  /* xProcessEC */        "Process",
  /* xProcessTypeEC */    "Process type",
  /* xGateEC */           "Gate",
  /* xSignalEC */         "Signal",
  /* xSignalParEC */      "Signal parameter",
  /* xStartUpSignalEC */  "Startup signal",
  /* xRPCSignalEC */      "RPC signal",
  /* xSortEC */           "Type",
  /* xSyntypeEC */        "Type",
  /* xSystemEC */         "System",
  /* xSystemTypeEC */     "System type",
  /* xBlockEC */          "Block",
  /* xBlockTypeEC */      "Block type",
  /* xChannelEC */        "Channel",
  /* xServiceEC */        "Service",
  /* xServiceTypeEC */    "Service type",
  /* xCompoundStmtEC */   "Compound stmt",
  /* xSyntVariableEC */   "Synthesized variable",
  /* xMonitorCommandEC */ ""
};


/*---+---------------------------------------------------------------
     xNextInputChar
-------------------------------------------------------------------*/
int xNextInputChar (void)
{
  while (*xInputPos == '\0') {
    if (XSYSD xSaveLine != (char *)0) {
      xInputPos++;
      return EOF;
    }
    xNextLine();
  }
  return *(xInputPos++);
}


xbool xScanTokenSkipsEoln = 0;
/*---+---------------------------------------------------------------
     xScanToken
-------------------------------------------------------------------*/
xxToken xScanToken (char * strVar)
{
  int PosRead = 0;
  int NextChar;
  int IsEvenNumber;

  strVar[PosRead] = '\0';
  NextChar = xNextInputChar();
  while (NextChar == ' ' || NextChar == '\t')
    NextChar = xNextInputChar();

  /* Skip ASN.1 comments: -- to --, -- to EOLN */
  if ( NextChar == '-' ) {
    NextChar = xNextInputChar();
    if ( NextChar == '-' ) {
      for (;;) {
        NextChar = xNextInputChar();
        if (NextChar == '\n' || NextChar == EOF) {
          xUngetChar();
          return xScanToken(strVar);
        }
        if (NextChar == '-' ) {
          NextChar = xNextInputChar();
          if (NextChar == '-' ) {
            return xScanToken(strVar);
          }
        }
      }
    } else {
      xUngetChar();
      NextChar = '-';
    }
  }
  /* Skip SDL comments */
  if ( NextChar == '/' ) {
    NextChar = xNextInputChar();
    if ( NextChar == '*' ) {
      for (;;) {
        NextChar = xNextInputChar();
        if (NextChar == '\n' || NextChar == EOF) {
          xUngetChar();
          return xScanToken(strVar);
        }
        if (NextChar == '*' ) {
          NextChar = xNextInputChar();
          if (NextChar == '/' ) {
            return xScanToken(strVar);
          }
        }
      }
    } else {
      xUngetChar();
      NextChar = '/';
    }
  }

  if ( NextChar == EOF )  return xxEOF;
  if ( NextChar == '\n' ) {
    if (xScanTokenSkipsEoln)
      return xScanToken(strVar);
    return xxEoln;
  }

  if ( NextChar == '/' ) {
    NextChar = xNextInputChar();
    if ( NextChar == '=' )
      return xxNE;
    xUngetChar();
    return xxSlash;
  }
  if ( NextChar == ':' ) {
    NextChar = xNextInputChar();
    if ( NextChar == ')' )
      return xxRParColon;
    xUngetChar();
    return xxColon;
  }
  if ( NextChar == '.' ) {
    NextChar = xNextInputChar();
    if ( NextChar == ')' )
      return xxRParDot;
    xUngetChar();
    return xxDot;
  }
  if ( NextChar == '-' ) {
    NextChar = xNextInputChar();
    if ( NextChar == '>' )
      return xxRArrow;
    xUngetChar();
    return xxMinus;
  }
  if ( NextChar == '*' ) {
    NextChar = xNextInputChar();
    if ( NextChar == '>' )
      return xxStarArrow;
    xUngetChar();
    return xxStar;
  }

  if ( NextChar == '+' ) return xxPlus;
  if ( NextChar == '=' ) return xxEQ;
  if ( NextChar == ',' ) return xxComma;
  if ( NextChar == ';' ) return xxSemicolon;
  if ( NextChar == '^' ) return xxArrowHead;
  if ( NextChar == '[' ) return xxLBracket;
  if ( NextChar == ']' ) return xxRBracket;
  if ( NextChar == '{' ) return xxLCurlyBracket;
  if ( NextChar == '}' ) return xxRCurlyBracket;
  if ( NextChar == '@' ) {
    strVar[PosRead++] = '@';
    strVar[PosRead] = '\0';
    return xxAt;
  }
  if ( NextChar == '!' ) return xxExclMark;
  if ( NextChar == '<' ) {
    NextChar = xNextInputChar();
    if ( NextChar == '<' )
      return xxQuaStart;
    if ( NextChar == '=' )
      return xxLE;
    xUngetChar();
    return xxLT;
  }
  if ( NextChar == '>' ) {
    NextChar = xNextInputChar();
    if ( NextChar == '>' )
      return xxQuaEnd;
    if ( NextChar == '=' )
      return xxGE;
    xUngetChar();
    return xxGT;
  }
  if ( NextChar == '?' ) {
    NextChar = xNextInputChar();
    if ( NextChar == '?' )
      return xx2QuestionMark;
    xUngetChar();
    return xxQuestionMark;
  }
  if ( NextChar == '(' ) {
    NextChar = xNextInputChar();
    if ( NextChar == '.' )
      return xxLParDot;
    if ( NextChar == ':' )
      return xxLParColon;
    xUngetChar();
    return xxLPar;
  }
  if ( NextChar == ')' ) return xxRPar;

  if ( NextChar == '\'' ) {
    strVar[PosRead++] = (char)NextChar;
    NextChar = xNextInputChar();
    if ( NextChar == '\n' ) {
      strVar[PosRead] = '\0';
      return xxId;
    }
    IsEvenNumber = 0;
    while ( NextChar != '\'' ||
            IsEvenNumber || 
            ( *xInputPos >= 'A' && *xInputPos <= 'Z' &&
              ( ( *(xInputPos+1) >= 'A' && *(xInputPos+1) <= 'Z' ) ||
                *(xInputPos+1) == '_' ) ) ||
            *xInputPos == '\''
          ) {
      strVar[PosRead++] = (char)NextChar;
      if (NextChar == '\'') IsEvenNumber = ! IsEvenNumber;
      NextChar = xNextInputChar();
      if ( NextChar == '\n' || NextChar == EOF ) {
        xUngetChar();
        xPrintString("Missing end of string\n");
        strVar[PosRead] = '\0';    
        return xxErrorToken;
      }
    }
    strVar[PosRead++] = '\'';    
    strVar[PosRead] = '\0';    
    return xxString;
  }

  if ( NextChar == '"' ) {
    strVar[PosRead++] = (char)NextChar;
    NextChar = xNextInputChar();
    if ( NextChar == '\n' ) {
      strVar[PosRead] = '\0';
      return xxId;
    }
    IsEvenNumber = 0;
    while ( NextChar != '"' ||
            IsEvenNumber || 
            ( *xInputPos >= 'A' && *xInputPos <= 'Z' &&
              ( ( *(xInputPos+1) >= 'A' && *(xInputPos+1) <= 'Z' ) ||
                *(xInputPos+1) == '_' ) ) ||
            *xInputPos == '"'
          ) {
      strVar[PosRead++] = (char)NextChar;
      if (NextChar == '"') IsEvenNumber = ! IsEvenNumber;
      NextChar = xNextInputChar();
      if ( NextChar == '\n' || NextChar == EOF ) {
        xUngetChar();
        xPrintString("Missing end of string\n");
        strVar[PosRead] = '\0';    
        return xxErrorToken;
      }
    }
    strVar[PosRead++] = '"';    
    strVar[PosRead] = '\0';    
    return xxASN1String;
  }

  while ( NextChar != '\n' && NextChar != ' '  && NextChar != '\t' &&
          NextChar != '+'  && NextChar != '!'  && NextChar != '/'  &&
          NextChar != '>'  && NextChar != '*'  && NextChar != '('  &&
          NextChar != ')'  && NextChar != '"'  && NextChar != ','  &&
          NextChar != ';'  && NextChar != '<'  && NextChar != '='  &&
          NextChar != '{'  && NextChar != '}'  && NextChar != '['  &&
          NextChar != ']'  && NextChar != ':'  && NextChar != '?'  &&
          NextChar != EOF ) {
    if ( NextChar == '-' && *xInputPos == '>' ) break;
    if ( NextChar == '.' && *xInputPos == ')' ) break;
    strVar[PosRead++] = (char)NextChar;
    NextChar = xNextInputChar();
  }
  xUngetChar();
  strVar[PosRead] = '\0';
  if (PosRead==0) return xxErrorToken;
  if (xfEqualIdString(strVar, "system") == 2)
    return xxSystem;
  if (xfEqualIdString(strVar, "package") == 2)
    return xxPackage;
  if (xfEqualIdString(strVar, "block") == 2)
    return xxBlock;
  if (xfEqualIdString(strVar, "process") == 2)
    return xxProcess;
  if (xfEqualIdString(strVar, "service") == 2)
    return xxService;
  if (xfEqualIdString(strVar, "procedure") == 2)
    return xxProcedure;
  if (xfEqualIdString(strVar, "operator") == 2)
    return xxOperator;
  if (xfEqualIdString(strVar, "substructure") == 2)
    return xxSubstructure;
  if (xfEqualIdString(strVar, "channel") == 2)
    return xxChannel;
  if (xfEqualIdString(strVar, "signalroute") == 2)
    return xxSignalroute;
  if (xfEqualIdString(strVar, "type") == 2)
    return xxType;
  if (xfEqualIdString(strVar, "null") == 2)
    return xxNull;
  if (xfEqualIdString(strVar, "env") == 2)
    return xxEnv;
  if (xfEqualIdString(strVar, "self") == 2)
    return xxSelf;
  if (xfEqualIdString(strVar, "parent") == 2)
    return xxParent;
  if (xfEqualIdString(strVar, "offspring") == 2)
    return xxOffspring;
  if (xfEqualIdString(strVar, "sender") == 2)
    return xxSender;
  return xxId;
}


/*---+---------------------------------------------------------------
     xUngetToken
-------------------------------------------------------------------*/
void xUngetToken (
  xxToken Token,
  char  * strVar)
{
  switch (Token) {
  case xxEOF :
    if (XSYSD xSaveLine == (char *)0) {
      break;
    }
    /* fall through */
  case xxSlash :
  case xxColon :
  case xxMinus :
  case xxPlus :
  case xxStar :
  case xxComma :
  case xxSemicolon :
  case xxArrowHead :
  case xxLPar :
  case xxRPar :
  case xxDot :
  case xxLBracket :
  case xxRBracket :
  case xxLCurlyBracket :
  case xxRCurlyBracket :
  case xxAt :
  case xxEQ :
  case xxQuestionMark :
  case xxExclMark :
  case xxEoln :
    xInputPos--;
    break;
  case xxLParDot :
  case xxRParDot :
  case xxLParColon :
  case xxRParColon :
  case xxQuaStart :
  case xxQuaEnd :
  case xxLT :
  case xxLE :
  case xxGT :
  case xxGE :
  case xxNE :
  case xxRArrow :
  case xxStarArrow :
  case xx2QuestionMark :
    xInputPos = xInputPos-2;
    break;
  case xxString :
  case xxASN1String :
  case xxId :
  case xxErrorToken :
    xInputPos = xInputPos-strlen(strVar);
    break;
  case xxEnv :
    xInputPos = xInputPos-3;
    break;
  case xxType :
  case xxNull :
  case xxSelf :
    xInputPos = xInputPos-4;
    break;
  case xxBlock :
    xInputPos = xInputPos-5;
    break;
  case xxSystem :
  case xxParent :
  case xxSender :
    xInputPos = xInputPos-6;
    break;
  case xxPackage :
  case xxProcess :
  case xxService :
  case xxChannel :
    xInputPos = xInputPos-7;
    break;
  case xxOperator :
    xInputPos = xInputPos-8;
    break;
  case xxProcedure :
  case xxOffspring :
    xInputPos = xInputPos-9;
    break;
  case xxSignalroute :
    xInputPos = xInputPos-11;
    break;
  case xxSubstructure :
    xInputPos = xInputPos-12;
    break;
  }
}


/*---+---------------------------------------------------------------
     xSkipLine
-------------------------------------------------------------------*/
/* This function skips everything up to and including the next
   '\n' or EOF.
*/

void xSkipLine (void)
{
  int c;
  for (c=xNextInputChar(); c!='\n' && c!=EOF; c=xNextInputChar())
    ;
}


/*---+---------------------------------------------------------------
     xScanS
-------------------------------------------------------------------*/

/* This function is never used in the current version of the monitor.
   It is not removed as it might be useful to get old customer
   designed Read function work without major changes.
*/
int xScanS (char * strVar)
{
  int PosRead = 0;
  int cnt;

  while (*xInputPos == ' ' && *xInputPos == '\t') xInputPos++;
  cnt = sscanf(xInputPos, "%s%n", strVar, &PosRead);
  if (cnt > 1)
    cnt = 1;
  if (cnt == 1)
    xInputPos += PosRead;
  return cnt;
}


static int doubleCancel = 0;
/*---+---------------------------------------------------------------
     xReadSynonym
-------------------------------------------------------------------*/
void xReadSynonym(
  void         *Result_Addr,
  tSDLTypeInfo *RootTypeNode,
  char         *Synonym_Name)
{
  int     intVar;
  int     Index;
  xxToken Token;
  char    strVar[1000];
  char   *StrP;

#if defined(XMONITOR) && defined(XCLOCK) && ! defined(XVALIDATOR_LIB)
  SDL_Time xTimeEnteringReadSynonym;

  xTimeEnteringReadSynonym = SDL_Clock();
#endif

  if (XSYSD First_Call) {
    StrP = getenv("SDTEXTSYNFILE");
    if (StrP) {
      if ( ! strcmp(StrP, "[[") ) {        /* Cancel rest of synonyms */
        XSYSD ExtSynFileName[0] = '\0';
        XSYSD ExtSynFile = stdin;
        doubleCancel = 1;
#ifdef XVALIDATOR_LIB
        if (topToolType != SET_LINK)       /* No output if TTCN Link */
#endif
        {
          PRINTF("Aborted input of external synonyms according to "
                 "environment variable \"SDTEXTSYNFILE\".\n");
        }
      }
      else {
        strcpy(XSYSD ExtSynFileName, StrP);
#ifdef XVALIDATOR_LIB
        if (topToolType != SET_LINK)       /* No output if TTCN Link */
#endif
        {
          PRINTF2("Using external synonym file \"%s\"", XSYSD ExtSynFileName);
          PRINTF(" according to environment variable \"SDTEXTSYNFILE\".\n");
        }
      }
      XSYSD First_Call = (xbool)0;
    }
  }
  if (XSYSD First_Call) {
#ifdef XVALIDATOR_LIB
    if (topToolType == SET_LINK) {      /* Error message if TTCN Link */
      PRINTF("#SDL system contains external synonyms\n");
      return;
    }
#endif
Again:
    xPrintString( "External synonym file : " );
    Token = xScanToken(strVar);
    if (Token == xxLBracket) {          /* Cancel */
      XSYSD ExtSynFileName[0] = '\0';
      XSYSD ExtSynFile = stdin;
      Token = xScanToken(strVar);
      if (Token == xxLBracket) {        /* Cancel rest of synonyms */
        doubleCancel = 1;
        PRINTF("Aborted input of external synonyms\n");
      }
      if (Token != xxEoln ) {
        xSkipLine();
      }
    } else if (Token == xxMinus) {
      XSYSD ExtSynFileName[0] = '\0';
      XSYSD ExtSynFile = stdin;
      xSkipLine();
    } else if (Token == xxEoln ) {
      XSYSD ExtSynFileName[0] = '\0';
      XSYSD ExtSynFile = stdin;
    } else if (Token == xxQuestionMark) {
      xPrintString(" Name of existing file (*.syn) : ");
      xSkipLine();
      Token = xScanToken(strVar);
      if (Token == xxLBracket) {          /* Cancel */
        XSYSD ExtSynFileName[0] = '\0';
        XSYSD ExtSynFile = stdin;
        Token = xScanToken(strVar);
        if (Token == xxLBracket) {        /* Cancel rest of synonyms */
          doubleCancel = 1;
          PRINTF("Aborted input of external synonyms\n");
        }
        if (Token != xxEoln ) {
          xSkipLine();
        }
      } else if (Token == xxMinus) {
	XSYSD ExtSynFileName[0] = '\0';
	XSYSD ExtSynFile = stdin;
	xSkipLine();
      } else if (Token == xxEoln ) {
	XSYSD ExtSynFileName[0] = '\0';
	XSYSD ExtSynFile = stdin;
      } else if (Token == xxQuestionMark) {
	xSkipLine();
	goto Again;
      } else {
	xUngetToken(Token, strVar);
	sscanf(xInputPos, "%s", XSYSD ExtSynFileName);
	xSkipLine();
	if ((XSYSD ExtSynFile = fopen(XSYSD ExtSynFileName, "r")) == NULL) {
	  PRINTF2("File %s not found\n", XSYSD ExtSynFileName);
	  goto Again;
	}
      }
    } else {
      xUngetToken(Token, strVar);
      sscanf(xInputPos, "%s", XSYSD ExtSynFileName);
      xSkipLine();
      if ((XSYSD ExtSynFile = fopen(XSYSD ExtSynFileName, "r")) == NULL) {
        PRINTF2("File %s not found\n", XSYSD ExtSynFileName);
        goto Again;
      }
    }
    XSYSD First_Call = (xbool)0;
  } else {
    if (XSYSD ExtSynFileName[0] != '\0') {
      if ((XSYSD ExtSynFile = fopen(XSYSD ExtSynFileName, "r")) == NULL) {
#ifdef XVALIDATOR_LIB
        if (topToolType == SET_LINK) {      /* Error message if TTCN Link */
          PRINTF2("#Cannot open external synonym file (%s) for reading "
                  "synonyms\n", XSYSD ExtSynFileName);
          return;
        }
#endif
        PRINTF2("Cannot reopen external synonym file (%s)",
                XSYSD ExtSynFileName);
        xPrintString(" for reading more synonyms\n");
        SDL_Halt();
      }
    }
  }
  if (XSYSD ExtSynFile == stdin) {
    if (doubleCancel) {
      memset(Result_Addr, 0, RootTypeNode->SortSize);
      return;
    }

TryAgain:
    PRINTF3("Synonym %s (%s) : ", Synonym_Name, RootTypeNode->Name);
    while (! xGenericReadSort(Result_Addr, RootTypeNode) ) {
      if (XSYSD xInputLine[0] == '[') {   /* Cancel */
        if (XSYSD xInputLine[1] == '[') { /* Cancel rest of synonyms */
          doubleCancel = 1;
          PRINTF("Aborted input of external synonyms\n");
        }
        memset(Result_Addr, 0, RootTypeNode->SortSize);
        break;
      }
      xSkipLine();
      xPrintString("Error in value\n");
      PRINTF3("Synonym %s (%s) : ", Synonym_Name, RootTypeNode->Name);
    }
    xSkipLine();
#if defined(XMONITOR) && defined(XCLOCK) && ! defined(XVALIDATOR_LIB)
    XSYSD xTimeInMonitor = xPlus_SDL_Duration(XSYSD xTimeInMonitor,
                  xMinusD_SDL_Time(SDL_Clock(), xTimeEnteringReadSynonym));
#endif
    return;
  }
  while ((intVar = fgetc(XSYSD ExtSynFile)) != EOF) {
    ungetc(intVar, XSYSD ExtSynFile);
    fscanf(XSYSD ExtSynFile, "%s", strVar);
    if (xfEqualIdString(Synonym_Name, strVar) == 2) {
      /* Read rest of line */
      Index = 0;
      while ((intVar = fgetc(XSYSD ExtSynFile)) == ' ' || intVar == '\t')
        ;
      ungetc(intVar, XSYSD ExtSynFile);
      while (Index < 998 &&
             (intVar = fgetc(XSYSD ExtSynFile)) != EOF && intVar != '\n')
        strVar[Index++] = (char)intVar;
      strVar[Index++] = '\n';
      strVar[Index] = '\0';
      xChangeInputLine(strVar);
      if (! xGenericReadSort(Result_Addr, RootTypeNode) ) {
#ifdef XVALIDATOR_LIB
        if (topToolType == SET_LINK) {      /* Error message if TTCN Link */
          PRINTF3("#Error in value for external synonym %s (%s)\n",
                  Synonym_Name, RootTypeNode->Name);
          return;
        }
#endif
        PRINTF3("Error in value for %s (%s)\n",
               Synonym_Name, RootTypeNode->Name);
        SDL_Halt();
      }
      xRestoreInputLine();
      fclose(XSYSD ExtSynFile);
#if defined(XMONITOR) && defined(XCLOCK) && ! defined(XVALIDATOR_LIB)
      XSYSD xTimeInMonitor = xPlus_SDL_Duration(XSYSD xTimeInMonitor,
                  xMinusD_SDL_Time(SDL_Clock(), xTimeEnteringReadSynonym));
#endif
      return;
    }
    while ((intVar = fgetc(XSYSD ExtSynFile)) != '\n' && intVar != EOF)
      ;
  }
#ifdef XVALIDATOR_LIB
  if (topToolType == SET_LINK) {      /* Error message if TTCN Link */
    PRINTF3("#Value not found for external synonym %s (%s)\n",
            Synonym_Name, RootTypeNode->Name);
    return;
  }
#endif
  PRINTF3("Value not found for %s (%s)\n", Synonym_Name, RootTypeNode->Name);
  fclose(XSYSD ExtSynFile);
  goto TryAgain;
  /*  SDL_Halt(); */
}


/*---+---------------------------------------------------------------
     xPromptQuestionMark
-------------------------------------------------------------------*/
xxToken xPromptQuestionMark(
  char           * Prompt,
  char           * QuestionPrompt,
  char           * strVar)
{
  xxToken          Token;

  Token = xScanToken(strVar);
  if (Token == xxEOF) return xxEOF;
  if (Token == xxEoln) {
    if (XSYSD xSaveLine != (char *)0) return xxEOF;
    if (XNOTINCLUDEFILE) {
      /* If reading include file do no ouput Prompt
         to prevent UI from trigger on ": " in Prompt */
      xPrintString(Prompt);
    }
    Token = xScanToken(strVar);
  }
  if (QuestionPrompt != (char *)0) {
    while (Token == xxQuestionMark || Token == xxEoln) {
      xPrintString(QuestionPrompt);
      if (Token != xxEoln) xSkipLine();
      Token = xScanToken(strVar);
    }
  } else {
    while (Token == xxQuestionMark) {
      xPrintString(Prompt);
      xSkipLine();
      Token = xScanToken(strVar);
    }
  }
  return Token;
}


/*---+---------------------------------------------------------------
     xGetIdNodeInECSet
-------------------------------------------------------------------*/
xIdNode xGetIdNodeInECSet(
  char           * Prompt,
  long             ECSet,
  xIdNode          FromNode,
  xbool          * EmptyInput,
  xbool            OKEmptyInput,
  xIdNode          LimId)
{
  char             strVar[256];
  xxToken          Token;

  *EmptyInput = (xbool)0;
  Token = xScanToken(strVar);
  if (Token == xxEoln) {
    if (XSYSD xSaveLine != (char *)0) return (xIdNode)0;
    if (XNOTINCLUDEFILE) {
      /* If reading include file do no ouput Prompt
         to prevent UI from trigger on ": " in Prompt */
      xPrintString(Prompt);
    }
    Token = xScanToken(strVar);
  }
  if ((Token == xxEoln && OKEmptyInput) || Token == xxRCurlyBracket) {
    *EmptyInput = (xbool)1;
    xUngetToken(Token, strVar);
    return (xIdNode)0;
  }
  if (Token == xxMinus) {
    if ( OKEmptyInput )
      *EmptyInput = (xbool)1;
    else
      xPrintString("Default name not allowed\n");
    return (xIdNode)0;
  }

  while ( Token == xxQuestionMark ||
          (Token == xxEoln && ! OKEmptyInput)
        ) {
    xMonListIdNodeECSet(ECSet, FromNode, LimId, (xbool)0);
    xPrintString(": ");
    if (Token != xxEoln) xSkipLine();
    Token = xScanToken(strVar);
    if ((Token == xxEoln && OKEmptyInput) || Token == xxRCurlyBracket) {
      *EmptyInput = (xbool)1;
      xUngetToken(Token, strVar);
      return (xIdNode)0;
    }
    if (Token == xxMinus) {
      if ( OKEmptyInput )
        *EmptyInput = (xbool)1;
      else
        xPrintString("Default name not allowed\n");
      return (xIdNode)0;
    }
  }
  return xReadIdNodeInECSet(Token, strVar, ECSet, FromNode, LimId);
}


/*---+---------------------------------------------------------------
     xReadIdNodeInECSet
-------------------------------------------------------------------*/
xIdNode xReadIdNodeInECSet(
  xxToken          Token,
  char           * strVar,
  long             ECSet,
  xIdNode          FromNode,
  xIdNode          LimId)
{
  xEntityClassType QuaEC = xSystemEC;
  xfCodeType       Code;

  Code = xfOk;
  if (Token == xxNull) {
    if (((1L<<((long)xProcessEC)) & ECSet) != 0)
      return (xIdNode)xNullId;
    else
      Token = xxId;
  }

  if (Token == xxQuaStart) Token = xScanToken(strVar);
  if (Token == xxSystem || Token == xxBlock || Token == xxProcess ||
      Token == xxService || Token == xxProcedure || Token == xxOperator ||
      Token == xxSubstructure || Token == xxPackage || Token == xxType) 
    FromNode = xSymbolTableRoot;
  while (Token == xxSystem || Token == xxBlock || Token == xxProcess ||
         Token == xxService || Token == xxProcedure || Token == xxOperator ||
         Token == xxSubstructure || Token == xxPackage || Token == xxType) {
    if (Token == xxSystem) {
      Token = xScanToken(strVar);
      if (Token == xxType) {
        QuaEC = xSystemTypeEC; Token = xScanToken(strVar);
      } else
        QuaEC = xSystemEC;
    } else if (Token == xxBlock) {
      Token = xScanToken(strVar);
      if (Token == xxType) {
        QuaEC = xBlockTypeEC; Token = xScanToken(strVar);
      } else
        QuaEC = xBlockEC;
    } else if (Token == xxProcess) {
      Token = xScanToken(strVar);
      if (Token == xxType) {
        QuaEC = xProcessTypeEC; Token = xScanToken(strVar);
      } else
        QuaEC = xProcessEC;
    } else if (Token == xxService) {
      Token = xScanToken(strVar);
      if (Token == xxType) {
        QuaEC = xServiceTypeEC; Token = xScanToken(strVar);
      } else
        QuaEC = xServiceEC;
    } else if (Token == xxProcedure) {
      QuaEC = xProcedureEC; Token = xScanToken(strVar);
    } else if (Token == xxOperator) {
      QuaEC = xOperatorEC; Token = xScanToken(strVar);
    } else if (Token == xxSubstructure) {
      QuaEC = xBlocksubstEC; Token = xScanToken(strVar);
    } else if (Token == xxPackage) {
      QuaEC = xPackageEC; Token = xScanToken(strVar);
    } else if (Token == xxType) {
      QuaEC = xSortEC; Token = xScanToken(strVar);
    }

    xfDecodeId(strVar, FromNode, 1L << ((long)QuaEC), &FromNode, &Code,
               (xIdNode)0);
    if (Code != xfOk) break;
    Token = xScanToken(strVar);
    if (QuaEC == xBlockEC && Token == xxColon) {
      /* Accept and skip ":<nr>" because maybe it is a block instance set */
      Token = xScanToken(strVar);
      if (Token == xxId) {
        Token = xScanToken(strVar);
      }
    }
    if (Token == xxSlash) Token = xScanToken(strVar);
  }

  if (Code == xfOk) {
    if (Token == xxQuaEnd) Token = xScanToken(strVar);
    if (Token == xxEnv &&
        ((1L<<((long)xProcessEC)) & ECSet) != 0) return (xIdNode)xEnvId;
    if (Token != xxId) {
      if ((((1L<<((long)xOperatorEC)) & ECSet) != 0) &&
          Token == xxPlus) {
        strVar[0] = '+';
        strVar[1] = '\0';
      }
      else {
        xPrintString("No name found\n");
        return (xIdNode)0;
      }
    }
    xfDecodeId(strVar, FromNode, ECSet, &FromNode, &Code, LimId);
    if (Code != xfOk &&
        (((1L<<((long)xOperatorEC)) & ECSet) != 0) &&
        FromNode->EC == xSortEC) {
      /* Operator idnodes are not below the Sort idnode,
         instead they are after on the same level */
      FromNode = FromNode->Suc;
      /* Search until the next Sort */
      while (FromNode && FromNode->EC != xSortEC) {
        if (xfEqualIdString(strVar, FromNode->Name) == 2) {
          Code = xfOk;
          return FromNode;
        }
        FromNode = FromNode->Suc;
      }
    }
  }

  if (Code == xfOk)
    return FromNode;
  if (Code == xfAmbiguous) {
    PRINTF2("Name was ambiguous: %s\n", strVar);
  }
  else if (Code == xfNotFound) {
    PRINTF2("Name was not found: %s\n", strVar);
  }
  return (xIdNode)0;
}


/*---+---------------------------------------------------------------
     PrintEntity
-------------------------------------------------------------------*/
static void PrintEntity(
  xIdNode           R,
  xbool             PrintEntityClass)
{
  if (PrintEntityClass)
    xWriteBuf_Fmt("%s %s ", xEntityString[R->EC], xWriteEntity(R));
  else
    xWriteBuf_Fmt("%s ", xWriteEntity(R));
}

/*---+---------------------------------------------------------------
     xMonListIdNodeECSet
-------------------------------------------------------------------*/
void xMonListIdNodeECSet(
  long              ECSet,
  xIdNode           FromNode,
  xIdNode           LimId,
  xbool             PrintEntityClass)
{
  xIdNode  R;
  xIdNode  ChanId;
  int      i;

  if ( FromNode->EC == xProcessEC &&
       ((1L<<((long)xStateEC)) & ECSet) &&
       ((xPrsIdNode)FromNode)->Super != (xPrsIdNode)0 )
    FromNode = (xIdNode)((xPrsIdNode)FromNode)->Super;

  if ( FromNode->EC == xProcessEC &&
       ((1L<<((long)xTimerEC)) & ECSet) &&
       ((xPrsIdNode)FromNode)->Super != (xPrsIdNode)0 )
    FromNode = (xIdNode)((xPrsIdNode)FromNode)->Super;

#ifndef XNOUSEOFSERVICE
  if ( FromNode->EC == xServiceEC &&
       ((1L<<((long)xStateEC)) & ECSet) &&
       ((xSrvIdNode)FromNode)->Super != (xSrvIdNode)0 )
    FromNode = (xIdNode)((xSrvIdNode)FromNode)->Super;

  if ( FromNode->EC == xServiceEC &&
       ((1L<<((long)xTimerEC)) & ECSet) &&
       ((xSrvIdNode)FromNode)->Super != (xSrvIdNode)0 )
    FromNode = (xIdNode)((xSrvIdNode)FromNode)->Super;
#endif

  for ( R=FromNode->First; R!=(xIdNode)0; R=R->Suc ){
    if (((1L << ((long)R->EC)) & ECSet) != 0) {

      if ( (LimId==(xIdNode)xEnvId) && ((xChannelOrSignalRoute) & ECSet) ) {
        /* list only channels into system from env */
        i = 0;
        for (ChanId = xEnvId->ToId[i++];
             ChanId != (xIdNode)0;
             ChanId = xEnvId->ToId[i++]) {
          if ( ChanId == R || ChanId == R->Suc ) {
            PrintEntity(R, PrintEntityClass);
            break;
          }
        }

      } else if ( (LimId!=(xIdNode)0) && ((xChannelOrSignalRoute) & ECSet) ) {
        /* list only channels into system with this signal (LimId) */
        i = 0;
        for (ChanId = xEnvId->ToId[i++];
             ChanId != (xIdNode)0;
             ChanId = xEnvId->ToId[i++]) {
          if ( ((ChanId==R) || (ChanId==R->Suc)) &&
                xInList((xSignalIdNode)LimId,
                        ((xChannelIdNode)ChanId)->SignalSet) ) {
            PrintEntity(R, PrintEntityClass);
            break;
          }
        }

      } else if ( (LimId==(xIdNode)xEnvId) &&
                  ((1L<<((long)xSignalEC)) & ECSet) ) {
        /* List only signals and rpcs that can be sent into system */
        i = 0;
        for (ChanId = xEnvId->ToId[i++];
             ChanId != (xIdNode)0;
             ChanId = xEnvId->ToId[i++]) {
          if (xInList((xSignalIdNode)R,
                      ((xChannelIdNode)ChanId)->SignalSet)) {
            PrintEntity(R, PrintEntityClass);
            break;
          }
        }

      } else if ( (LimId!=(xIdNode)0) &&
                  ((1L<<((long)xProcessEC)) & ECSet) ) {
        /* List only processes that can receive signal (LimId) */
        if (xInList((xSignalIdNode)LimId,
                    ((xPrsIdNode)R)->SignalSet)) {
          PrintEntity(R, PrintEntityClass);
        }

      } else if (R->EC == xStateEC &&
                 ((xStateIdNode)R)->StateNumber == ASTERISK_STATE) {
        /* Skip asterisk state */

      } else {
#ifdef XVALIDATOR_LIB
        if ((xPrsIdNode)R != xEnvId) {
#endif
          PrintEntity(R, PrintEntityClass);
#ifdef XVALIDATOR_LIB
        }
#endif
      }
    }
    if (R->EC == xChannelEC || R->EC == xSignalrouteEC)  /* Skip reverse */
      R=R->Suc;
  }
  if ( (LimId!=(xIdNode)0) && ((1L<<((long)xStateEC)) & ECSet) )
    return;  /* only states at this level. */

  for ( R=FromNode->First; R!=(xIdNode)0; R=R->Suc ) {
    if (ECSet != xVariableOrFormalPar || R->EC != xSortEC)
      xMonListIdNodeECSet(ECSet, R, LimId, PrintEntityClass);
  }

  if ( FromNode->EC == xProcessTypeEC &&
       (xVariableOrFormalPar & ECSet) &&
       ((xPrsIdNode)FromNode)->Super != (xPrsIdNode)0 )
    xMonListIdNodeECSet(ECSet, (xIdNode)((xPrsIdNode)FromNode)->Super, LimId,
                        PrintEntityClass);

  if ( FromNode->EC == xProcessTypeEC &&
       ((1L<<((long)xTimerEC)) & ECSet) &&
       ((xPrsIdNode)FromNode)->Super != (xPrsIdNode)0 )
    xMonListIdNodeECSet(ECSet, (xIdNode)((xPrsIdNode)FromNode)->Super, LimId,
                        PrintEntityClass);

#ifndef XNOUSEOFSERVICE
  if ( FromNode->EC == xServiceTypeEC &&
       (xVariableOrFormalPar & ECSet) &&
       ((xSrvIdNode)FromNode)->Super != (xSrvIdNode)0 )
    xMonListIdNodeECSet(ECSet, (xIdNode)((xSrvIdNode)FromNode)->Super, LimId,
                        PrintEntityClass);

  if ( FromNode->EC == xServiceTypeEC &&
       ((1L<<((long)xTimerEC)) & ECSet) &&
       ((xSrvIdNode)FromNode)->Super != (xSrvIdNode)0 )
    xMonListIdNodeECSet(ECSet, (xIdNode)((xSrvIdNode)FromNode)->Super, LimId,
                        PrintEntityClass);
#endif
}


/*---+---------------------------------------------------------------
     xfEqualIdString
-------------------------------------------------------------------*/
int xfEqualIdString(
  char *Id,
  char *ToCompareWith)
{
  /* Check if parameters are equal according to abbreviation */
  /* possibilities.                                          */
  /* Returns: 0 = not equal, 1 = equal, 2 = exact match      */

  int   Result, IndexInId, IndexInCompare, IdLength, CompareLength;
  xbool Found;

  IdLength = strlen(Id);
  CompareLength = strlen(ToCompareWith);
  IndexInId = 1;
  IndexInCompare = 1;
  Result = 1;   /* equal */
  while (Result == 1) {
    if (IndexInId > IdLength) {
      break;
    }
    if (Id[IndexInId - 1] == ' ') {
      break;
    }
    if (Id[IndexInId - 1] == '_' || Id[IndexInId - 1] == '-') {
      Found = (xbool)0;
      while (!Found && IndexInCompare <= CompareLength) {
        if (ToCompareWith[IndexInCompare - 1] == '_' ||
            ToCompareWith[IndexInCompare - 1] == '-')
          Found = (xbool)1;
        else
          IndexInCompare++;
      }
      if (!Found)
        Result = 0;
      else {
        IndexInCompare++;
        IndexInId++;
      }
      continue;
    }
    if (IndexInCompare > CompareLength) {
      Result = 0;
      break;
    }
    if (xToLower(ToCompareWith[IndexInCompare - 1]) !=
        xToLower(Id[IndexInId - 1]))
      Result = 0;
    else {
      IndexInCompare++;
      IndexInId++;
    }
  }
  if (Result != 1 || IndexInId != IndexInCompare)
     return Result;
  if (IndexInCompare > CompareLength)
    Result = 2;      /* exact match with exactly xxIdentifierLength chars */
  else if (ToCompareWith[IndexInCompare - 1] == ' ')
      Result = 2;    /* exact match with less chars */
  return Result;
}  /* *** xfEqualIdString *** */


/*---+---------------------------------------------------------------
     xCheckLimId
-------------------------------------------------------------------*/
static xbool xCheckLimId(
  xIdNode     Temp,
  long        ECSet,
  xIdNode     LimId)
{
  xChannelIdNode  ChanId;
  int             i;

  if ( (LimId == (xIdNode)xEnvId) && ((xChannelOrSignalRoute) & ECSet) ) {
    /* Check only channels into system from env */
    i = 0;
    for (ChanId = (xChannelIdNode)xEnvId->ToId[i++];
         ChanId != (xChannelIdNode)0;
         ChanId = (xChannelIdNode)xEnvId->ToId[i++]) {
      if ( (ChanId == (xChannelIdNode)Temp ||
            ChanId == (xChannelIdNode)Temp->Suc) )
        return (xbool)1;
    }
    return (xbool)0;
  }
  if ( (LimId != (xIdNode)0) && ((xChannelOrSignalRoute) & ECSet) ) {
    /* Check only channels into system with this signal (LimId) */
    i = 0;
    for (ChanId = (xChannelIdNode)xEnvId->ToId[i++];
         ChanId != (xChannelIdNode)0;
         ChanId = (xChannelIdNode)xEnvId->ToId[i++]) {
      if ( (ChanId == (xChannelIdNode)Temp ||
            ChanId == (xChannelIdNode)Temp->Suc) &&
            xInList((xSignalIdNode)LimId, ChanId->SignalSet) )
        return (xbool)1;
    }
    return (xbool)0;
  }
  if (LimId == (xIdNode)xEnvId && Temp->EC == xSignalEC) {
    /* Check only signals that can be sent into system */
    i = 0;
    for (ChanId = (xChannelIdNode)xEnvId->ToId[i++];
         ChanId != (xChannelIdNode)0;
         ChanId = (xChannelIdNode)xEnvId->ToId[i++]) {
      if (xInList((xSignalIdNode)Temp, ChanId->SignalSet))
        return (xbool)1;
    }
    return (xbool)0;
  }
  if (LimId != (xIdNode)0 && Temp->EC == xProcessEC) {
    /* Check only processes that can receive signal (LimId) */
    if (xInList((xSignalIdNode)LimId, ((xPrsIdNode)Temp)->SignalSet))
      return (xbool)1;
    else
      return (xbool)0;
  }
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xOneLevelDecodeId
-------------------------------------------------------------------*/
void xOneLevelDecodeId(
  char       *Id,
  xIdNode     Root,
  long        ECSet,
  xIdNode    *ResultId,
  xfCodeType *Code,
  xIdNode     LimId)
{
  xIdNode         Temp;

  *Code = xfNotFound;
  for (Temp = Root->First; Temp != (xIdNode)0; Temp = Temp->Suc) {
    if ( ( ((1L << ((long)Temp->EC)) & ECSet) != 0 ) &&
         ( Temp->EC != xStateEC ||
             ((xStateIdNode)Temp)->StateNumber != ASTERISK_STATE ) &&
         xCheckLimId(Temp, ECSet, LimId)
       ) {
      switch (xfEqualIdString(Id, Temp->Name)) {

      case 2:   /* exact match */
        *ResultId = Temp;
        *Code = xfOk;
        return;

      case 1:   /* equal */
        if (*Code != xfNotFound)
          *Code = xfAmbiguous;
        else {
          *Code = xfOk;
          *ResultId = Temp;
        }
        break;

      case 0:   /* not equal */
        break;

      default:  /* vacuous */
        break;

      }  /* case */
    }
    if (Temp->EC == xChannelEC || Temp->EC == xSignalrouteEC)
      Temp = Temp->Suc;                                     /* Skip reverse */
  }
}  /* *** xOneLevelDecodeId *** */


/*---+---------------------------------------------------------------
     xfDecodeId
-------------------------------------------------------------------*/
void xfDecodeId(
  char       *Id,
  xIdNode     Root,
  long        ECSet,
  xIdNode    *ResultId,
  xfCodeType *Code,
  xIdNode     LimId)
{
  xIdNode    Temp;
  xIdNode    TempResultId;
  xfCodeType TempCode;

  if ( Root->EC == xProcessEC &&
       ((1L<<((long)xStateEC)) & ECSet) &&
       ((xPrsIdNode)Root)->Super != (xPrsIdNode)0 )
    Root = (xIdNode)((xPrsIdNode)Root)->Super;
  if ( Root->EC == xProcessEC &&
       ((1L<<((long)xTimerEC)) & ECSet) &&
       ((xPrsIdNode)Root)->Super != (xPrsIdNode)0 )
    Root = (xIdNode)((xPrsIdNode)Root)->Super;
#ifndef XNOUSEOFSERVICE
  if ( Root->EC == xServiceEC &&
       ((1L<<((long)xStateEC)) & ECSet) &&
       ((xSrvIdNode)Root)->Super != (xSrvIdNode)0 )
    Root = (xIdNode)((xSrvIdNode)Root)->Super;
  if ( Root->EC == xServiceEC &&
       ((1L<<((long)xTimerEC)) & ECSet) &&
       ((xSrvIdNode)Root)->Super != (xSrvIdNode)0 )
    Root = (xIdNode)((xSrvIdNode)Root)->Super;
#endif
  xOneLevelDecodeId(Id, Root, ECSet, ResultId, Code, LimId);
  if (*Code == xfAmbiguous && xfEqualIdString(Id, (*ResultId)->Name) == 2)
    return;

  if ( (LimId!=(xIdNode)0) && ((1L<<((long)xStateEC)) & ECSet) )
    return;  /* only states at this level. */

  Temp = Root->First;
  while (Temp != (xIdNode)0 &&
         (*Code != xfAmbiguous ||
          xfEqualIdString(Id, (*ResultId)->Name) != 2)) {
          /* Continue search for exact match */
    xfDecodeId(Id, Temp, ECSet, &TempResultId, &TempCode, LimId);
    if (TempCode == xfAmbiguous) {
      if (*Code == xfNotFound ||
          xfEqualIdString(Id, (*ResultId)->Name) != 2) { /* Not Exact match */
        if (*Code == xfNotFound)
          *ResultId = TempResultId;
        *Code = xfAmbiguous;
      }
    }
    else if (TempCode == xfOk) {
      if (*Code == xfNotFound) {
        *ResultId = TempResultId;
        *Code = xfOk;
      }
      else {
        if (xfEqualIdString(Id, (*ResultId)->Name) == 2) { /* Exact match */
          if (xfEqualIdString(Id, TempResultId->Name) == 2 &&
              ((TempResultId->EC != xSignalEC &&
                TempResultId->EC != xTimerEC) ||
               *ResultId != TempResultId))
            /* If a signal or timer is declared in a process type the same
               entry in the symboltable can be found multiple times.
               But it should not be considered ambiguous. */
            *Code = xfAmbiguous;
          else
            *Code = xfOk;
        }
        else {
          if (xfEqualIdString(Id, TempResultId->Name) == 2) {
            *ResultId = TempResultId;
            *Code = xfOk;
          }
          else {
            *Code = xfAmbiguous;
          }
        }
      }
    }
    Temp = Temp->Suc;
  }  /* while */
  if ( Root->EC == xProcessTypeEC &&
       ((1L<<((long)xTimerEC)) & ECSet) &&
       ((xPrsIdNode)Root)->Super != (xPrsIdNode)0 )
    xfDecodeId(Id, (xIdNode)((xPrsIdNode)Root)->Super, ECSet, ResultId,
               Code, LimId);
#ifndef XNOUSEOFSERVICE
  if ( Root->EC == xServiceTypeEC &&
       ((1L<<((long)xTimerEC)) & ECSet) &&
       ((xSrvIdNode)Root)->Super != (xSrvIdNode)0 )
    xfDecodeId(Id, (xIdNode)((xSrvIdNode)Root)->Super, ECSet, ResultId,
               Code, LimId);
#endif
}  /* *** xfDecodeId *** */


/*---+---------------------------------------------------------------
     xReadProcess
-------------------------------------------------------------------*/
xPrsNode xReadProcess(
  char       * Prompt,
  xPrsIdNode * xIdNodeProcess,
  xIdNode      LimId)
{
  xPrsNode PrsNode;
  xbool    EmptyInput;
#ifdef XNRINST
  xxToken  Token;
  char     strVar[256];
  int      intVar;
  xbool    ShouldReadInstNo, HasReadColon;
  xPrsNode tmpPrsNode;
#ifdef XVALIDATOR_LIB
  int      InstNr;
#endif
#endif

#ifdef XVALIDATOR_LIB
  *xIdNodeProcess = (xPrsIdNode)xGetIdNodeInECSet(Prompt,
                                                  1L<<((long)xProcessEC),
                                                  (xIdNode)xSymbolTableRoot,
                                                  &EmptyInput,
                                                  (xbool)1,
                                                  LimId);
  if (*xIdNodeProcess == xNullId) return (xPrsNode)0;

  if (EmptyInput) {
    if (xNoOfInst(NULL) != 1) {
      xPrintString( "More than one active process\n" );
      return NULL;
    } else {
      PrsNode = GetPrs(1);
    }
  } else {
    PrsNode = xFirstActivePrs(*xIdNodeProcess);
  }
#else
  *xIdNodeProcess = (xPrsIdNode)xGetIdNodeInECSet(Prompt,
                                                  1L<<((long)xProcessEC),
                                                  (xIdNode)xSymbolTableRoot,
                                                  &EmptyInput,
                                                  (xbool)0,
                                                  LimId);
  if (*xIdNodeProcess == 0) return (xPrsNode)0;
  if (*xIdNodeProcess == xNullId) return (xPrsNode)0;

  PrsNode = *(*xIdNodeProcess)->ActivePrsList;
#endif
  if (PrsNode == (xPrsNode)0) {
    xPrintString("No active instance\n");
    return (xPrsNode)0;
  }

#ifdef XNRINST
  intVar = -1;
  ShouldReadInstNo = (xbool)0;
  HasReadColon = (xbool)0;
#ifdef XVALIDATOR_LIB
  if (xNoOfInst(*xIdNodeProcess) > 1)
#else
  if (PrsNode->NextPrs != (xPrsNode)0)
#endif
    ShouldReadInstNo = (xbool)1;
  Token = xScanToken(strVar);
  if (Token == xxColon) {
    ShouldReadInstNo = (xbool)1;
    HasReadColon = (xbool)1;
  } else {
    xUngetToken(Token, strVar);
  }

  if (ShouldReadInstNo) {
    Token = xScanToken(strVar);
    if (Token == xxEoln) {
      if (HasReadColon)
        xPrintString("Instance number : ");
      else
        xPrintString("More than one active instance\nInstance number : ");
      Token = xScanToken(strVar);
    }
    while (Token == xxQuestionMark) {
#ifdef XVALIDATOR_LIB
      InstNr=0;
      for (tmpPrsNode = PrsNode;
           tmpPrsNode != (xPrsNode)0;
           tmpPrsNode = xNextActivePrs(tmpPrsNode)) {
        InstNr++;
	PRINTF2("%d ",InstNr);
      }
#else
      for (tmpPrsNode = PrsNode;
           tmpPrsNode != (xPrsNode)0;
           tmpPrsNode = tmpPrsNode->NextPrs) {
        PRINTF2("%d ", XPRS_INSTNR(tmpPrsNode));
      }
#endif
      xPrintString(": ");
      xSkipLine();
      Token = xScanToken(strVar);
    }
    if (sscanf(strVar, "%d", &intVar) == 1) {
#ifdef XVALIDATOR_LIB
      InstNr = 1;
      while (InstNr != intVar) {
        InstNr++;
        PrsNode = xNextActivePrs(PrsNode);
        if (PrsNode == (xPrsNode)NIL) {
          PrintString("Instance with specified number is not active\n");
          return (xPrsNode)NIL;
        }
      }
      return PrsNode;
#else
      for (PrsNode = *(*xIdNodeProcess)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        if (XPRS_INSTNR(PrsNode) == intVar) {
          if (xSysD.xRestoringState) {
            /* Allow and skip "+" i.e. dead instance when Restore-State */
            Token = xScanToken(strVar);
            if (Token != xxPlus)
              xUngetToken(Token, strVar);
          }
          return PrsNode;
        }
      }
      xPrintString("Instance with specified number is not active\n");
      return (xPrsNode)0;
#endif
    } else {
      xPrintString("Illegal instance number\n");
      return (xPrsNode)0;
    }
  }
#endif
  return PrsNode;
}


#ifndef XNOUSEOFSERVICE
/*---+---------------------------------------------------------------
     xReadService
-------------------------------------------------------------------*/
xSrvNode xReadService(
  char       * Prompt,
  xSrvIdNode * xIdNodeService,
  xPrsNode     Prs,
  xbool      * EmptyInput)
{
  xSrvNode Srv;

  *xIdNodeService = (xSrvIdNode)xGetIdNodeInECSet(Prompt, 1L<<((long)xServiceEC),
    (xIdNode)Prs->NameNode, EmptyInput, (xbool)1, (xIdNode)0);
  if (*xIdNodeService == 0)
    return (xSrvNode)0; /* No such name OR EmptyInput */
  for (Srv=Prs->SrvList; Srv!=(xSrvNode)0; Srv=Srv->NextSrv)
    if (Srv->NameNode == *xIdNodeService)
      return Srv;
  return (xSrvNode)0;  /* Service is stopped */
}
#endif


/*---+---------------------------------------------------------------
     lenNL, addNL, indexNL, releaseNL
-------------------------------------------------------------------*/

#ifndef XVALIDATOR_LIB
int lenNL(void ** list)
{
  void ** l;

  if (list==(void **)NIL)
    return 0;
  else {
    for (l=list; *l!=(void *)NIL; l++)
      ;
    return l-list;
  }
}

void addNL(
  void ***list,
  void *  elem)
{
  int len;
  void ** temp;

  if (*list==(void **)NIL) {
    *list = (void **)XALLOC((xptrint)(2*(int)sizeof(void *)), 0);
    (*list)[0] = elem;
    (*list)[1] = (void *)NIL;
    return;
  }
  else {
    len = lenNL(*list);
    temp = (void **)XALLOC((xptrint)((len+2)*(int)sizeof(void *)), 0);
    memcpy((void *)temp, (void *)*list, len*(int)sizeof(void *));
    XFREE((void **)list, (xptrint)((len+1)*sizeof(xptrint)));
    *list = temp;
    (*list)[len] = elem;
    (*list)[len+1] = (void *)NIL;
    return;
  }
}

int indexNL(
  void **  list,
  void *   elem)
{
  int len,i;

  len=lenNL(list);
  for (i=0; i<len; i++)
    if (list[i]==elem)
      return i;
  return -1;
}

void releaseNL(
  void *** list)
{
  XFREE( (void **)list, (size_t)(lenNL( *list )+1)*sizeof(void *));
}
#endif


/*---+---------------------------------------------------------------
     xWriteOpParameter
-------------------------------------------------------------------*/
void xWriteOpParameter(
  char * Str,
  void *In_Addr,
  tSDLTypeInfo *SortNode)
{
  WriteBuf *Buf;
  Buf = WriteBuf_New(60);
  WriteBuf_Add_String(Buf, Str, 0);
  xGenericWriteSort(Buf, In_Addr, SortNode);
  WriteBuf_Add_String(Buf, "\n", 0);
  WriteBuf_Terminate(Buf);
  xPrintString(WriteBuf_Data(Buf));
  WriteBuf_Del(&Buf);
}


/*---+---------------------------------------------------------------
     xReadOperator
-------------------------------------------------------------------*/
xbool xReadOperator(
  void         *Result_Addr,
  tSDLTypeInfo *TypeNode)
{
  int     I = 0;
  xxToken Token;
  char    strVar[MAX_READ_LENGTH];
#if defined(XMONITOR) && defined(XCLOCK) && ! defined(XVALIDATOR_LIB)
  SDL_Time xTimeEnteringReadOperator;

  xTimeEnteringReadOperator = SDL_Clock();
#endif

  while (I <= 0) {
#ifdef XSIMULATORUI
#ifdef XVALIDATOR_LIB
    if (CommandFile->File != NULL) {
#else
    if (XSYSD CommandFile) {
#endif
                 /* Prevent UI from trigger on ": " */
      PRINTF2("Enter value (%s) :", TypeNode->Name);
      xPrintString(" ");
    }
    else
#endif
    PRINTF2("Enter value (%s) : ", TypeNode->Name);
    Token = xScanToken(strVar);
    if (Token == xxEoln) {
#if defined(XMONITOR) && defined(XCLOCK) && ! defined(XVALIDATOR_LIB)
      XSYSD xTimeInMonitor = xPlus_SDL_Duration(XSYSD xTimeInMonitor,
                  xMinusD_SDL_Time(SDL_Clock(), xTimeEnteringReadOperator));
#endif
      return (xbool)0;
    }
    xUngetToken(Token, strVar);
    I = xGenericReadSort(Result_Addr, TypeNode);
    if (I<=0 && XSYSD xInputLine[0] == '[') {   /* Cancel */
      xSkipLine();
#if defined(XMONITOR) && defined(XCLOCK) && ! defined(XVALIDATOR_LIB)
      XSYSD xTimeInMonitor = xPlus_SDL_Duration(XSYSD xTimeInMonitor,
                  xMinusD_SDL_Time(SDL_Clock(), xTimeEnteringReadOperator));
#endif
      return (xbool)0;
    }
    xSkipLine();
    if (I<=0) xPrintString("Error in value\n");
  }
#if defined(XMONITOR) && defined(XCLOCK) && ! defined(XVALIDATOR_LIB)
  XSYSD xTimeInMonitor = xPlus_SDL_Duration(XSYSD xTimeInMonitor,
                  xMinusD_SDL_Time(SDL_Clock(), xTimeEnteringReadOperator));
#endif
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xPrdInstance
-------------------------------------------------------------------*/
char * xPrdInstance(
  xPrdNode ThisPrdNode)
{
  int count = 1;
  xPrdNode PrdNode;
  static WriteBuf *PrdInstanceBuf = 0;

  if (!PrdInstanceBuf)
    PrdInstanceBuf = WriteBuf_New(60);
  else
    WriteBuf_Clear(PrdInstanceBuf);

  for (PrdNode = ThisPrdNode->DynamicFather;
       PrdNode != (xPrdNode)0;
       PrdNode = PrdNode->DynamicFather)
    if (PrdNode->NameNode == ThisPrdNode->NameNode)
      count++;
  WriteBuf_Add_String(PrdInstanceBuf,
                      xWriteEntity((xIdNode)ThisPrdNode->NameNode), 0);
  xAddBuf_Fmt(PrdInstanceBuf, ":%d", count);
  WriteBuf_Terminate(PrdInstanceBuf);
  return WriteBuf_Data(PrdInstanceBuf);
}


/*---+---------------------------------------------------------------
     xWriteEntity
-------------------------------------------------------------------*/
char * xWriteEntity(
  xIdNode Unit)
{
  static WriteBuf *WriteEntityBuf = 0;
  if (!WriteEntityBuf)
    WriteEntityBuf = WriteBuf_New(60);
  else
    WriteBuf_Clear(WriteEntityBuf);

  if ( Unit->EC != xStateEC &&
       Unit->EC != xTimerEC &&
       Unit->EC != xVariableEC &&
       Unit->EC != xFormalParEC &&
       Unit->EC != xLiteralEC &&
       xNeedsQualifier(Unit) ) {
    xGetQualifier(WriteEntityBuf, Unit, 0);
    WriteBuf_Add_Char(WriteEntityBuf, ' ');
  }
  WriteBuf_Add_String(WriteEntityBuf, Unit->Name, 0);
  WriteBuf_Terminate(WriteEntityBuf);
  return WriteBuf_Data(WriteEntityBuf);
}

/*---+---------------------------------------------------------------
     GetQualifier
-------------------------------------------------------------------*/
static void GetQualifier(
  WriteBuf *Buf,
  xIdNode   Unit,
  int       IsLast,
  int       BlockInstNumber )
{
  if (Unit->Parent != xSymbolTableRoot) {
    if (Unit->EC == xBlockEC)
      GetQualifier(Buf, Unit->Parent, 0,
                   BlockInstNumber/((xBlockIdNode)Unit)->NumberOfInst);
    else
      GetQualifier(Buf, Unit->Parent, 0, BlockInstNumber);
  }

  if ( Unit->EC == xPackageEC    || Unit->EC == xProcedureEC   ||
       Unit->EC == xProcessEC    || Unit->EC == xProcessTypeEC ||
       Unit->EC == xServiceEC    || Unit->EC == xServiceTypeEC ||
       Unit->EC == xSortEC       || Unit->EC == xSyntypeEC     ||
       Unit->EC == xSystemTypeEC || Unit->EC == xBlockEC       ||
       Unit->EC == xBlockTypeEC  || Unit->EC == xOperatorEC    ||
       ( Unit->EC == xSystemEC && IsLast )  ) {
    xAddBuf_Fmt(Buf, "%s %s", xEntityString[Unit->EC], Unit->Name);
    if (Unit->EC == xBlockEC && ((xBlockIdNode)Unit)->NumberOfInst > 1 ) {
      xAddBuf_Fmt(Buf, ":%d", 
		  1 + BlockInstNumber%((xBlockIdNode)Unit)->NumberOfInst);
    }
    if (!IsLast)
      WriteBuf_Add_Char(Buf, '/');
  }
}


/*---+---------------------------------------------------------------
     xGetQualifier
-------------------------------------------------------------------*/
void xGetQualifier(
  WriteBuf *Buf,
  xIdNode   Unit,
  int       BlockInstNumber)
{
  xIdNode   QuaNode;
  xIdNode   Sort;

  QuaNode = Unit->Parent;
  if (QuaNode != xSymbolTableRoot) {
    WriteBuf_Add_String(Buf, "<<", 0);
    if (Unit->EC == xOperatorEC) {
      /* Operator idnodes are not below the Sort idnode,
         instead they are after on the same level */
      for (Sort = QuaNode->First;
           Sort && (Sort != Unit);
           Sort = Sort->Suc) {
        /* Find the last Sort before the Operator */
        if (Sort->EC == xSortEC)
          QuaNode = Sort;
      }
    }
    GetQualifier(Buf, QuaNode, 1, BlockInstNumber);
    WriteBuf_Add_String(Buf, ">>", 0);
  }
  WriteBuf_Terminate(Buf);
}


/*---+---------------------------------------------------------------
     NeedsQualifier
-------------------------------------------------------------------*/
static xbool NeedsQualifier(
  xIdNode  Unit,
  xIdNode  Root)
{
  xIdNode  Temp;

  if ( Unit != Root &&
       Unit->EC == Root->EC &&
       ( Unit != Root->Suc || 
         ( Unit->EC!=xChannelEC && Unit->EC!=xSignalrouteEC && 
           Unit->EC!=xGateEC ) ) &&
       strcmp(Unit->Name, Root->Name) == 0 ) {
    return (xbool)1;
  }
  for (Temp=Root->First; Temp != (xIdNode)0; Temp = Temp->Suc) {
    if (NeedsQualifier(Unit, Temp)) return (xbool)1;
    if (Temp->EC==xChannelEC || Temp->EC==xSignalrouteEC || Temp->EC==xGateEC)
      Temp = Temp->Suc;
  }
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xNeedsQualifier
-------------------------------------------------------------------*/
xbool xNeedsQualifier(
  xIdNode  Unit)
{
#ifdef XVALIDATOR_LIB
  /* Check if this has been computed before */
  if (Unit->NeedsQualStatus > 0) {
    return (xbool)1;
  } else if (Unit->NeedsQualStatus < 0) {
    return (xbool)0;
  }
#endif

  if ( Unit->EC == xProcessEC &&
       ((xPrsIdNode)Unit)->InBlockInst != (xBlockIdNode)0 )
    return (xbool)1;

  if (NeedsQualifier(Unit, xSymbolTableRoot)) {
#ifdef XVALIDATOR_LIB
    Unit->NeedsQualStatus = 1;
#endif
    return (xbool)1;
  }
  else {
#ifdef XVALIDATOR_LIB
    Unit->NeedsQualStatus = -1;
#endif
    return (xbool)0;
  }
}


#endif
/********************** END XREADANDWRITEF *************************/



/*************************** XMONITOR ******************************/
#ifdef XMONITOR


/* KEEP xSymbolTypeStr UPDATED WITH xSymbolType */
char * xSymbolTypeStr [] = {
   "START", "INPUT", "PRIORITYINPUT", "CONTINUOUSSIGNAL",
   "TASK", "TASK", "TASK", "OUTPUT",
   "CREATE", "DECISION", "DECISION", "DECISION",
   "TRANSITIONOPTION", "SET", "RESET", "EXPORT",
   "PROCEDURECALL", "PROCEDURECALL", "RPC", "RPC",
   "IF", "LOOP", "LOOPTEST", "LOOPUPDATE", "BREAK", "CONTINUE",
   "NEXTSTATE", "JOIN", "STOP", "RETURN",
   "pCALL INPUT", "pCALL CALL", "pREPLY OUTPUT", "pCALL NEXTSTATE", 
   "pREPLY INPUT", "LABEL"
};



/*---+---------------------------------------------------------------
     xGetDirectoryName
-------------------------------------------------------------------*/
xbool xGetDirectoryName(
  char  *Prompt,
  char  *dirName,
  xbool *minusGiven)
{
  xxToken Token;

  Token = xPromptQuestionMark("Directory name : ", Prompt, dirName);
  if (Token == xxLBracket)
    return (xbool)0;

  if (Token == xxMinus) {
    *minusGiven = (xbool)1;
    return (xbool)1;
  }

  *minusGiven = (xbool)0;
  if (Token == xxASN1String || Token == xxString) {
    /* Directoryname contains blanks, unquote string */
    char *pstr = dirName;

    while (*pstr != '\0') {
      *pstr = *(pstr+1);
      pstr++;
    }
    *(pstr-2) = '\0';
    return (xbool)1;
  }

  xUngetToken(Token, dirName);
  sscanf(xInputPos, "%s", dirName);
  xInputPos += strlen(dirName);
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xGetFileName
-------------------------------------------------------------------*/
xbool xGetFileName(
  char *  Prompt,
  char *  strVar)
{
  xxToken Token;

  Token = xPromptQuestionMark("File name : ", Prompt, strVar);
  if (Token == xxLBracket)
    return (xbool)0;
  if (Token == xxASN1String || Token == xxString) {
    /* Filename contains blanks, unquote string */
    char *pstr = strVar;

    while (*pstr != '\0') {
      *pstr = *(pstr+1);
      pstr++;
    }
    *(pstr-2) = '\0';
    return (xbool)1;
  }
  xUngetToken(Token, strVar);
  sscanf(xInputPos, "%s", strVar);
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xGetAndOpenFile
-------------------------------------------------------------------*/
xbool xGetAndOpenFile(
  FILE ** F,
  xbool   IsRead,
  char *  strVar,
  char *  filter)
{
  char buf[100];

  if (IsRead) {
    sprintf(buf," Name of existing file (*.%s) : ", filter );
    if (!xGetFileName(buf,strVar)) {
      return 0;
    }
  } else {
    sprintf(buf," Legal filename (*.%s) : ", filter );
    if (!xGetFileName(buf,strVar)) {
      return 0;
    }
  }
  if (!IsRead && strcmp(strVar, "stdout") == 0) {
    *F = stdout;
    return (xbool)1;
  }
  if (IsRead) {
    if ((*F = fopen(strVar, "r")) == NULL) {
      PRINTF2("File %s not found\n", strVar);
      return (xbool)0;
    }
  } else {
    if ((*F = fopen(strVar, "w")) == NULL) {
      PRINTF2("File %s could not be created\n", strVar);
      return (xbool)0;
    }
  }
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xReadInstanceNumber
-------------------------------------------------------------------*/
xbool xReadInstanceNumber(
  char  * Prompt,
  int   * intVar,
  xbool * EmptyInput)
{
  char    strVar[256];
  xxToken Token;

  Token = xScanToken(strVar);
  if (Token == xxEoln) {
    xPrintString(Prompt);
    Token = xScanToken(strVar);
  }
  if (Token == xxEoln) {
    *EmptyInput = (xbool)1;
    xUngetToken(Token, strVar);
    return (xbool)1;
  }
  *EmptyInput = (xbool)0;
  while (Token == xxQuestionMark) {
    xPrintString("integer > 0 : ");
    xSkipLine();
    Token = xScanToken(strVar);
    if (Token == xxEoln) {
      *EmptyInput = (xbool)1;
      xUngetToken(Token, strVar);
      return (xbool)1;
    }
  }
  if (Token == xxMinus) {
    *EmptyInput = (xbool)1;
    return (xbool)1;
  }
  if (Token == xxId) {
    if ( sscanf(strVar, "%d", intVar) ) {
      if (*intVar < 1) {
        xPrintString("Entry number may not be less than 1\n");
        return (xbool)0;
      }
      return (xbool)1;
    }
  }
  xPrintString("Illegal input for instance number\n");
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xReadEntryNumber
-------------------------------------------------------------------*/
xbool xReadEntryNumber(
  char * Prompt,
  int  * intVar,
  int    MaxValue)
{
  xxToken Token;
  char    strVar[256];
  char    QPrompt[256];

  Token = xScanToken(strVar);
  if (MaxValue == 1 && Token == xxEoln) {
    *intVar = 1;
    xUngetToken(Token, strVar);
    return (xbool)1;
  }
  xUngetToken(Token, strVar);

  sprintf(QPrompt, "integer in range 1 to %d : ", MaxValue);
  Token = xPromptQuestionMark(Prompt, QPrompt, strVar);
  if (Token == xxId) {
    if ( sscanf(strVar, "%d", intVar) ) {
      if (*intVar < 1) {
        xPrintString("Entry number may not be less than 1\n");
        return (xbool)0;
      }
      if (*intVar > MaxValue) {
        xPrintString("Entry number too large\n");
        return (xbool)0;
      }
      return (xbool)1;
    }
  }
  xPrintString("Illegal input for entry number\n");
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xMonListVariables
-------------------------------------------------------------------*/
static void xMonListVariables(
  xIdNode    FromNode,
  char      *NameP)
{
  xIdNode  R;

  for ( R=FromNode->First; R!=(xIdNode)0; R=R->Suc ){
    if (((1L << ((long)R->EC)) & xVariableOrFormalPar) != 0) {
      if (NameP == (char *)0 || xfEqualIdString(NameP, R->Name) == 1) {
        /* PRINTF2("%s ", xWriteEntity(R)) */
        PRINTF2("%s ", R->Name)
      }
    }
  }
  if ( (FromNode->EC == xProcessTypeEC || FromNode->EC == xProcessEC) &&
       ((xPrsIdNode)FromNode)->Super != (xPrsIdNode)0 )
    xMonListVariables((xIdNode)((xPrsIdNode)FromNode)->Super, NameP);
#ifndef XNOUSEOFSERVICE
  if ( (FromNode->EC == xServiceTypeEC || FromNode->EC == xServiceEC) &&
       ((xSrvIdNode)FromNode)->Super != (xSrvIdNode)0 )
    xMonListVariables((xIdNode)((xSrvIdNode)FromNode)->Super, NameP);
#endif
  if ( (FromNode->EC == xProcedureEC || FromNode->EC == xOperatorEC) &&
       ((xPrdIdNode)FromNode)->Super != (xPrdIdNode)0 )
    xMonListVariables((xIdNode)((xPrdIdNode)FromNode)->Super, NameP);
}


/*---+---------------------------------------------------------------
     xReadVariable
-------------------------------------------------------------------*/
xxToken xReadVariable(
  char     * Prompt,
  char     * strVar,
  xbool    * EmptyInput,
  xbool      OKEmptyInput)
{
  xxToken    Token;

  *EmptyInput = (xbool)0;
  Token = xScanToken(strVar);
  if (Token == xxEoln) {
    xPrintString(Prompt);
    Token = xScanToken(strVar);
  }

  if (Token == xxEoln && OKEmptyInput) {
    *EmptyInput = (xbool)1;
    xUngetToken(Token, strVar);
    return Token;
  }
  if (Token == xxMinus) {
    if ( OKEmptyInput )
      *EmptyInput = (xbool)1;
    else
      xPrintString("Default name not allowed\n");
    return Token;
  }

  while ( Token == xxQuestionMark ||
          (Token == xxEoln && ! OKEmptyInput)
        ) {
    if (XSYSD xPrdScope != (xPrdNode)0)
      xMonListVariables((xIdNode)XSYSD xPrdScope->NameNode, (char *)0);
#ifndef XNOUSEOFSERVICE
    else if (XSYSD xSrvScope != (xSrvNode)0)
      xMonListVariables((xIdNode)XSYSD xSrvScope->NameNode, (char *)0);
#endif
    else
      xMonListVariables((xIdNode)XSYSD xPrsScope->NameNode, (char *)0);
    xPrintString(": ");
    if (Token != xxEoln) xSkipLine();
    Token = xScanToken(strVar);
    if (Token == xxEoln && OKEmptyInput) {
      *EmptyInput = (xbool)1;
      xUngetToken(Token, strVar);
      return Token;
    }
    if (Token == xxMinus) {
      if ( OKEmptyInput )
        *EmptyInput = (xbool)1;
      else
        xPrintString("Default name not allowed\n");
      return Token;
    }
  }
  return Token;
}


/*---+---------------------------------------------------------------
     xSearchVariable
-------------------------------------------------------------------*/
xVarIdNode xSearchVariable(
  char       *NameP,
  xIdNode     FromNode,
  xfCodeType *Code)
{
  xIdNode     xIdNodeVar;
  xIdNode     TempResultId;
  xfCodeType  TempCode;

  xOneLevelDecodeId(NameP, FromNode, xVariableOrFormalPar,
                    &xIdNodeVar, Code, (xIdNode)0);
  if (FromNode->EC == xProcessTypeEC || FromNode->EC == xProcessEC) {
    for (FromNode = (xIdNode)((xPrsIdNode)FromNode)->Super;
         FromNode != (xIdNode)0 && *Code != xfAmbiguous;
         FromNode = (xIdNode)((xPrsIdNode)FromNode)->Super) {
      xOneLevelDecodeId(NameP, FromNode, xVariableOrFormalPar,
                        &TempResultId, &TempCode, (xIdNode)0);
      if (TempCode == xfAmbiguous) {
        if (*Code == xfNotFound ||
            /* Not Exact match */
            xfEqualIdString(NameP, xIdNodeVar->Name) != 2) {
          *Code = xfAmbiguous;
        }
      }
      else if (TempCode == xfOk) {
        if (*Code == xfNotFound) {
          xIdNodeVar = TempResultId;
          *Code = xfOk;
        }
        else {
          if (xfEqualIdString(NameP, xIdNodeVar->Name) == 2) {
            /* Exact match */
            if (xfEqualIdString(NameP, TempResultId->Name) == 2)
              *Code = xfAmbiguous;
            else
              *Code = xfOk;
          }
          else {
            if (xfEqualIdString(NameP, TempResultId->Name) == 2) {
              xIdNodeVar = TempResultId;
              *Code = xfOk;
            }
            else {
              *Code = xfAmbiguous;
            }
          }
        }
      }
    }
  }
#ifndef XNOUSEOFSERVICE
  else if (FromNode->EC == xServiceTypeEC || FromNode->EC == xServiceEC) {
    for (FromNode = (xIdNode)((xSrvIdNode)FromNode)->Super;
         FromNode != (xIdNode)0 && *Code != xfAmbiguous;
         FromNode = (xIdNode)((xSrvIdNode)FromNode)->Super) {
      xOneLevelDecodeId(NameP, FromNode, xVariableOrFormalPar,
                        &TempResultId, &TempCode, (xIdNode)0);
      if (TempCode == xfAmbiguous) {
        if (*Code == xfNotFound ||
            /* Not Exact match */
            xfEqualIdString(NameP, xIdNodeVar->Name) != 2) {
          *Code = xfAmbiguous;
        }
      }
      else if (TempCode == xfOk) {
        if (*Code == xfNotFound) {
          xIdNodeVar = TempResultId;
          *Code = xfOk;
        }
        else {
          if (xfEqualIdString(NameP, xIdNodeVar->Name) == 2) {
            /* Exact match */
            if (xfEqualIdString(NameP, TempResultId->Name) == 2)
              *Code = xfAmbiguous;
            else
              *Code = xfOk;
          }
          else {
            if (xfEqualIdString(NameP, TempResultId->Name) == 2) {
              xIdNodeVar = TempResultId;
              *Code = xfOk;
            }
            else {
              *Code = xfAmbiguous;
            }
          }
        }
      }
    }
  }
#endif
  else if (FromNode->EC == xProcedureEC) {
    for (FromNode = (xIdNode)((xPrdIdNode)FromNode)->Super;
         FromNode != (xIdNode)0 && *Code != xfAmbiguous;
         FromNode = (xIdNode)((xPrdIdNode)FromNode)->Super) {
      xOneLevelDecodeId(NameP, FromNode, xVariableOrFormalPar,
                        &TempResultId, &TempCode, (xIdNode)0);
      if (TempCode == xfAmbiguous) {
        if (*Code == xfNotFound ||
            /* Not Exact match */
            xfEqualIdString(NameP, xIdNodeVar->Name) != 2) {
          *Code = xfAmbiguous;
        }
      }
      else if (TempCode == xfOk) {
        if (*Code == xfNotFound) {
          xIdNodeVar = TempResultId;
          *Code = xfOk;
        }
        else {
          if (xfEqualIdString(NameP, xIdNodeVar->Name) == 2) {
            /* Exact match */
            if (xfEqualIdString(NameP, TempResultId->Name) == 2)
              *Code = xfAmbiguous;
            else
              *Code = xfOk;
          }
          else {
            if (xfEqualIdString(NameP, TempResultId->Name) == 2) {
              xIdNodeVar = TempResultId;
              *Code = xfOk;
            }
            else {
              *Code = xfAmbiguous;
            }
          }
        }
      }
    }
  }
  if (*Code == xfOk)
    return (xVarIdNode)xIdNodeVar;
  return (xVarIdNode)0;
}


/*---+---------------------------------------------------------------
     xVariableInProcess
-------------------------------------------------------------------*/
xbool xVariableInProcess(
  char        *strVar,
  xVarIdNode  *xIdNodeVariable,
  xptrint     *VarPointer)
{
  xfCodeType              Code;

  if (XSYSD xPrdScope != (xPrdNode)0)
    *xIdNodeVariable =
      xSearchVariable(strVar, (xIdNode)XSYSD xPrdScope->NameNode, &Code);
#ifndef XNOUSEOFSERVICE
  else if (XSYSD xSrvScope != (xSrvNode)0)
    *xIdNodeVariable =
      xSearchVariable(strVar, (xIdNode)XSYSD xSrvScope->NameNode, &Code);
#endif
  else
    *xIdNodeVariable =
      xSearchVariable(strVar, (xIdNode)XSYSD xPrsScope->NameNode, &Code);

  if (*xIdNodeVariable == (xVarIdNode)0) {
    if (Code == xfAmbiguous) {
      PRINTF2("Name was ambiguous: %s, it might be an abbreviation of :\n", strVar);
      if (XSYSD xPrdScope != (xPrdNode)0)
        xMonListVariables((xIdNode)XSYSD xPrdScope->NameNode, strVar);
#ifndef XNOUSEOFSERVICE
      else if (XSYSD xSrvScope != (xSrvNode)0)
        xMonListVariables((xIdNode)XSYSD xSrvScope->NameNode, strVar);
#endif
      else
        xMonListVariables((xIdNode)XSYSD xPrsScope->NameNode, strVar);
      xPrintString("\n");
    }
    else if (Code == xfNotFound) {
      PRINTF2("Name was not found: %s\n", strVar);
    }
    return (xbool)0;
  }


  if (XSYSD xPrdScope != (xPrdNode)0) {
    if ((*xIdNodeVariable)->EC == xFormalParEC && XIS_ADDRESS(*xIdNodeVariable))
      *VarPointer = (xptrint)
        (*(void **)((xptrint)(XSYSD xPrdScope) + (*xIdNodeVariable)->Offset));
    else
      *VarPointer = (xptrint)(XSYSD xPrdScope) + (*xIdNodeVariable)->Offset;
  }
#ifndef XNOUSEOFSERVICE
  else if (XSYSD xSrvScope != (xSrvNode)0)
    *VarPointer = (xptrint)XSYSD xSrvScope + (*xIdNodeVariable)->Offset;
#endif
  else
    *VarPointer = (xptrint)XSYSD xPrsScope + (*xIdNodeVariable)->Offset;
  return (xbool)1;
}


/*---+---------------------------------------------------------------
     xPrintPrdVariable
-------------------------------------------------------------------*/
void xPrintPrdVariable(
  xVarIdNode IdNode,
  xPrdNode   PrdNode)
{
  PRINTF3("%s (%s)", IdNode->Name,
          xWriteEntity((xIdNode)IdNode->TypeNode->SortIdNode));
  xPrintString(" = ");
  if (IdNode->EC == xFormalParEC && XIS_ADDRESS(IdNode))
    xxWriteSort(*(void **)((xptrint)PrdNode + IdNode->Offset), IdNode->TypeNode);
  else
    xxWriteSort((void *)((xptrint)PrdNode + IdNode->Offset), IdNode->TypeNode);
  xPrintString("\n");
}


/*---+---------------------------------------------------------------
     xPrintAllPrdVariables
-------------------------------------------------------------------*/
static void xPrintAllPrdVariables(
  xPrdNode  PrdNode)
{
  xVarIdNode  VarId;
  xPrdIdNode  PrdId;

  for (VarId = (xVarIdNode)PrdNode->NameNode->First;
       VarId != (xVarIdNode)0;
       VarId = (xVarIdNode)VarId->Suc ){
    if (VarId->EC == xVariableEC || VarId->EC == xFormalParEC) {
      xPrintPrdVariable(VarId, PrdNode);
    }
  }
  for (PrdId = PrdNode->NameNode->Super;
       PrdId != (xPrdIdNode)0;
       PrdId = PrdId->Super)
    for (VarId = (xVarIdNode)PrdId->First;
         VarId != (xVarIdNode)0;
         VarId = (xVarIdNode)VarId->Suc ){
      if (VarId->EC == xVariableEC || VarId->EC == xFormalParEC) {
        xPrintPrdVariable(VarId, PrdNode);
      }
    }
}


/*---+---------------------------------------------------------------
     xAssignVariable
-------------------------------------------------------------------*/
void xAssignVariable(
  tSDLTypeInfo *TypeNode,
  xptrint       VarPointer)
{
  xxToken Token;
  char    strVar[MAX_READ_LENGTH];
  char    Prompt[256];
  void   *TempVar;
  xbool   AssignOk;

  sprintf(Prompt, "Value (%s) : ", TypeNode->Name);
#ifdef FIX_FOR_CPP
  Token = xScanToken(strVar);
  if (Token == xxQuestionMark || Token == xxEoln) {
    xPrintString(Prompt);
    if (Token != xxEoln) xSkipLine();
    Token = xScanToken(strVar);
  }
#else
  Token = xPromptQuestionMark(Prompt, (char *)0, strVar);
#endif
  if (Token == xx2QuestionMark) {
    PRINTF2(" (%s) = ", xWriteEntity((xIdNode)TypeNode->SortIdNode));
    xxWriteSort((void *)(VarPointer), TypeNode);
    xPrintString(" : ");
  } else {
    xUngetToken(Token, strVar);
  }

  TempVar = (void *)XALLOC((xptrint)TypeNode->SortSize, TypeNode);
  /* memcpy(TempVar, (void *)(VarPointer), TypeNode->SortSize); */
  /* memcpy not possible as pointers are copied as well!! */
  if (xGenericReadSort(TempVar, TypeNode) ) {
    AssignOk = (xbool)1;
#ifdef XVALIDATOR_LIB
    if (TypeNode->SortIdNode->Test_Function != 0)
      AssignOk = TypeNode->SortIdNode->Test_Function(TempVar);
#else
    /* Do not call Test_Function when Restore-State */
    if ( !xSysD.xRestoringState && TypeNode->SortIdNode->Test_Function != 0)
      AssignOk = TypeNode->SortIdNode->Test_Function(TempVar);
#endif
    if ( ! AssignOk) {
      if (xVerify("Value out of range, do you still want to assign value : "))
        AssignOk = (xbool)1;
      else
        xPrintString("Value not assigned\n");
    }
    if (AssignOk) {
      GenericFreeSort((void **)VarPointer, TypeNode);
      memcpy((void *)(VarPointer), TempVar, TypeNode->SortSize);
      xPrintString("Value assigned\n");
    }
  }
  else
    xPrintString("Value not assigned\n");
  XFREE(&TempVar, TypeNode->SortSize);
}


/*---+---------------------------------------------------------------
     IsSortWithComponents
-------------------------------------------------------------------*/

/* Returns true ( (xbool)1 ) if sort is structured sort and it
   is possible to Examine-Variable and Assign-Value to components
   of this type
*/

static xbool IsSortWithComponents(
  tSDLTypeInfo *SortNode)
{
  while (SortNode->TypeClass == type_SDL_Syntype ||
         SortNode->TypeClass == type_SDL_Inherits)
    SortNode = ((tSDLGenInfo *)SortNode)->CompOrFatherSort;

  if (SortNode->TypeClass == type_SDL_Array ||
      SortNode->TypeClass == type_SDL_GArray ||
      SortNode->TypeClass == type_SDL_Carray ||
      SortNode->TypeClass == type_SDL_ComBuf ||
      SortNode->TypeClass == type_SDL_Ref ||
      SortNode->TypeClass == type_SDL_Own ||
      SortNode->TypeClass == type_SDL_Oref ||
      SortNode->TypeClass == type_SDL_Struct ||
      SortNode->TypeClass == type_SDL_Choice ||
      SortNode->TypeClass == type_SDL_Union ||
      SortNode->TypeClass == type_SDL_UnionC ||
      SortNode->TypeClass == type_SDL_String ||
      SortNode->TypeClass == type_SDL_LString)
    return (xbool)1;
  return (xbool)0;
}

/*---+---------------------------------------------------------------
     IsSortOKGArrayComp
-------------------------------------------------------------------*/
static xbool IsSortOKGArrayComp(
  tSDLTypeInfo *IndexSort)
{
  while (IndexSort->TypeClass == type_SDL_Syntype ||
         IndexSort->TypeClass == type_SDL_Inherits)
    IndexSort = ((tSDLGenInfo *)IndexSort)->CompOrFatherSort;

  if (IndexSort == &ySDL_SDL_Integer ||
      IndexSort == &ySDL_SDL_Character ||
      IndexSort == &ySDL_SDL_Natural ||
      IndexSort == &ySDL_SDL_Charstring ||
      IndexSort == &ySDL_SDL_IA5String ||
      IndexSort == &ySDL_SDL_NumericString ||
      IndexSort == &ySDL_SDL_PrintableString ||
      IndexSort == &ySDL_SDL_VisibleString ||
      IndexSort == &ySDL_SDL_PId)
    return (xbool)1;
  if (IndexSort->TypeClass == type_SDL_ShortInt ||
      IndexSort->TypeClass == type_SDL_LongInt ||
      IndexSort->TypeClass == type_SDL_UnsignedShortInt ||
      IndexSort->TypeClass == type_SDL_UnsignedInt ||
      IndexSort->TypeClass == type_SDL_UnsignedLongInt)
    return (xbool)1;
  return (xbool)0;
}

/*---+---------------------------------------------------------------
     xHandleArrayRange
-------------------------------------------------------------------*/
static int xHandleArrayRange(
  xbool         IsExamine,
  char         *Str,
  xptrint       VarPointer,
  tSDLTypeInfo *ArraySort,
  void         *TempVar,
  long int      intVar)
{
  xxToken       Token;
  char          strVar[MAX_READ_LENGTH];
  void         *TempVar2;
  long int      intVar2, LowValue;
  long int      I;
  WriteBuf *    Buf;
  tSDLTypeInfo *IndexSort;
  tSDLTypeInfo *IndexRootSort;
  tSDLTypeInfo *ComponentSort;

  IndexSort = ((tSDLArrayInfo *)ArraySort)->IndexSort;
  IndexRootSort = IndexSort;
  while  (IndexRootSort->TypeClass == type_SDL_Syntype ||
          IndexRootSort->TypeClass == type_SDL_Inherits)
    IndexRootSort = ((tSDLGenInfo *)IndexRootSort)->CompOrFatherSort;
  ComponentSort = ((tSDLArrayInfo *)ArraySort)->CompSort;
  LowValue = ((tSDLArrayInfo *)ArraySort)->LowestValue;
  TempVar2 = (void *)XALLOC((xptrint)IndexSort->SortSize, IndexSort);

  Token = xScanToken(strVar);
  if (Token == xxEoln) {
    PRINTF2("Upper index (%s) : ", IndexSort->Name);
    Token = xScanToken(strVar);
  }
  xUngetToken(Token, strVar);
 
  if (xGenericReadSort(TempVar2, IndexSort) ) {
    intVar2 = GenericGetValue((unsigned)IndexSort->SortSize, TempVar2) - LowValue;
    if (intVar2 < 0 ||
        intVar2 >= ((tSDLArrayInfo *)ArraySort)->Length) {
      xPrintString("Array index out of range\n");
      XFREE(&TempVar2,IndexSort->SortSize);
      return 0;
    }
    if (intVar2 < intVar) {
      xPrintString("Higher index less than lower index\n");
      XFREE(&TempVar2,IndexSort->SortSize);
      return 0;
    }
    Token = xScanToken(strVar);
    if (Token != xxRPar) xUngetToken(Token, strVar);

    if (!IsExamine) {
      Token = xScanToken(strVar);
      if (XVALUE_SYNTAX &&
          Token != xxLParColon && Token != xxQuestionMark && Token != xxEoln) {
        xPrintString("Array value should start with (:\n");
        XFREE(&TempVar2,IndexSort->SortSize);
        return 0;
      }
      if (Token == xxLParColon) Token = xScanToken(strVar);

      /* for each index read component */
      for (I = intVar; I <= intVar2; I++) {
        if (Token == xxComma) Token = xScanToken(strVar);
        if (Token == xxEoln) {
          if (IndexRootSort == &ySDL_SDL_Character) {
            PRINTF2(" Index=%c", (char)(I+LowValue));
#ifndef XNOUSEOFOCTETBITSTRING
          } else if (IndexRootSort == &ySDL_SDL_Octet) {
            PRINTF2(" Index=%.2X", (SDL_Octet)(I+LowValue));
#endif
          } else if (IndexRootSort == &ySDL_SDL_Boolean) {
            if (I==0)
              xPrintString(" Index=false");
            else
              xPrintString(" Index=true");
          } else if (IndexRootSort->TypeClass == type_SDL_Enum) {
            if (I-LowValue < ((tSDLEnumInfo *)IndexSort)->NoOfLiterals) {
              PRINTF2(" Index=%s", 
                ((tSDLEnumInfo *)IndexSort)->LiteralList[I].LiteralName);
            }
          } else if (IndexRootSort->TypeClass == type_SDL_Integer) {
            PRINTF2(" Index=%ld", I+LowValue);
          }
          PRINTF2(" (%s) : ", ComponentSort->Name);
          Token = xScanToken(strVar);
        }
        xUngetToken(Token, strVar);

        if (! xGenericReadSort(
                (void *)(VarPointer + I * (int)ComponentSort->SortSize),
                ComponentSort) ) {
          xPrintString("Illegal component value\n");
          XFREE(&TempVar2,IndexSort->SortSize);
          return 0;
        }
        Token = xScanToken(strVar);
      }

      if (Token == xxEoln) {
        xPrintString(" End of array range : ");
        Token = xScanToken(strVar);
      }
      if (Token == xxRParColon || Token == xxQuestionMark || Token == xxEoln) {
        if (Token == xxEoln) xUngetToken(Token, strVar);
      }
    }

    Buf = WriteBuf_New(60);
    WriteBuf_Add_String(Buf, Str, 0);
    WriteBuf_Add_String(Buf, "(", 0);
    xGenericWriteSort(Buf, TempVar, IndexSort);
    WriteBuf_Add_String(Buf, ":", 0);
    xGenericWriteSort(Buf, TempVar2, IndexSort);
    WriteBuf_Add_String(Buf, ") = (: ", 0);
    for (I = intVar; I <= intVar2; I++) {
      xGenericWriteSort(Buf, (void *)(VarPointer + I*(int)ComponentSort->SortSize),
			ComponentSort);
      if (I < intVar2)
	WriteBuf_Add_String(Buf, ", ", 0);
    }
    WriteBuf_Add_String(Buf, " :)\n", 0);
    WriteBuf_Terminate(Buf);
    xPrintString(WriteBuf_Data(Buf));
    WriteBuf_Del(&Buf);
  }
  XFREE(&TempVar2,IndexSort->SortSize);
  return 1;
}


/*---+---------------------------------------------------------------
     xHandleVariableComponent
-------------------------------------------------------------------*/
static int xHandleVariableComponent(
  xbool         IsExamine,
  char         *Str,
  tSDLTypeInfo *SortNode,
  xptrint       VarPointer)
{
  typedef enum {xxDummyZero, xxDummyOne, xxDummyTwo} xxDymmyEnum;

  tSDLTypeInfo *IndexSort;
  tSDLTypeInfo *IndexRootSort;
  xVarIdNode    IdTemp, IdPresent;
  long int      intVar = 0;
  xxToken       Token;
  char         *inputPos;
  char          strVar[MAX_READ_LENGTH];
  WriteBuf     *Buf;
  void         *TempVar;
  tSDLTypeInfo *SN;
  xbool         EmptyInput;
  xbool         MoreReq, ChoicePrimary;
  int           Result = 0;
  xptrint       TempPointer;
  xIdNode       VarTmp;
  int           LowValue;

  Token = xScanToken(strVar);
  SN = SortNode;
  while (SN->TypeClass == type_SDL_Syntype ||
         SN->TypeClass == type_SDL_Inherits)
    SN = ((tSDLGenInfo *)SN)->CompOrFatherSort;
  ChoicePrimary = (xbool)0;
  if (SN->TypeClass == type_SDL_Choice || SN->TypeClass == type_SDL_Union) {
    if (Token == xxId) {
      inputPos = xInputPos;
      while (*inputPos == ' ' || *inputPos == '\t')
        inputPos++;
      if (*inputPos == ':')
        ChoicePrimary = (xbool)1;
    }
  }
  if (Token != xxEoln      && Token != xxLParDot &&
      Token != xxLParColon && Token != xxLBracket &&
      Token != xxLCurlyBracket && !ChoicePrimary) {

    if (SN->TypeClass == type_SDL_Array || SN->TypeClass == type_SDL_String ||
        SN->TypeClass == type_SDL_GArray || SN->TypeClass == type_SDL_Carray ||
        SN->TypeClass == type_SDL_ComBuf) {
      LowValue = 0;
      if (SN->TypeClass == type_SDL_String)
        IndexSort = &ySDL_SDL_Integer;
      else if (SN->TypeClass == type_SDL_GArray)
        IndexSort = ((tSDLGArrayInfo *)SN)->IndexSort;
      else {
        IndexSort = ((tSDLArrayInfo *)SN)->IndexSort;
        LowValue = ((tSDLArrayInfo *)SN)->LowestValue;
      }
      IndexRootSort = IndexSort;
      while  (IndexRootSort->TypeClass == type_SDL_Syntype ||
              IndexRootSort->TypeClass == type_SDL_Inherits)
        IndexRootSort = ((tSDLGenInfo *)IndexRootSort)->CompOrFatherSort;
      if (Token == xxLPar || Token == xxComma) Token = xScanToken(strVar);
      if (Token == xxEoln) {
        PRINTF2("Index (%s) : ", IndexSort->Name);
        Token = xScanToken(strVar);
      }
      xUngetToken(Token, strVar);
      TempVar = (void *)XALLOC((xptrint)IndexSort->SortSize, IndexSort);
      if (xGenericReadSort(TempVar, IndexSort) ) {
        if (SN->TypeClass == type_SDL_Array || SN->TypeClass == type_SDL_Carray ||
            SN->TypeClass == type_SDL_String || SN->TypeClass == type_SDL_ComBuf) {
          intVar = GenericGetValue((unsigned)IndexSort->SortSize, TempVar) -
                   LowValue;
          if (SN->TypeClass == type_SDL_Array || SN->TypeClass == type_SDL_Carray ||
              SN->TypeClass == type_SDL_ComBuf) {
            if (intVar < 0 || intVar >= ((tSDLArrayInfo *)SN)->Length) {
              xPrintString("Array index out of range\n");
              XFREE(&TempVar,IndexSort->SortSize);
              return 0;
            }
          }
        }

        /* Handle range in array */
        Token = xScanToken(strVar);
        if (Token == xxColon &&
           (SN->TypeClass == type_SDL_Array || SN->TypeClass == type_SDL_Carray)) {
          (void)xHandleArrayRange(IsExamine, Str, VarPointer,
             SN, TempVar, intVar);
          XFREE(&TempVar,IndexSort->SortSize);
          return 1;
        }
        if (Token == xxColon && SN->TypeClass == type_SDL_ComBuf) {
          if (((*(xComBuf *)VarPointer)==0)) {
            xPrintString("Not allowed to assign or examine component in \n");
            xPrintString("a not allocated communication buffer variable. \n");
            return 0;
          }
          (void)xHandleArrayRange(IsExamine, Str, 
             (xptrint)&((*(xComBuf *)VarPointer)->el),
             SN, TempVar, intVar);
          XFREE(&TempVar,IndexSort->SortSize);
          return 1;
        }

        if (Token != xxRPar) xUngetToken(Token, strVar);

	Buf = WriteBuf_New(60);
	xGenericWriteSort(Buf, TempVar, IndexSort);
	WriteBuf_Terminate(Buf);
        sprintf(strVar, "%s(%s)", Str, WriteBuf_Data(Buf));
	WriteBuf_Del(&Buf);

        if (SN->TypeClass == type_SDL_Array || SN->TypeClass == type_SDL_Carray ) {
          Result = xHandleVariableComponent(IsExamine, strVar,
              ((tSDLArrayInfo *)SN)->CompSort,
              VarPointer + intVar*(int)((tSDLArrayInfo *)SN)->CompSort->SortSize);

        } else if (SN->TypeClass == type_SDL_ComBuf) {
          if (((*(xComBuf *)VarPointer)==0)) {
            xPrintString("Not allowed to assign or examine component in \n");
            xPrintString("a not allocated communication buffer variable. \n");
            return 0;
          }
          Result = xHandleVariableComponent(IsExamine, strVar,
              ((tSDLArrayInfo *)SN)->CompSort,
              (xptrint)&((*(xComBuf *)VarPointer)->el) +
               intVar*(int)((tSDLArrayInfo *)SN)->CompSort->SortSize);

        } else if (SN->TypeClass == type_SDL_String) {
          if (intVar < 1) {
            xPrintString("String index must be >= 1\n");
            XFREE(&TempVar,IndexSort->SortSize);
            return 0;
          }
          VarPointer = (xptrint)((xString_Type *)VarPointer)->First;
          for (; intVar>1 && VarPointer!=0; intVar--)
            VarPointer = (xptrint)((xString_yptr)VarPointer)->Suc;
          if (VarPointer == 0) {
            xPrintString("String index too large\n");
            XFREE(&TempVar,IndexSort->SortSize);
            return 0;
          }
          Result = xHandleVariableComponent(IsExamine, strVar,
              ((tSDLGenListInfo *)SN)->CompSort, 
	      (xptrint)(VarPointer + ((tSDLGenListInfo *)SN)->yrecDataOffset));

        } else if (SN->TypeClass == type_SDL_GArray) {
          if ( IsSortOKGArrayComp(IndexSort) ) {
            if (IndexSort->SortIdNode->Test_Function != 0) {
              if (! IndexSort->SortIdNode->Test_Function(TempVar) ) {
                xPrintString("Array index out of range\n");
                XFREE(&TempVar,IndexSort->SortSize);
                return 0;
              }
            }
            TempPointer = (xptrint)((xGArray_Type *)VarPointer)->First;
            while (TempPointer != 0) {
              if ( GenericEqualSort(
                   (void *)(TempPointer + ((tSDLGArrayInfo *)SN)->yrecIndexOffset),
                   (void *)TempVar,
                   IndexSort) )
                break;
              TempPointer = (xptrint)((xGArray_yptr)TempPointer)->Suc;
            }
            if (!IsExamine && TempPointer == 0) {
              if (((xGArray_Type *)VarPointer)->Last != (xGArray_yptr)0) {
                ((xGArray_Type *)VarPointer)->Last->Suc =
                  (xGArray_yptr)XALLOC(((tSDLGArrayInfo *)SN)->yrecSize, 0);
                ((xGArray_Type *)VarPointer)->Last =
                  ((xGArray_Type *)VarPointer)->Last->Suc;
              } else {
                ((xGArray_Type *)VarPointer)->Last =
                  (xGArray_yptr)XALLOC(((tSDLGArrayInfo *)SN)->yrecSize, 0);
                ((xGArray_Type *)VarPointer)->First =
                  ((xGArray_Type *)VarPointer)->Last;
              }
              TempPointer = (xptrint)((xGArray_Type *)VarPointer)->Last;
              GenericAssignSort(
                (void *)(TempPointer + ((tSDLGArrayInfo *)SN)->yrecIndexOffset),
                (void *)TempVar,
                XASS_MR_ASS_NF,
                IndexSort);
            }
            if (TempPointer == 0) {
              Result = xHandleVariableComponent(IsExamine, strVar,
                ((tSDLGArrayInfo *)SN)->CompSort,
                (xptrint)(VarPointer + ((tSDLGArrayInfo *)SN)->arrayDataOffset));
            } else {
              Result = xHandleVariableComponent(IsExamine, strVar,
                ((tSDLGArrayInfo *)SN)->CompSort,
                (xptrint)(TempPointer + ((tSDLGArrayInfo *)SN)->yrecDataOffset));
            }
          } else {
            xPrintString(
              "Components to general arrays can only be handled for index types\n");
            xPrintString(
              "Integer, Character, Charstring, PId, and syntypes of these types.\n");
            Result = 0;
          }
        }
        XFREE(&TempVar,IndexSort->SortSize);
        return Result;
      }
      XFREE(&TempVar,IndexSort->SortSize);
    }

    if (SN->TypeClass == type_SDL_Struct || SN->TypeClass == type_SDL_Choice ||
        SN->TypeClass == type_SDL_Union  || SN->TypeClass == type_SDL_UnionC) {
      MoreReq = (xbool)0;
      if (Token == xxExclMark || Token == xxRArrow) {
        MoreReq = (xbool)1;
      } else {
        xUngetToken(Token, strVar);
      }
      IdTemp = (xVarIdNode)xGetIdNodeInECSet("Component : ", 
                                             1L<<((long)xVariableEC),
                                             (xIdNode)SN->SortIdNode,
                                             &EmptyInput,
                                             ! MoreReq,
                                             (xIdNode)0);
      if (EmptyInput) return 1;
      if (IdTemp != (xVarIdNode)0) {
        intVar = -1; /* tag should not be counted */
        VarTmp = SN->SortIdNode->First;
        while ((VarTmp != 0) && (VarTmp != (xIdNode)IdTemp)) {
          VarTmp = VarTmp->Suc;
          intVar++;
        }
        if (SN->TypeClass == type_SDL_Choice) {
          if ((intVar != -1) && (*(xxDymmyEnum *)VarPointer != intVar)) {
            PRINTF2("Selected component (%s) is not active\n", IdTemp->Name);
            return 0;
          }
          if ((intVar == -1) && !IsExamine) {
            xPrintString("It is not allowed to change the value of only the Present component\n");
            return 0;
          }
        }
        if (SN->TypeClass == type_SDL_Union) {
          if ((intVar != -1) && (*(int *)VarPointer != intVar)) {
            PRINTF2("Selected component (%s) is not active\n", IdTemp->Name);
            return 0;
          }
          if ((intVar == -1) && !IsExamine) {
            xPrintString("It is not allowed to change the value of only the tag component\n");
            return 0;
          }
        }
        if (Token == xxRArrow)
          sprintf(strVar, "%s->%s", Str, IdTemp->Name);
        else
          sprintf(strVar, "%s!%s", Str, IdTemp->Name);
        if (IdTemp->Offset == 65535) {
          xPrintString("A bitfield component cannot be selected for read or write\n");
          return 0;
        }
        intVar = xHandleVariableComponent(IsExamine, strVar, IdTemp->TypeNode,
            VarPointer + (int)IdTemp->Offset);
        if (intVar > 0 && !IsExamine) {
          /* Handle present field if optional component */
          IdPresent = (xVarIdNode)IdTemp->Suc;
          if (IdPresent != (xVarIdNode)0 && IdPresent->EC == xSyntVariableEC)
            *(SDL_Boolean *)(VarPointer + (int)IdPresent->Offset) = SDL_True;
        }

        return intVar;
      }
      return 0;
    }

    if (SN->TypeClass == type_SDL_Ref || SN->TypeClass == type_SDL_Own ||
        SN->TypeClass == type_SDL_Oref) {
      if (Token == xxStarArrow || Token == xxRArrow) {
        if (Token == xxStarArrow)
          sprintf(strVar, "%s*>", Str);
        else {
          xUngetToken(Token, strVar);
          sprintf(strVar, "%s", Str);
        }
        if (*(void **)VarPointer == 0) {
          xPrintString("Access through a NULL pointer\n");
          return 0;
        }
        return xHandleVariableComponent(IsExamine, strVar,
            ((tSDLGenInfo *)SN)->CompOrFatherSort,
            (xptrint)*((void **)VarPointer));
      }
    }
  }

  if (! IsExamine) {
    xUngetToken(Token, strVar);
    xAssignVariable(SortNode, VarPointer);
  }
  PRINTF3("%s (%s) = ", Str, xWriteEntity((xIdNode)SortNode->SortIdNode));
  xxWriteSort((void *)(VarPointer), SortNode);
  xPrintString("\n");
  return 1;
}


/*---+---------------------------------------------------------------
     xPrintPrsVariable
-------------------------------------------------------------------*/
void xPrintPrsVariable(
  xVarIdNode IdNode,
  xptrint    PrsNode)
{
  PRINTF3("%s (%s)",
    IdNode->Name,
    xWriteEntity((xIdNode)IdNode->TypeNode->SortIdNode)
  );
  xPrintString(" = ");
  xxWriteSort((void *) (PrsNode + IdNode->Offset), IdNode->TypeNode);
  xPrintString("\n");
  if (IdNode->EC == xVariableEC && IdNode->Offset2 != (xptrint)0) {
    PRINTF3("%s (exported value) (%s) = ",
      IdNode->Name,
      xWriteEntity((xIdNode)IdNode->TypeNode->SortIdNode));
    xxWriteSort((void *) (PrsNode + IdNode->Offset2), IdNode->TypeNode);    
    xPrintString("\n");
  }
}


/*---+---------------------------------------------------------------
     xPrintAllPrsVariables
-------------------------------------------------------------------*/
void xPrintAllPrsVariables(
  xIdNode    IdNode,
  xptrint    PrsNode)
{
  xVarIdNode  VarId;
  xPrsIdNode  ProcessId;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode  ServiceId;
#endif

  if (IdNode->EC == xProcessEC) {
    for ( ProcessId = (xPrsIdNode)IdNode;
          ProcessId != (xPrsIdNode)0;
          ProcessId = ProcessId->Super) {
      for ( VarId = (xVarIdNode)ProcessId->First;
            VarId != (xVarIdNode)0;
            VarId = (xVarIdNode)VarId->Suc ) {
        if (VarId->EC == xVariableEC || VarId->EC == xFormalParEC) {
          xPrintPrsVariable(VarId, PrsNode);
        }
      }
    }
#ifndef XNOUSEOFSERVICE
  } else {
    for ( ServiceId = (xSrvIdNode)IdNode;
          ServiceId != (xSrvIdNode)0;
          ServiceId = ServiceId->Super) {
      for ( VarId = (xVarIdNode)ServiceId->First;
            VarId != (xVarIdNode)0;
            VarId = (xVarIdNode)VarId->Suc ) {
        if (VarId->EC == xVariableEC || VarId->EC == xFormalParEC) {
          xPrintPrsVariable(VarId, PrsNode);
        }
      }
    }
#endif
  }
}


/*---+---------------------------------------------------------------
     ExamineVariable
-------------------------------------------------------------------*/
static void ExamineVariable(
  char * strVar)
{
  xVarIdNode    xIdNodeVariable;
  xbool         xEmptyInput;
  xptrint       VarPointer;
  xxToken       Token;
  xPrsNode      tmpPrs;
  xPrsIdNode    ProcessId;
  xbool         allInstances = (xbool)0;

  Token = xScanToken(strVar);
  if (Token == xxLPar) {
    tmpPrs = xReadProcess("Process : ", &ProcessId, (xIdNode)0);
    if (tmpPrs != (xPrsNode)0) {
      XSYSD xPrsScope = tmpPrs;
      XSYSD xPrdScope = (xPrdNode)0;
#ifndef XNOUSEOFSERVICE
      XSYSD xSrvScope = (xSrvNode)0;
#endif
    } else if (ProcessId) {
#ifdef XVALIDATOR_LIB
      XSYSD xPrsScope = xFirstActivePrs(ProcessId);
#else
      XSYSD xPrsScope = *ProcessId->ActivePrsList;
#endif
      if (XSYSD xPrsScope == (xPrsNode)0) {
        return;
      }
      XSYSD xPrdScope = (xPrdNode)0;
#ifndef XNOUSEOFSERVICE
      XSYSD xSrvScope = (xSrvNode)0;
#endif
      PRINTF2("%s ", xWri_SDL_PId(&(XSYSD xPrsScope->Self)));
      allInstances = (xbool)1;
    } else {
      return;
    }
    Token = xScanToken(strVar);
    if (Token != xxRPar) xUngetToken(Token, strVar);
  } else {
    xUngetToken(Token, strVar);
  }

  if (XSYSD xPrsScope == (xPrsNode)0) {
    xPrintScope((xbool)1);
    return;
  }

  Token = xReadVariable(
     "Variable name (type ? after name to select component) : ",
     strVar, &xEmptyInput, (xbool)1);
  if (xEmptyInput) {
    if (XSYSD xPrdScope != (xPrdNode)0)
      xPrintAllPrdVariables(XSYSD xPrdScope);
#ifndef XNOUSEOFSERVICE
    else if (XSYSD xSrvScope != (xSrvNode)0)
      xPrintAllPrsVariables((xIdNode)XSYSD xSrvScope->NameNode,
                            (xptrint)XSYSD xSrvScope);
#endif
    else
      xPrintAllPrsVariables((xIdNode)XSYSD xPrsScope->NameNode,
                            (xptrint)XSYSD xPrsScope);
    return;
  }

  if (Token == xxParent) {
    PRINTF2("Parent (pid) = %s\n", 
            xWri_SDL_PId(&XPRS_PARENT(XSYSD xPrsScope)));
    return;
  }
  if (Token == xxOffspring) {
    PRINTF2("Offspring (pid) = %s\n", 
            xWri_SDL_PId(&XPRS_OFFSPRING(XSYSD xPrsScope)));
    return;
  }
  if (Token == xxSender) {
    PRINTF2("Sender (pid) = %s\n", 
            xWri_SDL_PId(&XPRS_SENDER(XSYSD xPrsScope)));
    return;
  }
  if (Token == xxSelf) {
    PRINTF2("Self (pid) = %s\n", 
            xWri_SDL_PId(&XPRS_SELF(XSYSD xPrsScope)));
    return;
  }
  if (Token != xxId) {
    xPrintString("Illegal variable name\n");
    return;
  }
  if ( ! xVariableInProcess(strVar, &xIdNodeVariable, &VarPointer) ) {
    return;
  }
  Token = xScanToken(strVar);
  if ( Token != xxEoln && Token != xxSemicolon &&
       IsSortWithComponents(xIdNodeVariable->TypeNode) ) {
    xUngetToken(Token, strVar);
    (void)xHandleVariableComponent((xbool)1, xIdNodeVariable->Name,
                               xIdNodeVariable->TypeNode, VarPointer);
    return;
  }
  xUngetToken(Token, strVar);
  if (XSYSD xPrdScope != (xPrdNode)0)
    xPrintPrdVariable(xIdNodeVariable, XSYSD xPrdScope);
#ifndef XNOUSEOFSERVICE
  else if (XSYSD xSrvScope != (xSrvNode)0)
    xPrintPrsVariable(xIdNodeVariable, (xptrint)XSYSD xSrvScope);
#endif
  else
    xPrintPrsVariable(xIdNodeVariable, (xptrint)XSYSD xPrsScope);

  if (allInstances) {
    tmpPrs = XSYSD xPrsScope;
#ifdef XVALIDATOR_LIB
    tmpPrs = xNextActivePrs(tmpPrs);
#else
    tmpPrs = tmpPrs->NextPrs;
#endif
    while (tmpPrs != (xPrsNode)0) {
      PRINTF2("%s ", xWri_SDL_PId(&(tmpPrs->Self)));
      xPrintPrsVariable(xIdNodeVariable, (xptrint)tmpPrs);
#ifdef XVALIDATOR_LIB
      tmpPrs = xNextActivePrs(tmpPrs);
#else
      tmpPrs = tmpPrs->NextPrs;
#endif
    }
  }
}

/*---+---------------------------------------------------------------
     xExamineVariable
-------------------------------------------------------------------*/
void xExamineVariable(
  char * strVar)
{
  xPrsNode      oldPrsScope;
  xPrdNode      oldPrdScope;
#ifndef XNOUSEOFSERVICE
  xSrvNode      oldSrvScope;
#endif

  oldPrsScope = XSYSD xPrsScope;
  oldPrdScope = XSYSD xPrdScope;
#ifndef XNOUSEOFSERVICE
  oldSrvScope = XSYSD xSrvScope;
#endif

  ExamineVariable(strVar);

  XSYSD xPrsScope = oldPrsScope;
  XSYSD xPrdScope = oldPrdScope;
#ifndef XNOUSEOFSERVICE
  XSYSD xSrvScope = oldSrvScope;
#endif
}


/*---+---------------------------------------------------------------
     AssignValue
-------------------------------------------------------------------*/
static void AssignValue(
  char * strVar)
{
  xVarIdNode    xIdNodeVariable;
  xbool         xEmptyInput;
  xptrint       VarPointer;
  xxToken       Token;
  xPrsNode      tmpPrs;
  xPrsIdNode    ProcessId;

  Token = xScanToken(strVar);
  if (Token == xxLPar) {
    tmpPrs = xReadProcess("Process : ", &ProcessId, (xIdNode)0);
    if (tmpPrs != (xPrsNode)0) {
      XSYSD xPrsScope = tmpPrs;
      XSYSD xPrdScope = (xPrdNode)0;
#ifndef XNOUSEOFSERVICE
      XSYSD xSrvScope = (xSrvNode)0;
#endif
    } else {
      return;
    }
    Token = xScanToken(strVar);
    if (Token != xxRPar) xUngetToken(Token, strVar);
  } else {
    xUngetToken(Token, strVar);
  }

  if (XSYSD xPrsScope == (xPrsNode)0) {
    xPrintScope((xbool)1);
    return;
  }
  Token = xReadVariable("Variable name : ", strVar, &xEmptyInput, (xbool)0);
  if (Token == xxParent) {
    Token = xPromptQuestionMark("Value (pid) : ", (char *)0, strVar);
    if (Token == xx2QuestionMark) {
      PRINTF2(" (pid) = %s : ", 
              xWri_SDL_PId(&XPRS_PARENT(XSYSD xPrsScope)));
    } else {
      xUngetToken(Token, strVar);
    }
    if (xRead_SDL_PId(&XPRS_PARENT(XSYSD xPrsScope))) {
      xPrintString("Value assigned\n");
      PRINTF2("Parent (pid) = %s\n", 
              xWri_SDL_PId(&XPRS_PARENT(XSYSD xPrsScope)));
    }
    else
      xPrintString("Value not assigned\n");
    return;
  }
  if (Token == xxOffspring) {
    Token = xPromptQuestionMark("Value (pid) : ", (char *)0, strVar);
    if (Token == xx2QuestionMark) {
      PRINTF2(" (pid) = %s : ", 
              xWri_SDL_PId(&XPRS_OFFSPRING(XSYSD xPrsScope)));
    } else {
      xUngetToken(Token, strVar);
    }
    if (xRead_SDL_PId(&XPRS_OFFSPRING(XSYSD xPrsScope))) {
      xPrintString("Value assigned\n");
      PRINTF2("Offspring (pid) = %s\n", 
              xWri_SDL_PId(&XPRS_OFFSPRING(XSYSD xPrsScope)));
    }
    else
      xPrintString("Value not assigned\n");
    return;
  }
  if (Token == xxSender) {
    Token = xPromptQuestionMark("Value (pid) : ", (char *)0, strVar);
    if (Token == xx2QuestionMark) {
      PRINTF2(" (pid) = %s : ", 
              xWri_SDL_PId(&XPRS_SENDER(XSYSD xPrsScope)));
    } else {
      xUngetToken(Token, strVar);
    }
    if (xRead_SDL_PId(&XPRS_SENDER(XSYSD xPrsScope))) {
      xPrintString("Value assigned\n");
      PRINTF2("Sender (pid) = %s\n", 
              xWri_SDL_PId(&XPRS_SENDER(XSYSD xPrsScope)));
    }
    else
      xPrintString("Value not assigned\n");
    return;
  }
  if (Token != xxId) {
    xPrintString("Illegal variable name\n");
    return;
  }

  if ( ! xVariableInProcess(strVar, &xIdNodeVariable, &VarPointer) )
    return;

  if ( IsSortWithComponents(xIdNodeVariable->TypeNode) ) {
    Token = xScanToken(strVar);
    if ( Token != xxEoln       && Token != xxLParDot &&
         Token != xxLParColon  && Token != xxLBracket &&
         (Token != xxId || strcmp(strVar, "HEX")) &&
         /* Not trying to assign a HEX value */
         Token != xxLCurlyBracket) {
      xUngetToken(Token, strVar);
      if ( ! xHandleVariableComponent((xbool)0, xIdNodeVariable->Name,
                                  xIdNodeVariable->TypeNode, VarPointer) )
        xPrintString("Value not assigned\n");
      return;
    }
    xUngetToken(Token, strVar);
  }

  xAssignVariable(xIdNodeVariable->TypeNode, VarPointer);
  if (XSYSD xPrdScope != (xPrdNode)0)
    xPrintPrdVariable(xIdNodeVariable, XSYSD xPrdScope);
#ifndef XNOUSEOFSERVICE
  else if (XSYSD xSrvScope != (xSrvNode)0)
    xPrintPrsVariable(xIdNodeVariable, (xptrint)XSYSD xSrvScope);
#endif
  else
    xPrintPrsVariable(xIdNodeVariable, (xptrint)XSYSD xPrsScope);
}


/*---+---------------------------------------------------------------
     xAssignValue
-------------------------------------------------------------------*/
void xAssignValue(
  char * strVar)
{
  xPrsNode      oldPrsScope;
  xPrdNode      oldPrdScope;
#ifndef XNOUSEOFSERVICE
  xSrvNode      oldSrvScope;
#endif

  oldPrsScope = XSYSD xPrsScope;
  oldPrdScope = XSYSD xPrdScope;
#ifndef XNOUSEOFSERVICE
  oldSrvScope = XSYSD xSrvScope;
#endif

  AssignValue(strVar);

  XSYSD xPrsScope = oldPrsScope;
  XSYSD xPrdScope = oldPrdScope;
#ifndef XNOUSEOFSERVICE
  XSYSD xSrvScope = oldSrvScope;
#endif
}


/*---+---------------------------------------------------------------
     xListInputPort
-------------------------------------------------------------------*/
void xListInputPort(
  char * strVar)
{
  xPrsNode      PrsNode;
  int           count;
  xSignalNode   Signal;
  xxToken       Token;
  xPrsIdNode    ProcessId;

  Token = xScanToken(strVar);
  if (Token == xxLPar) {
    PrsNode = xReadProcess("Process : ", &ProcessId, (xIdNode)0);
    if (PrsNode == (xPrsNode)0) {
      return;
    }
    Token = xScanToken(strVar);
    if (Token != xxRPar) xUngetToken(Token, strVar);
  } else {
    xUngetToken(Token, strVar);
    if (XSYSD xPrsScope == (xPrsNode)0) {
      xPrintScope((xbool)1);
      return;
    }
    PrsNode = XSYSD xPrsScope;
  }

  PRINTF2("Input port of %s\n", xWri_SDL_PId(&XPRS_SELF(PrsNode)));
  count = 0;
  XBEGIN_INPUTPORT_LOOP(PrsNode, Signal)
    if (! XIS_STARTUP_SIGNAL(Signal)) {
      count++;
      if (count == 1) {
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
        xWriteBuf_Fmt("%-8s%-*s%-*sPriority\n",
                "Entry",
                xfShortIdentifierLength+1,
                "Signal name",
                xfShortIdentifierLength+7,
                "Sender");
#else
        xWriteBuf_Fmt("%-8s%-*sSender\n",
                "Entry",
                xfShortIdentifierLength+1,
                "Signal name");
#endif
      }
      if (XIS_CONT_SIGNAL(Signal)) {
        sprintf(strVar, "%s Prio %d",
                XSIGNAL_IDNODE(Signal)->Name, XCONT_SIG_PRIO(Signal));
        xWriteBuf_Fmt("%c%-7d%-*s%s\n",
                (Signal == XPRS_NEXT_REC_SIG(PrsNode) ? '*' : ' '),
                count,
                xfShortIdentifierLength+1,
                strVar,
                xWri_SDL_PId(&(XSIGNAL_SENDER(Signal))));
      }
      else {
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
        xWriteBuf_Fmt("%c%-7d%-*s%-*s%d\n",
                (Signal == XPRS_NEXT_REC_SIG(PrsNode) ? '*' : ' '),
                count,
                xfShortIdentifierLength+1,
                XSIGNAL_IDNODE(Signal)->Name,
                xfShortIdentifierLength+7,
                xWri_SDL_PId(&(XSIGNAL_SENDER(Signal))),
                XCONT_SIG_PRIO(Signal));
#else
        xWriteBuf_Fmt("%c%-7d%-*s%s\n",
                (Signal == XPRS_NEXT_REC_SIG(PrsNode) ? '*' : ' '),
                count,
                xfShortIdentifierLength+1,
                XSIGNAL_IDNODE(Signal)->Name,
                xWri_SDL_PId(&(XSIGNAL_SENDER(Signal))));
#endif
      }
    }
  XEND_INPUTPORT_LOOP
  if (count == 0)
    xPrintString("The input port is empty\n");
}


/*---+---------------------------------------------------------------
     xReadFPars
-------------------------------------------------------------------*/
int xReadFPars (
  xPrsIdNode    Prs,
  xSignalNode * Signal,
  char        * strVar )
{
  xIdNode xIdNodeFParPar;

  /* Treat first FPar:s in inherited process types. */
  if (Prs->Super != (xPrsIdNode)0)
    if (! xReadFPars(Prs->Super, Signal, strVar) ) return 0;

  /* Loop for formal parameters in this type (or ProcessEC) */
  for (xIdNodeFParPar=Prs->First;
       xIdNodeFParPar!=(xIdNode)0;
       xIdNodeFParPar=xIdNodeFParPar->Suc) {
    if (xIdNodeFParPar->EC==xFormalParEC) {
      sprintf(strVar, " Parameter %s (%s) : ",
              ((xVarIdNode)xIdNodeFParPar)->Name,
              ((xVarIdNode)xIdNodeFParPar)->TypeNode->Name);
      if (! xGenericReadOneParameter(
              ((xVarIdNode)xIdNodeFParPar)->TypeNode,
              strVar,
              (void *)((xptrint)(*Signal)+((xVarIdNode)xIdNodeFParPar)->Offset2))
         ) {
        PRINTF2("Error in parameter %s\n",
                ((xVarIdNode)xIdNodeFParPar)->Name);
        return 0;
      }
    }
  }
  return 1;
}

/*---+---------------------------------------------------------------
     xReadSignalParameters
-------------------------------------------------------------------*/
int xReadSignalParameters(
  xSignalIdNode IdNode,
  xSignalNode * Signal,
  SDL_PId       SendRec)
{
  xxToken Token;
  char          strVar[MAX_READ_LENGTH];
  xIdNode       xIdNodeSigPar;
  int           Count;
  xPrsIdNode    Prs;
  tSDLTypeInfo *SortNode;
  void         *Addr;
  xbool         SkipRest = (xbool)0;
  char          prompt[256];
  void         *TempVar;
  int           NextChar;

  /* Returns 1 if successfull otherwise 0 */
  /* Allocate the signal */
  *Signal = xGetSignal(IdNode, SendRec, SendRec);

  /* Read signal parameters */
  Token = xScanToken(strVar);
  if (Token != xxLPar) xUngetToken(Token, strVar);
  Count = 1;
  if (IdNode->EC==xStartUpSignalEC) {
    if (Token == xxLPar) {
      /* Allow empty parameter list for new Restore-State command */
      Token = xScanToken(strVar);
      if (Token == xxRPar)
        return 1;

      xUngetToken(Token, strVar);
    }
    /* Find process node (Prs := process node)*/
    /* The process node is always immediately before the startup */
    /* signal node */
    for (Prs=(xPrsIdNode)IdNode->Parent->First; 
         Prs->Suc!=(xIdNode)IdNode;
         Prs=(xPrsIdNode)Prs->Suc)
      ;
    if (! xReadFPars(Prs, Signal, strVar) ) return 0;
  } else { /* Signal or timer */
    for (xIdNodeSigPar = IdNode->First;
         xIdNodeSigPar != (xIdNode)0;
         xIdNodeSigPar = xIdNodeSigPar->Suc) {
      SortNode = ((xVarIdNode)xIdNodeSigPar)->TypeNode;
      Addr = (void *)((xptrint)(*Signal) + ((xVarIdNode)xIdNodeSigPar)->Offset);
      GenericFreeSort((void **)Addr, SortNode);
      if (SkipRest) {
        memset(Addr, 0, SortNode->SortSize);
        continue;
      }
      Token = xScanToken(strVar);
      if (Token != xxComma)
        xUngetToken(Token, strVar);
      sprintf(prompt, " Parameter %d (%s) : ", Count++, SortNode->Name);
      Token = xPromptQuestionMark(prompt, (char *)0, strVar);
      if (Token == xx2QuestionMark ) {
        TempVar = (void *)XALLOC((xptrint)SortNode->SortSize, SortNode);
        PRINTF2(" (%s) = ", xWriteEntity((xIdNode)SortNode->SortIdNode));
        xxWriteSort(TempVar, ((xVarIdNode)xIdNodeSigPar)->TypeNode);
        xPrintString(" : ");
        XFREE(&TempVar,SortNode->SortSize);
      }
      else if (Token == xxComma) {
        memset(Addr, 0, SortNode->SortSize);
        continue;
      }
      else if (Token == xxMinus) {
        NextChar = xNextInputChar();
        xUngetChar();
        if ( NextChar < '0' || NextChar > '9' ) { /* Not negative number */
          memset(Addr, 0, SortNode->SortSize);
          continue;
        }
        else {
          xUngetToken(Token, strVar);
        }
      }
      else if (Token == xxRPar) {
        memset(Addr, 0, SortNode->SortSize);
        /* Skip rest of parameters */
        SkipRest = (xbool)1;
        continue;
      }
      else {
        xUngetToken(Token, strVar);
      }
      if (! xGenericReadSort(Addr, SortNode) ) {
        PRINTF2("Error in parameter %d\n", Count-1);
        return 0;
      }
    }
  }
  Token = xScanToken(strVar);
  if (Token != xxRPar) xUngetToken(Token, strVar);
  return 1;
}


/*---+---------------------------------------------------------------
     xSymbolTable
-------------------------------------------------------------------*/
void xSymbolTable(
  xIdNode xSTN,
  int     xLvl )
{
  tSDLTypeInfo *SortNode;

  if ( xSTN == 0 )
    return;

  if (xLvl > 0 && xSTN->EC != xStartUpSignalEC &&
                  (xSTN->EC != xStateEC ||
                   ((xStateIdNode)xSTN)->StateNumber != ASTERISK_STATE) ) {
    PRINTF3("%*c", xLvl*2, ' ');
  }

  if ( xSTN->EC == xStateEC ) {
    if (((xStateIdNode)xSTN)->StateNumber != ASTERISK_STATE)
      PRINTF2("State %s\n", xSTN->Name);

  } else if ( xSTN->EC == xTimerEC ) {
    PRINTF2("Timer %s\n", xSTN->Name);

  } else if ( xSTN->EC == xFormalParEC ) {
    PRINTF3("FPAR %s %s\n", xSTN->Name, ((xVarIdNode)xSTN)->TypeNode->Name);

  } else if ( xSTN->EC == xLiteralEC ) {
    PRINTF2("Literal %s\n", xSTN->Name);

  } else if ( xSTN->EC == xVariableEC ) {
    if (xSTN->Parent->EC == xSortEC ||xSTN->Parent->EC == xSyntypeEC ) {
      if (((xSortIdNode)xSTN->Parent)->TypeInfo->TypeClass == type_SDL_Struct ||
          ((xSortIdNode)xSTN->Parent)->TypeInfo->TypeClass == type_SDL_Choice ||
          ((xSortIdNode)xSTN->Parent)->TypeInfo->TypeClass == type_SDL_Union  ||
          ((xSortIdNode)xSTN->Parent)->TypeInfo->TypeClass == type_SDL_UnionC ) {
        if (((xVarIdNode)xSTN)->Offset == 65535) {
          xPrintString("Bitfield ");
        }
      }
      PRINTF3("Component %s %s\n", xSTN->Name,
                                    ((xVarIdNode)xSTN)->TypeNode->Name);
    }
    else {
      PRINTF3("DCL %s %s\n", xSTN->Name, ((xVarIdNode)xSTN)->TypeNode->Name);
    }

  } else if ( xSTN->EC == xSyntVariableEC ) {
    if (xSTN->Parent->EC == xSortEC) {
      if (((xSortIdNode)xSTN->Parent)->TypeInfo->TypeClass == type_SDL_Struct ) {
        PRINTF3("Synt component %s %s\n", xSTN->Name,
                ((xVarIdNode)xSTN)->TypeNode->Name);
      }
    }
    else {
      PRINTF3("Synt variable %s %s\n", xSTN->Name,
              ((xVarIdNode)xSTN)->TypeNode->Name);
    }

  } else if ( xSTN->EC == xBlocksubstEC ) {
    PRINTF2("Substructure %s\n", xSTN->Name);

  } else if ( xSTN->EC == xProcedureEC ) {
    PRINTF2("Procedure %s\n", xSTN->Name);

  } else if ( xSTN->EC == xCompoundStmtEC) {
    PRINTF("Compound statement\n");

  } else if ( xSTN->EC == xOperatorEC ) {
    PRINTF2("Operator %s\n", xSTN->Name);

  } else if ( xSTN->EC == xPackageEC ) {
    PRINTF2("Package %s\n", xSTN->Name);

  } else if ( xSTN->EC == xProcessEC ) {
    if ( ((xPrsIdNode)xSTN)->Super == (xPrsIdNode)0) {
      PRINTF2("Process %s\n", xSTN->Name);
    } else {
      PRINTF3("Process %s instance of %s\n", xSTN->Name,
               ((xPrsIdNode)xSTN)->Super->Name);
    }

  } else if ( xSTN->EC == xProcessTypeEC ) {
    if ( ((xPrsIdNode)xSTN)->Super == (xPrsIdNode)0) {
      PRINTF2("Process type %s\n", xSTN->Name);
    } else {
      PRINTF3("Process type %s inherits %s\n", xSTN->Name,
               ((xPrsIdNode)xSTN)->Super->Name);
    }

#ifndef XNOUSEOFSERVICE
  } else if ( xSTN->EC == xServiceEC ) {
    if ( ((xSrvIdNode)xSTN)->Super == (xSrvIdNode)0) {
      PRINTF2("Service %s\n", xSTN->Name);
    } else {
      PRINTF3("Service %s instance of %s\n", xSTN->Name,
               ((xSrvIdNode)xSTN)->Super->Name);
    }

  } else if ( xSTN->EC == xServiceTypeEC ) {
    if ( ((xSrvIdNode)xSTN)->Super == (xSrvIdNode)0) {
      PRINTF2("Service type %s\n", xSTN->Name);
    } else {
      PRINTF3("Service type %s inherits %s\n", xSTN->Name,
               ((xSrvIdNode)xSTN)->Super->Name);
    }
#endif

  } else if ( xSTN->EC == xSignalEC || xSTN->EC == xRPCSignalEC ) {
    PRINTF2("Signal %s\n", xSTN->Name);

  } else if ( xSTN->EC == xStartUpSignalEC ) {
    /* startup signal, do nothing */

  } else if ( xSTN->EC == xSignalParEC ) {
    PRINTF2( "SignalParameter (%s)\n", ((xVarIdNode)xSTN)->TypeNode->Name);

  } else if ( xSTN->EC == xSortEC ) {
    SortNode = ((xSortIdNode)xSTN)->TypeInfo;
    if (SortNode->TypeClass == type_SDL_Integer ||
        SortNode->TypeClass == type_SDL_Real ||
        SortNode->TypeClass == type_SDL_Natural ||
        SortNode->TypeClass == type_SDL_Boolean ||
        SortNode->TypeClass == type_SDL_Character ||
        SortNode->TypeClass == type_SDL_Time ||
        SortNode->TypeClass == type_SDL_Duration ||
        SortNode->TypeClass == type_SDL_Pid ||
        SortNode->TypeClass == type_SDL_Charstring ||
        SortNode->TypeClass == type_SDL_Bit ||
        SortNode->TypeClass == type_SDL_Bit_string ||
        SortNode->TypeClass == type_SDL_Octet ||
        SortNode->TypeClass == type_SDL_Octet_string ||
        SortNode->TypeClass == type_SDL_IA5String ||
        SortNode->TypeClass == type_SDL_NumericString ||
        SortNode->TypeClass == type_SDL_PrintableString ||
        SortNode->TypeClass == type_SDL_VisibleString ||
        SortNode->TypeClass == type_SDL_NULL ||
        SortNode->TypeClass == type_SDL_Object_identifier) {
      PRINTF2("Sort %s xPredef\n", SortNode->Name);

    } else if ( SortNode->TypeClass == type_SDL_Userdef ) {
      PRINTF2("Sort %s xUserdef\n", SortNode->Name);

    } else if ( SortNode->TypeClass == type_SDL_Enum ) {
      PRINTF2("Sort %s xEnum\n", SortNode->Name);

    } else if ( SortNode->TypeClass == type_SDL_EmptyType ) {
      PRINTF2("Sort %s xEmptyType\n", SortNode->Name);

    } else if ( SortNode->TypeClass == type_SDL_ChoicePresent ) {
      PRINTF2("Sort %s xChoicePresent\n", SortNode->Name);

    } else if ( SortNode->TypeClass == type_SDL_Struct ) {
      PRINTF2("Sort %s xStruct\n", SortNode->Name);

    } else if ( SortNode->TypeClass == type_SDL_Choice ) {
      PRINTF2("Sort %s xChoice\n", SortNode->Name);

    } else if ( SortNode->TypeClass == type_SDL_Union ) {
      PRINTF2("Sort %s xUnion\n", SortNode->Name);

    } else if ( SortNode->TypeClass == type_SDL_UnionC ) {
      PRINTF2("Sort %s xUnionC\n", SortNode->Name);

    } else if ( SortNode->TypeClass == type_SDL_Array ) {
      PRINTF4("Sort %s Array (%s, %s)\n",
              SortNode->Name,
              ((tSDLArrayInfo *)SortNode)->IndexSort->Name,
              ((tSDLArrayInfo *)SortNode)->CompSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_Carray ) {
      PRINTF4("Sort %s Carray (%d, %s)\n",
              SortNode->Name,
              ((tSDLArrayInfo *)SortNode)->Length,
              ((tSDLArrayInfo *)SortNode)->CompSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_ComBuf ) {
      PRINTF3("Sort %s ComBuf (%d)\n",
              SortNode->Name,
              ((tSDLArrayInfo *)SortNode)->Length);

    } else if ( SortNode->TypeClass == type_SDL_GArray ) {
      PRINTF4("Sort %s Array (%s, %s)\n",
              SortNode->Name,
              ((tSDLGArrayInfo *)SortNode)->IndexSort->Name,
              ((tSDLGArrayInfo *)SortNode)->CompSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_String ) {
      PRINTF3("Sort %s String (%s, ...)\n",
              SortNode->Name,
              ((tSDLGenListInfo *)SortNode)->CompSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_LString ) {
      PRINTF4("Sort %s LString (%s, ...) size=%d\n",
              SortNode->Name,
              ((tSDLLStringInfo *)SortNode)->CompSort->Name,
              ((tSDLLStringInfo *)SortNode)->MaxLength);

    } else if ( SortNode->TypeClass == type_SDL_Powerset ) {
      PRINTF3("Sort %s PowerSet (%s)\n",
              SortNode->Name,
              ((tSDLPowersetInfo *)SortNode)->CompSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_GPowerset ) {
      PRINTF3("Sort %s PowerSet (%s)\n",
              SortNode->Name,
              ((tSDLGenListInfo *)SortNode)->CompSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_Bag ) {
      PRINTF3("Sort %s Bag (%s)\n",
              SortNode->Name,
              ((tSDLGenListInfo *)SortNode)->CompSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_Ref ) {
      PRINTF3("Sort %s Ref (%s)\n",
              SortNode->Name,
              ((tSDLGenInfo *)SortNode)->CompOrFatherSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_Own ) {
      PRINTF3("Sort %s Own (%s)\n",
              SortNode->Name,
              ((tSDLGenInfo *)SortNode)->CompOrFatherSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_Oref ) {
      PRINTF3("Sort %s Oref (%s)\n",
              SortNode->Name,
              ((tSDLGenInfo *)SortNode)->CompOrFatherSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_Inherits ) {
      PRINTF3("Sort %s Inherits %s\n",
              SortNode->Name,
              ((tSDLGenInfo *)SortNode)->CompOrFatherSort->Name);

    } else if ( SortNode->TypeClass == type_SDL_Syntype ) {
      PRINTF3("Sort %s Syntype = %s\n",
              SortNode->Name,
              ((tSDLGenInfo *)SortNode)->CompOrFatherSort->Name);
    }
    else {
      PRINTF2("Sort %s\n", SortNode->Name);
    }

  } else if ( xSTN->EC == xSyntypeEC ) {
    PRINTF2("xSyntypeEC - %s\n", xSTN->Name);

  } else if ( xSTN->EC == xSystemEC) {
    if (xSTN != xSymbolTableRoot) {
      PRINTF2("System %s\n", xSTN->Name);
    }

  } else if ( xSTN->EC == xSystemTypeEC ) {
    PRINTF2("System type %s\n", xSTN->Name);

  } else if ( xSTN->EC == xBlockEC ) {
    if ( ((xBlockIdNode)xSTN)->Super == (xBlockIdNode)0) {
      PRINTF2("Block %s\n", xSTN->Name);
    } else {
      PRINTF3("Block %s instance of %s\n", xSTN->Name,
               ((xBlockIdNode)xSTN)->Super->Name);
    }

  } else if ( xSTN->EC == xBlockTypeEC ) {
    if ( ((xBlockIdNode)xSTN)->Super == (xBlockIdNode)0) {
      PRINTF2("Block type %s\n", xSTN->Name);
    } else {
      PRINTF3("Block type %s inherits %s\n", xSTN->Name,
               ((xBlockIdNode)xSTN)->Super->Name);
    }

  } else if ( xSTN->EC == xChannelEC ) {
    PRINTF2("Channel %s\n", xSTN->Name);
    xSTN = xSTN->Suc;                      /* Skip reverse */

  } else if ( xSTN->EC == xSignalrouteEC ) {
    PRINTF2("Signalroute %s\n", xSTN->Name);
    xSTN = xSTN->Suc;                      /* Skip reverse */

  } else if ( xSTN->EC == xGateEC ) {
    PRINTF2("Gate %s\n", xSTN->Name);
    xSTN = xSTN->Suc;                      /* Skip reverse */

  } else if (xSTN->EC == xRemoteVarEC) {
    PRINTF2("Remote variable %s\n", xSTN->Name);

  } else if (xSTN->EC == xRemotePrdEC) {
    PRINTF2("Remote procedure %s\n", xSTN->Name);

#ifdef XUSESYNONYMIDNODES
  } else if (xSTN->EC == xSynonymEC) {
    PRINTF2("Synonym %s\n", xSTN->Name);
#endif

  } else {
    xPrintString("QUE?\n");
  }

  xSymbolTable(xSTN->First, xLvl+1);
  xSymbolTable(xSTN->Suc, xLvl);
}


/*---+---------------------------------------------------------------
     xPrintChannelLevel
-------------------------------------------------------------------*/
static void xPrintChannelLevel (xIdNode Node, int Level)
{
  PRINTF2("\n%d ", Level);
  if (Level > 0) PRINTF3("%*c", Level*2, ' ');
  PRINTF2("%s", Node->Name);
  if (Node->EC == xChannelEC || Node->EC == xSignalrouteEC ||
      Node->EC == xGateEC)
    if ((xIdNode)((xChannelIdNode)Node)->Reverse != Node->Suc)
      xPrintString("'");
  if (Node->EC == xProcessEC)
    xPrintString(" Process");
  else if (Node->EC == xSystemEC)
    xPrintString(" System");
  else if (Node->EC == xBlockEC)
    xPrintString(" Block");
  else if (Node->EC == xChannelEC)
    xPrintString(" Channel");
  else if (Node->EC == xSignalrouteEC)
    xPrintString(" Signalroute");
  else if (Node->EC == xGateEC)  
    xPrintString(" Gate");
}


/*---+---------------------------------------------------------------
     xPrintChannel
-------------------------------------------------------------------*/
void xPrintChannel (xIdNode Node, int Level)
{
  xIdNode        Next;
  xChannelIdNode ChId;
  int            Index;

  if (Node->EC == xSystemEC && Node != xSymbolTableRoot) {
    xPrintChannelLevel(Node, Level);

  } else if (Node->EC == xBlockEC) {
    xPrintChannelLevel(Node, Level);

  } else if (Node->EC == xProcessEC) {
    xPrintChannelLevel(Node, Level);
    xPrintString(" :");
    if (((xPrsIdNode)Node)->ToId != (xIdNode *)0) {
      for (Index=0; ((xPrsIdNode)Node)->ToId[Index] != (xIdNode)0; Index++) {
        if ( ((xPrsIdNode)Node)->ToId[Index]->EC == xChannelEC ||
             ((xPrsIdNode)Node)->ToId[Index]->EC == xSignalrouteEC ||
             ((xPrsIdNode)Node)->ToId[Index]->EC == xGateEC ) {
          ChId = (xChannelIdNode)((xPrsIdNode)Node)->ToId[Index];
          if (((xPrsIdNode)Node)->ToId[Index]->EC == xGateEC) {
            PRINTF3(" %s:%s", ChId->Parent->Name, ChId->Name);
          } else {
            PRINTF2(" %s", ChId->Name);
          }
          if (ChId->Suc != (xIdNode)ChId->Reverse) xPrintString("'");
        } else
          PRINTF2(" %s", ((xPrsIdNode)Node)->ToId[Index]->Name);
      }
    }
    xPrintString("   SIGNALSET :");
    if (((xPrsIdNode)Node)->SignalSet != (xSignalIdNode *)0) {
      for (Index=0;
           ((xPrsIdNode)Node)->SignalSet[Index] != (xSignalIdNode)0;
           Index++)
        PRINTF2(" %s", ((xPrsIdNode)Node)->SignalSet[Index]->Name);
    }

#ifndef XNOUSEOFSERVICE
  } else if (Node->EC == xServiceEC) {
    xPrintChannelLevel(Node, Level);
    xPrintString(" :");
    if (((xSrvIdNode)Node)->ToId != (xIdNode *)0) {
      for (Index=0; ((xSrvIdNode)Node)->ToId[Index] != (xIdNode)0; Index++) {
        if ( ((xSrvIdNode)Node)->ToId[Index]->EC == xChannelEC ||
             ((xSrvIdNode)Node)->ToId[Index]->EC == xSignalrouteEC ||
             ((xSrvIdNode)Node)->ToId[Index]->EC == xGateEC ) {
          ChId = (xChannelIdNode)((xSrvIdNode)Node)->ToId[Index];
          if (((xSrvIdNode)Node)->ToId[Index]->EC == xGateEC) {
            PRINTF3(" %s:%s", ChId->Parent->Name, ChId->Name);
          } else {
            PRINTF2(" %s", ChId->Name);
          }
          if (ChId->Suc != (xIdNode)ChId->Reverse) xPrintString("'");
        } else
          PRINTF2(" %s", ((xSrvIdNode)Node)->ToId[Index]->Name);
      }
    }
    xPrintString("   SIGNALSET :");
    if (((xSrvIdNode)Node)->SignalSet != (xSignalIdNode *)0) {
      for (Index=0;
           ((xSrvIdNode)Node)->SignalSet[Index] != (xSignalIdNode)0;
           Index++)
        PRINTF2(" %s", ((xSrvIdNode)Node)->SignalSet[Index]->Name);
    }
#endif

  } else if (Node->EC == xChannelEC || Node->EC == xSignalrouteEC ||
             Node->EC == xGateEC) {
    xPrintChannelLevel(Node, Level);
    xPrintString(" :");
    if (((xChannelIdNode)Node)->ToId != (xIdNode *)0) {
      for (Index=0; ((xChannelIdNode)Node)->ToId[Index] != (xIdNode)0; Index++) {
        if ( ((xChannelIdNode)Node)->ToId[Index]->EC == xChannelEC ||
             ((xChannelIdNode)Node)->ToId[Index]->EC == xSignalrouteEC ||
             ((xChannelIdNode)Node)->ToId[Index]->EC == xGateEC ) {
          ChId = (xChannelIdNode)((xChannelIdNode)Node)->ToId[Index];
          if (((xChannelIdNode)Node)->ToId[Index]->EC == xGateEC) {
            PRINTF3(" %s:%s", ChId->Parent->Name, ChId->Name);
          } else {
            PRINTF2(" %s", ChId->Name);
          }
          if (ChId->Suc != (xIdNode)ChId->Reverse) xPrintString("'");
        } else
          PRINTF2(" %s", ((xChannelIdNode)Node)->ToId[Index]->Name);
      }
    }
    xPrintString("   WITH :");
    if (((xChannelIdNode)Node)->SignalSet != (xSignalIdNode *)0 &&
        ((xChannelIdNode)Node)->SignalSet[0] != (xSignalIdNode)0) {
      for (Index=0;
           ((xChannelIdNode)Node)->SignalSet[Index] != (xSignalIdNode)0;
           Index++)
        PRINTF2(" %s", ((xChannelIdNode)Node)->SignalSet[Index]->Name);
    }
  }
  for (Next=Node->First; Next != (xIdNode)0; Next=Next->Suc)
    xPrintChannel(Next, Level+1);
}


/*---+---------------------------------------------------------------
       Types and Global Variables TEST COVERAGE
-------------------------------------------------------------------*/
#ifdef XVALIDATOR_LIB
#ifdef XCOVERAGE
static long int  SystemTransNo, SystemSymbNo;
#endif
#endif

/*---+---------------------------------------------------------------
     xAddAllCovearageInfo
-------------------------------------------------------------------*/
#ifdef XCOVERAGE
static void xAddAllCovearageInfo
  (xIdNode PrsId, long int *TransNo, long int *SymbNo)
{
  xIdNode Temp, ProcessId;
  int     i;
  xSymbolType  SymbolType;

  ProcessId = PrsId;
  while (ProcessId != (xIdNode)0 && 
         ProcessId->EC != xProcessEC && ProcessId->EC != xProcessTypeEC && 
         ProcessId->EC != xServiceEC && ProcessId->EC != xServiceTypeEC)
    ProcessId = ProcessId->Parent;

  if (PrsId->EC == xProcessEC || PrsId->EC == xProcessTypeEC) {
    for (i=0; i<=((xPrsIdNode)PrsId)->MaxSymbolNumber; i++) {
      (void)((xPrsIdNode)PrsId)->GRrefFunc(i, &SymbolType);
      if (SymbolType != xsAssignment2Statement &&
          SymbolType != xsValueReturningProcedureCall &&
          SymbolType != xsValueReturningRPC &&
          SymbolType != xspCALLInput &&
          SymbolType != xspCALLProcedureCall &&
          SymbolType != xspREPLYOutput &&
          SymbolType != xspCALLNextstate &&
          SymbolType != xspREPLYInput &&
          SymbolType != xsLoopTest &&
          SymbolType != xsLoopUpdate &&
          SymbolType != xsLabel) {
        *SymbNo += ((xPrsIdNode)PrsId)->CoverageArray[i];
      }
    }
#ifndef XNOUSEOFSERVICE
  } else if (PrsId->EC == xServiceEC || PrsId->EC == xServiceTypeEC) {
    for (i=0; i<=((xSrvIdNode)PrsId)->MaxSymbolNumber; i++) {
      (void)((xSrvIdNode)PrsId)->GRrefFunc(i, &SymbolType);
      if (SymbolType != xsAssignment2Statement &&
          SymbolType != xsValueReturningProcedureCall &&
          SymbolType != xsValueReturningRPC &&
          SymbolType != xspCALLInput &&
          SymbolType != xspCALLProcedureCall &&
          SymbolType != xspREPLYOutput &&
          SymbolType != xspCALLNextstate &&
          SymbolType != xspREPLYInput &&
          SymbolType != xsLoopTest &&
          SymbolType != xsLoopUpdate &&
          SymbolType != xsLabel) {
        *SymbNo += ((xSrvIdNode)PrsId)->CoverageArray[i];
      }
    }
#endif
  } else if (PrsId->EC == xProcedureEC) {
    for (i=0; i<=((xPrdIdNode)PrsId)->MaxSymbolNumber; i++) {
      (void)((xPrdIdNode)PrsId)->GRrefFunc(i, &SymbolType);
      if (SymbolType != xsAssignment2Statement &&
          SymbolType != xsValueReturningProcedureCall &&
          SymbolType != xsValueReturningRPC &&
          SymbolType != xspCALLInput &&
          SymbolType != xspCALLProcedureCall &&
          SymbolType != xspREPLYOutput &&
          SymbolType != xspCALLNextstate &&
          SymbolType != xspREPLYInput &&
          SymbolType != xsLoopTest &&
          SymbolType != xsLoopUpdate &&
          SymbolType != xsLabel) {
        *SymbNo += ((xPrdIdNode)PrsId)->CoverageArray[i];
      }
    }
  }

  if (PrsId->EC == xProcessEC || PrsId->EC == xProcessTypeEC)
    *TransNo += ((xPrsIdNode)PrsId)->NoOfStartTransitions;
#ifndef XNOUSEOFSERVICE
  if (PrsId->EC == xServiceEC || PrsId->EC == xServiceTypeEC)
    *TransNo += ((xSrvIdNode)PrsId)->NoOfStartTransitions;
#endif
  for (Temp=PrsId->First; Temp!=(xIdNode)0; Temp=Temp->Suc) {
    if (Temp->EC == xStateEC) {
      if (ProcessId != (xIdNode)0) {    /* not global procedure */
        if (ProcessId->EC == xProcessEC || ProcessId->EC == xProcessTypeEC) {
          for (i=0; i<=((xPrsIdNode)ProcessId)->SignalSetLength; i++)
            *TransNo += ((xStateIdNode)Temp)->CoverageArray[i];
#ifndef XNOUSEOFSERVICE
        } else {  /* Service */
          for (i=0; i<=((xSrvIdNode)ProcessId)->SignalSetLength; i++)
            *TransNo += ((xStateIdNode)Temp)->CoverageArray[i];
#endif
        }
      }
    } else if (
       Temp->EC == xSystemEC ||
       Temp->EC == xSystemTypeEC ||
       Temp->EC == xPackageEC ||
       Temp->EC == xBlockEC ||
       Temp->EC == xBlockTypeEC ||
       Temp->EC == xBlocksubstEC ||
       (Temp->EC == xProcessEC &&
         ((xPrsIdNode)Temp)->Super == (xPrsIdNode)0 &&
         Temp != (xIdNode)xEnvId) ||
       Temp->EC == xProcessTypeEC ||
#ifndef XNOUSEOFSERVICE
       (Temp->EC == xServiceEC &&
         ((xSrvIdNode)Temp)->Super == (xSrvIdNode)0) ||
       Temp->EC == xServiceTypeEC ||
#endif
       Temp->EC == xProcedureEC ||
       Temp->EC == xOperatorEC ) {
      xAddAllCovearageInfo(Temp, TransNo, SymbNo);
    }
  }
}
#endif


/*---+---------------------------------------------------------------
     xPrintCoverageArray
-------------------------------------------------------------------*/
#ifdef XCOVERAGE
void xPrintCoverageArray (xIdNode PrsId, int Level, int PassNo)
{
  int       i;
  long int  TransNo, SymbNo;
  xIdNode   Temp, ProcessId;
  xSymbolType  SymbolType;
  char    * SDTrefString;

  if (PrsId != xSymbolTableRoot) {
    if ((PrsId->EC == xProcessEC && ((xPrsIdNode)PrsId)->Super == (xPrsIdNode)0) ||
        PrsId->EC == xProcessTypeEC) {

      if (PassNo == 1) {
        if (PrsId->EC == xProcessTypeEC)
          fprintf(XSYSD xCoverageFile,
                  "\n%d  Process type %s : ", Level, PrsId->Name);
        else
          fprintf(XSYSD xCoverageFile,
                  "\n%d  Process %s : ", Level, PrsId->Name);
#ifndef XNOUSEOFSERVICE
        if  (((xPrsIdNode)PrsId)->Contents == (xIdNode *)0 ||
             ((xPrsIdNode)PrsId)->Contents[0] == (xIdNode)0 ||
             ((xPrsIdNode)PrsId)->Contents[0]->EC != xServiceEC ) {
#endif
          TransNo = 0; SymbNo = 0;
          xAddAllCovearageInfo(PrsId, &TransNo, &SymbNo);
          fprintf(XSYSD xCoverageFile,  "Transitions = %ld", TransNo);
          if (XSYSD SystemTransNo > 0)
            fprintf(XSYSD xCoverageFile, " (%ld%%)",
                                         (100*TransNo)/XSYSD SystemTransNo);
          fprintf(XSYSD xCoverageFile, ", Symbols = %ld", SymbNo);
          if (XSYSD SystemSymbNo > 0)
            fprintf(XSYSD xCoverageFile, " (%ld%%)",
                                         (100*SymbNo)/XSYSD SystemSymbNo);
          fprintf(XSYSD xCoverageFile, ", ");
#ifndef XNOUSEOFSERVICE
        }
#endif
        fprintf(XSYSD xCoverageFile, "MaxQ = %ld\n",
                                       ((xPrsIdNode)PrsId)->MaxQueueLength);
      } else {
        if (PrsId->EC == xProcessTypeEC)
          fprintf(XSYSD xCoverageFile, "\n%d  Process type %s\n",
                 Level, PrsId->Name);
        else
          fprintf(XSYSD xCoverageFile, "\n%d  Process %s\n",
                  Level, PrsId->Name);
#ifndef XNOUSEOFSERVICE
        if  (((xPrsIdNode)PrsId)->Contents == (xIdNode *)0 ||
             ((xPrsIdNode)PrsId)->Contents[0] == (xIdNode)0 ||
             ((xPrsIdNode)PrsId)->Contents[0]->EC != xServiceEC ) {
#endif
          if (((xPrsIdNode)PrsId)->StateList[START_STATE] != (xStateIdNode)0)
            fprintf(XSYSD xCoverageFile, "    %ld : Start  %s\n",
                    ((xPrsIdNode)PrsId)->NoOfStartTransitions,
                    ((xPrsIdNode)PrsId)->GRrefFunc(0, &SymbolType));
          for (Temp=PrsId->First; Temp!=(xIdNode)0; Temp=Temp->Suc) {
            if (Temp->EC == xStateEC) {
              for (i=0; i<((xPrsIdNode)PrsId)->SignalSetLength; i++) {
                if (((xStateIdNode)Temp)->SignalHandlArray[i] == xInput ||
                    ((xStateIdNode)Temp)->SignalHandlArray[i] == xPrioInput ||
                    ((xStateIdNode)Temp)->SignalHandlArray[i] == xEnablCond) {
                  fprintf(XSYSD xCoverageFile, "    %ld : ",
                          ((xStateIdNode)Temp)->CoverageArray[i] );
                  fprintf(XSYSD xCoverageFile, "%s  %s  %s\n", Temp->Name,
                         ((xPrsIdNode)PrsId)->SignalSet[i]->Name,
                         ((xPrsIdNode)PrsId)->GRrefFunc(
                              (((xStateIdNode)Temp)->InputRef)[i], &SymbolType));
                }
              }
              if (((xStateIdNode)Temp)->ContSig_Function != 0) {
                fprintf(XSYSD xCoverageFile, "    %ld : ",
                  ((xStateIdNode)Temp)->CoverageArray
                                        [((xPrsIdNode)PrsId)->SignalSetLength]);
                fprintf(XSYSD xCoverageFile, "%s  Continuous signal\n",
                        Temp->Name);
              }
            }
          }
          fprintf(XSYSD xCoverageFile, "    --------------------\n");

          if (((xPrsIdNode)PrsId)->StateList[START_STATE] != (xStateIdNode)0)
            i = 0;
          else
            i = 1;
          for ( ; i<=((xPrsIdNode)PrsId)->MaxSymbolNumber; i++) {
            SDTrefString = ((xPrsIdNode)PrsId)->GRrefFunc(i, &SymbolType);
            if (SymbolType != xsAssignment2Statement &&
                SymbolType != xsValueReturningProcedureCall &&
                SymbolType != xsValueReturningRPC &&
                SymbolType != xspCALLInput &&
                SymbolType != xspCALLProcedureCall &&
                SymbolType != xspREPLYOutput &&
                SymbolType != xspCALLNextstate &&
                SymbolType != xspREPLYInput &&
                SymbolType != xsLoopTest &&
                SymbolType != xsLoopUpdate &&
                SymbolType != xsLabel) {
              fprintf(XSYSD xCoverageFile, "    %ld %s : %s\n",
                ((xPrsIdNode)PrsId)->CoverageArray[i],
                xSymbolTypeStr[SymbolType],
                SDTrefString );
            }
          }
#ifndef XNOUSEOFSERVICE
        }
#endif
      }

#ifndef XNOUSEOFSERVICE
    } else if ((PrsId->EC == xServiceEC && ((xSrvIdNode)PrsId)->Super == (xSrvIdNode)0) ||
        PrsId->EC == xServiceTypeEC) {

      if (PassNo == 1) {
        TransNo = 0; SymbNo = 0;
        xAddAllCovearageInfo(PrsId, &TransNo, &SymbNo);
        if (PrsId->EC == xServiceTypeEC)
          fprintf(XSYSD xCoverageFile,
                  "\n%d  Service type %s : Transitions = %ld",
                  Level, PrsId->Name, TransNo);
        else
          fprintf(XSYSD xCoverageFile,
                  "\n%d  Service %s : Transitions = %ld",
                Level, PrsId->Name, TransNo);
        if (XSYSD SystemTransNo > 0)
          fprintf(XSYSD xCoverageFile, " (%ld%%)",
                                       (100*TransNo)/XSYSD SystemTransNo);
        fprintf(XSYSD xCoverageFile, ", Symbols = %ld", SymbNo);
        if (XSYSD SystemSymbNo > 0)
          fprintf(XSYSD xCoverageFile, " (%ld%%)",
                                       (100*SymbNo)/XSYSD SystemSymbNo);
        fprintf(XSYSD xCoverageFile, "\n");
      } else {
        if (PrsId->EC == xServiceTypeEC)
          fprintf(XSYSD xCoverageFile, "\n%d  Service type %s\n",
                 Level, PrsId->Name);
        else
          fprintf(XSYSD xCoverageFile, "\n%d  Service %s\n",
                  Level, PrsId->Name);
        if (((xSrvIdNode)PrsId)->StateList[START_STATE] != (xStateIdNode)0)
          fprintf(XSYSD xCoverageFile, "    %ld : Start  %s\n",
                  ((xSrvIdNode)PrsId)->NoOfStartTransitions,
                  ((xSrvIdNode)PrsId)->GRrefFunc(0, &SymbolType));
        for (Temp=PrsId->First; Temp!=(xIdNode)0; Temp=Temp->Suc) {
          if (Temp->EC == xStateEC) {
            for (i=0; i<((xSrvIdNode)PrsId)->SignalSetLength; i++) {
              if (((xStateIdNode)Temp)->SignalHandlArray[i] == xInput ||
                  ((xStateIdNode)Temp)->SignalHandlArray[i] == xPrioInput ||
                  ((xStateIdNode)Temp)->SignalHandlArray[i] == xEnablCond) {
                fprintf(XSYSD xCoverageFile, "    %ld : ",
                        ((xStateIdNode)Temp)->CoverageArray[i] );
                fprintf(XSYSD xCoverageFile, "%s  %s  %s\n", Temp->Name,
                       ((xSrvIdNode)PrsId)->SignalSet[i]->Name,
                       ((xSrvIdNode)PrsId)->GRrefFunc(
                            (((xStateIdNode)Temp)->InputRef)[i], &SymbolType));
              }
            }
            if (((xStateIdNode)Temp)->ContSig_Function != 0) {
              fprintf(XSYSD xCoverageFile, "    %ld : ",
                ((xStateIdNode)Temp)->CoverageArray
                                      [((xSrvIdNode)PrsId)->SignalSetLength]);
              fprintf(XSYSD xCoverageFile, "%s  Continuous signal\n",
                      Temp->Name);
            }
          }
        }
        fprintf(XSYSD xCoverageFile, "    --------------------\n");

        if (((xSrvIdNode)PrsId)->StateList[START_STATE] != (xStateIdNode)0)
          i = 0;
        else
          i = 1;
        for ( ; i<=((xSrvIdNode)PrsId)->MaxSymbolNumber; i++) {
          SDTrefString = ((xSrvIdNode)PrsId)->GRrefFunc(i, &SymbolType);
          if (SymbolType != xsAssignment2Statement &&
              SymbolType != xsValueReturningProcedureCall &&
              SymbolType != xsValueReturningRPC &&
              SymbolType != xspCALLInput &&
              SymbolType != xspCALLProcedureCall &&
              SymbolType != xspREPLYOutput &&
              SymbolType != xspCALLNextstate &&
              SymbolType != xspREPLYInput &&
              SymbolType != xsLoopTest &&
              SymbolType != xsLoopUpdate &&
              SymbolType != xsLabel) {
            fprintf(XSYSD xCoverageFile, "    %ld %s : %s\n",
              ((xSrvIdNode)PrsId)->CoverageArray[i],
              xSymbolTypeStr[SymbolType],
              SDTrefString );
          }
        }
      }
#endif

    } else if (PrsId->EC == xProcedureEC || PrsId->EC == xOperatorEC) {
      if (PassNo == 2) {
        if (PrsId->EC == xProcedureEC)
          fprintf(XSYSD xCoverageFile, "\n%d  Procedure %s\n", Level, PrsId->Name);
        else
          fprintf(XSYSD xCoverageFile, "\n%d  Operator %s\n", Level, PrsId->Name);

        ProcessId = PrsId->Parent;
        while (ProcessId != (xIdNode)0 &&
               ProcessId->EC != xProcessEC && ProcessId->EC != xProcessTypeEC)
          ProcessId = ProcessId->Parent;
        if (PrsId->EC == xProcedureEC && ProcessId != (xIdNode)0) {
              /* not operator, not global procedure */
          if (((xPrdIdNode)PrsId)->StateList[START_STATE] != (xStateIdNode)0)
            fprintf(XSYSD xCoverageFile, "    %ld : Start  %s\n",
                    ((xPrdIdNode)PrsId)->CoverageArray[0],
                    ((xPrdIdNode)PrsId)->GRrefFunc(0, &SymbolType));

          for (Temp=PrsId->First; Temp!=(xIdNode)0; Temp=Temp->Suc) {
            if (Temp->EC == xStateEC) {
              for (i=0; i<((xPrsIdNode)ProcessId)->SignalSetLength; i++) {
                if (((xStateIdNode)Temp)->SignalHandlArray[i] == xInput ||
                    ((xStateIdNode)Temp)->SignalHandlArray[i] == xPrioInput ||
                    ((xStateIdNode)Temp)->SignalHandlArray[i] == xEnablCond) {
                  fprintf(XSYSD xCoverageFile, "    %ld : ",
                          ((xStateIdNode)Temp)->CoverageArray[i] );
                  fprintf(XSYSD xCoverageFile, "%s  %s  %s\n", Temp->Name,
                      ((xPrsIdNode)ProcessId)->SignalSet[i]->Name,
                      ((xPrdIdNode)PrsId)->GRrefFunc(
                            (((xStateIdNode)Temp)->InputRef)[i], &SymbolType));
                }
              }
              if (((xStateIdNode)Temp)->ContSig_Function != 0) {
                fprintf(XSYSD xCoverageFile, "    %ld : ",
                        ((xStateIdNode)Temp)->CoverageArray
                          [((xPrsIdNode)ProcessId)->SignalSetLength] );
                fprintf(XSYSD xCoverageFile, "%s  Continuous signal\n",
                        Temp->Name);
              }
            }
          }
        } else if (PrsId->EC == xOperatorEC) {
          fprintf(XSYSD xCoverageFile, "    %ld : Start  %s\n",
                  ((xPrdIdNode)PrsId)->CoverageArray[0],
                  ((xPrdIdNode)PrsId)->GRrefFunc(0, &SymbolType));
        }
        fprintf(XSYSD xCoverageFile, "    --------------------\n");

        if (((xPrdIdNode)PrsId)->StateList[START_STATE_PRD] != (xStateIdNode)0)
          i = 0;
        else
          i = 1;
        for ( ; i<=((xPrdIdNode)PrsId)->MaxSymbolNumber; i++) {
          SDTrefString = ((xPrdIdNode)PrsId)->GRrefFunc(i, &SymbolType);
          if (SymbolType != xsAssignment2Statement &&
              SymbolType != xsValueReturningProcedureCall &&
              SymbolType != xsValueReturningRPC &&
              SymbolType != xspCALLInput &&
              SymbolType != xspCALLProcedureCall &&
              SymbolType != xspREPLYOutput &&
              SymbolType != xspCALLNextstate &&
              SymbolType != xspREPLYInput &&
              SymbolType != xsLoopTest &&
              SymbolType != xsLoopUpdate &&
              SymbolType != xsLabel) {
            fprintf(XSYSD xCoverageFile, "    %ld %s : %s\n",
              ((xPrdIdNode)PrsId)->CoverageArray[i],
              xSymbolTypeStr[SymbolType],
              SDTrefString );
          }
        }
      }

    } else if (PrsId->EC == xSystemEC) {
      if (PassNo == 1) {
        fprintf(XSYSD xCoverageFile,
          "******************* PROFILING INFORMATION ******************\n");
        XSYSD SystemTransNo = 0; XSYSD SystemSymbNo = 0;
        xAddAllCovearageInfo(PrsId->Parent, &XSYSD SystemTransNo,
                             &XSYSD SystemSymbNo);
        fprintf(XSYSD xCoverageFile, "\n%d  System %s : Transitions = %ld",
          Level, PrsId->Name, XSYSD SystemTransNo);
        fprintf(XSYSD xCoverageFile, ", Symbols = %ld\n", XSYSD SystemSymbNo);
      } else {
        fprintf(XSYSD xCoverageFile,
          "\n\n****************** COVERAGE TABLE DETAILS ******************\n");
        fprintf(XSYSD xCoverageFile, "\n%d  System %s\n", Level, PrsId->Name);
      }
    } else if (PrsId->EC == xSystemTypeEC) {
      fprintf(XSYSD xCoverageFile, "\n%d  System type %s\n", Level, PrsId->Name);
    } else if (PrsId->EC == xPackageEC) {
      fprintf(XSYSD xCoverageFile, "\n%d  Package %s\n", Level, PrsId->Name);
    } else if (PrsId->EC == xBlockEC &&
               ((xBlockIdNode)PrsId)->Super == (xBlockIdNode)0) {
      fprintf(XSYSD xCoverageFile, "\n%d  Block %s\n", Level, PrsId->Name);
    } else if (PrsId->EC == xBlockTypeEC) {
      fprintf(XSYSD xCoverageFile, "\n%d  Block type %s\n", Level, PrsId->Name);
    } else if (PrsId->EC == xBlocksubstEC) {
      fprintf(XSYSD xCoverageFile, "\n%d  Substructure %s\n", Level, PrsId->Name);
    } else if (PrsId->EC == xSortEC && PassNo == 2) {
      for (Temp = PrsId->First; 
           Temp != (xIdNode)0 && Temp->EC != xOperatorEC;
           Temp = Temp->Suc) ;
      if (Temp != (xIdNode)0)
        fprintf(XSYSD xCoverageFile, "\n%d  Sort %s\n", Level, PrsId->Name);
    }
  }

  for (Temp=PrsId->First; Temp!=(xIdNode)0; Temp=Temp->Suc)
    if (Temp != (xIdNode)xEnvId && Temp != (xIdNode)&yPacR_Predefined)
      xPrintCoverageArray(Temp, Level+1, PassNo);
}
#endif
      /* XCOVERAGE */



/*---+---------------------------------------------------------------
     xCoverageStatistics
-------------------------------------------------------------------*/
/* Computes the number of symbols and the number of executed
symbols for a subtree in the symbol table */
#ifdef XCOVERAGE
void xCoverageStatistics (
  xIdNode Id,
  int    *execSymbs, 
  int    *totalSymbs)
{
  int     i;
  xIdNode Temp;
  xSymbolType  SymbolType;
  
  if ((Id->EC == xProcessEC &&
       ((xPrsIdNode)Id)->Super == (xPrsIdNode)0) ||
      Id->EC == xProcessTypeEC) {
    for (i=0; i<=((xPrsIdNode)Id)->MaxSymbolNumber; i++) {
      (void)((xPrsIdNode)Id)->GRrefFunc(i, &SymbolType);
      if (SymbolType != xsAssignment2Statement &&
          SymbolType != xsValueReturningProcedureCall &&
          SymbolType != xsValueReturningRPC &&
          SymbolType != xspCALLInput &&
          SymbolType != xspCALLProcedureCall &&
          SymbolType != xspREPLYOutput &&
          SymbolType != xspCALLNextstate &&
          SymbolType != xspREPLYInput &&
          SymbolType != xsLoopTest &&
          SymbolType != xsLoopUpdate &&
          SymbolType != xsLabel) {
        (*totalSymbs)++;
        if (((xPrsIdNode)Id)->CoverageArray[i]>0) {
          (*execSymbs)++;
        }
      }
    }
#ifndef XNOUSEOFSERVICE
  } else if ((Id->EC == xServiceEC &&
              ((xSrvIdNode)Id)->Super == (xSrvIdNode)0) ||
             Id->EC == xServiceTypeEC) {
    for (i=0; i<=((xSrvIdNode)Id)->MaxSymbolNumber; i++) {
      (void)((xSrvIdNode)Id)->GRrefFunc(i, &SymbolType);
      if (SymbolType != xsAssignment2Statement &&
          SymbolType != xsValueReturningProcedureCall &&
          SymbolType != xsValueReturningRPC &&
          SymbolType != xspCALLInput &&
          SymbolType != xspCALLProcedureCall &&
          SymbolType != xspREPLYOutput &&
          SymbolType != xspCALLNextstate &&
          SymbolType != xspREPLYInput &&
          SymbolType != xsLoopTest &&
          SymbolType != xsLoopUpdate &&
          SymbolType != xsLabel) {
        (*totalSymbs)++;
        if (((xSrvIdNode)Id)->CoverageArray[i]>0) {
          (*execSymbs)++;
        }
      }
    }
#endif
  } else if (Id->EC == xProcedureEC || Id->EC == xOperatorEC) {
    for (i=0; i<=((xPrdIdNode)Id)->MaxSymbolNumber; i++) {
      (void)((xPrdIdNode)Id)->GRrefFunc(i, &SymbolType);
      if (SymbolType != xsAssignment2Statement &&
          SymbolType != xsValueReturningProcedureCall &&
          SymbolType != xsValueReturningRPC &&
          SymbolType != xspCALLInput &&
          SymbolType != xspCALLProcedureCall &&
          SymbolType != xspREPLYOutput &&
          SymbolType != xspCALLNextstate &&
          SymbolType != xspREPLYInput &&
          SymbolType != xsLoopTest &&
          SymbolType != xsLoopUpdate &&
          SymbolType != xsLabel) {
        (*totalSymbs)++;
        if (((xPrdIdNode)Id)->CoverageArray[i]>0) {
          (*execSymbs)++;
        }
      }
    }
  }
  for (Temp=Id->First; Temp!=(xIdNode)0; Temp=Temp->Suc) {
    if (Temp != (xIdNode)xEnvId)
      xCoverageStatistics(Temp, execSymbs, totalSymbs);
  }
}
#endif
      /* XCOVERAGE */


/*---+---------------------------------------------------------------
     xClearCoverage
-------------------------------------------------------------------*/
#ifdef XCOVERAGE

void xClearCoverage (xIdNode Node)
{
  xStateIdNode statenode;
  xPrsIdNode PrsNode;
  xPrdIdNode PrdNode;
  xIdNode Child;
#ifndef XNOUSEOFSERVICE
  xSrvIdNode SrvNode;
#endif

  if (Node->EC==xSystemEC) {
    XSYSD SystemTransNo = 0;
    XSYSD SystemSymbNo = 0;

  } else if (Node->EC==xProcessEC || Node->EC == xProcessTypeEC) {
    PrsNode = (xPrsIdNode)Node;
    PrsNode->NoOfStartTransitions=0;
    if (PrsNode->MaxSymbolNumber>0) { /* Process ENV has ==-1 */
      memset( (void *)PrsNode->CoverageArray, 0, 
              (PrsNode->MaxSymbolNumber+1)*sizeof(*PrsNode->CoverageArray) );
    }
    for (statenode=(xStateIdNode)PrsNode->First;
         statenode;
         statenode=(xStateIdNode)statenode->Suc) {
      if (statenode->EC==xStateEC) {
        memset( (void *)statenode->CoverageArray, 0, 
               (PrsNode->SignalSetLength+1)*sizeof(*statenode->CoverageArray));
      }
    }

#ifndef XNOUSEOFSERVICE
  } else if (Node->EC == xServiceEC || Node->EC == xServiceTypeEC) {
    SrvNode = (xSrvIdNode)Node;
    SrvNode->NoOfStartTransitions=0;
    if (SrvNode->MaxSymbolNumber>0) {
      memset( (void *)SrvNode->CoverageArray, 0, 
             (SrvNode->MaxSymbolNumber+1)*sizeof(*SrvNode->CoverageArray) );
    }
    for (statenode=(xStateIdNode)SrvNode->First;
         statenode;
         statenode=(xStateIdNode)statenode->Suc) {
      if (statenode->EC==xStateEC) {
        memset( (void *)statenode->CoverageArray, 0, 
               (SrvNode->SignalSetLength+1)*sizeof(*statenode->CoverageArray));
      }
    }
#endif

  } else if (Node->EC==xProcedureEC) {
    PrdNode = (xPrdIdNode)Node;
    if (PrdNode->MaxSymbolNumber>0) {
      memset( (void *)PrdNode->CoverageArray, 0, 
              (PrdNode->MaxSymbolNumber+1)*sizeof(*PrdNode->CoverageArray) );
    }
    PrsNode = (xPrsIdNode)Node->Parent;
    while (PrsNode &&
           PrsNode->EC != xProcessEC && PrsNode->EC != xProcessTypeEC)
      PrsNode = (xPrsIdNode)PrsNode->Parent;
    if (PrsNode) {    /* not global procedure */
      for (statenode=(xStateIdNode)PrdNode->First;
           statenode;
           statenode=(xStateIdNode)statenode->Suc) {
        if (statenode->EC==xStateEC) {
          memset( (void *)statenode->CoverageArray, 0, 
               (PrsNode->SignalSetLength+1)*sizeof(*statenode->CoverageArray));
        }
      }
    } else {
      /* ??? Global procedure !!! */
    }
  }

  for (Child=Node->First; Child; Child=Child->Suc) {
    xClearCoverage(Child);
  }
}

#endif


#endif
/************************* END XMONITOR ****************************/





/***************************** XMSCE *******************************/
#ifdef XMSCE

#ifdef XVALIDATOR_LIB
char       ** xMSCETraceList;
int xSilentMSCE = 0; /* Set when calling SDL_Output in
			    SDL_OutputTimerSignal to prevent extra MSC-trace */
static int GlobalProcessInstanceId = 0;
static int GlobalSignalInstanceId = 0;

#endif

static WriteBuf *MSCE_Buf = 0;

#define MRESET            \
  if (!MSCE_Buf) \
    MSCE_Buf = WriteBuf_New(100); \
  else \
    WriteBuf_Clear(MSCE_Buf)
#define MCAT(a)           WriteBuf_Add_String(MSCE_Buf,a,0)
#define MCAT2(f,a)        xAddBuf_Fmt(MSCE_Buf,f,a)
#define MCAT3(f,a,b)      xAddBuf_Fmt(MSCE_Buf,f,a,b)
#define MCAT4(f,a,b,c)    xAddBuf_Fmt(MSCE_Buf,f,a,b,c)
#define MCATSORT(val,sort) xGenericWriteSort(MSCE_Buf,val,sort)

#ifdef XVALIDATOR_LIB
#define MPRINTF           \
  { \
    WriteBuf_Terminate(MSCE_Buf); \
    xSaveMSCETrace(WriteBuf_Data(MSCE_Buf)); \
  }
#else
#define MPRINTF           \
  { \
    WriteBuf_Terminate(MSCE_Buf); \
    MPrintString(WriteBuf_Data(MSCE_Buf)); \
  }
#endif


/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       Function Implementations XMSCE - SIMULATOR SPECIFIC FUNCTIONS
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#ifndef XVALIDATOR_LIB

/*---+---------------------------------------------------------------
     MPrintString
-------------------------------------------------------------------*/
static void MPrintString(
  char * Str)
{
#ifdef XCONNECTPM
  if (xSysD.xNoticeBoard.PMConnected && xSysD.xNoticeBoard.MSCEStarted) {
    xMPrintString(Str);
  } else
#endif
    fprintf(xSysD.MSCLog.File, "%s\n", Str);
#ifdef XDEBUGF
  printf("%s\n", Str);
#endif
}

/*---+---------------------------------------------------------------
     xMSCETraceValue
-------------------------------------------------------------------*/
static int xMSCETraceValue(
  SDL_PId PId)
{
  xIdNode  IdNode;
  xPrsNode Process;

  if (xEq_SDL_PId_NULL(PId)) {
    if ( ! XREADYQ_EMPTY)
      Process = XREADYQ_FIRST;
    else
      return xSysD.MSCETrace;
  } else if (XIS_PID_IN_SYSTEM(PId)) {
    Process = XPID_TO_PRS(PId);
  } else {
    Process = XPID_TO_PRS(xEnv);
  }

  /* Test PId */
  if (Process->MSCETrace >= 0)
    return Process->MSCETrace;

  /* Test Process Instance Set */
  if (Process->NameNode->MSCETrace >= 0)
    return Process->NameNode->MSCETrace;

  /* Test Blocks */
  for (IdNode = Process->NameNode->Parent;
       IdNode != (xIdNode)0 && IdNode->EC != xSystemEC;
       IdNode = IdNode->Parent) {
    if (IdNode->EC == xBlockEC)
      if (((xBlockIdNode)IdNode)->MSCETrace >= 0)
        return ((xBlockIdNode)IdNode)->MSCETrace;
  }

  /* Test System */
  if (IdNode != xSymbolTableRoot && ((xSystemIdNode)IdNode)->MSCETrace >= 0)
    return ((xSystemIdNode)IdNode)->MSCETrace;

  /* Take default value */
  return xSysD.MSCETrace;
}


/*---+---------------------------------------------------------------
     xIsMSCETraced
-------------------------------------------------------------------*/
static xbool xIsMSCETraced(
  SDL_PId PId)
{
  return xMSCETraceValue(PId) > 0;
}


/*---+---------------------------------------------------------------
     xIsMSCETracedIdNode
-------------------------------------------------------------------*/
static xbool xIsMSCETracedIdNode(
  xPrsIdNode PrsId)
{
  xIdNode IdNode;

  if (PrsId->MSCETrace >= 0)
    return PrsId->MSCETrace > 0;
  for (IdNode = PrsId->Parent;
       IdNode != (xIdNode)0 && IdNode->EC != xSystemEC;
       IdNode = IdNode->Parent) {
    if (IdNode->EC == xBlockEC)
      if (((xBlockIdNode)IdNode)->MSCETrace >= 0)
        return ((xBlockIdNode)IdNode)->MSCETrace > 0;
  }
  if (IdNode != xSymbolTableRoot && ((xSystemIdNode)IdNode)->MSCETrace >= 0)
    return ((xSystemIdNode)IdNode)->MSCETrace > 0;
  return xSysD.MSCETrace > 0;
}


/*---+---------------------------------------------------------------
     xBlockIsBlockTraced
-------------------------------------------------------------------*/
static xbool xBlockIsBlockTraced(
  xBlockIdNode block)
{
  xIdNode IdNode;

  if (block->MSCETrace == 3)
    return (xbool)1;

  for (IdNode = block->Parent;
       IdNode != (xIdNode)0 && IdNode->EC != xSystemEC;
       IdNode = IdNode->Parent)
    ;

  if (IdNode != xSymbolTableRoot && ((xSystemIdNode)IdNode)->MSCETrace == 3)
    return (xbool)1;

  return xSysD.MSCETrace == 3;
}


/*---+---------------------------------------------------------------
     xMSCEBlockTraced
-------------------------------------------------------------------*/
static xIdNode xMSCEBlockTraced(
  SDL_PId PId)
{
  xPrsIdNode PrsId;
  xIdNode    IdNode;
  xPrsNode   Process;

  if (xEq_SDL_PId_NULL(PId)) {
    if ( ! XREADYQ_EMPTY)
      Process = XREADYQ_FIRST;
    else
      return (xIdNode)0;
  } else if (XIS_PID_IN_SYSTEM(PId)) {
    Process = XPID_TO_PRS(PId);
  } else {
    Process = XPID_TO_PRS(xEnv);
  }

  if (Process->MSCETrace >= 0)
    return (xIdNode)0;

  PrsId = Process->NameNode;
  if (PrsId->MSCETrace >= 0)
    return (xIdNode)0;
  for (IdNode = PrsId->Parent;
       IdNode != (xIdNode)0 && IdNode->EC != xSystemEC;
       IdNode = IdNode->Parent) {
    if (IdNode->EC == xBlockEC && xBlockIsBlockTraced((xBlockIdNode)IdNode)) {
      return IdNode;
    }
  }

  return (xIdNode)0;
}


/*---+---------------------------------------------------------------
     xMSCEOutputTraced
-------------------------------------------------------------------*/
static xbool xMSCEOutputTraced(
  xSignalNode Signal)
{
  int     SenderTraceValue, ReceiverTraceValue;
  xIdNode SenderBlockTraced, ReceiverBlockTraced;
  SDL_PId Sender, Receiver;

  Sender = XSIGNAL_SENDER(Signal);
  Receiver = XSIGNAL_RECEIVER(Signal);
  SenderTraceValue = xMSCETraceValue(Sender);
  ReceiverTraceValue = xMSCETraceValue(Receiver);
  if ( SenderTraceValue == 3 && ReceiverTraceValue == 3 ) {
    SenderBlockTraced = xMSCEBlockTraced(Sender);
    ReceiverBlockTraced = xMSCEBlockTraced(Receiver);
    if (SenderBlockTraced != ReceiverBlockTraced) return (xbool)1;
    return (xbool)0;
  }
  if ( (SenderTraceValue >= 1 && ReceiverTraceValue >= 1) ||
       (SenderTraceValue == 2 && ReceiverTraceValue <= 0) ||
       (SenderTraceValue <= 0 && ReceiverTraceValue == 2) )
    return (xbool)1;
  return (xbool)0;
}

/*---+---------------------------------------------------------------
     xMSCEditorStopped
-------------------------------------------------------------------*/
void xMSCEditorStopped (void)
{
  if (xSysD.MSCLogStarted) {
    xSysD.MSCLogStarted = 0;
    xPrintString("\nMSC-Log stopped since the connected MSCE has stopped.\n");
  }
}


/*---+---------------------------------------------------------------
     WriteMSCETimeNow
-------------------------------------------------------------------*/
static void WriteMSCETimeNow (void)
{
  SDL_Time T;
  MCAT(" #SDTNOW(");
#ifdef XMONITOR
  if (xSysD.StoppedInMonitor)
    T = xSysD.NowInMonitor;
  else
#endif
    T = SDL_Now();
  MCATSORT((void *)&T, (tSDLTypeInfo *)&ySDL_SDL_Time);
  MCAT(")");
}

/*---+---------------------------------------------------------------
     xMSCEClose
-------------------------------------------------------------------*/
void xMSCEClose (void)
{
#ifdef XCONNECTPM
  if (xSysD.MSCLogStarted && ! xSysD.xNoticeBoard.MSCEStarted) {
#else
  if (xSysD.MSCLogStarted) {
#endif
    MRESET;
    MCAT("endmsc;");
    MPRINTF;
    if (fclose(xSysD.MSCLog.File) != 0)
      xPrintString("Error closing MSC-Log file\n");
  } 
}


#endif
  /* ! XVALIDATOR_LIB */

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       Function Implementations XMSCE - VALIDATOR SPECIFIC FUNCTIONS
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#ifdef XVALIDATOR_LIB

/*---+---------------------------------------------------------------
     xSaveMSCETrace
-------------------------------------------------------------------*/
static void xSaveMSCETrace (char * Info)
{
  /* Update xMSCETraceList */
  addNL((void ***)&xMSCETraceList, (void *)xCopyStr(Info));
}


#endif
  /* XVALIDATOR_LIB */

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       Function Implementations XMSCE - COMMON FUNCTIONS
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

/*---+---------------------------------------------------------------
     MCATSignalParams
-------------------------------------------------------------------*/
static void MCATSignalParams(
  xSignalNode Signal)
{
  xVarIdNode SigPar;

  if (Signal->NameNode->First == NULL) /* No parameters to signal */
    return;

  MCAT("(");
  for (SigPar = (xVarIdNode)Signal->NameNode->First;
       SigPar != (xVarIdNode) 0;
       SigPar = (xVarIdNode)SigPar->Suc) {
    xGenericWriteSort(MSCE_Buf,
		      (void *)((xptrint)Signal + SigPar->Offset),
		      SigPar->TypeNode);
    if (SigPar->Suc) MCAT(", ");
  }
  MCAT(")");
}


/*---+---------------------------------------------------------------
     MCATTimerParams
-------------------------------------------------------------------*/
static void MCATTimerParams(
  xSignalNode Signal)
{
  if (Signal->NameNode->First == NULL) /* No parameters to timer */
    return;

  MCAT(" #SDTMSCPAR");
  MCATSignalParams(Signal);

}



/*---+---------------------------------------------------------------
     MCATNowAndSymbolRef
-------------------------------------------------------------------*/
static void MCATNowAndSymbolRef (void)
{
#ifdef XVALIDATOR_LIB
  MCAT2(" %s", xCurrentSymbolRef);
#else
  WriteMSCETimeNow();
#ifdef XMONITOR
  if (! xSysD.StoppedInMonitor)
#endif
    MCAT2(" %s", xSysD.xCurrentSymbolRef);
#endif
}

/*---+---------------------------------------------------------------
     MCATNowAndPrevSymbolRef
-------------------------------------------------------------------*/
static void MCATNowAndPrevSymbolRef (void)
{
#ifdef XVALIDATOR_LIB
  MCAT2(" %s", xPreviousSymbolRef);
#else
  WriteMSCETimeNow();
#ifdef XMONITOR
  if (! xSysD.StoppedInMonitor)
#endif
    MCAT2(" %s", xSysD.xPreviousSymbolRef);
#endif
}


/*---+---------------------------------------------------------------
     MCATFPars
-------------------------------------------------------------------*/
static void MCATFPars (
  xPrsIdNode   Prs,
  xSignalNode  Signal,
  xbool       *IsFirst,
  int          Level)
{
  xVarIdNode SigPar;

  /* Treat first FPar:s in inherited process types. */
  if (Prs->Super != (xPrsIdNode)0)
    MCATFPars(Prs->Super, Signal, IsFirst, Level+1);

  /* Loop for formal parameters in this type (or ProcessEC) */
  for (SigPar = (xVarIdNode)Prs->First;
       SigPar != (xVarIdNode)0;
       SigPar = (xVarIdNode)SigPar->Suc) {
    if (SigPar->EC == xFormalParEC) {
      if (*IsFirst) {
        *IsFirst = (xbool)0;
	MCAT(" (");
      } else {
	MCAT(", ");
      }
      xGenericWriteSort(MSCE_Buf,
			(void *)((xptrint)Signal + SigPar->Offset2),
			SigPar->TypeNode);
    }
  }
  if (Level==1 && !(*IsFirst))
    MCAT(")");
}

/*---+---------------------------------------------------------------
     MCATCreateParams
-------------------------------------------------------------------*/
static void MCATCreateParams(
  SDL_PId     PId,
  xSignalNode Signal)
{
  xbool      IsFirst = (xbool)1;
  MCATFPars(XPID_TO_PRS(PId)->NameNode, Signal, &IsFirst, 1);
}


#ifdef XVALIDATOR_LIB
/*---+---------------------------------------------------------------
     MCATInstName
-------------------------------------------------------------------*/
static void MCATInstName(
  SDL_PId pid)
{
  if (xEq_SDL_PId_NULL( pid ) ||
      xEq_SDL_PId(pid,xStoppedPId) ||
      xEq_SDL_PId(pid,xNotDefPId)) {
    MCAT("XNOTDEF");
  } else if (xEq_SDL_PId(pid, xEnv)) {
    MCAT("env_0");
  } else {
    MCAT3("%s_%d",
	  XPID_TO_PRS(pid)->NameNode->Name,
	  XPID_TO_PRS(pid)->GlobalInstanceId );
  }
}

#else
/*---+---------------------------------------------------------------
     MCATInstName
-------------------------------------------------------------------*/
static void MCATInstName(
  SDL_PId  PId)
{
  xBlockIdNode BlockTraced;
  int          TraceValue;

  if (xEq_SDL_PId_NULL(PId) || xEq_SDL_PId(PId, xNotDefPId)) {
    MCAT("NULL");
    return;
  }
  BlockTraced = (xBlockIdNode)xMSCEBlockTraced(PId);
  TraceValue = xMSCETraceValue(PId);
  if (BlockTraced != (xBlockIdNode)0) {
    MCAT3("%s_%d", 
	  BlockTraced->Name, BlockTraced->GlobalInstanceId);
  } else if (TraceValue <= 0) {
    MCAT2("Void_%d", xSysD.VoidProcessInstanceId);
  } else if (xEq_SDL_PId(PId, xEnv) || ! XIS_PID_IN_SYSTEM(PId)) {
    MCAT("env_0");
  } else {
#ifdef XNRINST
    MCAT4("%s_%d_%d",
	  XPID_TO_PRS(PId)->NameNode->Name, XPID_INSTNR(PId),
          XPID_GLOBID(PId) );
#else
    MCAT3("%s_%d",
	  XPID_TO_PRS(PId)->NameNode->Name,
          XPID_GLOBID(PId) );
#endif
  }
}
#endif


/*---+---------------------------------------------------------------
     MSCFilter
-------------------------------------------------------------------*/
/* Apostrophe doubled in buffer */
static void MSCFilter (WriteBuf *Buf)
{
  char *tmp;
  int pos, Apost;
  unsigned int new_length;

  tmp = WriteBuf_Data(Buf);
  pos = 0; Apost = 0;
  for (pos=0; pos<WriteBuf_Length(Buf); pos++) {
    if (tmp[pos] == '\'')
      Apost++;
  }
  if (Apost == 0)
    return;
  WriteBuf_Secure(Buf, Apost);
  new_length = WriteBuf_Length(Buf) + Apost;
  for (pos=WriteBuf_Length(Buf)-1; pos>=0 && Apost>0; pos--) {
    WriteBuf_Data(Buf)[pos+Apost] = WriteBuf_Data(Buf)[pos];
    if (WriteBuf_Data(Buf)[pos] == '\'') {
      Apost--;
      WriteBuf_Data(Buf)[pos+Apost] = '\'';
    }
  }
  WriteBuf_Set_Length(Buf, new_length);
}


#ifdef XSIGPATH

#define DEFAULTMSCEENVChannels (xbool)0
static xbool MSCEENVChannels = DEFAULTMSCEENVChannels;
  /* true if Env should be split into channels in MSC trace */

/*---+---------------------------------------------------------------
     xSetEnvSplitIntoChannels
-------------------------------------------------------------------*/
void xSetEnvSplitIntoChannels(xbool par)
{
  MSCEENVChannels = par;
}

/*---+---------------------------------------------------------------
     xIsEnvSplitIntoChannels
-------------------------------------------------------------------*/
xbool xIsEnvSplitIntoChannels (void)
{
  return MSCEENVChannels;
}

/*---+---------------------------------------------------------------
     xGetDefaultEnvSplitIntoChannels
-------------------------------------------------------------------*/
xbool xGetDefaultEnvSplitIntoChannels (void)
{
  return DEFAULTMSCEENVChannels;
}

/*---+---------------------------------------------------------------
     MCATInstName2
-------------------------------------------------------------------*/
static void MCATInstName2(
  SDL_PId     PId,
  xSignalNode signal)
{
#ifdef XVALIDATOR_LIB
  if (MSCEENVChannels && xEq_SDL_PId(PId, xEnv) && signal->EnvChannel) {
    MCAT(signal->EnvChannel->Name);
  }
  else {
    MCATInstName(PId);
  }
#else
  xBlockIdNode BlockTraced;
  int          TraceValue;

  if (xEq_SDL_PId_NULL(PId) || xEq_SDL_PId(PId, xNotDefPId)) {
    MCAT("NULL");
    return;
  }
  BlockTraced = (xBlockIdNode)xMSCEBlockTraced(PId);
  TraceValue = xMSCETraceValue(PId);
  if (BlockTraced != (xBlockIdNode)0) {
    MCAT3("%s_%d",
	  BlockTraced->Name, BlockTraced->GlobalInstanceId);
  } else if (TraceValue <= 0) {
    MCAT2("Void_%d", xSysD.VoidProcessInstanceId);
  } else if (xEq_SDL_PId(PId, xEnv) || ! XIS_PID_IN_SYSTEM(PId)) {
    if (MSCEENVChannels && signal->EnvChannel) {
      MCAT(signal->EnvChannel->Name);
    }
    else {
      MCAT("env_0");
    }
  } else {
    MCAT4("%s_%d_%d",
	  XPID_TO_PRS(PId)->NameNode->Name, XPID_INSTNR(PId),
          XPID_GLOBID(PId) );
  }
#endif
}


# ifndef XVALIDATOR_LIB
/*---+---------------------------------------------------------------
     MCATInstNameEnvCha
-------------------------------------------------------------------*/
static void MCATInstNameEnvCha(
  SDL_PId     pid,
  xSignalNode signal,
  xbool       isSender,
  xIdNode     Path[],
  int         PathLength)
{
  int         Index;

  if (MSCEENVChannels &&
      (xEq_SDL_PId(pid, xEnv) || ! XIS_PID_IN_SYSTEM(pid))) {
    if (isSender) {
      for (Index = 0; Index < PathLength; Index++) {
        if (Path[Index]->EC == xChannelEC) {
          signal->EnvChannel = (xChannelIdNode)Path[Index];
          break;
        }
      }
    }
    else {
      for (Index = PathLength; Index >= 0; Index--) {
        if (Path[Index]->EC == xChannelEC) {
          signal->EnvChannel = (xChannelIdNode)Path[Index];
          break;
        }
      }
    }
  }
  MCATInstName2(pid, signal);
}
# endif
#else
#define MCATInstName2(pid, signal) MCATInstName(pid)
#endif
       /* XSIGPATH */

#ifdef XVALIDATOR_LIB
/*---+---------------------------------------------------------------
     xMSCEOutput
-------------------------------------------------------------------*/
void xMSCEOutput(
  xSignalNode  Signal,
  int          NrReceivers)
{
  if ( xEq_SDL_PId_NULL(Signal->Sender) )
    return;
  if (Signal->GlobalInstanceId > 0) {
    return;
  }

  /* Get a unique id for this signal */
  Signal->GlobalInstanceId = ++GlobalSignalInstanceId;

  /* print the output statement */
  MRESET;
  MCATInstName2(Signal->Sender, Signal);
  MCAT3(" : out %s,%d",
	Signal->NameNode->Name,
	Signal->GlobalInstanceId);
  MCATSignalParams(Signal);
  MCAT(" to ");
  if (NrReceivers <= 0 || xEq_SDL_PId(Signal->Receiver,xStoppedPId)) {
    /* Set receive=Sender to make the messaga go through the
       MSC PR parser and be displayed in the MSC editor */
    MCATInstName2(Signal->Sender, Signal);
  } else {
    MCATInstName2(Signal->Receiver, Signal);
  }
  MCAT("; /*");
  if ( NrReceivers <= 0 || xEq_SDL_PId(Signal->Receiver,xStoppedPId) )
    MCAT(" #SDTSTATUS(LOST)");
  if (xCurrentSymbolRef) {
    MCAT2(" %s", xCurrentSymbolRef); 
  }
  MCAT(" */\n");
  MPRINTF;
}

#else
/*---+---------------------------------------------------------------
     xMSCEOutput
-------------------------------------------------------------------*/
#ifdef XSIGPATH
void xMSCEOutput(
  xSignalNode  Signal,
  int          NrOfReceivers,
  xIdNode      Path[],
  int          PathLength)
#else
void xMSCEOutput(
  xSignalNode  Signal,
  int          NrOfReceivers)
#endif
{
  int     SenderTraceValue, ReceiverTraceValue;
  SDL_PId Sender, Receiver;

  if (xSysD.MSCLogStarted == 0) return;
  if ( xEq_SDL_PId_NULL(XSIGNAL_SENDER(Signal)) ) return;
  if (XSIGNAL_GLOBID(Signal) > 0) return;
  Sender = XSIGNAL_SENDER(Signal);
  Receiver = XSIGNAL_RECEIVER(Signal);

  /* Handle error cases:
     - No receiver found, no path to receiver
     - Sent to stopped process 
  */
  if ( NrOfReceivers <= 0 ||
         ( XIS_PID_IN_SYSTEM(Receiver) &&
           ! xEq_SDL_PId(Receiver, XPID_TO_PRS(Receiver)->Self) ) ) {
    /* No trace if sender is not traced */
    if ( ! xIsMSCETraced(Sender) ) return;

    XSIGNAL_GLOBID(Signal) = ++xSysD.GlobalSignalInstanceId;
    MRESET;
#ifdef XSIGPATH
    MCATInstNameEnvCha(Sender, Signal, (xbool)1, Path, PathLength);
#else
    MCATInstName(Sender);
#endif
    MCAT3(" : out %s,%d ",
	  XSIGNAL_IDNODE(Signal)->Name, XSIGNAL_GLOBID(Signal));
    MCATSignalParams(Signal);
    MCAT(" to ");
#ifdef XSIGPATH
    MCATInstNameEnvCha(Sender, Signal, (xbool)1, Path, PathLength);
#else
    MCATInstName(Sender);          /* FIX. No receiver!!! Use Sender instead */
#endif
    MCAT("; /* #SDTSTATUS(LOST)");
    WriteMSCETimeNow();
#ifdef XMONITOR
    if (! xSysD.StoppedInMonitor)
#endif
      MCAT2(" %s", xSysD.xCurrentSymbolRef); 
    MCAT(" */");
    MPRINTF;
    return;
  }

  if (! xMSCEOutputTraced(Signal) ) return;

  /* Create the Void instance if needed */
  SenderTraceValue = xMSCETraceValue(Sender);
  ReceiverTraceValue = xMSCETraceValue(Receiver);
  if ( (SenderTraceValue == 2 && ReceiverTraceValue <= 0) ||
       (SenderTraceValue <= 0 && ReceiverTraceValue == 2) ) {
    if (xSysD.VoidProcessInstanceId == 0) {
      xSysD.VoidProcessInstanceId = ++xSysD.GlobalProcessInstanceId;
      MRESET;
      MCAT2("Void_%d : instancehead;", xSysD.VoidProcessInstanceId);
      MPRINTF;
    }
  }

  XSIGNAL_GLOBID(Signal) = ++xSysD.GlobalSignalInstanceId;
  MRESET;
#ifdef XSIGPATH
  MCATInstNameEnvCha(Sender, Signal, (xbool)1, Path, PathLength);
#else
  MCATInstName(Sender);
#endif
  MCAT3(" : out %s,%d ",
	XSIGNAL_IDNODE(Signal)->Name, XSIGNAL_GLOBID(Signal));
  MCATSignalParams(Signal);
  MCAT(" to ");
#ifdef XSIGPATH
  MCATInstNameEnvCha(Receiver, Signal, (xbool)0, Path, PathLength);
#else
  MCATInstName(Receiver);
#endif
  MCAT("; /*");
  WriteMSCETimeNow();
  if (
#ifdef XMONITOR
      ! xSysD.StoppedInMonitor &&
#endif
      xSysD.xCurrentSymbolRef &&
      XIS_PID_IN_SYSTEM(Sender)) {
    MCAT2(" %s", xSysD.xCurrentSymbolRef); 
  }
  MCAT(" */\n");
  MPRINTF;
}
#endif

/*---+---------------------------------------------------------------
     xMSCEOutputDiscard
-------------------------------------------------------------------*/
void xMSCEOutputDiscard(
  xSignalNode  S)
{

#ifndef XVALIDATOR_LIB
  if ( ! xSysD.MSCLogStarted) return;
  if (! xMSCEOutputTraced(S) ) return;
#endif

  MRESET;
  MCATInstName(S->Receiver);
  MCAT3( " : in %s,%d",
	 S->NameNode->Name,
	 S->GlobalInstanceId);
  MCATSignalParams(S);
  MCAT(" from ");
  MCATInstName2(S->Sender, S);
  MCAT("; /* #SDTSTATUS(LOST) */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCETimerOutput
-------------------------------------------------------------------*/
#ifdef __BORLANDC__
#pragma argsused
#endif
void xMSCETimerOutput(
  xSignalNode  S)
{
  /* No representation in MSC PR */
}


/*---+---------------------------------------------------------------
     xMSCETimerOutputDiscard
-------------------------------------------------------------------*/
void xMSCETimerOutputDiscard(
  xSignalNode  S)
{

#ifndef XVALIDATOR_LIB
  /* Traced if: Receiver is traced and not block trace. */
  if ( ! xSysD.MSCLogStarted) return;
  if (! xMSCEOutputTraced(S) ) return;
  if (XSIGNAL_GLOBID(S) <= xSysD.GlobalSignalInstanceIdWhenStart) {
    PRINTF2(
      "\nTimer %s is set before MSC trace started,\n  not displayed in MSCE.\n",
      XSIGNAL_IDNODE(S)->Name);
    return;
  }
#endif

  MRESET;
  MCATInstName(S->Receiver);
  MCAT3( " : timeout %s,%d",
	 S->NameNode->Name,
	 S->GlobalInstanceId);
  MCAT("; /* #SDTSTATUS(LOST)");
  MCATTimerParams(S);
#ifndef XVALIDATOR_LIB
  WriteMSCETimeNow();
#endif
  MCAT(" */\n");
  MPRINTF;
}



/*---+---------------------------------------------------------------
     xMSCECreate
-------------------------------------------------------------------*/
void xMSCECreate(
  SDL_PId  P,
  xSignalNode StartUpSig)
{
  xPrsNode Temp = XPID_TO_PRS(P);
  int      Index;

#ifndef XVALIDATOR_LIB
  /* Trace if: Created process traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if ( ! xIsMSCETraced(P) ) return;
  if (xMSCEBlockTraced(P) != (xIdNode)0) return;

#endif

  /* ENV instance declaration */
  if (Temp->NameNode == xEnvId) {
#ifdef XSIGPATH
    if (MSCEENVChannels && xEnvId->ToId) {
      for (Index=0; xEnvId->ToId[Index]; Index++) {
        if (xEnvId->ToId[Index]->EC == xChannelEC) {
          MRESET;
          MCAT2("%s : instancehead;\n",
		xEnvId->ToId[Index]->Name);
          MPRINTF;
        }
      }
      return;
    }
#endif
    MRESET;
    MCATInstName(P);
    MCAT(" : instancehead;\n");
    MPRINTF;
    return;
  }

  /* Other instance declarations */
#ifdef XVALIDATOR_LIB
  Temp->GlobalInstanceId = ++GlobalProcessInstanceId;
#else
  XPID_GLOBID(P) = ++xSysD.GlobalProcessInstanceId;
#endif

  /* Instance definition */
  MRESET;
  MCATInstName(P);
  if (xNeedsQualifier((xIdNode)Temp->NameNode)) {
    MCAT2(" : instancehead %s ", xEntityString[xProcessEC]);
    xGetQualifier(MSCE_Buf, (xIdNode)Temp->NameNode, Temp->BlockInstNumber); 
    MCAT2(" %s;", Temp->NameNode->Name);
  }
  else {
#ifdef XVALIDATOR_LIB
    MCAT2(" : instancehead %s;", Temp->NameNode->Name);
#else
    MCAT3(" : instancehead %s %s;",
          xEntityString[xProcessEC],
          Temp->NameNode->Name);
#endif
  }
  if (StartUpSig != 0)
    MCAT(" /* #SDTSTATUS(DYNAMIC) */");
  MCAT("\n");
  MPRINTF;

  /* Create statement */
#ifndef XVALIDATOR_LIB
  /* Traced if the dynamic create and creator is traced */
  if ( StartUpSig == (xSignalNode)0 ) return;
  if ( ! xIsMSCETraced(StartUpSig->Sender) ) return;
#endif

  if (StartUpSig && !xEq_SDL_PId_NULL(StartUpSig->Sender)) {
    MRESET;
    MCATInstName(StartUpSig->Sender);
    MCAT(" : create ");
    MCATInstName(P);
    MCATCreateParams(P, StartUpSig);
    MCAT("; /*");
    MCATNowAndSymbolRef();
    MCAT(" */\n");
    MPRINTF;
  }
}


/*---+---------------------------------------------------------------
     xMSCEUnsuccessfulCreate
-------------------------------------------------------------------*/
#ifdef __BORLANDC__
#pragma argsused
#endif
void xMSCEUnsuccessfulCreate(
  xPrsIdNode PrsId, SDL_PId Parent, xSignalNode StartUpSig)
{
#ifndef XVALIDATOR_LIB
  /* Trace if both parent and offspring is traced and not block trace */
  if ( ! xSysD.MSCLogStarted)  return;
  if ( ! xIsMSCETraced(Parent) ) return;
  if ( ! xIsMSCETracedIdNode(PrsId) ) return;
  if (xMSCEBlockTraced(Parent) != (xIdNode)0) return;
#endif

  /* Print action statement */
  MRESET;
  MCATInstName(Parent);
  MCAT2(" : action 'Create %s failed'; /*", PrsId->Name);
  MCATNowAndSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCESet
-------------------------------------------------------------------*/
void xMSCESet(
  SDL_Time     T,
  xSignalNode  S)
{
#ifndef XVALIDATOR_LIB
  SDL_PId Receiver;

  /* Traced if: Receiver is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  Receiver = XSIGNAL_RECEIVER(S);
  if ( ! xIsMSCETraced(Receiver) ) return;
  if (xMSCEBlockTraced(Receiver) != (xIdNode)0) return;
#endif

  /* Get a unique id for this timer */
  S->GlobalInstanceId = ++XSYSD GlobalSignalInstanceId;

  /* Print set statement */
  MRESET;
  MCATInstName( S->Receiver );
  MCAT3( " : set %s,%d (",
	 S->NameNode->Name,
	 S->GlobalInstanceId
       );
#ifdef XVALIDATOR_LIB
  T = xMinus_SDL_Duration(T,SDL_Now());
#else
#ifdef XMONITOR
  if (xSysD.StoppedInMonitor) {
    T = xMinus_SDL_Duration(T, xSysD.NowInMonitor);
  } else {
#endif
    T = xMinus_SDL_Duration(T,SDL_Now());
#ifdef XMONITOR
  }
#endif
#endif
  MCATSORT((void *)&T, (tSDLTypeInfo *)&ySDL_SDL_Time);
  MCAT("); /*");
  MCATTimerParams(S);
  MCATNowAndSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCEReset
-------------------------------------------------------------------*/
#ifdef XVALIDATOR_LIB
/* ResetType==1 -> Reset
   ResetType==2 -> Implicit reset
*/
void xMSCEReset(xSignalNode  S, int ResetType)
#else
void xMSCEReset(
  xSignalNode  S)
#endif
{
#ifndef XVALIDATOR_LIB
  SDL_PId Receiver;
  /* Traced if Receiver is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  Receiver = XSIGNAL_RECEIVER(S);
  if ( ! xIsMSCETraced(Receiver) ) return;
  if (xMSCEBlockTraced(Receiver) != (xIdNode)0) return;

  if (XSIGNAL_GLOBID(S) <= xSysD.GlobalSignalInstanceIdWhenStart) {
    PRINTF2(
      "\nTimer %s is set before MSC trace started,\n  not displayed in MSCE.\n",
      XSIGNAL_IDNODE(S)->Name);
    return;
  }
#endif

  MRESET;
  MCATInstName(S->Receiver);
  MCAT3( " : reset %s,%d",
	 S->NameNode->Name,
	 S->GlobalInstanceId);
  MCAT("; /*");
#ifdef XVALIDATOR_LIB
  if (ResetType==2)
#else
  if (xSysD.DoingReset != 1)
#endif
    MCAT(" #SDTSTATUS(IMPLICIT_RESET)");
  MCATTimerParams(S);
  MCATNowAndSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCENextstate
-------------------------------------------------------------------*/
void xMSCENextstate(
  xPrsNode  PrsP,
  int       InState)
{
  xStateIdNode StateId;

#ifdef XVALIDATOR_LIB
  if (xValMode != xSim || xSilentMSCE > 0 || ! xShowStatesInMSCE)
    return;
#else
  /* Traced if process is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if (xSysD.MSCSymbolLevel < 1) return;
  if ( ! xIsMSCETraced(PrsP->Self) ) return;
  if (xMSCEBlockTraced(PrsP->Self) != (xIdNode)0) return;
#endif

  MRESET;
  MCATInstName(PrsP->Self);
  MCAT(" : condition ");

#ifdef XVALIDATOR_LIB
  StateId = GetStateNode(PrsP);
  MCAT(StateId->Name);
#endif

#ifndef XNOUSEOFSERVICE
  if ( PrsP->ActiveSrv != (xSrvNode)0 ) {
    if ( PrsP->ActiveSrv->ActivePrd != (xPrdNode)0 ) {
#ifndef XVALIDATOR_LIB
      StateId = xGetState(PrsP, PrsP->ActiveSrv->ActivePrd,
          PrsP->ActiveSrv->ActivePrd->NameNode->StateList, InState);
      MCAT(StateId->Name);
#endif
      MCAT2(" comment 'in procedure %s'",
            PrsP->ActiveSrv->ActivePrd->NameNode->Name);
    } else {
#ifndef XVALIDATOR_LIB
      StateId = xGetState(PrsP, (xPrdNode)0,
                          PrsP->ActiveSrv->NameNode->StateList, InState);
      MCAT(StateId->Name);
#endif
      MCAT2(" comment 'in service %s'",
	    PrsP->ActiveSrv->NameNode->Name);
    }
  } else {
#endif
    if ( PrsP->ActivePrd != (xPrdNode)0 ) {
#ifndef XVALIDATOR_LIB
      StateId = xGetState(PrsP, PrsP->ActivePrd,
          PrsP->ActivePrd->NameNode->StateList, InState);
      MCAT(StateId->Name);
#endif
      MCAT2(" comment 'in procedure %s'",
	    PrsP->ActivePrd->NameNode->Name);
#ifndef XVALIDATOR_LIB
    } else {
      StateId = xGetState(PrsP, (xPrdNode)0,
                          PrsP->NameNode->StateList, InState);
      MCAT(StateId->Name);
#endif
    }
#ifndef XNOUSEOFSERVICE
  }
#endif

  MCAT("; /*");
  MCATNowAndPrevSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCENextstateDiscard
-------------------------------------------------------------------*/
#ifdef __BORLANDC__
#pragma argsused
#endif
void xMSCENextstateDiscard(
  xPrsNode    PrsP,
  xSignalNode Signal)
{
#ifndef XVALIDATOR_LIB
  if ( ! xSysD.MSCLogStarted) return;
  if (! xMSCEOutputTraced(Signal) ) return;
  if (XSIGNAL_GLOBID(Signal) <= xSysD.GlobalSignalInstanceIdWhenStart) {
    PRINTF2(
    "\nSignal %s is sent before MSC trace started,\n  not displayed in MSCE.\n",
           XSIGNAL_IDNODE(Signal)->Name);
    return;
  }
#endif

  if (Signal->NameNode->EC==xTimerEC) {
    /* Print 'timeout' statement */
    MRESET;
    MCATInstName(Signal->Receiver);
    MCAT3( " : timeout %s,%d",
	   Signal->NameNode->Name,
	   Signal->GlobalInstanceId);
    MCAT("; /* #SDTSTATUS(LOST)");
    MCATTimerParams(Signal);
#ifndef XVALIDATOR_LIB
    WriteMSCETimeNow();
#endif
    MCAT(" */\n");
    MPRINTF;
    return;
  }

  MRESET;
  MCATInstName(Signal->Receiver);
  MCAT3( " : in %s,%d",
	 Signal->NameNode->Name,
	 Signal->GlobalInstanceId);
  MCATSignalParams(Signal);
  MCAT( " from " );
#ifdef XVALIDATOR_LIB
  if (xEq_SDL_PId(Signal->Sender, xStoppedPId)) {
#else
  if ( XIS_PID_IN_SYSTEM(Signal->Sender) &&
       Signal->Sender.LocalPId->PrsP->Self.LocalPId !=
       Signal->Sender.LocalPId ) {
#endif
    /* If Sender has stopped, use Receiver as Sender
       to make MSC editor accept the signal */
    MCATInstName(Signal->Receiver);
  } else {
    MCATInstName2(Signal->Sender, Signal);
  }
  MCAT("; /* #SDTSTATUS(LOST)");
#ifndef XVALIDATOR_LIB
  WriteMSCETimeNow();
#endif
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCEStop
-------------------------------------------------------------------*/
void xMSCEStop(
  xPrsNode  PrsP)
{
#ifndef XVALIDATOR_LIB
  /* Traced if process is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if ( ! xIsMSCETraced(PrsP->Self) ) return;
  if (xMSCEBlockTraced(PrsP->Self) != (xIdNode)0) return;
#endif

  MRESET;
  MCATInstName(PrsP->Self);
  MCAT(" : stop; /*");
  MCATNowAndPrevSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCEProcedureStart
-------------------------------------------------------------------*/
void xMSCEProcedureStart(
  xPrsNode  PrsP,
  xPrdNode  PrdVarP)
{
#ifdef XVALIDATOR_LIB
  if (xValMode != xSim || xSilentMSCE > 0 || ! xShowActionsInMSCE)
    return;
#else
  /* Traced if process is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if (xSysD.MSCSymbolLevel < 2) return;
  if ( ! xIsMSCETraced(PrsP->Self) ) return;
  if (xMSCEBlockTraced(PrsP->Self) != (xIdNode)0) return;
#endif

  MRESET;
  MCATInstName(PrsP->Self);
  MCAT2(" : action 'procedure start %s'; /*",
	PrdVarP->NameNode->Name);
  MCATNowAndSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCEProcedureReturn
-------------------------------------------------------------------*/
void xMSCEProcedureReturn(
  xPrsNode  PrsP,
  xPrdNode  PrdVarP)
{
#ifdef XVALIDATOR_LIB
  if (xValMode != xSim || xSilentMSCE > 0 || ! xShowActionsInMSCE)
    return;
#else
  /* Traced if process is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if (xSysD.MSCSymbolLevel < 2) return;
  if ( ! xIsMSCETraced(PrsP->Self) ) return;
  if (xMSCEBlockTraced(PrsP->Self) != (xIdNode)0) return;
#endif

  MRESET;
  MCATInstName(PrsP->Self);
  MCAT2(" : action 'return from %s'; /*",
	PrdVarP->NameNode->Name);
  MCATNowAndSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCEDecision
-------------------------------------------------------------------*/
void xMSCEDecision(
  xPrsNode      PrsP,
  void         *In_Addr,
  tSDLTypeInfo *SortNode)
{
  WriteBuf *Buf;

#ifdef THREADED_MSCTRACE
  if ( ! xSysD.MSCLogStarted) return;
#else
#ifdef XVALIDATOR_LIB
  if (xValMode != xSim || xSilentMSCE > 0 || ! xShowActionsInMSCE)
    return;
#else
  /* Traced if process is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if (xSysD.MSCSymbolLevel < 2) return;
  if ( ! xIsMSCETraced(PrsP->Self) ) return;
  if (xMSCEBlockTraced(PrsP->Self) != (xIdNode)0) return;
#endif
#endif /* THREADED_MSCTRACE */

  MRESET;
  MCATInstName(PrsP->Self);
  MCAT(" : action 'decision ");

  Buf = WriteBuf_New(60);
  xGenericWriteSort(Buf, In_Addr, SortNode);
  if (WriteBuf_Length(Buf) <= 50) {
    MSCFilter(Buf);
    WriteBuf_Add_WriteBuf(MSCE_Buf, Buf);
    MCAT("'; /*");
  } else {
    MCAT("...'; /*");
  }
  WriteBuf_Del(&Buf);
  MCATNowAndSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCETask
-------------------------------------------------------------------*/
void xMSCETask(
  xPrsNode  PrsP,
  char     *In_Str)
{
  WriteBuf *Buf;

#ifdef THREADED_MSCTRACE
  if ( ! xSysD.MSCLogStarted) return;
#else
#ifdef XVALIDATOR_LIB
  if (xValMode != xSim || xSilentMSCE > 0 || ! xShowActionsInMSCE)
    return;
#else
  /* Traced if process is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if (xSysD.MSCSymbolLevel < 2) return;
  if ( ! xIsMSCETraced(PrsP->Self) ) return;
  if (xMSCEBlockTraced(PrsP->Self) != (xIdNode)0) return;
#endif
#endif /* THREADED_MSCTRACE */

  MRESET;
  MCATInstName(PrsP->Self);
  if (strlen(In_Str)<=50) {
    MCAT(" : action 'task\n");
    Buf = WriteBuf_New(60);
    WriteBuf_Add_String(Buf, In_Str, 0);
    MSCFilter(Buf);
    WriteBuf_Add_WriteBuf(MSCE_Buf, Buf);
    WriteBuf_Del(&Buf);
    MCAT("'; /*");
  } else {
    MCAT(" : action 'task\n...'; /*");
  }
  MCATNowAndSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCEAssign
-------------------------------------------------------------------*/
void xMSCEAssign(
  xPrsNode      PrsP,
  char         *In_Str,
  void         *In_Addr,
  tSDLTypeInfo *SortNode)
{
  WriteBuf *Buf;

#ifdef THREADED_MSCTRACE
  if ( ! xSysD.MSCLogStarted) return;
#else
#ifdef XVALIDATOR_LIB
  if (xValMode != xSim || xSilentMSCE > 0 || ! xShowActionsInMSCE)
    return;
#else
  /* Traced if process is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if (xSysD.MSCSymbolLevel < 2) return;
  if ( ! xIsMSCETraced(PrsP->Self) ) return;
  if (xMSCEBlockTraced(PrsP->Self) != (xIdNode)0) return;
#endif
#endif /* THREADED_MSCTRACE */

  MRESET;
  MCATInstName(PrsP->Self);
  MCAT2(" : action 'task\n%s", In_Str);

  Buf = WriteBuf_New(60);
  if (SortNode != 0)
    xGenericWriteSort(Buf, In_Addr, SortNode);
  if (SortNode != 0 && WriteBuf_Length(Buf) <= 50) {
    MSCFilter(Buf);
    WriteBuf_Add_WriteBuf(MSCE_Buf, Buf);
    MCAT("'; /*");
  } else {
    MCAT(" ...'; /*");
  }
  WriteBuf_Del(&Buf);
  MCATNowAndSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCETransition
-------------------------------------------------------------------*/
void xMSCETransition(
  xPrsNode Process)
{

#ifndef XVALIDATOR_LIB
  xSignalNode Signal;

  if ( ! xSysD.MSCLogStarted) return;
#endif

  /* No trace if procedure start transition */
  if (Process->ActivePrd != (xPrdNode)0 &&
      (Process->ActivePrd->State == START_STATE &&
       Process->pREPLY_Waited_For == (XSIGTYPE)0
      )
     )
    return;

#ifndef XNOUSEOFSERVICE
  if (Process->ActiveSrv != (xSrvNode)0)
    if (Process->ActiveSrv->ActivePrd != (xPrdNode)0 &&
        (Process->ActiveSrv->ActivePrd->State == START_STATE &&
         Process->ActiveSrv->pREPLY_Waited_For == (XSIGTYPE)0
        )
       )
      return;
#endif

  /* No trace if spont trans, startup signal reception or cont. signal */
  if (!Process->Signal || 
      Process->Signal->NameNode->EC == xStartUpSignalEC ||
      Process->Signal->NameNode == xContSigId ||
      Process->Signal->NameNode == xNoneSigId )
    return;

  /* Prevent several inevents */
#ifndef XNOUSEOFSERVICE
  if (Process->ActiveSrv != (xSrvNode)0) {
    if (Process->Signal->NameNode == Process->ActiveSrv->pREPLY_Waited_For)
      Process->ActiveSrv->pREPLY_Waited_For = (XSIGTYPE)0;
  }
  else
#endif
    if (Process->Signal->NameNode == Process->pREPLY_Waited_For)
      Process->pREPLY_Waited_For = (XSIGTYPE)0;

#ifndef XVALIDATOR_LIB
  Signal = XPRS_NEXT_REC_SIG(Process);
  if (! xMSCEOutputTraced(Process->Signal) ) return;
  if (XSIGNAL_GLOBID(Signal) <= xSysD.GlobalSignalInstanceIdWhenStart) {
    PRINTF2(
    "\nSignal %s is sent before MSC trace started,\n  not displayed in MSCE.\n",
          XSIGNAL_IDNODE(Signal)->Name);
    return;
  }
#endif

  if (Process->Signal->NameNode->EC==xSignalEC ||
      Process->Signal->NameNode->EC==xRPCSignalEC) {
    /* Print 'in' statement */
    MRESET;
    MCATInstName(Process->Self);
    MCAT3( " : in %s,%d",
	   Process->Signal->NameNode->Name,
	   Process->Signal->GlobalInstanceId);
    MCATSignalParams(Process->Signal);
    MCAT( " from " );
#ifdef XVALIDATOR_LIB
    if (xEq_SDL_PId(Process->Signal->Sender,xStoppedPId)) {
      /* If Sender has stopped use Receiver as Sender
	 to make MSC editor accept the signal */
      MCATInstName(Process->Signal->Receiver);
    } else {
      MCATInstName2(Process->Signal->Sender, Process->Signal);
    }
#else
    MCATInstName2(XSIGNAL_SENDER(Signal), Process->Signal);
#endif
    MCAT("; /*");

  } else if (Process->Signal->NameNode->EC==xTimerEC) {
    /* Print 'timeout' statement */
    MRESET;
    MCATInstName(Process->Self);
    MCAT3( " : timeout %s,%d; /*",
	   Process->Signal->NameNode->Name,
	   Process->Signal->GlobalInstanceId);
    MCATTimerParams(Process->Signal);
  }
  MCATNowAndSymbolRef();
  MCAT(" */\n");
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCEEnvReceive
-------------------------------------------------------------------*/
void xMSCEEnvReceive(
  xSignalNode Signal)
{
#ifndef XVALIDATOR_LIB
  if ( ! xSysD.MSCLogStarted) return;
  if (! xMSCEOutputTraced(Signal) ) return;
#endif

  if (Signal->NameNode->EC==xTimerEC) {
    /* Print 'timeout' statement */
    MRESET;
    MCATInstName(Signal->Receiver);
    MCAT3( " : timeout %s,%d; /*",
	   Signal->NameNode->Name,
	   Signal->GlobalInstanceId);
    MCATTimerParams(Signal);
    MCAT(" */\n");
    MPRINTF;
  } else {
    /* Print 'in' statement */
    MRESET;
    MCATInstName2(Signal->Receiver, Signal);
    MCAT3( " : in %s,%d",
	   Signal->NameNode->Name,
	   Signal->GlobalInstanceId);
    MCATSignalParams(Signal);
    MCAT( " from " );
    MCATInstName2(Signal->Sender, Signal);
    MCAT(";");
#ifndef XVALIDATOR_LIB
    MCAT(" /*");
    WriteMSCETimeNow();
    MCAT(" */");
#endif
    MCAT("\n");
    MPRINTF;
  }
}

#ifdef XVALIDATOR_LIB
/*---+---------------------------------------------------------------
     xMSCEStart
-------------------------------------------------------------------*/
static void xMSCEStart(
  xIdNode FromNode)
{
  xPrsIdNode  xIdNodeProcess;
  xPrsNode PrsNode;

  for ( xIdNodeProcess = (xPrsIdNode)FromNode->First;
	xIdNodeProcess;
	xIdNodeProcess = (xPrsIdNode)xIdNodeProcess->Suc ){
    if (xIdNodeProcess->EC == xProcessEC) {
      for (PrsNode = xFirstActivePrs(xIdNodeProcess);
	   PrsNode != (xPrsNode)NIL;
	   PrsNode = xNextActivePrs(PrsNode)) {
	xMSCECreate(PrsNode->Self, (xSignalNode)0);
      }
    }
  }
  for ( xIdNodeProcess = (xPrsIdNode)FromNode->First;
	xIdNodeProcess;
	xIdNodeProcess = (xPrsIdNode)xIdNodeProcess->Suc ){
    xMSCEStart((xIdNode)xIdNodeProcess);
  }
}
#else
/*---+---------------------------------------------------------------
     xMSCEStart
-------------------------------------------------------------------*/
static void xMSCEStart(
  xIdNode FromNode)
{
  xIdNode  IdNode;
  xPrsNode PrsNode;

  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    if (IdNode->EC == xProcessEC) {
      for (PrsNode = *((xPrsIdNode)IdNode)->ActivePrsList;
           PrsNode != (xPrsNode)0;
           PrsNode = PrsNode->NextPrs) {
        xMSCECreate(PrsNode->Self, (xSignalNode)0);
      }
    }
    if (IdNode->EC == xBlockEC && xBlockIsBlockTraced((xBlockIdNode)IdNode)) {
      ((xBlockIdNode)IdNode)->GlobalInstanceId = ++xSysD.GlobalProcessInstanceId;
      MRESET;
      MCAT3("%s_%d",
	    ((xBlockIdNode)IdNode)->Name,
	    ((xBlockIdNode)IdNode)->GlobalInstanceId);
      MCAT3(" : instancehead %s %s;",
	    xEntityString[xBlockEC], 
            IdNode->Name);
      MPRINTF;
    }
  }
  for ( IdNode  = FromNode->First;
        IdNode != (xIdNode)0;
        IdNode  = IdNode->Suc ){
    xMSCEStart(IdNode);
  }
}
#endif

#ifdef XVALIDATOR_LIB
/*---+---------------------------------------------------------------
     xMSCEInit
-------------------------------------------------------------------*/
/*
Returns an initialized MSC trace list
*/
char ** xMSCEInit (void)
{
  xMSCETraceList = (char **)NIL;
  MRESET;
  MCAT2("msc %sTrace; /* #SDTMSCTRACE(2.0) */\n", 
	xSystemId->Name);
  MPRINTF;
  MRESET;
  if (topToolType==SET_VALIDATOR) {
    MCAT("text 'Validator trace\ngenerated by\nSDL Validator 4.4';\n");
  } else {
    MCAT("text 'Trace generated by\nSDL to TTCN Link 4.4';\n");
  }
  MPRINTF;
  xMSCECreate(xEnv, (xSignalNode)0);
  xMSCEStart((xIdNode)xSystemId);
  return xMSCETraceList;
}

#else
/*---+---------------------------------------------------------------
     xMSCEInit
-------------------------------------------------------------------*/
void xMSCEInit (void)
{
  xSysD.GlobalSignalInstanceIdWhenStart = xSysD.GlobalSignalInstanceId;
  xSysD.VoidProcessInstanceId = 0;
#ifdef XCONNECTPM
  if (! xSysD.xNoticeBoard.MSCEStarted) {
#endif
    MRESET;
    MCAT2("msc %sTrace; /* #SDTMSCTRACE(2.0) */",
	  xSysD.SystemName);
    MPRINTF;
#ifdef XCONNECTPM
  }
#endif
  MRESET;
  MCAT("text 'Simulation trace\ngenerated by\nSDL Simulator 4.4';");
  MPRINTF;
  xMSCEStart(xSymbolTableRoot);
}
#endif


/*---+---------------------------------------------------------------
     xMSCEConstructor
-------------------------------------------------------------------*/
void xMSCEConstructor(
  SDL_PId  P,
  char * VarName,
  char * ClassName)
{
#ifndef XVALIDATOR_LIB
  /* Trace if: Created process traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if ( ! xIsMSCETraced(P) ) return;
  if (xMSCEBlockTraced(P) != (xIdNode)0) return;
#endif

  MRESET;
  MCAT3("%s : instancehead Class %s;\n",
	VarName, ClassName);
  MPRINTF;

  MRESET;
  MCATInstName(P);
  MCAT2(" : create %s;", VarName);
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCEDestructor
-------------------------------------------------------------------*/
void xMSCEDestructor(
  SDL_PId  P,
  char * VarName)
{
#ifndef XVALIDATOR_LIB
  /* Traced if process is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if ( ! xIsMSCETraced(P) ) return;
  if (xMSCEBlockTraced(P) != (xIdNode)0) return;
#endif

  MRESET;
  MCAT2("%s : stop;", VarName);
  MPRINTF;
}


/*---+---------------------------------------------------------------
     xMSCEMethodCall
-------------------------------------------------------------------*/
void xMSCEMethodCall(
  SDL_PId  P,
  char * VarName,
  char * MethodName)
{
  int SignalNumber;
#ifndef XVALIDATOR_LIB
  /* Traced if process is traced and not block trace */
  if ( ! xSysD.MSCLogStarted) return;
  if ( ! xIsMSCETraced(P) ) return;
  if (xMSCEBlockTraced(P) != (xIdNode)0) return;
#endif

  SignalNumber = ++XSYSD GlobalSignalInstanceId;

  MRESET;
  MCATInstName(P);
  MCAT4(" : out %s,%d to %s;", 
	MethodName, SignalNumber, VarName);
  MPRINTF;

  MRESET;
  MCAT4("%s : in %s,%d from ;", 
	VarName, MethodName, SignalNumber);
  MCATInstName(P);
  MPRINTF;

  MRESET;
  MCAT4("%s : out %s,%d to ", 
	VarName, MethodName, SignalNumber);
  MCATInstName(P);
  MCAT(";");
  MPRINTF;

  MRESET;
  MCATInstName(P);
  MCAT4(" : in %s,%d from %s;", 
	MethodName, SignalNumber, VarName);
  MPRINTF;
}


#endif
/*************************** END XMSCE *****************************/

