/******************************************************************************
 * Copyright by Telelogic AB 1999
 *
 *  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.
 *****************************************************************************/


/*
  N.B.
  Please refer to: 
  <Install Dir>/examples/msctrace/<Platform specific path>/msctracedemo.c
  for an example of how this interface is used.
  */

#ifndef msctrace_h
#define msctrace_h

#ifdef __cplusplus
#define CONST const
#define STANDARDBOOL
extern "C" {
#else
#define CONST
#endif

  

/* Declarations */
/*************************************************************************/
/*************************************************************************/

#ifndef STANDARDBOOL
#ifndef bool
typedef int bool;
#endif

#ifndef true
extern CONST int true;
extern CONST int false;
#endif
#endif /* STANDARDBOOL */

typedef unsigned int MTIdentifier;
typedef char MTIdString[(sizeof (MTIdentifier)) *3 +1];

typedef struct mtDiagram_* MTDiagram;

typedef enum MTErrId_ {
  NoError,
  UnknownError,
  StartingToolFailed,
  StartingPostMasterFailed,
  StartingMSCEFailed,
  SendPRFailed,
  WritePRFailed,
  MemError,
  CreatingMSCDiagramFailed,
  LoadingMSCDiagramFailed,
  ClearingMSCDiagramFailed,
  ClosingMSCDiagramFailed,
  TerminatingMSCEFailed,
  OpeningFileFailed,
  ShowingDiagramFailed,
  ShowingObjectFailed
} MTErrId;

  
/* Functional Interface */
/*************************************************************************/
/*************************************************************************/

/* NOTE:
   A name inside angle brackets (e.g. <name>) refers to the variable in the
   function prototype.
   */


/* Error handling */
/*************************************************************************/
/*
  The error functions are divided into two parts:
   
  * Errors that comes directly through the interface
 
  * Errors that either occurs due to failiure in the communication
    with the MSC Edítor/Tracer or due to the fact that some
    error condition/problem was detected in the MSC Editor/Tracer.

  Each of these types of errors is accessible either as a string or as
  an identifier. The latter is interesting for determining the program
  execution (e.g. detecting that the user does not have an MSC
  license) while the first is interesting when giving feedback to the customer
  or while debugging.
  */

CONST MTErrId MTGetLastError (CONST MTDiagram diagram);
/*
  Gets the error code of the last error that occured.
  */

CONST char*   MTGetLastErrorStr (CONST MTDiagram diagram);
/*
  Gets a explanatory text associted with the error that occured.
  */

CONST MTErrId MTGetLastPMError (CONST MTDiagram diagram);
/*
  Gets the error code associated with the communication error
  or the error condition in the MSC Editor/Tracer.
  */

CONST char*   MTGetLastPMErrorStr (CONST MTDiagram diagram);
/*
  Gets an explanatory text associted with the communication
  error that occured.
  */

/* MSCE Control */
/*************************************************************************/
/* This part of the interface is used to control the MSC Editor/Tracer
   
   Some functions here are not related to tracing at all, but are useful
   for other purposes.
   */
  

bool MTLoadMSC_File (MTDiagram *pDiagram, CONST char* fileName);
/* Loads the specified MSC (PR) file into the MSCE.
   <pDiagram> is allocated for you and accociated with the
   diagram that is defined by <filename>. You should call one of
   the functions (MTEndMSCDiagram, MTTerminateMSCE) that releases
   this reasource at some later time. Read the specifics on these functions
   to decide when which of these functions is appropriate.

   This function might be useful if you have made a trace on file
   and want your tool to show it automatically.
   */


bool MTClearDiagram (MTDiagram diagram);
/*
  Removes all the symbols in the diagram accociated with <diagram>,
  only the diagrams name is preserved.
  */

bool MTTerminateMSCE (MTDiagram* diagram);
/*
  Terminates the MSCE, Should only be called if either MTLoadMSC_File or
  MTStartMSCDiagram fails (returns false) and <diagram> != NULL
  and MTLastError returns <CreatingMSCDiagramFailed> (typically this
  indicates that the MSC Editor/Tracer was started, but could not
  create a diagram (e.g. no license was obtained).

  In this situation an MSC Editor/Tracer is running, but the user
  has no possibility to terminate the editor, since he has no
  window to interact with.
  */

bool MTDisconnect (void);
/* Call this function before exiting your application in order to notify
   the application (the postmaster) that takes care of the communication
   between the MSC Editor/Tracer and your application/this library.
   */

/* Tracing */
/*************************************************************************/
/* This part of the interface is used for generating MSC Traces,
   either on file or Interactively (i.e. symbols show up in the MSC
   Editor/Tracer as each function call is made).
   */
  
bool MTStartMSCDiagram (MTDiagram* pDiagram,
                        CONST char* diagramName,
                        CONST char* filePath);
/* Creates a new MSC Diagram with <diagramName>
   
   If a filename is provided (<filePath> != NULL) then a log of the events is
   created on the specified file (if no file related errors occur).
   
   If no filename is provided (<filePath> == NULL) a new MSC diagram is
   created in the MSC Editor/Tracer in "real-time"
   Please also consult MTShowLastObject and MTShowDiagram.
  
   If no postmaster is running, it is started.  
   If the MSC Editor/Tracer is not running, it also started.

   Please however ensure that these applications are either in the current
   directory or in the path.

   This function emits the following PR:
   mscdiagram <diagramName>;
   */

bool MTEndMSCDiagram (MTDiagram* pDiagram);
/* Ends the tracing of an MSC Diagram.
   
   The function either closes the connection to the current MSC Editor/Tracer
   (if you are tracing interactively) or emits the following PR:
   endmsc;
   and closes the PR File.
   
   After calling this function <pDiagram> is invalid (== NULL) and may
   not be used in this state again.
   All resources asociated with that diagram are released.
   */


/* Misc. helper routines for tracing */

MTIdentifier MTGetNewIdentifier (MTDiagram diagram);
/* This function creates an identifier that can be used to create
   either a timerIdentification or a msgIdentification.
   The identifier is transformed to a string with MTIdentifierToStr

   It's primary use is when the identification of these entities
   is not inherently provided by the events that are traced.
   */

void MTIdentifierToStr (CONST MTIdentifier identifier, MTIdString idString);
/* Transformes a identifier to a string*/

int MTGetLastObjectId (CONST MTDiagram diagram);
/* Useful for remembering a specific object's identity.
   Makes it possible to show that object later stage with MTShowObject.
   */

bool MTShowLastObject (CONST MTDiagram diagram, CONST bool fRaiseWindow);
/* Shows the last object that was inserted into <diagram> in the
   MSC Editor/Tracer.
   If <fRaiseWindow> is true the window is activated and placed topmost.
   If <fRaiseWindow> is false the window stays at the position it had.

   This function has no effect if <diagram> was created with
   MTStartMSCDiagram with <filePath> != NULL, since then that
   diagram is not connecected to an MSC Editor/Tracer.

   Note that if your diagram is connected to an MSC Editor/Tracer
   this functions should be called with <fRaiseWindow> == true atleast once
   in order to show the diagram. Another possibility is to call MTShowDiagram.

   Please note that this function will fail if the user succedes to remove
   the "last" object before this function is called.
   */

bool MTShowObject (CONST MTDiagram diagram,
                   CONST int objId,
                   CONST bool fRaiseWindow);
/* Calling
   MTShowObject (diagram, MTGetLastObjectId (diagram), fRaiseWindow);
   is analogous to calling:
   MTShowLastObject (diagram, fRaiseWindow);
   */
   

bool MTShowDiagram (CONST MTDiagram diagram);
/* Shows a diagram by rasing a window and showing the diagram
   accociated with <diagram> in it */


/* MSC PR wrappers */

/* These functions are used to either create PR on a file or create the
   corresponding object in the MSC Editor/Tracer.

   There is an example application in:
   <Install Dir>/examples/msctrace/<Platform specific path>/msctracedemo.c
   that will help you to get a feeling for what these functions do.

   Please study it an run it.

   GENERAL NOTES:
   Square brackets "[ optional ]" are used to show which parameters are
   optional. Unless specifically noted an optional parameter that should not
   receive a value should have NULL as a paramter.

   The strings provided must obey the lexical rules of the MSC'96 standard.
   The only exception to this rule is the strings provided in Text, Comment
   and Action symbols. The string delimeter escaping is done for you, so
   you only need to provide the strings "as is".

   Parameter sdtRef (and its variants creatingSdtRef and createdSdtRef)
   are reserved for future use and should allways be NULL.

   Supplying a value to commentText (and its variants) appends a comment
   symbol with the provided text in the appropriate place.

   Parameter sdtNow (and its variants) is the time a specific event
   occurred. This value can be viewed in the MSC Editor/Tracer info window.

   Generally you should always provide msg and timer identifications
   (<msgIdentification> and <timerIdentification>) in order to uniquely
   identify messages and timers that have the same name. Note that
   it is possible (and allowed) to send two messages (named m) from
   instance (named a) to instance (named b). When instance b then receives
   the messages (named m) it can not determine which of the messages is
   received first (it IS possible to have a situation that the message
   that is sent last is received first). Unless the msg and timer
   identification is not specified, the MSc Editor/Tracer has no means
   of discriminate between these two cases.

   Since the C comment coincides with the MSC note (notes in MSC corresponds
   to C comments), we will write MSC notes in the documentation (incorrectly)
   in order not to interfere with the source code in this file as:
   / * note * /
   and not (correctly) as:
   /* note */


bool MTInstanceHead (MTDiagram diagram,
                     CONST char* instanceName,
                     CONST char* kindDenominatorName,
                     CONST char* qualifierText,
                     CONST char* instanceKindName,
                     CONST char* decomposition,
                     CONST char* commentText,

                     CONST char* sdtNow,
                     CONST char* sdtRef);

/*
  MTInstanceHead generates an instance head in the MSC Editor/Tracer
  
  On file the corresponding PR is Generated:
  [/ * #SDTNOW(<sdtnow>) * /] 
  <instanceName> : instance
  [ [<kindDenominatorName>] [<< <qualifierText> >>] instanceKindName]
  [ [decomposed [as <decomposition>] ]
  [comment '<commentText>'];
  
  NOTE:
  The <decomposition> parameter works not in a standard way:
  If <decomposition> == NULL        no "decomposed is generated.
  If <decomposition> == ""          only "decomposed" is generated.
  If <decomposition> == "instName"  then "decomposed as instName" is generated.
  */


bool MTCreateInstance (MTDiagram diagram,
                       CONST char* creatingInstanceName,
                       CONST char* creatingParameterList,
                       CONST char* creatingCommentText,
                       CONST char* creatingSdtNow,
                       CONST char* creatingSdtRef,
                       
                       CONST char* createdInstanceName,
                       CONST char* kindDenominatorName,
                       CONST char* qualifierText,
                       CONST char* instanceKindName,
                       CONST char* decomposition,
                       CONST char* createdCommentText,

                       CONST char* createdSdtNow,
                       CONST char* createdSdtRef);
/*
  MTCreateInstance generates an instance creation.

  On file the corresponding PR is generated:
  PR corresponding to MTInstanceHead is generated for the
  parametrs starting at <createdInstanceName>, then the following
  PR is generated:
  <creatingInstanceName> : create [/ * #SDTNOW(<creatingSdtNow>) * /]
  createdInstanceName [comment '<commentText>'];
  */


bool MTInstanceEnd  (MTDiagram diagram,
                     CONST char* instanceName,
                     CONST char* commentText,

                     CONST char* sdtNow,
                     CONST char* sdtRef);
/*
  MTInstanceEnd ends an instance. Semantically this instance is not
  terminated, more communication can however not take place in this
  MSC diagram (see MTStopInstance for comparison).

  The following PR is generated:
  <instanceName> : [/ * #SDTNOW(<sdtNow>) * /] end [comment '<commentText>'];
  */


bool MTStopInstance (MTDiagram diagram,
                     CONST char* instanceName,
                     CONST char* commentText,
                     
                     CONST char* sdtNow,
                     CONST char* sdtRef);
/*
  MTStopInstance terminates an instance. Semantically this instanace is
  destroyed and any comunication with this instance is impossible (see
  MTInstanceEnd for comparison).

  The following PR is generated:
  <instanceName> : [/ * #SDTNOW(<sdtNow>) * /] stop [comment '<commentText>'];
  */


bool MTAction (MTDiagram diagram,
               CONST char* instanceName,
               CONST char* actionText,
               CONST char* commentText,
               
               CONST char* sdtNow,
               CONST char* sdtRef);
/*
  MTAction adds an action on the specified instance.

  The following PR is generated:
  <instanceName> : action [/ * #SDTNOW(<sdtNow>) * /] '<actionText>'
  [comment '<commentText>'];
  */


bool MTStartTimer (MTDiagram diagram,
                   CONST char* instanceName,
                   CONST char* timerName,
                   CONST char* timerIdentification,
                   CONST char* duration,
                   CONST char* parameterList,
                   CONST char* commentText,

                   CONST char* sdtNow,
                   CONST char* sdtRef);
/*
  MTStartTimer starts a timer on the specified instance.

  The following PR is generated:
  <instanceName> : set [/ * #SDTNOW(<sdtNow>) * /] <timerName>
  [, <timerIdentification>] [(<duration>)] [/ * #SDTPARAM(<parameterList>) * /]
  [comment '<commentText>'];
  */


bool MTStopTimer (MTDiagram diagram,
                  CONST char* instanceName,
                  CONST char* timerName,
                  CONST char* timerIdentification,
                  CONST char* commentText,

                  CONST char* sdtNow,
                  CONST char* sdtRef);
/*
  MTStopTimer stops a timer.

  The following PR is generated:
  <instanceName> : reset [/ * #SDTNOW(<sdtNow>) * /] <timerName>
  [, <timerIdentification>] [comment '<commentText>'];
  */


bool MTTimeout (MTDiagram diagram,
                CONST char* instanceName,
                CONST char* timerName,
                CONST char* timerIdentification,
                CONST char* commentText,

                CONST char* sdtNow,
                CONST char* sdtRef);
/*
  MTTimout makes a timer expire (timeout).

  The following PR is generated:
  <instanceName> : timeout [/ * #SDTNOW(<sdtNow>) * /] <timerName>
  [, <timerIdentification>] [comment '<commentText>'];
  */

bool MTSendMessage (MTDiagram diagram,
                    CONST char* fromInstanceName,
                    CONST char* toInstanceName,
                    CONST char* messageName,
                    CONST char* msgIdentification,
                    CONST char* parameterList,
                    CONST char* commentText,

                    CONST char* sdtNow,
                    CONST char* sdtRef);
/*
  MTSendMessage sends a message from one instance to another.
  Note that the message is only connected to the "from" instance, and
  the to instance will be represented by a black hole (lost message).

  The following PR is generated:
  <fromInstanceName> : out [/ * #SDTNOW(<sdtNow>) * /] <messageName>
  [, <msgIdentification>] [(<parameterList>)] to <toInstanceName>
  [comment '<commentText>'];
  */



bool MTLostMessage (MTDiagram diagram,
                    CONST char* fromInstanceName,
                    CONST char* toInstanceName,
                    CONST char* messageName,
                    CONST char* msgIdentification,
                    CONST char* parameterList,
                    CONST char* commentText,

                    CONST char* sdtNow,
                    CONST char* sdtRef);
/*
  MTLostMessage produces a lost message ("black hole"). The message starts
  at the <fromInstnace> and if the optional <toInstance> is specified, that
  instance name will appear beside the "black hole"

  The <msgIdentification> needs only be specified when a message that
  was sent from one instance to another instance (with MTSendMessage)
  later proves to get lost. If it is possible to detect that a message
  is lost right away (i.e. MTLostMessage is called without sending the message
  first), the msgIdentification has no function

  The following PR is generated:
  <fromInstanceName> : out [/ * #SDTNOW(<sdtNow>) * /] <messageName>
  [, <msgIdentification>] [(<parameterList>)] to lost [<toInstanceName>]
  [comment '<commentText>'];
  */


bool MTReceiveMessage (MTDiagram diagram,
                       CONST char* fromInstanceName,
                       CONST char* toInstanceName,
                       CONST char* messageName,
                       CONST char* msgIdentification,
                       CONST char* parameterList,
                       CONST char* commentText,

                       CONST char* sdtNow,
                       CONST char* sdtRef);
/*
  MTReceiveMessage receives a message from one instance to another.
  Note that if there is no sent message with <msgIdentification> in the
  current diagram a found message will be produced. The reason for this is
  that sometimes you do not want to trace from the point when your
  system starts, but instead wait until it gets "interesting". In this case
  some message(s) may have been sent at an earlier time, but not received until
  now.

  If the <msgIdentification> is found the sent message is connected to the
  receiveing instance.
  
  The following PR is generated:
  <toInstanceName> : in [/ * #SDTNOW(<sdtNow>) * /] <messageName>
  [, <msgIdentification>] [(<parameterList>)] from <fromInstanceName>
  [comment '<commentText>'];
  */


bool MTFoundMessage (MTDiagram diagram,
                     CONST char* fromInstanceName,
                     CONST char* toInstanceName,
                     CONST char* messageName,
                     CONST char* parameterList,
                     CONST char* commentText,

                     CONST char* sdtNow,
                     CONST char* sdtRef);
/*
  MTFoundMessage produces a found message ("white hole"). The message ends
  at the <toInstnace> and if the optional <fromInstance> is specified, that
  instance name will appear beside the "white hole"
  
  Contrary to MTLostMessage, MTFoundMessage has not <msgIdentification>
  as parameter since the situation when you transform a received message to
  a lost message is either done automatically (the message was never "sent")
  or has not meaningful interpretation.
  
  The following PR is generated:
  <toInstanceName> : in [/ * #SDTNOW(<sdtNow>) * /] <messageName>
  [(<parameterList>)] from found [<fromInstanceName>]
  [comment '<commentText>'];
  */


bool MTStartCoregion (MTDiagram diagram,
                      CONST char* instanceName,
                      CONST char* commentText,
                      
                      CONST char* sdtNow,
                      CONST char* sdtRef);
/*
  MTStartCoregion starts a coregion on the specified instance.
  
  The following PR is generated:
  <instanceName> : concurrent [/ * #SDTNOW(<sdtNow>) * /]
  [comment '<commentText>'];
  */
  

bool MTEndCoregion   (MTDiagram diagram,
                      CONST char* instanceName,
                      CONST char* commentText,

                      CONST char* sdtNow,
                      CONST char* sdtRef);
/*
  MTEndCoregion ends a coregion.
  
  The following PR is generated:
  <instanceName> : endconcurrent [/ * #SDTNOW(<sdtNow>) * /]
  [comment '<commentText>'];
  */


bool MTCondition (MTDiagram diagram,
                  CONST char* instanceName,
                  CONST char* conditionText,
                  CONST char* commentText,

                  CONST char* sdtNow,
                  CONST char* sdtRef);
/*
  MTCondition places a condition on a specific instance.
  Note that the <conditionText> must be a comma separated list of names.

  Note also that unlike for other MTxxx functions that takes an instance
  name as a parameter, MTConition can actually take a comma separated
  list as a parameter to <instanceName>. A warning of using this feature
  is however in place. If you are tracing a system with different processes
  that are not syncronized in any way it is hard to determine when both
  instances are in such a state that it is possible to emit a condition
  that spans several instance axis. In this case it is better to let each
  process emit its condition at the apropriate time.

  The following PR is generated:
  <instanceName> : condition [/ * #SDTNOW(<sdtNow>) * /] conditionText
  [comment '<commentText>'];
  */


bool MTText (MTDiagram diagram,
             CONST char* text,

             CONST char* sdtNow,
             CONST char* sdtRef);
/*
  MTText places a text symbol in the MSC Diagram. Sínce text symbols
  are only placed at the top of the diagram from the left to the right,
  They are only useful for recording information about the trace
  (e.g. what executable was traced, at what time, etc.).

  If you want text near a specific event, supply that string to
  the <commentText> parameter for the apropriate event.


  The following PR is generated:
  text [/ * #SDTNOW(<sdtNow>) * /] '<text>';
  */



#ifdef NOTNOW
/* These functions are not supported in this version */

bool MTSDTSetRefToolId    (MTDiagram diagram, CONST char* toolID);
void MTSetTraceTool       (CONST char* traceToolId);
void MTSetTraceToolSource (MTDiagram diagram, CONST char* traceToolSource);


typedef void (* MTNavigateToSDTRef) (CONST char* userString);

void MTSetNavigeteToSDTRefCallback (MTNavigateToSDTRef * userFunction);
#endif /* NOTNOW */


#ifdef __cplusplus
}
#endif

#endif /* msctrace_h */
