MPE XL User Interface Enhancements [ COMMUNICATOR 3000/XL - REL. 2.0 (A.30.00) ] MPE/iX Communicators
COMMUNICATOR 3000/XL - REL. 2.0 (A.30.00)
MPE XL User Interface Enhancements
by the MPE XL User Interface Project
Commercial Systems Division
This article describes the MPE XL User Interface enhancements provided
with this release of MPE XL. Each enhancement description also provides
syntax usage examples.
NEW COMMANDS
Two new commands have been added to this release of MPE XL. :PAUSE causes
the Command Interpreter (CI) to idle for a specified number of seconds.
The new :ELSEIF command allows for a more compact IF...ELSE...ENDIF
construct. The :SHOWCATALOG command can now be executed programmatically
via the COMMAND and HPCICOMMAND intrinsics, and :COPY works with TEMP
files and recognizes the domain and device specifications for back
referenced files.
PAUSE
Syntax
________________________________________________________________________
| |
| SYNTAX: PAUSE num_seconds |
________________________________________________________________________
The :PAUSE command causes the CI to "sleep". The duration is specified
by num_seconds, which is a required integer parameter. Num_seconds may
not exceed the HPTIMEOUT variable when HPTIMEOUT is in effect, i.e., set
to a value greater than zero. For example: if the user sets HPTIMEOUT
to 30 minutes (SETVAR hptimeout 30) and num_seconds is specified as 2000
then the warning: "PAUSE TIME EXCEEDS HPTIMEOUT. HPTIMEOUT VALUE USED.
(CIWARN 9032)", is displayed and a pause time of 1800 seconds will be
used.
Example
PAUSE can be used to synchronize a command file and a job without
using any files.
CMDFILEA
strm joba
jobexist !lastjob
while cierror = 1 do
pause 5
jobexist !lastjob
endwhile
NOTE STRM is a command file which captures the job number in the
variable LASTJOB after streaming the file, see Example A.
JOBEXIST is a command file that sets CIERROR to 1 if the job exists
and to 0 if the job is not found, see Example B.
In the above example CMDFILEA invokes STRM to stream JOBA and waits for
JOBA to finish. The waiting ends when JOBEXIST sets CIERROR to zero.
The :PAUSE command prevents the loop from being CPU intensive.
PAUSE is available from the CI, jobs, command files, UDCs,
programmatically via the COMMAND and HPCICOMMAND intrinsics, and in break
mode. Pressing BREAK stops the pause.
ELSEIF
Syntax
________________________________________________________________________
| |
| SYNTAX: ELSEIF expression [THEN] |
________________________________________________________________________
The :ELSEIF command works similarly to IF. It evaluates expression and if
the expression is TRUE then the commands following it are executed. If
the expression is FALSE then the commands after ELSEIF are skipped until
a matching ELSEIF, ELSE or ENDIF is found. The :ELSEIF command can only
be used in conjunction with the IF command. It has no meaning by itself.
The complete IF construct now appears as:
IF expression [THEN]
...
[ ELSEIF expression [THEN] ]
...
[ ELSEIF expression [THEN] ]
.
.
.
[ ELSE ]
...
ENDIF
The word "THEN" at the end of expression is optional. If it is present
it will be ignored, i.e., not considered as part of the expression. This
is consistent with the parsing of "DO" in the WHILE command.
Using ELSEIF improves the readability of user commands and jobstreams.
The limit of thirty nested IFs does not apply since ELSEIF is not
considered a nested IF.
Example
ELSEIF can be used to simulate a Pascal CASE statement.
if reply = 1 then
doit1
elseif reply = 2 then
doit2
elseif reply = 3 then
doit3
else
echo Invalid reply.
endif
In this example, the final ELSE command is analogous to the OTHERWISE
clause in an HP Pascal CASE construct. As can be seen below, the same
example without using ELSEIF is more cumbersome:
if reply = 1 then
doit1
else
if reply = 2 then
doit2
else
if reply = 3 then
doit3
else
echo Invalid reply.
endif
endif
endif
The ELSEIF command is available from the CI, jobs, all user commands,
programmatically via the COMMAND and HPCICOMMAND intrinsics, and in break
mode. Pressing BREAK has no effect (unless the expression contains the
new input evaluator function, described later).
Copy
The syntax of the :COPY command remains unchanged; however, TEMP files
can now be copied. By default, a TEMP file is found before a permanent
file of the same name. The target file (TO=) will be of the same domain
as the source file (FROM=), unless overridden by the domain option (TEMP
or SAVE) of a file equation. Also, the LDEV number or device class can
be changed through a file equation with the DEV= parameter. As
previously available, the filename can also be altered using a file
equation. All other FILE parameters are ignored.
Example
:file tartmp;temp;rec=-80,,f,ascii
:comment {target is TEMP; rec= specification is ignored}
:copy myprog,*tartmp
:file savef;save;dev=4
:comment {target is PERM on ldev 4}
:copy tempfil,*savef
:file sysfile;dev=sysdisc
:comment {target is the same domain as source; resides on "sysdisc"}
:copy file,*sysfile
NEW VARIABLES
Release 2.0 of MPE XL supports eight new predefined variables:
HPACCTCAP, HPACCTCAPF, HPCONNSECS, HPCPUMSECS, HPGROUPCAP, HPGROUPCAPF,
HPQUIET, and HPTYPEAHEAD.
HPAcctCap / HPAcctCapF / HPGroupCap / HPGroupcapF
These four read-only variables contain the capabilities of the current
logon group and account. The "F" suffix provides the formatted version
of the capability mask.
Example
:showvar hp[ag]@cap@
HPACCTCAP = -4259381
HPACCTCAPF = SM,AM,AL,GL,DI,OP,CV,UV,LG,PS,NA,NM,CS,ND,SF,BA,IA,PM,MR,DS,PH
HPGROUPCAP = 384
HPGROUPCAPF = BA,IA
HPConnSecs
HPCONNSECS is a read-only integer variable that contains the connect time
measured in seconds. This is usually different than the value derived by
(60 * HPCONNMINS), since HPCONNMINS rounds up on 30 seconds, as the
example below illustrates.
Example
:showvar hpconn@
HPCONNMINS = 4198
HPCONNSECS = 251917
:calc hpconnmins * 60
251880, $3D7E8, %753750
HPCPUMSecs
HPCPUMSECS is a read-only integer variable that contains the CPU time
measured in milliseconds. As with HPCONNSECS, HPCPUMSECS is usually
different than (1000 * HPCPUSECS), since HPCPUSECS rounds up on 500
milliseconds.
Example
:showvar hpcpu@s
HPCPUMSECS = 25898
HPCPUSECS = 26
:calc hpcpusecs * 1000
26000, $6590, %62620
HPQuiet
This read-only boolean variable displays whether or not the current
session will receive TELL messages. This feature is controlled by the
SET MSG=ON|OFF native mode command, and the SETMSG ON|OFF compatibility
mode command. Prior to Release 2.0 this value could only be seen by
doing a :SHOWJOB command. For example:
:showjob #s589
JOBNUM STATE IPRI JIN JLIST INTRODUCED JOB NAME
#S589 EXEC QUIET 138 138 MON 9:43A MGR.UI
This session has set messages off as indicated by the "QUIET" value under
the IPRI column. If HPQUIET is TRUE for the current session then that
session will not accept TELL messages, and a :SHOWJOB will display
"QUIET" as shown above.
HPTypeAhead
HPTYPEAHEAD is a read-write boolean variable that enables or disables the
"typeahead" feature supported on the Avesta and Console. "Typeahead"
refers to the ability of the interactive user to "pre-type" commands,
replies to prompts, etc. before the CI or subsystem is ready to accept
input. The default value is FALSE meaning that "typeahead" is disabled.
Setting HPTYPEAHEAD to TRUE enables the "typeahead" feature. Typeahead
is not supported in the following environments: jobs, redirected CI
input, and LAN access.
Example
A logon UDC may use HPTYPEAHEAD as follows:
CISTART
option logon
setvar hptypeahead hpjobtype = "S"
...
NEW EVALUATOR FUNCTIONS
There are eleven new expression evaluator functions and one modified
function in Release 2.0 of MPE XL. All evaluator functions return either
an integer, boolean, or string value and are typed according to their
function return. The new functions are: ALPHA, ALPHANUM, INPUT, LTRIM,
MAX, MIN, NUMERIC, ODD, RPT, RTRIM and SETVAR. POS has been modified.
Alpha / AlphaNum / Numeric
Syntax
________________________________________________________________________
| |
| SYNTAX: ALPHA (string) |
| ALPHANUM (string) |
| NUMERIC (string) |
________________________________________________________________________
These three boolean functions accept a string parameter and return TRUE
or FALSE depending on the contents of the parameter:
ALPHA is TRUE if the string parameter contains only alphabetic
characters. Alphabetic characters are all letters ('A' .. 'Z' and 'a'
.. 'z').
NUMERIC is TRUE if the string parameter contains only numeric characters.
Numeric characters are all digits ('0' .. '9').
ALPHANUM returns TRUE if the string parameter contains only alphabetic or
numeric characters.
Example
:calc alpha(hpusercapf)
FALSE
:if alpha('abcd') then
*** EXPRESSION TRUE
:calc alphanum('$fff')
FALSE
:if alphanum('012c')
*** EXPRESSION TRUE
:calc numeric('-12')
FALSE
:if numeric('01234') then
LTrim / RTrim
Syntax
________________________________________________________________________
| |
| SYNTAX: LTRIM (string [,trimchar]) |
| RTRIM (string [,trimchar]) |
________________________________________________________________________
These two string functions accept a string parameter and return that
string with all leading or trailing trimchar removed, respectively. If
trimchar is omitted then a blank is assumed. If trimchar is not found at
the beginning (LTRIM) or end (RTRIM) of string then string is unchanged.
Example
:echo The non-blank length of "abc " is ![len(rtrim('abc '))].
The non-blank length of "abc " is 3.
:calc ltrim('AAAbbCC',"AA")
AbbCC
:if ups(rtrim("file.grp ")) = 'FILE.GRP' then
*** EXPRESSION TRUE
Max / Min
Syntax
_______________________________________________________________________
| |
| SYNTAX: MAX (int1 [,int2] [,int3]...) |
| MIN (int1 [,int2] [,int3]...) |
_______________________________________________________________________
The MIN and MAX integer functions return the minimum or maximum value,
respectively, from a list of integers or integer expressions.
Example
:calc min(5, abs(-11), 0, len(hpaccount), -5/2)
-2, $FFFFFFFE, %37777777776
:calc max(hpnumjobs, 2^30)
1073741824, $40000000, %10000000000
Odd
Syntax
________________________________________________________________________
| |
| SYNTAX: ODD (integer) |
________________________________________________________________________
The ODD boolean function accepts an integer parameter and returns TRUE if
the parameter is an odd number. ODD(x) is equivalent to (x BAND 1) = 1.
Example
:setvar text "abcde "
:calc odd(len(rht(rtrim(text),pos('b',text)))+1)
TRUE
:calc odd(0)
FALSE
:calc odd(-2)
FALSE
Rpt
Syntax
________________________________________________________________________
| |
| SYNTAX: RPT (string, count) |
________________________________________________________________________
The string function RPT accepts a string and an integer count and
functionally returns string repeated count times. If count is negative
then string is reversed before being repeated abs(count) times.
:calc rpt('xyZZy',5)
xyZZyxyZZyxyZZyxyZZyxyZZy
:setvar text "This line is centered"
:echo ![rpt(" ",39-len(text)/2)]!text
This line is centered
:calc rpt("mud",-3)
dumdumdum
Input / Setvar
Syntax
________________________________________________________________________
| |
| SYNTAX: INPUT ([ prompt_string [,wait] ]) |
| SETVAR (varname, var_value) |
________________________________________________________________________
The INPUT and SETVAR functions permit more compact and efficient user
commands.
The INPUT string function accepts an optional string parameter, which is
used as a prompt, and an optional integer wait parameter, for timed
reads. The function prompts the user with prompt_string and functionally
returns the user's $STDIN response. It is similar to the CI's :INPUT
command, except that user input is always returned as a string, rather
than setting a variable. Also, pressing BREAK causes INPUT to terminate
with CIERR 9745; whereas the INPUT command quietly sets the variable to
the null string. One final difference is how a single carriage return is
processed. The INPUT function simply returns the null string, unlike the
:INPUT command, which works differently depending on the existence of the
variable being input. If wait is omitted then no timed read is done.
The SETVAR function accepts a variable name (which cannot be an
expression) and a value, which may be any string, integer or boolean
expression. The result of the evaluation of var_value is functionally
returned and the variable varname is also set to this value. This
function is analogous to the SETVAR command.
Example
:while ups(lft(input("Purge file (y/n)? ",60),1)) = "Y" do...
Purge file (y/n)?
:setvar i 0
:while setvar(i,i+1) <= limit do...
:while setvar(program,input("Enter program name>"))
"//" do...
Enter program name>
:while ups(lft(ltrim(rtrim(input("Continue (y/n)? "))),1)) = "Y" do
Continue (y/n)?
Pos
Syntax
________________________________________________________________________
| |
| SYNTAX: POS (string1, string2 [,n]) |
________________________________________________________________________
The POS function has been modified for Release 2.0. A new optional
integer parameter has been added to control which occurrence of string1
is found in string2. If N is omitted then one is assumed, meaning that
the position of the first match of string1 found in string2 is returned.
This is the pre-2.0 behavior. On the other hand, if N is greater than
one then the position of the Nth occurrence of string1 in string2 is
returned. If N is negative then matching starts from the end of string2
rather than from the beginning. If no match occurs, or N is zero then
zero is functionally returned.
Example
:calc pos('.','file.grp.acct')
5, $5, %5
:calc pos(".",'file.grp.acct',2)
9, $9, %11
:calc pos('.',"file.grp.acct",-1)
9, $9, %11
EXAMPLE A
The STRM command file, used in the :PAUSE command example, streams a job
file and captures the job number in the variable LASTJOB.
PARM file, entry="main"
COMMENT STRM streams "file" and captures the job number in the variable
COMMENT LASTJOB. This is done by running a second level CI with it's
COMMENT $stdlist redirected to a file, then running another second level CI
COMMENT with its input redirected to that same file.
COMMENT
if "!entry" = "main" then
if not finfo('!file',0) then
echo (STRM): ![ups("!file")] does not exist.
return
endif
if finfo('strmtmp',0) then
purge strmtmp,temp
endif
file strmtmp,new;temp;rec=-80,,v,ascii;nocctl
setvar cierror 0
continue
run ci.pub.sys;parm=3;info="stream !file";stdlist=*strmtmp
if cierror = 0 and finfo('strmtmp',19) > 2 then
COMMENT Reinvoke STRM to capture the job number.
file strmtmp,oldtemp
continue
run ci.pub.sys;parm=3;info="strm xx,entry=get_jobnum";stdin=*strmtmp;&
stdlist=$null
endif
reset strmtmp
purge strmtmp,temp
elseif "!entry" = "get_jobnum" then
COMMENT Assumes $stdin redirected to file strmtmp, which contains the
COMMENT job number. First 2 inputs skip CI's prompt and info string.
input lastjob
input lastjob
setvar lastjob ltrim(rtrim(input()))
endif
EXAMPLE B
The JOBEXIST command file, used in the :PAUSE example, sets CIERROR to 1
if the passed in job number is found by the :SHOWJOB command, else
CIERROR is set to 0.
PARM jobnum
COMMENT JOBEXIST does a showjob to disc. If the disc file contains only 3
COMMENT records then the job does not exist and CIERROR is set to 0, else the
COMMENT job exists and CIERROR is set to 1. "Jobnum" should be of the form:
COMMENT "#J|Snnn".
COMMENT Verify syntax of "jobnum" parm.
setvar _jobexist_job ups("!jobnum")
if lft(_jobexist_job,1)
"#" then
setvar _jobexist_job "#"+_jobexist_job
endif
if str(_jobexist_job,2,1)
"J" and str(_jobexist_job,2,1)
"S" then
echo (JOBEXIST): J|S missing from job parm, assuming a JOB.
setvar _jobexist_job "#J"+rht(_jobexist_job,len(_jobexist_job)-1)
endif
if finfo('jobtmp',0) then
purge jobtmp,temp
endif
file jobtmp,new;temp;rec=-80,,f,ascii;nocctl
setvar cierror 0
continue
showjob !_jobexist_job;*jobtmp
if cierror = 0 and finfo('jobtmp',19) > 3 then
COMMENT Found job.
setvar cierror 1
else
setvar cierror 0
endif
deletevar _jobexist_@
reset jobtmp
purge jobtmp,temp
MPE/iX Communicators