This example shows how to use the registration facility in one of your programs. The example does not include any of the programs that are being called, nor does it show anything but an excerpt of the calling program.
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. Here is an example ILE C program that 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 run-time conditions. The following is an example in ILE C, of how to add an exit program to a registered exit point. The exit program named TSTXITPROGQGPL is added to the exit point registered in the previous example named QIBM_QXIC_TSTXPOINTA.
/********************************************************************/ /* 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); }