For a general discussion of stream reading/writing/creating, see the Files (and Streams) section.
The following functions operate upon streams:
CHARIN | Reads in one or more characters. |
CHAROUT | Writes out one or more characters. |
CHARS | Counts the number of characters waiting to be read. |
CHDIR | Change the current directory. |
COPYFILE | Copies (duplicates) one or more files. |
DELETEFILE | Deletes one or more files. |
DIR | Create or delete a directory. |
DIRECTORY | Query the current directory, and/or change the directory. |
DRIVEINFO | Queries information about a drive such as its free space. |
DRIVEMAP | Queries the drives by type, such as listing all CDROM drives. |
EDITNAME | Transforms a filename based upon a template containing wildcards. |
FILESPEC | Extracts part of a pathname. |
LINEIN | Reads in a line. |
LINEOUT | Writes out a line. |
LINES | Counts the number of lines waiting to be read. |
LOADTEXT | Reads all of the lines of a text file into a stem variable. Also can save a stem variable to a text file. |
MATCHNAME | Tests for the existence of a certain file or directory, perhaps with certain attributes. Alternately, enumerate all of the files in a given directory, perhaps filtering only those that match a certain template containing wildcards, or which have certain attributes. |
MOVEFILE | Moves one or more files from one location to another. When the file remains on the same drive, this essentially renames a file. |
PATH | Gets a full pathname from a filename, queries the current directory, sets the current directory, and/or splits a pathname into separate elements. |
QUALIFY | Gets a full pathname from a filename. |
SEARCHPATH | Locates a file, or queries path environment variables, or returns the path to special directories such as Windows. |
STATE | Tests if a file/stream actually exists. |
STREAM | Opens/closes/seeks streams, and reports stream diagnostics/information. |
VALUEIN | Reads in a numeric value from a binary (ie, non-text) file. |
VALUEOUT | Write out numeric values to a binary (ie, non-text) file (ie, in non-text format). |
Reads in one or more characters.
Synopsis
chars = CHARIN(stream, position, length)
Args
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names). If omitted, the default is to read from STDIN (typically, get one or more characters from the user via a prompt in the console window).
position specifies at what character position (within the stream) to start reading from, where 1 means to start reading at the very first character in the stream. If omitted, the default is to resume reading at where a previous call to CHARIN(), LINEIN(), or VALUEIN() left off (or where the current read character position is).
length indicates the requested number of characters to read in. If 0, then CHARIN() merely sets the "read character position" to position without reading any characters and returns an empty string. (ie, Similiar to using STREAM's SEEK). If length is omitted, CHARIN() defaults to reading only 1 character.
Returns
A string containing the characters. This may be less than the number of characters requested if there are not enough remaining characters in the stream, including even an empty string if there are no more characters remaining at all, or there was an error. See Reading a file.
Notes
You may use the CHARS function to determine how many remaining characters are available to be read, before calling CHARIN().
If the operating system has a problem reading from the stream, then this raises a NOTREADY condition, and CHARIN() may return less characters than requested (or even none).
After a call to CHARIN(), you can use STREAM's 'D' option to return an informative error message as to the nature of any error that may have occurred. This will return an empty string if there was no error. Otherwise, unless you SIGNAL (or CALL) ON NOTREADY, it may be difficult to distinguish between an error occuring, or reaching the end of a persistent stream.
If a NOTREADY condition is raised, your NOTREADY handler can use CONDITION('D') to return the name of the stream in error (and then use STREAM's 'D' option to fetch an informative error message).
For a transient stream (such as STDIN):
You can't specify a position, or this raises a SYNTAX condition with an error number of 40.42.
If there are not as many characters available as how many you have requested, then program execution may stop until the requested number of characters are available. Execution will resume when the requested characters are finally made available (or the user manually aborts which will raise a HALT condition).
For a persistent stream:
If position is beyond the last character in the stream, then this raises a NOTREADY condition, and CHARIN() will return an empty string.
If there are not as many characters available as the number requested, then the remaining characters (and only those characters) are returned immediately. A NOTREADY condition is not raised. A subsequent call to CHARIN() (without specifying a new position), after you have already read all characters from the stream, will then raise a NOTREADY condition, and CHARIN() will return an empty string.
Examples
Example use | Return value |
CHARIN(, , 1) |
/* Gets the next keypress from the user */ |
CHARIN('myfile', , 10) |
/* Reads the next 10 bytes from 'myfile' */ |
CHARIN('myfile', 1) |
/* Resets the read character pointer to the start of 'myfile' */ |
See also
Writes out one or more characters.
Synopsis
result = CHAROUT(stream, string, position)
Args
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names). If omitted, the default is to write to STDOUT (typically, display the data in the console window).
position specifies at what character position (within the stream) to start writing the data, where 1 means to start writing at the very first character in the stream. If omitted, the default is to resume writing at where a previous call to CHAROUT() or VALUEOUT() left off (ie, where the current write character position is).
string are the characters (ie, data) to write out. If omitted or an empty string, then CHAROUT() merely sets the "write character position" to position without writing any characters. (ie, Similiar to using STREAM's SEEK).
If both position and string are omitted, the stream will be closed. (ie, Similiar to using STREAM's CLOSE).
Returns
0 if the string was written out successfully. If an error, CHAROUT() returns a count of how many characters remain unwritten.
Notes
See Saving a file.
If the operating system has a problem writing to the stream, then this raises a NOTREADY condition, and CHAROUT() may return non-zero.
After a call to CHAROUT(), you can use STREAM's 'D' option to return an informative error message as to the nature of any error that may have occurred. This will return an empty string if there was no error.
Program execution will stop until all requested data has been written to the stream (or the user manually aborts which will raise a HALT condition).
If a NOTREADY condition is raised, your NOTREADY handler can use CONDITION('D') to return the name of the stream in error (and then use STREAM's 'D' option to fetch an informative error message).
For a transient stream (such as STDIN):
You can't specify a position, or this raises a SYNTAX condition with an error number of 40.42.
For a persistent stream:
If position is beyond the immediate end of the stream (ie, more than one character beyond the last character already in the stream), then this raises a NOTREADY condition and CHAROUT() returns non-zero.
Examples
Example use | Return value |
CHAROUT(, 'Hi') |
/* Prints "Hi" to the console */ |
CHAROUT('myfile', 'Hi') |
/* Writes 2 chars of "Hi" to 'myfile' */ |
CHAROUT('myfile') |
/* Closes 'myfile' */ |
See also
Counts the number of characters waiting to be read from a particular stream (via CHARIN(), or perhaps LINEIN()).
Synopsis
howmany = CHARS(stream)
Args
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names). If omitted, the default is to count how many characters are available from STDIN (typically, check if the user has already typed one or more characters via a prompt in the console window).
Returns
A count of how many characters are waiting to be read. or 0 if none.
Notes
If there are no characters waiting to be read, then CHARS() always returns 0. But if there are characters waiting to be read, on some interpreters, CHARS() may return the actual number of such characters. On other interpreters, only a 1 will ever be returned to indicate that "there is at least one character waiting to be read". So, you should not assume that CHARS() returns an accurate count of just how many characters are waiting to be read. See Determine how many characters can be read.
Examples
Example use | Return value |
CHARS() |
/* Counts how many chars the user has already typed */ |
CHARS('myfile') |
/* Counts the remaining chars in 'myfile' */ |
See also
Changes the current directory.
Synopsis
result = CHDIR(dirname)
Args
dirname is the directory to make current. This could be a relative path (ie, referenced from the current directory) rather than a full path (ie, referenced from the root of a drive).
Returns
1 if success, or 0 if an error.
Notes
How the directory is specified may be platform dependent.
If an error in setting the directory to dirname, then RXFUNCERRMSG() can be used to retrieve an informative error message as to the nature of the failure. Unlike DIRECTORY(), a SYNTAX condition will not be raised.
To query the current directory, use PATH() or DIRECTORY().
Examples
Example use | Return value |
CHDIR('C:\Blort') |
'1' /* if success */ |
See also
PATH, DIRECTORY, DIR, FILESPEC, MATCHNAME
Copies one or more files.
Synopsis
result = COPYFILE(source, destination, option)
Args
source is the name of the file to copy. This may contain the full path (ie, drive and directory names also) or just the filename part (in which case the source file is assumed to be in the current directory). The filename part may contain the wildcard characters * and ? to copy all files matching that template, or no wildcards if copying a specific file/directory with that name. If omitted, source defaults to "*.*" (ie, all files in the current directory are copied). To copy all files in a specific directory other than the current directory, source must be the name of that directory and end with a slash or backslash character. The directory must exist, or an error will be returned.
destination is the new name for the destination (ie, copy). This may contain the full path (ie, drive and directory names also) or just the filename part (in which case the destination is copied to the current directory). The filename part may contain the wildcard characters * and ? to transform the source filename (like with EDITNAME), or no wildcards if a specific name is desired. To copy all source files into another specific directory other than the current directory but retain the same names, then destination must be the name of that directory and end with a slash or backslash character. The directory must exist, or an error will be returned.
option must be the following:
Value Meaning 'R' (Replace) Overwrite any destination file that has the same name. Without this option, COPYFILE() will return an error if there is already a destination file with the same name.
Returns
An empty string if success, or an error message if an error.
Notes
See Copying/Moving files and directories.
How the drive and directories are specified may be platform dependent. Reginald will accept either a slash or backslash to separate directory names.
COPYFILE() will return an error if you specify a specific file to copy and it doesn't exist, or there is a problem copying the file(s). COPYFILE() will not return an error if you specify some wildcard template for source, but there are no files that match.
If an error happens, then this raises a NOTREADY condition, and the file(s) may not be copied. Your NOTREADY handler can use CONDITION('D') to return an informative error message.
Examples
Example use | Return value |
COPYFILE('C:\Blort', 'D:\Blort2') |
/* Copies 'C:\Blort' to 'D:\Blort2' */ |
COPYFILE('C:\Blort', 'D:\Blort2', 'R') |
/* Copies 'C:\Blort' to 'D:\Blort2', overwriting D:\Blort2 if it already exists */ |
COPYFILE('C:\MyDir\', 'C:\MyDir2\') |
/* Copies all files in 'C:\MyDir' to 'C:\MyDir2' */ |
COPYFILE('C:\*.bak', 'C:\MyDir\') |
/* Copies all files in C:\ that end with .bak to 'C:\MyDir' */ |
COPYFILE('*.bat', '*.bak') |
/* Copies all files in the current directory that end with .bat, renaming them with a .bak extension |
See also
Deletes one or more files.
Synopsis
result = DELETEFILE(name)
Args
name is the name of the file to delete. This may contain the full path (ie, drive and directory names also) or just the filename part (in which case the source file is assumed to be in the current directory). The filename part may contain the wildcard characters * and ? to delete all files matching that template, or no wildcards if deleting a specific file/directory with that name. If omitted, name defaults to "*.*" (ie, all files in the current directory are deleted). To delete all files in a specific directory other than the current directory, name must be the name of that directory and end with a slash or backslash character. The directory must exist, or an error will be returned.
Returns
An empty string if success, or an error message if an error.
Notes
See Deleting files.
How the drive and directories are specified may be platform dependent. Reginald will accept either a slash or backslash to separate directory names.
DELETEFILE() will not return an error if the file doesn't exist.
If an error happens, then this raises a NOTREADY condition, and the file(s) may not be deleted. Your NOTREADY handler can use CONDITION('D') to return an informative error message.
Examples
Example use | Return value |
DELETEFILE('C:\Blort') |
/* Deletes 'C:\Blort' */ |
DELETEFILE('C:\MyDir\') |
/* Deletes all files in 'C:\MyDir' */ |
DELETEFILE('*.bak') |
/* Deletes all files in the current directory that end with .bat */ |
See also
Create or delete a directory.
Synopsis
error = DIR(dirname, operation)
Args
dirname is the name of the directory to create or delete. This could be a relative path (ie, referenced from the current directory) rather than a full path (ie, referenced from the root of a drive).
operation must be one of the following:
Value Meaning 'C' Create the directory. 'D' Delete the directory.
If omitted, operation defaults to 'C'.
Returns
An empty string if success, or an error message if an error.
Notes
How the directory is specified may be platform dependent.
DIR() does not return an error if the directory that you are trying to create already exists. On the other hand, if the directory that you're trying to create conflicts with an existing filename in the same parent directory, then this is an error.
If an error happens, then this raises a NOTREADY condition, and the directories(s) may not be created/deleted. Your NOTREADY handler can use CONDITION('D') to return an informative error message.
If creating a directory, and any parent directories do not exist, they will also be created. For example, if you pass a dirname of C:\temp\mydir\mysubdir, and although C:\temp exists, there is no mydir inside of it, then mydir will be automatically created along with mysubdir. When deleting a directory, parent directories are not deleted.
<dirname may end with a slash or backslash.
Examples
Example use | Return value |
DIR('C:\MyDir') /* Creates C:\MyDir */ |
'' /* if successful */ |
DIR('C:\MyDir', 'D') /* Deletes C:\MyDir */ |
'' /* if successful */ |
See also
CHDIR, DIRECTORY, FILESPEC, QUALIFY
Query the current directory, and/or change the directory.
Synopsis
current = DIRECTORY(dirname)
Args
dirname is the directory to make current. This could be a relative path (ie, referenced from the current directory) rather than a full path (ie, referenced from the root of a drive). If omitted, then the directory is not changed.
Returns
The full pathname of the current directory.
Notes
How the directory is specified may be platform dependent.
If an error occurs in setting the directory to dirname, a SYNTAX error is raised, and your SYNTAX handler can use CONDITION('D') to return an informative error message about the problem. So too, a SYNTAX error is raised if there is a problem returning the current directory's name.
Examples
Example use | Return value |
DIRECTORY() |
'C:\Windows' /* whatever the current dir is */ |
DIRECTORY('Blort') /* Assume we're in C:\MyDir */ |
'C:\MyDir\Blort' |
See also
Queries information about a drive such as its free space.
Synopsis
error = DRIVEINFO(varname, drive)
Args
drive is the name of the drive whose information is to be returned, for example 'C' for the C drive. If omitted, then information is returned for the current drive.
varname is the name of the REXX variable where information is returned. The name of the drive itself is returned in varname (so if drive is omitted, you can find out what the current drive is). The returned drive name always ends with a colon and backslash. The Free Bytes is returned in the variable name with a .0 extension. The Drive Size is returned in the variable name with a .1 extension. The Volume Serial Number is returned in the variable with a .2 extension. The Volume Label is returned in the variable name with a .3 extension. The file system name (ie, "FAT", "NTFS", etc) is returned in the variable with a .5 extension. The length of a filename component is returned in the variable with a .6 extension. (If the drive supports long file names, this will be greater than 11). The drive type is returned in the variable with a .4 extension. (See DRIVEMAP() for the types. Attributes for this drive are returned in the variable with a .7 extension.
The attribute bits for a drive are:
Bit Meaning 0 Case of filenames is preserved when saved. 1 Case matters in filenames. 2 Unicode is preserved in filenames when saved. 3 The file system preserves and enforces ACLs on this drive. 4 Files may be compressed individually. 15 The entire drive is compressed, for example, with Doublespace or Drivespace.
Returns
"0" if success, or an error number if a failure.
Notes
An appropriate error message can be gotten by passing the returned error number to UNIXERROR. The error number and message may be operating system specific. If an error happens, then this raises a NOTREADY condition. Your NOTREADY handler can use CONDITION('D') to return an informative error message (instead of UNIXERROR).
The drive name may be specified with a colon and or a trailing backslash, and may even be the full path name of a file or directory upon the drive.
Examples
Example use | Return value |
DRIVEINFO('Info') |
/* Returns info about the current drive in the variable named Info */ |
DRIVEINFO('Blort', 'C') |
/* Returns info about the C drive in the variable named Blort */ |
DRIVEINFO('Blort', 'C:\windows') |
/* Returns info about the C drive in the variable named Blort */ |
See also
Queries the drives by type, such as listing all CDROM drives.
Synopsis
listing = DRIVEMAP(start, type)
Args
start is the drive at which to start listing drives. For example, 'C' skips the 'A' and 'B' drives, and starts listing at the 'C' drive. If omitted, then the first drive listed is 'A'.
type is what type of drives to list. It may be one of the following:
Type Meaning 'CDROM' List only CDROM drives. 'FIXED' List only FIXED drives (ie, drives without removeable media, such as a hard drive). 'REMOVEABLE' List only drives with removeable media. 'MEMORY' List only RAM drives. 'NETWORK' List only network drives.
If type is omitted, then all of the above types of drives are listed.
Returns
If successful, a string containing all of the drives (of the specified Type) is returned, each separated by a space. For example, 'A:\ B:\ C:\'. If an error (or no drives of that Type are found), an empty string is returned.
Notes
The start drive name may be specified with a colon and or a trailing backslash, and may even be the full path name of a file or directory upon the drive.
If an error happens, then this raises a NOTREADY condition. Your NOTREADY handler can use CONDITION('D') to return an informative error message.
Examples
Example use | Return value |
DRIVEMAP() |
/* Lists all drives */ |
DRIVEMAP('C', 'CDROM') |
/* Lists all CDROM drives, skipping A and B drives */ |
See also
Transforms a filename based upon a template containing wildcards.
Synopsis
newname = EDITNAME(name, template, options)
Args
name is the filename to which the template is applied. This could contain the full path (ie, drive and directory names too) or just the filename part. If a full path is specified, you'll have to specify the 'U' or 'S' option.
When name is a drive or directory name (rather than a file's name), you should end name with a \ character (unless your intention is to transform the name of a directory in order to create a new directory name).
template is the template to apply to the filename. This could contain the full path or just the filename part. If a full path is specified, you'll have to specify the 'U', 'S', and/or 'T' option. Characters in the template replace their respective characters at the same positions in name, except for the wildcard characters ? and *. ? is replaced by the one, respective character in name at the same position. * is replaced by the respective character in name at the same position followed by all other characters up to a dot. Also, you can choose to have any drive and directory names on the template replace the drive and directory names on name.
If template is omitted, it defaults to *.* (ie, the transformed name has the same filename and extension parts as the Source, although the drive and directory may be different if you specify the 'S' option).
When template is a directory's name (as opposed to a file), you must end the arg with a \ character, or \*.* (unless name is also a directory name, and you wish to transform it as so).
options must be the following:
Value Meaning 'U' Use the drive/directory names on name, and ignore any drive/directory names on template. 'S' Use the drive/directory names on template, unless the 'T' option is also specified, and ignore any drive/directory names on name. 'T' Ignore any drive/directory names on template.
If omitted, options defaults to none of the above. (ie, Drive and directory names are utilized upon both name and template. The drive/directory names of template are appended to the drive/directory names of name. You should therefore first strip off any undesired drive/directory names before calling EDITNAME).
Returns
The new filename with the template applied to name.
Notes
EDITNAME() can be used to easily transform the filename part of a full pathname, for example to change the name of a file so that you can use the new name to create another file without overwriting the original. Or, it can be used to strip off the drive and directory on the original name and put a different drive and directory on the name.
How the drive and directories are specified may be platform dependent. Reginald will accept either a slash or backslash to separate directory names, and will substitute the proper character (on newname) for the given operating system.
The original name is not altered.
Examples
Example use | Return value |
EDITNAME('hello', 'hi') |
'hi' |
EDITNAME('hello.cmd', '*.exe') |
'hello.exe' |
EDITNAME('hello.cmd', 'hi.*') |
'hi.cmd' |
EDITNAME('hello.cmd', '*.*') |
'hello.cmd' |
EDITNAME('C:\mydir\hello.cmd', 'c:\', 'S') |
'c:\hello.cmd' |
EDITNAME('C:\mydir\hello.bak', '*.bak', 'U') |
'C:\mydir\hello.bak' |
EDITNAME('c:\mydir\', 'd:\mydir2\hi.bak', 'U') |
'c:\mydir\hi.bak' |
EDITNAME('mydir\mydir2\hello.cmd', 'c:\*2.*', 'S') |
'c:\hello2.cmd' |
EDITNAME('C:\mydir\hello.cmd', 'c:\', 'ST') |
'hello.cmd' |
See also
PATH, MATCHNAME, FILESPEC, QUALIFY
Extracts part of a pathname.
Synopsis
part = FILESPEC(option, pathname)
Args
pathname is the full path name of the file/stream, complete with drive and directory names, as well as any possible extension upon the file's name. For example, "C:\WINDOWS\NOTEPAD.EXE" includes all four elements -- the drive name "C:", the directory names "\WINDOWS\", the filename "NOTEPAD.EXE", and the extension ".EXE".
option indicates which part of the full path you wish to be returned, as so:
Option Meaning D Return the drive name. P Return the directory names. N Return the file name (including extension). E Return the extension only.
Returns
The requested part of the path if success, or an empty string if no such part exists in pathname.
Notes
How the drive and directories are specified may be platform dependent. Reginald will accept either a slash or backslash to separate directory names.
Examples
Example use | Return value |
FILESPEC('P', 'C:\MyDir\MySubDir\Blort.txt') |
'\MyDir\MySubDir\' |
FILESPEC('D', 'C:\MyDir\MySubDir\Blort.txt') |
'C:' |
FILESPEC('N', 'C:\MyDir\MySubDir\Blort.txt') |
'Blort.txt' |
FILESPEC('E', 'C:\MyDir\MySubDir\Blort.txt') |
'.txt' |
See also
Reads in a line from a particular stream.
Synopsis
line = LINEIN(stream, position, count)
Args
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names). If omitted, the default is to read from STDIN (typically, get a line from the user via a prompt in the console window).
position specifies at what line position (within the stream) to start reading from, where 1 means to start reading at the very first line in the stream. If omitted, the default is to resume reading at where a previous call to LINEIN() left off (ie where the current read line position is).
count indicates the requested number of lines to read in. If specified, count can be only 1 or 0. If 0, then LINEIN() merely sets the "read line position" to position without reading any line (ie, similiar to using STREAM's SEEK), and returns an empty string. If count is 1 or omitted, LINEIN() reads 1 line.
Returns
A string containing the characters of one line. Any operating-system-specific "end of line" characters are stripped from the end of the line. A blank line will return an empty string, but also an error will cause an empty line to be returned.
Notes
See Reading a file.
You may use the LINES function to determine how many remaining lines are available to be read, before calling LINEIN().
If the operating system has a problem reading from the stream, then this raises a NOTREADY condition, and LINEIN() will return an empty string.
After a call to LINEIN(), you can use STREAM's 'D' option to return an informative error message as to the nature of any error that may have occurred. This will return an empty string if there was no error. Otherwise, unless you SIGNAL ON NOTREADY, it may be difficult to distinguish between an error occuring, or encountering a blank line, or reaching the end of a persistent stream.
If a NOTREADY condition is raised, your NOTREADY handler can use CONDITION('D') to return the name of the stream in error (and then use STREAM's 'D' option to fetch an informative error message).
Intermingling calls to CHARIN() and LINEIN() upon the same stream can result in odd behavior unless you specify position on a call to LINEIN() after calling CHARIN() (and vice versa).
For a transient stream (such as STDIN):
You can't specify a position, or this raises a SYNTAX condition with an error number of 40.42.
If there is not a line available, then program execution may stop until a line is available. Execution will resume when the line is finally made available (or the user manually aborts which will raise a HALT condition).
For a persistent stream:
If position is beyond the last line in the stream, then this raises a NOTREADY condition, and LINEIN() will return an empty string.
A subsequent call to LINEIN() (without specifying a new position), after you have already read all lines from the stream, will raise a NOTREADY condition, and LINEIN() will return an empty string.
Examples
Example use | Return value |
LINEIN(, , 1) |
/* Gets the next line from the user */ |
CHARIN('myfile', , 1) |
/* Reads the next line from 'myfile' */ |
CHARIN('myfile', 1) |
/* Resets the read line pointer to the start of 'myfile' */ |
See also
Writes out a line to a particular stream.
Synopsis
result = LINEOUT(stream, string, position)
Args
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names). If omitted, the default is to write to STDOUT (typically, display the data in the console window).
position specifies at what line position (within the stream) to start writing the line, where 1 means to start writing at the very first line in the stream. If omitted, the default is to resume writing at where a previous call to LINEOUT() left off (ie, where the current write line position is).
string are the characters (ie, data) to write out as one complete line. (Any necessary, operating-system-specific "end of line" characters are automatically added to the end of the line). If omitted or an empty string, then LINEOUT() merely sets the "write line position" to position without writing any line. (ie, Similiar to using STREAM's SEEK).
If both position and string are omitted, the stream will be closed. (ie, Similiar to using STREAM's CLOSE).
Returns
0 if successful. If an error, the number of lines unwritten (ie, 1).
Notes
See Saving a file.
The end of a stream is considered to be one position after the last, already existing character in the stream. In other words, the end of the stream is at the end of any, already existing characters. Normally, if you set position to some place before the end of the stream, then all characters/lines after that position in the original stream are deleted. The net result is that you truncate the stream at that position (ie, you change where the end of the stream occurs), and then append your new line at this new end point.
If you would prefer to be able to overwrite certain data within the middle of a stream, without destroying all original data after the portion you overwrite, then you can use Reginald's 'OPTIONS NOLINEOUTTRUNC'.
If the operating system has a problem writing to the stream, then this raises a NOTREADY condition, and LINEOUT() may return non-zero.
After a call to LINEOUT(), you can use STREAM's 'D' option to return an informative error message as to the nature of any error that may have occurred. This will return an empty string if there was no error.
Program execution will stop until the line has been written to the stream (or the user manually aborts which will raise a HALT condition).
If a NOTREADY condition is raised, your NOTREADY handler can use CONDITION('D') to return the name of the stream in error (and then use STREAM's 'D' option to fetch an informative error message).
Intermingling calls to CHAROUT() and LINEOUT() upon the same stream can result in odd behavior unless you specify position on a call to LINEOUT() after calling CHAROUT() (and vice versa).
For a transient stream (such as STDIN):
You can't specify a position, or this raises a SYNTAX condition with an error number of 40.42.
For a persistent stream:
If position is beyond the immediate end of the stream (ie, more than one line beyond the last line already in the stream), then this raises a NOTREADY condition, and LINEOUT() returns non-zero.
Examples
Example use | Return value |
LINEOUT(, 'Hi') |
/* Prints "Hi" to the console and moves to the next line */ |
LINEOUT('myfile', 'Hi') |
/* Writes a line containing "Hi" to 'myfile' */ |
LINEOUT('myfile') |
/* Closes 'myfile' */ |
See also
Counts the number of lines waiting to be read from a particular stream (via LINEIN()).
Synopsis
howmany = LINES(stream, mode)
Args
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names). If omitted, the default is to count how many lines are available from STDIN (typically, check if the user has already typed one or more lines via a prompt in the console window).
mode is one of the following:
Mode Meaning 'C' (Count) Count how many more lines are actually waiting to be read. 'N' (Normal) Return a 1 if there are one or more lines to be read, or a 0 if there are no more.
If mode is omitted, then the default mode (typically "Normal") is used.
Returns
A count of how many lines are waiting to be read. or 0 if none.
Notes
The LINES() built-in function may have two different "modes" of operation. See Determine how many lines are available.
When LINES() is used in the 'Normal' mode, then it always returns a 1 if there is at least one more line to be read in the stream. Even if there is more than one line yet to be read, it will still return a 1.
There is another mode that LINES() supports. In 'Count' mode, LINES() actually does count how many more lines are in the stream. (So, if you have just opened the stream, and not yet read anything from it, then you will be at the beginning of the stream, and LINES() will report how many lines are really in the stream). 'Count' mode involves a lot more overhead than 'Normal' mode, so that's why there is a 'Normal' mode. Sometimes, it's important to a programmer to know only if there is another line to be read, but not necessarily how many more. So, 'Normal' mode is a lot quicker for that purpose.
If there are no lines waiting to be read, then LINES() always returns 0 in either mode.
Reginald allows setting the default mode of LINES(). Use an 'OPTIONS NOFAST_LINES_BIF_DEFAULT' statement once prior to any calls to LINES() to set the default mode as 'Count'. To set the default mode as 'Normal', then use 'OPTIONS FAST_LINES_BIF_DEFAULT'.
Examples
Example use | Return value |
LINES() |
/* Counts how many lines the user has already typed */ |
LINES('myfile') |
/* Counts the remaining lines in 'myfile' */ |
See also
Reads all of the lines of a text file into successive tails of one stem variable.
Synopsis
result = LOADTEXT(stemname, stream, options)
Args
stemname is the name of the stem variable to store the lines of the text file. If omitted, the default is to get lines from STDIN (typically, from the user typing them via a prompt in the console window) until a blank line (ie, the ENTER key is pressed without any other characters before it).
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names). If omitted, the default is to read whatever lines are available from STDIN (typically, lines the user has already typed via a prompt in the console window).
options may be any or all of the following:
Options Meaning 'T' (Trailing) Strip out trailing spaces from each line. 'L' (Leading) Strip out leading spaces from each line. 'B' (Blank) Strip out blank lines. 'S' (Save) Saves the stem variable to a text file (ie, a save operation instead of load).
If option is omitted, it defaults to none of the above.
Returns
A 1 if successful. or 0 if an error.
Notes
The stem name, with a tail of 0 appended to it, will be a count of how many lines are in the text file. Each line will be in its own tail, where the stem name with a 1 appended contains the first line, the stem name with a 2 appended contains the second line, etc. For example, if you pass a stemname of 'mystem.', then mystem.0 contains a count of how many lines are read in, mystem.1 contains the first line, mystem.2 contains the second line, mystem.3 contains the third line, etc.
Note: You must put quotes around stemname if you're specifying it as a literal string. Otherwise, it will be considered to be a variable whose value is the name of the desired stem. Also, stemname must end with a dot. Note that a legal stem name could include several dots, such as mystem.firstfile. for the name.
If you have trapped the NOTREADY condition, then NOTREADY is raised if there is an error reading/saving the lines of the file. Your NOTREADY handler can use CONDITION('D') to return the name of the stream in error (and then use STREAM's 'D' option to fetch an informative error message).
If the stream is already open (because you have used some other function to read from it, or explicitly opened it with STREAM), and the current read position is not at the beginning of the file, then LOADTEXT() will read only those lines from the current read position to the end of the file. To read from the beginning, use Stream()'s SEEK command to reposition the file, or the CLOSE command to close it, before calling LOADTEXT(). If the file is already open for writing, then the lines will overwrite at the current position. If the current position is at the end of the file, you can therefore append new lines to the file.
Examples
Example use | Return value |
LOADTEXT('blort.', 'C:\WINDOWS\SYSTEM.INI') |
/* Reads the lines of 'C:\WINDOWS\SYSTEM.INI' into a variable named blort. */ |
LOADTEXT('blort.', 'file.txt', 'TL') |
/* Reads the lines of 'file.txt' into blort, stripping leading and trailing spaces on each line. */ |
See also
Tests for the existence of a certain file or directory, perhaps with certain attributes. Alternately, can enumerate all of the files in a given directory, perhaps filtering only those that match a certain template containing wildcards, or which have certain attributes.
Synopsis
next = MATCHNAME(search, stem, template, attributes, options)
Args
template is the template to match, if you wish to filter by name. This may contain the full path (ie, drive and directory names also) if searching a specific drive or directory for matching names, or just the filename part (to search the current directory for names that match). The filename part may contain the wildcard characters * and ? to match any file matching that template, or no wildcards if testing for the existence of a specific file/directory with that name. If omitted, template defaults to "*.*" (ie, searches the current directory for all files/directories without filtering by name).
attributes are the attributes to match, if you wish to filter by attributes. attributes can be any of the following:
Attribute Meaning 'D' Include sub-directories (but not contents of those sub-directories). 'S' Include system files. 'N' Include normal files. 'H' Include hidden files. 'C' Include compressed files. 'R' Include read-only files. 'A' Include files with the archive bit set. 'T' Include temporary files.
If attributes is omitted, it defaults to none of the above (ie, items are not filtered by their attributes). More than one attribute may be specified. The order of attributes is irrelevant.
options determines what information is reported by MATCHFILE(). options can be any of the following:
Option Meaning 'N' Report the name of the matching item. 'F' Fully qualify the matching item's name. (ie, Include the drive and directory names). Otherwise, only the filename part is reported. 'S' Report the size of the matching item. Directories will have an empty string as the size. 'D' Report the last modified date of the matching item. 'A' Report the attributes of the matching item. 'O' Perform one match only. It is not necessary to specifically close down the search if MATCHFILE() returns a matching item.
If options is omitted, it defaults to 'N'. More than one option may be specified. The order of options is irrelevant.
stem is the name of the variable where the above information is reported. If the item's name is to be reported, it is stored in the variable with the same name as stem. If the item's size is to be reported, it is stored in the variable name of stem with a tail name of .0 added. If the item's date is to be reported, it is stored in the variable name of stem with a tail name of .1 added. If the item's attributes are to be reported, they are stored in the variable name of stem with a tail name of .2 added. If stem is omitted, then this is an indication that you wish to abort a series of calls that you have been making to MATCHNAME() (ie, close down the search on this template).
search is the instance (ie, number) for this MATCHNAME() template. If you are going to be enumerating more than one template simultaneously (by intermixing calls to MATCHFILE() with different templates), then you need to give each template its own, unique search number. Otherwise, if you're enumerating only one template at a time, then you may omit search.
Returns
Each time that MATCHNAME() is successfully called, it returns an empty string, and sets your stem variable to information pertaining to the next item that matches your template and attributes. If an error, then MATCHNAME() closes down the search and returns an error message. If there are no more items that match your template and attributes, then MATCHFILE() closes down the search and returns the string DONE.
Notes
MATCHNAME() can be used to easily resolve a filename containing the wildcard characters * and ?. In this way, your script can support "filename global pattern matching", allowing the user to easily specify many files that your script must act upon, without forcing the user to type the name of every single file that he wants processed.
How the drive and directories are specified in template may be platform dependent. Reginald will accept either a slash or backslash to separate directory names. When reporting the name, MATCHNAME() will ensure that it is properly formatted for the given operating system. Reginald will also trim off any leading and trailing spaces from template upon operating systems where such spaces are not legal. The original template is not altered.
Unless you specify the 'O' option, then you must either loop around calls to MATCHNAME() until it either returns an error message or the string DONE, or you must explicitly end the search by calling MATCHFILE() one last time and omit the stem arg. If you specify the 'O' arg, then you can't make repeated MATCHFILE() calls to enumerate all of the matches for a given template. You can make only one call to enumerate the first match.
If an error happens, then this raises a NOTREADY condition. Your NOTREADY handler can use CONDITION('D') to return an informative error message. Note that it is not considered an error if there are no matching files to your specifications, so even if you trap NOTREADY condition, you still need to check the return from MATCHNAME to see whether it is an empty string (a matching file is found) or "DONE" (no more files match your specification). But by trapping NOTREADY, your NOTREADY handler can deal with all other errors from MATCHNAME.
Examples
See Listing the contents of a directory for more examples and details.
See also
Moves one or more files from one location to another. When the file remains on the same drive, this essentially renames a file.
Synopsis
result = MOVEFILE(source, destination)
Args
source is the name of the file to move. This may contain the full path (ie, drive and directory names also) or just the filename part (in which case the source file should be in the current directory). The filename part may contain the wildcard characters * and ? to move all files matching that template, or no wildcards if moving a specific file/directory with that name. If omitted, source defaults to "*.*" (ie, all files in the current directory are moved). To move all files in a specific directory other than the current directory, source must be the name of that directory and end with a slash or backslash character. The directory must exist, or an error will be returned.
destination is the new name for the destination (ie, moved file). This may contain the full path (ie, drive and directory names also) or just the filename part (in which case the destination is just the source file renamed). The filename part may contain the wildcard characters * and ? to transform the source filename as per EDITNAME, or no wildcards if a specific name is desired. To move all source files into another specific directory other than the current directory but retain the same names, then destination must be the name of that directory and end with a slash or backslash character. The directory must exist, or an error will be returned.
Returns
An empty string if success, or an error message if an error.
Notes
See Copying/Moving files and directories.
How the drive and directories are specified may be platform dependent. Reginald will accept either a slash or backslash to separate directory names.
MOVEFILE() will return an error if you specify a specific file to move and it doesn't exist. MOVEFILE() will not return an error if you specify some wildcard template for source, but there are no files that match. MOVEFILE() will return an error if there is already a destination file with the same name as destination. If an error happens, then this raises a NOTREADY condition, and the file(s) may not be moved. Your NOTREADY handler can use CONDITION('D') to return an informative error message.
Examples
Example use | Return value |
MOVEFILE('C:\Blort', 'D:\Blort2') |
/* Moves 'C:\Blort' to 'D:\Blort2' */ |
MOVEFILE('C:\MyDir\', 'C:\MyDir2\') |
/* Moves all files in 'C:\MyDir' to 'C:\MyDir2' */ |
MOVEFILE('C:\*.bak', 'C:\MyDir\') |
/* Moves all files in C:\ that end with .bak to 'C:\MyDir' */ |
MOVEFILE('*.bat', '*.bak') |
/* Renames all files in the current directory that end with .bat, renaming them with a .bak extension. |
See also
Gets a full pathname from a partial name, queries the current directory, sets the current directory, splits a pathname into separate elements assigning each piece to a compound variable, and/or checks if a pathname is a drive/directory or file.
PATH() is akin to a combination of FILESPEC(), DIRECTORY(), QUALIFY(), and more, all wrapped up into one function. As such, it can replace those functions. It is supported only by Reginald.
Synopsis
error = PATH(varname, pathname, options)
Args
pathname is the name of a file or drive/directory. It may be fully qualified with drive and parent directory names, as well as any possible extension upon the file's name. For example, "C:\WINDOWS\NOTEPAD.EXE" includes all four elements -- the drive name "C:\", the directory names "WINDOWS\", the filename "NOTEPAD", and the extension ".EXE". Or, it may be a partial name. For example, "NOTEPAD.EXE" specifies only the filename and extension parts. The name may also include wildcards such as "C:\WINDOWS\*.INI" to specify any item in the C:\WINDOWS directory that has an extension of ".INI".
If you wish pathname to be split apart into its separate elements of drive, directories, filename, and extension, then varname is the name of the stem variable where those elements are returned. If varname is omitted, then pathname is simply the name of where you would like the current directory to be set.
Note: Don't forget to put quotes around varname, and do not end it with a dot.
options may be any of the following:
Option Meaning 'V' Check whether pathname is an existing drive/directory name, or a filename, before parsing it into separate elements. 'J' Join the filename and extension elements together in one variable, instead of separating the extension into its own variable.
Returns
An empty string if successful, or an error message if an error.
Notes
When pathname is separated into elements, the drive name is assigned to the stem variable with a ".0" extension, the directory names (if any) are assigned to the stem variable with a ".1" extension, the filename (if any) minus the extension is assigned to the stem variable with a ".2" extension, and the extension (if any) is assigned to the stem variable with a ".3" extension (unless the 'J' option is specified). So, if you pass a varname of 'MyVar', then the drive name is assigned to MyVar.0, the directory names (if any) are assigned to MyVar.1, the filename (if any) is assigned to MyVar.2, and the extension (if any) is assigned to MyVar.3 (assuming no 'J' option). If an element is not present in pathname, then its respective compound variable is an empty string. For example, if there is no extension, then MyVar.3 would be "".
How the drive and directories are specified in pathname may be platform dependent. Reginald will accept either a slash or backslash to separate directory names. When returning the separated elements, PATH() will ensure that those elements are properly formatted for the given operating system, such that they can be concatenated back together to form a legal pathname. For Windows, this means that the drive and directory names end with a backslash, and the extension begins with a dot. Reginald will also trim off any leading and trailing spaces from pathname upon operating systems where such spaces are not allowed.
If an error happens, then this raises a NOTREADY condition. Your NOTREADY handler can use CONDITION('D') to return an informative error message.
Examples
To set the current directory, you will pass in pathname as the desired directory, and omit varname. For example, to set the current directory to "C:\WINDOWS', you would call PATH() as so:
error = PATH(, 'C:\WINDOWS') IF error \== "" THEN SAY "ERROR:" errorYou do not need to specify the full path. For example, assume that the current directory is "C:\WINDOWS". To set the current directory to the sub-directory "MyDir\MyName" inside of "C:\WINDOWS", you can call PATH() as so:
error = PATH(, 'MyDir\MyName') IF error \== "" THEN SAY "ERROR:" errorThis results in the current directory being C:\WINDOWS\MyDir\MyName, assuming that MyName is a directory. If MyName happens to be the name of an existing file, then it is trimmed off and the current directory is set to C:\WINDOWS\MyDir. This saves you the trouble of having to trim off the filename/extension from a path in order to set the directory (but only works if the file actually exists).
Note:
If any of the parent directories do not exist, you will get an appropriate error message.To split a name into separate elements, you need to supply varname. For example, to split the name "C:\MyDir\MySubDir\MyFile.Extension" into separate pieces and store those pieces into variables named MYSTEM.0, MYSTEM.1, MYSTEM.2, and MYSTEM.3, you would call PATH() as so:
error = PATH('MyStem', 'C:\MyDir\MySubDir\MyFile.Extension') IF error \== "" THEN SAY "ERROR:" errorIf successful, this would result in the following assignments:
MyStem.0 = 'C:\' MyStem.1 = 'MyDir\MySubDir\' MyStem.2 = 'MyFile' MyStem.3 = '.Extension'Use the 'V' option if you need to verify whether pathname is an existing drive/directory, or a filename (for a file that may or may not exist). For example, consider splitting apart "C:\MyDir\MySubDir\MyFile.Extension", and let's assume that MyFile.Extension is an existing directory inside of C:\MyDir\MySubDir. Now call PATH() with the 'V' option:
error = PATH('MyStem', 'C:\MyDir\MySubDir\MyFile.Extension', 'V') IF error \== "" THEN SAY "ERROR:" errorIf successful, this would result in the following assignments:
MyStem.0 = 'C:\' MyStem.1 = 'MyDir\MySubDir\MyFile.Extension\' MyStem.2 = '' MyStem.3 = ''Note that MyFile.Extension is now considered part of the directory names, which end with a backslash. And the filename and extension parts are now empty strings. In this way, you can test whether MyStem.2 and MyStem.3 are empty to determine whether you have an existing directory name. Of course, if you instead have a filename, that file may or may not exist. You can then use STATE() to verify its existence, or try to open the file with STREAM()'s 'OPEN READ' to verify if it exists, as so:
error = PATH('MyStem', 'C:\MyDir\MySubDir\MyFile.Extension', 'V') IF error \== "" THEN SAY "ERROR:" error ELSE DO /* Is it an existing directory? */ IF MyStem.2 == "" & MyStem.3 == "" THEN SAY "It's a directory." /* It's a filename. */ ELSE DO /* Is it an existing file? */ IF STATE() THEN SAY "It doesn't yet exist." ELSE SAY "It's a file." END ENDpathname may also contain wildcards. For example, consider this call:
error = PATH('MyStem', 'C:\MyDir\*.*', 'V') IF error \= "" THEN SAY "ERROR:" errorIf successful, this would result in the following assignments:
MyStem.0 = 'C:\' MyStem.1 = 'MyDir\' MyStem.2 = '*' MyStem.3 = '.*'You can also use the 'J' option if you don't wish the filename and extension parts separated, as so:
error = PATH('MyStem', 'C:\MyDir\*.INI', 'VJ') IF error \= "" THEN SAY "ERROR:" errorIf successful, this would result in the following assignments:
MyStem.0 = 'C:\' MyStem.1 = 'MyDir\' MyStem.2 = '*.INI' MyStem.3 = ''To query the current directory, and also parse it into separate elements of drive and directory names, you omit pathname, for example, assuming the current directory is "C:\WINDOWS":
error = PATH('MyStem') IF error \= "" THEN SAY "ERROR:" errorIf successful, this would result in the following assignments:
MyStem.0 = 'C:\' MyStem.1 = 'WINDOWS\' MyStem.2 = '' MyStem.3 = ''
See also
MATCHNAME, FILESPEC, QUALIFY, DIRECTORY, CHDIR, STATE
Gets a fully qualified name of a file/stream, complete with drive and directory names, from a partial pathname, for example, perhaps only the filename itself.
Synopsis
fullname = QUALIFY(name)
Args
name is the partial path name of the file/stream.
Returns
If successful, the fully qualified path name, complete with drive and directory names. If an error, an empty string (and SYNTAX condition is raised).
Notes
How the drive and directories are specified may be platform dependent. Reginald will accept either a slash or backslash to separate directory names, and will substitute the proper character (on the returned fullname) for the given operating system. Reginald also trims leading/trailing spaces from name upon operating systems where such spaces are not allowed.
QUALIFY() constructs the full path name using the current drive and current directory. It does not check for the actual existence of such a file. If desired, use STATE or MATCHNAME (if name could contain wildcards) to verify if a file/stream by that name actually exists.
QUALIFY() works only upon persistent streams. A transient stream will raise a SYNTAX condition.
Examples
Example use | Return value |
QUALIFY('Blort.txt') /* Assume current dir is C:\MyDir\MySubDir */ |
'C:\MyDir\MySubDir\Blort.txt' |
See also
Searches the specified path for the specified file/directory and returns the full path name of the file/directory if found. Also can be used to get the value of an environment variable, or special Windows directory.
Synopsis
fullname = SEARCHPATH(path, filename)
Args
filename is the file to search for. The wildcards * and ? can be used. * matches any amount of characters up to a \, :, or . (dot). ? matches any one character. If wildcards are used, they appear in the returned fullname. If filename is omitted, then only path is evaluated.
path is where to search for the file. If omitted, Windows searches default paths (including the WINDOWS and SYSTEM directories, as well as any environment variable paths). The path can contain an environment variable (which must be enclosed between two % characters). For example, assume that an environment variable called MYPATH is set to SomeDir\SomeSubDir. If you pass a path of C:\%MYPATH%\AnotherDir, then the fullname is evaluated to C:\SomeDir\SomeSubDir\AnotherDir.
Certain environment variables are already defined. They are:
Path Meaning '%WIN%' Returns the Windows directory. '%SYS%' Returns the System directory. '%PROGRAMS%' Returns the Program Files directory. '%RECENT%' Returns the Recent Documents directory. '%SENDTO%' Returns the Send To directory. '%FONTS%' Returns the Fonts directory. '%TEMP%' Returns the directory for temporary files. '%DESKTOP%' Returns the path to the Current User's desktop. '%DOCS%' Returns the path to the Current User's My Documents folder. '%FAV%' Returns the path to the Current User's Favorites folder. '%MENU%' Returns the Current User -> Start Menu's "Programs" folder. '%STARTUP%' Returns the Current User -> Start Menu's "Programs -> Startup" folder. '%ADESKTOP%' Returns the path to All Users' desktop. '%ADOCS%' Returns the path to All Users' Documents. '%AMENU%' Returns All Users -> Start Menu's "Programs" folder. '%ASTARTUP%' Returns All Users -> Start Menu's "Programs -> Startup" folder.
Returns
The full path name of the file if it is found in the specified path. If the file can't be found, an empty string is returned. If filename is omitted, then the value of path is returned (with a \ character appended to the end. To omit this final character, pass an empty string for filename).
Notes
How the drive and directories are specified may be platform dependent. Reginald will accept either a slash or backslash to separate directory names. Reginald also trims leading/trailing spaces from name upon operating systems where such spaces are not allowed.
Examples
SEARCHPATH() is typically used in two situations:
name = SEARCHPATH('C:\%MYPATH%') IF name \== 'C:\%MYPATH%\' && name \== "" THEN SAY "Found it, and the path is" nameAs you can see from the second line above, an appropriate error check is to see that SEARCHPATH returned a fullname with the environment variable resolved.
name = SEARCHPATH(, 'WIN.INI') IF name \== "" THEN SAY "Found it, and the full path is" nameAs you can see from the second line above, an appropriate error check when you pass the second arg is to see that SEARCHPATH returned a non-empty fullname.
Note that you can do both simultaneously above (ie, pass an environment name as the first arg, and a filename as the second arg, and come up with the complete path of that file with the environment variable resolved).
/* Search for a 'rxdlg.dll' along LIBPATH */ name = SEARCHPATH('%LIBPATH%', 'rxdlg.dll') /* found it? */ IF name \== "" THEN SAY "Found it"
See also
Tests if a file/stream actually exists.
Synopsis
result = STATE(name)
Args
name is the name of the file/stream whose existence is to be checked.
Returns
0 if the stream exists, or 1 if it does not exist.
Notes
How the drive and directories are specified may be platform dependent. Reginald will accept either a slash or backslash to separate directory names. Reginald also trims leading/trailing spaces from name upon operating systems where such spaces are not allowed.
STATE() can also be used to check for the existence of a directory, but can't report whether name is an existing directory or file. Use MATCHNAME instead if it is important to also determine the attributes for name (such as whether it is a directory or file, read-only, hidden, etc).
If name could contain wildcard characters, then use MATCHNAME instead to test for the existence of a matching file/directory. STATE() does not take wildcard characters into consideration.
Examples
Example use | Return value |
STATE('C:\MyDir\MySubDir\Blort.txt') |
/* Determines if 'C:\MyDir\MySubDir\Blort.txt' exists */ |
See also
Opens/closes/seeks streams, and reports stream diagnostics/information.
Synopsis
result = STREAM(stream, option, command)
Args
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names).
option specifies which task you wish STREAM() to perform. It must be one of the following:
Option Meaning C (Command) Executes a command. The command arg to STREAM() will specify which command. S (Status) Returns the string 'READY' if the stream is open and more data can be read from, or written to, the stream. Returns the string 'NOTREADY' if the "read character" and "read line" positions are already at the end of the stream and a further call to LINEIN() or CHARIN() would cause a NOTREADY error. Returns the string 'ERROR' if the last operation caused the stream to be in error state. When a stream is in error state, calls to functions such as LINEIN(), LINEOUT(), CHARIN(), and CHAROUT() seem to indicate successful operation, but no actual operation is carried out. You must issue a STREAM() RESET command on the stream in order to clear its error state before any actual operations can resume. Returns the string 'UNKNOWN', if a stream has not yet been accessed by REXX. D (Description) Returns any error message associated with the last operation performed upon the stream. If there was no error, then an empty string is returned.
If option is omitted, it defaults to 'S'.
command is specified only when option is 'C'. It must be one of the following:
Option Meaning CLOSE Close the stream. If successful, return an empty string. If an error, raise NOTREADY and return the string 'ERROR: xxx' where xxx is replaced by some error number from the operating system. STREAM()'s 'D' option may yield a more specific error message. FLUSH Flush any data in the operating system's I/O buffers. If successful, return the string 'READY'. If an error, raise NOTREADY and return 'ERROR'. STREAM()'s 'D' option may yield a more specific error message. If the stream was not open, return 'UNKNOWN'. OPEN READ Open an existing stream for reading only (ie, CHARIN(), LINEIN()). Place the "read line" and "read character" positions at the start of the stream. If successful, return the string "READY:". If an error (including if the stream doesn't exist), raise NOTREADY and return the string 'ERROR: xxx' as per the CLOSE command. Other programs may also open the stream for reading (ie, shared read access), but not shared write access. OPEN WRITE Open the stream for writing only (ie, CHAROUT(), LINEOUT()). If the stream does not exist, create it. If it exists, retain its existing data. Place the "write line" and "write character" positions at the end of the stream. If successful, return the string "READY:". If an error, raise NOTREADY and return the string 'ERROR: xxx' as per the CLOSE command. No other program may be simultaneously accessing the stream while your script has this stream open (ie no shared access). OPEN BOTH Open the stream for both reading and writing. If the stream does not exist, create it. If it exists, retain its existing data. Place the "read line" and "read character" positions at the start of the stream, and the "write line" and "write character" positions at the end of the stream. If successful, return the string "READY:". If an error, raise NOTREADY and return the string 'ERROR: xxx' as per the CLOSE command. No other program may be simultaneously accessing the stream while your script has this stream open (ie no shared access). OPEN BOTH SHARED This is the same as 'OPEN BOTH', except that other programs may also open the stream for reading/writing (ie, shared access). This is supported only by Reginald. OPEN WRITE APPEND Open the stream for writing only. If the stream does not exist, create it. If it exists, retain its existing data. Place the "write line" and "write character" positions at the end of the stream. You are not allowed to set the position in this stream. (It is assumed to be a transient stream). If successful, return the string "READY:". If an error, raise NOTREADY and return the string 'ERROR: xxx' as per the CLOSE command. No other program may be simultaneously accessing the stream while your script has this stream open (ie no shared access). OPEN WRITE REPLACE Open the stream for writing only. If the stream does not exist, create it. If it exists, delete any previous contents of the stream. Place the "write line" and "write character" positions at the start of the stream. If successful, return the string "READY:". If an error, raise NOTREADY and return the string 'ERROR: xxx' as per the CLOSE command. No other program may be simultaneously accessing the stream while your script has this stream open (ie no shared access). OPEN BOTH APPEND Open the stream for both reading and writing. If the stream does not exist, create it. If it exists, retain its existing data. Place the "read line" and "read character" positions at the start of the stream, and the "write line" and "write character" positions at the end of the stream. You are not allowed to set the position in this stream. (It is assumed to be a transient stream). If successful, return the string "READY:". If an error, raise NOTREADY and return the string 'ERROR: xxx' as per the CLOSE command. No other program may be simultaneously accessing the stream while your script has this stream open (ie no shared access). OPEN BOTH REPLACE Open the stream for both reading and writing. If the stream does not exist, create it. If it exists, delete any previous contents of the stream. Place the "read line", "read character", "write line", and "write character" positions at the start of the stream. If successful, return the string "READY:". If an error, raise NOTREADY and return the string 'ERROR: xxx' as per the CLOSE command. No other program may be simultaneously accessing the stream while your script has this stream open (ie no shared access). OPEN WRITE SHARED This is the same as 'OPEN BOTH REPLACE', except that other programs may also open the stream for reading/writing (ie, shared access). This is supported only by Reginald. RESET Clears a stream's error state. If successful, and the stream is ready to operate again, returns the string 'READY'. If an error, returns the string 'UNKNOWN', and you will need to open the stream again. READABLE Returns 1 if read permission is allowed on the stream. Returns 0 otherwise. WRITABLE Returns 1 if write permission is allowed on the stream. Returns 0 otherwise. EXECUTABLE Returns 1 if the stream is an executable. Returns 0 otherwise. STATUS Returns a string containing information about the stream as so: '<mode> READ: char= <rcharno> line= <rlineno> WRITE: char= <wcharno> line= <wlineno> <type>'
where: <mode> = "READ/WRITE", "READ", or "WRITE"
<rcharno> = Current read character position (0 is first char)
<rlineno> = Current read line position (1 is first line)
<wcharno> = Current write character position
<wlineno> = Current write line position
<type> = "PERSISTENT" or "TRANSIENT"If an error, returns an empty string.
FSTAT If successful, return a string from the operating system containing information about the stream, including how much data it contains (or its free space in the case of a drive), its permission bits, and other operating system specific info. If an error (including if the stream doesn't exist), return an empty string. QUERY DATETIME If successful, return a string containing the date/time that the stream was last modified. The format is Month-Day-Year Hour:Minute:Second, where the year is 2 digits. If an error, return an empty string. QUERY TIMESTAMP If successful, return a string containing the date/time that the stream was last modified. The format is Year-Month-Day Hour:Minute:Second, where the year is 4 digits. If an error, return an empty string. QUERY EXISTS If successful, return the fully qualified path name of the stream. If an error, return an empty string. QUERY HANDLE If successful, return the handle of the stream if it is open by REXX. If an error (or the handle is not open by REXX), return an empty string. QUERY POSITION READ If successful, return the current "read character position" for the stream, where 0 is the first character in the stream. If an error, return an empty string. QUERY POSITION WRITE If successful, return the current "write character position" for the stream, where 0 is the first character in the stream. If an error, return an empty string. QUERY POSITION READ CHAR Same as QUERY POSITION READ. QUERY POSITION WRITE CHAR Same as QUERY POSITION WRITE. QUERY POSITION READ LINE If successful, return the current "read line position" for the stream, where 1 is the first line in the stream. If an error, return an empty string. QUERY POSITION WRITE LINE If successful, return the current "write line position" for the stream, where 1 is the first line in the stream. If an error, return an empty string. QUERY POSITION SYS If successful, return the current position of the "read character pointer" for the stream as reported by the operating system, where 0 is the first character in the stream. If an error, return an empty string. This may ultimately be more accurate than QUERY POSITION READ. QUERY SIZE If successful, return the size of the stream in bytes. If an error, return an empty string. QUERY STREAMTYPE If successful, return the stream's type -- either 'TRANSIENT', 'PERSISTENT', or 'UNKNOWN' (if REXX has not accessed it). If an error, return an empty string. SEEK <offset> READ CHAR Set the "read character position" to a new position. <offset> is that new position. This can be signed number if seeking backward/forward a specific number of characters from the current position. For example, -2 would seek two bytes less than the current position. To use the end of the stream as a reference point, preface the position with a < character. For example, <5 would set the read character position to 5 characters before the end of the stream. To use the start of the stream as a reference point, preface the position with a > character. For example, >10 would set the read character position to the tenth character in the stream. If successful, STREAM() returns the new "read character position" referenced from the start of the stream, where 0 is the first character in the stream. If an error, raises NOTREADY, and returns a non-numeric string. SEEK <offset> READ LINE Set the "read line position" to a new position. <offset> is that new position. This can be signed number if seeking backward/forward a specific number of lines from the current position. For example, -2 would seek two lines less than the current position. To use the end of the stream as a reference point, preface the position with a < character. For example, <5 would set the read line position to 5 lines before the end of the stream. To use the start of the stream as a reference point, preface the position with a > character. For example, >10 would set the read line position to the tenth line in the stream. If successful, STREAM() returns the new "read line position" referenced from the start of the stream, where 1 is the first line in the stream. If an error, raise NOTREADY and return a non-numeric string. SEEK <offset> WRITE CHAR Similiar to SEEK READ CHAR, except this sets the "write character position" to a new position. SEEK <offset> WRITE LINE Similiar to SEEK READ LINE, except this sets the "write line position" to a new position.
Returns
Depends upon option (and possibly command). See above.
Notes
If a NOTREADY condition is raised, your NOTREADY handler can use CONDITION('D') to return the name of the stream in error (and then use STREAM's 'D' option to fetch an informative error message).
It is best to explicitly open a stream with one of STREAM's OPEN commands, and then close it with STREAM's CLOSE command after you're done using the stream.
Reads in a numeric value from a binary (ie, non-text) file.
Synopsis
value = VALUEIN(stream, position, length, options)
Args
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names). If omitted, the default is to read from STDIN.
position specifies at what character position (within the stream) to start reading from, where 1 means to start reading at the very first character in the stream. If omitted, the default is to resume reading at where a previous call to CHARIN() or VALUEIN() left off (ie, where you current read character position is).
length is a 1 to read in the next binary byte (ie, 8-bit value), a 2 to read in the next binary short (ie, 16-bit value), or a 4 to read in the next binary long (ie, 32-bit value). If length is omitted, VALUEIN() defaults to reading a byte.
options can be any of the following:
Option Meaning M The value is stored (in the stream) in Motorola (big endian) byte order, rather than Intel (little endian) byte order. The effects only long and short values. H Read in the value as hexadecimal (rather than the default of base 10, or decimal, which is the base that REXX uses to express numbers). The value can later be converted with X2D(). B Read in the value as binary (base 2). - The value is signed (as opposed to unsigned). V stream is the actual data string from which to extract a value. You can now replace calls to SUBSTR and C2D with a single, faster call to VALUEIN.
If omitted, options defaults to none of the above.
Returns
The value, if successful. If an error, an empty string is returned (unless the NOTREADY condition is trapped via CALL method. Then, a '0' is returned).
Notes
Most REXX stream functions such as CHARIN() and LINEIN() assume that you'll be reading text (ie, ascii) files. So, for example, if the file contains the value 135, then it will actually contain the 3 ascii characters (ie, bytes) of '1', '3', and '5'. But some data files that you need to read may be binary files. For example, the 135 value may be stored as one, binary byte. VALUEIN() can be useful to read values from such a file since it automatically translates a byte, short, or long in the file to the equivalent REXX numeric string.
You may use the CHARS function to determine how many remaining characters are available to be read, before calling VALUEIN().
If the operating system has a problem reading from the stream, then this raises a NOTREADY condition.
After a call to VALUEIN(), you can use STREAM's 'D' option to return an informative error message as to the nature of any error that may have occurred. This will return an empty string if there was no error. Otherwise, unless you SIGNAL ON NOTREADY, it may be difficult to distinguish between an error occuring, or reaching the end of a persistent stream.
If a NOTREADY condition is raised, your NOTREADY handler can use CONDITION('D') to return the name of the stream in error (and then use STREAM's 'D' option to fetch an informative error message).
For a transient stream (such as STDIN):
You can't specify a position, or this raises a SYNTAX condition with an error number of 40.42.
If there are not as many characters available as how many required to return the value you have requested, then program execution may stop until the requested number of characters are available. Execution will resume when the requested characters are finally made available (or the user manually aborts which will raise a HALT condition). Otherwise, VALUEIN() may return an empty string and raise NOTREADY.
For a persistent stream:
If position is beyond the last character in the stream, then this raises a NOTREADY condition, and VALUEIN() will return an empty string.
If there are not as many characters available as how many required to return the value you have requested, then program execution may stop until the requested number of characters are available. Execution will resume when the requested characters are finally made available (or the user manually aborts which will raise a HALT condition). Otherwise, VALUEIN() may return an empty string and raise NOTREADY.
Examples
Example use | Return value |
VALUEIN('myfile', , 2) |
/* Reads the next short from 'myfile' */ |
VALUEIN('myfile', , 4, '-') |
/* Reads the next signed long from 'myfile' */ |
See also
Write out numeric values to a binary (ie, non-text) file (ie, in non-text format).
Synopsis
result = VALUEOUT(stream, values, position, size, options)
Args
stream is the name of the stream. It can include the full path to the stream (ie, any drive and directory names). If omitted, the default is to write to STDOUT (typically, display the data in the console window).
position specifies at what character position (within the stream) to start writing the data, where 1 means to start writing at the very first character in the stream. If omitted, the default is to resume writing at where a previous call to CHAROUT() or VALUEOUT() left off (or where the "write character pointer" was set via STREAM's SEEK).
values are the numeric values (ie, data) to write out. Each value is separated by one space.
size is a 1 if each value is to be written as a byte (ie, 8-bit value), 2 if each value is to be written as a short (16-bit value), or 4 if each value is to be written as a long (32-bit value). If omitted, size defaults to 1.
options can be any of the following:
Option Meaning M Write out the values in Motorola (big endian) byte order, rather than Intel (little endian) byte order. The effects only long and short values. H The values you supplied are specified in hexadecimal. B The values you supplied are specified in binary (base 2). V stream is the name of a variable, and the data will be overlaid onto that variable's value. You can now replace calls to D2C and OVERLAY with a single, faster call to VALUEOUT, especially when a variable has a large amount of non-text data.
If omitted, options defaults to none of the above.
Returns
0 if the string was written out successfully. If an error, VALUEOUT() returns non-zero.
Notes
See Saving a binary file.
If the operating system has a problem writing to the stream, then this raises a NOTREADY condition, and VALUEOUT() will return non-zero.
After a call to VALUEOUT(), you can use STREAM's 'D' option to return an informative error message as to the nature of any error that may have occurred. This will return an empty string if there was no error.
Program execution will stop until all requested data has been written to the stream (or the user manually aborts which will raise a HALT condition).
You can intermingle calls to VALUEOUT() with calls to CHAROUT(), upon the same string, if you wish to write out strings of ASCII characters intermingled with binary values.
If a NOTREADY condition is raised, your NOTREADY handler can use CONDITION('D') to return the name of the stream in error (and then use STREAM's 'D' option to fetch an informative error message).
For a transient stream (such as STDIN):
You can't specify a position, or this raises a SYNTAX condition with an error number of 40.42.
For a persistent stream:
If position is beyond the immediate end of the stream (ie, more than one character beyond the last character already in the stream), then this raises a NOTREADY condition and VALUEOUT() returns non-zero.
Examples
Example use | Return value |
VALUEOUT('myfile', 3000, , 2) |
/* Writes the value 3000 to 'myfile' as a short */ |
VALUEOUT('MyVar', '-1 3', 6, 4, 'V') |
/* Overwrite two long values of -1 and 3 starting at the sixth byte of MyVar's data */ |
See also