To introduce the looping facility into an applications package a number of steps are required. These affect the monolith routine, individual applications and possibly their interface files, and documentation.
You must modify both the monolith to loop. The basic arrangement is shown below.
LPG_AGAIN returns .TRUE.
value until the list of data files is exhausted.
The additional code is the LPG_START call, the testing of LPG_AGAIN for any further files to process in a DO WHILE …END DO loop (or use IF .. END IF with a GOTO if you prefer), and the declaration of LPG_AGAIN.
LPG_START has three tuning arguments.
.TRUE.
causes multi-valued parameters (i.e. ones for accessing data files) to
report their value at each invocation; in essence this presents the names of the data file at
each invocation. Single-valued parameters are not shown. Set
.TRUE.
disables the looping. Thus LPG_AGAIN would only return .TRUE.
at the first invocation. Thus the package behaves as if LPG looping was not present. The
application corresponding to the required action will always be invoked at least once.
These tuning options are best controlled through environment variables accessed in the monolith. For example, Kappa invokes KAPLIBS calls
where KPG1_ENVDF inquires whether an environment variable is defined or not, and
KPG1_ENV0R obtains a floating-point value, but using the default of 0.0 seconds should
KAPPA_LOOP_DELAY
be undefined.
There is a further tuning possibility. Some users like to be able supply the same data for output as input, although this is potentially hazardous. Here is another extract from Kappa showing how this is switched using LPG_REPLA.
The applications should use the routines LPG_ASSOC, LPG_PROP, LPG_CREAT, and
LPG_CREP to
get identifier for NDFs, in place of the corresponding routines (i.e. replace LPG with NDF in the
names) from the NDF library.
For catalogues, routines LPG_CATASSOC and LPG_CATCREAT should be used in place of CAT_ASSOC and CAT_CREAT.
On the first invocation of the application, groups of data files are obtained whenever one of the above LPG routines is used to get an NDF or CAT identifier, and an identifier corresponding to the first name in each group is returned to the application. On subsequent invocations, the names in the groups obtained during the first invocation are used without obtaining new parameter values from the environment. The index of the returned data file within each group is incremented by 1 each time the application is invoked.
If an application is invoked more than once, all other parameters retain the values they had at the end
of the first invocation. Applications that use this scheme should avoid having parameters with
VPATH=DYNAMIC
in the interface file (described in SUN/115), since the dynamic default calculated on
the first invocation will then be re-used for all subsequent invocations; that may be inappropriate. A
better scheme is to have VPATH=DEFAULT
, PPATH=DYNAMIC
and DEFAULT=!
. The code should then annul
any PAR__NULL
status after accessing the parameter, and use the previously calculated dynamic default
value for the parameter. In this scheme, the parameter value is !
at the end of the first invocation, and
so retains this value for all subsequent invocations, resulting in appropriate dynamic defaults being
used.
A situation in which the above suggestion does not work is if an application sometimes sets a
dynamic default, and sometimes does not. In this case, you do not want to have VPATH=DEFAULT
,
DEFAULT=!
because this would require the application to abort in the cases where there is no dynamic
default available. It is probably better in these cases to have VPATH=PROMPT
, PPATH=DYNAMIC
and accept the fact that the user will be prompted for a parameter that was previously
defaulted.
Some applications test to see if a parameter was specified on the command line, and vary their
behaviour accordingly. This is achieved by checking the state of the parameter before accessing it, a
state of PAR__ACTIVE
(or SUBPAR__ACTIVE
) indicating that the parameter already has a value. This is
correct on the first invocation, but not on subsequent invocations because the first invocation may
have set a parameter value, resulting in subsequent invocations thinking that the parameter was given
on the command line. To avoid this, applications should call LPG_STATE in place of PAR_STATE.
LPG_STATE remembers the state of the parameter on the first invocation, and returns that state,
rather than the current parameter state, on subsequent invocations. The arguments are the
same.
One disadvantage of LPG is that any parameters written by the application, such the results of some analysis or statistics, will only record the values for the last data file processed.