Example: Using registration facility APIs

These ILE C programs show how to register an exit point, how to add an exit program to the exit point, and how to call the exit program based on the exit point information that is retrieved.

This example does not include any of the programs that are being called, nor does it show anything but an excerpt of the calling program.
Note: By using the code examples, you agree to the terms of the Code license and disclaimer information.

The first thing to do, after deciding in what program object the exit point is to be placed, is to register that exit point. It is also important to remember that the exit point format defines what the exit program data looks like. This ILE C program registers an exit point named QIBM_QXIC_TSTXPOINTA.

/********************************************************************/
/*  PROGRAM:      RegisterPoint                                     */
/*                                                                  */
/*  LANGUAGE:     ILE C                                             */
/*                                                                  */
/*  DESCRIPTION:  This program registers an exit point in an        */
/*                application.                                      */
/*                                                                  */
/* APIs USED:     QusRegisterExitPoint                              */
/*                                                                  */
/********************************************************************/
#include <string.h>
#include <qusec.h>
#include <qusrgfa1.h>

/********************************************************************/
/*  Structure for the control block                                 */
/********************************************************************/
typedef _Packed struct Control_x{
        int                  Num_Vlen_Recs;
        Qus_Vlen_Rec_4_t     Vlen_Rec_1;
        char                 Description[50];
} Control_Rec;


int main () {

   Qus_EC_t     Error_Code     = {0};

   char         EPnt_Name[20]  = "QIBM_QXIC_TSTXPOINTA";
   char         EPnt_F_Name[8] = "USUSOOOO";
   int          EProg_Number   = -1;
   Control_Rec  EPnt_Controls  = {0};

/*****************************************
*** INITIALIZING ALL STRUCTURES::      ***
*****************************************/

   Error_Code.Bytes_Provided = sizeof(Error_Code);

   EPnt_Controls.Num_Vlen_Recs = 1;
   EPnt_Controls.Vlen_Rec_1.Length_Vlen_Record = 62;
   EPnt_Controls.Vlen_Rec_1.Control_Key = 8;
   EPnt_Controls.Vlen_Rec_1.Length_Data = 50;
   memcpy( EPnt_Controls.Description , "Example Exit Point" , 17 );

   QusRegisterExitPoint (EPnt_Name,
                         EPnt_F_Name,
                         &EPnt_Controls,
                         &Error_Code);
   if ( Error_Code.Bytes_Available ) {
      printf("\nEXCEPTION : %s",Error_Code.Exception_Id);
      exit (1);
   }
   return(0);
}

After an exit point has been registered, exit programs must be added to that point, indicating the possible calls based on runtime conditions. The following ILE C program adds an exit program named TSTXITPROGQGPL to the QIBM_QXIC_TSTXPOINTA exit point that is registered in the previous example.

/********************************************************************/
/*  PROGRAM:      AddProgram                                        */
/*                                                                  */
/*  LANGUAGE:     ILE C                                             */
/*                                                                  */
/*  DESCRIPTION:  This program adds an exit program to a registered */
/*                exit point.                                       */
/*                                                                  */
/* APIs USED:     QusAddExitProgram                                 */
/*                                                                  */
/********************************************************************/

#include <qusec.h>
#include <qusrgfa1.h>

/********************************************************************/
/*  Structure for the Exit Program Attributes                       */
/********************************************************************/

typedef _Packed struct Xit_Att{
        int                  Num_Vlen_Recs;
        Qus_Vlen_Rec_4_t     ADPG_Vlen;
        int                  CCSID;
        char                 Reserved;
} Xit_Attributes;

int main () {

   Qus_EC_t       Error_Code       = {0};

   char           EPnt_Name[20]    = "QIBM_QXIC_TSTXPOINTA";
   char           EPnt_F_Name[8]   = "USUSOOOO";
   int            EProg_Number     = -1;
   char           Q_EProg_Name[20] = "TSTXITPROGQGPL      ";
   char           EProg_Data[10]   = "EXAMPLE   ";
   int            Len_EProg_Data   = sizeof(EProg_Data);
   Xit_Attributes EProg_Attributes;


   Error_Code.Bytes_Provided=sizeof(Error_Code);

   EProg_Attributes.Num_Vlen_Recs=1;
   EProg_Attributes.ADPG_Vlen.Length_Vlen_Record=16;
   EProg_Attributes.ADPG_Vlen.Control_Key=3;
   EProg_Attributes.ADPG_Vlen.Length_Data=4;
   EProg_Attributes.CCSID = 37;

   QusAddExitProgram (EPnt_Name,
                      EPnt_F_Name,
                      EProg_Number,
                      Q_EProg_Name,
                      EProg_Data,
                      Len_EProg_Data,
                      &EProg_Attributes,
                      &Error_Code);
   if ( Error_Code.Bytes_Available ) {
      printf("\nEXCEPTION : %s",Error_Code.Exception_Id);
      exit (1);
   }
   return(0);
}

When you have registered an exit point and have added the exit programs to that exit point, you can do exit program calls from within your application. The information needed to do the calls is obtained from the Retrieve Exit Information API. In the following sample a conditional call is made based on the exit point information.

