REXX Tips & Tricks:REXXUTIL functions

This section contains hints about the functions from the DLL REXXUTIL.

Using REXXUTIL
If you're using REXXUTIL very often and your PC has enough memory (8 MB or more), you should load REXXUTIL in the STARTUP.CMD.

Example for STARTUP.CMD: /* Important: STARTUP.CMD must be a REXX program to load REXXUTIL! */ call RxFuncAdd "SysLoadFuncs", "REXXUTIL", "SysLoadFuncs" call SysLoadFuncs exit 0

Using REXXUTIL if booted from diskette
If you've booted OS/2 from diskette, you can use REXXUTIL in the following circumstances:
 * The stub program to load the REXX support is BOS2REXX.EXE
 * The OS/2 DLLs normally in the directory \OS2\DLL are accessible through the LIBPATH. Of course, these DLLs won't fit on a diskette. But they may be on a hard disk or a codeserver.
 * And last you must load each function from REXXUTIL by hand with RxFuncAdd. You can't use SysLoadFuncs if booted from diskette!

You can't use the WPS related functions from REXXUTIL if booted from diskette, but mostly all other functions work fine. For example I've tested the following functions:
 * SysCls
 * SysCurPos
 * SysCurState
 * SysDriveInfo
 * SysDriveMap
 * SysGetKey
 * SysMkDir
 * SysOS2Ver
 * SysRmDir
 * SysTempFileName
 * SysTextScreenSize
 * Note:See also the DLL CLTRUTIL included in the OS/2 WARP Server/OS/2 WARP Connect.
 * See also New REXXUTIL functions in Object REXX.

The functions to work on the macro space
The new REXXUTIL DLL provided with Object-Oriented REXX contains some functions to work with the macro space (see New REXXUTIL functions in Object REXX). These functions return the following error codes:
 * okay, no error
 * Not enough memory
 * Macro not found
 * Extension required
 * Macro already exist
 * File error
 * Signature error
 * Sourcefile not found
 * Invalid position

Some further hints for these functions:

SysAddRexxMacro can only load one macro from a REXX cmd file at a time. You can't load a tokenized REXX program into the macro space using this function. SysAddRexxMacro overwrites an existing macro. The file with the REXX macro must have an extension - SysAddRexxMacro doesn't find files without an extension.

