REXX Tips & Tricks:Miscellaneous: Difference between revisions
mNo edit summary |
|||
(10 intermediate revisions by the same user not shown) | |||
Line 22: | Line 22: | ||
Please note that you cannot use OS/2 commands that change the environment in a REXX program running under PMREXX. You have to use a similar REXX function for that purpose (e.g. directory() instead of CD, VALUE() instead of SET, etc.). | Please note that you cannot use OS/2 commands that change the environment in a REXX program running under PMREXX. You have to use a similar REXX function for that purpose (e.g. directory() instead of CD, VALUE() instead of SET, etc.). | ||
Warning: The default address environment for a REXX program started via PMREXX in WARP 3 is PMREXX; the default environment in WARP 4 is CMD. Therefore, you cannot distinguish between the environments using ADDRESS() in WARP 4! | ;Warning: The default address environment for a REXX program started via PMREXX in WARP 3 is PMREXX; the default environment in WARP 4 is CMD. Therefore, you cannot distinguish between the environments using ADDRESS() in WARP 4! | ||
;Note:see also PMPopup/2 if you only want to use simple dialog boxes in REXX programs. | ;Note:see also PMPopup/2 if you only want to use simple dialog boxes in REXX programs. | ||
==The RXQUEUE filter== | ==The RXQUEUE filter== | ||
The purpose of the RXQUEUE filter is to copy the output of an OS/2 program into a REXX queue (The RXQUEUE filter is the external program RXQUEUE.EXE - not the built-in function [[RXQUEUE]]!) The syntax for RXQUEUE filter is: | |||
>>──RXQUEUE──┬───────────┬──┬────────┬──────>< | |||
└─queuename─┘ ├─/FIFO──┤ | |||
├─/LIFO──┤ | |||
└─/CLEAR─┘ | |||
The RXQUEUE filter usually operates on the default queue named "SESSION". However, if an environment variable named "RXQUEUE" exists, the RXQUEUE value is used for the queue name. | |||
'''Parameters''' | |||
;queuename:This is the name of the queue to use. The queue must already exist. The name of a queue can only contain the following characters: 'A'...'Z', '0'...'9', '.', '!', '?' and '_'. Lowercase letters are converted to uppercase letters. | |||
;/LIFO:Stacks items from STDIN last in, first out (LIFO) on a REXX queue. | |||
;/FIFO:Queues items from STDIN first in, first out (FIFO) on a REXX queue. | |||
;/CLEAR:Removes all lines from a REXX queue. | |||
;Note: Again, do not confuse the RXQUEUE filter with the RXQUEUE built-in function! Note further that you cannot use the RXQUEUE filter to write a REXX queue to STDOUT - you've to write a REXX program to do this task. (see [[Write the REXX Queue to STDOUT]] for an example). | |||
==Return code of the function ADDRESS== | |||
A REXX program can use the function <tt>ADDRESS</tt> to detect the current environment. Following is a list of environments I know about (see [Passing parameter to Rexx Dialog programs] and [[REXX Tips & Tricks:General hints for REXX#Run a REXX program under a specific environment|Run a REXX program under a specific environment]] for examples for using this function.): | |||
{|class="wikitable" | |||
!Return code of ADDRESS||Environment||Comments | |||
|- | |||
|CMD||OS/2 REXX Interpreter; also Object REXX for Win95/WinNT||use PARSE SOURCE to distinguish between the interpreter: OS/2 REXX returns OS/2; Object REXX for WinNT returns WIN32 | |||
|- | |||
|CMS||VM/ESA 1.1 REXX Interpreter|| | |||
|- | |||
|COMMAND||Bill's REXX for DOS<br/>IBM PC DOS 7 REXX Interpreter||Use PARSE VERSION to distinguish between the environments. | |||
|- | |||
|CPEDIT||CPEDIT, an XEDIT clone from IBM|| | |||
|- | |||
|CPICOMM||SAA common environment especially used with communications|| | |||
|- | |||
|DFS||Display File Systems|| | |||
|- | |||
|DOS||Bill's REXX for DOS<br/>IBM PC DOS 7 REXX Interpreter||Use PARSE VERSION to distinguish between the environments. | |||
|- | |||
|EPM||EPM, OS/2 Editor|| | |||
|- | |||
|GLOBE||PMGlobe 2.18||IBM EWS Graphic program from Mike Cowlishaw, IBM UK Laboratories | |||
|- | |||
|FLEETSTREET||FleetStreet v1.03||Msg Reader & Editor for Squish msg bases | |||
|- | |||
|INT2E||Bill's REXX for DOS|| | |||
|- | |||
|ispcir||OS/2 DialogManager, IBM|| | |||
|- | |||
|IPSEXEC||Tritus SPF, Tritus Inc.|| | |||
|- | |||
|ISREDIT||SPF/2, CTC|| | |||
|- | |||
|KEDIT||KEDIT, an XEDIT clone from Mansfield Software | |||
|- | |||
|ksh||IBM's AIX REXX||The value is independent from the current shell | |||
|- | |||
|MVS||OS/390 v1.2 (PGM=IRXJCL) REXX Interpreter|| | |||
|- | |||
|NULL||DrDialog||this is an alternate SubCommand-Handler for DrDialog programs | |||
|- | |||
|PMREXX||PMREXX, OS/2 PMREXX.EXE (see the warning in the section [[#Using PMREXX]])|| | |||
|- | |||
|REXXTERM||REXXTERM, Quercus Software|| | |||
|- | |||
|RXDLG||Rexx Dialog|| | |||
|- | |||
|SAY||DrDialog||this is an alternate SubCommand-Handler for DrDialog programs | |||
|- | |||
|STARTDOS||StartDOS||a program to start DOS VDMs by Monte Copeland | |||
|- | |||
|SYSTEM||Bill's REXX for DOS<br/>Mark Hesslings's Regina REXX for Windows NT||use PARSE SOURCE to distinguish between the interpreter: Bill's REXX returns MSDOS, Mark's REXX returns WIN32 | |||
|- | |||
|TE2||TE/2, Oberon Software|| | |||
|- | |||
|THE||THE Hessling Editor by Mark Hessling||THE is an XEDIT clone for various operating systems | |||
|- | |||
|TSO||OS/390 v1.2 (TSO) REXX Interpreter|| | |||
|- | |||
|VISION||ObjectVision, Borland|| | |||
|- | |||
|UNIX||uniREXX on Solaris v2.6|| | |||
|- | |||
|ZOC||ZOC 2.x, Markus Schmidt||One of the best OS/2 terminal programs available! | |||
|} | |||
==ANSI ESC Sequences== | ==ANSI ESC Sequences== | ||
ANSI ESC Sequences - also called ANSI commands - are useful for doing some display I/O control in REXX. | |||
To use ANSI commands the OS/2 ANSI support must be active. To activate the ANSI support use the OS/2 command ANSI ON and to deactivate the ANSI support use the OS/2 command ANSI OFF. To get the current status of the ANSI support use the OS/2 command ANSI without a parameter. The default for the ANSI support is ON. (see Check if ANSI is active - 1 - or Check if ANSI is active - 2 - for REXX source to detect if ANSI support is active from within a REXX program) | |||
Each ANSI command begins with the sequence ESC[. where ESC represents the ASCII code 1Bh (= 27 decimal). If there is more than one parameter for an ANSI command, use a semicolon (;) to separate the parameter. | |||
To output ANSI commands you can use the functions LINEOUT and CHAROUT or the statement SAY. Example: | |||
say "1B"x || "[30;41m" || "This text is black on red" | |||
call lineOut , "1B"x || "[31;40m" || "This text is red on black" | |||
call charOut , "1B"x || "[0m" || "This text is in default color" | |||
(see Using ANSI sequences for some sample code using ANSI sequences and RxLBox - menu routine in REXX is a menu program using only ANSI sequences to implement the navigation with cursor keys and function keys) | |||
;Note:To use the ANSI commands to set or get the cursor position you must use the function CHAROUT! (see SysCls for another minor restriction) | |||
;Further Note:Almost all ANSI Control Characters are documented in the command reference of WARP version 4. | |||
{|class="wikitable" | |||
|+ANSI Commands | |||
!Command||Function | |||
|- | |||
|ESC[colsA||Cursor up # lines | |||
|- | |||
|ESC[colsB||Cursor down # lines | |||
|- | |||
|ESC[rowsC||Cursor right # columns | |||
|- | |||
|ESC[rowsD||Cursor left # columns | |||
|- | |||
|ESC[row;colH||Position the cursor (the upper left corner is 1,1) | |||
|- | |||
|ESC[2J||Clear the whole screen | |||
|- | |||
|ESC[K||Clear the rest of the line | |||
|- | |||
|ESC[6n||Get the current cursor position (see Get the current cursor position) | |||
|- | |||
|ESC[row;colf||Position the cursor (like "H") | |||
|- | |||
|ESC[row;colR||Report current cursor line and column (*) | |||
|- | |||
|ESC[=modeh||Set the display mode (see below) | |||
|- | |||
|ESC[=model||Set the display mode (see below) | |||
|- | |||
|ESC[attr;attr;..m||Set the color attribute (see below) | |||
|- | |||
|ESC[key;"str"p||Redefine the key "key" with the string "str" (see Key redefinitions and Key Codes for key redefinitions) | |||
|- | |||
|ESC[s||Save the current cursor position (nested calls are not allowed) | |||
|- | |||
|ESC[u||Restore the cursor position (nested calls are not allowed) | |||
|} | |||
{|class="wikitable" | |||
|+Display attributes | |||
!Attribute||Description | |||
|- | |||
|0||all attributes off (white on black) | |||
|- | |||
|1||bold | |||
|- | |||
|2||normal | |||
|- | |||
|4||underline (only on b/w displays) | |||
|- | |||
|5||blink | |||
|- | |||
|7||reverse video | |||
|- | |||
|8||invisible | |||
|- | |||
|30-37||set the foreground color: | |||
:30=Black, 31=Red, 32=Green, 33=Yellow | |||
:34=Blue, 35=Magenta, 36=Cyan, 37=White | |||
|- | |||
|40-47||set the background color: | |||
:40=Black, 41=Red, 42=Green, 43=Yellow | |||
:44=Blue, 45=Magenta, 46=Cyan, 47=White | |||
|} | |||
{|class="wikitable" | |||
|+Display modes | |||
!Mode||Description | |||
|- | |||
|0||Text 40x25 monochrome | |||
|- | |||
|1||Text 40x25 color | |||
|- | |||
|2||Text 80x25 monochrome | |||
|- | |||
|3||Text 80x25 color | |||
|- | |||
|4||Graphics 320x200 4 colors | |||
|- | |||
|5||Graphics 320x200 2 color | |||
|- | |||
|6||Graphics 640x200 2-color | |||
|- | |||
|7||cursor wrap off (7l) or on (7h) | |||
|} | |||
===Key Codes for key redefinitions=== | |||
{|class="wikitable" | |||
|+Keycodes for key redefinitions (extract) | |||
!ASCII Key Codes||Code||SHIFT+Code||CTRL+Code||ALT+Code | |||
|- | |||
|F1||0;59||0;84||0;94||0;104 | |||
|- | |||
|F2||0;60||0;85||0;95||0;105 | |||
|- | |||
|F3||0;61||0;86||0;96||0;106 | |||
|- | |||
|F4||0;62||0;87||0;97||0;107 | |||
|- | |||
|F5||0;63||0;88||0;98||0;108 | |||
|- | |||
|F6||0;64||0;89||0;99||0;109 | |||
|- | |||
|F7||0;65||0;90||0;100||0;110 | |||
|- | |||
|F8||0;66||0;91||0;101||0;111 | |||
|- | |||
|F9||0;67||0;92||0;102||0;112 | |||
|- | |||
|F10||0;68||0;93||0;103||0;113 | |||
|- | |||
|F11||0;133||0;135||0;137||0;139 | |||
|- | |||
|F12||0;134||0;136||0;138||0;140 | |||
|- | |||
|Home (numeric key)||0;71||55||0;119||— | |||
|- | |||
|Up Arrow (numeric key)||0;72||56||(0;141)||— | |||
|- | |||
|Page Up (numeric key)||0;73||57||0;132||— | |||
|- | |||
|Left Arrow (numeric key)||0;75||52||0;115||— | |||
|- | |||
|Right Arrow (numeric key)||0;77||54||0;116||— | |||
|- | |||
|End (numeric key)||0;79||49||0;117||— | |||
|- | |||
|Down Arrow (numeric key)||0;80||50||(0;145)||— | |||
|- | |||
|Page Down (numeric key)||0;81||51||0;118||— | |||
|- | |||
|Ins (numeric key)||0;82||48||(0;146)||— | |||
|- | |||
|Del (numeric key)||0;83||46||(0;147)||— | |||
|- | |||
|Home||(224;71)||(224;71)||(224;119)||(224;151) | |||
|- | |||
|Up Arrow||(224;72)||(224;72)||(224;141)||(224;152) | |||
|- | |||
|Page Up||(224;73)||(224;73)||(224;132)||(224;153) | |||
|- | |||
|Left Arrow||(224;75)||(224;75)||(224;115)||(224;155) | |||
|- | |||
|Right Arrow||(224;77)||(224;77)||(224;116)||(224;157) | |||
|- | |||
|End||(224;79)||(224;79)||(224;117)||(224;159) | |||
|- | |||
|Down Arrow||(224;80)||(224;80)||(224;145)||(224;154) | |||
|- | |||
|Page Down||(224;81)||(224;81)||(224;118)||(224;161) | |||
|- | |||
|Insert||(224;82)||(224;82)||(224;146)||(224;162) | |||
|- | |||
|Delete||(224;83)||(224;83)||(224;147)||(224;163) | |||
|- | |||
|Print Screen||—||—||0;114||— | |||
|- | |||
|Pause/Break||—||—||0;0||— | |||
|- | |||
|Backspace||8||8||127||(0) | |||
|- | |||
|Enter||13||—||10||(0,28) | |||
|- | |||
|Tab||9||0;15||(0;148)||(0;165) | |||
|- | |||
|Null||0;3||—||—||— | |||
|- | |||
|ESC||27||27||27||27 | |||
|- | |||
|Space||32||32||32||23 | |||
|- | |||
|A||97||65||1||0;30 | |||
|- | |||
|B||98||66||2||0;48 | |||
|- | |||
|C||99||67||3||0;46 | |||
|- | |||
|D||100||68||4||0;32 | |||
|- | |||
|E||101||69||5||0;18 | |||
|- | |||
|F||102||70||6||0;33 | |||
|- | |||
|G||103||71||7||0;34 | |||
|- | |||
|H||104||72||8||0;35 | |||
|- | |||
|I||105||73||9||0;23 | |||
|- | |||
|J||106||74||10||0;36 | |||
|- | |||
|K||107||75||11||0;37 | |||
|- | |||
|L||108||76||12||0;38 | |||
|- | |||
|M||109||77||13||0;50 | |||
|- | |||
|N||110||78||14||0;49 | |||
|- | |||
|O||111||79||15||0;24 | |||
|- | |||
|P||112||80||16||0;25 | |||
|- | |||
|Q||113||81||17||0;16 | |||
|- | |||
|R||114||82||18||0;19 | |||
|- | |||
|S||115||83||19||0;31 | |||
|- | |||
|T||116||84||20||0;20 | |||
|- | |||
|U||117||85||21||0;22 | |||
|- | |||
|V||118||86||22||0;47 | |||
|- | |||
|W||119||87||23||0;17 | |||
|- | |||
|X||120||88||24||0;45 | |||
|- | |||
|Y||121||89||25||0;21 | |||
|- | |||
|Z||122||90||26||0;44 | |||
|- | |||
|1||49||(*)||—||0;120 | |||
|- | |||
|2||50||(*)||—||0;121 | |||
|- | |||
|3||51||(*)||—||0;122 | |||
|- | |||
|4||52||(*)||—||0;123 | |||
|- | |||
|5||53||(*)||—||0;124 | |||
|- | |||
|6||54||(*)||—||0;125 | |||
|- | |||
|7||55||(*)||—||0;126 | |||
|- | |||
|8||56||(*)||—||0;126 | |||
|- | |||
|9||57||(*)||—||0;127 | |||
|- | |||
|0||48||(*)||—||0;129 | |||
|- | |||
| !||33||—||—||(*) | |||
|- | |||
| " ||34||—||—||(*) | |||
|- | |||
| � ||21||—||—||(*) | |||
|- | |||
| $ ||36||—||—||(*) | |||
|- | |||
| % ||37||—||—||(*) | |||
|- | |||
| & ||38||—||—||(*) | |||
|- | |||
| / ||47||—||—||(*) | |||
|- | |||
| ( ||40||—||—||(*) | |||
|- | |||
| ) ||41||—||—||(*) | |||
|- | |||
| = ||61||—||—||(*) | |||
|- | |||
| ? ||63||—||—||(*) | |||
|- | |||
| ` ||96||—||—||— | |||
|- | |||
| ' ||39||—||—||— | |||
|- | |||
| * ||42||—||—||— | |||
|- | |||
| + ||43||—||—||— | |||
|- | |||
| # ||35||—||—||— | |||
|- | |||
| , ||44||—||—||— | |||
|- | |||
| ; ||59||—||—||— | |||
|- | |||
| . ||46||—||—||— | |||
|- | |||
| : ||58||—||—||— | |||
|- | |||
| - ||45||—||—||— | |||
|- | |||
| _ ||95||—||—||— | |||
|- | |||
| < ||60||—||—||— | |||
|- | |||
| > ||62||—||—||— | |||
|- | |||
| ^ ||94||—||—||— | |||
|- | |||
| ° ||248||—||—||— | |||
|- | |||
| \ ||92||—||—||— | |||
|- | |||
| [ ||91||—||—||— | |||
|- | |||
| ] ||93||—||—||— | |||
|- | |||
| { ||123||—||—||— | |||
|- | |||
| } ||125||—||—||— | |||
|- | |||
|<nowiki>|</nowiki>||124||—||—||— | |||
|- | |||
|~ ||126||—||—||— | |||
|- | |||
|@ ||64||—||—||— | |||
|- | |||
|ENTER (keypad)||13||—||10||(0;166) | |||
|- | |||
|/ (keypad)||47||47||(0;142)||(0;74) | |||
|- | |||
|* (keypad)||42||(0;144)||(0;78)||— | |||
|- | |||
| - (keypad)||45||45||(0;149)||(0;164) | |||
|- | |||
| + (keypad)||43||43||(0;150)||(0;55) | |||
|- | |||
|5 (keypad)||(0;76)||53||(0;143)||— | |||
|- | |||
|ä (German umlaut)||132||142||—||— | |||
|- | |||
|ö (German umlaut)||148||153||—||— | |||
|- | |||
|ü (German umlaut)||129||154||—||— | |||
|- | |||
|ß (German special)||225||—||—||— | |||
|} | |||
;Note:Use the values in parenthesis with care - they may work or may not work. | |||
=="Compiling" REXX programs== | =="Compiling" REXX programs== | ||
I don't know of a real REXX compiler for OS/2 REXX. But because the REXX interpreter stores an tokenized copy of each REXX program in the EAs of the program, it is possible to delete the source code from REXX programs (see REXXCC). Another method to "compile" a REXX program is used by the program RxCLS. But this is also no real compiler. | |||
The only method to create a standalone REXX program that runs on any machine with or without REXX installed is to create an EXE containing the REXX program and a static version of a REXX interpreter. This is possible with the package Rexx/Wrapper and the REXX Interpreter Regina from Mark Hessling (see Internet - Web Pages) | |||
To "compile" an Object-Oriented REXX program you can use the program REXXC.EXE which is part of Object-Oriented REXX. REXXC.EXE creates the token image and saves it in a REXX cmd. This method avoids the 64 K limit for the token image. (see also the [[#Creating "compiled" programs for Classic REXX and Object REXX]]) | |||
Another method to create a token image of your REXX program is to load the REXX program into the macro space and save the macro space into a file. This will produce a token image of your REXX program that you can reload into the macrospace and execute it from there. This method also avoids the 64 K limit of the EAs. (see REXXCC - a REXX "compiler") In this case you need an additional loader to load the token image into the macro space again before you can execute it. | |||
Or use LoadMac.cmd to create and load the token image: | |||
<code> | |||
REM *** Create the token image | |||
LOADMAC CLEAR ADD:myProg.CMD SAVE:myProg.IMG | |||
REM *** Load the image into the REXX macro space | |||
LOADMAC CLEAR LOAD:MyProg.IMG | |||
REM *** Execute the image | |||
REXXTRY call myprog myparms | |||
REM *** Drop the image from the REXX macro space | |||
LOADMAC DROP:MyProg | |||
REM *** or (if the image contains more than one macro) | |||
LOADMAC CLEAR | |||
</code> | |||
see also Debugging a "compiled" REXX program, Get the source code of a "compiled" REXX program, and Protect the source code of a REXX program | |||
===Creating "compiled" programs for Classic REXX and Object REXX=== | |||
To use a "compiled" program in Classic REXX and in Object REXX you must create a "compiled" version for Classic REXX (created for example with REXXCC) and a "compiled" version for Object REXX (created with REXXC.EXE from Object REXX). Then, to call your "compiled" REXX program you should use a "wrapper" program written in REXX (Do not "compile" the wrapper program!). | |||
The wrapper program might look as follows: | |||
<code> | |||
/* ------------------------------------------------------------------ */ | |||
/* sample wrapper to call a "compiled" REXX program depending on the */ | |||
/* version of the current REXX interpreter (Classic REXX or */ | |||
/* Object REXX) */ | |||
/* */ | |||
/* Note: */ | |||
/* */ | |||
/* This program assumes */ | |||
/* */ | |||
/* - the REXX program "compiled" for Classic REXX is called */ | |||
/* <name_of_this_prog>C.CMD */ | |||
/* */ | |||
/* - the REXX program "compiled" for Object REXX is called */ | |||
/* <name_of_this_prog>O.CMD */ | |||
/* */ | |||
/* - both programs are in the same directory as this program */ | |||
/* */ | |||
/* init the return code */ | |||
rc = 255 | |||
/* get the parameter */ | |||
parse arg thisParameters | |||
/* get the name of this program */ | |||
parse source . . thisFile | |||
progBaseName = substr( thisFile,1 lastPos( ".", thisFile )-1 ) | |||
/* check the version of the current REXX */ | |||
/* interpreter */ | |||
parse upper version thisVersion thisVersionNo | |||
if thisVersion = "OBJREXX" | thisVersionNo > 4.00 then | |||
do | |||
/* current REXX interpreter is Object REXX */ | |||
"@cmd /c " progBaseName || "O.CMD" thisParameters | |||
end /* if thisVersion = "OBJREXX" | thisVersionNo > 4.00 then */ | |||
else | |||
do | |||
/* current REXX interpreter is Classic REXX */ | |||
"@cmd /c " progBaseName || "C.CMD" thisParameters | |||
end /* else */ | |||
return rc | |||
</code> | |||
==Prevent REXX from creating a token image== | ==Prevent REXX from creating a token image== | ||
Set the read-only attribute of REXX cmds for which the REXX interpreter should not create a token image (or copy them to a read-only disk or to a filesystem not supporting Extended Attributes). | Set the read-only attribute of REXX cmds for which the REXX interpreter should '''not''' create a token image (or copy them to a read-only disk or to a filesystem '''not''' supporting Extended Attributes). | ||
==Extend the program REXXTRY.CMD== | |||
The program REXXTRY.CMD (in the directory \OS2) is really useful to test some REXX statements. But it has one disadvantage: The input routine is very simple. | |||
But, thanks to Albert Crosby, there's a simple way to overcome this disadvantage. Albert Crosby who's that you might ask. Well, Albert Crosby is the author of a REXX routine called CMDLINE1.CMD which is very suitable to extend the input routine from REXXTRY.CMD | |||
To do this do the following: | |||
Create a copy of the file REXXTRY.CMD and name it EREXXTRY.CMD. | |||
Extract the source code of CMDLINE.CMD from this document (see Using the samples) | |||
Load the file EREXXTRY.CMD into a text editor and append the source of CMDLINE1.CMD at the end of EREXXTRY.CMD. | |||
Then insert the following lines in EREXXTRY.CMD before the line parse arg argrx: | |||
<code> | |||
/* ------------------------------------------------------------------ */ | |||
/* history of changes for RXT&T version: */ | |||
/* */ | |||
/* RXT&T v1.60 /bs */ | |||
/* - changed code to also work if REXXUTIL is not accessible */ | |||
/* */ | |||
/* RXT&T v1.70 /bs */ | |||
/* - corrected an error in the RxFuncAdd calls */ | |||
/* - in the previous version, undefined function keys lead to */ | |||
/* invalid return codes in cmdline. Corrected. */ | |||
/* - added code to save and load the history list to the routine */ | |||
/* cmdline */ | |||
/* The keys for handling the history file are: */ | |||
/* F2 - save the history list (overwrite an existing file) */ | |||
/* ALT-F2 - save the history list (append to an existing file) */ | |||
/* SHIFT-F2 - load the history list */ | |||
/* CTRL-F2 - change the history list file */ | |||
/* ALT-F4 - save history list and exit program */ | |||
/* - added online help for the edit keys (CTRL-F1) */ | |||
/* */ | |||
/* RXT&T v2.00 /bs */ | |||
/* - added code to handle situations when other programs drop the */ | |||
/* REXXUTIL functions */ | |||
/* RXT&T v2.30 /bs */ | |||
/* - added key definitions for loading and dropping REXXUTIL */ | |||
/* functions (F11 and F12) */ | |||
/* RXT&T v2.40 /bs */ | |||
/* - added code to show the version of the active REXX interpreter */ | |||
/* */ | |||
/* (c) 1996 Bernd Schemmer, Germany, EMail: Bernd.Schemmer@gmx.de */ | |||
/* */ | |||
/* */ | |||
ReStart: /* v2.00 */ | |||
if rxFuncQuery "SysCurPos" = 0 then /* v1.60 */ | |||
call rxFuncDrop "SysCurPos" /* v1.60 */ | |||
if rxFuncQuery "SysGetKey" = 0 then /* v1.60 */ | |||
call rxFuncDrop "SysGetKey" /* v1.60 */ | |||
/* load the necessary REXXUTIL v1.60 */ | |||
/* functions v1.60 */ | |||
call RxFuncAdd "SysCurPos", "RexxUtil", "SysCurPos" /* v1.70 */ | |||
call RxFuncAdd "SysGetKey", "RexxUtil", "SysGetKey" /* v1.70 */ | |||
!rexxUtilLoaded = 0 /* v1.60 */ | |||
/* check if the rxFuncAdd calls were v1.60 */ | |||
/* successful v1.60 */ | |||
signal ON Syntax Name RexxUtilNotLoaded /* v1.60 */ | |||
call SysCurPos /* v1.60 */ | |||
/* use the extended input v1.60 */ | |||
/* routine only if possible v1.60 */ | |||
!rexxUtilLoaded = 1 /* v1.60 */ | |||
/* name of the file for the history v1.70 */ | |||
/* list v1.70 */ | |||
!history.file = "EREXXTRY.HST" /* v1.70 */ | |||
/* redefine some keys */ | |||
!history.key.61 = "exit" /* F3 */ | |||
!history.key.104 = "?" /* ALT-F1 */ | |||
/* F11 load REXXUTIL v2.30 */ | |||
!history.key.133 = "call rxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs'; | |||
call SysLoadFuncs; say 'REXXUTIL loaded.'"; | |||
/* F12 drop REXXUTIL v2.30 */ | |||
!history.key.134 = "call SysDropFuncs; say 'REXXUTIL functions dropped.'" | |||
/* see Key redefinitions for further key codes */ | |||
RexxUtilNotLoaded: /* v1.60 */ | |||
/* ------------------------------------------------------------------ */ | |||
</code> | |||
Now replace the line '''parse pull inputrx''' in EREXXTRY.CMD with | |||
<code> | |||
/* ------------------------------------------------------------------ */ | |||
parse version tVersion /* v2.40 */ | |||
say " --- Current REXX interpreter is: "tversion /* v2.40 */ | |||
if !rexxUtilLoaded <> 1 then /* v1.60 */ | |||
do /* v2.00 */ | |||
say " --- no extended keys available --- " /* v2.00 */ | |||
say " --- use ""signal restart"" to try to load" , /* v2.30 */ | |||
"the extended key support again --- " /* v2.30 */ | |||
inputrx = lineIN() /* v1.60 */ | |||
end /* v2.00 */ | |||
else /* v1.60 */ | |||
do /* v1.70 */ | |||
say " --- extended keys are active," || , /* v1.70 */ | |||
" CTRL-F1 = online help ---" /* v1.70 */ | |||
inputrx = cmdLine() /* v1.60 */ | |||
end /* v1.70 */ | |||
/* ------------------------------------------------------------------ */ | |||
</code> | |||
Save the file EREXXTRY.CMD. | |||
That's all! You've just created EREXXTRY.CMD - a clone of REXXTRY.CMD with a much more comfortable input routine. | |||
See also: CMDLINE | |||
=="Undocumented" REXX functions== | =="Undocumented" REXX functions== | ||
Line 62: | Line 688: | ||
Note The parameter option is only needed for DBCS strings) | Note The parameter option is only needed for DBCS strings) | ||
For SBCS strings you should not use this parameter. | For SBCS strings you should not use this parameter. | ||
==REXX ANSI Standard== | |||
There's now an ANSI standard for REXX. The REXX Standard number is X3.274. You can get a copy of the Standard from the ANSI at: | |||
:American National Standards Institute<br/>Attn: Customer Service<br/>11 West 42nd Street<br/>New York, NY 10036<br/>Phone: +1 212 642 4900<br/>Fax: +1 212 302 1286<br/>(see Internet - Web Pages) | |||
The document costs $125 (+S&H). A cheaper way for retrieving a copy of the standard is: | |||
Download the pre-publication PostScript draft version of the standard from Mike Cowlishaw's REXX home page (see Internet - Web Pages). This version is functional identical to the ANSI version. | |||
---- | |||
;History | |||
"Since 1991, a technical committee has been preparing a document for a proposed American National Standard (ANSI Standard) for REXX. Here is the committee's charter: | |||
The project is for development of an American National Standard. The scope of this standard will be 'The REXX Language' described by Michael F. Cowlishaw in his book, altered as necessary to promote portability, reliability, maintainability and efficient execution of REXX programs on a variety of computing systems." | |||
The X3J18 committee has been operationg under the procedures of the American National Standards Institute (ANSI); the addresses of the Chairman, Vice-Chairman, and Secretary are as follows: | |||
;Chairman:B L Marks<br/>IBM UK Laboratories<br/>Hursley Park<br/>Winchester, England SO21 2JN | |||
;Vice-chairman:N F N Milsted<br/>IX Corporation<br/>575 W. Madison, Suite 3610<br/>Chicago, IL 60661 | |||
;Secretary:E Spire<br/>The Workstation Group<br/>6300 River Road<br/>Rosemont, IL 60018 | |||
[[Category:REXX Tips & Tricks]] | [[Category:REXX Tips & Tricks]] |
Latest revision as of 05:12, 28 January 2020
This section contains some further useful information.
Using PMREXX
The syntax for PMREXX is:
>>──PMREXX───┬────┬──┬─────────────┬─┬───────────┬─>< ├─/Q─┤ └─rexxprogram─┘ └─parameter─┘ └─/T─┘
Where:
- /Q
- Close PMREXX after the REXX program ends (no "The program has ended" message box)
- /T
- Start PMREXX in trace mode
- rexxprogram
- Name of the rexx program
- parameter
- Parameter for the REXX program
All parameters, except rexxprogram, are optional.
Using PMREXX with the parameter /Q is useful for simple programs which only need to show a PM messagebox (using RxMessageBox). For an example see Saving the Desktop (3.0)
(see Run a REXX program under a specific environment on how to force a program to run under PMREXX)
Please note that you cannot use OS/2 commands that change the environment in a REXX program running under PMREXX. You have to use a similar REXX function for that purpose (e.g. directory() instead of CD, VALUE() instead of SET, etc.).
- Warning
- The default address environment for a REXX program started via PMREXX in WARP 3 is PMREXX; the default environment in WARP 4 is CMD. Therefore, you cannot distinguish between the environments using ADDRESS() in WARP 4!
- Note
- see also PMPopup/2 if you only want to use simple dialog boxes in REXX programs.
The RXQUEUE filter
The purpose of the RXQUEUE filter is to copy the output of an OS/2 program into a REXX queue (The RXQUEUE filter is the external program RXQUEUE.EXE - not the built-in function RXQUEUE!) The syntax for RXQUEUE filter is:
>>──RXQUEUE──┬───────────┬──┬────────┬──────>< └─queuename─┘ ├─/FIFO──┤ ├─/LIFO──┤ └─/CLEAR─┘
The RXQUEUE filter usually operates on the default queue named "SESSION". However, if an environment variable named "RXQUEUE" exists, the RXQUEUE value is used for the queue name.
Parameters
- queuename
- This is the name of the queue to use. The queue must already exist. The name of a queue can only contain the following characters: 'A'...'Z', '0'...'9', '.', '!', '?' and '_'. Lowercase letters are converted to uppercase letters.
- /LIFO
- Stacks items from STDIN last in, first out (LIFO) on a REXX queue.
- /FIFO
- Queues items from STDIN first in, first out (FIFO) on a REXX queue.
- /CLEAR
- Removes all lines from a REXX queue.
- Note
- Again, do not confuse the RXQUEUE filter with the RXQUEUE built-in function! Note further that you cannot use the RXQUEUE filter to write a REXX queue to STDOUT - you've to write a REXX program to do this task. (see Write the REXX Queue to STDOUT for an example).
Return code of the function ADDRESS
A REXX program can use the function ADDRESS to detect the current environment. Following is a list of environments I know about (see [Passing parameter to Rexx Dialog programs] and Run a REXX program under a specific environment for examples for using this function.):
Return code of ADDRESS | Environment | Comments |
---|---|---|
CMD | OS/2 REXX Interpreter; also Object REXX for Win95/WinNT | use PARSE SOURCE to distinguish between the interpreter: OS/2 REXX returns OS/2; Object REXX for WinNT returns WIN32 |
CMS | VM/ESA 1.1 REXX Interpreter | |
COMMAND | Bill's REXX for DOS IBM PC DOS 7 REXX Interpreter |
Use PARSE VERSION to distinguish between the environments. |
CPEDIT | CPEDIT, an XEDIT clone from IBM | |
CPICOMM | SAA common environment especially used with communications | |
DFS | Display File Systems | |
DOS | Bill's REXX for DOS IBM PC DOS 7 REXX Interpreter |
Use PARSE VERSION to distinguish between the environments. |
EPM | EPM, OS/2 Editor | |
GLOBE | PMGlobe 2.18 | IBM EWS Graphic program from Mike Cowlishaw, IBM UK Laboratories |
FLEETSTREET | FleetStreet v1.03 | Msg Reader & Editor for Squish msg bases |
INT2E | Bill's REXX for DOS | |
ispcir | OS/2 DialogManager, IBM | |
IPSEXEC | Tritus SPF, Tritus Inc. | |
ISREDIT | SPF/2, CTC | |
KEDIT | KEDIT, an XEDIT clone from Mansfield Software | |
ksh | IBM's AIX REXX | The value is independent from the current shell |
MVS | OS/390 v1.2 (PGM=IRXJCL) REXX Interpreter | |
NULL | DrDialog | this is an alternate SubCommand-Handler for DrDialog programs |
PMREXX | PMREXX, OS/2 PMREXX.EXE (see the warning in the section #Using PMREXX) | |
REXXTERM | REXXTERM, Quercus Software | |
RXDLG | Rexx Dialog | |
SAY | DrDialog | this is an alternate SubCommand-Handler for DrDialog programs |
STARTDOS | StartDOS | a program to start DOS VDMs by Monte Copeland |
SYSTEM | Bill's REXX for DOS Mark Hesslings's Regina REXX for Windows NT |
use PARSE SOURCE to distinguish between the interpreter: Bill's REXX returns MSDOS, Mark's REXX returns WIN32 |
TE2 | TE/2, Oberon Software | |
THE | THE Hessling Editor by Mark Hessling | THE is an XEDIT clone for various operating systems |
TSO | OS/390 v1.2 (TSO) REXX Interpreter | |
VISION | ObjectVision, Borland | |
UNIX | uniREXX on Solaris v2.6 | |
ZOC | ZOC 2.x, Markus Schmidt | One of the best OS/2 terminal programs available! |
ANSI ESC Sequences
ANSI ESC Sequences - also called ANSI commands - are useful for doing some display I/O control in REXX.
To use ANSI commands the OS/2 ANSI support must be active. To activate the ANSI support use the OS/2 command ANSI ON and to deactivate the ANSI support use the OS/2 command ANSI OFF. To get the current status of the ANSI support use the OS/2 command ANSI without a parameter. The default for the ANSI support is ON. (see Check if ANSI is active - 1 - or Check if ANSI is active - 2 - for REXX source to detect if ANSI support is active from within a REXX program)
Each ANSI command begins with the sequence ESC[. where ESC represents the ASCII code 1Bh (= 27 decimal). If there is more than one parameter for an ANSI command, use a semicolon (;) to separate the parameter.
To output ANSI commands you can use the functions LINEOUT and CHAROUT or the statement SAY. Example:
say "1B"x || "[30;41m" || "This text is black on red" call lineOut , "1B"x || "[31;40m" || "This text is red on black" call charOut , "1B"x || "[0m" || "This text is in default color"
(see Using ANSI sequences for some sample code using ANSI sequences and RxLBox - menu routine in REXX is a menu program using only ANSI sequences to implement the navigation with cursor keys and function keys)
- Note
- To use the ANSI commands to set or get the cursor position you must use the function CHAROUT! (see SysCls for another minor restriction)
- Further Note
- Almost all ANSI Control Characters are documented in the command reference of WARP version 4.
Command | Function |
---|---|
ESC[colsA | Cursor up # lines |
ESC[colsB | Cursor down # lines |
ESC[rowsC | Cursor right # columns |
ESC[rowsD | Cursor left # columns |
ESC[row;colH | Position the cursor (the upper left corner is 1,1) |
ESC[2J | Clear the whole screen |
ESC[K | Clear the rest of the line |
ESC[6n | Get the current cursor position (see Get the current cursor position) |
ESC[row;colf | Position the cursor (like "H") |
ESC[row;colR | Report current cursor line and column (*) |
ESC[=modeh | Set the display mode (see below) |
ESC[=model | Set the display mode (see below) |
ESC[attr;attr;..m | Set the color attribute (see below) |
ESC[key;"str"p | Redefine the key "key" with the string "str" (see Key redefinitions and Key Codes for key redefinitions) |
ESC[s | Save the current cursor position (nested calls are not allowed) |
ESC[u | Restore the cursor position (nested calls are not allowed) |
Attribute | Description |
---|---|
0 | all attributes off (white on black) |
1 | bold |
2 | normal |
4 | underline (only on b/w displays) |
5 | blink |
7 | reverse video |
8 | invisible |
30-37 | set the foreground color:
|
40-47 | set the background color:
|
Mode | Description |
---|---|
0 | Text 40x25 monochrome |
1 | Text 40x25 color |
2 | Text 80x25 monochrome |
3 | Text 80x25 color |
4 | Graphics 320x200 4 colors |
5 | Graphics 320x200 2 color |
6 | Graphics 640x200 2-color |
7 | cursor wrap off (7l) or on (7h) |
Key Codes for key redefinitions
ASCII Key Codes | Code | SHIFT+Code | CTRL+Code | ALT+Code |
---|---|---|---|---|
F1 | 0;59 | 0;84 | 0;94 | 0;104 |
F2 | 0;60 | 0;85 | 0;95 | 0;105 |
F3 | 0;61 | 0;86 | 0;96 | 0;106 |
F4 | 0;62 | 0;87 | 0;97 | 0;107 |
F5 | 0;63 | 0;88 | 0;98 | 0;108 |
F6 | 0;64 | 0;89 | 0;99 | 0;109 |
F7 | 0;65 | 0;90 | 0;100 | 0;110 |
F8 | 0;66 | 0;91 | 0;101 | 0;111 |
F9 | 0;67 | 0;92 | 0;102 | 0;112 |
F10 | 0;68 | 0;93 | 0;103 | 0;113 |
F11 | 0;133 | 0;135 | 0;137 | 0;139 |
F12 | 0;134 | 0;136 | 0;138 | 0;140 |
Home (numeric key) | 0;71 | 55 | 0;119 | — |
Up Arrow (numeric key) | 0;72 | 56 | (0;141) | — |
Page Up (numeric key) | 0;73 | 57 | 0;132 | — |
Left Arrow (numeric key) | 0;75 | 52 | 0;115 | — |
Right Arrow (numeric key) | 0;77 | 54 | 0;116 | — |
End (numeric key) | 0;79 | 49 | 0;117 | — |
Down Arrow (numeric key) | 0;80 | 50 | (0;145) | — |
Page Down (numeric key) | 0;81 | 51 | 0;118 | — |
Ins (numeric key) | 0;82 | 48 | (0;146) | — |
Del (numeric key) | 0;83 | 46 | (0;147) | — |
Home | (224;71) | (224;71) | (224;119) | (224;151) |
Up Arrow | (224;72) | (224;72) | (224;141) | (224;152) |
Page Up | (224;73) | (224;73) | (224;132) | (224;153) |
Left Arrow | (224;75) | (224;75) | (224;115) | (224;155) |
Right Arrow | (224;77) | (224;77) | (224;116) | (224;157) |
End | (224;79) | (224;79) | (224;117) | (224;159) |
Down Arrow | (224;80) | (224;80) | (224;145) | (224;154) |
Page Down | (224;81) | (224;81) | (224;118) | (224;161) |
Insert | (224;82) | (224;82) | (224;146) | (224;162) |
Delete | (224;83) | (224;83) | (224;147) | (224;163) |
Print Screen | — | — | 0;114 | — |
Pause/Break | — | — | 0;0 | — |
Backspace | 8 | 8 | 127 | (0) |
Enter | 13 | — | 10 | (0,28) |
Tab | 9 | 0;15 | (0;148) | (0;165) |
Null | 0;3 | — | — | — |
ESC | 27 | 27 | 27 | 27 |
Space | 32 | 32 | 32 | 23 |
A | 97 | 65 | 1 | 0;30 |
B | 98 | 66 | 2 | 0;48 |
C | 99 | 67 | 3 | 0;46 |
D | 100 | 68 | 4 | 0;32 |
E | 101 | 69 | 5 | 0;18 |
F | 102 | 70 | 6 | 0;33 |
G | 103 | 71 | 7 | 0;34 |
H | 104 | 72 | 8 | 0;35 |
I | 105 | 73 | 9 | 0;23 |
J | 106 | 74 | 10 | 0;36 |
K | 107 | 75 | 11 | 0;37 |
L | 108 | 76 | 12 | 0;38 |
M | 109 | 77 | 13 | 0;50 |
N | 110 | 78 | 14 | 0;49 |
O | 111 | 79 | 15 | 0;24 |
P | 112 | 80 | 16 | 0;25 |
Q | 113 | 81 | 17 | 0;16 |
R | 114 | 82 | 18 | 0;19 |
S | 115 | 83 | 19 | 0;31 |
T | 116 | 84 | 20 | 0;20 |
U | 117 | 85 | 21 | 0;22 |
V | 118 | 86 | 22 | 0;47 |
W | 119 | 87 | 23 | 0;17 |
X | 120 | 88 | 24 | 0;45 |
Y | 121 | 89 | 25 | 0;21 |
Z | 122 | 90 | 26 | 0;44 |
1 | 49 | (*) | — | 0;120 |
2 | 50 | (*) | — | 0;121 |
3 | 51 | (*) | — | 0;122 |
4 | 52 | (*) | — | 0;123 |
5 | 53 | (*) | — | 0;124 |
6 | 54 | (*) | — | 0;125 |
7 | 55 | (*) | — | 0;126 |
8 | 56 | (*) | — | 0;126 |
9 | 57 | (*) | — | 0;127 |
0 | 48 | (*) | — | 0;129 |
! | 33 | — | — | (*) |
" | 34 | — | — | (*) |
� | 21 | — | — | (*) |
$ | 36 | — | — | (*) |
% | 37 | — | — | (*) |
& | 38 | — | — | (*) |
/ | 47 | — | — | (*) |
( | 40 | — | — | (*) |
) | 41 | — | — | (*) |
= | 61 | — | — | (*) |
? | 63 | — | — | (*) |
` | 96 | — | — | — |
' | 39 | — | — | — |
* | 42 | — | — | — |
+ | 43 | — | — | — |
# | 35 | — | — | — |
, | 44 | — | — | — |
; | 59 | — | — | — |
. | 46 | — | — | — |
: | 58 | — | — | — |
- | 45 | — | — | — |
_ | 95 | — | — | — |
< | 60 | — | — | — |
> | 62 | — | — | — |
^ | 94 | — | — | — |
° | 248 | — | — | — |
\ | 92 | — | — | — |
[ | 91 | — | — | — |
] | 93 | — | — | — |
{ | 123 | — | — | — |
} | 125 | — | — | — |
| | 124 | — | — | — |
~ | 126 | — | — | — |
@ | 64 | — | — | — |
ENTER (keypad) | 13 | — | 10 | (0;166) |
/ (keypad) | 47 | 47 | (0;142) | (0;74) |
* (keypad) | 42 | (0;144) | (0;78) | — |
- (keypad) | 45 | 45 | (0;149) | (0;164) |
+ (keypad) | 43 | 43 | (0;150) | (0;55) |
5 (keypad) | (0;76) | 53 | (0;143) | — |
ä (German umlaut) | 132 | 142 | — | — |
ö (German umlaut) | 148 | 153 | — | — |
ü (German umlaut) | 129 | 154 | — | — |
ß (German special) | 225 | — | — | — |
- Note
- Use the values in parenthesis with care - they may work or may not work.
"Compiling" REXX programs
I don't know of a real REXX compiler for OS/2 REXX. But because the REXX interpreter stores an tokenized copy of each REXX program in the EAs of the program, it is possible to delete the source code from REXX programs (see REXXCC). Another method to "compile" a REXX program is used by the program RxCLS. But this is also no real compiler.
The only method to create a standalone REXX program that runs on any machine with or without REXX installed is to create an EXE containing the REXX program and a static version of a REXX interpreter. This is possible with the package Rexx/Wrapper and the REXX Interpreter Regina from Mark Hessling (see Internet - Web Pages)
To "compile" an Object-Oriented REXX program you can use the program REXXC.EXE which is part of Object-Oriented REXX. REXXC.EXE creates the token image and saves it in a REXX cmd. This method avoids the 64 K limit for the token image. (see also the #Creating "compiled" programs for Classic REXX and Object REXX)
Another method to create a token image of your REXX program is to load the REXX program into the macro space and save the macro space into a file. This will produce a token image of your REXX program that you can reload into the macrospace and execute it from there. This method also avoids the 64 K limit of the EAs. (see REXXCC - a REXX "compiler") In this case you need an additional loader to load the token image into the macro space again before you can execute it.
Or use LoadMac.cmd to create and load the token image:
REM *** Create the token image
LOADMAC CLEAR ADD:myProg.CMD SAVE:myProg.IMG
REM *** Load the image into the REXX macro space
LOADMAC CLEAR LOAD:MyProg.IMG
REM *** Execute the image
REXXTRY call myprog myparms
REM *** Drop the image from the REXX macro space
LOADMAC DROP:MyProg
REM *** or (if the image contains more than one macro)
LOADMAC CLEAR
see also Debugging a "compiled" REXX program, Get the source code of a "compiled" REXX program, and Protect the source code of a REXX program
Creating "compiled" programs for Classic REXX and Object REXX
To use a "compiled" program in Classic REXX and in Object REXX you must create a "compiled" version for Classic REXX (created for example with REXXCC) and a "compiled" version for Object REXX (created with REXXC.EXE from Object REXX). Then, to call your "compiled" REXX program you should use a "wrapper" program written in REXX (Do not "compile" the wrapper program!).
The wrapper program might look as follows:
/* ------------------------------------------------------------------ */
/* sample wrapper to call a "compiled" REXX program depending on the */
/* version of the current REXX interpreter (Classic REXX or */
/* Object REXX) */
/* */
/* Note: */
/* */
/* This program assumes */
/* */
/* - the REXX program "compiled" for Classic REXX is called */
/* <name_of_this_prog>C.CMD */
/* */
/* - the REXX program "compiled" for Object REXX is called */
/* <name_of_this_prog>O.CMD */
/* */
/* - both programs are in the same directory as this program */
/* */
/* init the return code */
rc = 255
/* get the parameter */
parse arg thisParameters
/* get the name of this program */
parse source . . thisFile
progBaseName = substr( thisFile,1 lastPos( ".", thisFile )-1 )
/* check the version of the current REXX */
/* interpreter */
parse upper version thisVersion thisVersionNo
if thisVersion = "OBJREXX" | thisVersionNo > 4.00 then
do
/* current REXX interpreter is Object REXX */
"@cmd /c " progBaseName || "O.CMD" thisParameters
end /* if thisVersion = "OBJREXX" | thisVersionNo > 4.00 then */
else
do
/* current REXX interpreter is Classic REXX */
"@cmd /c " progBaseName || "C.CMD" thisParameters
end /* else */
return rc
Prevent REXX from creating a token image
Set the read-only attribute of REXX cmds for which the REXX interpreter should not create a token image (or copy them to a read-only disk or to a filesystem not supporting Extended Attributes).
Extend the program REXXTRY.CMD
The program REXXTRY.CMD (in the directory \OS2) is really useful to test some REXX statements. But it has one disadvantage: The input routine is very simple.
But, thanks to Albert Crosby, there's a simple way to overcome this disadvantage. Albert Crosby who's that you might ask. Well, Albert Crosby is the author of a REXX routine called CMDLINE1.CMD which is very suitable to extend the input routine from REXXTRY.CMD
To do this do the following:
Create a copy of the file REXXTRY.CMD and name it EREXXTRY.CMD.
Extract the source code of CMDLINE.CMD from this document (see Using the samples)
Load the file EREXXTRY.CMD into a text editor and append the source of CMDLINE1.CMD at the end of EREXXTRY.CMD.
Then insert the following lines in EREXXTRY.CMD before the line parse arg argrx:
/* ------------------------------------------------------------------ */
/* history of changes for RXT&T version: */
/* */
/* RXT&T v1.60 /bs */
/* - changed code to also work if REXXUTIL is not accessible */
/* */
/* RXT&T v1.70 /bs */
/* - corrected an error in the RxFuncAdd calls */
/* - in the previous version, undefined function keys lead to */
/* invalid return codes in cmdline. Corrected. */
/* - added code to save and load the history list to the routine */
/* cmdline */
/* The keys for handling the history file are: */
/* F2 - save the history list (overwrite an existing file) */
/* ALT-F2 - save the history list (append to an existing file) */
/* SHIFT-F2 - load the history list */
/* CTRL-F2 - change the history list file */
/* ALT-F4 - save history list and exit program */
/* - added online help for the edit keys (CTRL-F1) */
/* */
/* RXT&T v2.00 /bs */
/* - added code to handle situations when other programs drop the */
/* REXXUTIL functions */
/* RXT&T v2.30 /bs */
/* - added key definitions for loading and dropping REXXUTIL */
/* functions (F11 and F12) */
/* RXT&T v2.40 /bs */
/* - added code to show the version of the active REXX interpreter */
/* */
/* (c) 1996 Bernd Schemmer, Germany, EMail: Bernd.Schemmer@gmx.de */
/* */
/* */
ReStart: /* v2.00 */
if rxFuncQuery "SysCurPos" = 0 then /* v1.60 */
call rxFuncDrop "SysCurPos" /* v1.60 */
if rxFuncQuery "SysGetKey" = 0 then /* v1.60 */
call rxFuncDrop "SysGetKey" /* v1.60 */
/* load the necessary REXXUTIL v1.60 */
/* functions v1.60 */
call RxFuncAdd "SysCurPos", "RexxUtil", "SysCurPos" /* v1.70 */
call RxFuncAdd "SysGetKey", "RexxUtil", "SysGetKey" /* v1.70 */
!rexxUtilLoaded = 0 /* v1.60 */
/* check if the rxFuncAdd calls were v1.60 */
/* successful v1.60 */
signal ON Syntax Name RexxUtilNotLoaded /* v1.60 */
call SysCurPos /* v1.60 */
/* use the extended input v1.60 */
/* routine only if possible v1.60 */
!rexxUtilLoaded = 1 /* v1.60 */
/* name of the file for the history v1.70 */
/* list v1.70 */
!history.file = "EREXXTRY.HST" /* v1.70 */
/* redefine some keys */
!history.key.61 = "exit" /* F3 */
!history.key.104 = "?" /* ALT-F1 */
/* F11 load REXXUTIL v2.30 */
!history.key.133 = "call rxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs';
call SysLoadFuncs; say 'REXXUTIL loaded.'";
/* F12 drop REXXUTIL v2.30 */
!history.key.134 = "call SysDropFuncs; say 'REXXUTIL functions dropped.'"
/* see Key redefinitions for further key codes */
RexxUtilNotLoaded: /* v1.60 */
/* ------------------------------------------------------------------ */
Now replace the line parse pull inputrx in EREXXTRY.CMD with
/* ------------------------------------------------------------------ */
parse version tVersion /* v2.40 */
say " --- Current REXX interpreter is: "tversion /* v2.40 */
if !rexxUtilLoaded <> 1 then /* v1.60 */
do /* v2.00 */
say " --- no extended keys available --- " /* v2.00 */
say " --- use ""signal restart"" to try to load" , /* v2.30 */
"the extended key support again --- " /* v2.30 */
inputrx = lineIN() /* v1.60 */
end /* v2.00 */
else /* v1.60 */
do /* v1.70 */
say " --- extended keys are active," || , /* v1.70 */
" CTRL-F1 = online help ---" /* v1.70 */
inputrx = cmdLine() /* v1.60 */
end /* v1.70 */
/* ------------------------------------------------------------------ */
Save the file EREXXTRY.CMD.
That's all! You've just created EREXXTRY.CMD - a clone of REXXTRY.CMD with a much more comfortable input routine.
See also: CMDLINE
"Undocumented" REXX functions
The following REXX functions to work with DBCS mixed Strings are only documented in the IBM: OS/2 2.0 Procedures Language/2 Reference Manual and in the Object-Oriented REXX online documentation:
- DBADJUST
- DBBRACKET
- DBCENTER
- DBLEFT
- DBRIGHT
- DBRLEFT
- DBRRIGHT
- DBTODBCS
- DBTOSBCS
- DBUNBRACKET
- DBVALIDATE
- DBWIDTH
Well, for the "normal" REXX programmer only two of these functions are interesting (The functions also work with SBCS strings):
Name DBRLEFT( string, n {,option} ) Function Delete n chars beginning with the first char Example DBRLEFT( "ABCDEFG", 2 ) gives "CDEFG" Note The parameter option is only needed for DBCS strings) For SBCS strings you should not use this parameter.
Name DBRRIGHT( string, n {,option} ) Function Delete n chars beginning with the last char Example DBRRIGHT( "ABCDEFG", 3 ) gives "ABCD" Note The parameter option is only needed for DBCS strings) For SBCS strings you should not use this parameter.
REXX ANSI Standard
There's now an ANSI standard for REXX. The REXX Standard number is X3.274. You can get a copy of the Standard from the ANSI at:
- American National Standards Institute
Attn: Customer Service
11 West 42nd Street
New York, NY 10036
Phone: +1 212 642 4900
Fax: +1 212 302 1286
(see Internet - Web Pages)
The document costs $125 (+S&H). A cheaper way for retrieving a copy of the standard is:
Download the pre-publication PostScript draft version of the standard from Mike Cowlishaw's REXX home page (see Internet - Web Pages). This version is functional identical to the ANSI version.
- History
"Since 1991, a technical committee has been preparing a document for a proposed American National Standard (ANSI Standard) for REXX. Here is the committee's charter:
The project is for development of an American National Standard. The scope of this standard will be 'The REXX Language' described by Michael F. Cowlishaw in his book, altered as necessary to promote portability, reliability, maintainability and efficient execution of REXX programs on a variety of computing systems."
The X3J18 committee has been operationg under the procedures of the American National Standards Institute (ANSI); the addresses of the Chairman, Vice-Chairman, and Secretary are as follows:
- Chairman
- B L Marks
IBM UK Laboratories
Hursley Park
Winchester, England SO21 2JN - Vice-chairman
- N F N Milsted
IX Corporation
575 W. Madison, Suite 3610
Chicago, IL 60661 - Secretary
- E Spire
The Workstation Group
6300 River Road
Rosemont, IL 60018