8.6.2.3 RXMSQ — The External Data Queue Exit Handler
The external data queue exit handler is used as a hook for
operations manipulating the external data queue (or the stack).
Unfortunately, the stack is a borderline case of what is relevant
to the REXX SAA API. Operations like putting something on,
retrieving a string from, obtaining the size, etc. of the stack is
not part of the SAA API.
However, some of this functionality is seemingly here; but not
all. For instance for the RXMSQPLL subfunction, SAA API is called
by the interpreter before the interpreter calls whatever system-
specific call is available for retrieving a string from the stack.
Thus the SAA API can be used by an application to provide the
interpreter with a fake stack, but it is not a suitable means for
the application itself to manipulate the real stack.
The RXMSG exit has four subfunctions:
[RXMSQPLL]
This is called before a line is retrieved from the stack
and the application may itself provide the interpreter
with an alternative line. On entry, the third parameter
points to a structure having the following definition:
typedef struct {
RXSTRING rxmsq_retc;
} RXMSQPLL_PARM;
The rxmsq_retc field holds the string to be retrieved
from the stack. Note that it is an output parameter, so
its value on entry is undefined.
[RXMSQPSH]
This is called before the interpreter puts a line on the
stack, and it may grab the line itself, and thus prevent
the interpreter from putting the line on the stack.
Note that this exit handles both pushing and queuing.
The third parameter is:
typedef struct {
struct {
unsigned rxfmlifo: 1;
} rxmsq_flags;
RXSTRING rxmsq_value;
} RXMSQPSH_PARM;
Here the field rxmsq_value holds the string to be put on
the stack. Whether the string is to be pushed or queued
is determined by the boolean value rxmsq_flags.rxmlfifo,
which is TRUE if the string is to be pushed.
All values are input values. What happens if you change
them is not defined in the SAA API. Some
implementations may let you modify the contents of
rxmsq_value and return RXEXIT_NOT_HANDLED and the string
push by the interpreter contains the modified string.
However, you should not rely on this since it is highly
incompatible. You may not de-allocate rxmsq_value.
[RXMSQSIZ]
this is called before the interpreter tries to determine
the size of the stack, and it may present an alternative
size to the interpreter. The third parameter is:
typedef struct {
ULONG rxmsq_size;
} RXMSQSIZ_PARM;
The field rxmsq_size can be set to the number the
application wants the QUEUED() function to return. Note
that this parameter is undefined on entry, so it cannot
be used to retrieve the number of lines on the stack.
[RXSQNAM]
This is called before the interpreter tries to retrieve
the name of the current stack, and it may present the
interpreter with an alternative name. Note that this
functionality is part of SAA but not TRL; it supports
the Get option of the RXQUEUE() built-in function. Note
that there are no other exits supporting the other
options of RXQUEUE(). The third parameter for this exit
is:
typedef struct {
RXSTRING rxmsq_name;
} RXMSQNAM_PARM;
As with RXSQMSIZ, the field rxmsq_name can be set to the
name which the application wants to return to the
interpreter as the name of the current stack. Note that
this is an output-only parameter; its value on input is
undefined, and in particular is not the name of the real
stack.
Note that this area is troublesome. In TRL, external data queues
are not defined as part of the language, while in SAA it is.
Thus, TRL-compliant interpreters are likely to implement stacks in
various ways that may not be compatible with the SAA.
PREV NEXT