I have a CMD command object that drives an RPGLE program. Because the command may be called with several different parameters, some of which are mutually exclusive, I parse the parameter passed by using a data structure in the RPGLE so I can handle the different scenarios that pass the parameters in various positions.
For example, the CMD file has:
CMD PROMPT('Reprint Invoices and Credits')
PARM KWD(ORDERNUM) TYPE(ORDER) +
PROMPT('For order number:')
PARM KWD(INVDATE) TYPE(*DATE) PASSATR(*YES) +
PROMPT('For invoice date')
PARM KWD(DATERANGE) TYPE(DTRANGE) +
PROMPT('For date range:')
PARM KWD(TRANSTYPE) TYPE(*CHAR) LEN(9) RSTD(*YES) +
DFT(*BOTH) VALUES(*INVOICES *CREDITS *BOTH) +
PASSATR(*YES) PROMPT('Transactions to print')
DTRANGE: ELEM TYPE(*DATE) MIN(1) PASSATR(*YES) +
PROMPT('Beginning date')
ELEM TYPE(*DATE) MIN(1) PASSATR(*YES) +
PROMPT('Ending date')
ORDER: ELEM TYPE(*DEC) LEN(6) MIN(1) PASSATR(*YES) +
PROMPT('Order number')
ELEM TYPE(*DEC) LEN(2) MIN(0) PASSATR(*YES) +
PROMPT('Shipment number (optional)')
DEP CTL(*ALWAYS) PARM(ORDERNUM INVDATE DATERANGE) +
NBRTRUE(*EQ 1)
The user can print by various criteria: order number, date, date range. Only one of these three methods can be chosen. Depending on what the user chooses, the parameters get delivered to the called RPGLE program differently.
********************************************************************
* Parameters from CMD object INV_REPRNT
D InputParms DS TEMPLATE QUALIFIED
D AllParms 143A
D ParmType 2 2A Can't find in manual
D 'Type' might be
D a misnomer
D
D OrdDteAttr 3 3A For attr's, see
D OrderNum 4 7P 0 SEU help for
D ShipAttr 8 8A CMD PASSATR
D Shipment 9 10P 0
D OrdInvCMAttr 21 21A
D OrdInvCM 22 30A char 9
D
D InvDate@ 4 10A
D DteInvCMAttr 13 13A
D DteInvCM 14 22A char 9
D
D BeginDateAttr 13 13A
D BeginDate@ 14 20A
D EndDateAttr 21 21A
D EndDate@ 22 28A
D RgeInvCMAttr 29 29A
D RgeInvCM 30 38A char 9
As you can see, the position of the later parameters like TRANSTYPE
shift position depending on which of the earlier parameters was chosen. OrdInvCM
starts at 22, DteInvCM
starts at 14, RgeInvCM
starts at 30. This is not a problem as this data structure and the code using it is able to pick out the right position to read from based on the mysterious little attribute that I am calling ParmType
. As far as I can tell, this attribute is not documented anywhere in the CL manuals on the internet or in the help included in the SEU editor (which has information on PASSATR
that is not in the online manuals). I have pieced together a little of ParmType
's behavior in relation to the pass attributes, enough to use it, but not enough to fully understand it.
Some constants to make parsing the PASSATR
easier (not every possibility):
D Null C CONST(X'00')
D Parm2 C CONST(X'02')
D NumSpecd C CONST(X'A1') 1010 0001
D NumUnspecd C CONST(X'21') 0010 0001
D CharQSpecd C CONST(X'C5') 1100 0101 Quoted
D CharQUnspecd C CONST(X'45') 0100 0101 Quoted
D CharUQSpecd C CONST(X'85') 1000 0101 Unquoted
D CharUQUnspecd C CONST(X'05') 0000 0101 Unquoted
D
D IsSpecd C CONST(X'80') >= 1000 0000
I have found that:
IF P.ParmType = Null;
IF P.OrdDteAttr >= IsSpecd;
// this is a single date
ELSE;
IF P.BeginDateAttr >= IsSpecd;
// this is a data range
ELSE;
// this is error condition I have not gotten yet
ENDIF;
ENDIF;
ELSE;
IF P.OrdDteAttr >= IsSpecd;
// this is an order number
ELSE;
// this is error condition I have not gotten yet
ENDIF;
ENDIF;
In other words the ParmType
has a hex value of '00' when the parameter is either a date or a date range. The ParmType
has a hex value of '02' when the parameter is a packed *DEC (6P 0) for 'Order number'.
I would like to understand how this ParmType
value gets set at a given number so I can robustly write programs that can accept various parameter combinations. I also do not see a particular reason why the data range fields start over at 14 rather than at 4 like the single date does. I was able to exploit this fact to make the necessary distinction, but I do not know if the command system did this on purpose because it saw that I had two possibilities of the same data type or if this is just a lucky break that is not guaranteed to occur. A similar question occurs if I want to add a additional packed parameter as a choice, say an invoice number. The 'PASSATR' hex value of 'A1' could tell you it was packed, but not which type (order number or invoice number). It might be that the command system shifts the position similar to what it did with date range, but I have not run that particular experiment.
In short, is there documentation or at least deduced algorithms on how commands build their parameter lists so that one can predict what these fields will contain and where they will be located?