/********************************************************************/
/*  PROGRAM:      RetrieveAndProcess                                */
/*                                                                  */
/*  LANGUAGE:     ILE C                                             */
/*                                                                  */
/*  DESCRIPTION:  This is an excerpt of a program that retrieves    */
/*                information on an exit point, and does processing */
/*                based on that information.                        */
/*                                                                  */
/* APIs USED:     QusRetrieveExitInformation                        */
/*                                                                  */
/********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <qusec.h>
#include <qusrgfa2.h>

/********************************************************************/
/*  Structure for Selection Criteria on the Retrieve                */
/********************************************************************/
typedef _Packed struct RTVEI_Select_C_x {
        Qus_Selcrtr_t        Crit;
        Qus_Select_Entry_t   Select_Entry;
        char                 RTV_String[10];
} RTVEI_Select_C;

/********************************************************************/
/*  Conv_Lib converts the library name to a null terminated string  */
/********************************************************************/

char * Conv_Lib(char in_lib[], char *tmp) {
      int x = 0;

      while ( (in_lib[x] != ' ') && x!=10 ) {
         *tmp=in_lib[x++];
         tmp++;
      }
      return(tmp);
}

int main() {

   Qus_EXTI0200_t       *EXTI0200;
   Qus_EXTI0200_Entry_t *EXTI0200_Entry;
   char                 *Pgm_Data;

   Qus_EC_t        Error_Code= {0};

   char            EPnt_Name[20]  = "QIBM_QXIC_TSTXPOINTA";
   char            EPnt_F_Name[8] = "USUSOOOO";
   int             EProg_Number   = -1;

   int             Counter;
   char            *tmp_str;
   char            *lib;

   char            Handle[16]     = "                ";
   int             Length_Of_R_Var;
   char            RTVEI_Format_Name[8];
   RTVEI_Select_C  EProg_Select_C = {0};


/*****************************************
*  Initializing Structures               *
*****************************************/

   Error_Code.Bytes_Provided = sizeof(Error_Code);

   tmp_str=(char *)malloc(sizeof(char));
   lib=(char *)malloc(sizeof(char));
   EXTI0200=(Qus_EXTI0200_t *) malloc ( ( sizeof( Qus_EXTI0200_t ) +
        sizeof( Qus_EXTI0200_Entry_t ) + MAX_PGM_DATA_SIZE ) * 2 );
   EProg_Select_C.Crit.Number_Sel_Criteria = 1;
   EProg_Select_C.Select_Entry.Size_Entry = 26;
   EProg_Select_C.Select_Entry.Comp_Operator = 1;
   EProg_Select_C.Select_Entry.Start_Pgm_Data = 0;
   EProg_Select_C.Select_Entry.Length_Comp_Data = 10;
   memcpy( EProg_Select_C.RTV_String , "EXAMPLE   " , 10 );

   Length_Of_R_Var = (sizeof( Qus_EXTI0200_t ) +
                sizeof( Qus_EXTI0200_Entry_t ) +
                MAX_PGM_DATA_SIZE) *2;
   memcpy( RTVEI_Format_Name , "EXTI0200" , 8 );

   QusRetrieveExitInformation (Handle,
                               EXTI0200,
                               Length_Of_R_Var,
                               RTVEI_Format_Name,
                               EPnt_Name,
                               EPnt_F_Name,
                               EProg_Number,
                               &EProg_Select_C,
                               &Error_Code);
   if ( Error_Code.Bytes_Available ) {
      printf("\nEXCEPTION : %s",Error_Code.Exception_Id);
      exit (1);
   }

/********************************************************
*  Call all of the preprocessing exit programs returned *
********************************************************/
   Counter=EXTI0200->Number_Programs_Returned;

   while ( Counter-- ) {

     EXTI0200_Entry = (Qus_EXTI0200_Entry_t *) EXTI0200;
     EXTI0200_Entry = (Qus_EXTI0200_Entry_t *)((char *)EXTI0200 +
                       EXTI0200->Offset_Program_Entry);
     Pgm_Data = (char *) EXTI0200_Entry;
     Pgm_Data += EXTI0200_Entry->Offset_Exit_Data;

     Conv_Lib(EXTI0200_Entry->Program_Library,lib);

     sprintf( tmp_str , "CALL  %s/%.10s %.*s" ,
          lib,
          EXTI0200_Entry->Program_Name,
          EXTI0200_Entry->Length_Exit_Data,
          Pgm_Data );
     system( tmp_str );
/********************************************************
*  This is where Error Handling on the exit program     *
*  would be done.                                       *
********************************************************/
     if ( Counter ) {
         memcpy(EXTI0200->Continue_Handle,Handle,16);
         QusRetrieveExitInformation(Handle,
                                    EXTI0200,
                                    Length_Of_R_Var,
                                    RTVEI_Format_Name,
                                    EPnt_Name,
                                    EPnt_F_Name,
                                    EProg_Number,
                                    &EProg_Select_C,
                                    &Error_Code);
         if ( Error_Code.Bytes_Available ) {
            printf("\nEXCEPTION : %s",Error_Code.Exception_Id);
            exit (1);
         }
      }
   }

   return(0);
}