У меня есть командный объект CMD, который управляет программой RPGLE. Поскольку команда может быть вызвана с несколькими различными параметрами, некоторые из которых являются взаимоисключающими, я анализирую переданный параметр, используя структуру данных в RPGLE, чтобы я мог обрабатывать различные сценарии, в которых параметры передаются в различных положениях.
Например, в файле CMD есть:
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)
Пользователь может печатать по различным критериям: номер заказа, дата, диапазон дат. Можно выбрать только один из этих трех методов. В зависимости от того, что выбирает пользователь, параметры по-разному доставляются в вызываемую программу RPGLE.
********************************************************************
* 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
Как видите, положение более поздних параметров, таких как TRANSTYPE
, сдвигается в зависимости от того, какой из более ранних параметров был выбран. OrdInvCM
начинается с 22, DteInvCM
начинается с 14, RgeInvCM
начинается с 30. Это не проблема, поскольку эта структура данных и код, использующий ее, могут выбрать правильную позицию для чтения на основе таинственного маленького атрибута, который я вызываю ParmType
. Насколько я могу судить, этот атрибут не задокументирован нигде в руководствах по CL в Интернете или в справке, включенной в редактор SEU (который содержит информацию о PASSATR
, которой нет в онлайн-руководствах). Я немного собрал воедино поведение ParmType
по отношению к атрибутам pass, достаточно, чтобы его использовать, но недостаточно, чтобы полностью его понять.
Некоторые константы, облегчающие синтаксический анализ PASSATR
(не все возможности):
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
Я обнаружил, что:
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;
Другими словами, ParmType
имеет шестнадцатеричное значение «00», если параметр представляет собой дату или диапазон дат. ParmType
имеет шестнадцатеричное значение «02», когда параметр представляет собой упакованный * DEC (6P 0) для «Номер заказа».
Я хотел бы понять, как это значение ParmType
устанавливается на заданное число, чтобы я мог надежно писать программы, которые могут принимать различные комбинации параметров. Я также не вижу особой причины, по которой поля диапазона данных начинаются с 14, а не с 4, как это бывает с единственной датой. Я смог использовать этот факт, чтобы провести необходимое различие, но я не знаю, делала ли система команд это специально, потому что она увидела, что у меня есть две возможности с одним и тем же типом данных, или это просто счастливый случай, который не гарантирован. Аналогичный вопрос возникает, если я хочу добавить дополнительный упакованный параметр в качестве выбора, скажем, номер счета-фактуры. Шестнадцатеричное значение «PASSATR» в «A1» может сказать вам, что он был упакован, но не его тип (номер заказа или номер счета-фактуры). Возможно, система команд меняет положение так же, как это было с диапазоном дат, но я не проводил этот конкретный эксперимент.
Короче говоря, существует ли документация или, по крайней мере, выведенные алгоритмы о том, как команды создают свои списки параметров, чтобы можно было предсказать, что эти поля будут содержать и где они будут расположены?