The sample command processor in Figure 1 demonstrates
the use of the parse service routine. A validity checking routine
is also provided. The syntax for the sample command is:
PROCESS dsname [ ACTION ]
[ NOACTION ]
where dsname is a positional operand and ACTION/NOACTION
are keyword operands. NOACTION is the default if neither ACTION nor
NOACTION are specified.
Figure 1. A sample command
processor
PROCESS TITLE 'SAMPLE TSO/E COMMAND PROCESSOR '
PROCESS CSECT ,
PROCESS AMODE 31 COMMAND'S ADDRESSING MODE
PROCESS RMODE 31 COMMAND'S RESIDENCY MODE
***********************************************************************
* *
* TITLE - PROCESS *
* *
* DESCRIPTION - SAMPLE TSO/E COMMAND PROCESSOR *
* *
* FUNCTION - THIS SIMPLE COMMAND PROCESSOR DEMONSTRATES THE USE *
* OF THE PARSE SERVICE ROUTINE TO SYNTAX CHECK THE *
* COMMAND OPERANDS. *
* *
* OPERATION - PROCESS IS A REENTRANT COMMAND PROCESSOR THAT PERFORMS *
* THE FOLLOWING PROCESSING: *
* *
* 1 - ESTABLISHES ADDRESSABILITY AND SAVES THE CALLER'S REGISTERS *
* 2 - ISSUES A GETMAIN FOR DYNAMIC STORAGE *
* 3 - USES THE PARSE SERVICE ROUTINE (IKJPARS) TO DETERMINE THE *
* VALIDITY OF THE COMMAND OPERANDS *
* 4 - PROVIDES A VALIDITY CHECKING ROUTINE TO PERFORM ADDITIONAL *
* CHECKING OF THE POSITIONAL OPERAND *
* 5 - ISSUES A FREEMAIN TO RELEASE THE DYNAMIC STORAGE *
* 6 - RESTORES THE CALLER'S REGISTERS BEFORE RETURNING *
* 7 - RETURNS TO THE TMP WITH A RETURN CODE IN REGISTER 15 *
* *
***********************************************************************
*
PROCESS CSECT
STM R14,R12,12(R13) SAVE CALLER'S REGISTERS
LR R11,R15 ESTABLISH ADDRESSABILITY WITHIN
USING PROCESS,R11 THIS CSECT
LR R2,R1 SAVE THE POINTER TO THE CPPL
* AROUND THE GETMAIN
GETMAIN RU,LV=L_SAVE_AREA OBTAIN A DYNAMIC WORK AREA
USING SAVEAREA,R1 AND ESTABLISH ADDRESSABILITY
ST R1,8(R13) PUT THE ADDRESS OF PROCESS'S SAVE
* AREA INTO THE CALLER'S SAVE AREA
ST R13,B_PTR PUT THE ADDRESS OF PROCESS'S SAVE
* AREA INTO ITS OWN SAVE AREA
LR R13,R1 LOAD GETMAINED AREA ADDRESS
USING SAVE_AREA,R13 POINT TO THE DYNAMIC AREA
DROP R1 DON'T USE R1 ANY MORE
GETMAIN RU,LV=L_WORK_AREA OBTAIN A DYNAMIC WORK AREA
USING WORKA,R1 AND ESTABLISH ADDRESSABILITY TO
* THE DYNAMIC WORK AREA
STM R0,R1,WORK_AREA_GM_LENGTH SAVE LENGTH AND ADDR OF
* DYNAMIC AREA
LR R10,R1 GET READY TO USE R10 AS THE
USING WORKA,R10 DATA AREA SEGMENT BASE REGISTER
DROP R1
ST R2,CPPL_PTR SAVE THE POINTER TO THE CPPL
***********************************************************************
* *
* MAINLINE PROCESSING *
* *
***********************************************************************
*
XC RETCODE,RETCODE INITIALIZE THE RETURN CODE
GETMAIN RU,LV=L_PPL OBTAIN A DYNAMIC PPL WORK AREA
STM R0,R1,PPL_LENGTH SAVE LENGTH AND ADDR OF DYNAMIC PPL
GETMAIN RU,LV=L_ANSWER OBTAIN A DYNAMIC PPL ANSWER AREA
STM R0,R1,ANSWER_LENGTH SAVE LENGTH AND ADDR OF DYNAMIC PPL
* ANSWER AREA
L R2,PPL_PTR GET THE ADDRESS OF THE PPL
USING PPL,R2 AND ESTABLISH ADDRESSABILITY
L R1,CPPL_PTR GET ADDRESS OF CPPL
USING CPPL,R1 AND ESTABLISH ADDRESSABILITY
MVC PPLUPT,CPPLUPT PUT IN THE UPT ADDRESS FROM CPPL
MVC PPLECT,CPPLECT PUT IN THE ECT ADDRESS FROM CPPL
MVC PPLCBUF,CPPLCBUF PUT IN THE COMMAND BUFFER ADDRESS
* FROM THE CPPL
L R1,WORK_AREA_GM_PTR GET THE ADDRESS OF THE COMMAND
* PROCESSOR'S DYNAMIC WORK AREA TO
ST R1,PPLUWA BE PASSED TO THE VALIDITY CHECK
* ROUTINE
DROP R1
L R1,ANSWER_PTR GET THE ADDRESS OF THE PARSE
* ANSWER AREA AND
ST R1,PPLANS STORE IT IN THE PPL
XC ECB,ECB CLEAR COMMAND PROCESSOR'S
* EVENT CONTROL BLOCK (ECB)
LA R1,ECB GET THE ADDRESS OF THE COMMAND
* PROCESSOR'S ECB AND
ST R1,PPLECB PUT IT IN THE PPL
L R1,PCLADCON GET THE ADDRESS OF THE PCL AND
ST R1,PPLPCL PUT IT IN THE PPL FOR PARSE
CALLTSSR EP=IKJPARS,MF=(E,PPL) INVOKE PARSE
DROP R2
LTR R15,R15 IF PARSE RETURN CODE IS ZERO
BZ PROCESS PERFORM PROCESSING FOR THE COMMAND
MVC RETCODE(4),ERROR SET CP RETURN CODE TO 12
B CLEANUP PREPARE TO RETURN TO THE TMP
*
PROCESS DS 0H
* .
* .
* .
*
* CODE TO PERFORM THE FUNCTION OF THE COMMAND PROCESSOR GOES HERE.
* AFTER CALLING THE PARSE SERVICE ROUTINE TO VALIDATE THE COMMAND
* OPERANDS, USE THE PDL RETURNED BY PARSE TO DETERMINE WHICH
* OPERANDS THE USER ENTERED. THEN PERFORM THE FUNCTION REQUESTED
* BY THE USER.
*
* .
* .
* .
*
*
***********************************************************************
* *
* CLEANUP AND TERMINATION PROCESSING *
* *
***********************************************************************
*
CLEANUP DS 0H
L R1,PPL_PTR POINT TO PPL IN DYNAMIC WORK AREA
FREEMAIN RU,LV=L_PPL,A=(1) FREE THE STORAGE FOR THE PPL
L R1,ANSWER_PTR POINT TO THE ANSWER PLACE
L R1,0(0,R1) POINT TO THE PDL
IKJRLSA (R1) FREE STORAGE THAT PARSE ALLOCATED
* FOR THE PDL
L R1,ANSWER_PTR POINT TO THE ANSWER PLACE
FREEMAIN RU,LV=L_ANSWER,A=(1) FREE THE STORAGE FOR THE
* ANSWER WORD
L R5,RETCODE SAVE RETURN CODE AROUND FREEMAIN
L R1,WORK_AREA_GM_PTR POINT TO MODULE WORK AREA
FREEMAIN RU,LV=L_WORK_AREA,A=(1)
* FREE THE MODULE WORKAREA
LR R1,R13 LOAD PROCESS'S SAVE AREA ADDRESS
L R13,B_PTR CHAIN TO PREVIOUS SAVE AREA
DROP R13
FREEMAIN RU,LV=L_SAVE_AREA,A=(1) FREE THE MODULE SAVEAREA
L R14,12(R13) HERE'S OUR RETURN ADDRESS
LR R15,R5 HERE'S THE RETURN CODE
LM R0,R12,20(R13) RESTORE REGS 0-12
BSM 0,R14 RETURN TO the TMP
***********************************************************************
* POSITCHK - IKJPOSIT VALIDITY CHECKING ROUTINE *
* *
* IF THE DATA SET NAME HAS A PREFIX OF SYS1 THEN THE VALIDITY *
* CHECKING ROUTINE RETURNS A CODE OF 4 TO PARSE. THIS RETURN *
* CODE INDICATES TO PARSE THAT IT SHOULD ISSUE A MESSAGE TO THE *
* TERMINAL AND PROMPT THE USER TO RE-ENTER THE DATA SET NAME. *
* *
* IF THE DATA SET PREFIX IS ANYTHING OTHER THAN SYS1, THEN *
* THIS ROUTINE RETURNS A CODE OF 0 TO PARSE. *
* *
***********************************************************************
DROP R10 WE WILL REUSE REGISTER 10
POSITCHK DS 0D
STM R14,R12,12(R13) SAVE PARSE'S REGISTERS
LR R9,R15
USING POSITCHK,R9 ESTABLISH ADDRESSABILITY
LR R2,R1 SAVE THE VALIDITY CHECK PARAMETER
* LIST PARSE PASSED TO US
GETMAIN RU,LV=L_SAVE_AREA OBTAIN A DYNAMIC SAVE AREA FOR
* THE POSITCHK ROUTINE
USING SAVEAREA,R1 AND ESTABLISH ADDRESSABILITY
ST R1,8(R13) PUT THE ADDRESS OF THIS ROUTINE'S
* SAVE AREA INTO PARSE'S SAVE AREA
ST R13,B_PTR PUT THE ADDRESS OF THIS ROUTINE'S
* SAVE AREA INTO ITS OWN SAVE AREA
* FOR CALLING
LR R13,R1 LOAD ADDRESS OF GETMAINED AREA
USING SAVEAREA,R13 AND ESTABLISH ADDRESSABILITY
L R10,4(R2) POINT TO THE COMMAND PROCESSOR'S
* ORIGINAL DYNAMIC WORK AREA
USING WORKA,R10 DATA AREA SEGMENT BASE REGISTER
ST R2,VALCHK_PARAMETER_LIST_PTR
* SAVE THE ADDRESS OF THE VALIDITY
* CHECK PARAMETER LIST
LM R1,R3,0(R2) GET THE ADDRESS OF THE PDE
STM R1,R3,VALIDITY_CHECK_PARAMETER_LIST
* SAVE CONTENTS OF PARAMETER LIST
XC POSITCHK_RETCODE,POSITCHK_RETCODE
* MAKE SURE WE START WITH A ZERO
* RETURN CODE
L R2,PDEADR GET THE ADDRESS OF THE PDE
USING DSNAME_PTR,R2 AND ESTABLISH ADDRESSABILITY TO
* OUR MAPPING OF THE PDE
TM DSNAME_FLAGS1,QUOTE IS THE DATA SET NAME IN QUOTES?
BNO DSNOK NO - DATA SET NAME IS OK
L R4,DSNAME_PTR POINT TO THE DSN
CLC 0(L'SYS1,R4),SYS1 IS HIGH LEVEL-DESCRIPTOR SYS1?
BNE DSNOK NO
L R5,FOUR SYS1 IS INVALID. SET RC=4
ST R5,POSITCHK_RETCODE SAVE THE RETURN CODE
DSNOK LR R1,R13 LOAD ROUTINE'S SAVE AREA ADDRESS
L R13,B_PTR CHAIN TO PREVIOUS SAVE AREA
L R5,POSITCHK_RETCODE LOAD THE RETURN CODE
FREEMAIN RU,LV=L_SAVE_AREA,A=(1)
* FREE THE MODULE WORKAREA
L R14,12(R13) HERE'S OUR RETURN ADDRESS
LR R15,R5 HERE'S THE RETURN CODE
LM R0,R12,20(R13) RESTORE REGS 0-12
BSM 0,R14 RETURN TO PARSE
DROP R9
DROP R10
DROP R13
*
***********************************************************************
* *
* DECLARES FOR CONSTANTS *
* *
***********************************************************************
*
PCLADCON DC A(PCLDEFS) ADDRESS OF PCL
FOUR DC F'4' USED TO SET/TEST RETURN CODE
EIGHT DC F'8' USED TO SET/TEST RETURN CODE
TWELVE DC F'12' USED TO SET/TEST RETURN CODE
ERROR DC F'12' USED TO SET/TEST RETURN CODE
SYS1 DC C'SYS1.' HIGH-LEVEL DESCRIPTOR
***********************************************************************
* *
* PARSE MACROS USED TO DESCRIBE THE COMMAND OPERANDS *
* *
***********************************************************************
*
PCLSTART DS 0H
PCLDEFS IKJPARM DSECT=PRDSECT
DSNPCE IKJPOSIT DSNAME, +
PROMPT='THE NAME OF THE DATA SET YOU WANT TO PROCESS. +
ENTER '?'' FOR HELP', +
HELP=('A DATA SET NAME WHICH HAS A FIRST-LEVEL QUALIFIER+
OTHER THAN 'SYS1'.'), +
VALIDCK=POSITCHK
ACTPCE IKJKEYWD DEFAULT='NOACTION'
IKJNAME 'ACTION'
IKJNAME 'NOACTION'
IKJENDP
LPCL EQU *-PCLSTART LENGTH OF THE PCL
*
***********************************************************************
* *
* DECLARES FOR DYNAMIC VARIABLES *
* *
***********************************************************************
*
WORK_AREA DSECT
WORKA DS 0F START OF DYNAMIC WORK AREA
WORK_AREA_GM_LENGTH DS F LENGTH OF WORKAREA
WORK_AREA_GM_PTR DS F ADDRESS OF WORKAREA
PPL_LENGTH DS F LENGTH OF PPL
PPL_PTR DS F ADDRESS OF PPL
ANSWER_LENGTH DS F LENGTH OF PPL ANSWER AREA
ANSWER_PTR DS F ADDRESS OF PPL ANSWER AREA
CPPL_PTR DS F ADDRESS OF THE CPPL FROM TMP
RETCODE DS F THE RETURN CODE
PARSE_RETCODE DS F THE RETURN CODE FROM PARSE
POSITCHK_RETCODE DS F THE RETURN CODE FROM THE POSITCHK
* VALIDATION EXIT
ECB DS F CP'S EVENT CONTROL BLOCK
VALCHK_PARAMETER_LIST_PTR DS F POINTER TO THE VALIDITY CHECK
* PARAMETER LIST
***********************************************************************
* *
* MAPPING OF THE PDE BUILT BY PARSE TO DESCRIBE A DSNAME OR DSTHING *
* OPERAND. *
* *
***********************************************************************
*
DSNAME_DSTHING DSECT PDE MAPPING FOR THE FOR DSNAME
* OR DSTHING
DSNAME_PTR DS F POINTER TO THE DSNAME
DSNAME_LENGTH_1 DS H LENGTH OF THE DATA SET NAME
* EXCLUDING QUOTES
DSNAME_FLAGS1 DS CL1 FLAGS BYTE
*
* 0... .... THE DATA SET NAME IS NOT PRESENT
* 1... .... THE DATA SET NAME IS PRESENT
* .0.. .... THE DATA SET NAME IS NOT CONTAINED WITHIN QUOTES
* .1.. .... THE DATA SET NAME IS CONTAINED WITHIN QUOTES
*
DS CL1 RESERVED
DSNAME_MEMBER_PTR DS F POINTER TO THE MEMBER NAME
DSNAME_LENGTH_2 DS H LENGTH OF THE MEMBER NAME
* EXCLUDING PARENTHESES
DSNAME_FLAGS2 DS CL1 FLAGS BYTE
*
* 0... .... THE MEMBER NAME IS NOT PRESENT
* 1... .... THE MEMBER NAME IS PRESENT
*
DS CL1 RESERVED
DSNAME_PASSWORD_PTR DS F POINTER TO THE DATA SET PASSWORD
DSNAME_LENGTH_3 DS H LENGTH OF THE PASSWORD
DSNAME_FLAGS3 DS CL1 FLAGS BYTE
*
* 0... .... THE DATA SET PASSWORD IS NOT PRESENT
* 1... .... THE DATA SET PASSWORD IS PRESENT
*
DS CL1 RESERVED
L_DSNAME_PDE EQU *-DSNAME_PTR
*
***********************************************************************
* *
* MAPPING OF THE PDE BUILT BY PARSE TO DESCRIBE THE KEYWORD OPERAND *
* *
***********************************************************************
*
KEYWD_PDE DSECT
KEYWD_NUM DS H CONTAINS THE NUMBER OF THE IKJNAME
* MACRO INSTRUCTION THAT CORRESPONDS
* TO THE OPERAND ENTERED/DEFAULTED
*
L_KEYWD_PDE EQU *-KEYWD_PDE
*
IKJPPL PARSE PARAMETER LIST
L_PPL EQU *-PPL
*
IKJCPPL COMMAND PROCESSOR PARAMETER LIST
L_CPPL EQU *-CPPL
*
ANSWER DSECT
DS F PARSE ANSWER PLACE. PARSE PLACES A
* POINTER TO THE PDL HERE
L_ANSWER EQU *-ANSWER
*
CVT DSECT=YES CVT MAPPING NEEDED FOR CALLTSSR MACRO
*
***********************************************************************
* *
* EQUATES *
* *
***********************************************************************
*
R0 EQU 0
R1 EQU 1
R2 EQU 2
R3 EQU 3
R4 EQU 4
R5 EQU 5
R6 EQU 6
R7 EQU 7
R8 EQU 8
R9 EQU 9
R10 EQU 10
R11 EQU 11 BASE REGISTER
R12 EQU 12
R13 EQU 13 DATA REGISTER
R14 EQU 14 RETURN ADDRESS
R15 EQU 15 RETURN CODE
QUOTE EQU X'40' FULLY-QUALIFIED DATA SET NAME
END PROCESS