EGL main Text UI programs that are generated for the IMS/VS target environment run as IMS™ message processing programs (MPPs).
If the target transaction is a non-EGL program that needs form input from the message queue at the start of processing, the EGL program should use a deferred program-to-program message switch (EGL show statement). Otherwise, the EGL program should use an immediate program-to-program message switch (EGL transfer to transaction statement).
The following table shows the methods used to pass data between conversational programs (generated with spaSize > 0 build descriptor option).
| Action | Immediate switch (optional input form) | Deferred switch (with input form) |
|---|---|---|
| Coding and generating | Define both programs as segmented = YES. Generate both programs as conversational (spaSize > 0). | Define both programs as segmented = YES. Generate both programs as conversational (spaSize > 0). |
| Performing the transfer | The transferring program cannot send a form. If it is an EGL program, it uses a transfer to transaction statement to send a record. | The transferring program must write the form to a message queue associated with the terminal after first writing the SPA. If it is an EGL program, it does this using a show with a form and an optional record. |
| Using an input form | The target program can optionally have an input form. | The target program must have an input form. |
| Passing a record | The record is transferred in the SPA. | The record, if any, is transferred in the SPA. |
| Specifying segmentation status byte | If spaStatusBytePosition is specified, the segmentation status byte is always placed in the last byte of the SPA. The target program always ignores the value of the segmentation status byte. | If spaStatusBytePosition=n is specified, the segmentation status byte is placed in either position 15 or the last byte of the SPA, based on the value of n. The target program uses the value of the segmentation status byte when there is an input form integrity problem caused by the program user pressing PA1 or PA2. |
| Note: The segmentation status byte specified by spaStatusBytePosition is used only for program-to-program transfers for conversational programs. The byte is present for transfers between conversational programs and other programs. However, a transferring non-EGL program should always set the byte to blank. A target non-EGL program should always ignore the value of the segmentation status byte. | ||
With this technique, two segmented conversational EGL programs can change both the transaction name and the PSB name without presenting a form to the program user. Different FormGroups can be used by the two programs. The example below shows a skeleton definition of the two programs.
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord1",
@DLI { psb="psb" } }
// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1A;
// FormGroup
use FORMGX;
function main()
...
sysVar.transferName = 'trx1b';
transfer to transaction sysVar.transferName passing basicRecord1;
...
end // end main
end // end ProgramA
program ProgramB type textUIProgram // inputForm is optional
{segmented=yes, inputRecord="basicRecord1", inputForm="form2",
@DLI { psb="psb" } }
// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1B;
// FormGroup
use FORMGY;
function main()
// generated EGL logic does the following:
// initializes basicRecord1
// if inputForm is specified:
// converses form2
// performs edits for form2
// converses form2 until form2 passes all edits
// gives control to the first statement in the main function
...
end // end main
end // end ProgramB
The EGL-generated program control logic automatically handles the SPA and the record (basicRecord1) that is passed from Program A to Program B. The data area of the SPAs for programs A and B must be at least large enough to hold the larger of the records involved.
The non-EGL program must be an IMS conversational program. The EGL program must be defined similarly to program B in "Immediate switch between two EGL programs" above. The spaSize build descriptor option must specify the SPA size that is being used by the non-EGL program.
If you specified spaSize=n and spaStatusBytePosition=p as build descriptor options, the segmentation status byte is at the end of the SPA, regardless of the value of spaStatusBytePosition. The non-EGL program should initialize the segmentation status byte to blank before inserting the SPA.
The non-EGL program must be an IMS conversational program. The EGL program must be defined similarly to program A in "Immediate switch between two EGL programs" above. The spaSize build descriptor option must specify the SPA size that is being used by the non-EGL program.
The non-EGL program must issue a get unique to the I/O PCB to read the SPA. For the required layout of the SPA, see “Format of the IMS SPA for message switching.” The SPA is created by the EGL program control logic. The data area of the SPA contains the record that the EGL program passed on the transfer to transaction statement.
If you specified spaSize=n and spaStatusBytePosition=p as build descriptor options, the segmentation status byte is at the end of the SPA, regardless of the value of spaStatusBytePosition. The non-EGL program should ignore the last byte of the SPA.
With this technique, two segmented conversational EGL programs can change both the transaction name and the PSB name when a form is presented to the program user. You must use the same FormGroup for both programs. You do not have to transfer a record, but a form is required. The example below shows a skeleton definition of the two programs.
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord2",
@DLI { psb="psb" } }
// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2A;
// FormGroup
use FORMG2;
function main()
...
sysVar.transferName = 'trx2b';
show form2 returning to sysVar.transferName passing basicRecord2;
...
end // end main
end // end ProgramA
program ProgramB type textUIProgram // inputForm is required
{segmented=yes, inputRecord="basicRecord2", inputForm="map2",
@DLI { psb="psb" } }
// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2B;
// FormGroup
use FORMG2;
function main()
// generated EGL logic does the following:
// initializes basicRecord2
// performs edits for map2
// converses map2 until map2 passes all edits
// gives control to the first statement in the main function
...
end // end main
end // end ProgramB
The non-EGL program must be an IMS conversational program. The EGL program must be defined similarly to program B in "Deferred switch between two EGL programs" above. The spaSize build descriptor option must specify the SPA size that is being used by the non-EGL program.
If you specified spaSize=n and spaStatusBytePosition=p as build descriptor options, then you must initialize the segmentation status byte at the offset within the SPA specified by spaStatusBytePosition=p. Initialize the segmentation status byte to blank.
The non-EGL program must be an IMS conversational program. The EGL program must be defined similarly to program A in "Deferred switch between two EGL programs" above. The EGL program must set the modified property to YES for all variable data fields on the form that are required as input in the non-EGL program. The spaSize build descriptor option must specify the SPA size that is being used by the non-EGL program.
If you specified spaSize=n and spaStatusBytePosition=p as build descriptor options, the segmentation status byte is either at position 15 or at the last byte of the SPA. The non-EGL program should ignore the value of the segmentation status byte.
The following table shows the methods used to pass data between nonconversational programs. A nonconversational program is a main textUI program generated with the spaSize build descriptor option set to 0 (as is the default).
| Action | Immediate switch (optional input form) | Deferred switch (with input form) |
|---|---|---|
| Coding and generating | Define both programs as segmented = YES. Generate both programs as nonconversational (spaSize = 0). | Define both programs as segmented = YES. Generate both programs as nonconversational (spaSize = 0). |
| Performing the transfer | The transferring program cannot send a form. If it is an EGL program, it uses a transfer to transaction with a record. | The transferring program must write the form to a message queue associated with the terminal. If it is an EGL program, it uses a show statement with a form and an optional record. |
| Using an input form | The target program can optionally have an input form. | The target program must have an input form. |
| Passing a record | The record is transferred in the message. | The record, if any, is transferred in the work database. |
When developing EGL programs, this technique is the same as transferring with segmented conversational EGL programs, except that the spaSize build descriptor option is set to 0 (nonconversational). With this technique two nonconversational EGL programs can change both the transaction name and the PSB name without presenting a form to the program user. Different form groups can be used by the two programs.
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord1",
@DLI { psb="psb" } }
// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1A;
// FormGroup
use FORMGX;
function main()
...
sysVar.transferName = 'trx1b';
transfer to transaction sysVar.transferName passing basicRecord1;
...
end // end main
end // end ProgramA
program ProgramB type textUIProgram
// omit inputForm for better performance
{segmented=yes, inputRecord="basicRecord1", inputForm="form2",
@DLI { psb="psb" } }
// Declarations
basicRecord1 TRANSFER_RECORD;
psb PSB1B;
// FormGroup
use FORMGY;
function main()
// generated EGL logic does the following:
// initializes basicRecord1
// if inputForm is specified:
// converses form2
// performs edits for form2
// converses form2 until form2 passes all edits
// gives control to the first statement in the main function
...
end // end main
end // end ProgramB
The EGL-generated program control logic automatically handles the IMS message that is used to transfer control and the record that is passed from program A to B.
The non-EGL program must be an IMS nonconversational program. The EGL program must be defined similarly to program B in the nonconversational "Immediate switch between two EGL programs."
The non-EGL program must insert a message to an alternate PCB. The destination must be set to the transaction name for the EGL program. The non-EGL program must supply the header information (length, ZZ, and transaction name) in the message. For the required layout of the message, see “Format of EGL input message for IMS nonconversational message switch.” The EGL-generated program control logic automatically removes the header information, so the EGL program receives only the data.
The non-EGL program must be an IMS nonconversational program. The EGL program must be defined similarly to program A in the nonconversational "Immediate switch between two EGL programs."
The non-EGL program must issue a get unique to the I/O PCB to retrieve the record that the EGL program passed on the transfer to transaction statement. For the required layout of the message, see “Format of EGL input message for IMS nonconversational message switch.” The EGL-generated program control logic automatically supplies the header information (length, ZZ, transaction name), so the EGL program defines only the data. However, the non-EGL program must be prepared to accept the header information.
From an EGL developer's viewpoint, this technique is identical to transferring with segmented conversational EGL programs, except that the spaSize build descriptor option is set to 0, indicating nonconversational programs. With this technique two nonconversational EGL programs can change both the transaction name and the PSB name when a form is presented to the program user. You must use the same formGroup for both programs. You do not have to transfer a record, but a form is required.
program ProgramA type textUIProgram
{segmented=yes, inputRecord="basicRecord2",
@DLI { psb="psb" } }
// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2A;
// FormGroup
use FORMG2;
function main()
...
sysVar.transferName = 'trx2b';
show form2 returning to sysVar.transferName passing basicRecord2;
...
end // end main
end // end ProgramA
program ProgramB type textUIProgram // inputForm is required
{segmented=yes, inputRecord="basicRecord2", inputForm="map2",
@DLI { psb="psb" } }
// Declarations
basicRecord2 TRANSFER_RECORD;
psb PSB2B;
// FormGroup
use FORMG2;
function main()
// generated EGL logic does the following:
// initializes basicRecord2
// performs edits for map2
// converses map2 until map2 passes all edits
// gives control to the first statement in the main function
...
end // end main
end // end ProgramB
The non-EGL program must be an IMS nonconversational program. The EGL program must be defined similarly to program B in the nonconversational "Deferred switch between two EGL programs."
The non-EGL program must be an IMS nonconversational program. The EGL program must be defined similarly to program A in the nonconversational "Deferred switch between two EGL programs." The EGL program must set the modified property to YES for all variable data fields on the form that are needed as input in the non-EGL program.
EGL programs can communicate with non-EGL programs by performing add or get next statements on records in serial files that are associated with the IMS message queue.
An EGL basic program, running as either an MPP or a transaction-driven batch message processing program (BMP), can then use the file to read the messages with get next statements. The EGL program automatically strips the header information from the message and puts the data into the serial record.
A non-EGL program can write a series of records to the IMS message queue for later processing by an EGL basic program, running as either an MPP or a transaction-driven BMP. The non-EGL program must insert a record in the format shown in the following table to an alternate I/O PCB associated with the transaction that processes the record.
| Field | Length in bytes | Type of data | Description |
|---|---|---|---|
| Segment length | 2 | Binary | The length of the segment. |
| Reserved (ZZ) | 2 | Binary | Reserved. |
| IMS transaction name | 8 | Character | The IMS transaction name for the EGL program. |
| Program-defined fields | Variable | Variable | This area contains the data items defined in the EGL serial record. |
An EGL basic program uses get next to read a serial file associated with the I/O PCB and then processes the message. The EGL program automatically removes the IMS message header (segment length, ZZ, and transaction name), so the program receives only the message data in the serial record.
When an EGL program does an add to a serial file associated with a message queue, the EGL program automatically adds the IMS message header in front of the record data, and then inserts the message to the alternate PCB. The EGL program is only concerned with the actual data in the message.
A non-EGL program running as either an MPP or a transaction-driven BMP can process the message queue. The format of the message actually inserted to the message queue and received by the non-EGL program is shown in the table in the previous section, "From non-EGL program to EGL program."