$* $* Note 'DRAFT' line, also I don't like the special "I" $* $*-------------------------------------------------------------------*$ $* Reference Summary for the REX language and support modules. *$ $*-------------------------------------------------------------------*$ $* To process this file: TMP REXCARD *$ $* TTEXT REXCARD <(FINAL> *$ $* Inspired by PL8CARD6 by Hank Warren, Yorktown Heights. *$ $*-------------------------------------------------------------------*$ $* $* $ is used for open/close keep. The first $ also causes a 1/4-skip: $=?$?.skq .bk $=/$/.ek $pop,$,/?$* Keeps $* $read ttfmacs $read press $= ! (@l$=/!/)@l$pop,!,/ $* Command language entry (open/close font) $= ' $x'cd'$=/'/$x'ed'$pop,',/ $* Alternate open/close single quotes. $= .' (@q$'''')@q $* Solitaire or symmetrical quote. $= ." (@q$'"')@q $* Solitaire or symmetrical twin quote. $= ./ $'/' $* Slash $= | (@o$x'4f')@o $* Or $= < (@o$x'ad')@o $* Left Square Bracket $= > (@o$x'bd')@o $* Right Square Bracket $= (( (@o$'(')@o $* Bigger Left Paren $= )) (@o$')')@o $* Bigger Right Paren $=/.lb /(@o$x'c0')@o/$* Explicit Left brace $=/.rb /(@o$x'd0')@o/$* .. Right brace $=/%/.hs=.3 / $=/.sk/.vs&1;c / $=/.sk /.vs=0.7.2,0.9.2;c / $=/.skr /.vs=0.6.3,0.8.2;c / $=/.skh /.vs=0.3.6,0.4.6;c / $=/.skq /.vs=0.1.8,0.2.3;c / $=/.sp/.vs=0.7.2,0.9.2 / $=/.sph /.vs=0.3.6,0.4 / $=/.nl /.vs=0,0.0.4;c /$* New line (same as .break). $=/.pp /.vs=0,0.0.5;c .hs=1 / $=/.box /.br=l,r,r2,r2,r2;l;r /$* End with .er (no parameter). $=/<.>/.ov=b100 .ov=e /$* Point here. $=/<..>/.hs=s100 /$* Horizontal space to place pointed at. $= ? $* Tab. $=/.cpn/.ov=b,-2.0 (@sn)@s.ov=e .ov=c .ov=b (@u.cn1=+ )@u.ov=e /$* Circled page number. $=/*/.ov=b,-2.3 $x'5c'.ov=e /$* Shift asterisk down a bit $=/__/.ov=b,-1.5 .-.ov=e / $=/&&/&.ov=r,0,b55 &/ $=/==/=.ov=r,0,b65 =/ $= e1 e(@b1)@b $= e2 e(@b2)@b $= e3 e(@b3)@b $= e4 e(@b4)@b $= e5 e(@b5)@b $pop ... $pop -> .fp=APS5,no .fs=b,press,6,-2 )@b$* For subscripts .fs=c,press-ital,6,-2 )@c .fs=d,Gothic-bold,8 )@d$* For headings .fs=h,univers-65,16 )@h$* For Major title .fs=i,ibm-logo,24,-12 )@i .fs=j,ibm-logo,18 )@j .fs=l,Bell-gothic,7 )@l$* For language keywords $*.fs=m,Press,7 )@m$* For capital "I" .fs=m,Bell-gothic,7 )@m$* For capital "I" .fs=o,Letter-gothic,7 )@o$* For operators, braces, brackets, etc etc. .fs=p,Univers-55,7 )@p$* For proper pound sign .fs=q,Letter-gothic,7 )@q$* For straight up and down quotes. .fs=s,special-symbols,18 )@s .fs=u,Bell-gothic,6 )@u .fs=w,press,8;x,press-ital;y,press-bold $* For descriptive text. .rn1=0,0 .rn2=0.4,4.5 .rn3=0.3,1.5 .rn4=1.5,4 .pdt=87,0,87,70,2,2 .cdt=31,4,2 .ls=8.5,9.5 .cp=nd,b .bh .rs=0,0 .rh .cr=all .vst=2 .hst=30 .cpn.st .cpn.vst=1 .rf .cr=all .vst=1.5 .ls=9,9 .hst=8.8 (@dIBM INTERNAL USE ONLY.hst=21 IBM INTERNAL USE ONLY)@d.vst=4 .bt $* ----------------- OK now the data proper ... ------------------------ .dtt=15.5 .vst=1 .ls=16,16 (@iIBML)@i?(@hREX ?Reference)@h (@dVM(@y/)@y370.hst=.2 (@y.bul)@y.hst=.2 CMS)@d?(@hSummary)@h .vst=1 $* .ls=7.9,8.9 .ls=8.5,9.0 .hr=l,r,r4 .tf $* ----------------- Footnote for page 1 ... ------------------------ .bf=bot .dtt=3.6 .nl .box (@yKey to symbols used on this card:)@y .skq .nl !GOTHIC! ?.- indicates language keywords .nl _italics_ ?.- indicate defined syntactic units .nl < > ?.- brackets indicate an optional item .nl ... ?.- ellipses mean multiple items are allowed .nl .lb .rb ?.- braces specify list of alternatives (choose one) .nl | ?.- separates alternatives in a list .er .ef $* --------------------------------------------------------------------- .skh .jt=n First Edition (October 1980) - for REX version 2.08 .sk (@dCONTENTS)@d .skh .dtt=30,r,$x'7d4b407d' .ilt=1 .nl !REX EXEC!?1 .nl !Data items!?2 .nl !Expressions!?2 .nl !Statements!?3 .nl !Templates and Parsing!?5 .nl !Compound variable names!?5 .nl !Built-in variables!?5 .nl !Issuing commands to CMS!?5 .nl !Interactive Debugging!?6 .nl !REXFNS function package!?6 .nl !REXFNS2 function package!?7 .nl !REXWORDS function package!?7 .nl !Utility Modules!?7 .nl !Restrictions!?8 .nl !The Command and Exec Plist!?8 .nl !Sample REX Exec!?9 .il=0 .sk .hr=l,r,r4 .sk REX is a command programming language which allows you to combine useful sequences of commands to create new commands. $* highish-level proper level readable $* right sized bights It is used in conjunction with, or as a replacement for, the CMS EXEC and EXEC 2 languages. REX is especially suitable for writing Execs or editor macros, but is also a useful tool for algorithm development. .sk (@dREX EXEC)@d .skh Invoke using: !REX! <_parameter_> .skh .dtt=9.5;11;12.5 .hit=t1 !REX $'?'! ?describes REX EXEC and how to use the on-line help and tutorial. $ !REX! (@mI)@m ?installs REX in your CMS system under the name !EXEC! so that you may execute Execs written in any of the three languages. You probably will want to put '!EXEC REX! (@mI)@m' in your PROFILE EXEC. $$ !REX! ?enters the on-line help, viewing an index of topics. $$ !REX 200nn! ?(where !nn! is a REX error message number) describes the meaning of the error message and the likely cause of the error. $$ !REX kkk! ?(where !kkk! is a REX keyword) gives immediate information on the specified topic. .hi $ .nc $ .skr (@dDATA ITEMS)@d .skh The REX language is designed for the easy manipulation of character strings. Its expressions and instructions manipulate the following _items_: .skq .dtt=9.5;11;12.5 .hit=t1 $$ _string_ ?A _string_ is a quoted string of characters. Use two quotes to obtain one quote inside the string. The string may be specified in hexadecimal if the final quote is followed by an !X!. Some valid _strings_ are:%%!."Next." %.'Don.'.'t%touch.' %.'1de8.'x! $$ _number_ ?A _number_ is a string of up to 9 decimal digits before and./or after an decimal point. It may have a leading sign. Some valid _numbers_ are:%%%!17%%%98.07%%%.101! $$ _name_ ?A _name_ refers to a variable, which can be assigned any value. It may consist of up to 150 characters from the following selection: .nl ?.hst=0.6 (@o$'A-Z, a-z, 0-9, @ # $ % $ _ . ? ! ' )@o(@p$x'db')@p .nl ?The first character may not be a digit or period, except if the _name_ consists of the period alone. The _name_ is translated to upper case before use, and forms the initial value of the variable. Some valid _names_ are: %%%!Fred%%%COST(@o$'?')@o%%%next(@o$'_')@oindex%%%A.j! $$ _function-call_ ?A _function-call_ invokes an external routine with 0 to 7 arguments. The called routine will return a character string. A _function-call_ has the format: .nl ? _function-name_!((<_expr_> <,_expr_>...))! .nl ?_Function-name_ must be adjacent to the left parenthesis, and may be a _name_ or a _string_. $ .hi $ .skr (@dEXPRESSIONS)@d .skh Most REX statements permit the use of expressions, following the style of PL/I. Expressions are evaluated from left to right, modified by the priority of the operators (as ordered below). Parentheses may be used to change the order of evaluation. .nl All operations (except prefix operations) act on two _items_, and result in a character string. $ .skq .dtt=9.5;11;12.5 .hit=t1 $ !Prefix !(@o$' + - ^')@o ?Prefix operations: Plus; Minus; and Not. (For (@o+)@o and (@o-)@o, _item_ must evaluate to a _number_, for (@o^)@o, it must be '1' or '0'.) $$ (@o* $' / //')@o ?Multiply; Divide; Divide and return the remainder. (Both _items_ must evaluate to _numbers_.) $$ (@o$'+ -')@o ?Add; Subtract. (Both _items_ must evaluate to _numbers_.) $$ !(blank)! (@o $' ||')@o ?Concatenate: with or without blank. Abuttal of _items_ causes direct concatenation. $$ (@o$'= == ^= >= <= ^> ^< > <')@o .nl ?Comparisons (arithmetic compare if both _items_ evaluate to a _number_). The (@o$'==')@o operator checks for an (@yexact)@y match. $$ (@o$'&')@o ?Logical And. (Both _items_ must be '0' or '1'.) $$ (@o$'| &&')@o ?Logical Or; logical Exclusive Or. (Both _items_ must be '0' or '1'.) .hi .skh $$ The results of (@yarithmetic)@y operations are expressed to the same decimal precision as the more precise of the two _items_. For example, (@o123.57 + 12)@o will result in (@o135.57)@o. Results of division are rounded rather than truncated. $$ .skr (@dSTATEMENTS)@d .skh REX statements are built out of clauses consisting of a series of _items_, operators, etc. The semicolon at the end of each clause is often not required, being implied by line-ends and after the keywords !THEN, ELSE,! or !OTHERWISE!. A clause may be continued from one line to the next by using a comma at the end of the line. This then acts like a blank. Open _strings_ or _comments_ are not affected by line ends, and do not require a continuation character. .nl Keywords are shown in capitals in this list, however they may appear in either (or mixed) case. Keywords are only reserved when they are found in the correct context. $$ In the descriptions below: _expr_ is an expression as described above; _stmt_ is (@yany)@y one of the listed statements; _template_ is a parsing template, as described in a later section; _name_ is usually the name of a variable (see above). $$ .skq .dtt=9.5;11;12.5 .hit=t1 !_name_ (@o=)@o <_expr_>;! ?assignment: the variable _name_ is set to the value of _expr_. $$ !_expr_;! ?the value of _expr_ is issued as a command. $$ !ADDRESS <.lb _name_|_string_.rb <_expr_>>;! redirect commands or a single command to new environment. $$ !ARGS <_template_>;! ?parse the argument string into variables. The contents of all variables except the last are translated to upper case. (Note: the first argument is always the name of the Exec or subroutine.) $$ !CALL _name_ <_expr_>;! ?call an internal subroutine. On return, the variable _name_ will have the value from the !RETURN! statement. Subroutines may be called recursively. $$ !DO <_name_ (@o=)@o _expri_ > <.lb UNTIL|WHILE.rb _expr_>;! .nl .hst=1.2 ! <_stmt_>... END;! ?statement grouping with optional repetition and condition. The variable _name_ is stepped from _expri_ to _exprt_ in steps of _exprb_. These _exprs_ are evaluated only once at the top of the loop and must result in a whole number. This iterative phrase may be replaced by a single _expr_ which is a loop count (no variable used). If a !WHILE! or !UNTIL! is given, its _expr_ must evaluate to '0' or '1'. The condition is tested at the top of the loop if !WHILE! or at the bottom if !UNTIL!. $$ !DROP <_name_>...;! ?drop (reset) the named, or all, variables. $$ !EXIT <_expr_>;! ?leave the Exec . $$ !IF _expr_ .lb ;|THEN.rb _stmt_ .nl .hst=1.2 _stmt_>! ?if _expr_ evaluates to '1', execute the statement following the '!;!' or !THEN!. Otherwise (evaluates to '0') skip that statement and execute the one following the !ELSE! clause, if present. $$ !INTERPRET _expr_;! ?evaluate _expr_ and then execute the resultant string as if part of the original program. $$ !ITERATE <_name_>;! ?start next iteration of innermost repetitive loop . $$ !LEAVE <_name_>;! ?terminate innermost loop . $$ !NOP;! ?dummy statement, has no side-effects. $$ !PARSE ARGS <_template_>;! !ARGS! without upper case translation. $$ !PARSE PULL <_template_>;! !PULL! without upper case translation. $$ !PARSE SOURCE <_template_>;! parse program source description '!CMS .lb COMMAND|FUNCTION.rb fn ft fm!'. $$ !PARSE VAR _name_ <_template_>;! parse the value of _name_. $$ !PARSE VERSION <_template_>;! parse data describing interpreter. $$ !PROCEDURE;! ?start a new generation of variables within a subroutine. $$ !PULL <_template_>;! ?read the next string from the system queue ("stack") and parse it into variables. The contents of all variables except the last are translated to upper case. $$ !PUSH <_expr_>;! ?push _expr_ onto head of the system queue ("stack LIFO"). $$ !QUEUE <_expr_>;! ?add _expr_ to the tail of the system queue ("stack FIFO"). $$ !RETURN <_expr_>;! ?evaluate _expr_ and return the value to the caller. (Pushes the value onto the system queue if not a function or internal call.) $$ !SAY <_expr_>;! ?evaluate _expr_ and then display the result on the user$''''s console, using current line size. $$ !SELECT;! .nl .hst=1.2 !...! .nl .hst=1.2 ! <_stmt_>...>! .nl .hst=1.2 !END;! ?the !WHEN! _exprs_ are evaluated in sequence until one results in '1'. the _stmt_ immediately following it is executed and control then leaves the construct. If no _expr_ evaluates to '1', control passes to those _stmts_ following the !OTHERWISE! which must then be present. $$ !SIGNAL .lb ON|OFF.rb .lb _name_|_string_.rb ;! enable or disable exception traps. (The condition must be !ERROR, EXIT, NOVALUE, or SYNTAX!, and control will pass to the label of that name should the event occur while !ON!.) $$ !SIGNAL _expr_;! ?go to the label specified. Any pending statements, !DO ... END, INTERPRET,! etc. are terminated. $$ !TRACE _expr_;! ?if numeric then (if negative) inhibit tracing for a number of clauses, or (if positive) inhibit debug mode for a number of clauses. Otherwise trace according to first character of the value of _expr_: .nl ?'!E!'?=?trace after non-zero return codes. .nl ?'!C!'?=?trace all commands. .nl ?'!A!'?=?trace all clauses. .nl ?'!R!'?=?trace all clauses and expressions. .nl ?'(@mI)@m'?=?as '!R!', but trace intermediate evaluation results and name substitutions also. .nl ?'!L!'?=?trace only labels. .nl ?'!S!'?=?display rest of program without any execution (shows control nesting). .nl ?'!O!' or null = no trace. .nl ?'$x'5a''?=?trace according to the next character, and inhibit command execution. .nl ?$x'cd6fed'?=?turn debug mode (pause after trace) on or off. $$ _name_!:! ?form of labels for !CALL! or !SIGNAL!. The colon always acts as a clause separator. $$ (@o/*)@o !form of comment! (@o*/)@o may be used anywhere except in the middle of a _name_ or _string_. (Required on first line to identify REX Execs.) .hi $ $* Start 'page' 5, change heading first (no second circle) .rh .cr=all .vst=2 .hst=30 .cpn.vst=1 .bt .nc .skr $ (@dTEMPLATES for ARGS, PULL, and PARSE)@d .skh The !PULL, ARGS!, and !PARSE! instructions use a _template_ to parse a string. The template specifies the _names_ of variables that are to be given new values, together with optional triggers to control the parsing. Each _name_ in the template is assigned one word (without any leading or trailing blanks) from the input string in sequence, except that the last _name_ is assigned the remainder of the string (if any) unedited. If there are fewer words in the string than names in the template, all excess variables are set to null. In all cases, (@yall)@y the variables in the template are given a new value. $$ If !PULL! or !ARGS! are used, then the separately assigned words (@yonly)@y will first be translated to upper case. When this translation is not desired, use the !PARSE! instruction. $$ .skq The parsing algorithm also allows some pattern matching, in which you may "trigger" on either a _string_ or a _special-character_ (the '(@o()@o' is useful in the CMS environment, for example). A _special-character_ is one of: .skq .ct (@o+ - * / $'| & = ^ < > , : ) (')@o .skq .jt $$ If the template contains such a trigger, then alignment will occur at the next point where the trigger exactly matches the data. A trigger match splits the string up into separate parts, each of which is parsed in the same way as a complete string would be. $ $.skr (@dCOMPOUND VARIABLE NAMES)@d .skh Any _name_ may be "compound" in that it may be composed of several parts (separated by periods) some of which may have variable values. The parts are then substituted independently, to generate a fully resolved _name_. In general .skh .hst=1 _s(@b0)@b.s(@b1)@b.s(@b2)@b. --- .s(@bn)@b_ ?will be substituted to form: .skq .hst=1 _d(@b0)@b.v(@b1)@b.v(@b2)@b. --- .v(@bn)@b_ ?where _d(@b0)@b_ is upper case of _s(@b0)@b_ .nl ?_v(@b1)@b-v(@bn)@b_ are values of _s(@b1)@b-s(@bn)@b_. $$ .skq This facility may be used for content-addressable arrays and other indirect addressing modes. As an example, the sequence: .skq .ct !J(@o = )@o5; A.J(@o =)@o .'fred.';! .skq .jt would assign '!fred!' to the variable '!A.5!'. $ $.skr (@dBUILT-IN VARIABLES)@d .skq There are two built-in variables: .skh .dtt=9.5;11;12.5 .hit=t1 !RC!?is set to the return code after each executed command. .skq !SIGL!?is set to the line number of last line that caused !SIGNAL, CALL or RETURN! jump. .hi $ $.skr (@dISSUING COMMANDS to CMS)@d .skq The default environment for commands in Execs is CMS. A command is an expression, which may include _function-calls_, arithmetic operations, and so on. Operators or other special characters (for example '(@o()@o' or '(@o*)@o') must therefore be specified in a _string_ if they are to appear in the issued command. $$ To issue a CP command or call another Exec, the first word of the expression value should be '!CP!' or '!EXEC!' respectively. Use the !OBEY! command instead if full CMS command resolution is to be applied. $$ In editor macros, the default environment for commands is the same as the filetype of the macro. $ $* Start 'page' 6 .nc $* Restore normal heading .rh .cr=all .vst=2 .hst=30 .cpn.st .cpn.vst=1 .bt .skr .sk .bf=bot .tu .hr=l,r,r2 .sk=2 (@jIBML)@j .sk !Mike Cowlishaw, Mail Point 182, IBM UK Laboratories, Hursley Park, Winchester, UK. .sk CJN address: REXMAIL at WINPA Telephone: (UK) 0962-4433! .ef .tf $* Start 'page' 7 .nc .skr $ (@dINTERACTIVE DEBUGGING)@d .skq Execution of a TRACE instruction with a prefix '(@o$x'6f')@o' turns on debug mode. REX will then pause after most instructions which are traced at the console. You may then do one of three things: $$ (1) Enter a null line to continue execution. $$ (2) Enter an '(@o=)@o' to re-execute the clause last traced. $$ (3) Enter a list of REX instructions, which are interpreted immediately (!DO-END! statements must be complete, etc.). During execution of the string, no tracing takes place, except that non-zero return codes from host commands are displayed. Execution of a !TRACE! instruction with the '(@o$x'6f')@o' prefix will turn off debug mode. Other !TRACE! instructions affect the tracing that will occur when normal execution continues. .nl The numeric form of the !TRACE! instruction may be used to allow sections of program to be executed without pause for debug input. '!TRACE _n_!', (i.e. positive result) will allow execution to continue without pause for _n_ traced clauses. '!TRACE -_n_!', (i.e. a negative result) will allow execution to continue without pause and with tracing inhibited for _n_ clauses that would otherwise be traced. $ $.skr (@dREXFNS PACKAGE of BASIC FUNCTIONS)@d .skq REX has no "built-in" functions although several packages of external functions are available. The REXFNS package will be loaded automatically if needed, and includes the following: $$ .dtt=9.5;11;12.5 .hit=t1 !DATATYPE((string))! ?returns '!NUM!' if the !string! is a valid number otherwise returns '!CHAR!'. $$ !DATE(())! ?returns the date e.g. '!6 Nov 80!'. $$ !DELSTR((string,n<,k>))! ?deletes specified sub-string. $$ !INDEX((haystack,needle))! returns the position of the !needle! in the !haystack! (same format as PL/I). $$ !LASTPOS((needle,haystack))! returns the position of the last occurrence of the !needle! in the !haystack!. $$ !LENGTH((string))! ?returns the length of the !string!. $$ !LINESIZE(())! ?returns terminal line length. $$ !NEST(())! ?will return the current depth of Exec nesting (independent of Exec language). $$ !POS((needle,haystack))! ?returns the position of the !needle! in the !haystack!. $$ !READFLAG(())! ?returns '!STACK!' if the next !PULL! will read from the stack, otherwise returns '!CONSOLE!'. $$ !REPEAT((string,n))! ?returns !n(@o+)@o1! concatenated copies of !string!. $$ !STRIP((string<,.lb .'L.'|.'T.'|.'B.'.rb >))! ?returns string less leading, trailing, or both sets of blanks. Default is !.'T.'!. $$ !SUBSTR((string,n<,k>))! ?returns the sub-string of !string! which begins at the !n!th character, and is of length !k!. $$ !SYMBOL((.'_name_.'))! ?returns '!VAR!' if the _name_ has been used as a variable, otherwise returns '!LIT!'. $$ !TIME(())! ?returns the local time e.g. '!03:23:35!'. $$ !TRANS((string<,to-table<,from-table>>))! Same as PL/I !TRANSLATE! function, except that default translate tables convert !string! to upper case. $$ !TRUNC((string<,n>))! ?returns all of the !string! up to the first '!.!' plus up to !n! characters after it (default !n!(@o=)@o!0!). $$ !USERID(())! ?returns Virtual Machine userid. $$ !WCOUNT((string))! ?returns the number of words in the !string!. $ .hi $.skr (@dREXFNS2 PACKAGE of EXTENDED FUNCTIONS)@d .skq The extended function package is loaded automatically when needed. Note that the Logical functions (AND, OR, etc.) act on the individual bits within the character string arguments. $$ .dtt=9.5;11;12.5 .hit=t1 !AND((string,string<,pad>))! ?logically AND the strings. $$ !CLCL((string,string<,pad>))! ?compare character strings. $$ !CLXL((hexes,hexes<,pad>))! ?compare hex strings. $$ !COUNTBUF(())! ?return depth of Stack. $$ !D2X((number<,length>))! ?convert decimal to hex characters. $$ !E2X((hexes))! ?pack hex characters to bytes. $$ !FETCH((addr<,length>))! ?get bytes from storage. !addr! must be in binary form. $$ !OR((string,string<,pad>))! ?logically OR the strings. $$ !REVERSE((string))! ?reverses the string. $$ !SUBSET(())! ?returns '1' if in CMS SUBSET, else '0'. $$ !TM((string,mask<,pad>))! ?test string under mask. $$ !TYPEFLAG(())! ?test and set typing control flag. $$ !VERIFY((string,ref<,(@o$'^')@o>))! ?check the string for invalid characters. $$ !XOR((string,string<,pad>))! ?exclusive OR the strings. $$ !XRANGE((>))! return range of characters. $$ !X2D((hexes))! ?convert hex characters to decimal. $$ !X2E((string))! ?unpack bytes to hex characters. $.hi $.skr (@dREXWORDS PACKAGE of WORD PROCESSING FUNCTIONS)@d .skq These functions all treat data as a series of words delimited by blanks. The package is loaded automatically when needed. $$ .dtt=9.5;11;12.5 .hit=t1 !CENT((string,k))! ?returns !string! centred (width !k!). $$ !FIND((string,phrase))! ?returns the word number of the first word where !phrase! matches the !string!. Returns '!0!' if the !phrase! is not found. $$ !JUSTIFY((string,k))! ?justifies !string! to both margins (width !k!), by adding blanks between words. $$ !LEFT((string,k))! ?returns a string of length !k! with !string! left justified in it. $$ !RIGHT((string,k))! ?returns !string! right justified (width !k!). $$ !SPACE((string,n))! ?puts !n! spaces between each word. !n! may be !0!, to remove all blanks. $$ !WORD((string,n))! ?returns the !n!th word in the !string!. $.hi $.skr (@dUTILITY MODULES)@d .skq All commands that may be called from EXEC or EXEC 2 may be used with REX, except those that always attempt to set "Old EXEC" variables. Some of the modules available which are especially useful with Execs are: $$ .dtt=9.5;11;12.5 .hit=t1 !CLEAR! ?clears a 3270 screen. $$ !CONGET! ?does an immediate read to the Console regardless of the state of the input queue. $$ !EMSG! ?behaves like (@o&)@o!EMSG! in CMS EXEC. $$ !FSX! ?allows full screen control of console or dialed 3270s, especially useful for application modelling. $*$$ $*!HT! and !RT! ?halt or resume typing to the terminal. $$ !IEMP! ?allows Execs and macros to be kept in virtual storage to avoid disk I/O. $$ !IOS3270! ?general menu manipulation program, directly sets REX variables, can display screens from libraries, etc. $$ !IOX! ?uses the REX variables interface for I/O to CMS files, PUNCH, etc. $$ !MODULES! ?tests for the existence of modules called from an Exec. Strongly recommended for use in any Execs which are "for export". $$ !OSRESET! ?resets storage for PL/I etc. $$ !PROMPT! ?will prompt the 3270 user with data in the command input area. $$ !QEXEC! ?detects which of REX and EXEC2 are currently active. $$ !REXDUMP! ?is a debugging aid that displays up to 50 characters, and the length, of all currently active variables. $$ !RXLOCATE! ?function: controlled search for one string in another. .nl ?Call as: !LOCATE((needle,haystack<,n<,.'(@o^)@o.'>>))! $$ !RXRND! ?function: returns random integer. Call as: !RND((>))! $$ !STACKIO! ?general I/O package, similar to !IOX!, but interfacing to Execs via the Stack. $.hi .skr $ (@dRESTRICTIONS)@d .skq There are no restrictions on the length or content of manipulated character data (other than your Virtual Machine size). $$ .skq (@yCMS Restrictions:)@y .skq Exec files cannot be more that 65,535 bytes wide or more than 65,533 (_sic_) records long. .skq Lines read from the console cannot exceed 130 bytes. REX will format output lines of any length to fit the console. .skq Stacked lines are limited to 130 or 255 bytes (depending on CMS Release). .skq Commands entered from CMS command level are translated to upper case by CMS before being passed to REX. .skq Command names, function names, and the environment named by an !ADDRESS! statement will be truncated to 8 characters. $$ .skq (@yImplementation Restrictions:)@y .skq The _name_ of a variable or label may not exceed 150 bytes, and a literal _string_ may not exceed 250 bytes. .skq The internal representation of a clause (after removal of comments, extra blanks etc.) may not exceed 500 bytes. .skq A _number_ may not have more than 9 digits before and./or after the decimal point. .skq The control stack (for !IF, CALL! etc.) is limited to depth 100. .skq Functions cannot have more than 7 arguments. $ $.skr (@dCOMMAND and EXEC PLIST)@d .skq REX Execs may be invoked from programs via SVC 202 and the standard CMS Plist. The Plist can be extended to allow an untokenised string to be passed and also to permit execution directly from storage. $$ .skq For in-store execution, Filename and Filetype are still required in the file block, since these determine the logical program name and the default command environment. $$ .skq REX always provides an extended Plist (without a file block) when invoking commands. $$ .skq The standard CMS Plist consists of a series of 8-byte tokens, pointed to by GPR1, and terminated by (@o8X.'FF.')@o. The top byte of GPR1 may be set to (@oX.'00.')@o. If the top byte of GPR1 is set to (@oX.'01.')@o then this signifies that GPR0 points to the extended Plist. For calling REX, this has the form: $ $.tu .dtt=3;5.5;13 .ws=1 .cs=0.1 .box .skq (@o * The extended Plist: * a) defines the argument string * b) points to an optional File Block EPL?DS?0F?** Extended Plist ?DC?A(COMVERB)?$'->' CL5.'EXEC .' ?DC?A(BEGARGS)?$'->' argument string ?DC?A(ENDARGS)?$'->' character after end of *???argument string ?DC?A(FBL)?$'->' file block, if present, *???otherwise is A(0) .skh * The file block (only required for non- * EXEC or in-storage files) FBL?DS?0F?** File block ?DC?CL8.'name.'?logical name of program ?DC?CL8.'type.'?default destination for *???commands (blanks or .'EXEC.' *???both default to CMS) ?DC?CL2.'mode.'?should normally be .' .' ?DC?H.'extlen.'?length of extension block *???in fullwords: H.'2.' for in- *???store execution, else H.'0.' * Extension block starts here (only required * for in-store program): ?DC?AL4(PGM)?$'->' Descriptor list start ?DC?AL4(PND-PGM)?Length of descriptor list .skh * Descriptor list for in-store program: PGM?DS?0F ?DC?A(line$'.'1)?Address of line$'.'1 ?DC?F.'len$'.'1.'?Length of line$'.'1 ?? ... ?DC?A(line$'.'k)?Address of line$'.'k ?DC?F.'len$'.'k.'?Length of line$'.'k PND?EQU?* )@o .ws=.33 .cs=0 .er .skq $ .tf .sk .skr .skr (@dSAMPLE REX EXEC)@d .tu .dtt=3;5.5;13 .ws=1 .cs=0.1 .es=1 .skr (@o /* MOVE: Move file to another disk */ Args me Fn Ft Fm (nfm . If fn=.'.' $x'4f' fn=.'$x'6f'.' $x'4f' nfm=.'.' then do say .'Syntax is: MOVE Fn $x'ad'Ft $x'ad'Fm$x'bdbd' (x.' say .' where $x'7f'x$x'7f' is the target disk..' exit 100; end .skr IOX STATE Fn Ft Fm .'(FN FT FM.' if rc=28 then say .'Nothing to move$x'5a'.' if rc$'^='0 then exit rc .skr STATE fn ft nfm if rc=0 then do Say .'$x'7f'.'fn ft nfm.'$x'7f' exists: $x'7fe87f' to replace.' pull ans . if ans $'^=' .'Y.' then do Say .'File not moved.' Exit; end end else if rc$'^='28 then exit rc .skr COPYFILE fn ft fm .'= =.' nfm .'(OLDDATE REPLACE.' if rc=0 then ERASE fn ft fm if rc$'^='0 then exit rc Say .'$x'7f'.'fn ft.'$x'7f' moved to disk $x'7f'.'nfm.'$x'7f'.' )@o $endr ----------------------------------------------------------------------------------------------------------