SysLoadRexxMacroSpace can only load an image that was previously saved with SysSaveRexxMacroSpace. SysLoadRexxMacroSpace works only if the macro space is empty (thus you can't concenate two or more images in the macro space but AFAIK the number of macros in the image is not limited).

There's no function to get a list of all existing macros in the macrospace.

(see also LoadMac.cmd)

The function SysCLS
The function SysCLS clears the screen using the default colors. To clear the screen with non-default colors (set with ANSI ESC sequences) you must use the OS/2 command CLS.

Source: John Seitz

The function SysCopyObject
In theory you can use the function SysCopyObject to copy a file with a long name from an HPFS formatted drive to a FAT formatted drive. In real life it works sometimes and sometimes not. This seems to be a bug.

SysCopyObject does not overwrite an existing file.

(see also Copy a file from HPFS to FAT and vice versa for a workaround)

The function SysCreateObject
SysCreateObject does not support the object settings database DATABASE.DAT in the directory \OS2\INSTALL.

You cannot use the SysCreateObject parameter title to change the title of an existing object. You must use the setup string keyword TITLE to do this.

SysCreateObject does not replace an existing object when a caret is used in the object title to represent a new line character. Example.: /* Create an object and update it                                    */ call RxFuncAdd "SysLoadFuncs", "REXXUTIL", "SysLoadFuncs" call SysLoadFuncs do 2 call SysCreateObject "WPProgram" ,, "Title^with Caret" ,, "" ,, "EXENAME=C:\OS2\CMD.EXE;PROGTYPE=WINDOWABLEVIO;" ,, "U" end /* do 2 */

This code should create an object on the desktop in the first round and update that object (with the same settings) in the second round. But instead of that, it creates two objects on the desktop. To avoid this, either don't use a caret in the title of an object or. better yet, always create objects with an object ID.

(Source: APAR PJ17176)

Be aware that using the function SysCreateObject with the last parameter set to Replace will destroy the object and all shadows of the object before recreating it (without recreating the shadows)!

The function SysDestroyObject
Use the REXXUTIL function SysDestroyObject to delete a complete directory tree including the sub directories (Source: Michael Platschek).

Please note that this is not possible if there are read-only files in one of the directories. To get around this limitation you can use the function SysFileTree (see also Delete a directory(-tree)): /* sample code to delete a directory tree                            */ /* dirToDelete contains the name of the directory */ /* to delete                                     */ dirToDelete = 'D:\TEST' /* load the functions from the DLL REXXUTIL      */ call rxFuncAdd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs' call SysLoadFuncs /* clear the read-only, the hidden and the system */ /* flag from all files                           */ call SysFileTree dirToDelete || '\*.*', dummyStem, 'BS', '*****', '-*---' /* delete the directory tree                     */ call SysDestroyObject dirToDelete

The function SysFileSearch
"When SysFileSearch is called with a file that has lines greater than 255 characters the strings returned contain the line truncated to 255 characters." (Source: APAR PJ19726 fixed in WARP 3 Fixpack #15)

The function SysFileTree
The date returned by the functions SysFileTree and STREAM is always the date the file was last modified.

See REXX and Y2K for information about SysFileTree and Y2K.

The function SysIni
Using the function SysIni to write data to a non-existing ini file creates a file with that name.

The function SYSINI returns ERROR: if called about 12900 (+/- 100) times in a loop to retrieve/set a value from/in one or more INI files. After the error occurs, you can't use the function SYSINI in that session anymore. To get around this, you have to close the session and open another.

(see also RxIni)

The function SysOS2Ver
The result of the REXXUTIL function SysOS2Ver under OS/2 Version 3 WARP is 2.30.

The result of the REXXUTIL function SysOS2Ver under OS/2 WARP 4 is 2.40.

The function SysPutEA
Use an empty string as the third parameter of SysPutEA to delete an Extended Attribute.

Use the OS/2 program EAUTIL to delete all Extended attributes of a file or directory.

The function SysQueryEAList
Ordinarily, it is not possible to get a list of all existing Extended Attributes in Classic REXX. But there is a function called SysQueryEAList in the REXXUTIL.DLL from Object-Oriented REXX that will list all EAs attached to a specified file or directory. This DLL can also be used in Classic REXX (see ).

The function SysQueryClassList
The function SysQueryClassList does not work after resetting the WPS (with RESETWPS.EXE from WPTOOLS, for example).

A possible workaround for this problem is to open a new OS/2 session and issue the SysQueryClassList from within this session. This workaround may not be effective in every situation.

This bug seems to be fixed in WARP 4.

Source: Christian Langanke

The function SysSearchPath
If a filename is passed to the function SysSearchPath without an extension, but WITH a trailing dot, the function will return the filename WITHOUT the trailing dot (provided, of course, that the file exists); e.g.: newName = SysSearchpath( 'PATH', 'test.' ) returns 'C:\test' if that file exists (and C:\ is in the PATH variable).

The function SysSleep
Note that there is no guarantee that the function SysSleep sleeps exactly the time given to it as parameter. The real sleep time depends on the system load of the running OS/2 system. Therefore you should use a routine like for example Wait until a specific time if you're using SysSleep to wait for a specific time.

New REXXUTIL functions in WARP
There are 5 new functions in OS/2 WARP Version 3 to work on WPS objects: All functions are mentioned in the documentation. But because the documentation for these functions is really a pit, I include the documentation from the REXX Reference Summary Handbook by Dick Goran (captured from a message in a public CompuServe Forum):
 * SysMoveObject
 * SysCopyObject
 * SysSaveObject
 * SysOpenObject
 * SysCreateShadow

The following new functions have been added to REXXUTIL in WARP Version 3.0:
 * SysCopyObject( object_name, object_destination )
 * Returns 1 if object_name was successfully copied to object_destination; otherwise, returns 0. If the object already exists in the destination location, it is not copied and a 0 is returned.
 * Both object_name and object_destination can be a WPS object ID (the unique string preceded with a '<' and terminated with a '>') assigned to the object when it was created (e.g. ) or a fully qualified file name. The predefined object IDs are shown in Section 4.1 beginning on page 89.
 * Note 01: The copied object will not have an OBJECTID whether the original object had one assigned or not.
 * Note 02: Some of the object's other properties are not copied along with the object. Specifically, ASSOCTYPE= belonging to the original object does not appear on the copy. This is consistent with what occurs when using drag & drop to copy


 * SysCreateShadow( object_name, object_destination )
 * Returns 1 if a shadow of object_name was successfully created at the specified location, object_destination; otherwise, returns 0.
 * Both object_name and object_destination can be a WPS object ID (the unique string preceded with a '<' and terminated with a '>') assigned to the object when it was created (e.g. ) or a fully qualified file name. The predefined object IDs are shown in Section 4.1 beginning on page 89.


 * SysMoveObject( object_name, object_destination )
 * Returns 1 if object_name was successfully moved to object_destination; otherwise, returns 0. If the object already exists in the destination location, it is not moved and a 0 is returned.
 * Both object_name and object_destination can be a WPS object ID (the unique string preceded with a '<' and terminated with a '>') assigned to the object when it was created (e.g. ) or a fully qualified file name. The predefined object IDs are shown in Section 4.1 beginning on page 89.


 * SysOpenObject( object_name, view, flag )
 * Returns 1 if the WPS object object_name was successfully opened on the Desktop; otherwise, returns 0.
 * Object_name can be a WPS object ID (the unique string preceded with a '<' and terminated with a '>') assigned to the object when it was created (e.g. ) or a fully qualified file name. The predefined object IDs are shown in Section 4.1 beginning on page 89.
 * View specifies the view to be opened and can contain either a numeric value or the equivalent string. The function will pass all numeric values to the underlying wpOpen or wpViewObject function without testing the value for validity.
 * 0 - DEFAULT
 * 1 - ICON
 * 2 - SETTINGS
 * 3 - HELP
 * 4 - RUNNING
 * 5 - PROMPTDLG
 * 101 - Tree view       (added RXT&T v2.00 /bs)
 * 102 - details view    (added RXT&T v2.00 /bs)
 * 121 - PALETTE
 * Flag can contain a 1 indicating that an existing view of an object can be opened on top of the Desktop (resurfaced) by calling the wpViewObject method or a 0 indicating that the view specified in view is to be opened using the wpOpen method. The following comment originated in the description of the wpOpen method:
 * "In general, wpViewObject should be used instead of the wpOpen method. This is because wpViewObject takes into consideration the setting in the Object Open Behavior field on the Window page of the Settings notebook for the object. If a view of the object is already open, wpViewObject will depending on the setting of the Object Open Behavior field, either display the existing window for the object or create a new object."
 * "In contrast, wpOpen always opens a new view of the object. Under certain circumstances this might be called for, but, under most circumstances, wpViewObject should be called instead."


 * SysSaveObject( object_name, timing_flag )
 * Returns 1 if the WPS object object_name was successfully saved; otherwise, returns 0.
 * File system objects (WPFileSystem) are saved in the file system's extended attributes and abstract objects are saved in the OS2.INI (user) file. Transient objects (WPTransient) cannot be saved.
 * Object_name can be a WPS object ID (the unique string preceded with a '<' and terminated with a '>') assigned to the object when it was created (e.g. ) or a fully qualified file name. The predefined object IDs are shown in Section 4.1.
 * Timing_flag can be 0 (Boolean false - object is to be saved synchronously) or 1 (Boolean true - object is to saved asynchronously).


 * Note: No, you can't use the new REXXUTIL.DLL in OS/2 version prior to WARP.

New REXXUTIL functions in Object REXX
The new Object-Oriented REXX contains an enhanced REXXUTIL DLL. This DLL exports a lot of new functions in addition to the normal REXXUTIL DLL (see below).

You don't need to install Object-Oriented REXX to use its enhanced REXXUTIL DLL. The DLL also runs under Classic REXX in OS/2 WARP 3 and OS/2 WARP Version 4. (Note that the default REXX interpreter in OS/2 WARP 4 is still Classic REXX!)

Use one of the following methods to use the new REXXUTIL.DLL in Classic REXX when Classic REXX is your default (i.e., currently installed) REXX.

Using the new REXXUTIL.DLL as default REXXUTIL.DLL

To use the new REXXUTIL.DLL as the default REXXUTIL.DLL with Classic REXX, rename the original REXXUTIL.DLL to something like REXXUTIL.BAK. Then copy the file REXXUTIL.DLL (and REXXCRT.DLL in OS/2 WARP 3) from Object-Oriented REXX to the OS/2 DLL directory \OS2\DLL and reboot. Note that in OS/2 WARP Version 4 the new REXXUTIL.DLL is named OREXUTIL.DLL when Classic REXX is the default REXX interpreter. (When Object-Oriented REXX is installed as the default REXX, OREXUTIL.DLL is automatically renamed to REXXUTIL.DLL and the corresponding DLL for Classic REXX becomes CREXUTIL.DLL)

That's it.

Using only the new functions from the new REXXUTIL.DLL

To use only the new functions from the new REXXUTIL DLL, copy the REXXUTIL.DLL from Object-Oriented REXX into a new directory, for example C:\OREXX.

In OS/2 WARP 3 you must also copy the DLL REXXCRT.DLL from Object-Oriented REXX into the OS/2 DLL directory; in OS/2 WARP Version 4 this DLL already exists in the OS/2 DLL directory.

To use a function from the new REXXUTIL DLL, simply load it using RxFuncAdd. You must use the RxFuncAdd statement for every function from the new REXXUTIL.DLL you need - you cannot use SysLoadFuncs! It's also important in this case that you use the fully qualified name for the DLL in the RxFuncAdd statement!

Example:  /* To show how we can have the REXXUTIL DLL for Classic REXX loaded  */ /* as the default and -- at the same time -- use the new functions of */ /* the Object REXX DLL, in this example we'll first load REXXUTIL    */ /* from Classic REXX. (This first step is not required every time you */ /* call a function from Object REXX's REXXUTIL.)                     */

/* load the REXXUTIL DLL from Classic REXX                           */ call RxFuncAdd "SysLoadFuncs", "REXXUTIL", "SysLoadFuncs" call SysLoadFunc

/* load the functions SysBootDrive and SysProcessType from the new   */ /* REXXUTIL DLL                                                      */ /* (assuming the new REXXUTIL.DLL is in the directory C:\OREXX)      */

call RxFuncAdd "SysBootDrive",  "c:\orexx\rexxutil", "SysBootDrive" call RxFuncAdd "SysProcessType", "c:\orexx\rexxutil", "SysProcessType"  Following is a list of the new functions in the REXXUTIL.DLL from Object-Oriented REXX (Please note that the following links will only work if Object REXX is the default REXX interpreter on your system!):
 * SysAddRexxMacro:add a routine to the REXX macro space
 * SysClearMacroSpace:clear the REXX macro space
 * SysDropRexxMacro:remove a routine from the REXX macro space
 * SysLoadRexxMacroSpace:load a function into the REXX macro space
 * SysQueryRexxMacro:query the existence of a macro space function
 * SysReorderRexxMacro:change the order in the REXX macro space
 * SysSaveRexxMacroSpace:save the REXX macro space
 * SysCreateEventSem:create or open an OS/2 event semaphore
 * SysOpenEventSem:open an OS/2 event semaphore
 * SysPostEventSem:post an OS/2 event semaphore
 * SysResetEventSem:reset an OS/2 event semaphore
 * SysWaitEventSem:wait on an OS/2 event semaphore
 * SysCloseEventSem:close an OS/2 event semaphore
 * SysBootDrive:get the OS/2 boot drive
 * SysFileSystemType:get the name of the file system for a drive
 * SysQueryEAList:retrieve a complete list of EA names
 * SysElapsedTime:use the OS/2 high-frequency timer service
 * SysCreateMutexSem:create or open an OS/2 mutex semaphore
 * SysOpenMutexSem:open an OS/2 mutex semaphore
 * SysCloseMutexSem:close an OS/2 mutex semaphore
 * SysReleaseMutexSem:release an OS/2 mutex semaphore
 * SysRequestMutexSem:request an OS/2 mutex semaphore
 * SysGetCollate:get the country-specific collating table
 * SysMapCase:perform national language uppercase mapping of a string
 * SysNationalLanguageCompare:compare two strings using a country-specific collating table
 * SysProcessType:get the type of the process in which the REXX program is running
 * SysSetPriority:change the priority of the current process
 * SysQueryProcessCodePage:query the current code page for the process
 * SysAddFileHandle:get and set the number of file handles
 * SysSetFileHandle:set the number of file handles available to the current process
 * SysSetProcessCodePage:change the current code page for the process
 * SysShutdownSystem:shut down the OS/2 system
 * SysWildCard:produce an OS/2 edited file name using a source name and a wild card pattern

The updated version of Object REXX from 11 Nov 1997 (see Object REXX for OS/2) contains some additional new REXXUTIL functions. (Please note that the following links will only work if the Object REXX from 11 Nov 1997 is the default REXX interpreter on your system!) These additional functions are: Also new in this version of REXXUTIL is the ability to use the Sysini function in non-PM environments. To do this, the new DLL SHPIINST.DLL must be in the LIBPATH.
 * SysQueryExtLibPath:query the value of BEGINLIBPATH/ENDLIBPATH
 * SysSetExtLibPath:set the value of BEGINLIBPATH/ENDLIBPATH
 * SysQuerySwitchList:query the task list
 * SysSwitchSession:switch to a specific session

The updated version of Object REXX from 18 May 1999 (see Object REXX for OS/2) contains some additional new REXXUTIL functions. (Please note that the following links will not work even if the Object REXX from 18 May 1999 is the default REXX interpreter on your system because the functions are not documented in the INF file! see Documentation for the new REXXUTIL functions) These additional functions are:
 * SysDumpVariables:Dump the contents of all variables
 * SysGetFileDateTime:Get the date of a file or directory
 * SysSetFileDateTime:Set the date of a file or directory
 * SysStemCopy:Copy a stem
 * SysStemDelete:Delete one or more entries in a stem with numbered index
 * SysStemInsert:Insert an entry in a stem with numbered index
 * SysStemSort:Sort a stem
 * SysUtilVersion:Retrieve the REXXUTIL version
 * SysVersion:Retrieve the OS version in string format


 * Warning: According to some messages on CompuServe the REXXUTIL DLL from the beta versions of Object-Oriented REXX are not fully compatible with the normal REXXUTIL DLL!
 * But now that the Special Edition of Object-Oriented REXX is available at the Net for free you shouldn't use the Beta anyway.

Documentation for the new REXXUTIL functions
This section contains the documentation for the new functions in the REXXUTIL.DLL from Object-Oriented REXX from 18 May 1999 (The documentation is missing in the file REXX.INF).

SysDumpVariables
result = SysDumpVariables([filename])
 * Syntax:


 * Params:filename - name of the file where variables are appended to (dump is written to STDOUT if omitted)

Name=MYVAR, Value="This is the content of MYVAR"
 * Function:This function dumps all variables in the current scope either to the specified file (new data will be appended) or to STDOUT if the filename parameter is omitted. The format of the data is (one variable per line):

Call SysDumpVariables "MyVars.Lst" /* append vars to file */ Call SysDumpVariables             /* list vars on STDOUT */
 * Examples:

0 - dump completed OK -1 - failure during dump
 * Return:

SysSetFileDateTime
result = SysSetFileDateTime(filename [,newdate] [,newtime])
 * Syntax:

filename - name of the file to update newdate - new date to set in format YYYY-MM-DD OS/2: (YYYY > 1980) Win: (YYYY > 1800) AIX/Linux: (YYYY > 1900) newtime - new time to set in format HH:MM:SS (24 hr format)
 * Params:


 * Function:This function can be used to modify the "Last Modified" Date of the specified file. If no new date or new time is specified then the file date and time will be set to the current time (TOUCH). If only one of date or time is omitted then this parameter will be left unchanged.

For OS/2 and Windows NT the filename may also specify a directory name. This does not work with Windows 95/98 or AIX/Linux however.

The file you want to change must not be opened by another process or at least it must allow shared writes in order to update the timestamp.

Call SysSetFileDateTime "MyFile.Log" /* touch file */ Call SysSetFileDateTime "MyFile.Log", "1998-12-17" Call SysSetFileDateTime "MyFile.Log",, "16:37:21" Call SysSetFileDateTime "MyFile.Log", "1998-12-17", "16:37:21" Call SysSetFileDateTime "C:\MyDir"   /* touch dir on OS/2, NT */
 * Examples:

0 - file date/time was updated correctly -1 - failure attribute update
 * Return:

SysGetFileDateTime
result = SysGetFileDateTime(filename [,timesel])
 * Syntax:

filename - name of the file to query timesel - What filetime to query: CREATE/ACCESS/WRITE
 * Params:


 * Function:The function call returns the selected file date time attribute of the specified file if this is supported by the operating and file system (e.g. FAT does not provide Create/Access). The selector for the time to be returned can be abbreviated with its first character.

For OS/2 and Windows NT the filename may also specify a directory name. This does not work with Windows 95/98 or AIX/Linux however.

The file you want to query must not be opened by another process or at least it must allow shared reads in order to query the timestamp.

Say "File creation time:" SysGetFileDateTime("MyFile.Log", "C") Say "File last access time:" SysGetFileDateTime("MyFile.Log", "A") Say "File last update time:" SysGetFileDateTime("MyFile.Log", "W") Say "Directory creation time:" SysGetFileDateTime("C:\MyDir", "C")
 * Examples:

-1 - file date/time query failed other - date and time as YYYY-MM-DD HH:MM:SS
 * Return:

SysStemCopy
result = SysStemCopy(fromstem, tostem, [from], [to], [count] [,insert])
 * Syntax:

fromstem - name of source stem tostem - - name of target stem from - first index in source stem to copy to - position where items are copied/inserted in target stem count - number of items to copy/insert insert - 'I' to indicate insert instead of 'O' overwrite
 * Params:


 * Function:Copy elements from the source stem to the target stem. Elements in the source stem are copied starting at the from index (default 1) into the target stem beginning at the to index (default 1). The number of items to copy to the target stem can be specified with count (default is to copy all items in the source stem). You can optionally specify that the items should be inserted into the target stem at the position and the existing items will be shifted to the back accordingly.

This function operates only on stem arrays that specify the number of elements in stem.0 and all elements must be numbered from 1 to n with no omitted index.

Source.0 = 3 Source.1 = "Hello" Source.2 = "from" Source.3 = "REXX" Call SysStemCopy "Source.", "Target." Call SysStemCopy "Source.", "Target.", 1, 5, 2, "I"
 * Examples:

0 - stem copy was successful -1 - stem copy failed
 * Return:

SysStemDelete
result = SysStemDelete(stem, startitem [,itemcount])
 * Syntax:

stem - name of stem where item will be deleted startitem - index of item to delete itemcount - number of items to delete if more than 1
 * Params:


 * Function:Deletes the specified item at index startitem in the stem. If more than one item is to be deleted then the count of items can be specified as the third parameter. After deleting the requested items the stem will be compacted, that means items following the deleted items will be shifted up into the vacant positions.

This function operates only on stem arrays that specify the number of elements in stem.0 and all elements must be numbered from 1 to n with no omitted index.

Call SysStemDelete "MyStem.", 5 Call SysStemDelete "MyStem.", 5, 4
 * Examples:

0 - delete was successful -1 - delete failed
 * Return:

SysStemInsert
result = SysStemInsert(stem, position, value)
 * Syntax:

stem - name of stem where item will be inserted position - index where new item will be inserted value - new item value
 * Params:


 * Function:A new item will be inserted at the specified position in the stem. All existing items in the stem from the specified position will be shifted up by one to make room for the new item.

This function operates only on stem arrays that specify the number of elements in stem.0 and all elements must be numbered from 1 to n with no omitted index.

Call SysStemInsert "MyStem.", 5, "New value for item 5"
 * Example:

0 - insert was successful -1 - insert failed
 * Return:

SysStemSort
result = SysStemSort(stem, order, type, start, end, firstcol, lastcol)
 * Syntax:


 * Params:stem - name of stem to sort
 * order - 'A' or 'D' for sort order (default: ascending)
 * type - 'C', 'I' for comparision type (case/ignore, default: case)
 * start - first index to sort (default: 1)
 * end - last index to sort (default: last item)
 * firstcol - first column to use as sort key (default: 1)
 * lastcol - last column to use as sort key (default: last column)


 * Function:This call sorts all or the specified items in the stem. Sort order can be specified as ascending or descending, comparison type can respect or ignore the case of the strings being compared.
 * The sorting can further be narrowed by specifying the first and last item to be sorted or by specifying the columns used as the sorting key. The sort uses a quicksort algorithm, so the order of equal elements according to the sort key is undetermined.
 * This function operates only on stem arrays that specify the number of elements in stem.0 and all elements must be numbered from 1 to n with no omitted index.

/* sort all elements descending, use cols 5 to 10 as key */ Call SysStemSort "MyStem.", "D",,,,5, 10 /* sort all elements ascending, ignore the case */ Call SysStemSort "MyStem.", "A", "I"
 * Examples:

/* sort elements 10 to 20 ascending, use cols 1 to 10 as key */ Call SysStemSort "MyStem.",,,10, 20, 1, 10

0 - sort was successful -1 - sort failed
 * Return:

SysVersion
result = SysVersion Say SysVersion      /* show OS and version */
 * Syntax:
 * Params:None
 * Function:This function returns a string to identify the operating system and its version. The returned string contains an identifier for the operating system as the first word and then the version in the second word.
 * Examples:
 * Return:Operating system and version
 * Possible output for operating systems supported by Object REXX:

Say SysVersion  ->  "WindowsNT 4.00" Say SysVersion  ->  "OS/2 2.40" Say SysVersion  ->  "AIX 4.2" Say SysVersion  ->  "Linux 2.0.34"
 * Note:This function can be used to replace the operating system specific functions SysOS2Ver, SysWinVer, and SysLinVer.

SysUtilVersion
result = SysUtilVersion
 * Syntax:
 * Params:None
 * Function:This function returns a version number that identifies the current level of the REXX Utilities package. This can be used to verify that certain functions are available.

If RxFuncQuery("SysUtilVersion") = 1 |, SysUtilVersion < "2.00" Then Say "Your REXXUTIL.DLL is not at the current level" If a specific function should be used that was added at a later REXXUTIL level a similar check can be performed by querying that function: If RxFuncQuery("SysSetFileDateTime") = 1 Then Say "Your REXXUTIL.DLL is not at the current level"
 * Examples:Since this function was not part of the original packaging a sample logic to check for a certain level of REXXUTIL could look like this:


 * Return:REXXUTIL version number in the format (n.mm)