
Table of Contents
1. File Modes
1.1. Getting lists of applicable modes
1.2. Modes Available
1.2.1. File-modes
1.2.2. Port-modes
1.2.3. Network-modes
1.3. Using file forks
1.4. Finding all available forks
2. Files and Ports
3. Network Protocols
4. Data Series
4.1. Sort Function
4.1.1. Terminology
4.1.2. Arguments
4.1.3. Comparators
4.1.4. Comparison dialect
4.1.5. Examples
5. Math Related
6. Command Line
7. Mold and Load
7.1. Load/All
8. Console
9. Control
10. Interpreter
11. Objects
11.1. Make Object Object
11.2. Third Object
12. Serial Port Access
12.1. Specifying a Serial Port
12.2. Operation
13. Other Changes
GET-MODES and SET-MODES functions have been added for file and network ports. Two new port actions are introduced:
get-modes Return current modes for an open port. set-modes Change modes for an open port. The get-modes function has the following syntax:
The block being passed in consists of words defining which modes should be queried. Each word corresponds to one mode. get-modes returns a block which contains pairs of mode names and current mode settings.get-modes: native [ {Return mode settings for a port} target [file! url! block! port!] modes [word! block!] ]Example:
indicating that someport is opened in direct and non-binary (text) mode.>> get-modes someport [direct binary] == [direct: true binary: false]Alternatively a single word can be passed in, in which case get-modes returns the value directly, without putting it into a name-value block.
Example:
As another alternative a name/value-paired block can be passed in, of the same format as the block get-modes returns. In that case the values are ignored.>> get-modes someport 'binary == falseExample:
The set-modes function has the following syntax:>> get-modes someport [direct: none binary: none] == [direct: true binary: false]
The block being passed in consists of name-value pairs describing the modes to be changed. A block returned by get-modes can be passed as an argument to set-modes. set-modes returns the port that was passed as an argument.set-modes: native [ {Change mode settings for a port} target [file! url! block! port!] modes [block!] ]Example:
The mode block accepted by set-modes is actually an object-style initialization block and allows multiple names to reference the same value.>> set-modes someport [direct: false binary: false]Example:
>> set-modes someport [direct: binary: false]
get-modes supports a few "special" modes, which do not return mode settings for a specific port, but rather a set of modes that is applicable for a file (or directory, socket etc.). These are "file-modes", "copy-modes", "network-modes" and "port-modes". If any of these modes are specified in a get-modes request then the response contains a block of matching modes which are available on the current filesystem.
The above example is for an Amiga. Note that the mode block returned by any of these special requests is identical for all files and directories within a filesystem (and all sockets within a scheme), i.e. it varies per platform and possibly per filesystem and scheme, but not per file or socket. The purpose of this feature is only to provide a mechanism to obtain a list of supported modes, not to obtain the actual mode settings. To obtain the actual mode settings for a port the returned block has to be used in another call to get-modes:>> get-modes somefileordir 'port-modes == [direct binary lines no-wait (...a few more...) ] >> get-modes somefileordir 'file-modes == [file-note creation-date archived script (...a few more...) ] >> get-modes someudpsocket 'network-modes == [broadcast multicast-groups type-of-service]
The difference between "file-modes" and "copy-modes" is:>> get-modes somefileordir get-modes somefileordir 'file-modes == [file-note: "cool graphics" creation-date: 1-Jan-2000 archived: true script: false]
file-modes Return all modes of the underlying data (typically a file), regardless of how it was opened. copy-modes Same as file-modes, but only return those modes which are safe to copy, i.e. which can (and should) be included in a set-modes call when creating a new file, in order to create an exact clone of an existing file. If a platform provides file properties which are not safe to copy or which necessarily vary on copied files (e.g. Unix inodes) then those modes would show up in the block returned by file-modes, but not by copy-modes. Copying all file properties from file1 to file2 can be done with the following call:
>> set-modes file2 get-modes file1 get-modes file1 'copy-modes
1.2.1. File-modes
Platforms which only support a single file date export it via modification-date. Similarly, platforms which do not support multi-user file access modes make the file access modes available via owner-read/write/delete/execute.
- status-change-date, modification-date, access-date, backup-date, creation-date: REBOL date. modification-date is available on all platforms. status-change-date is available in Unix. access-date is available in Unix and Windows. creation-date is available in Windows and MacOS. backup-date is available in MacOS. All modes are settable and gettable, except that modification-date and access-date are not settable in Elate.
- owner-name, group-name: REBOL string (user/group name). Available in Unix.
- owner-id, group-id: REBOL integer (user/group id). Available in Unix and AmigaOS (>=V39).
- owner-read, owner-write, owner-delete, owner-execute, group-read, group-write, group-delete, group-execute, world-read, world-write, world-delete, world-execute: REBOL logic. All -read, -write and -execute modes are available in Unix, BeOS, QNX and Elate. owner-read, owner-write, owner-execute and owner-delete are available in AmigaOS. All group- and world- modes are available in AmigaOS >=V39. owner-write is also available in Windows (mapped to the inverse of the Windows "read-only" bit).
- comment: REBOL string (file comment). Available in AmigaOS only.
- script, archived, system, hidden, hold, pure: REBOL logic (additional flags). Script, hold and pure are available in AmigaOS only. Archived is available in AmigaOS and Windows. System and hidden are available in Windows only.
- type, creator: REBOL string. Available in MacOS only.
1.2.2. Port-modes
- read, write, binary, lines, no-wait, direct: REBOL logic. Binary, lines and no-wait are settable.
1.2.3. Network-modes
- broadcast: REBOL logic. UDP only. Setting this to true allows sending broadcasts from a socket. All platforms except BeOS.
- multicast-groups: REBOL block of blocks. UDP only, describes which multicast groups a socket has joined. Each sub-block consists of two IP addresses (tuples): the multicast group and the IP address of the interface on which the multicast group was joined. Typically available in MacOS, Windows, most Unix platforms, QNX and AmigaOS (Miami/MiamiDx only). Availability is determined at runtime and varies with the OS version and TCP/IP protocol stack version.
- type-of-service: REBOL integer. UDP and TCP. This is the value of the 8-bit "TOS" field in IP headers. Typical values are 0 (default), 2 (minimize cost), 4 (maximize reliability), 8 (maximize throughput) and 16 (minimize latency), but the interpretation of this field is up to the TCP/IP stack and intermediate routers, and not enforced by REBOL. All platforms except BeOS.
- keep-alive: REBOL logic. TCP only. Setting this to true forces TCP to send "keep-alive" packets after a certain period of time (typically 4 hours). All platforms except BeOS.
- receive-buffer-size, send-buffer-size: REBOL integer. UDP and TCP. Size of receive and send buffer within the TCP/IP stack. Default values and allowed ranges vary widely between platforms. Primarily useful for UDP. Increasing this values usually does NOT improve performance. All platforms except BeOS.
- multicast-interface: REBOL string. UDP only. The default interface to use for multicasting. Same platforms as multicast-groups.
- multicast-ttl: REBOL integer. UDP only. The time-to-live value (maximum propagation distance) of multicasts. Same platforms as multicast-groups.
- multicast-loopback: REBOL logic. UDP only. If set to true sent multicasts are looped back to the local socket. Same platforms as multicast-groups.
- no-delay: REBOL logic. TCP only. Disables the Nagle algorithm. Most protocols perform better if this is set to false. It should only be set to true if a protocol is interactive in nature AND relies on precise event timing in combination with queueing (e.g. X11). All platforms except BeOS.
- interfaces: REBOL block of objects. Each object represents one network interface and currently contains the following fields: "name": interface name (on some platforms this is a dummy name). "address": local IP address. "netmask": subnet mask. "broadcast": broadcast address. "remote-address": remote IP address for point-to-point interfaces. "flags": a block of words describing interface properties, currently supported words are "broadcast" (interface supports broadcasting), "multicast" (interface supports multicasting), "loopback" (interface is the loopback interface) and "point-to-point" (interface is a point-to-point interface, as opposed to a multi-drop interface). Some values may be none (e.g. "remote-address" on a multi-drop interface). In Windows all interfaces appears as multi-drop (including PPP), with dummy netmasks. Available in all platforms, except BeOS, Elate, WinCE. Not settable.
The /custom refinement to read, open and write allows access to different forks of a file (currently useful for MacOS only).
The specified fork name defines which fork to open:open/custom %myfile [fork "name"] ; Specify which fork to open.If no fork is specified (no fork specifier in the custom block or none is passed instead of "name"), then for non-Mac platforms the file is opened normally. For Mac the data fork is opened. If the /new refinement is used then the file size is reset to zero bytes. For Mac this means that all forks are reset to zero bytes. (Note: this behavior has changed from Core 2.3. Previously open/new on Macintosh would only reset the size of the data fork, and there was no way to reset the size of the resource fork.)
If a fork is specified by name then that fork is opened. If the /new refinement is used then the size of only that fork is reset to zero bytes. If the fork does not exist (and, for write access, cannot be created) on the current filesystem then an error is thrown.
Non-Mac platforms only have a single fork named "data". Mac platforms have two forks, named "data" and "resource".
This is done using the mode mechanism, in a way similar to finding all supported modes.
Example above on Mac. For all other platforms only ["data"] would be returned.>> get-modes somefile 'forks == ["data" "resource"]
- Added asynchronous wait-able DNS for Unix and Windows. For example: open dns:///async, then insert/wait/copy.
- Asynchronous HTTP better supported. You can open/direct/no-wait an HTTP request and use WAIT and COPY to receive the results as they arrive.
- WAIT [0 port] now returns the port if it has data, none otherwise.
- Added WAIT/all refinement, which causes wait to return a block of all ports that have data.
- The /no-wait refinement allows a port to be opened in non-blocking mode. COPY on a non-blocking port returns an empty string unless the end of the port has been reached, in which case it returns none.
- WAIT now supports port handlers (http, tcp etc.) in /direct mode.
- Added AWAKE field in port-specs and root protocol to specify a block or function called when wait is about to wake up. Used to implement background processing.
- WAIT works correctly on /lines ports opened without /with.
- TO-LOCAL-FILE and TO-REBOL-FILE functions can be used to convert to and from the local OS file path formats.
- Added local-port, remote-ip and remote-port fields to port spec for consistent values independent of port creation.
- MAKE-DIR/deep creates all needed directories in a long path.
- CONNECTED? native for most platforms.
- Fixed incorrect port-id assignment on accepted sockets.
- Fixed bug that would prevent UDP listen sockets from responding to packets from different origins.
- SPLIT-PATH was modified to properly split the path and target of a file path.
- Added APOP - Authentication for pop:// that does not send passwords to the server in clear text.
- Added imap:// protocol. URL format and behavior identical to pop://, plus additional URL formats specified in RFC 2192.
- Fixed SEND when /header and no FROM address is given
- Fixed do-send to change email lines with only a single "." to have two periods so those emails will not blow out anymore.
- HASH! and LIST! datatypes now offer more complete, consistent, reliable, and faster operation.
- The SELECT, FIND, UNION, INTERSECT, EXCLUDE, DIFFERENCE, and UNIQUE functions accept a /skip refinement to specify data size.
- UNIQUE accepts the /case refinement.
- TO-BINARY of tuples now uses the tuple values instead of forming the tuple.
- JOIN on binary values now joins as binaries, not FORMed strings.
- FIND now works on all types of functions properly.
- FIND/REVERSE works for bitsets.
- Pick on objects and functions with negative number fixed.
- Fixed bug in ENBASE that could cause invalid characters to be inserted into a base-64-encoded string.
- Removed /only refinement from DIFFERENCE (EXCLUDE is equivalent).
- MINIMUM-OF and MAXIMUM-OF series. You can use MINIMUM-OF and MAXIMUM-OF on a single series argument which will return the series offset to the least or greatest contained value respectively. Eg:
minimum-of reduce [pi .099 10 * 100] == [0.099 1000] maximum-of reduce [pi .099 10 * 100] == [1000]
Several changes and additions have been made to SORT to add functionality, including reverse sorting, hierarchical sorting (sorting on more than one field), sorting of only part of a series, stable sorting (items that are "equal" are not swapped during sorting), and easier specification of sort criteria (without the need for a custom comparator function). The new SORT function is fully backward-compatible.
4.1.1. Terminology
Record A single logical item in the series to sort. Usually a character if the series to sort is a string, or a value if the series to sort is a block. If the /skip refinement is used then a record consists of multiple, consecutive elements in the series. Field A part of a record. With the /skip refinement and a skip length of n a field is one of n elements in the record. If the /skip refinement is not used and the series to sort is a block which contains sub-blocks, then a field is one item of a sub-block (NOT the complete sub-block). This allows field-wise sorting of blocked records. In all other cases a field is identical to a record (i.e. each record has exactly one field). Field offset An integer specifying the offset of a field within a record. For a record consisting of n fields a field offset can be between 1 and n.
4.1.2. Arguments
In addition to the series to sort, the new sort action accepts the following refinements. New behavior is marked with [NEW].
/case Sort case-sensitive. This only has an effect for fields of type string or character. /skip size Treat series as records of fixed size. size is of type integer. /all Used in combination with the /skip refinement. [NEW] By default only a single field in a record is used for comparison. If the /all refinement is used then all fields in a record are used for comparison. /compare comparator Specify a custom comparator. This can be a field offset (type integer [NEW]), a comparator function, or a comparator block [NEW]. See below. /reverse Sort in reverse. [NEW] /part size Sort only part of a series. (Similar to the use of the /part refinement in copy or change [NEW]).
4.1.3. Comparators
Sorting is performed by comparing and swapping elements, i.e. comparators define the sort order. The following comparators are supported:
- No comparator (i.e. no /compare refinement). In this case the first field in each record is used for comparison. If the /all refinement is used then all fields in each record are used for comparison. /case and /reverse are observed normally.
- Field offset (integer) [NEW]. Specifies the field to use for comparison. If the /all refinement is used as well then the specified field is the first field to use, and all subsequent fields are used as well. /case and /reverse are observed normally.
- Function. Function called by the sort action to compare two records. The records are passed as arguments, and the function needs to return -1, 0 or 1, if the first record is smaller than, equal to or greather than the second record, respectively. [NEW] For backward compatibility the function may also return true or false, where true indicates that the first record is less than or equal to the second record, and false indicates that the first record is greater than the second record. /case is ignored. /reverse is observed normally, i.e. /reverse inverts the meaning of the comparator function. If the /skip refinement is used then the argument passed to the comparison function only consists of the first field in the record, not the complete record. This is for backward compatibility with the old sort function. In order to pass the complete record, in a block, use the /all refinement.
- Block [NEW]. Comparison dialect specifying the type of comparison in more detail. See below.
4.1.4. Comparison dialect
The following items can appear in a comparison block:
field offset (integer) Specifies the offset of the next field to compare. Fields are compared in the order specified. reverse (word) Sets the comparison for all subsequently specified fields to reverse. forward (word) Sets the comparison for all subsequently specified fields to forward (opposite of reverse). case (word) Makes the comparison for all subsequently specified fields case-sensitive. no-case (word) Makes the comparison for all subsequently specified fields case-insensitive (opposite of case). to (word) field offset (integer) Specifies a range of fields to compare, e.g. [1 to 5] compares fields one to five. With comparison blocks the /all, /case and /reverse refinements slightly change their behaviors: /all is equivalent to adding "to max-field" to the end of the comparison block, i.e. when the end of the comparison block is reached comparison continues until the end of the record is reached. /case specifies that the default case mode (until a case or no-case word is reached) is case-sensitive. Otherwise it is case-insensitive. /reverse reverses the resulting list as a whole, and is independent of the reverse/forward words in the comparison block.
4.1.5. Examples
>> a: [10 "Smith" "Larry" 20 "Smith" "Joe" 80 "Brown" "Harry" 50 "Wood" "Jim"] >> sort/skip a 3 ; sorts on the first field (number) == [10 "Smith" "Larry" 20 "Smith" "Joe" 50 "Wood" "Jim" 80 "Brown" "Harry"] >> sort/skip/compare a 3 2 ; sorts on the second field (last name) == [80 "Brown" "Harry" 10 "Smith" "Larry" 20 "Smith" "Joe" 50 "Wood" "Jim"] >> sort/skip/compare/all a 3 2 ; sorts on the second field and following fields (last name and first name) == [80 "Brown" "Harry" 20 "Smith" "Joe" 10 "Smith" "Larry" 50 "Wood" "Jim"] >> sort/skip/reverse a 3 ; sorts on the first field (number), in reverse == [80 "Brown" "Harry" 50 "Wood" "Jim" 20 "Smith" "Joe" 10 "Smith" "Larry"] >> sort/skip/compare a 3 [2 reverse 3] ; sorts on the last name forward, and the first name in reverse == [80 "Brown" "Harry" 10 "Smith" "Larry" 20 "Smith" "Joe" 50 "Wood" "Jim"]
- Added CHECKSUM/secure and RANDOM/secure, producing cryptographically secure checksums and random numbers respectively.
- Added CHECKSUM/hash and CHECKSUM/method (same as checksum/secure, but with a selectable algorithm: 'md5 or 'sha1), and checksum/key (calculates a keyed message digest). MD5 added as an alternative checksum algorithm.
- Subtraction of a date! value months bug fixed.
- The >, >=, <, <= functions have been removed from the pair! datatype. They lead to hard-to-find errors.
- Time! values can convert to integers and decimals.
- NOW/precise returns greater precision on time. Useful for timing events.
- REBOL startup command line now accepts "--" to signal the end of startup switches. Remaining items on the command line are arguments to be passed to the REBOL script. This also allows REBOL to start without a script but with arguments passed.
- When starting from the command line, system/script/args == string of all args, system/options/args == block of separate args. All items following the specification of the script are considered arguments.
- REBOL now deals with arbitrary amount of command line arguments-- no fixed size.
- MOLD/only does not produce the outermost [] in the resulting string.
- Molding a recursive block or object will print [...] when on the second instance of the recursive item. So, you can now PRINT MOLD SYSTEM !
- Molding strings greater that 50 characters containing unbalanced "{" characters are now reloadable.
- LOAD/next/header results in a block with the evaluated header followed by the rest of the script as a string.
- Loading strings with CTRL chars greater than CTRL-Z now allowed.
- Added script HEADER/CONTENT field. When set TRUE, the script's entire source text can be accessed from SYSTEM/SCRIPT/HEADER/CONTENT (when evaluated with DO) or from the header object (when loaded with LOAD/header or LOAD/next/header). This allows your script to access other data that may be part of its script file (e.g. the REBOL archive format, RIP).
Added /all refinement to LOAD. LOAD/all of a script does not evaluate the REBOL header. LOAD/all always returns a block.Load function refinement precedence:
The ALL refinement will be ignored when other refinements are present. Previous table shows the current behavior of the various refinement combinations with LOAD.Evaluate Returns Header? (pseudo example) ----------------------------------------------------------------------------- load yes header-obj [rest of script] load/next no [first-val { rest of script }] load/next/header yes [header-obj {rest of script}] load/header yes [header-obj rest of script] load/all no [all of script as data] load/next/all no [first-val { rest of script }] load/header/all yes [header-obj rest of script] load/next/header/all yes [header-obj {rest of script}]
- Console tab completion now completes as much of the defined word or file path as possible.
- Added proper console reinitialization code when REBOL is woken up after Ctrl-Z followed by "fg" (for Unix and shells with job control).
- File name completion in the console is now case-insensitive for operating systems that have case-insensitive file systems (Windows, AmigaOS etc.)
- Screen now gets cleared on first console output, not signon message.
- A BREAK used in the first block of a WHILE will cause a BREAK from the while loop.
- CATCH and THROW work more reliably in more cases.
- FOREACH returns correct value on empty series.
- Binding speed greatly improved for top-level words.
- Indefinite extent fixed for many cases. Use.
- SYSTEM/LOCALE object added. Currently has month and day names. *Weekdays are separate strings in system/locale/days.
- CONTEXT function added as a shortcut to MAKE object!.
- You can now QUERY an object. QUERY will return a block containing the fields that have been modified in an object since its creation or since it was last passed to QUERY/clear. QUERY will return none if there have not been any changed fields. QUERY/clear will clear the modified state of all the fields in an object.
- Objects now accept LOGIC! values as arguments for to pick (for consistency with blocks).
You can now make an object out of two other objects, a "template object" and a "spec object". When making a new object out of two other objects, the bindings of words coming only from the "spec object" will be maintained, words shared by both the template object and the spec object will take their values from the spec object. This will cause some differences in behavior because the block spec approach is lexical and the object spec approach is definitional.
You can use THIRD on the object to get back a block of set-word value pairs from the object:
The block returned from THIRD on an object is like an object spec block, however the set-words are bound to their object. This block is like a snapshot of the object's values at that time. You can also use the returned block to set values in the object:z: make object! [a: 99 b: does [a + 1]] t: third z == [a: 99 b: func [][a + 1]]
set first t 199 z/b == 200
This specification describes the creation and operation of serial communication ports within REBOL. Serial ports were supported in version 2.3 but were not documented.
Serial ports are created in the same manner as other ports within REBOL. The scheme name for serial ports is "serial:". The specification of a serial port may include the device number, the communication speed, the number of data bits, the parity and number of stop bits. The specification information can be specified directly by setting the appropriate fields within the port specification object or by creating a URL which contains the same information. Any field not specified will be given a default value.The default serial port settings are:
URL's are encoded with the different fields separated by slashes. For example,device: port1 speed: 9600 data-bits: 8 parity: none stop-bits: 1
The order of fields is not significant, as the type of field can be determined by the content.serial://port1/9600/8/none/1Within a port specification, the various parameters are stored in the following object fields:
The portN specification is an indirect reference to the communication device. It refers to the Nth device defined in the System/ports/serial block. This block is initialized by default depending on the system being used and can be modified in user.r to reflect any local requirements.host: device speed: speed data-bits: data bits parity: parity stop-bits: stop bitsFor example, on Windows the block might be defined as:
or if COM1 is being used by the mouse, it might just be:System/ports/serial: [ com1 com2 ]
On unix-style systems, the block might be defined as:System/ports/serial: [ com2 ]
or if the first device should correspond to COM2:System/ports/serial: [ ttyS0 ttyS1 ]
Thus, the ports can be specified in a machine indpendent manner while the machine specific definition can be controlled using the serial definition block in System/ports/serial.System/ports/serial: [ ttyS1 ttyS0 ]
Serial ports are always opened as direct ports in much the same way as console and network ports. They may be opened as either /STRING or /BINARY with the default being /STRING. They are opened by default as asynchronous, but may be made synchronous by using the /WAIT refinement. When operating asynchronously, any attempts to copy data from the port will return NONE if no data is present. When operating synchronously, the copy will block until data is available.Data can be written to the port using the INSERT native. Data can be read from the port using the PICK, FIRST or COPY natives with the usual ramifications. As usual with direct ports, the REMOVE, CLEAR, CHANGE and FIND functions are not supported.
The UPDATE function can be used to change port parameters. For example, to change the speed after an initial connection has been established, you could just do:
Changing the device number or the System/ports/serial and calling UPDATE will have no effect. Once the port has been opened with a particular device, the device can't be changed.ser-port: open serial://9600 ser-port/speed: 2400 update ser-portThere are two additional port fields that can't be set with a URL, but can be set in a port specification block or by manually changing them. The RTS-CTS field specifies whether hardware handshaking should be used on the port. The default is ON. To change the default, do:
A timeout value can be specified by modifying the timeout field in the port structure. The timeout value only applies to serial ports that are opened with the /wait refinement. When the timeout expires, a serial port timeout error will be generated. To set the timeout value do:ser-port/rts-cts: off update ser-port
Serial ports work properly with the WAIT native.ser-port/timeout: 10 ; 10 second timeout
- HAS function added as a shortcut to define functions with local variables but no arguments.
- Fixed CONFIRM to throw error on bad pick operation.