Tuesday May 7, 2024

dL4 for Windows Runtime 11.3 Release
All Rights Reserved.  Copyright (c) 1997 - 2022 by:
Dynamic Concepts, Inc. Irvine, CA 92618 USA


Email address:  techsupport@dynamic.com
Information:    www.dynamic.com
Downloads:      ftp.dynamic.com


Pre-installation instructions
=============================

o   WARNING: This release will NOT run with existing SSNs that use a 
    license number that begins with "FE".  These obsolete SSNs include 
    almost all SSNs created before December 2001.  Please contact the 
    Dynamic Concepts Sales department for information on replacing SSNs 
    that use "FE" license numbers.  Please read the following Passport 
    section for additional licensing information.

o   This release requires the use of Passport for Windows 2.2 or later.
    Passport for Windows requires the presence of an ethernet interface.
    SSNs for Passport 2.1.3 or later are machine specific and must not be
    installed on more than one system.  Unlike previous versions of dL4 for
    Windows, the number of simultaneous dL4 sessions will be restricted to
    the licensed number of users plus three phantom ports or extra window
    sessions.

o   This release requires an SSN authorized for release 11 of dL4.  In order
    to use the SQL, MySQL, Oracle, or Microsoft SQL Server drivers, the SSN
    must be authorized for the SQL driver option.  Please contact the Dynamic
    Concepts Sales department for information on obtaining required SSNs.

o   To use the Oracle SQL driver, the Oracle runtime libraries from Oracle
    must be installed.  The libraries are NOT needed to use scope or run
    if the Oracle SQL driver is not used. These libraries can be found in 
    Oracle "Instant Client" package for Windows that can be downloaded from
    oracle.com.  The libraries must be placed in the dL4 installation directory
    (usually "\Program Files\dL4") or the full path of the Oracle library
    directory must be added to the PATH environment variable.

o   To use the MySQL SQL or MySQL Full-ISAM drivers, the MySQL runtime library
    libmySQL.dll from MySQL must be installed.  The library is NOT needed to
    use scope or run if the MySQL drivers are not used.  The library must be
    placed in the dL4 installation directory (usually "\Program Files\dL4") or
    the full path of the MySQL library directory must be added to the PATH
    environment variable.

o   Problem reports should be emailed to techsupport@dynamic.com.  All problem
    reports should contain a description of the problem, the operating 
    system name/revision, and, if at all possible, a reproducible sequence 


Installation instructions
=========================

To install dL4 for Windows, perform the following steps:

    1. If the dl4login network login service is installed, then, before
       updating dL4, all users must log off and the dl4login service must be
       stopped.  The command "net stop dl4login" can be used at a command
       prompt to stop the dl4login service.

    2. Remove any previous dL4 for Windows release.

    3. Run the dL4 installation program 1B_dl4_11.3.exe and follow the 
       displayed instructions.  Press "Yes" when the program asks if 
       Passport should be installed.

    4. If you haven't registered your license and SSN using the 
       Passport ssnmaint utility, run ssnmaint.  dL4 cannot be 
       used until Passport is installed and your license 
       registered.

    5. If you intend to use loadsave.exe, add the installation 
       directory to your PATH variable.  

    6. If data files will be accessed over a network, run checksys.exe
       from the installation directory to detect out-of-date or
       misconfigured operating system modules.  The checksys utility
       should be run on each Windows client system and each Windows
       file server in the network.  See the "Networking" section below 
       for details.


Installation instructions for dL4Login
======================================

    dL4 for Windows includes an optional telnet-like service which makes
    it possible to run dL4 applications on a Windows server from thin
    clients that run dL4Term.  The server must use Windows 2000 or later.
    To install the service, perform these steps:

    1. Install dL4 for Windows as described in the previous section.

    2. Using an administrator account and a command line prompt, run the
       script "instlogn.bat" in the dL4 installation directory (which is
       usually "C:\Program Files\dL4"):

         cd \Program Files\dL4
         instlogn.bat <ip-address> <port> <domain> <profile-dir>

       where

         <ip-address> is the IP address of the server
         <port> is the TCP port number to be used
         <domain> is the Windows domain defining the user accounts
         <profile-dir> is the full path of the user profile directory

       For example,

         instlogn.bat 192.168.0.5 23 %COMPUTERNAME% c:\dL4Profiles

       For systems that do not use Windows domains, the domain name is the
       name of the server.  If port 23 is used, any existing telnet service
       must be disabled.  Systems that have software firewalls may require
       reconfiguration of the firewall to accept connections to the
       selected port number.

       The command window must be run in administrator mode (use a 
       "right click" and select administrator mode).

    3. Each user of the dl4login service must have an account with local
       logon privileges on the Windows server.  A text file must also exist
       in the profile directory for each user with the name "u_name" or
       "u_name.txt" where "name" is the Windows user id.  This file defines
       user specific environment variable values.  Each line of the file
       must be either a SET command, an INCLUDE command, or a comment line
       as shown below:

         set <variable-name> = <value>
         include <filename-in-the-profile-directory>
         ; comment text

       An INCLUDE file is a text file containing SET, INCLUDE, or comment
       lines.  Each user profile must define the values HOMEPATH and 
       COMMAND via SET commands or INCLUDE files.  The HOMEPATH value
       defines the initial directory when a user logs onto the system.  The
       COMMAND value defines the program which will be executed when the
       user logs in.  The following is a typical user profile:

         set HOMEPATH=C:\Users\username
         set TERMDIR="C:\Program Files\dL4\Term"
         set TERM=dl4term
         set LIBSTRING=C:\AppDir
         set LUMAP=Data=C:\AppData
         set COMMAND="C:\Program Files\dL4\runc.exe" mastermenu.dl4

       On 64-bit versions of Windows, use "\Program Files (x86)" instead
       of "\Program Files".

       If a SCOPE command line login is desired, set the value of COMMAND
       to scope.exe:

         set COMMAND="C:\Program Files\dL4\scopec.exe" -noshell

       Note that the scopec "-noshell" option is added to prevent users
       from trying to start non-dL4 programs such as "Word" which cannot
       be used via dL4Login.  On 64-bit versions of Windows, use
       "\Program Files (x86)" instead of "\Program Files".  Once dL4Login
       is installed and user profiles have been created, users can login by
       connecting to the server with dL4Term using the IP address and port
       specified in the instlogn.bat command.  A port number is specified
       in dL4Term by connecting to "server:port" instead of simply "server".

       The dL4Login user profile supports an optional REALUSERID value.  If
       defined, the value is used as the actual login id.  This feature can
       be used to implement alternate user profiles with different
       environment variable values for the same actual login id.  The user
       must login using the name of the user profile file (without the "u_"
       prefix).  For example, a profile named "u_fredacctg" with the line

           set REALUSERID=fred

       could be created for the user "fred" to start an accounting
       application.  To login, "fred" would type "fredacctg" as his login
       id along with his normal password.

       Before using dL4Login, please check your Windows server license to
       be certain that you are in compliance with Microsoft user license
       rules.  Servers may need special configuration options to support
       more than 10 simultaneous connections via dL4Login.


Acknowledgements
==========================

This product includes software developed by the OpenSSL Project for use
in the OpenSSL Toolkit (http://www.openssl.org/).  The OpenSSL license
file and copyright notice is included in the file credits.txt.


File list
=========

readme.txt          This file
license.txt         Runtime license terms and conditions      
credits.txt         OpenSSL license and copyright information
checksys.exe        Utility to detect operating system configuration 
                    problems
codebase.dll        Runtime library
dcictree.dll        Runtime library
dl4basic.dll        Runtime library
dl4chwin.dll        Runtime library
dl4fldrv.dll        Runtime library
dl4login.exe        Network utility to provide telnet-like remote access to
                    a Windows server.
dl4pipe.exe         Internal utility used by the pipe driver
dl4rt.dll           Runtime library
dl4servr.exe        Network service utility to run a dL4 program whenever a
                    TCP connection is made to a specific IP address and 
                    port number.
dl4sockt.dll        Runtime library
dl4stdrv.dll        Runtime library
doc\                Miscellaneous driver documentation.
instlogn.bat        Batch script to install the dl4login remote access service.
loadsave.exe        dL4 compile-and-save console program
makeres.exe         dL4 utility to compile resource files
msvcr100.dll        Runtime library
pfilter.exe         Printer character translation filter
runc.exe            Special version of BASIC interpreter for CGI programs
                    and piped I/O
runw.exe            BASIC interpreter
scopec.exe          Special version of dL4 IRIS-style command interpreter 
                    for CGI programs and piped I/O
scopew.exe          dL4 IRIS-style command interpreter 
testlock.exe        Record lock testing utility
dfltlp.bat          Printer script for default Windows printer
selectlp.bat        Printer script for user selected Windows printer
printer\            Directory of printer scripts
term\               Directory of terminal definition files for use with
                    scopec.exe and runc.exe
tools\              Various utilities


Highlights of This Release
==========================

o   The DL4ABENDDUMP environment variable can be set to produce program
    dumps when programs exit with an uncontrolled error or a STOP statement
    while executing from the "run" utility.

o   Huge Plus files support indexed contiguous files with terabyte indexes.

o   Huge+ files on 64-bit platforms support up to 4 billion records.

o   The socket and TLS/SSL socket drivers support IPv6 addresses.


New in This Release
=================================================================

May  7, 2024 (Release 11.3)

o   A new driver, "Huge Full-ISAM", has been added to support Full-ISAM files
    larger than 2 gigabytes.  A Huge Full-ISAM file can be as large as 256
    gigabytes and can have more than 2 billion records.  Huge Full-ISAM
    files have behavior compatible with FoxPro Full-ISAM files and are 
    created in the same way except that the driver name is "Huge Full-ISAM".
    A Huge Full-ISAM file consists of a data portion ("filename") and an
    index portion ("filename.idx").  Unlike FoxPro Full-ISAM files, Huge 
    Full-ISAM files do not require that the data portion have an extension 
    of ".dbf".  Huge Full-ISAM files can be encrypted if created with 
    "<N=''key''>" (see the description of encrypted Indexed-Contiguous file
    for more information about encryption keys).

    Examples:

        BUILD #1,"filename" As "Huge Full-ISAM"
        Define Record #1;CustomerRec.
        Add Index #1,1;Key1.

        BUILD #1,"<N=''keyname''> filename" As "Huge Full-ISAM"

o   The default value of ISAMSECT has been increased from 8 to 16 to support
    larger indexes in Huge Full-ISAM and Huge Indexed-Contiguous files.

o   "Preferences" dialogs use larger fonts if the window font is larger than
    the system font and the enlarged dialog still fits within the window.

o   A new utility, tools/rebuild, has been added to rebuild indexes in
    Full-ISAM files.

o   The "-s" option in tools/query, which outputs DEF STRUCT source code
    for Full-ISAM records and indexes, now adds sample code to build an
    empty file duplicating the structure of the selected Full-ISAM file.

o   The directory and sorted directory drivers now support a charset open
    option.

o   The tools/keymaint utility now supports longer file paths.

o   The tools/keymaint utility now has an "S" command to scan for all keys
    pointing at the selected record number.  In addition, the record number
    field width has been increased from 7 to 9 digits.  File paths beginning
    with "/" are no longer converted to uppercase.

o   The email driver now supports a "MSGID" open option to add a "Message-ID"
    line to the email header when desired.

o   Two new standard intrinsic functions, SHA384? and ADDSHA384?, have been
    added to dL4.  SHA384?() returns the SHA384 checksum of the first argument.
    The argument must be either a binary or a string value.  An optional second 
    binary argument can be used to pass an intermediate value from a previous
    call to ADDSHA384?().  This allows a combined checksum of multiple values
    to be calculated.  Checksums are calculated against the DIMmed size of 
    strings so that zero characters can be included in the checksum.  To 
    avoid this, simply pass strings with subscripts.  So that string values 
    will produce the same checksums on all platforms, each UNICODE character 
    of a string is forced into a most-significant-byte first ordering for 
    calculation.  To use the SHA384 functions, the encryption option must be
    enabled in the SSN for dL4.

    BASIC syntax:

        Dim chksum?[48], intermediate?[512]

        chksum? = SHA384?(var)
        chksum? = SHA384?(var,intermediate?)

        Clear intermediate?
        intermediate? = AddSHA384?(var)
        intermediate? = AddSHA384?(var,intermediate?)

o   Two new standard intrinsic functions, SHA512? and ADDSHA512?, have been
    added to dL4.  SHA512?() returns the SHA512 checksum of the first argument.
    The argument must be either a binary or a string value.  An optional second 
    binary argument can be used to pass an intermediate value from a previous
    call to ADDSHA512?().  This allows a combined checksum of multiple values
    to be calculated.  Checksums are calculated against the DIMmed size of 
    strings so that zero characters can be included in the checksum.  To 
    avoid this, simply pass strings with subscripts.  So that string values 
    will produce the same checksums on all platforms, each UNICODE character 
    of a string is forced into a most-significant-byte first ordering for 
    calculation.  To use the SHA512 functions, the encryption option must be
    enabled in the SSN for dL4.

    BASIC syntax:

        Dim chksum?[64], intermediate?[512]

        chksum? = SHA512?(var)
        chksum? = SHA512?(var,intermediate?)

        Clear intermediate?
        intermediate? = AddSHA512?(var)
        intermediate? = AddSHA512?(var,intermediate?)

o   The intrinsic CALL RSASign() now supports SHA384 and SHA512 checksums.

o   Bug fixed: the "Terminal File Printer" driver would not write to a file
    name containing multiple periods or various special characters.

o   Bug fixed: a memory violation occurred in the ODBC SQL driver when
    closing the channel after performing a query that returned more than
    13383 rows.

o   Bug fixed: concatenating a number or a date to a string in a LET
    statement or with an assignment operator caused memory corruption or
    segment violation faults if the destination was too small.  This
    did not occur if the destination used double subscripts.

Oct 21, 2022 (Maintenance Release 11.2.3)

o   The tools/port utility now displays user names rather than user numbers
    when the "LIST" or "MU" options are specified.  Example:

        tools/port all mu

o   Bug fixed: auxiliary printing to devices did not work on Windows 11.

Jun 15, 2022 (Maintenance Release 11.2.2)

o   The 'WCTIPTEXT' mnemonic has been enhanced to control the display time
    of tip text "balloons".  The mnemonic string PChr$(1,TenthSecs)+'WCTIPTEXT'
    changes the display time "TenthSecs" tenth seconds.  The maximum
    display time is limited to 32 seconds by the Windows operating system.

o   The OpenSSL library has been updated to version 1.1.1o.

o   Various driver related documentation files are now provided in the 
    "dl4\Doc" directory.

o   Behavior change: in DECIMAL8 display mode, printing "\x7f\" (the DECIMAL8 
    and DECIMAL9 lead in character) is now ignored if the trailing value is 
    illegal.

o   Behavior change: CALL FINDF() no longer reports a file as existing if
    an intermediate directory is inaccessible.

o   CALL MONITOR() in tools/oldcalls.lib has been enhanced to match new
    features in unibasic.

o   Bug fixed: switching to 132 column mode ('NR') when the window was too
    close to the right side of the display cause the window to move too far
    to the left and moved further left with the next change to 132 column
    mode.

o   Bug fixed: adding a new variable to a running program in the debugger
    corrupted the runtime variable table.

Dec  1, 2021 (Maintenance Release 11.2.1)

o   Two new intrinsic CALLs, DECIMAL8 and DECIMAL9, have been added to
    convert integer values to and from compressed string formats.  The
    DECIMAL8 format supports 12 decimal digit integers in an 8 character
    field while the DECIMAL9 formats supports 14 digits in 9 characters.
    Both formats store values as readable decimal strings if possible.  If 
    used in an indexed file key, the string values will sort according to
    the integer value.
    
    The DECIMAL8 and DECIMAL9 formats simplify changing applications and  data
    files to support a larger range of values.  When output to dL4 Term  11.3
    or later, DECIMAL8 and DECIMAL9 format strings can be automatically
    converted to readable decimal numbers with the font width adjusted to 
    fit into 8 or 9 columns.  This output behavior is enabled by the new 
    'DECIMAL8' mnemonic (Unicode xF21D) which can be output by an application 
    or the initialization strings of a dL4 or uniBasic terminal definition
    file.  The DECIMA8 and DECIMAL9 formats are supported by uniBasic 11.2.5
    and ODBCdL4 Server 1.8.4.

    BASIC syntax:

        Call Decimal8(NumExpr, StringVar$$)
        Call Decimal8(StringExpr, NumVar)

        Call Decimal9(NumExpr, StringVar$$)
        Call Decimal9(StringExpr, NumVar)

    CALL DECIMAL8() and CALL DECIMAL9() convert the numeric expression value
    'NumExpr' storing the result in the string variable 'StringVar$' or
    convert the string expression 'StrExpr' to the numeric variable 'NumVar'.
    The strings are 8 characters long for DECIMAL8 and 9 characters long for 
    DECIMAL9.  The numbers must be non-negative integers.  The source strings
    must be exactly 8 or 9 characters long.

    The compressed string format uses zero filled decimal for values when 
    possible.  For example, "CALL DECIMAL8(123,S$)" would store "00000123"
    in the variable S$.  If the number is too large to fit in decimal format,
    the number is stored as 8 or 9 character base 62 number with leading 
    zeroes and a leading character of 0x7f.  Base 62 digits are represented 
    by the characters 0-9, A-Z, and a-z.  The second character of the 
    compressed format for DECIMAL9 uses characters W-Z and a-z for the 
    base 62 digit to distinguish the 9 character format from the 8 character 
    format.

    CALL DECIMAL8() and CALL DECIMAL9() can generate the following errors:

        208  -  The parameter list is incorrect or a destination string 
                variable is too small.

        15   -  The converted string contains a number which is too large 
                to be stored in the destination numeric variable.

        15   -  The source numeric expression is negative or is too large 
                to be converted.

        98   -  The source string contains an improperly formatted number.

o   A new mnemonic, 'RFONTWIDTH', has been defined to change the current
    font width.  The string 'n RFONTWIDTH' saves the current font width and 
    then changes the font width to 'n' percent of the current width where 'n'
    is between 1 and 100 inclusive.  The mnemonic 'RFONTWIDTH' without 
    parameters restores the original font width saved by the last 
    'n RFONTWIDTH' operation.  Setting the font size or performing an
    'RFONTWIDTH' operation clears any previously  saved font width.  The 
    'RFONTWIDTH' mnemonic is supported by version 11.3 of dL4 Term and dL4 
    for Windows.

o   The FIND, LIST, DUMP, and BREAK commands now support an alternate string 
    delimiter, "\", when selecting program lines.  Using backslash as  the
    delimiter allows the search string to contain "/" characters.

    Example:

        find \/usr/bin\

o   Enhancement: the debugger now supports the BSTR$() and BVAL() functions.

o   Behavior change: MSC$(5) now returns the name of the calling program
    if the current program was run via SWAP 1xx statement.

o   Behavior change: the intrinsic CALL CHSTAT() now treats a program
    started via a SWAP 1xx statement as being in a SWAP level and can return
    the name of the parent program.

o   Behavior change: the intrinsic function CALLSTAT$() now treats a program
    started via a SWAP 1xx statement as being in a SWAP level and returns
    the name of the parent program.  The level type is set to "External SWAP".

o   Behavior change: ERR(0) now translates dL4 error 265 ("Long CHAIN 
    attempted") to 165 ("dL4 specific error") instead of error 6 ("No such 
    line").

o   Bug fixed: SWAP 1xx statements in unibasic reported an error 6 if the
    dL4 program exited with a CHAIN "" statement.

Oct 19, 2020 (Release 11.2)

o   dL4 for Windows is now compiled and linked using Microsoft Visual
    Studio 2019.  Window versions prior to Windows 7 are no longer 
    supported.

o   The dL4 ABEND program dump feature enhances the dL4 "run" utility to
    automatically produce a program dump file whenever "run" terminates due 
    an error in the current program or if the program executes a STOP 
    statement.  The automatic program dump is only performed if the 
    environment variable DL4ABENDDUMP is set to an absolute path (a path
    starting with a "/" character).  The generated dump file is a text file 
    using the same format and with the same contents as used by CALL 
    PROGRAMDUMP.

    The following macro values can be used in the DL4ABENDDUMP path:

        %PGMNAME%     Current program filename
        %PORT%        Port number of the current program
        %DATE%        Current date ("YYMMDD")
        %TIME%        Current time ("HHMMSS")
        %name%        Value of the environment variable "name"

    These macro values will be replaced by their current values.  For example,
    if DL4ABENDDUMP is set to "C:\appdumps\p%PORT%-%DATE%.txt!" on port 12 
    on March 15 2021, an ABEND dump would write the dump file to
    "C:\appdumps\p12-210315.txt".  If the file specified by DL4ABENDDUMP 
    already exists, it will be replaced by the new dump file.

o   A new utility, tools/dl4parms, has been added to display the current
    dL4 runtime parameters.

o   Behavior change: the LOAD and CONVERT commands now display a warning
    message if overlapping or out-of-order line numbers are encountered.

o   Enhancement: program dumps now include the current LUMAP and DL4LUST
    values.

o   Enhancement: CALL PROGRAMDUMP() now generates specific errors rather
    than a generic error 38 if the CALL fails.

o   Enhancement: the email driver now adds required line termination if the
    program does not.  This change prevents SMTP server errors and 
    incorrectly formatted attachments.

o   Enhancement: CALL DXSAVE() supports line feed characters in values.

o   Enhancement: the email driver now returns TLS/SSL status information in
    the CHF$(%xx) function result.

o   Enhancement: the MSC$(-4) and MSC$(-5) functions now add the strings
    "Command line" and "Debugger" to indicate whether command line 
    interpretation is available (present in SCOPE and absent in RUN).

o   Behavior change: the "run" utility now places quotation marks  around
    command line parameters as needed when building the command line image 
    to be read by "INPUT (0,X)S$".

o   Bug fixed: the DISPLAY command handled subscripts incorrectly when
    string array subscripts were used with a single substring subscript.  For
    example "display S$[2,3,10]" where S$ is a two dimensional string array.

o   Bug fixed: the DISPLAY command did not work if an array subscript was
    specified with an array variable that did not have subscripts.  For
    example "display X[Y]" did not work while "display X[Y[0]]" succeeded
    when both X and Y were one dimensional arrays.

Oct 30, 2019 (Release 11.1)

o   The maximum size of the index portion of Portable and Universal 
    Indexed-Contiguous files has been increased to 2 terabytes on
    systems that support files larger than 2 gigabytes.  The maximum size
    can be further increased by setting ISAMSECT to values greater than the
    default of 8.  Increasing the value of ISAMSECT may also be desirable
    when using large keys and may increase performance.  The size of the
    data portion is limited only by the amount of storage space available.
    To use this feature a file must be created as a "Portable Huge+
    Indexed-Contiguous" or "Universal Huge+ Indexed-Contiguous" file.
    Example:

        Build #1,"[1:40]File" As "Portable+ Huge Indexed-Contiguous"

    To share huge files across a network, both the file server and the client 
    systems must support sharing files larger than 2 gigabytes in size.

    On 64-bit platforms such 66 (Red Hat 6/7) or 64 (Red Hat 5), Huge+ files
    also increase the maximum number of records from 2147483647 to 4278190080.
    On 32-bit systems, using record number greater than 2147483647 will result
    in illegal record number errors.

o   The "H+" option letters ('BUILD #1,"<H+>[10:100]file"') can be used to 
    select the "Huge+" format when creating a Portable Formatted, 
    Contiguous, or Indexed file.  This option allows a file to grow to
    2 terabytes or more in size on operating systems that support user
    files of that size (see above).

o   The intrinsic CALL FILEINFO() has been extended to report "Huge+" files
    by adding 16384 to array element 13 (attributes word 2) and as "H+"
    in the filename argument.

o   The socket and TLS/SSL socket drivers now support IPv6 addresses.
    Numeric IPv6 addresses must be specified within brackets ("[::1]") and
    enclosed in quotation marks.

o   The TLS/SSL socket driver now accepts certificate files in PKCS12 format
    if the file extension is ".p12" or ".pfx".

o   A new standard intrinsic, CALL RSASIGN(), has been added to dL4 to
    generate RSA signatures.

    BASIC syntax:

        Call RSASign(Sig?, SigLen, ChecksumName$, Checksum?, KeyFilePath$
               [, KeyFilePassword$ ])

    Outputs an RSA signature to the binary string 'Sig?' and returns the
    signature length in bytes in 'SigLen'.  The signature is generated
    from the checksum contained in the binary string 'Checksum?' using
    the RSA private key in the PEM file 'KeyFilePath$'.  A P12 file can be
    used if the file extension is ".p12".  If the key file is encrypted, the
    encryption passphrase must be passed in 'KeyFilePassword$'.  The string
    "ChecksumName$" must be "MD5", "SHA1", or "SHA256".

o   Two new intrinsic CALLS have been added to encrypt and decrypt binary
    strings.  Character strings can be encrypted or decrypted by using CALL
    TRANSLATE() to convert character strings to and from binary strings.
    The CALLs are available only on platforms 36 (Red Hat ES6 32 bit). 66
    (Red Hat ES6 64 bit), and 07 (IBM AIX 7.1).

    BASIC syntax:

        Call Encrypt(Var?, VarLen, CipherName$, Mode, Key? {, IV? })

    Encrypt 'VarLen' bytes of the binary string 'Var?' using the cipher 
    specified by 'CipherName$', the binary encryption key 'Key?', and
    the optional initialization vector IV?.  If 'Mode' is 1, the data
    will be PKCS7 padded to fill the encryption block size.  If 'Mode' is
    zero, the data will not be padded and 'VarLen' must be a multiple of
    the encryption block size.  The encrypted string is returned in 'Var?'.
    The actual number of bytes generated, which may exceed the original
    value of 'VarLen' due to padding, is returned in 'VarLen'. Both 'Key?'
    and 'IV?' must contain the number of bytes required by the selected
    cipher for the key and initialization vector values.

    BASIC syntax:


        Call Decrypt(Var?, VarLen, CipherName$, Mode, {, IV? })

    Decrypt 'VarLen' bytes of the binary string 'Var?' using the cipher
    specified by 'CipherName$', the binary encryption key 'Key?', and 
    the optional initialization vector IV?.  If 'Mode' is 1, the data is
    PKCS7 padded and the padding will be removed.  If 'Mode' is zero,
    the data is not padded and 'VarLen' must be a multiple of the block
    size.  The decrypted string is returned in 'Var?'.  The actual number 
    of bytes returned, which may be less than the original value of 'VarLen'
    due to padding, is returned in 'VarLen'. Both 'Key?' and 'IV?' must
    contain the number of bytes required by the selected cipher for the 
    key and initialization vector values.

    The value of 'CipherName$' must be one of the following ciphers:

    aes-128-cbc, aes-128-ecb, aes-192-cbc, aes-192-ecb, 
    aes-256-cbc, aes-256-ecb, des-cbc, des-ecb, 
    des-ede3-cbc, des-ede3-ecb, aes_128_cbc, aes_128_ecb, 
    aes_192_cbc, aes_192_ecb, aes_256_cbc, aes_256_ecb, 
    des_cbc, des_ecb, des_ede3_cbc, or des_ede3_ecb

o   Error reporting for terminal definition files has been improved.

o   Behavior change: the JUMP statement now supports jumping to substatements
    beyond the specified line number.  A substatement argument which is zero
    or negative is treated as substatement 1.  These changes increase 
    compatibility with uniBasic.

o   Behavior change: CHF(4xx) now includes the size of the index portion of
    Indexed Contiguous or Fox-Pro Full-ISAM files.

o   Behavior change: the tools/term utility now reports the port status as
    "Dbg" if the port is reading a debugger command.

o   Behavior change: the PORT statement in mode 3 now reports the port state
    as 12 if the port is reading a debugger command.

o   The preferences dialog "Preferences -> Export Preferences" has been renamed
    to "Export Settings".  The registry export file now includes all dL4
    registry values.

o   The Windows Printer driver now supports a "TITLE=<name>" open option to
    set the document name.

o   A new Edit menu toggle, "Flash cursor", has been implemented to display
    the cursor as a giant block cursor.

o   Bug fixed: CALL TRANSLATE() generated an error 38 when translating an
    illegal character and did not return the source and destination 
    character counts.  The CALL has also been changed to return specific
    errors for bad parameters.

o   Bug fixed: Statements such as "IF <boolean> THEN NEXT:" that used keywords
    as labels could not be converted.

o   Bug fixed: Programs that had string variable names that matched keywords
    could not be converted.

o   Bug fixed: the CONVERT command and the LOADSAVE convert option did not
    convert statements similar to "IF A THEN IF B" and instead reported syntax
    errors.

o   Bug fixed: the CONVERT command and the LOADSAVE convert option did not
    convert statements such as "A = A + 1" or "A = A - 1" correctly unless a
    conversion profile was used..

o   Bug fixed: the MySQL Full-ISAM driver did not support the "DateIsLocal"
    open option when specified in the DL4MYSQLISAM runtime parameter.

o   Bug fixed: the Full-ISAM Bridge did not work when SEARCH statements used
    binary variables as keys.

o   Bug fixed: reindexing (CHANNEL 37,#c) did not work on Fox-Pro Full-ISAM
    files.

o   Bug fixed: filename completion in SCOPE used the first directory in
    DL4LUST rather than the current working directory if DL4LUST was defined.

o   Bug fixed: IF statements did not support short format GOTOs
    ("IF <expr> <line#>").

Apr 17, 2018 (Maintenance Release 10.6.7)

o   Support for using dL4 on a secondary monitor has been added to the dL4
    Window driver.  

o   A new preferences dialog, "Preferences -> Export Preferences", has been
    added to save the window settings to a registry export file.  The
    settings can be imported on a different system or account by double
    clicking on the export file.

o   Enhancement: the tools/term utility now displays the status of a port as
    "Dbg" if the port is reading a command for the debugger.

o   Enhancement: PORT mode 3 now returns a status of 12 if the port is
    reading a command for the debugger.

o   Enhancement: CHF(4xx) now includes the size of the index portion of an
    indexed contiguous file when reporting the size of a file.

o   Enhancement: the Full-ISAM Bridge driver now supports "OPTION FLUSH AFTER
    STATEMENT ON".

o   Bug fixed: moving the "thumb" in the vertical scroll bar did not set the
    position correctly if the history buffer contained a large number of
    lines (thousands).

o   Bug fixed: a memory violation occurred in the pipe driver or the pfilter
    utility when translating a bad character to the default character.

o   Bug fixed: illegal ISAMSECT runtime parameter values sometimes caused a
    divide by zero fault.

Nov 30, 2017 (Maintenance Release 10.6.6)

o   A new standard intrinsic, CALL GETRANDOM(), has been added to dL4 to
    fill character or binary strings with random characters or bytes.

    Syntax:

        Call GetRandom(Option, {Var1 {,VarN}...})

    Where:
        Option  is 0 for random 8 bit or 16 bit values
                   1 for random printable ASCII values (0x20 - 0x7e)
                   2 for random alphanumeric ASCII values ("A"-"Z", "0"-"9")
                   3 for random alphabetic ASCII values ("A" - "Z")
                   4 for random numeric ASCII values ("0"-"9")
        VarN    is a binary or character string variable

o   The performance of the 'IOCI' mnemonic when used with dl4login and dL4
    Term has been improved.

o   Enhancement: the REPLACE$() and REPLACECI$() intrinsic string functions
    now accept a negative match count to replace substrings starting from the
    end of the source string.

o   Enhancement: the BSTR$() and BVAL() functions now accept base values of
    2, 8, 16, or 36.

o   Enhancement: an optional numeric second parameter has been implemented
    in the intrinsic function BASE64?() to receive the actual number of bytes
    returned by the function.

        Declare Intrinsic Function Base64?

        Binary? = Base64?(StringVariable$,ActualLengthInBytes)

o   Bug fixed: the REPLACE$() and REPLACECI$() intrinsic string functions
    replaced all occurrences of the target string rather than the specified
    number if the occurrence count was greater than 100.

o   Bug fixed: the profile driver sometimes returned an incorrect record
    number from the CHF(1xx) function.

o   Bug fixed: the intrinsic CALL COPYARRAY() generated a memory violation
    when copying array elements of a multi-dimensional array.

o   Bug fixed: the intrinsic CALL TRANSLATE() did not store a terminator
    character at the end of destination string.

o   Bug fixed: the intrinsic functions MD5?(), ADDMD5?(), SHA1?(), ADDSHA1?(),
    SHA256?(), and ADDSHA256?() set a random error code when a parameter
    type error was detected.

Apr 27, 2017 (Maintenance Release 10.6.5)

o   The SSL Socket and SSL Socket Text drivers now support anonymous
    connections. If the open option "anonymous=true" is used, the drivers
    negotiate an encrypted connection without using TLS/SSL certificates.
    This option provides encryption but does not protect against man-in-the-
    middle attacks.

o   The mnemonic sequence 'x1,y1,x2,y2 CE' can now be used to clear a
    specified rectangle in a window.  The area will be cleared using the
    current background color.  GUI elements within the rectangle are not
    deleted.

o   The mnemonic sequence '-1 PENWEIGHT' can now be used to reset the pen
    width to the default value.

o   Enhancement: the tools/query utility now displays index information for
    C-Tree files.

o   Enhancement: the email driver now generates additional error information
    if a "server storage full" or "sender address rejected" error occurs.

o   Bug fixed: typing escape at a scope command line prompt sometimes caused
    scope to immediately exit.

o   Bug fixed: if an error occurred while rebuilding indexes (CHANNEL 37),
    an incorrect error message was sometimes reported.

o   Bug fixed: the SSL Socket driver and SSL Socket Text drivers sometimes
    caused a memory violation when performing a DCO_OPENTO operation.

o   Bug fixed: SPAWN statements sometimes failed when multiple SPAWN
    statements were executed simultaneously.

o   Bug fixed: CALL TRXCO() failed to set the status variable if unusual
    errors occurred.

Dec 28, 2016 (Maintenance Release 10.6.4)

o   Bug fixed: the Microsoft SQL Server Full-ISAM driver did not work
    with SQL Server 2012 or later. An SQL syntax error was reported
    when accessing records.

o   Bug fixed: the Microsoft SQL Server Full-ISAM driver had a memory
    and thread leak when creating tables.

Nov 22, 2016 (Maintenance Release 10.6.3)

o   Bug fixed: the Terminal File Printer driver reported "File transfer
    failed" when closed after performing a non-binary file transfer.

o   Bug fixed: the email driver would hang for 5 minutes during an OPEN
    statement if the "USESSL" option was used and encryption was not
    enabled in the SSN.

o   Bug fixed: the LIST, SHOW, and DUMP commands sometimes caused a memory
    fault when displaying program lines with around 200 or 400 characters.

Jun  6, 2016 (Maintenance Release 10.6.2)

o   A new standard intrinsic, CALL RTRIMSTR(), has been added to dL4 to
    remove trailing spaces from all string members of structure variables,
    all string elements of string arrays, or string variables.  Non-string
    members, elements, or variables are left unchanged.

    Syntax:

        Call RTrimStr(Variable {,Variable} ...)

    where "Variable" is a variable of any type.

o   The Windows Page Printer driver and the "Preferences -> Aux Printer"
    dialog now support the "EOLToCRLF" option without requiring usage of the
    "BINARY=TRUE" option. The "EOLToCRLF" option converts either carriage-
    return or line-feed to a two character carriage-return line-feed
    sequence.

o   Bug fixed: a program exception occurred when a list box such as WCLIST
    was displayed with empty fields.

o   A potential problem when using the MySQL drivers with the MariaDB
    client library has been fixed.

o   The OpenSSL library has been updated to 1.0.2h.

Mar 16, 2016 (Maintenance Release 10.6.1)

o   Bug fixed: the ODBC SQL driver could not read NVARCHAR columns if the
    column value was longer than one half of the column width.  An error
    15 (overflow) was reported when reading longer values.

Feb 23, 2016 (Release 10.6)

o   The tools/term utility now has an IO mode to display the rate of I/O
    operations on one or more ports for all or selected drivers.  For
    example, the command

        term all io sql

    displays the number of SQL driver open, read, write, and search operations
    per second for each port during a 60 second measuring period.  The new
    mode has the syntax

        term [first[-last] | ALL] IO <driver> [options]

    The required value "<driver>" is a case insensitive driver or driver class
    name as displayed by the SCOPE "drivers" command.  If the name contains a 
    space, then the name must be enclosed in quotations marks.  If a class
    name is used, all drivers in that class are selected.  The name "" selects
    all drivers. The value "[options]" can be omitted or it can be one or more
    of the following:

        TR   Display ports with the highest rate of driver reads
        TW   Display ports with the highest rate of driver writes
        TS   Display ports with the highest rate of driver searches
        TO   Display ports with the highest rate of driver opens
        D    Display number of operations instead of rate
        C    Repeat display continuously
        P    Page display

o   The PORT statement has been extended with a new mode, 10, to return
    driver usage counts for a specified port number and driver type.  The
    statement

        PORT portnum,10,status,driver$,pid$,user$,station$,pgm$,o,r,w,s

    queries port "portnum" and returns, if "status" is zero, the count of
    opens, reads, write, and searches into the variables "o", "r", "w", and
    "s".  Usage counts are returned only for the driver name or driver class
    name "driver$".  A driver name of "" will select all drivers.  The usage
    counts are modulo 2^31.  The statement also returns the user id in "user$",
    the terminal or workstation name in "station$", and the current program
    name in "pgm$".  An operating system dependent process identifier is
    returned in "pid$".

o   Behavior change: when the CLEAR statement is used to close a socket, the
    socket driver will discard any remaining output data.

o   Behavior change: the SSL Socket and SSL Socket Text drivers now perform a
    unidirectional disconnect when the channel is closed to avoid a very long
    delay which occured with some SSL servers.

o   The MySQL SQL and MySQL Full-ISAM drivers now accept version 10 of the
    MySQL library (version 10 is the MariaDB equivalent to the MySQL library).

o   Bug fixed: when using SWAP 100, 110 or 120 statements, program loading
    errors were not reported to the caller.

o   Bug fixed: suspending file writes with dl4cntl did not work in programs
    executed by the SWAP 100, 110, or 120 statements.

o   Bug fixed: the number of history pages could not be set to the intended
    maximum of 99 pages.

o   Bug fixed: the cut and paste keys could not be used in WCNUMBER edit 
    boxes.

o   Bug fixed: rapid SPAWNing of ports often failed.

Aug 10, 2015 (Release 10.5)

o   The "Terminal File Printer" driver has been extended to support copying
    non-text files to a dL4 Term client system.  Example:

        Dim Buffer?[4096]
        Open #1,"[1:1]filename" As "Raw"
        Open #2,"(binary)filename" As "Terminal File Printer"
        Do
            Read #1;Buffer?
            BytesRead = Chf(1501)
            If BytesRead = 0 Exit Do
            Write #2;Buffer?[1,BytesRead]
        Loop
        Close #2
        Close #1

    The "Terminal File Printer" driver normally requests the dL4Term user to
    choose the destination file path for both binary and non-binary files.
    Files can be written without user interaction if the file name is in the
    form "logical-directory/file" and the logical directory is defined in
    the download logical unit map on the client system.  The registry string
    value

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4Term\WinTerm\DownloadLUMAP

    on the client system defines the translation of logical directories to
    physical directories using the same syntax as an LUMAP value
    ("dir1=path1 dir2=path2").

    DownloadLUMAP registry value example:

        "doc=C:\users\sam\Documents dld=C:\users\sam\Download"

o   The SYSTEM 31, SYSTEM 33, and SYSTEM 39 statements, which execute client
    system commands when using dL4Term, have been extended to optionally use
    files generated by the "Terminal File Printer" driver.  Such files in
    SYSTEM commands are specified by the 'DOWNLOAD' mnemonic followed by
    a file name in the form "logical-directory/filename" where
    "logical-directory" is a directory defined in the download logical unit
    map.  The  file name must have the same file extension as needed by the
    command.  The example below copies the file "query.txt" to the client
    system and runs the notepad utility to display the file.

        Dim Buffer?[4096]
        Open #1,"[1:1]query.txt" As "Raw"
        Open #2,"(binary)doc/report.txt" As "Terminal File Printer"
        Do
            Read #1;Buffer?
            BytesRead = Chf(1501)
            If BytesRead = 0 Exit Do
            Write #2;Buffer?[1,BytesRead]
        Loop
        Close #2
        Close #1
        SYSTEM 31,"wordpad " + 'DOWNLOAD' + "doc/report.txt"

    Note: the download logical unit map can be used to map SYSTEM statement
    file references whether or not the file was created using the "Terminal
    File Printer" driver.

o   A new preferences dialog, "Preferences -> File Mapping" has been added
    to display or modify the resource and download logical unit maps.

o   A new mnemonic, 'WCPROGRESS', has been added to create standard Windows
    progress bars.  The mnemonic sequence to create a progress bar is

        PChr$(n,x1,y1,x2,y2,"label",options,range);'WCPROGRESS'

    where
        n           is the GUI element number of the progress bar
        x1          is the upper left column of the progress bar
        y1          is the upper left row of the progress bar
        x2          is the lower right column of the progress bar
        y2          is the lower right row of the progress bar
        label       title string displayed near the progress bar or ""
                    if no label is desired.
        options     an optional numeric parameter as in other GUI elements.
        range       an optional numeric parameter specifying the maximum
                    value of the progress bar range.  The value must be
                    between 0 and 2147483647. The default range is 0 to 100.

    The length of the displayed progress bar is controlled by printing an
    integer value between 0 and the range limit to the program bar element.
    The color of the progress bar is determined by Windows if Windows Themes
    mode is enabled.

    Example:

        Print 'XX';
        Print PChr$(1,10,5,40,6,"");'WCPROGRESS';
        For P = 1 To 100
            Print '1WCSELECT';Str$(P);'CR 0WCSELECT';
            Pause 2
        Next P

o   Behavior change: the vertical centering of large font text in WCCOLORBTN
    elements has been improved.

o   The "SSL Socket" driver now supports server side applications by allowing
    a new SSL connection to be negotiated on a channel open to the "TCP Socket"
    or "Raw File" driver.  The OPEN statement must specify the "SSL Socket"
    driver, use the existing socket channel number as the "path" argument,
    and include an "accept" open option.  The open options should also contain
    a "root=<root certificate file path>" option and a "cert=<server
    certificate file path>" option.  The "SSL Socket" driver is intended to
    be used with self-signed certificates and does not currently check for
    domain names or revoked certificates.  The "verify" open option can be
    used to require the client side to supply a client certificate (which must
    be signed via the root certificate from the server side open options).
    A "password=<string>" open option can be used for encrypted certificates.

    By default, the "SSL Socket" driver requires current SSL protocols and
    strong encryption.  The "oldprotocol=true" and "oldcipher=true" open
    options can be used to enable the use of any version of the SSL protocol
    and any available cipher.

    Example of SSL socket "listening":

        Dim SockOpts$[60],I$[100],3%,I
        Open #1,":9631" As "TCP Listen Socket"
        I = 0
        SockOpts$ = "accept,root=root.pem,cert=server.pem"
        Do 
            Open #2,{1} As "Socket"
            Open #3,{2,SockOpts$} As "SSL Socket"
            I = I + 1
            Do 
                Try Print #3;"Session";I;Tim#(0);"\15\\12\"; Else Exit Do 
                Try Read #3,-1,-1,100;I$ Else Rem
                If Spc(8) <> 123 Exit Do 
            Loop 
            Close #3
            Close #2
        Loop 

    Example of SSL application started by dl4servr using "run -D":

        Declare Intrinsic Sub DupChannel
        Dim I$[100],3%,I
        Call DupChannel(1,-1) ! Open standard input/output on channel 1
        Open #2,{1,"accept=true,root=root.pem,cert=server.pem"} As "SSL Socket"
        I = I + 1
        Do 
            Try Print #2;"Session";I;Tim#(0);"\15\\12\"; Else Exit Do 
            Try Read #2,-1,-1,100;I$ Else Rem
            If Spc(8) <> 123 Exit Do 
        Loop 
        Close #2
        Close #1
        End 

o   The "SSL Socket" driver will now supply client certificates to an SSL
    server if the "cert=<certificate file path>" open option is used.

o   The "SSL Socket" driver normally accepts any SSL certificate offered
    by an SSL server even if the certificate authority isn't recognized or
    if the certificate has expired.  The "verify" open option can be used to
    reject any SSL certificate that is not recognized by the root certificate
    specified by the "root=<path>" open option.  The "verify" option can be
    used by the driver in either client or server mode.

o   The "SSL Socket" driver has been extended to support the CHF$(500+channel)
    function which returns miscellaneous driver information.  The function
    result is a system dependent text description of the current SSL
    encryption used by the channel.

o   The "run" utility can now be used with a "-D" command line option to open
    standard input and output to the "Raw File" driver instead of the
    "Terminal Window" driver.  This is needed when running SSL server side
    applications that are started by dl4servr or an equivalent.

    Example:

        run -D serverprogram

o   Bug fixed: characters and images were rendered poorly on high resolution
    displays (usually small laptop systems with high definition screens)
    because Windows returned incorrect screen size information to dL4.  Font
    size preferences may need to be reconfigured when upgrading such systems
    to this version of dL4 for Windows.

o   Bug fixed: the "append=true" option caused an error in CALL PROGRAMDUMP() 
    unless the dump file already existed.

Jun  2, 2015 (Maintenance Release 10.4.2)

o   Bug fixed: WCCOLORBTN elements could not be selected via keyboard 
    accelerator characters.

Apr 21, 2015 (Maintenance Release 10.4.1)

o   Bug fixed: header label text was not displayed for 'WCLISTGRID' elements.

Feb 27, 2015 (Release 10.4)

o   Windows versions older than Windows XP such as Windows 98 or Windows NT
    are no longer supported.

o   Support has been added for SWAP statement modes 100, 110, and 120 which
    are used by uniBasic release 10 programs to call dL4 subprograms.
    Arguments can be passed in these SWAP modes in the same manner as in the
    CALL-subprogram statement.  The arguments can be expressions, numeric
    variables, string variables, array elements, or entire array variables
    (using the same "[]" suffix as in CALL statements).  Array arguments
    cannot be re-dimensioned in the subprogram.

    Syntax:
        SWAP Mode,"pgmpath",Arg1,Arg2,...,ArgN

    The three SWAP modes differ in how the user terminal is handled.  Mode
    100 supports all mnemonics according to the terminal type and performs
    normal dL4 terminal initialization.  Mode 110 uses a "dumb" or "glass tty"
    terminal definition that does not support display mnemonics and leaves
    the terminal state unchanged.  Mode 120 supports all mnemonics according
    to the terminal type and, if uniBasic window tracking is enabled, preserves
    the screen (the screen is cleared before the dL4 subprogram is executed
    and restored after the subprogram exits),

    For compatibility with uniBasic, SWAP statement modes 100, 110, and 120
    can be used by dL4 programs and start separate dL4 processes.  For better
    performance, SWAP statements using modes 100, 110, and 120 should be
    replaced with CALL-subprogram statements when converting programs from
    uniBasic to dL4.

    Two new error codes are used by the new SWAP modes:

        292  SWAP failed due to incompatible dL4 and uniBasic revisions
        293  Error copying SWAP program parameters

o   When using the new SWAP 100, 110, or 120 statements, it is now possible
    to step into or out of a subprogram using the "." (step) command.  The
    ".." (step over) command can be used to step over SWAP 1xx statements.
    When stepping into a subprogram, the debugger will be entered at the
    first line of the subprogram regardless of the step count.  The step
    count will be similarly ignored when stepping out of a subprogram.

o   The 'WCACTION' code 8 mnemonic can now be applied to a window to report
    when the user selects a GUI element when the focus was previously on the
    window containing the GUI element.  Code 8 is identical to code 1 but the
    MSC(45) function will return the newly selected GUI element number rather
    than element 0.  The purpose of this action is to terminate a character
    mode input in the window if a user "clicks" on a GUI element.
    Example:

        Print PChr$(0,8,"\15\");'WCACTION';

o   The 'WCACTION' code 9 mnemonic can now be applied to a window to report
    when the user "left clicks" on the window (but not in a GUI element in
    the window).  After a program has read the string generated by 'WCACTION'
    9, the program can obtain the column and row of the "click" from MSC(47)
    and MSC(48).  MSC(47) and MSC(48) will use the grid scaling that was in
    effect when the 'WCACTION' was set.  Setting 'WCACTION' 9 disables the
    ability to mark window text for copy and paste using the mouse.  Example:

        Print PChr$(0,9,'F63');'WCACTION';

o   A new mnemonic, 'XST', has been implemented to set GUI element tab stops
    using coordinates from the window containing the GUI element rather than
    the font of the GUI element itself.  This makes it possible to align tab
    stops with text in the window or other GUI elements.  The 'XST' mnemonic
    can be used with any GUI element that supports the 'ST' mnemonic.

o   A "Use Alternate Size" check box has been added to the "Preferences ->
    Font Size" dialog to select the dL4 version 7 font sizing method.

o   A new character set, ISO 8859-15, has been added.  The new character set
    is similar to ISO 8859-1 ("Latin1"), but adds support for the Euro sign
    and some other characters while removing some less commonly used non-ASCII
    characters.  Specifically, these characters are added:

        Unicode     ISO 8859-15

        0x20AC      0xA4        Euro sign
        0x0160      0xA6        Latin capital letter S with caron
        0x0161      0xA8        Latin small letter S with caron
        0x017D      0xB4        Latin capital letter Z with caron
        0x017E      0xB8        Latin small letter Z with caron
        0x0152      0xBC        Latin capital ligature OE
        0x0153      0xBD        Latin small ligature OE
        0x0178      0xBE        Latin capital letter Y with diaeresis

    The following characters were removed relative to ISO 8859-1:

        Unicode     ISO 8859-1

        0x00A4      0xA4        Currency sign
        0x00A6      0xA6        Broken vertical bar
        0x00A8      0xA8        Spacing diaeresis
        0x00B4      0xB4        Spacing acute
        0x00B8      0xB8        Spacing cedilla
        0x00BC      0xBC        Fraction one quarter
        0x00BD      0xBD        Fraction one half
        0x00BE      0xBE        Fraction three quarters

    The new character set can be used with portable indexed contiguous files,
    portable formatted files, and text files.  Examples:

        Open #1,"(charset=ISO 8859-15)textfile" As "Text"
        Build #6,"(charset=ISO 8859-15)[1:40]contigfile"

o   Text files using the ISO 8859-15 character set can be built or opened
    using the driver names "Latin 9 Text" or "Latin 9 Encrypted Text".  The
    new driver names can also be used in the "DL4DRIVERS" runtime parameter
    to change the default text file character set.  Examples:

        Open #1,"textfile" As "Latin 9 Text"

        DL4DRIVERS="Latin 9 Text"

o   A new channel function, CHF(18xx), has been implemented to return one if
    the current record is locked and zero if the record is not locked.

o   The Full-ISAM Bridge driver has been enhanced to support a longer date
    range in the DTOC() function when using the "AA" mask.  The "AA" mask
    now supports a range from 1900 to 2259 ("00" to "Z9") instead of
    1900 to 2059 ("00" to "E9").

o   The portable indexed contiguous file driver can now write text log files
    describing all statements (such as WRITE) that change a data file. This
    feature is intended for use only at the direction of Dynamic Concepts
    support personnel.  Logging is enabled and disabled using the tools/setlog
    utility ("tools/setlog -on data_file_path").  The log file uses the same
    name and path as the data file with the file extension set to ".log".
    The log file is not supported by the KILL, MODIFY, or DUPLICATE statements.

o   It is now possible to select alternate dL4 configurations when starting
    SCOPE or RUN.  The "-c config_name" command line option redirects all
    configuration registry access to the key "config_name".  The symbol
    "config_name" must be composed of letters and digits only.  Alternate
    configurations include window size, initial font, and any other option
    listed under the "Preferences" menu.  Alternate configurations are created
    by starting SCOPE with the "-c" option and then setting preferences.  The
    "-c" option does not control configuration information passed using
    environment variables.  Alternate configurations are stored under the
    key "Software\DynamicConcepts\dL4\Config".

o   Two new intrinsic CALLs, UBTIME() and BITSTIME(), have been implemented
    to duplicate the date/time format used by uniBasic in IRIS and BITS modes.
    The previously existing CALL TIME() uses an IRIS BASIC date/time format.

o   A new intrinsic CALL IMSNUMMEMCOPY() has been added to better duplicate 
    the behavior of IMS BASIC when copying to a numeric variable.  When
    copying to a numeric variable, CALL IMSNUMMEMCOPY() treats the size 
    parameter as the number of array elements to copy rather than the number
    of bytes.

o   A new standard intrinsic, CALL COPYFILL(), has been added to dL4 to copy
    values from a source variable to a destination variable space filling all
    strings, string array elements, or string structure members.

    Syntax:

        Call CopyFill(Dest,Source)

    where "Dest" and "Source" are variables of any type.  "Dest" and "Source"
    must be of the same type.

o   A new intrinsic function, ASCII$(), has been added to format a string
    with backslashed octal notation for all non-ASCII characters.  The
    ASCII$() function formats all characters in a string up to the
    dimensioned size (double subscripting can be used to select which
    characters will be formatted).

    Syntax:

        ASCII$(<string>)
    
    Where "<string>" is a string variable or a string expression.

o   The intrinsics CALL GATHER() and CALL SCATTER() have been extended to
    support structure variables.  Both CALLs also now support an optional
    leading numeric mode parameter which controls space filling and trimming.
    When using CALL GATHER() with the mode set to one, the values of string
    variables are space filled to the dimensioned size of the variable before
    being appended to the destination variable.  When using CALL SCATTER()
    with the mode set to one, trailing spaces are removed from values when
    string variables are extracted.  A mode of zero (the default mode)
    disables space filling and trimming.

o   The intrinsic CALL BITMANIP() has been extended to perform 32-bit
    operations instead of 16-bit operations when 10 is added to the standard
    mode values.

o   An option, "-r", has been added to the SCOPE BASIC mode "file" command
    to display additional channel information such as the open mode, the
    current record number, and whether the current record is locked.  If
    the current record is locked, a capital letter "L" is appended to the
    displayed record number.

    Syntax:

        file -r

o   Enhancement: a "-n" option has been added to the SCOPE DISPLAY command to
    print all characters in the full dimensioned size of string variables
    including null characters.

o   Behavior change: the MySQL SQL and MySQL Full-ISAM drivers now attempt
    to increase the I/O retry limit when used with common MySQL library
    revisions.  This change may prevent "server connection lost" errors
    when using the tools/TERM or tools/PORT utilities to monitor a program
    that uses the MySQL drivers.

o   Bug fixed: CALL TIME() sometimes failed to terminate the result string.

o   Bug fixed: the octal option in scope DL4CMDDEF profiles set hexadecimal
    listing mode rather than octal listing mode.

o   Bug fixed: the "Windows Printer" driver sometimes failed to open printers
    after the auxiliary printer was used with the 'BO'/'EO' or similar
    mnemonics.

Sep  2, 2014 (Maintenance Release 10.3.9)

o   Behavior change: WCCOLORBTN buttons now support multiline labels.

o   Bug fixed: MSC(45) did not report the element number of WCPAD GUI elements.

o   Bug fixed: the tools/query utility did not display the size of huge files
    correctly.

Jul  2, 2014 (Maintenance Release 10.3.8)

o   The TERM utility in the Tools/ directory now has a SNAP option to
    request a program dump on a specified port without causing the port
    to exit.  The SNAP option can only be used if the specified port has
    the DL4PORTDUMP environment variable defined to specify the dump file
    location.  Example:

        #term 5 snap

o   Bug fixed: when setting WCNUMBER edit box values or grid cells, the
    strings were not converted to the locale specified decimal point
    characters.  This caused mangling of the values and non-localized
    display of the numbers.

Jun 26, 2014 (Maintenance Release 10.3.7)

o   Bug fixed: windows were not always refreshed properly causing changes
    to be invisible or delayed.

o   Bug fixed: the TIM(6) function was sometimes off by one day for one hour
    after midnight.

Jun 16, 2014 (Maintenance Release 10.3.6)

o   Behavior change: when using the ODBC SQL driver, "File not found" error
    messages now contain additional information about the cause of the error.

o   Behavior change: the "Pipe to Command" driver now returns the path of
    the script in CHF$(13xx).

o   Bug fixed: due to an error in Windows 7, remote printers in the form
    "\\server\printer" could not be opened with "-d printer_path" option
    in pfilter.

o   Bug fixed: due to an error in Windows 7, remote printers in the form
    "\\server\printer" could not be opened.  Such printers can now be opened
    by adding a "create" open option.

o   Bug fixed: when reading with the MySQL SQL driver, strings were filled
    with spaces to three times the column size.  The "LATIN1" option did
    not work.

Jan  6, 2014 (Maintenance Release 10.3.5)

o   Specific cells in 'WCGRID' or 'WCSORTGRID' rows can now be updated by
    using the 'n,r,c WCSELECT' mnemonic to address column "c" of row "r"
    of GUI element "n" and then performing a "PRINT" of the new values.
    Sequential cells can be updated by printing multiple values separated
    by 'HT' characters.  Updating cells using the 'n,r,c WCSELECT' method
    will not cause the rows to be re-sorted if local sorting is being used.

    Example:

      Print '2,10,1 WCSELECT';
      Print "123.45";'HT';"Updated"

o   Bug fixed: the header of a 'WCGRID' or 'WCSORTGRID' GUI element was
    sometimes displayed as blank.

o   Bug fixed: rows updated by an application in a 'WCGRID' or 'WCSORTGRID'
    GUI element were sometimes reported by CALL GRIDROW() as changed by the
    user.

o   Bug fixed: GUI elements were created with incorrect positions if the main
    window was scrolled to display history lines.

Dec 27, 2013 (Maintenance Release 10.3.4)

o   Behavior change: the MySQL SQL and MySQL Full-ISAM drivers now append the
    native MySQL error code and error text to the error messages for connection
    related errors.  Error message text is displayed by the HELP command and
    returned by the MSC$(2) function.

o   Behavior change: the DynamicXport DXOPEN and DXCLOSE intrinsic procedures
    now add additional information to the error 38 message text if a CALL
    fails.  Error message text is displayed by the HELP command and returned
    by the MSC$(2) function.

o   Behavior change: leading quotation marks are now preserved when using 
    tab characters to complete a filename.

o   Bug fixed: switching from and then back to scopew or dL4 Term while
    displaying a large WCGRID or WCSORTGRID table sometimes caused a memory
    violation.

o   Bug fixed: memory could be corrupted while editing a WCNUMBER value or
    a numeric column in a grid.

o   Bug fixed: the focus was not set correctly after changing the sorting
    order of a 'WCSORTGRID' element.

o   Bug fixed: CALL GRIDROW() did not advance to the next field when
    processing an empty ("") numeric or data field.

o   Bug fixed: the LIST, FIND, and SHOW commands sometimes reported illegal
    character errors when displaying program lines.

Dec  4, 2013 (Maintenance Release 10.3.3)

o   A new 'WCACTION' code, 7, has been implemented to report tabbing forward
    from the last cell of the last row of a 'WCGRID' or 'WCSORTGRID' grid
    element. One use of this new action is to add a new row to be filled out
    by the user.  Applications doing this will need to use the 'n,r,c WCFOCUS'
    or 'n,r,c BEGIN' mnemonic to set the focus to the new row.

o   'WCACTION' 4 and 'WCACTION' 5 now support an optional fourth parameter to
    specify the number of rows at which to send the action string.  The
    default value of 1 sends the action string when only one row is left after
    or before the current position.  Using a value greater than one will make
    latency delays less likely.  When the action string is received, the
    application should at minimum send the number of rows specified by the
    'WCACTION' mnemonic.  Example

        PRINT PCHR$(10,4,'F40',8);'WCACTION';

o   The 'WCGRID' and 'WCSORTGRID' elements now support options 1 (disable)
    and options 2 (tab stop) for each column definition when creating a grid
    element. If the tab stop option isn't specified in at least one column,
    then all columns are treated as tab stops.  When tabbing or back tabbing
    to a new row, focus will be placed in the first (or last) writable column.

o   The 'n,r,c BEGIN' mnemonic can be printed to set the input focus on row
    'r' and column 'c' of 'WCGRID' or 'WCSORTGRID' element 'n' and select any
    data in the cell.

o   The MySQL SQL driver now supports character sets other than ANSI Latin 1.
    The driver will transfer any Unicode character supported by the table
    being accessed.  Unicode characters that are not supported by a MySQL
    table may be replaced by question mark characters depending on the MySQL
    server configuration.  The "Latin1=True" open option and DL4MYSQL
    environment variable option can be used to limit the character set to
    ANSI Latin 1.

o   Bug fixed: the SQL drivers sometimes reported an illegal character error
    from SEARCH statements when there were no illegal characters in the
    SQL statements being executed.

o   Bug fixed: when using 'WCGRID' or 'WCSORTGRID' elements, the grid was
    sometimes mispositioned showing non-existent rows.

o   Bug fixed: when using 'WCGRID' or 'WCSORTGRID' elements, a horizontal
    scroll bar was sometimes displayed when it wasn't needed.

o   Bug fixed: when using 'WCGRID' or 'WCSORTGRID' elements, the "wait for
    paging" windows flashed too quickly to be read.

o   Bug fixed: when using 'WCGRID' or 'WCSORTGRID' elements, memory 
    violations sometimes occurred when adding rows.

Sep 24, 2013 (Maintenance Release 10.3.2)

o   Two new program options have been implemented to prevent programs from
    being saved without a required protection option.  If a program contains
    the statement

        OPTION PROGRAM FILE IS RUN ONLY

    then the program must be saved using the run-only ("-ro") option.
    The statement 

        OPTION PROGRAM FILE IS PROTECTED

    requires that the program be saved using a PSAVE OSN.  Note that these
    options do not apply the specified protection, but instead report an
    error if the protection is not used.

o   The Microsoft SQL Full-ISAM driver now uses ODBC instead of DBLIB to
    access servers.  This change was necessary because DBLIB is no longer
    supported by Microsoft.  Most programs using the driver should not
    require any changes.

o   Bug fixed: the DISPLAY command caused a memory violation when displaying
    strings with a large number of non-printable characters.

o   Bug fixed: programs using the MAP RECORD AS statement could not be loaded
    on pre-10.3.1 versions of dL4 if saved on 10.3.1.

o   Bug fixed: setting a breakpoint on a local procedure did not cause a
    breakpoint to occur when the procedure was executed.

o   Bug fixed: the EDIT command reported a format or syntax error when used
    on LET statements in which the name of the destination variable matched
    a BASIC command name.

Aug  6, 2013 (Maintenance Release 10.3.1)

o   The LIST, FIND, SHOW, and DUMP commands now support a "-s" option to
    toggle whether search matches ("LIST /string/") should be highlighted.
    The LIST, FIND, and SHOW commands default to using highlighting while
    the DUMP command defaults to no highlighting.  The defaults can be
    changed by using the "s" option in DL4CMDDEF (as described in the
    10.4 comments below).  Highlighting normally uses reverse video, but a
    color can defined in a DL4CMDDEF "File=" profile:

        [POSColors0]
        ; Use red for highlighting matches instead of "Reverse"
        Found=0xff0000

o   Bug fixed: bad program files were sometimes created causing an error 
    165 - "file may be corrupted".

o   Bug fixed: keyboard shortcuts did not work with 'WCCOLORBTN' and
    'WCDEFAULTCLRBTN' if Windows Theme mode was enabled.

Jul 22, 2013 (Release 10.3)

o   Text and raw files can now be encrypted on any platform that supports
    dL4 encrypted files.  Data can be encrypted using the AES, "Triple DES",
    or DES algorithms.  To use encrypted files, the dL4 encryption option
    must be enabled in the SSN.  Encrypted text or raw files are slightly
    larger than non-encrypted files but the channel functions will return
    the size of the file as if the files were not encrypted.
    
    A file is encrypted by creating the file with an "N" attribute.  For
    example, the following BUILD statement creates an encrypted text file
    using a key named "CustData":

        BUILD #1,"<N=''CustData''>filename" As "Encrypted Text"

    The key "CustData" is NOT the actual passphrase used to encrypt the data.
    Instead, "CustData" is the logical name of an encryption key that has
    been previously defined using a SYSTEM 100 statement or loaded from a key
    file.  A key name is case insensitive and can include any character except
    for a double or single quotation mark.  The quotation marks in the 
    filename string surrounding the key name are mandatory.  Raw files are
    encrypted by building the file with the "Encrypted Raw" driver.
    
    An OPEN, ROPEN, or EOPEN statement does not use any special syntax to
    open encrypted files.  When a previously encrypted file is opened, dL4
    uses the currently defined keys to open the file.  If none of the current
    keys matches the one required by the file, an error 284 is generated.  If
    a current key matches the key name needed to open a file, but the
    encryption parameters of the key do not match those used to create the
    file, an error 284 will be generated.

    Each dL4 session maintains a list of keys to be used in creating or
    opening encrypted files.  The list is initially loaded with the keys from
    the optional key file and can be modified during the session by executing
    SYSTEM 100 statements.  The list persists throughout the dL4 session
    until dL4 exits even when different programs are loaded.  The key list
    is NOT passed to separate sessions started via SPAWN, PORT, or CALL TRXCO
    statements.

    The SYSTEM 100 statement is used to add, modify, or delete keys in the
    current key list.  If the DL4KEYFILE environment variable is defined when
    dL4 starts, the string will be used as the key file path for the session.
    Key files are text files containing one or more key definitions. If a user
    defined passphrase is used, a SYSTEM 100 statement must define the key
    "SYS_KEYFILE" using the chosen passphrase and cipher before opening or
    creating any encrypted files.  Key files are created using the MAKEKEY
    utility or by using the SYSTEM statement.

o   A new utility, tools/makeenc, has been added to encrypt or decrypt text
    and raw files.  This utility cannot be used to encrypt or decrypt
    indexed or contiguous files.

o   The 'WCACTION' code 1 mnemonic can now be applied to a window to report
    when the user selects a GUI element when the focus was previously on the
    window containing the GUI element.  The purpose of this action is to 
    terminate a character mode input in the window whenever a user "clicks"
    on a GUI element.  Example:

        Print PChr$(0,1,"\15\");'WCACTION';

o   The LIST, FIND, SHOW, and DUMP commands now support a "-i" option to
    suppress listing of lines from INCLUDE files.  A "-a" option can be used
    to list INCLUDE file lines when the default listing mode is "-i".  The
    "-i" option will only work with program files generated by version 10.3
    or later of the LOADSAVE utility.

o   The LIST, FIND, SHOW, and DUMP commands now support "-p" and "-p1" options
    to display program lines using different colors for different parts of
    statements or different types of lines.  Using the "-p" option, the
    following colors are used:

        blue - standard keywords, operators, and functions
        brown - numeric or string literal values (such as 1.3 or "abc")
        green - REM lines and end-of-line comments
        red - lines containing syntax errors

    Using the "-p1" option, blue is used for variable names instead of 
    standard keywords, operators, or functions.  The "-p" and "-p1" options
    are ignored if color output isn't supported.

o   A "DL4CMDDEF" environment variable can now be used to change the default
    behavior of commands in SCOPE.  The value "list=XYZ" will set the default
    LIST command options to the letters "X", "Y", and "Z".  Defaults can be
    set for the LIST, DUMP, FIND, and SHOW commands.  The value "file=path"
    causes SCOPE to read defaults from a profile file.

    Example enabling colors in LIST commands and hexadecimal in LIST or DUMP
    commands:

        DL4CMDDEF="list=ph dump=h"
        export DL4CMDDEF

    Example using a profile file:

        DL4CMDDEF="file=C:\my_scope_profile"
        export DL4CMDDEF

    Example of a profile file:

        [Commands]
        ; Default to using colors and hexadecimal in LIST or SHOW commands
        list=ph
        [POSColors]
        ; Change "list -p" coloring,
        ; A -1 value indicates that no special coloring should be used
        Literal=-1
        Variable=-1
        Procedure=-1
        StdFunction=-1
        ; Statement keywords will be displayed in blue (RGB value)
        Statement=0x0000ff
        Remark=-1
        Option=-1
        Label=-1
        LineRef=-1
        ; Punctuation keywords will be displayed in red (RGB value)
        Punctuation=0xff0000
        VarOp=-1
        ; Operators will be displayed in red (RGB value)
        Operator=0xff0000
        EndOfStatement=-1
        StructRef=-1
        Illegal=-1
        [POSColors1]
        ; Use yellow instead of blue to variable names
        Variable=0xffff00

o   A "-o" option has been added to the LIST, DUMP, FIND, and SHOW commands
    to use octal for displaying non-printable characters in string literals.
    This option can be used when the DL4CMDDEF environment variable has been
    used to set the default display mode to hexadecimal.

o   Enhancement: the "timeout=seconds" option is now supported by the DL4EMAIL
    environment/registry value.

o   Behavior change: the grouping of radio buttons with adjacent WCGROUP
    rectangles has been improved.

o   Beta behavior change: The Encrypted Text and Encrypted Raw file drivers
    now support using ROPEN to open a file for read-only access.

o   Bug fixed: the DUPLICATE statement generated an error whenever it was
    executed.

o   Bug fixed: moving the thumb in the horizontal scroll bar of a WCGRID
    element did not work.

o   Bug fixed: the vertical scroll thumb was not repositioned when the sorting
    order of a WCGRID element was changed.

Apr 23, 2013 (Release 10.2)

o   This release supports the visual theme feature of Windows and can display
    GUI elements using updated styles.  This feature is disabled by default
    but can be enabled via the "Preferences -> Window Options -> Use Theme"
    check box.

o   A new mnemonic, 'WCSTYLE', controls the style of GUI elements.  Normally,
    dL4 for Windows and dL4 Term display GUI elements in the traditional
    style or the Windows theme style according to the setting of
    "Preferences->Window Options->Use Theme".  An application can use the
    'WCSTYLE' mnemonic to override the user selection as follows:

      '0 WCSTYLE'  -  use the latest style supported by the operating system
                      and dL4 (this is currently the same as '2 WCSTYLE')
      '1 WCSTYLE'  -  use the traditional style (as used before dL4 10.2) if
                      supported by the operating system
      '2 WCSTYLE'  -  use the Windows theme style of Windows XP thru Windows 8
                      if supported by the operating system

    The 'WCSTYLE' mnemonic, if used, should be output to the main window
    immediately after an 'XX" mnemonic and before any other windows or any GUI
    elements are created.  All Windows and GUI elements use the same style.
    The 'XX' mnemonic, when output to the main window, clears any current
    application style setting and restores the user selected style.

o   The statement

        SYSTEM 39,"string",S

    will try to open "string" on the user's PC where "string" can be a URL 
    (to open the URL in the default browser), a file (to open the file in the
    application associated with the file extension such as ".pdf"), or an
    executable program.  The variable "S" will be set to zero if "string"
    was successfully opened and non-zero if the program couldn't be opened.
    Unlike SYSTEM 31, the statement does not wait for the open to finish and
    exit.  URLs must begin with "http://" or "https://".  In the default
    configuration, the user will be prompted via a message box to permit or
    deny running the command.  As with SYSTEM 31 and SYSTEM 33, the DWORD
    registry value

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\AllowSYSTEMCmd

    or

    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\WinTerm\AllowSYSTEMCmd

    can be set to one to automatically perform SYSTEM 39 without displaying 
    the message box (note: if set to zero, an "AllowSYSTEMCmd" value in  
    HKEY_CURRENT_USER will require the message box no matter how the
    HKEY_LOCAL_MACHINE value is set).

Dec 28, 2012 (Maintenance Release 10.1.4)

o   Bug fixed: tabbing between GUI elements did not work in a child window
    that contained a WCPAD element with tip text.

o   Bug fixed: WCGRID and WCDATE GUI elements were not displayed as disabled
    if they were created with the "disabled" option (option 1).

o   Bug fixed: if permission ("<nnn>") or other open parameters were placed 
    in front of the destination filename of a DUPLICATE statement, the open
    parameters were included in the filename.

Nov 21, 2012 (Maintenance Release 10.1.3)

o   Bug fixed: in 'WCGRID' or 'WCSORTGRID' GUI elements, some column types,
    such as image buttons, were not displayed as disabled when the grid
    element itself was disabled.

o   Bug fixed: 'WCDATE' GUI elements did not properly display themselves as
    disabled when the elements were disabled.

o   Bug fixed: GUI resource files did not always work unless the resource
    file was set in the current procedure with "CALL SETRESOURCE()".

Nov 16, 2012 (Maintenance Release 10.1.2)

o   Enhancement: the "mask$" parameter in a 'WCGRID' column definition can
    now be used to set the maximum number of characters in edit box columns
    (such as 'WCSTRING') by using a numeric value instead of a string.

    The WCGRID "columns" string is a sequence of column definition strings.
    Each column definition string has the format:

    PChr$(width, name$)+'WCxxxx'
    PChr$(width, name$, options)+'WCxxxx'
    PChr$(width, name$, options, mask$)+'WCxxxx'
    PChr$(width, name$, options, maxlen)+'WCxxxx'

    width    initial column width in grid column units
    name$    column label to be displayed in the header.
    options  an optional numeric parameter, see description below.
    mask$    optional string parameter controlling the display format.  For
             'WCIMAGEBTN' columns, the mask$ value specifies the file path or
             resource name of the button image.
    maxlen   optional numeric parameter controlling the maximum length in
             characters of a 'WCSTRING', 'WCNUMBER', 'WCPRIVATE', or
             'WCEDITDROP' column value.
    WCxxxx   column type specified as 'WCSTRING', 'WCNUMBER', 'WCDATE',
             'WCPRIVATE', 'WCTEXT', 'WCLISTDROP', 'WCEDITDROP', 'WCBUTTON',
             'WCRJBUTTON', 'WCLJBUTTON', 'WCCOLORBTN', 'WCIMAGEBTN',
             'WCCHECK', or 'WCRADIO'.

o   Behavior change: 'WCDATE' GUI elements and grid columns now allow users
    to enter a date as a numeric string without separators.  For example, if
    the system date format is MM/DD/YY, a user could enter "12382" or 
    "01231982" for January 23, 1982.

o   Behavior change: 'WCTEXT' columns in 'WCGRID' GUI elements now return a
    value of "" instead of the displayed value of the read-only column.  This
    is consistent with the behavior of 'WCTEXT' GUI elements and reduces
    network traffic.

o   Bug fixed: if option 4 (send "change" event) was used with a 'WCDATE'
    GUI element, the change event string was not sent if the date was changed
    using the dropdown calendar.

o   Bug fixed: 'WCBQRYBUF' set the special query buffering mode only in the
    window where the 'WCBQRYBUF' mnemonic was printed instead of setting the
    mode for all windows as documented.

o   Bug fixed: 'WCTEXT' columns in 'WCGRID' GUI elements did not display a
    value.

o   Bug fixed: using mode 1 of CALL SWAPF() sometimes caused a memory
    violation when used with global common variables.

o   Bug fixed: the BASIC "check -n" command failed and reported a "Program
    in use" error if the current program had been loaded from a program file.

Oct 10, 2012 (Maintenance Release 10.1.1)

o   Enhancement: the MySQL Full-ISAM driver now supports version 5.5 of the
    MySQL Server.

o   Enhancement: the ODBC SQL driver now translates additional common ODBC
    error codes to dL4 error codes.

o   Enhancement: a block "IF A IF B" line can now contain "THEN" after each
    IF statement as needed to convert BITS mode UniBasic programs.

o   Behavior change: the tools/convert.prf and tools/convbits.prf conversion
    profiles have been changed to rename all ERRMSG$ variables to ERRMSG_$.
    This avoids a conflict with the ERRMSG$() intrinsic function.  If desired,
    the "[Edit]" section of the conversion profile can be modified to use a
    new name other than "ERRMSG_$".

o   Bug fixed: the SQLV$() function and related functions generated two
    carriage return or line feed characters whenever a single such character
    was specified.

o   Bug fixed: in the CONVERT command and the LOADSAVE convert mode, variable
    names starting with "FN" were treated as old style function names even
    when the variable name had too many characters or the wrong characters 
    for a function name.

o   Bug fixed: the MySQL Full-ISAM driver had a small memory leak.

Sep  5, 2012 (Release 10.1)

o   New GUI mnemonics, 'WCGRID' and 'WCSORTGRID', have been implemented to
    create grid style GUI input elements.  The 'WCGRID' mnemonic is used to
    create a grid of unlimited size where the application implements any
    sorting options.  The 'WCSORTGRID' mnemonic is used for smaller grids
    where the user can change the displayed order at any time by "clicking"
    on a column header. Grid boxes consist of a header row and one or more
    data rows.  The rows can contain one or two lines.  The header row
    displays labels for each column and shows which column, if any, is used
    for the sorting order (ascending or descending).  The header column
    separators can be "grabbed" using a left mouse click and used to resize
    columns.  Individual columns can be string boxes, number boxes, date boxes,
    private string boxes, list drop boxes, edit drop boxes, buttons, check
    boxes, or radio buttons.
    
    Vertical and horizontal scroll bars are provided if the number of rows or
    the row width exceeds the size of the grid box.  Users can also scroll
    through the grid by typing up arrow, down arrow, page up, or page down
    keys in a grid cell.

    Syntax:

    PChr$(n,x1, y1, x2, y2, "columns", options, rowh);'WCGRID'
    PChr$(n,x1, y1, x2, y2, "columns", options, rowh, headerh);'WCGRID'

    n       element number of the grid box (must be unique in window)
    x1,y1   Upper left grid coordinates of the rectangle containing the
            grid box and title
    x2,y2   Lower right grid coordinates of the rectangle enclosing the grid
            box and title
    columns a string that defines the columns and column labels.
    options a required numeric parameter, see description below
    rowh    numeric data row height in grid coordinates.
    headerh an optional numeric parameter specifying the height of the header
            row.  If not specified, the data row height is used.

    The "columns" string is a sequence of column definition strings.  Each
    column definition string has the format:

    PChr$(width, name$)+'WCxxxx'
    PChr$(width, name$, options)+'WCxxxx'
    PChr$(width, name$, options, mask$)+'WCxxxx'

    width    initial column width in grid column units
    name$    column label to be displayed in the header.
    options  an optional numeric parameter, see description below.
    mask$    optional string parameter controlling the display format.  For
             'WCIMAGEBTN' columns, the mask$ value specifies the file path or
             resource name of the button image.
    WCxxxx   column type specified as 'WCSTRING', 'WCNUMBER', 'WCDATE',
             'WCPRIVATE', 'WCTEXT', 'WCLISTDROP', 'WCEDITDROP', 'WCBUTTON',
             'WCRJBUTTON', 'WCLJBUTTON', 'WCCOLORBTN', 'WCIMAGEBTN',
             'WCCHECK', or 'WCRADIO'.

    If a long row is to be displayed as two lines, a 'CR' mnemonic must be
    used in the 'columns' string as a line delimiter.

    Radio buttons must be adjacent to form a group.  Radio button groups
    must be separated by a non-radio button column.

    The grid "options" parameter is the sum of the following option values:

    1       Disable and "gray out" the grid box (user can't select the box)
    2       Use the grid box as a tab stop (in element number order)
    4       Send input to window when the user leaves a modified row
            MSC(48) will be set to the row number and MSC(47) will be -1
    16      Don't display first field of row, but return it as part of the row
    32      Any loss of input focus is reported as an input value change

    If not needed, the value of the grid "options" must be zero.

    The column "options" parameter is the sum of the following option values:

    4       Send input to window when the user leaves a modified cell
            MSC(48) will be set to the row number and MSC(47) will be the
            column number.
    16      Don't display first field of drop down list, but return it as the
            value of the cell (WCLISTDROP columns only)
    32      Any loss of input focus is reported as an input value change

    If not needed, the value of the column "options" must be zero.

    As in 'WCLISTGRID' boxes, WCACTIONs 4 and 5 are supported to tell the
    application when a user has scrolled to the beginning or end of the grid
    so that the application can add new grid rows.

    Rows are inserted into a grid by printing the column values as strings
    with 'HT' mnemonics terminating each column.  The final column of a row
    can be terminated by a 'CR' mnemonic or end-of-line character.  The row
    is inserted at the current position which is typically the end of the
    grid but may be changed by printing 'n,r WCSELECT' where 'n' is the GUI
    element number and 'r' is the grid row number (0 origin).  If the 'MH'
    mnemonic is the first character of a new row, that row will be inserted
    at the beginning of the grid instead of the end of the grid without
    changing the current position.  An existing row can be deleting by
    selecting the row using 'n,r WCSELECT' and then printing a line containing
    only a 'DL' mnemonic.  An existing row can be updated by selecting the row
    and then printing the new row contents as a line prefixed with a 'DL'
    mnemonic.

    The 'n WCMARK' and 'n WCUNMARK' mnemonics can be printed to a grid element
    to set a row as currently selected or to clear the selection.  The
    'fg,bg WCMARKCOLOR' mnemonic can be printed to a grid element to set the
    color used to display the currently selected row.

    The 'n,r,c WCFOCUS' mnemonic can be printed to set the input focus on
    row 'r'and column 'c' of the grid element 'n'.

    The 'PREVPAGE' and 'NEXTPAGE' mnemonics can be used to define popup
    messages to inform the user that the end of the grid has been reached or
    to wait while the application is reading additional rows.  The message
    text is set by printing a line to the grid with a 'PREVPAGE' or 'NEXTPAGE'
    mnemonic as the first character of the text.  Any existing 'PREVPAGE' or
    'NEXTPAGE' message will be replaced.  These messages can be deleted by
    printing a line that contains only a 'PREVPAGE' or 'NEXTPAGE' mnemonic.

    Immediately after a grid element is created, the drop-down lists in
    'WCLISTDROP' or 'WCEDITDROP' columns must be initialized by printing each
    list ending with a double 'CR'.  If a 'WCLISTDROP' column used option 16
    ("hidden" field), then each line must consist of the hidden value, an 'HT'
    character, and the associated display value.

    To display grid rows using alternating colors, print a 'fg,bg WCALTCOLOR'
    mnemonic to the grid.

    To display modified cells with specific colors, print a 'fg,bg WCEDITCOLOR'
    mnemonic to the grid.

    To set tool tip text for each cell in a column, print
    
        PChr$(n, c, "text");'WCTIPTEXT';

    where 'n' is the element number of the grid and 'c' is the column number
    starting at 0.

    When using 'WCGRID', the column headers act as buttons.  If "clicked", the
    application receives a function key character ('Fn' where 'n' is the grid
    element number modulo 64) or, if set, the action string.  The application
    can determine which header was selected by using the MSC(47) function to
    determine the zero based column number (MSC(48), the row number, will be
    -1).  The application can then ignore the request or reload the grid in
    the requested order.  An 'n,c,d SORT' mnemonic can be printed to display
    an up arrow (ascending) or down arrow (descending) indicator on header
    column 'c' of the grid 'n' ('d' is 1 for ascending order or -1 for
    descending order).

    When using 'WCSORTGRID', the column headers act as locally processed sort
    control buttons.  The display order is changed immediately after the user
    "clicks" on the header.  The application is not informed about the change
    and will continue to use and see the original row numbers used to populate
    the grid.  If rows are added by the application to the grid after the user
    selects a sorting order, the new rows will be displayed in the selected
    order.  If the user modifies a row after selecting a sorting order, the
    row will NOT be repositioned unless the sorting order is changed.  An
    application can select a sorting order by printing the 'n,c,d SORT'
    mnemonic where 'n' is the element number of the grid, 'c' is the zero
    based column for sorting, and 'd' is 1 for ascending order or -1 for
    descending order.

    If a button in a row is "clicked", the application receives a function key
    character ('Fn' where 'n' is the grid element number modulo 64) or, if
    set, the action string.  The application can determine which button was
    selected by using the MSC(47) function to determine the zero based column
    number and MSC(48) to get the row number.

    Users can enter data in any column other than a WCTEXT column or a push
    button if the column already has a value.  To allow a user to define a new
    row, the row must be filled with default values.

    Grid elements do not return anything if a 'WCQUERY' mnemonic is sent to a
    grid element.  The values of individual rows can be requested by printing
    the 'n,r WCQUERYROW' mnemonic where 'n' is the grid element number and 'r'
    is the desired row.  The value of the row is returned as a carriage return
    terminated line with tab characters ('HT') separating the column values.
    Applications can parse the result string themselves or use the new
    intrinsic CALL GRIDROW() to store the column values.  An application can
    request the values of modified or new rows by printing the
    'n,0 WCQUERYNEW' mnemonic which returns the first such row or an empty
    line if there are no such rows.  Additional modified or new rows can be
    requested by printing the 'n WCQUERYNEW' mnemonic.  All rows returned by
    'WCQUERYNEW' are prefixed by the row number and a tab ('HT') character.

    As with all other GUI mnemonics, the 'WCGRID' and 'WCSORTGRID' mnemonics
    can only be used with dL4Term or in dL4 for Windows.  The grid mnemonics
    cannot be used on Windows 98 or ME.

    Example program:

    Declare Intrinsic Sub GridRow
    Def Struct ROW=Name$[30],3%,Cost,Code$[20]
    Dim Header$[100],Action$[1],Query$[2000],Row. As ROW
    Print 'XX 0 FONTCOLOR 12632256 BACKCOLOR CS';
    Print PChr$(0,2^24-1);'WCSETCOLOR';
    Print 'WCSETFONT';
    ! Create grid element
    Header$ = PChr$(20,"Product name") + 'WCSTRING'
    Header$ = Header$ + PChr$(10,"Cost") + 'WCNUMBER'
    Header$ = Header$ + PChr$(10,"Code") + 'WCEDITDROP'
    Print PChr$(2,10,5,72,10,Header$,4,1);'WCSORTGRID';
    Print '2WCSELECT';
    Print PChr$(0,255*256);'WCALTCOLOR';
    ! Initialize the "Code" dropdown list
    For I = 1 To 5
      Print I Using "Code&&"
    Next I
    Print
    ! Place initial data in grid
    Print 'PREVPAGE' + "Please wait, reading preceding page."
    P = 1000
    N = 1019
    For I = P To N
      Print "Name #";I;'HT';(I + .99) Using "#####.##";'HT';BStr$(I * 12345,16)
    Next I
    Print 'NEXTPAGE' + "Please wait, reading next page."
    ! Set initial position to middle of data
    Print '10WCMARK';
    Print '0WCSELECT';
    ! Set scrolling actions
    Print PChr$(2,4,'F20');'WCACTION';
    Print PChr$(2,5,'F21');'WCACTION';
    Print PChr$(1,36,12,44,14,"Done",0);'WCBUTTON'; ! display 'Done' button
    Print @10,1;"Modify one or more rows and then press the 'Done' button."
    Print 'BQ';
    Do 
      Input Len (1);""Action$
      If Action$ = 'F1'
        Print @0,17;"Done button pressed!"
        Exit Do 
      End If 
      Select Case Action$
        Case 'F2'
          Print @0,3;"Row";Msc(48);"changed"
        Case 'F20'
          ! User is at first row, add more at the start of the grid
          Print '2WCSELECT';
          For I = 1 To 10
            P = P - 1
            If P <= 900
              ! Simulate beginning of file and delete "reading" message
              Print 'PREVPAGE';"Beginning of table"
              Exit For
            End If
            Print 'MH';
            Print "Name #";P;'HT';(P + .99) Using "#####.##";'HT';
            Print BStr$(P * 12345,16)
          Next I
          Print '0WCSELECT';
        Case 'F21'
          ! User is at last grid row, add more at the end of the grid
          Print '2WCSELECT';
          For I = 1 To 10
            N = N + 1
            If N >= 1100
              ! Simulate end of file and replace "reading" message
              Print 'NEXTPAGE'+"End of table"
              Exit For
            End If
            Print "Name #";N;'HT';(N + .99) Using "#####.##";'HT';
            Print BStr$(N * 12345,16)
          Next I
          Print '0WCSELECT';
        Case Else 
          Print "Error input";BStr$(Int(Action$),16)
      End Select 
    Loop 
    Print @0,18;"New or modified rows"
    Print '2,0WCQUERYNEW';
    Do
      Input ""Query$
      If Query$ = "" Exit Do
      Call GridRow(Query$,RowNum,Row.)
      Print "Changed row";RowNum;"  Name = ";Row.Name$;"  Cost =";Row.Cost;
      Print "  Code = ";Row.Code$
      Print '2WCQUERYNEW';
    Loop
    Print 'EQ 0WCFOCUS K3';
    End 

o   A new standard intrinsic, CALL GRIDROW(), has been added to dL4 to ease
    parsing and storing the column values returned from a 'WCGRID' or
    'WCSORTGRID' GUI element.

    BASIC syntax:

        Call GridRow({Mode {,ErrorColumn},} Row$, Variable {,Variable} ...)

    Where:
        Mode        is an optional numeric expression which must be zero
        ErrorColumn is an optional numeric variable which receives the
                    last column number processed.  
        Row$        is a string of column values delimited by 'HT' characters
                    in the format returned by a query to 'WCGRID'.
        Variable    is a string, numeric, date, structure, or array
                    variable which will receive values sequentially from
                    the columns in Row$.

    Example:

        Print PChr$(2,RowNumber);'WCQUERYROW';
        Input ""Query$
        Call GridRow(Query$,Column1Value,Column2Value$,Column3Value)
        Print Column1Value,Column2Value$,Column3Value

o   A new GUI mnemonic, 'WCDATE', has been implemented to create GUI input
    elements for date values.  A date input box consists of an edit box
    similar to 'WCNUMBER' and a drop down button.  The edit box is used to
    display and input date values.  The drop down button, when pressed,
    puts a calendar under the edit box which can be used to select a new
    date.  The edit box displays the date value in a numeric format such as
    "MM/DD/YYYY" with the ordering of year, month, and day as well as the
    separator character controlled by the Windows language/region settings.
    User input is restricted to digits, separator characters, and edit keys.
    The date value can be set by writing a date in the format "YYYYMMDD" 
    followed by a carriage return to the date element.  The date can be set
    to nothing (the initial default value) by writing "" to the date element
    or by the user deleting all characters from the edit box.  When queried,
    a date element returns the date value in the format "YYYYMMDD" if the
    date is set, "" if no date is set, and "00000000" if the date is set but
    invalid.

o   A new 'WCACTION' code, 6,  has been implemented to report double clicking
    on list box elements or buttons without reporting a preceding single click
    code.  This makes it possible for an application to use double clicks for
    a completely different function than single clicks.  WCACTION 6 is
    supported for use with 'WCBUTTON', 'WCLIST', 'WCLISTGRID', 'WCSHOWLIST',
    'WCSHOWLISTGRID', and 'WCPAD'.

    Example:

        PRINT PCHR$(10,6,'F40');'WCACTION';

    Note: when using WCACTION 6, single clicks are not reported until the
    system double click timeout has occurred (typically a .6 second delay).
    A similar delay will occur in list boxes when a user selects a new row
    with the arrow keys.  The double click timing can be changed by setting
    the following DWORD value in the registry to the number of milliseconds
    to wait for the second click:

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\DoubleClickMS

    This value will be used by all windows on the system after dL4 is started.

o   The MySQL SQL and MySQL Full-ISAM drivers now load the MySQL library
    dynamically rather than having the library linked into SCOPE or RUN.
    This change simplifies use of the MySQL drivers because MySQL licenses no
    longer need to be purchased through Dynamic Concepts.  If a user needs
    a MySQL license or support contract, these can be purchased directly
    from a MySQL supplier.  To use the MySQL SQL or MySQL Full-ISAM driver,
    a system will need the "SQL" option enabled in the SSN.

    Because MySQL is no longer linked into dL4 or included in the dL4 
    installation, the MySQL libmysqlclient shared runtime library must be
    installed in order to use the MySQL drivers.  The library is NOT needed
    to use scope or run if the MySQL driver is not used.  On most systems,
    the library is named libmysqlclient.so or libmysqlclient.so.15.  The
    library may be available on your operating system installation media or
    it can be downloaded from mysql.com.  The library should be placed in
    a standard library directory such as /usr/lib or /usr/lib64 or in
    /usr/lib/dl4.  Alternatively, set LD_LIBRARY_PATH or a similar environment
    variable to point at the directory containing the MySQL library.

    The MySQL drivers are no longer supported on the following platforms:
    SCO OpenServer 5 (99), Solaris SPARC (1A), and HPUX (E9).  Please
    contact Dynamic Concepts if you need to use MySQL on these platforms.

o   A new driver, "ODBC SQL", has been implemented so that applications
    can use SQL statements to issue commands and queries to system ODBC
    drivers.  The driver interface is essentially identical to the MySQL SQL
    driver.  SQL statements are executed with SEARCH statements and standard
    READ or READ RECORD statements are used to read the results.  The SQL
    syntax used in the ODBC SQL driver follows the ODBC standard.  All system
    ODBC drivers support the ODBC core set of SQL statements, but may offer
    various features beyond the core requirements.
    
    The ODBC SQL driver is currently supported only on the Windows and
    64-bit Linux platforms but may be implemented on other platforms in the
    future.  On Linux, the driver uses UnixODBC drivers.  Please see the
    operating system and UnixODBC documentation for information on what
    drivers are available and how they can be installed.  The ODBC SQL driver
    can only be used if the dL4 SQL option is enabled in the SSN.

    The ODBC SQL driver recognizes the following transaction control
    statements:

        BEGIN TRAN
        BEGIN TRAN ISOLATION LEVEL READ COMMITTED
        BEGIN TRAN ISOLATION LEVEL READ UNCOMMITTED
        BEGIN TRAN ISOLATION LEVEL REPEATABLE READ
        BEGIN TRAN ISOLATION LEVEL SERIALIZABLE
        COMMIT TRAN
        ROLLBACK TRAN

    The statement keywords are not case sensitive.  In each of the statements
    above, the word "TRAN" is optional and can also be replaced with the word
    "WORK" or "TRANSACTION".  The BEGIN statement starts a transaction at the
    default level or the specified isolation level (see Microsoft or UnixODBC
    documentation for an explanation of isolation levels).  The COMMIT and
    ROLLBACK statements end a transaction.  Transaction control can only be
    used if the system ODBC driver supports transactions.

    The filename in an ODBC SQL OPEN statement has the format "dsn:database"
    where "dsn:" is optional.  The "dsn" can be a system DSN, a user DSN,
    a file DSN, or an inline DSN.  An inline DSN specifies all DSN parameters
    in the filename string and must begin with "driver=..." to select a system
    ODBC driver.  Parameters in an inline DSN are separated by semicolons.
    The following is an example of an inline DSN using the Microsoft SQL
    Server ODBC driver on dL4 for Windows:

        DSN$ = "''Driver=SQL Server;Server=servername''"
        Open #1,DSN$+":database" As "ODBC SQL"

    Inline DSNs will normally need to be quoted because driver names contain
    spaces.

    The ODBC SQL driver recognizes the following open options:

        "Commit=..."    optional boolean value which, if true, tells the
                        driver to commit any transactions that are in
                        progress when the channel is closed.  The default
                        is to rollback any such transactions.
        "DateIsLocal=..." optional boolean value which, if true causes
                        date values to be converted to the local date with a
                        local time of midnight.  This option may be needed
                        in some time zones (such as New Zealand) to obtain
                        the expected local date.
        "Isolation=..." set the default transaction isolation mode to
                        "Read Committed", "Read Uncommitted",
                        "Repeatable Read", or "Serializable".
        "NADNULL=..."   optional boolean value which, if true, converts NULL
                        date values in a result set to "not-a-date" values
                        (if read into date variables).  This option also
                        converts "not-a-date" values in SQLV$(), SQLNV$(),
                        and SQLSNV$() to SQL NULLs.
        "Password=..."  optional password, ignored if used with an inline
                        "driver=" DSN specification.
        "Pswd=..."      optional password, ignored if used with an inline
                        "driver=" DSN specification.
        "RTrim=..."     optional boolean value which, if true, removes all
                        trailing spaces from results (default FALSE).
        "Scroll=..."    optional boolean value which, if false, disables 
                        scrollable result sets (default TRUE).  A scrollable
                        result set allows random access to the rows of a
                        result set but consumes much more memory since it
                        must retain all of the rows in a driver buffer.
        "String=..."    optional boolean value which, if true, allows all 
                        result set values to be read as strings regardless of
                        the actual column date type (default FALSE).  The
                        string option can also be set to "YYYYMMDD" which sets
                        the option to true and also converts date values
                        to the format "YYYYMMDD" when read into strings.
        "Ucid=..."      optional boolean value which, if true, forces all
                        identifiers from SQLN$(), SQLSN$(), SQLNV$(), and
                        SQLSNV$() to uppercase (default FALSE).
        "User=..."      optional user name, ignored if used with an inline
                        "driver=" DSN specification.

    Example:

        Open #5,"(user=public,pswd=xyz,rtrim=t)dbsrvr2:test" As "ODBC SQL"

    The ODBC SQL driver supports numeric, character, date, date/time, and
    binary data types if those types are supported by the selected system
    ODBC driver.  Other data types are supported only if the application
    use SQL conversion functions to produce generate standard data types. 
    If the "scroll=false" option is used, all access to result sets must be
    sequential and the CHF(channel) function cannot be used to obtain the
    number of rows returned.

    The ODBC SQL driver, when a channel is closed, rolls back any pending
    transaction for which a COMMIT has not been executed.  The open option
    "COMMIT=TRUE" can be used to prevent this rollback if desired.  Clearing
    a channel always performs a rollback for pending operations.  The COMMIT
    option can also be specified in the DL4ODBCSQL environment variable.

    The DL4ODBCSQL environment variable can be used to supply default
    values for the DSN, database name, or other options as follows:

        "Catalog=..."   database name.
        "Commit=..."    boolean value which, if true, tells the driver to
                        commit any transactions that are in progress when
                        the channel is closed.  By default, such transactions
                        are rolled back.
        "Database=..."  database name.
        "DateIsLocal=..." boolean value which, if true causes date values to
                        be converted to the local date with a local time of
                        midnight.  This option may be needed in some time
                        zones (such as New Zealand) to obtain the expected
                        local date.
        "DB=..."        database name.
        "DSN=..."       data source.
        "NADNULL=..."   boolean value which, if true, converts NULL date
                        values in a result set to "not-a-date" values (if
                        read into date variables).  This option also converts
                        "not-a-date" values in SQLV$(), SQLNV$(), and
                        SQLSNV$() to SQL NULLs.
        "Password=..."  password.
        "Pswd=..."      password.
        "RTrim=..."     boolean value which, if true, removes all trailing
                        spaces from results (default FALSE).
        "Server=..."    data source.
        "String=..."    boolean value which, if true, allows all result set
                        values to be read as strings regardless of the actual
                        column date type (default FALSE).
        "UCID=..."      boolean value which, if true, forces all identifiers
                        from SQLN$(), SQLSN$(), SQLNV$(), and SQLSNV$() to
                        uppercase (default FALSE).
        "User=..."      user name.
    
    Example:

        DL4ODBCSQL=dsn=dbsrvr2,user=acctng,password=notsecret
        export DL4ODBCSQL

o   The portable contiguous file driver has been extended to support a
    "usecharset=name" option to override the data character set of a file
    and instead use the character set specified by "name".  For example,
    a Universal file could be opened with "usecharset=toggled ANSI" to
    read 8-bit character values written by a UniBasic program.

o   The portable contiguous file driver has been extend to support an
    "allcharset=name" option to create an Indexed-Contiguous file that uses
    the character set specified by "name" for both data and key values.

o   The OPEN statement now supports the 'k' option to build a Universal or
    Huge Indexed-Contiguous file with IRIS keys.

o   The MAKEUNIV utility can now convert files that use IRIS keys.

o   The MAKEUNIV utility now supports a "-a makehuge" command line option
    to convert files to Huge files.  The "MakeHuge=True" option can be used
    in the conversion profile file section to convert individual files to
    Huge files.

o   The DATEUSING$() function now obeys "OPTION DATE FORMAT NATIVE".

o   Automatic string to date conversion in the LET statement now accepts
    purely numeric date values such as YYYYMMDD, YYMMDD, or YYYYMMDDHHNNSS.

o   The OPEN statement now accepts "STYLE" and "TITLE" as synonyms for "STYL"
    and "TITL".

o   Command line processing in SCOPE has been extended to complete partial
    filenames when a horizontal tab character (control-I) is pressed.

o   The Windows Page Printer driver and the "Preferences -> Aux Printer"
    dialog now support a "EOLToCRLF" option to convert either carriage
    return or line feed to a two character carriage return line feed
    sequence.

o   Enhancement: the comma alignment and TAB mnemonic sequences are now
    supported when the Windows printer driver is used in binary mode.

o   Bug fixed: 'WCTIPTEXT' did not work with 'WCEDITDROP', 'WCLISTDROP',
    and 'WCEDITLIST' GUI elements.

o   Bug fixed: filename completion in scope did not work if the partial
    filename was immediately preceded by a comma.

o   Bug fixed; the 'SCRIPT' mnemonic could only be used when running a 
    program via dL4Term and not in dL4 for Windows.

o   Bug fixed: contiguous files with partially encrypted records could not
    be opened without the encryption key.

o   Bug fixed: attempting to write to a file with partially encrypted records
    caused a memory violation.

Dec  1, 2011 (Maintenance Release 9.5.5)

o   Two new open options have been added to the email driver to improve support
    for HTML email with inline images.  To send HTML email with images using
    content ids, use the options "Content=html,AttachAs=relatedmime" or just
    "Content=HTMLMIME".  Restriction: when using inline images, files cannot
    be attached to be saved by the user.

    Example:

        Dim Opts$[100],Cid$[45]
        Opts$ = "(From=someone,Content=htmlmime)"
        Open #1,Opts$ + "somebody" As "Email"
        Print #1;"This is <b>bold</b> and this is <u>underlined.</u>"
        Get #1,-1799,1;Cid$
        Print #1;"<img width=40 height=40 src=''cid:";Cid$;"''>"
        Print #1;"This is after the image."
        Add #1,-1,1;"apicture.jpg","image/jpeg"
        Close #1

o   A new open option has been added to the email driver to simplify
    debugging email server problems.  The "log=file_path" option records
    all communication with the email server to the specified file.

o   Bug fixed: memory faults sometimes occurred when adding or deleting 
    records from FoxPro Full-ISAM files.  Any existing file that causes
    memory faults should be rebuilt to fully correct the problem.

o   Bug fixed: when using the "Sorted Directory" driver, the "SEARCH >"
    operation sometimes skipped the first matching entry.

Jun 28, 2011 (Maintenance Release 9.5.4)

o   Bug fixed: disabling the Preferences menu on the menu bar disabled all
    Preferences options in the system menu.

Jun 14, 2011 (Maintenance Release 9.5.3)

o   Bug fixed: using CALL SETRESOURCE() and the SWAP statement sometimes
    caused the channel table to be corrupted.

o   Bug fixed: the SWAP statement passed the current resource file to the
    child program even when SWAP mode 1 was not being used.

o   Bug fixed: displaying undefined character values in the UniBasic mnemonic
    range caused a random error message.

o   Bug fixed: when using the MySQL driver NADNULL=TRUE option, such values
    were sometimes stored as zero dates rather than as nulls in the MySQL
    table.

Apr 18, 2011 (Maintenance Release 9.5.2)

o   Improve buffer overflow behavior when RUNC is used with standard input
    connected to a socket.

o   Bug fixed: the ITEM number and other ITEM options were not compiled
    correctly for arrays in structures.  This caused READ RECORD, WRITE
    RECORD, and other structure oriented statements to give incorrect
    results.  Programs that use ITEM options on array in structures 
    should be re-compiled.

Apr  4, 2011 (Maintenance Release 9.5.1)

o   A memory violation sometimes occurred when using the MAKERES resource
    file compiler on some platforms.

Mar 23, 2011 (Release 9.5)

o   A new mnemonic, 'SCRIPT', has been implemented to display strings that
    have been defined in a resource file.  When using dL4Term, script strings
    can speed the display of complex GUI screens because scripts are cached
    on the client system and thus only needed to be transmitted the first time
    the script is used.  Script strings are defined in the "[Scripts]" section
    of a resource file using syntax similar to dL4 string expressions.  The
    following resource file defines a script called "Page1" for an input
    screen: 

        [dL4 Resources]
        [Scripts]
        Page1='4GRIDFONT'
        ; Initialize the menus
        += PChr$(101,"&Menu1","")+'WCMENU'
        += PChr$(102,"&Help","")+'WCMENUACTION'
        += PChr$(103,"&Bye","")+'WCMENUACTION'
        += 'WCENDMENU'
        += PChr$(102,1,'F4')+'WCACTION'
        += PChr$(103,1,'F3')+'WCACTION'
        ; Display the form title in double high characters
        += @120,0;+'8FONTSIZE'+"ORDER ENTRY"+'4FONTSIZE'
        ; Display some labels
        += @0,8;+"Name:"+@0,16;+"Address:"+@0,24;+"City:"
        += @200,24;+"State:"+@0,32;+"ZIP:"
        ; Create buttons and edit boxes for input
        += PChr$(2,4,80,36,85,"OK",2)+'WCBUTTON'
        += PChr$(3,144,80,176,85,"Cancel",2)+'WCBUTTON'
        += PChr$(4,284,80,316,85,"Help",2)+'WCBUTTON'
        += PChr$(11,40,8,160,13,"",2)+'WCSTRING'
        += PChr$(12,40,16,160,21,"",2)+'WCSTRING'
        += PChr$(13,40,24,160,29,"",2)+'WCSTRING'
        += PChr$(14,240,24,280,68,"",2)+'WCLISTDROP'
        += PChr$(15,40,32,80,37,"",2)+'WCSTRING'

    The lines beginning with "+=" are continuation lines which append
    characters to the current, "Page1", definition line.  The space after
    the "+=" is not required.

    The following program displays "page1":

        Declare Intrinsic Sub SetResource
        Call SetResource("example.res")
        Print 'XX';PChr$("Page1");'SCRIPT';

    Note that the resource source file shown above must be compiled into
    "example.res" using the MAKERES utility:

        makeres -o example.res example.src

o   The MAKERES utility now supports three new sections: "[Scripts]",
    "[Script Files]", and "[Constants]".  The "[Scripts]" section defines
    script strings (see the 'SCRIPT' mnemonic above) using string expressions
    while the "[Script Files]" section defines script strings by importing
    characters from UTF-8 text files.  The "[Constants]" section is used to
    define numeric and string constants for use in later "[Scripts]" sections.

    In the "[Scripts]" section, script strings are defined using the syntax

        <string resource name>=<string expression>

    String expressions use dL4 syntax and support both string and numeric
    subexpressions.  There is a single string operator, "+", which
    concatenates two string subexpressions or appends a formatted number
    to a string ("string" + number).  String expressions can use the PChr$(),
    "@X;", and '@X,Y;" string functions.  String literal values can be
    defined using either double quotes for character strings ("abc") or
    single quotes for mnemonic strings ('CS').  Numeric expressions can
    use addition ("+"), subtraction ("-"), multiplication ("*"), division
    ("/"), modulo ("MOD"), or negation ("-") operators.  Numeric expressions
    can also use the following functions:

        ABS(<numeric expression>)
        INT(<numeric expression>)
        INT(<string expression>)
        STR$(<numeric expression>)
        LEN(<string expression>)
    
    Both string and numeric expressions can use parentheses to control the
    order of evaluation.  Expressions can use constants defined in any
    preceding "[Constants]" section.

    A string definition can be continued using lines with the syntax

        +=<string expression>

    which appends a string expression to the preceding string definition.  A
    string definition can use any number of such continuation lines limited
    only by memory.

    Constants are defined in the "[Constants]" using the syntax

        <string constant name>=<string expression>

    or

        <numeric constant name>=<numeric expression>

    A constant name consists of 1 to 63 characters beginning with a letter
    and otherwise consisting of letters, digits, or underscores.  Constant
    names are case-insensitive.  As in the "[Strings]" section, the
    "[Constants]" section supports continuation lines for string constant
    using the syntax

        +=<string expression>

    Lines in the "[Script Files]" section have the syntax

        <string resource name>=<file path>

    where "<file path>" is the path of a UTF-8 or 7-bit ASCII text file.

    Resource file source example:

        [dL4 Resources]
        [Constants]
        OKBTN_TIP="Submit the order using the current values"
        HELPBTN_TIP="Display a help window"
        [Scripts]
        Page1='4GRIDFONT'
        ; Display the form title in double high characters
        += @120,0;+'8FONTSIZE'+"ORDER ENTRY"+'4FONTSIZE'
        ; Display some labels
        += @0,8;+"Name:"+@0,16;+"Address:"+@0,24;+"City:"
        += @200,24;+"State:"+@0,32;+"ZIP:"
        ; Create buttons and edit boxes for input
        += PChr$(2,4,80,4 + 32,80 + 5,"OK",2)+'WCBUTTON'
        += PChr$(2,OKBTN_TIP)+'WCTIPTEXT'
        += PChr$(3,144,80,176,85,"Cancel",2)+'WCBUTTON'
        += PChr$(3,"Cancel the order")+'WCTIPTEXT'
        += PChr$(4,284,80,316,85,"Help",2)+'WCBUTTON'
        += PChr$(4,HELPBTN_TIP)+'WCTIPTEXT'

o   The resource file mechanism can now be used to update files in
    application defined directories.  For example, a Java class file on a
    client system could be updated for use with a SYSTEM 31 statement.  The
    files to be updated are placed in the "[Files]" section of a resource
    file with the resource name set to a logical destination directory name
    followed by a slash ("/") and the destination file name.  The registry
    string value

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\ResourceLUMAP

    defines the translation of logical directories to physical directories
    using the same syntax as an LUMAP value ("dir1=path1 dir2=path2").  Each
    time the application prints the mnemonic PChr$("dir/filename")+'RESOURCE',
    dL4 checks if the file resource "dir/filename" has been installed and,
    if not, copies the file resource to the specified directory.  The typical
    use in an application is to print one or more 'RESOURCE' mnemonic sequences
    and then execute a SYSTEM 31 or 33 statement that uses the files.  The
    file resources are only copied the first time the file is used or when
    the resource file is updated.  Please note the files will NOT be copied
    unless the "ResourceLUMAP" registry entry has been defined and the user
    has write access to the destination directories.  The destination
    directories should not be shared between users if multiple users might
    be running the application at the same time.

    Resource file example:

        [dL4 Resources]
        [Files]
        doc/help.pdf=/usr/src/helpfile.pdf
        doc/syntax.pdf=/usr/src/syntax.pdf

    ResourceLUMAP registry value example:

        "doc=C:\users\sam\documents lib=C:\users\sam\library"

    Program example:

        Print PChr$("doc/help.pdf");'RESOURCE';
        Print PChr$("doc/syntax.pdf");'RESOURCE';
        System 31,"helpviewer.exe"

o   Some applications depend on specific font or window options and will not
    work properly if the user changes those options.  It is now possible to
    selectively delete any of the "Preferences" dialogs or disable any of the 
    "Preferences->Font Size" options.  To use this feature, set the registry
    DWORD value

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\UsePrefsMenu

    to the sum of the following hexadecimal options:

             1    enable all dialogs and options
             2    enable "Font Size" dialog
             4    enable "Window Options" dialog
             8    enable "Frame" dialog
            10    enable "Attributes" dialog
            20    enable "Keyboard" dialog
            40    enable "Translation" dialog
            80    enable "Aux Printer" dialog
           100    enable "Screen Print" dialog
         10000    enable font name selection
         20000    enable font size selection
         40000    enable font color selection
         80000    enable "Use Bold Font" check box
        100000    enable "Use Maximum Size" check box
        200000    enable "Stretch to Screen" check box
        400000    enable "Menu Bar" check box
        800000    enable "Edit" menu check box
       1000000    enable "Prefs" menu check box
       2000000    enable rows and columns boxes

    For example, to enable all "Preferences" dialogs, but disallow setting
    the font name, the "Use Bold Font" option, the "Use Maximum Size" option,
    and the "Stretch to Screen" option, set "UsePrefsMenu" to the hexadecimal
    value 7FC601FE (decimal 2143683070).

o   A "-d list" command line option has been added to runw.exe to disable
    various window features and behaviors.  "list" must be one or more of
    the keywords listed below separated by commas:

        "abort" or "a" - ignore the abort key (usually control-D)
        "preferences" or "p"  - disable the preferences menu
        "print" - disable the "print window" function

o   A "Preferences->Translation" dialog has been added to configure
    translating output characters.  This feature is intended for applications
    that depend on terminal emulators that perform similar output translation.
    For example, a UniBasic application might have used some 7-bit ASCII
    values as European characters which were not supported in UniBasic.  This
    translation feature is intended only for printable characters.  Mnemonic
    characters and ASCII control characters cannot be translated.  Characters
    in GUI elements are not translated, but may be in the future.  For
    compatibility with future releases, the translation feature should not
    be configured if GUI elements are used in applications.

o   The SYSTEM 31 and SYSTEM 33 statements, which execute client system
    commands when using dL4Term, have been extended to optionally use
    data files supplied from the application resource file.  Resources in
    SYSTEM commands are specified by the 'RESOURCE' mnemonic followed by
    a resource name.  The resource name must have the same file extension
    needed by the command.  For example, the command

        SYSTEM 31,"notepad " + 'RESOURCE' + "help.txt"

    runs the notepad utility on the client system using the resource
    "help.txt" as the text file to display.  File resources for use in
    SYSTEM commands must be defined in the new "[Files]" section of the
    resource source file:  Example:

        [dL4 Resources]
        [Files]
        help.txt=/usr/src/helpfile.txt

    In this release, if the system command modifies the data file, the
    modifications will be visible whenever a SYSTEM command uses the same
    resource for the same user.  This behavior may be changed in the
    production release of dL4.

o   A "Terminal File Printer" driver has been added to print to text files
    on the client system when using dL4Term.

        Open #1,"filename.txt" as "Terminal File Printer"

    The filename should only be a filename and must not include any path
    information.  The user will be presented with a "SAVE" dialog to specify
    where the file will be stored.  A "(charset=xxx)" open option can be used
    to construct a text file using an alternate character set (such as UTF-8).

o   The "Terminal Printer", "Default Terminal Printer", and "Windows Terminal
    Printer" drivers now treat the 'NR'/'WD' mnemonics as equivalent to the
    'BC'/'EC' mnemonics.

o   The "Portable Indexed-Contiguous" and "Huge Portable Indexed-Contiguous"
    drivers now support an "ALLCHARSET=character-set" BUILD option to set the
    character set of both the data file and the index.  The tools/query utility
    has been extended to print the index character set for a file.  If the
    index character set is set to UTF-8, the key length must be long enough
    to support any multiple byte characters.

o   The "c-tree Index" and "c-tree Huge Index" drivers now support an OPEN
    and BUILD "CHARSET=character-set" option.  If the character set is UTF-8,
    the key length must be long enough to support any multiple byte
    characters.

o   A new intrinsic CALL, DXOpenUTF8(), has been added to support using
    the UTF-8 character set in dynamicXport web pages.  If a dynamicXport
    application uses DXOpenUTF8() instead of DXOpen() and uses UTF-8 based
    web pages, then any Unicode character can be used in input or output
    strings.

o   A new intrinsic CALL, DXOpenCleanANSI(), has been added as an alternative
    for CALL DXOpen() in dynamicXport applications.  If CALL DXOpenCleanANSI()
    is used instead of CALL DXOpen(), all illegal characters will be stripped
    by CALL DXSet() instead of causing a runtime error.

o   A new intrinsic function, SQLSND$(), has been added for use with SQL
    drivers such as the "MySQL SQL".  The SQLSND$() function is identical to
    the SQLSNV$() function except that it tells SQL drivers to format all
    date/time variable values as date only values.

o   Enhancement: the MySQL SQL driver now allows applications to read
    character column results into binary variables ("name?") rather than
    just string variables.  This can be used to read the results of the
    MySQL encryption functions.

o   Enhancement: the BASIC DUMP command can now produce UTF-8 files if the
    "(charset=utf-8)" option is placed before the file name.  Any non-ASCII
    and non-mnemonic characters in string literals will be listed as UTF-8
    rather than using the backslash octal or hexadecimal notation.  Example:

        DUMP (charset=utf-8)file

o   Bug fixed: programs with array members in structures sometimes could
    not be saved on 64-bit systems.  A "Device not accessible" error was
    output by either the SAVE command or by the LOADSAVE utility instead
    of successfully creating the program file.

o   Bug fixed: The RUNW and RUNC utilities did not display STOP messages
    correctly.

o   Bug fixed: the Full-ISAM Bridge driver only initialized data in the first
    filler field.

o   Beta bug fixed: drawing pictures and using other resource file components
    sometimes only worked the first time that a resource file was used.

o   Bug fixed: dL4Login logged errors in user profiles only as a line number.

Oct 26, 2010 (Maintenance Release 9.4.2)

o   Bug fixed: a memory leak occurred when GUI elements were deleted after
    using the WCSETFONT mnemonic.

Sep 27, 2010 (Maintenance Release 9.4.1)

o   The MySQL, MySQL Full-ISAM, and Oracle SQL drivers now support placing
    quotation marks around open parameters such as the user name or password.

o   Enhancement: the tools/bitsdir utility now supports the "<<" and ">>"
    selection options.

o   Behavior change: the tools/makekey utility now warns the user if saving
    a master key file is aborted because the specified passphrase is "".

o   Bug fixed: if a child window extended beyond the screen, the 'NR' and 'WD'
    mnemonics moved the child window to an incorrect position.

o   Bug fixed: deleted records in some files weren't reused causing those
    files to grow unexpectedly large or exceed the maximum file size.  Files
    that have already encountered this problem must be rebuilt to restore
    the deleted record pool.

o   Bug fixed: the MySQL Full-ISAM driver sometimes generated illegal or slow
    queries on tables that didn't have a unique index without null values.

o   Bug fixed: the tools/query utility sometimes reported file date/times
    that were wrong by one hour.

o   Bug fixed: CALL STRSRCH44() returned incorrect results or caused a 
    memory violation if a step value other than 1 was used.

o   Bug fixed: using the "key=eNN" option to create an encrypted index in
    a non-encrypted file caused a "file not found" error instead of a
    "bad key size" error.

Aug  6, 2010 (Release 9.4)

o   Indexes can now be encrypted in encrypted Indexed-Contiguous files.  For
    compatibility and performance, indexes are not encrypted by default.  An
    index is only encrypted if the index was created by SEARCH mode 0 with
    16384 added to the key length or the "key=" option was used and the key
    length was prefixed by an "e" or "E". 

    Example using SEARCH mode 0:

      ! Create an indexed file with a non-encrypted 20 character index 1 and
      ! an encrypted 20 character index 2.
      Dim K$[20],R,S
      Build #1,"<n=''keyname''>[1:40]file"
      R = 10 \ Search #1,0,1;K$,R,S \ If S Stop
      R = 10 + 16384 \ Search #1,0,2;K$,R,S \ If S Stop
      Search #1,0,0;K$,R,S \ If S Stop
      Close #1

    Example using the "key=" option:

      ! Create an indexed file with a non-encrypted 20 character index 1 and
      ! an encrypted 20 character index 2.
      Build #1,"<n=''keyname''>(key=20:e20)[1:40]file"
      Close #1

    The encryption status of an index can be determined using SEARCH mode 12
    which returns the key length of an index with 16384 added if the index
    is encrypted.  SEARCH mode 12 is otherwise identical to SEARCH mode 1
    when used to determine key length.  The tools/query utility has been 
    extended to display the encryption status of indexes as part of the
    key length table.

o   The tools/buildxf utility has been extended so that encrypted indexes can
    be created when building encrypted indexed contiguous files.  An encrypted
    index is specified by prefixing the key length with an "e" or "E".

o   The pipe driver has been extended to allow using the TRANSLATE= option
    without an OPENAS=, PATH=, or OUTPUT= option in the printer script.  The
    translate option will perform character translation using the specified
    printer definition file and pass the output to the script.  This feature
    can be used instead of pfilter so that translation errors, such as
    "bad character", are reported to the application.

o   Behavior change: when converting UniBasic programs, mnemonic octal values
    in string literals will be converted to special UniBasic compatible
    values if the mnemonic value s cannot be converted to dL4 mnemonic values.
    This will most commonly occur when the apparent mnemonic octal values are
    actually binary string values.  In previous release, such untranslatable
    mnemonic values caused a syntax error.

o   The LOADSAVE utility now uses any source file open options such as
    "(charset=stripped ASCII") when opening INCLUDE files.

o   Behavior change: statements which contain ambiguities between the "MOD"
    operator and the "MODIFY" statement keywords ("IF A MODIFY ...") are now
    treated as MODIFY statements if parsing as a MOD operator results in a
    syntax error.  This change improves conversion of UniBasic programs.

o   Behavior change: when converting UniBasic programs, leading plus signs
    are ignored in OPEN statement filename expressions ("OPEN #1,+F$").
    In UniBasic, leading plus signs were legal but ignored.

o   The MySQL SQL driver now supports using the ADD statement to insert
    multiple rows to a table from an array of structures.  This special ADD
    statement offers significantly increased performance when inserting large
    numbers of rows to a table.  The syntax of the statement is

        ADD #c,8;TableName$,ColumnNames$,Rows.[]

    where:

        TableName$      is the name of the table to which the rows will be
                        added.  The table name must match the case of the
                        actual table name.

        ColumnNames$    is a comma separated list of column names to set in
                        each row.  This list can be produced by the SQLN$()
                        function.

        Rows.[]         is an array of structures where each structure contains
                        the values of a row to be inserted.  Note that all
                        elements of the array will be added to the table.  The
                        members in the structure must match the order of the
                        column names in "ColumnNames$".

    The record number of 8 is required and specifies that the ADD statement
    will not start, commit, or rollback a transaction.  If any of the
    insertions fail, an error will be reported but any successful insertions
    will be added to the table unless the application explicitly starts a
    transaction before the ADD statement and uses a rollback.

    Record number 9 can be used in the ADD statement to enable date formatting
    rules similar to those of the SQLDT$() function.

o   The "Arial Mono for dL4" font is now installed as part of dL4 for Windows.

o   Bug fixed: negative numbers in terminal definition files or printer
    definition files were treated as overflow errors on 64-bit systems.

Jul 27, 2010 (Maintenance Release 9.3.3)

o   Behavior change: The MySQL SQL driver now returns "00000000" if a date
    value is zero and the "STRING=YYYYMMDD" option is enabled.  The driver
    returns "*" for zero dates if the "STRING=Y" option is enabled.

o   A new intrinsic function, UBRND(), and a new intrinsic CALL, UBRNDSEED(),
    have been added to dL4 to provide a UniBasic compatible sequence of
    pseudo-random numbers.  These procedures are intended for use in test
    programs that run in both UniBasic and dL4.  In the dL4 versions of such
    test programs, all occurrences of the RND() function can be replaced by
    UBRND() and CALL UBRNDSEED() can be used instead of the RANDOM statement.

    Syntax:

        X = UBRnd(scale)
        Call UBRndSeed(seed)

o   Bug fixed: the 'CT' (clear tabs) mnemonic could not be used with list
    boxes such as 'WCLIST'.

o   Bug fixed: WCLISTGRID and WCSHOWLISTGRID list boxes did not position
    columns correctly.  Short columns were sometimes skipped and the final
    column was offset significantly.

o   Bug fixed: list box thumbs were not sized correctly after an insertion.

o   Bug fixed: when converting programs using the standard conversion profiles
    from the "tools" directory, the ERM function was not converted to the
    ERRMSG$ function.

o   Bug fixed: printing a large array or displaying a large array could not
    be interrupted by the ESCAPE key when using dL4Term.

May 28, 2010 (Maintenance Release 9.3.2)

o   The DL4LOCALE runtime parameter has been extended to accept a "number=xxx"
    value to override the operating system numeric locale information.  The
    "xxx" value is a string specifying the native characters for the currency
    symbol, the group separator, the decimal point, and the digits in that
    order.  The "xxx" value does not need to specify all of the locale
    characters.  For example, to set the group separator and the decimal point,
    it is only necessary to list those characters preceded by the currency
    symbol.  The "xxx" value must be placed in quotation marks if one of the
    characters is a comma.  Please note that the numeric locale information is
    only used if OPTION NUMERIC FORMAT NATIVE is used a program.

    Example:

        DL4LOCALE='number="#.,"'
        export DL4LOCALE

o   The DL4LOCALE runtime parameter has been extended to accept a "date=order"
    value to override the system date ordering.  The "order" value must be one
    of the following three character codes:

        YMD     Year Month Day
        YDM     Year Day Month
        MDY     Month Day Year
        MYD     Month Year Day
        DMY     Day Month Year
        DYM     Day Year Month

o   Due to problems with attachment handling in Microsoft OutLook 2002/XP,
    the email driver now only sends content id headers when the driver can
    determine that the headers are needed.  Content id headers are only needed
    when using inline attachments.  This change should be fully compatible with
    existing applications using the content id feature, but, if desired, the
    previous behavior can be restored by adding a "CONTENTID" option to the
    DL4EMAILSERVER runtime parameter (note that DL4EMAILSERVER value must
    always begin with the email server name or IP address).

o   A "nocontentid" open option has been added to the email driver to disable
    sending content id headers.  This option may be needed to send attachments
    to Microsoft Outlook 2002/XP.  The "nocontentid" option can be used with
    email for any email client, but cannot be used when generating HTML email
    with inline images that use content ids.  The "nocontentid" option can be
    used in either the open options or as part of the DL4EMAILSERVER runtime
    parameter.  Example:

        Open #1,(nocontentid,attachas=mime,from=someone)"somebody" As "Email"

o   The scoansi terminal definition file has been modified to correct a
    problem where vertical bars were displayed as the digit 3 in some
    locales.

o   Behavior change: dl4login now limits the maximum rate of login attempts
    to make dictionary attacks on passwords less practical.  The new "/b"
    and "/r" options in dl4servr can be used to alter the limits.

o   Bug fixed: in list boxes, such as'WCLIST', items could not be selected
    by typing the first character of the item.

o   Bug fixed: fonts sometimes appeared lighter after an 'XX' mnemonic was
    printed.

o   Bug fixed: when using the dl4login terminal service, a bad character
    error was generated if a program tried to draw images to dL4 Term 
    release 9.1.2 or earlier.  Drawing images succeeded only when dL4 Term
    9.3 or later was used.

o   Bug fixed: when using the dl4login terminal service, SYSTEM 31 statements
    failed when using dL4Term 9.1.2 or earlier.

o   Bug fixed: the "-c" option did not work in the tools/checksum utility.

Mar 17, 2010 (Maintenance Release 9.3.1)

o   Bug fixed: CALL DRAWIMAGE() could not display files on a printer.

o   Bug fixed: the 'FITIMAGE' and 'FILLIMAGE' mnemonics could not display
    files on a printer.

Mar 15, 2010 (Release 9.3)

o   To support storage area networks with snapshot features, a new dl4cntl
    utility has been added to suspend all data file updates while a snapshot
    is taken.  Suspending updates ensures that index files aren't saved with
    partial updates which cause broken links and unusable index files.  This
    feature is typically used in a snapshot script with a "dl4cntl -suspend"
    command executed prior to the snapshot and a "dl4cntl -resume" command
    executed when the snapshot is finished.  To use dl4cntl, all dL4 programs
    and the snapshot script must have the "DL4SUSPEND" environment variable
    set to "true" or to the same lock name. The suspend feature should only
    be used for snapshots that can be completed in a short period of time
    (seconds rather than minutes).

    While updates are suspended, any program that attempts to modify, delete,
    or create an indexed contiguous, contiguous, formatted, or FoxPro Full-ISAM
    file will freeze until updates are permitted.  A frozen program will not
    respond to the user typing ESCAPE or to "term evict" commands until updates
    are resumed.  The update suspension does not prevent updates of MySQL 
    databases or output to text files.  The tools/term utility displays the
    status of a suspended program as "Susp".  The PORT mode 3 statement returns
    a status of 11 for suspended programs.

o   Two new GUI mnemonics, 'WCLISTGRID' and WCSHOWLISTGRID', have been
    implemented to create list boxes with a grid-like appearance.  The list
    boxes are identical to standard list boxes ('WCLIST' and 'WCSHOWLIST'),
    but offer these additional features:

        1. Horizontal lines are drawn between items in the list.
        2. Vertical lines are drawn at each tab position defined by the 'ST'
           mnemonic.
        3. The title string can include 'HT' mnemonics to align text to
           the grid columns.
        4. The title string can include color mnemonics.
        5. The new WCACTIONs 4 and 5 are supported to tell the application
           when a user has scrolled to the beginning or end of the list so
           that the application can add new list items.
        6. If an 'MH' mnemonic is the first character of a new item, that
           item will be inserted at the beginning of the list instead of
           the end of the list.
        7. The 'PREVPAGE' and 'NEXTPAGE' mnemonics can be used to mark special
           items to be displayed without grid lines.  These items are placed
           at the beginning and end of the list to inform the user to wait
           while the application is reading additional items.  The 'PREVPAGE'
           or 'NEXTPAGE' must be the first character of the special item.  Any
           existing 'PREVPAGE' or 'NEXTPAGE' item will be replaced.  These
           special items can be deleted from the list by printing a line
           that contains only a 'PREVPAGE' or 'NEXTPAGE' mnemonic.

    The application must add spaces for any desired justification or centering
    of each field.  The application must also truncate, if necessary, the field
    data to prevent overflowing the provided space.

    Like 'WCSHOWLIST', 'WCSHOWLISTGRID' creates a display-only list box that
    does not allow the user to select items.

    Syntax:

    PChr$(n,x1, y1, x2, y2, "label", options);'WCLISTGRID'
    PChr$(n,x1, y1, x2, y2, "label", options);'WCSHOWLISTGRID'

    n       element number of the list box (must be unique in window)
    x1,y1   Upper left grid coordinates of the rectangle containing the
            list box and title
    x2,y2   Lower right grid coordinates of the rectangle enclosing the list
            box and title
    label   title string displayed near the list box
    options an optional numeric parameter, see description below

    The "options" parameter is the sum of following option values:

    1       Disable and "gray out" the list box (user can't select the box)
    2       Use the list box as a tab stop (in element number order)
    4       Send input to window when value changes
    8       Allow selection of multiple items (WCLISTGRID only)
    16      Don't display first field of list, but return only it as the value
            (WCLISTGRID only)
    32      Any loss of input focus is reported as an input value change
            (option 4)

    The default value of "options" is zero.

    As with all other GUI mnemonics, these new mnemonics can only be used with
    dL4Term or in dL4 for Windows.

    Example program:

    Dim Header$[100],Action$[1],Query$[2000]
    Print 'XX 0 FONTCOLOR 12632256 BACKCOLOR CS';
    Print PChr$(0,2^24-1);'WCSETCOLOR';
    Print 'WCSETFONT';
    ! Create list grid element
    Header$ = "Product name" + 'HT' + "Cost" + 'HT' + "Code"
    Print PChr$(2,10,5,72,10,Header$,2);'WCLISTGRID';
    ! Place initial data in list grid
    Print '2WCSELECT';
    Print '20ST 30ST 40ST';
    Print 'PREVPAGE GN' + "Please wait, reading preceding page."
    P = 1000
    N = 1019
    For I = P To N
      Print "Name #";I;'HT';(I + .99) Using "#####.##";'HT';BStr$(I * 12345,16)
    Next I
    Print 'NEXTPAGE GN' + "Please wait, reading next page."
    ! Set initial position to middle of data
    Print '10WCMARK';
    Print '0WCSELECT';
    ! Set scrolling actions
    Print PChr$(2,4,'F20');'WCACTION';
    Print PChr$(2,5,'F21');'WCACTION';
    Print PChr$(1,36,12,44,14,"OK",0);'WCBUTTON'; ! display 'ok' button
    Print @10,1;"Choose a list item and press the 'OK' button."
    Print 'BQ';
    Do 
      Input Len (1);""Action$
      If Action$ = 'F1'
        Print @0,17;"OK button pressed!"
        Exit Do 
      End If 
      Select Case Action$
        Case 'F20'
          ! User is at first list item, add more at the start of the list
          Print '2WCSELECT';
          For I = 1 To 10
            P = P - 1
            If P <= 900
              ! Simulate beginning of file and delete "reading" message
              Print 'MH PREVPAGE'
              Exit For
            End If
            Print 'MH';
            Print "Name #";P;'HT';(P + .99) Using "#####.##";'HT';
            Print BStr$(P * 12345,16)
          Next I
          Print '0WCSELECT';
        Case 'F21'
          ! User is at last list item, add more at the end of the list
          Print '2WCSELECT';
          For I = 1 To 10
            N = N + 1
            If N >= 1100
              ! Simulate end of file and replace "reading" message
              Print 'NEXTPAGE RE'+"End of list"
              Exit For
            End If
            Print "Name #";N;'HT';(N + .99) Using "#####.##";'HT';
            Print BStr$(N * 12345,16)
          Next I
          Print '0WCSELECT';
        Case Else 
          Print "Error input";BStr$(Int(Action$),16)
      End Select 
    Loop 
    Print PChr$(2);'WCQUERY';
    Input ""Query$
    Print 'EQ 0WCFOCUS K3';
    Print @0,18;"List selection = ";Query$
    End 

o   Two new WCACTION codes have been defined for use with the 'WCLISTGRID',
    'WCSHOWLISTGRID', 'WCLIST', and 'WCSHOWLIST' mnemonics.  Action 4, if
    defined, causes a list box to send the associated string whenever the
    user scrolls to the first item in the list box.  Action 5, if defined,
    causes a list box to send the associated string whenever the user scrolls
    to the last item in the list box.  An application can use these new
    actions to add additional items to a list box only when necessary.
    
    Syntax:

    PChr$(n,a,text$);'WCACTION'

    n       Element number of the input element
    a       Action number to be modified:
            4    send text$ when the first list item is displayed
            5    send text$ when the last list item is displayed
    text$   String value used by the action

o   Image files for use with 'WCIMAGEBTN', 'WCDEFAULTIMGBTN', 'FITIMAGE',
    'FILLIMAGE', CALL DRAWIMAGE(), and future GUI image controls can now
    be combined in a single resource file.  Using a resource file instead of
    multiple image files simplifies application installation and improves
    performance when using dL4Term due to client side caching of resource data.
    To use a resource file, an application first calls the new intrinsic
    CALL SETRESOURCE("path") to define the current resource file.  All GUI
    mnemonics and CALL DRAWIMAGE() will then try to load images from the
    resource file.  If the image name can't be found in the resource file
    or if the name contains directory information, dL4 will try to open the
    name as a file.  The current resource file is part of the unit context
    and it is passed to procedures, functions, subprograms, and through
    CHAIN statements.  When returning from an external procedure, external
    function, or subprogram, the current resource file is restored to its
    previous value.  For this reason, CALL SETRESOURCE() should be executed
    in the main program of an application when the application first starts.  

    A resource file is created by using the new MAKERES utility:

        makeres -o resource-file source-file

    The source file is a text file with the following format:

        [dL4 Resources]
        [Pictures]
        resource-name1=image-file-path1
        resource-name2=image-file-path2
          .
          .
        resource-nameN=image-file-pathN

    where:

        "resource-nameN" is the resource name that the program will use
                         for the image in mnemonics and CALL DRAWIMAGE()

        "image-file-pathN" is the path of the image file for the resource.

    A resource name consists of 1 to 63 characters beginning with a letter
    and otherwise consisting of letters, digits, or underscores.  Resource
    names are case-insensitive.

    Example resource source file:

        [dL4 Resources]
        [Pictures]
        helpicon=help.jpg
        gballoon=/u/images/green-balloon.jpg

    Example program:

        Declare Intrinsic Sub SetResource
        Call SetResource("/application/resources")
        Print PChr$(2,10,5,20,7,"helpicon");'WCIMAGEBTN';
        Print PChr$("gballoon",10,10,30,16);'FITIMAGE';

o   Two new mnemonics, 'WCIMAGEBTN' and 'WCDEFAULTIMGBTN', have been added to
    create push buttons with image files displayed on the buttons instead of
    title text.  The mnemonic sequences to create image buttons are

        PChr$(n,x1,y1,x2,y2,"image");'WCIMAGEBTN'
        PChr$(n,x1,y1,x2,y2,"image");'WCDEFAULTIMGBTN'

        PChr$(n,x1,y1,x2,y2,"image",options);'WCIMAGEBTN'
        PChr$(n,x1,y1,x2,y2,"image",options);'WCDEFAULTIMGBTN'

        PChr$(n,x1,y1,x2,y2,"image",options,"disabled");'WCIMAGEBTN'
        PChr$(n,x1,y1,x2,y2,"image",options,"disabled");'WCDEFAULTIMGBTN'

    where
        n           is the GUI element number of the button
        x1          is the upper left column of the button
        y1          is the upper left row of the button
        x2          is the lower right column of the button
        y2          is the lower right row of the button
        "image"     is the path or resource name of the image to be displayed
        options     is the standard GUI element options value
        "disabled"  is the path or resource name of the image to be displayed
                    when the button is disabled.  If a disabled image is not
                    specified, a disabled image button will use an "grayed out"
                    version of "image".

    Other than using images instead of title text, image buttons operate
    exactly the same as text buttons.

o   Two new mnemonics, 'WCCOLORBTN' and 'WCDEFAULTCLRBTN', have been added to
    create push buttons that use the current GUI text and background colors.
    Color buttons are created and used in the same way as standard text
    buttons ('WCBUTTON' and 'WCDEFAULTBTN').  Examples:

        Print PChr$(n,x1,y1,x2,y2,"title text");'WCCOLORBTN'
        Print PChr$(n,x1,y1,x2,y2,"title text");'WCDEFAULTCLRBTN'
        Print PChr$(n,x1,y1,x2,y2,"title text",options);'WCCOLORBTN'
        Print PChr$(n,x1,y1,x2,y2,"title text",options);'WCDEFAULTCLRBTN'

o   Four new mnemonics, 'WCRJBUTTON', 'WCLJBUTTON', WCDEFAULTRJBTN',
    'WCDEFAULTLJBTN', have been implemented to create buttons with right
    justified ("RJ") or left justified ("LJ") title text.

o   A new mnemonic, 'WCTIPTEXT', has been implemented to define tool tip text
    balloons that are displayed whenever a user places the pointer near a
    GUI element that has tip text.  The mnemonic sequence

        PChr$(n,"text");'WCTIPTEXT'

    sets the tip text to be used for GUI element "n" in the current window.
    The mnemonic sequence 'N WCTIPTEXT' can be used to set the maximum width
    of tip text lines and thus select multiline display.  Tip text is limited
    to a maximum of 1000 characters.

o   Two new mnemonics have implemented to control the size of the main window
    when using dL4Term or dL4 for Windows.  The mnemonic 'w,h WALTSIZE' sets
    the main window size to "w" columns and "h" rows" as defined by the
    current grid coordinate setting.  For example, the statement

        Print '100,30 WALTSIZE';

    would set the main window size to 100 columns and 30 rows.  If the new
    window size would place the edges outside the screen, the window will be
    repositioned.  The original window size can be restored using the
    'WCSTDSIZE' or 'XX' mnemonics.

    The WALTSIZE mnemonic does not change the current font size even if the
    new window size exceeds the screen size.  The WALTSIZE and WSTDSIZE
    mnemonics can only be used with the main window.  Windows opened on
    channels can be resized using the SIZE statement.

    The WALTSIZE mnemonic should not be used in combination with the 'NR' or
    'WD' mnemonics.

o   A new mnemonic, 'WCTITLE', has been implemented to change the title of
    an existing GUI control.  The mnemonic sequence
    
        PChr$(n,"New title");'WCTITLE'

    is used to set the title of GUI element "n".  The mnemonic sequence

        PChr$("New title");'WCTITLE'

    is used to set the title of the currently selected GUI element.

o   When using dL4Term or dL4 for Windows, new GET operation codes can be used
    to determine the size of a window in pixels.  The new GET codes are:

        -1042   Number of rows in pixels
        -1043   Number of columns in pixels

    The following example program prints the main window width and height in
    pixels:

        Get #-3,-1042;Rows
        Print "Height in pixels:";Rows
        Get #-3,-1043;Columns
        Print "Width in pixels:";Columns

    Note: channel -3 is a special channel number for the main window.  The
    new GET codes can be used on any channel open to a window when using
    dL4Term or dL4 for Windows.

o   When using dL4Term or dL4 for Windows, new GET operation codes can be used
    to determine the maximum possible size of a window in either grid units
    or pixels.  The new GET codes are:

        -1016   Maximum number of rows in grid units
        -1017   Maximum number of columns in grid units
        -1018   Maximum number of rows in pixels
        -1019   Maximum number of columns in pixels

    The maximum size is defined as the screen size minus space for the window
    frame, a menu bar, and a vertical scroll bar.

    The following example program prints the maximum possible width and
    height in character rows and columns:

        Get #-3,-1016;MaxRows
        Print "Maximum rows:";MaxRows
        Get #-3,-1017;MaxColumns
        Print "Maximum columns:";MaxColumns

    Note: channel -3 is a special channel number for the main window.  The
    new GET codes can be used on any channel open to a window when using
    dL4Term or dL4 for Windows.

o   A new input mode, "activate on special character", has been implemented
    to terminate input whenever the user types one of an application defined
    set of characters.  This mode is similar to "activate on control character"
    ('IOBC') except that the application can define the characters that cause
    input activation.  The special character set is defined using the
    statement "SYSTEM 38,S$" where the string S$ contains the activation
    characters.  After SYSTEM 38 is used to define the special characters,
    the mnemonic 'BACTSP' is used to enable activate on special character
    mode and the mnemonic 'EACTSP' is used to disable the mode.

o   Two new mnemonics, 'BPSWD' and 'EPSWD', have been added to enable and
    disable password input mode.  Using 'BPSWD' input mode, INPUT statements
    will echo input characters as asterisks.  Example:

        Print 'BPSWD';
        Input "Password? " P$
        Print 'EPSWD'

o   Input editing such as moving backward to delete or insert characters has
    always been supported in dL4, but many terminal types do not provide the
    necessary edit keys.  SCOPE now supports standard control characters for
    use on the SCOPE command line, when entering BASIC commands, or in the
    EDIT command.  The control characters are:

        control-L       Move left
        control-R       Move right
        control-T       Toggle insert mode
        control-N       Move to the end of input
        control-O       Move to the start of input
        control-F       Move to next word
        control-P       Move to previous word

    These control characters are defined in the "[InputActions]" section of
    the supplied terminal definition files in the dL4 "term" directory as
    "extended" input actions.  These extended action keys are in addition to
    any terminal specific keys such "Insert" or "Home".  For compatibility
    with applications that read control characters, these extended input
    actions are not active while applications are running unless the actions
    are enabled by the 'XTDEDIT' mnemonic or by CALL INPEDIT().

o   Two new mnemonics, 'XTDEDIT' and 'STDEDIT', have been added to enable
    and disable extended input action definitions in terminal definition
    files.  When 'XTDEDIT' mode is active, any "[InputActions]" entry with
    the "extended" attribute will override the standard input action for a
    character.  The extended input action definitions are normally used for
    the input editing as described above. 

o   Attribute mnemonics such as 'BU', 'EU', 'BBOLD', and 'EBOLD' can now
    be printed to list boxes ('WCLIST', 'WCLISTGRID', ...) as long as the
    mnemonics do not change the current attribute settings.  For example,
    'EU' can be used as long as underlining was not enabled by 'WCSETFONT'.

o   Two new drivers, "SSL Socket" and "SSL Socket Text", have been added to
    support TLS/SSL connections.  The usage of these drivers is identical to
    that of the "TCP Socket" and "Socket Text" drivers except that TLS/SSL
    connections are used.  To ease error handling and because the drivers will
    typically be used with trusted servers, the SSL drivers accept self-signed,
    expired, or other invalid server certificates.  The SSL drivers are 
    available on the Windows (1B), Linux (6D and 64), SCO (99 and 55), and
    AIX (07) platforms.  To use the SSL drivers, the dL4 encryption feature
    must be licensed in the SSN.

o   The email driver has been enhanced to support SMTP servers that use or 
    require TLS/SSL connections.  If the "SSL" option is specified, the email
    driver will connect to port 465 (the SMTP TLS/SSL port) instead of the
    standard SMTP port 25.  To use TLS/SSL connections on port 25, the "USESSL"
    or "SSLONLY" options must be used.  The "USESSL" option tells the driver
    to use TLS/SSL on port 25 if the SMTP server supports TLS/SSL and, if not,
    to use a non-encrypted connection.  The "SSLONLY" option tells the driver
    to connect using TLS/SSL and to reject a non-encrypted connection.  The
    PORT option can be used to specify non-standard port numbers.  Example:

        Open #1,(usessl,from=someone)"somebody" As "Email"

    TLS/SSL connections are supported on the Windows (1B), Linux (6D and 64),
    SCO (99 and 55), and AIX (07) platforms.  To use TLS/SSL connections, the
    dL4 encryption feature must be licensed in the SSN.

o   Two new open options have been added to the Windows Page Printer
    driver to control duplex printing.  The "DUPLEX=True" option selects
    duplex printing with vertical binding.  The option "DUPLEXH=True" selects
    duplex printing aligned for horizontal binding.

    rem dl4opts=openas=selected page printer,lpi=8,cpi=10,duplex=true
    rem
    rem dL4 selected by dialog printer script

o   A new open option, "Formname=name" has been added to the Windows Page
    Printer driver to select a Windows form name.  "name" must match a
    Windows form name.

o   A new open option, "SourceBin=name" has been added to the Windows Page
    Printer driver to select a source/output bin.  "name" can be either one
    of the standard bin names listed below or a bin code number.
    
    Standard bin names: auto, cassette, envelope, envmanual, formsource,
    largecap, largefmt, lower, manual, middle, smallfmt, tractor, upper

o   Two new standard intrinsic functions, SHA1? and ADDSHA1?, have been added 
    to dL4.  SHA1?() returns the SHA1 checksum of the first argument.  The
    argument must be either a binary or a string value.  An optional second 
    binary argument can be used to pass an intermediate value from a previous
    call to ADDSHA1?().  This allows a combined checksum of multiple values to 
    be calculated.  Checksums are calculated against the DIMmed size of 
    strings so that zero characters can be included in the checksum.  To 
    avoid this, simply pass strings with subscripts.  So that string values 
    will produce the same checksums on all platforms, each UNICODE character 
    of a string is forced into a most-significant-byte first ordering for 
    calculation.  To use the SHA1 functions, the encryption option must be
    enabled in the SSN for dL4.

    BASIC syntax:

        Dim chksum?[20], intermediate?[128]

        chksum? = SHA1?(var)
        chksum? = SHA1?(var,intermediate?)

        Clear intermediate?
        intermediate? = AddSHA1?(var)
        intermediate? = AddSHA1?(var,intermediate?)

o   Two new standard intrinsic functions, SHA256? and ADDSHA256?, have been
    added to dL4.  SHA256?() returns the SHA256 checksum of the first argument.
    The argument must be either a binary or a string value.  An optional second 
    binary argument can be used to pass an intermediate value from a previous
    call to ADDSHA256?().  This allows a combined checksum of multiple values
    to be calculated.  Checksums are calculated against the DIMmed size of 
    strings so that zero characters can be included in the checksum.  To 
    avoid this, simply pass strings with subscripts.  So that string values 
    will produce the same checksums on all platforms, each UNICODE character 
    of a string is forced into a most-significant-byte first ordering for 
    calculation.  To use the SHA256 functions, the encryption option must be
    enabled in the SSN for dL4.

    BASIC syntax:

        Dim chksum?[32], intermediate?[128]

        chksum? = SHA256?(var)
        chksum? = SHA256?(var,intermediate?)

        Clear intermediate?
        intermediate? = AddSHA256?(var)
        intermediate? = AddSHA256?(var,intermediate?)

o   A "-h" option has been added to the BASIC LIST and DUMP commands to enable
    hexadecimal representation instead of octal for non-printable characters.

o   The dL4 debugger has been enhanced to support "+" and "-" commands to
    move up and down the call stack.  These commands are short forms of the
    "LEVEL +" and "LEVEL -" commands.

o   The DESCDTOC key part option in the Full-ISAM Bridge driver has been 
    extended to support YYYY, MM, DD, HH, NN, SS, and SSSSS format codes.

o   The LOADSAVE utility has been extended to support M4-style "define()",
    "include()", and "changecom(!)" directives.  These directives are only
    recognized if the "-m" or "-M" option is specified.  The "-m" and "-M"
    options differ in that macro symbols are case-insensitive with '-m" and
    case-sensitive with "-M" (as in M4).  The "define()" directive is used
    to define constant values as shown below:

        define(NAMELEN, eval(2 * 20))
        Def Struct DATAREC
          Member ProductName$[NAMELEN]
          Member 3%,Cost
        End Def
        Dim Name$[NAMELEN]

    The "define()", "eval()", "include()", and "changecom(!)" directives
    are implemented as macro statements and do not produce any lines in
    the resulting program.

o   The CHECKSUM utility in the Tools/ directory now accepts "-sha1" and
    "-sha256" options to generate SHA1 or SHA256 checksums.

o   A "-C" option has been added to the MAKEUNIV utility to continue converting
    a file even if errors occur when reading the source records or keys.  It
    is the responsibility of the user to correct any inconsistencies in the
    converted file due to missing records or keys.

o   The dl4login terminal service utility now supports a "-n" command line
    option which can sometimes improve response time when performing single
    character input.  In this release, the "-n" option can be enabled only by
    changing the dl4login service registry values and restarting the dl4login
    service.

o   Behavior change: the 'IOBS' and 'IOES' mnemonics no longer cause illegal
    character errors.  The mnemonics are now accepted but ignored.

o   Bug fixed: CHF(12xx) and CHF(13xx) did not work on channels open to
    windows when using dL4Term.

o   Bug fixed: Suspending window tracking with WINDOW OFF and WINDOW ON
    with no open windows sometimes caused text to disappear.

o   Bug fixed: when a window was scrolled outside of the standard position,
    WCTIPTEXT did not work for WCPAD GUI elements.

o   Bug fixed: the LOADSAVE utility silently failed without an error message
    if the output filename was illegal.

o   Bug fixed: the LOADSAVE utility silently failed without an error message
    if the "-L" option was used and non-existent line numbers were referenced.

Dec  3, 2009 (Release 9.2)

o   The email driver now generates content id values for all attached files
    so that HTML email can display inline images.  An email application can
    obtain the content id string for an attachment by using a GET statement
    such as:

        Get #C,-1799,N;CID$

    where channel 'C' is open to the email driver, 'N' is the attachment
    number, and 'CID$' is a string variable that receives the content id
    value.  Content id values can be up to 45 characters in length.
    Attachment numbers normally begin with zero for the first attachment,
    but applications can explicitly specify the attachment number in the
    item number of the ADD statement that inserted the attachment (the
    record number must be -1).  Duplicate attachment numbers must not be
    used and will produce inconsistent results.

    Example:

        Dim Opts$[100],Cid$[45]
        Opts$ = "(From=someone,Content=html,AttachAs=usertype)"
        Open #1,Opts$ + "somebody" As "Email"
        Print #1;"This is <b>bold</b> and this is <u>underlined.</u>"
        Get #1,-1799,1;Cid$
        Print #1;"<img width=40 height=40 src=''cid:";Cid$;"''>"
        Print #1;"This is after the image."
        Add #1,-1,1;"apicture.jpg","image/jpeg"
        Close #1

o   The MySQL SQL driver now supports a "DateIsLocal=True" open option to
    enable conversion of date-only column values to a local date and a
    local time of midnight.  This option may be needed in some time zones
    (such as New Zealand) to obtain the expected local date.  The option 
    may also be placed in the DL4MYSQL runtime parameter.

o   The MySQL Full-ISAM driver now supports a "DateIsLocal=True" open option
    to enable conversion of date-only column values to a local date and a
    local time of midnight.  This option may be needed in some time zones
    (such as New Zealand) to obtain the expected local date.

o   The MySQL SQL and Oracle SQL drivers have been extended to support the
    "MAP #c;" statement which restores physical mapping of columns after
    "MAP RECORD" has set a logical mapping.

o   The RENUMBER command now supports a "-e" option to renumber programs that 
    have statements that reference non-existent line numbers instead of
    printing an error message.

o   A new sample library, tools/txt2pdf.lib, has been added to demonstrate
    producing a PDF file from simple text.

o   Behavior change: dL4 normally turns the cursor off in windows unless an
    input is in progress.  Beginning with this release, dL4 will NOT turn off
    the cursor if the application is using single character non-echoed binary
    or 'IOBC' input.  The application is presumed to be handling input editing
    itself and the application is given the responsibility for controlling
    cursor display.  This change improves performance for slow networks.

o   Bug fixed: printing the input mode restore string from "GET #-3,-1083;S$"
    caused echo to be enabled when it should have been disabled.

o   Bug fixed: the screen cursor was sometimes disabled after a SYSTEM
    statement was executed.

Jul  6, 2009 (Maintenance Release 9.1.1)

o   Bug fix: programming a function key with the 'PGMFN' mnemonic sometimes
    caused non-function keys to be programmed to the same value.

o   Bug fix: arrays of structures could not be indexed in conditional
    breakpoints or debugger "LET" commands.

May 22, 2009 (Release 9.1)

o   The major release number of dL4 has been increased from 7 to 9 to
    match the major release of UniBasic.  This numbering makes it
    easier to support combined dL4 and UniBasic licenses on Unix and
    Linux systems.

o   Global variables can now be created by "OPTION GLOBAL COM ON" and the COM
    statement.  The new program option causes variables in COM statements to
    be passed to external procedures and to all subsequent programs invoked by
    CHAIN, CALL, or SWAP.  Global COM variables can also be passed to spawned
    programs using a new SPAWN statement mode.  Unlike traditional COM
    variables, global COM variables do not require each program to receive and
    pass on each COM variable.  For example, if program "A" calls program "B"
    which calls program "C", program "C" can use global COM variables from
    program "A" even if program "B" does not use those global COM variables.

    Each program that defines or uses global COM variables must have the
    GLOBAL COM option enabled.  If a program does not have the GLOBAL COM
    option enabled, any existing global COM variables will persist and can
    be used by subsequent programs.  Global COM variables are not preserved
    by "long" CHAIN statements or between SCOPE command lines.  Global COM
    variables are created when COM statements allocate variables.  Once
    created, a global COM variable can be accessed by any program declaring
    the same variable name in a COM statement or using a unDIMmed variable
    of the same name.  If a program uses "OPTION GLOBAL COM ON" and "OPTION
    AUTODIM OFF", then global COM variables must be explicitly imported with
    a COM statement.  To explicitly import a string or array global variable
    with a COM statement, the dimensions must match the original values or
    the variable will be re-dimensioned.  Global COM structure variables must
    be imported with a COM statement or declared with the new DECLARE DIM
    statement in order to define the structure type.

    An error 289, "Error initializing global COM variables", will occur if
    an internal error is detected when passing global COM variables to a
    SPAWNed program.

    In the following example, the program "main" creates two global COM
    variables and then calls "subpgm" which uses the COM variables.

    Program "main"

        Option Default Global Com On
        Com 3%,CurrRec,CustName$[60]
        Dim 2%,N
        CurrRec = 10
        CustName$ = "Example"
        N = 19 ! Note that N is not a global variable
        Call "subpgm"

    Program "subpgm"

        Option Default Global Com On
        Print CurrRec,CustName$
        Print N ! Displays "0" because N isn't a global variable
        End

o   Two new statements, DECLARE COM and DECLARE DIM have been added so that
    programs can define the structure type of global COM variables.  Example:

    Declare Dim Rec. As CUSTREC

o   Additional modes have been added to the SWAP statement to control how
    global COM variables are passed.  Modes 1 and 2 (the default) pass
    global COM variables to the SWAP program, but the parent program will
    not see any changes in the COM variables when the SWAP program exits.
    The new mode 3 (pass COM and open channels) and mode 4 (pass COM only)
    pass global COM variables and return any changed values to the parent
    program.

o   Additional modes have been added to the intrinsic CALL SwapF() to control
    how global COM variables are passed.  Modes 1 and 2 pass global COM
    variables to the SWAP program, but the parent program will not see any
    changes in the COM variables when the SWAP program exits. The new mode 4
    (pass COM only) and mode 5 (pass COM and open channels) pass global COM
    variables and return any changed values to the parent program.

o   An optional mode parameter has been added to the SPAWN statement to control
    whether global COM variables are passed.  Global COM variables are passed
    to the spawned program only if mode 1 is specified.  If the mode is not
    specified or if the mode is zero, global COM variables are not passed.
    
    Syntax:

        SPAWN Program$,PortNum
        SPAWN Mode,Program$,PortNum

    Example:

        Spawn 1,"runreport",P  ! Spawn program and pass global variables

o   The SIZE command in SCOPE BASIC mode has been extended to display the
    total size of the global COM variables.

o   When converting IMS programs, IMS GDIM statements are converted to COM
    statements.  The statement "OPTION DEFAULT DIALECT IMS1" or "OPTION 
    DEFAULT GLOBAL COM ON" must be added to enable global COM variable
    behavior.  The conversion profile in the IMS2DL4 utility adds both of
    these options as it converts programs.

o   When converting IMS programs, IMS style structure definition and
    DIM statements are converted to dL4 format.

o   When converting IMS programs, long function names with a single
    argument without parentheses ("DTDAY$ N") are now accepted.

o   "TRAP" statements in IMS programs are now translated to ERROR statements
    when converting IMS programs.

o   A new program option, "OPTION DIALECT IMS1", has been implemented to 
    enable IMS compatibility features beyond those of "OPTION DIALECT IMS".
    The new IMS1 option enables "OPTION GLOBAL COM ON" and "OPTION CALL 
    DL4ERROR ON".

o   A new program option, "OPTION CALL DL4ERROR ON", has been implemented to
    enable calling the subprogram "dl4error" whenever an error occurs before
    invoking any local error handler (such as TRY or IF ERR).  If the debugger
    is in use, the error will be reported in the debugger before the "dl4error"
    subprogram is run.  The subprogram is loaded by first searching the
    directory of the current program and then the normal program search list
    (LIBSTRING and/or DL4LUST).  If the subprogram "dl4error" cannot be found,
    normal error handling will proceed.  The "dl4error" subprogram is passed
    four parameters: the error number, the line number of the error, the
    name of the program in which the error occurred, and the error handler
    status.  The error handler status is 0 if there was no IF ERR, ERRSET, or
    ERRSTM handler set, 1 if there was, and 2 if the error handler was set
    to a REM statement ("IF ERR 0 REM").  If an error occurs within the
    "dl4error" subprogram, normal error handling is used and "dl4error" will
    not be called recursively.

o   A new statement, CHAIN WRITE IF, has been added to perform a CHAIN WRITE
    without reporting an error if any of the variables weren't dimensioned.
    Example:

        CHAIN WRITE IF SubTotal, Filename$

o   When converting IMS BASIC programs, CHAIN READ and CHAIN WRITE statements
    are now converted to CHAIN READ IF and CHAIN WRITE IF statements to
    duplicate the less restrictive rules used by IMS BASIC. 

o   A new intrinsic CALL, IMSChkCh(), has been added to improve the
    performance of converted IMS BASIC programs.  The CALL can find
    which channel, if any, a specified filename is open on.  If the
    specified filename is "", the CALL returns the read/write status
    of the specified channel and the filename open on that channel.
    The return status has the values 0 (not open), 1 (open for reading
    only), and 2 (open for reading and writing).

    BASIC syntax:

        Call IMSChkChnl(Channel,Filename$,Status)
        Call IMSChkChnl(Mode,Channel,Filename$,Status)

    Where:
        Mode        is an optional and ignored parameter.
        Channel     is the channel on which the filename is open or
                    receives the channel number on which Filename$ is open.
        Filename$   is the filename to search for or, if the original
                    filename is "", receives the filename open on the
                    specified channel.
        Status      receives the channel status (0 for not open, 1 for
                    read only, and 2 for read/write).

o   A new intrinsic CALL, FieldVal(), has been added to improve the
    performance of converted IMS BASIC programs.  CALL FieldVal() validates
    whether string contains a valid alphabetic, floating point, integer,
    date, or month value according to the specified mode.

    BASIC syntax:

        Call FieldVal(Mode,Field$,Status)

    Where:
        Mode        is the field format to check for.
                    Mode 1  - check if Field$ contains only alphabetic or
                              space characters.
                    Mode 2  - check if Field$ contains an integer or
                              floating point number (no exponent) with
                              optional leading spaces.
                    Mode 4  - check if Field$ contains an integer value
                              with optional leading spaces.
                    Mode 8  - check if Field$ contains a MDDYY, MMDDYY,
                              MDDYYYY, or MMDDYYYY date value with optional
                              leading or trailing spaces.
                    Mode 16 - check if Field$ contains an integer month
                              number (1-12) with optional leading spaces.
        Field$      is the field value to validate.
        Status      is set to 0 if the field is valid and 1 if the
                    field is not valid.

o   A new intrinsic function, DTPart(), has been added to improve the
    performance of converted IMS BASIC programs.  The function extracts
    parts of an IMS date/time value.

    BASIC syntax:

        PartValue = DTPart(IMSDateValue, Part)

    Where:
        IMSDateValue    is an IMS date value DDDDD.SSSSS.
        Part            selects the date/time value to be extracted from
                        IMSDateValue.
                        1 - year (1 - 9999)
                        2 - quarter (1 - 4)
                        3 - month (1 - 12)
                        4 - day of year (1 - 366)
                        5 - day of month (1 - 31)
                        6 - day of week (0 - 6)
                        7 - week of year (1 - 53)
                        8 - hour of day (0 - 23)
                        9 - minute of hour (0 - 59)
                        10 - second of minute (0 - 59)

o   A new intrinsic function, DTFormat$(), has been added to improve the
    performance of converted IMS BASIC programs.  The function formats
    an IMS date/time value according to a mask.

    BASIC syntax:

        Date$ = DTFormat(IMSDateValue, Mask$)

    Where:
        IMSDateValue    is an IMS date value DDDDD.SSSSS.
        Mask$           is a DateUsing$() style mask.

o   A new intrinsic CALL, SplitStr(), has been added to split a string into
    substrings according to a specified separator character.  CALL SplitStr()
    is compatible with the IMS CALL $PARSE or CALL 22.

    BASIC syntax:

        Call SplitStr({Mode,} {Status,} Sep$, Src$, Field1$ {,Field2$}...)

    Where:
        Mode    is 0 or unspecified for standard mode which skips to the
                next "Fieldn$" parameter if the current parameter is too
                small for the current field.  Mode 1 truncates and ignores
                any extra characters.  Mode 2 reports overflow as a status
                of 1 or an error 38 if the status parameter isn't used.
        Status  is a numeric variable in which status is returned.
        Sep$    is a string value specifying a single character terminator.
        Src$    is the source string value to split.
        FieldN$ are string variables in which field values are returned.
                If the number of field variables exceeds the number of
                fields, the variable following the final field will be
                set to "".

o   A new intrinsic CALL, IMSCheckDigits(), has been added to support IMS
    programs.  The CALL is similar to CALL CheckDigits() checking if a
    string contains any non-digit characters, but the status is returned in
    a numeric parameter instead of causing an error.  An all numeric string
    or an empty string ("") return a status of 0.  A status of 1 is returned
    if a non-digit character is found.

    BASIC syntax:

        Call IMSCheckDigits(S$,R)

    Where:
        S$      is a string value to check.
        R       is a numeric variable in which the status is returned
                (0 if only digit characters are found and 1 if any
                non-digit characters are encountered).

o   A new intrinsic CALL, IMSCheckNumber(), has been added to support IMS
    programs.  The CALL is similar to CALL CheckNumber() checking if a
    string contains an invalid number string, but the status is returned in
    a numeric parameter instead of causing an error.  A valid number string
    or an empty string ("") return a status of 0.  Any other string value
    returns a status of 1.

    BASIC syntax:

        Call IMSCheckNumber(S$,R)

    Where:
        S$      is a string value to check.
        R       is a numeric variable in which the status is returned
                (0 if a valid number of "" is found and 1 if an invalid
                number is encountered).

o   A new intrinsic CALL Redir() has been added to support converted IMS
    programs.  The CALL causes INPUT statements to read from a specified
    channel or file.  Normal input is restored when the channel or file
    reports an error or end of file.

    BASIC syntax:

        Call Redir(Channel)
        Call Redir(Path$)

    Where:
        Channel     is a channel open to a text file.
        Path$       is a path of a text file.

o   New intrinsic CALLs InitBuf(), ReadBuf(), and WriteBuf() have been added
    to support converted IMS programs.  The CALLs are used to create and
    access a virtual record in memory which is used to pass values between
    CHAINed or SWAPped programs.

    BASIC syntax:

        Call InitBuf(Size)
        Call ReadBuf(Offset {,Variable})
        Call WriteBuf(Offset {,Variable})

    Where:
        Size        the number of bytes to allocate for a virtual record
                    which is stored in memory and persists between programs.

        Offset      the byte offset to write to or read from within the
                    virtual record.

        Variable    one or more numeric or string variables to write from
                    or read to.

o   A new intrinsic CALL InpEdit() has been added to support converted IMS
    programs.

    BASIC syntax:

        Call InpEdit(Mode)

    The "Mode" parameter is a numeric expression containing a sum of the
    following option values:

        The value 1, if set, enables extended input edit features such as
        insert toggling and causes control characters to be ignored if
        entered as data.

        The value 2, if set, enables lowercase to uppercase conversion.

        The value 4, if set, is not supported and causes an error 38.

o   A new intrinsic string function, GMTDATEUSING$(), has been added to
    format dates using GMT dates and times.  The GMTDATEUSING$() function
    is otherwise identical to the DATEUSING$() function.

o   Enhancement: the intrinsic CALL INPBUF now accepts an optional channel
    number as the first argument.

o   The Full-ISAM Bridge driver DTOC() and DTON() functions have been extended
    with ".sssss" and "sssss" date mask format codes.  These codes support IMS
    style date/time values in which the integer portion of a number is the
    date in days and the first five digits to the right of the decimal point
    contain the time of day in seconds since midnight.  For IMS compatible
    values, the DDDDDBASEDATE option must be used in the profile to specify
    a base year of 1900.  Example:

        [FullISAMBridge]
        File=database.table
        OpenAs=MySQL Full-ISAM
        OpenInProfileDirectory=False
        DDDDDBaseDate=1900
            .
            .
        Field=DATE1N,60,3%,,,DTON("DDDDD.SSSSS")
            .
            .
        Field=DATE2,100,11,,,DTOC("DDDDD.SSSSS")

o   A new key part option, DESCDTOC(), has been implemented to support "DDDDD"
    or "DDDDDD" format descending key parts in bridge profiles when used with
    Microsoft SQL Server.  The DESCDTOC() option is similar to the DTOC()
    option.  The option is currently restricted to "DDDDD" or "DDDDDD" masks.
    The option value is generated by subtracting the date in days from 100000.
    Example:

        KeyPart=INVDATE,0,5,"","0123456789",DESCDTOC("DDDDD")

o   The Full-ISAM Bridge driver has been extended to support a DESCDTOCBASE
    option in the main bridge profile section to change the offset value
    used by the DESCDTOC() translation function from its default value of
    100000.  Example:

        DESCDTOCBASE=99999

o   The IC2FI (tools/ic2fi) utility has been extended to support the new
    DESCDTOC() key part option and the DESCDTOCBASE option.

o   The IC2FI (tools/ic2fi) utility has been extended to accept "FILE=" lines
    in the bridge profile.

o   The IC2FI (tools/ic2fi) utility now accepts underscores in index names.

o   The Full-ISAM Bridge driver now supports a "NOSORT" option on key part
    definitions to allow a key part to use a DTOC() or DTON() date mask that
    does not sort correctly (such as "MMDDYYYY").  This option is intended
    to be used temporarily while converting a file with the IC2FI utility.
    When used, the NOSORT option must precede the DTOC() or DTON() option.

o   The Full-ISAM Bridge driver now supports options to skip any keys that
    have values matching the keypart prefix values.  The "SkipIfPrefix=True"
    option can be set in the first section of the bridge profile to enable
    skipping on all indexes.  A "Skip" option can be added to one of the key
    parts in an index definition to enable skipping on that specific index.
    Skipping should be enabled when using ROPEN to read through record locks
    so that the driver will ignore any temporary records.  This option should
    not be used unless the prefix values are such that they will never match
    any actual key values.  Example:

        KeyPart=NAME,0,16,"ZZZZZZZZ","0123456789",SKIP

o   The Microsoft SQL Server Full-ISAM driver has been extended to support
    the DESCENDING option on index members.

o   The Microsoft SQL Server Full-ISAM and MySQL Full-ISAM drivers now
    support CALL READREF().  As in all other drivers, record locking is now
    disabled only when both the write protection ("W") and locking disabled
    ("L") options are used.  In previous releases, the write protection 
    option by itself disabled record locking.

o   Behavior change: the Microsoft SQL Server Full-ISAM driver now supports
    database identifiers (such as column or index names) of up to 127
    characters.

o   The 'PGMFN' and 'PGMHELPFN' mnemonics have been extended to support
    programming of any key.  The mnemonic sequence 
    
        PChr$("c","text");'PGMFN'

    will program the key that normally produces the character "c" to generate
    the string "text".  A new check box, "Program Keys", has been added to
    the "Preferences -> Window Options" dialog to allow the user to disable
    keyboard programming.  This option can be used to immediately disable
    programming during application development if the keyboard is programmed
    incorrectly.

o   A new mnemonic, 'WCCU', has been defined to simplify clearing the values
    of a range of GUI elements.  The mnemonic string '5,7WCCU' clears the
    GUI elements 5, 6, and 7.  The upper limit of the element range can
    exceed the highest existing element number.  The 'WCCU' mnemonic can also
    be used with a single parameter to clear a single GUI element.

o   The GUI libraries in the tools directory have been enhanced.  A new
    library, gui4.lib, has been added.

o   All "Preferences" dialogs have been changed to apply options to the
    current session.  The new option values will take effect when the "OK"
    or "Apply" buttons are selected.  It is no longer necessary to restart dL4
    to use the new option values.  The "Font Size", "Window Options", and
    "Frame" dialogs have "Apply" buttons which apply any changes but leave the
    dialog active so that changes can be tested before exiting the dialogs.
    Selecting the "Cancel" button does not undo changes made by the "Apply"
    button.

o   A "Preferences->Attributes" dialog has been added to configure how
    character attributes such as underline, reverse video, or protection
    are displayed.  The dialog can be used to map any attribute or combination
    of attributes to a different set of attributes or colors.  For example,
    the logical attribute of "protected" normally causes characters to be
    displayed as dimmed.  In the "Attributes" dialog, this can be changed so
    that protected characters are displayed as green characters by selecting
    the logical attribute "Protected" in the "Current Definition", setting
    the color with the "Foreground" button, and then selecting the "Set"
    and "OK" buttons.  Changing the attribute mapping effects all future
    output, but it does not redraw the current window or history buffer.
    The displayed attributes of protected characters can be changed, but
    protected characters always have the attribute of "protected".

o   The "Preferences->Font" dialog has been replaced with a new "Font Size"
    dialog.  The new "Font Size" dialog has color buttons to control the
    default foreground and background colors.  Check boxes have been added to
    select a "Maximum Size" or "Stretch to Screen" window.  A maximum size
    window uses the maximum size of the selected font that allows the window
    to fit on the screen.  The "Stretch to Screen" window is similar to the
    maximum size window but may change the character aspect ratio so that the
    window is larger (note that "stretching" will have no effect if there is
    insufficient space to add one pixel to each character or if the font does
    not support changing the aspect ratio).
    
    Changes in the font, font color, font size, or window size are applied to
    the main window when the "OK" or "Apply" buttons are selected.  Only the
    window text is redrawn: all non-character graphics and pictures will 
    disappear.  All graphical elements such as buttons, edit boxes, or list
    boxes will be unchanged.  Due to these limitations, it is best to apply
    font changes before or after running applications.  Selecting the "Cancel"
    button does not undo changes made by the "Apply" button.

o   The "Preferences->Window" dialog has been renamed as "Window Options".
    All options in the dialog are applied immediately to the current session
    when the "OK" or "Apply" buttons are selected.  The foreground and
    background color buttons have been moved to the new "Font Size" dialog.
    The "CL/CE History" check box controls whether text deleted by the 'CL'
    or 'CE' mnemonics is added to the history buffer (if the history buffer
    itself is enabled).  The "Shade History" check box controls whether text
    in the history buffer is displayed using the original colors or with
    inverted colors.  Dimming of protected characters is now configured
    in the "Preferences->Attributes" dialog and so the "No Dim BP" check box
    has been removed.

o   The "Preferences->Frame" dialog has been modified to remove the "Menu Bar"
    check box.  The "Menu Bar" check box is now displayed only in the
    "Window Options" dialog.  All options in the dialog are applied immediately
    to the current session when the "OK" or "Apply" buttons are selected.

o   A "Mute" item has been added to the "Edit" menu to disable the terminal
    bell.  Selecting the "Mute" item toggles the state of the mute switch.
    If a check mark is displayed, the bell is muted.

o   The "Preferences -> Keyboard" dialog has been enhanced to allow "Unicode
    to Input Action" to modify parts of existing Unicode ranges instead of
    requiring the user to delete and then reenter the unchanged portions.

o   A new "-S" option for the LOADSAVE utility adds an initial comment to
    the output program file that specifies the date, time, source path, and
    current user when the program was compiled.

o   A new runtime parameter, "DL4CONTIG", is now supported to define the
    default character set and numeric map type for newly created indexed
    contiguous and contiguous files.  The DL4CONTIG parameter supports
    the CHARSET, NUMMAP, and COUNTUSED options used in the BUILD statement.
    For example, setting DL4CONTIG to "charset=IRIS,nummap=IEEE" would
    cause the statement

        BUILD #1,"[10:40]file"

    to build a contiguous file that used the IRIS character set and IEEE
    numerics.  This new feature can be used to make new files match the
    format of old files so that MAT READ and MAT WRITE statements can
    copy records as strings even though the records contain non-standard
    numeric formats.

o   A minimal UniBasic program file driver has been added so that the QUERY
    utility can report UniBasic program files as such rather than as text
    files.

o   Enhancement: the FILE command and all program dumps now display channel
    functions up to 16.

o   Behavior change: the command history in SCOPE now retains the current
    history position so that repeated "down arrow" commands can be used to
    report a previous sequence of commands.

o   Behavior change: the email driver no longer inserts multiple spaces when
    breaking a long subject string into multiple lines.  The driver now tries
    to break the subject string on a word boundary and otherwise inserts a
    single space.

o   A new function, MSC$(10), has been implemented to return the path of
    the program, if any, that CHAINed to the current program.

o   The dl4login terminal service utility now sets the environment variables
    "DL4LOGINNAME" to the user login name and "DL4LOGINDOMAIN" to the user
    login domain name.  These values can be used in user profiles to set
    values expected by applications such as "LOGNAME".

o   The SYSTEM statement mode has been extended to control whether the
    WINDOW OPEN statement creates a window with scrolling enabled.  The
    statement "SYSTEM 36" causes the next WINDOW OPEN statement to create a
    non-scrolling window.  The normal mode of creating windows with scrolling
    is restored after the execution of a WINDOW OPEN statement or it can be
    explicitly restored by the statement "SYSTEM 37".

o   The syntax 'BUILD #c;"X",..." is now accepted and converted to a standard
    BUILD statement when converting IMS programs.

o   Behavior change: the number of records value in file specifications (the
    "N" in "[N:R]") is now optional when building contiguous or indexed
    contiguous files.

o   Arrays of structures can now be passed as "AS *" parameters.  An "AS *"
    parameter that is an array use subscripts so that individual structure
    elements can be passed to other routines or to intrinsic such as SQLV$().

o   The tools/query utility now allows quotation marks around the driver
    name if the "AS" option is used.

o   The number of Indexed Contiguous file indexes that can be simultaneously
    opened is no longer restricted by the value of the ISAMFILES runtime
    parameter.  The internal tables are dynamically expanded as necessary
    if ISAMFILES is too small.  Note that operating system limits may still
    apply on the maximum number of open files or record locks.

o   Rules for converting "CALL $CALLSTAT" have been added to the IRIS and BITS
    program conversion profiles tools/convert.prf and tools/convbits.prf.

o   Behavior change: records in converted UniBasic data files that exceed the
    standard Portable or Universal file size limits but are within the 2
    gigabyte size limit are now accessible and will no longer cause illegal
    record number errors.  The MAKEUNIV utility can now convert non-portable
    UniBasic files that exceed the standard Portable or Universal file size
    limits.

o   A new channel function, CHF(17cc), has been implemented in the MySQL SQL
    driver to return one if the current result set has one or more rows and
    zero if the result set is empty.  This provides compatibility with the
    Oracle SQL driver.

o   Beta behavior change: the "Preferences -> Font Size" dialog no longer
    changes all of the text to the current foreground and background colors
    when a font change is applied or saved.  Text colors are now changed
    only in text that used the previous colors and only if the foreground or
    background colors have been updated.

o   Bug fixed: the "CHECK -n" command sometimes caused memory violations.

o   Bug fixed: programs that used structure variables exceeding the maximum
    number of members did not report errors when SAVEd.  Structure variables
    in dL4 cannot have more than 255 members or more than a total of 1023
    members including members in sub-structures.

o   Bug fixed: fonts were not displayed correctly on some systems such as
    Windows 98 systems with only 16 color displays.

o   Bug fixed: the "line GO" command in the debugger did not work correctly
    if "line" was the current line number.

o   Bug fixed: each open of the MySQL SQL driver caused a small memory leak.

o   Bug fix: the LOADSAVE utility did not report I/O errors encountered
    while reading the source file.

o   Bug fix: the IC2FI (tools/ic2fi) utility could not create new bridge
    profiles on Windows systems.

o   Bug fixed: when using "OPTION ARGUMENT CHECKING IS WEAK" and a CALL
    statement was at the end of a single line IF and the final argument was
    an array, the CALL statement was not properly encoded causing an error
    208 at runtime.  Programs where this error occurs must be recompiled
    to correct the encoding.

o   Bug fixed: the statement "CALL ENV(1,Name$,Value$)" returned without
    changing "Value$" if the environment variable value was larger than the
    DIMmed size of "Value$".

o   Beta bug fixed: "SPAWN 1" failed if the number of global COM variables
    was less than 25.

o   Beta bug fixed: the number of global COM variables could not exceed 24.

o   Beta bug fixed: "OPTION CALL DL4ERROR ON" only passed the first three
    parameters to "dl4error" and did not pass the error handler status.

o   Beta bug fixed: CALL ReadBuf() returned random values if data was read
    from an offset that hadn't been previous written with CALL WriteBuf().
    Such reads now return zeroed data.

o   Beta bug fixed: an address violation sometimes occurred when entering
    the debugger.

o   Beta bug fixed: the APPLY buttons in the "Preferences" dialogs updated 
    the running session but did not save the new options in the registry.

o   Beta bug fixed: the "Preferences -> Font Size" dialog did not display
    font names correctly on Windows 98/ME systems.

Jan  5, 2009 (Maintenance Release 7.3.2)

o   New intrinsic functions, SQLEQV$(), SQLEQD$(), and SQLEQDT$(), have been
    added for use with the Oracle SQL and MySQL SQL drivers.  The functions 
    are identical to the SQLV$(), SQLD$(), and SQLDT$() functions except that
    they prefix the encoded value with an "=" symbol if the value is not
    NULL and generate "IS NULL" if the value is NULL.  Using these functions
    simplify the generation of WHERE clauses when the values may be NULL.

o   A new intrinsic CALL, SpaceStr(), has been added to initialize variables.
    Syntax:

        Call SpaceStr(Variable {,...})

    Where:
        Variable    A variable of any type.  String variables, string arrays,
                    and the string members of structures will be filled with
                    spaces.  All other variable types will be zeroed as in
                    the CLEAR statement.

o   Bug fixed: memory violations occurred after the intrinsic function
    CallStat$() or other functions were used with smaller than expected
    argument strings.

o   Bug fixed: numeric query results with a large number of decimal places
    caused an error 70 ("Data read error") in the MySQL SQL driver.

o   Bug fixed: numeric query results with a large number of decimal places
    caused an error 70 ("Data read error") in the Oracle SQL driver.

o   Bug fixed: SEARCH mode 7, which returns the number of active records,
    returned the true value plus one if record zero was deleted.

o   Bug fixed: a memory leak sometimes occurred if the debugger was first
    entered while in a SWAPped program.

Jul 11, 2008 (Maintenance Release 7.3.1)

o   The Oracle SQL driver now sets the session to use "CURSOR_SHARING=SIMILAR"
    to improve performance through SQL statement caching.

o   A new channel function, CHF(17cc), has been implemented in the Oracle SQL
    driver to return one if the current result set has one or more rows and
    zero if the result set is empty.  This function is faster than CHF(cc) 
    if the exact number of rows is not needed.

o   The auxiliary printer, "Terminal Printer", and "Windows Terminal Printer"
    drivers now support the 'LITNUL' and 'LITCR' mnemonics on printers that
    have the "Binary=True" option.  The 'LITNUL' mnemonic is used to output
    a binary zero character to a printer.  The 'LITCR' mnemonic is used to
    output a carriage return without a linefeed to a printer that has the
    "CRToCRNL" option enabled.

o   DEL characters ("\177\") are now passed to the auxiliary printer for use
    with the "Binary=True" option.

o   The "Terminal Printer" and "Window Terminal Printer" drivers now support
    writing binary variables ("B?") to printers that have the "Binary=True"
    option enabled.

o   Bug fixed: commands in the form "BREAK IF ..." caused random error
    messages instead of format/syntax errors.

Jun  3, 2008 (Release 7.3)

o   A new driver, "Oracle SQL", has been implemented so that applications
    can use SQL statements to issue commands and queries to an Oracle
    database server.  Both standard SQL statements and Oracle specific syntax
    can be used.  The driver interface is essentially identical to the MySQL
    SQL driver.  SQL statements are executed with SEARCH statements and
    standard READ or READ RECORD statements are used to read the results.
    Unlike the MySQL driver, the Oracle SQL driver supports the standard 
    timeout option on the SEARCH statement and will interrupt any operation
    if an escape or interrupt key is pressed.
    
    While both Oracle and MySQL implement standard SQL statements, they differ
    in details and offer different enhancements to the standard SQL syntax.  
    For example, the "INTO" keyword of the SQL INSERT statement is optional in
    MySQL, but it is required in Oracle.  Additionally, unquoted identifier
    names in Oracle are converted to all uppercase letters, but quoted Oracle
    identifiers are case sensitive.  Note that the SQLN$(), SQLSN$(), SQLNV$(),
    and SQLSNV$() intrinsic functions produce quoted identifiers which will
    be case sensitive unless the UCID open option is used.  Please see Oracle
    documentation for a full description of Oracle SQL syntax.

    The filename in a Oracle SQL OPEN statement has the format 
    "server_name:database_name" where "server_name:" is optional and can
    specify either a server name or a server IP address.  The Oracle SQL
    driver recognizes the following open options:

        "user=..."      user name, optional if provided elsewhere.
        "password=..."  password, optional if provided elsewhere.
        "pswd=..."      password, optional if provided elsewhere.
        "port=..."      optional port number.
        "rows=..."      optional number of rows to prefetch on queries.
        "rtrim=..."     optional boolean value which, if true, removes all
                        trailing spaces from results (default FALSE).
        "scroll=..."    optional boolean value which, if false, disables 
                        scrollable result sets (default TRUE).  A scrollable
                        result set cannot contain LONG character or binary
                        values.
        "string=..."    optional boolean value which, if true, allows all 
                        result set values to be read as strings regardless of
                        the actual column date type (default FALSE).
        "ucid=..."      optional boolean value which, if true, forces all
                        identifiers from SQLN$(), SQLSN$(), SQLNV$(), and
                        SQLSNV$() to uppercase (default FALSE).

    Example:

        Open #5,"(user=public,pswd=xyz,rtrim=t)dbsrvr2:orcl" As "Oracle SQL"

    The Oracle SQL driver supports numeric, character, date, date/time, and
    binary data types.  Other data types are supported only if the application
    use SQL conversion functions to produce generate standard data types. 
    User defined data types are not supported.  Queries returning long or
    "very long" character or binary columns are supported only if the
    "scroll=false" option is used on the OPEN statement.  If the "scroll=false"
    option is used, all access to result sets must be sequential and the
    CHF(channel) function cannot be used to obtain the number of rows returned.

    The Oracle SQL driver, when a channel is closed, rolls back any pending
    transaction for which a COMMIT has not been executed.  The open option
    "COMMIT=TRUE" can be used to prevent this rollback if desired.  Clearing
    a channel always performs a rollback for pending operations.  The COMMIT
    option can also be specified in the DL4ORACLESQL environment variable.

    The Oracle SQL driver uses Oracle version 10 or version 11 libraries.  
    These libraries are not supplied as part of dL4.  In order to use the
    Oracle driver, the libraries must be installed either in the dL4
    installation directory (usually "\Program Files\dL4") or the full path
    of the Oracle library directory must be added to the PATH environment
    variable.  The Oracle libraries can be obtained by downloading the
    Oracle "Instant Client" package from www.oracle.com.

    The Oracle version 11 libraries produce debugging and diagnostic logs by
    default.  This logging can be disabled in the sqlnet.ora configuration
    file.  A sample sqlnet.ora file is supplied in the dL4 "Tools" directory.
    The file can be used by setting the environment variable TNS_ADMIN to point
    at the "Tools" directory.  A full description of the sqlnet.ora file
    and other Oracle configuration files can be found in documentation
    supplied by Oracle.

    The DL4ORACLESQL environment variable can be used to supply default
    values for the server name, database name, user name, or password.  In
    addition, default values for the "commit", "rows", "rtrim", "string", and
    "ucid" open options can be specified in the DL4ORACLESQL value.  Example:

        DL4ORACLESQL=server=192.168.100.2,user=acctng,password=notsecret
        export DL4ORACLESQL

    The Oracle SQL driver is currently supported only on the Linux 32-bit x86,
    Linux 64-bit x86, and Windows platforms.  Other platforms will be
    supported in the future based on demand and the availability of the 
    Oracle libraries.

o   The Oracle SQL and the MySQL SQL drivers support the new mode 16 of the
    CHF() function to return the last Oracle or MySQL specific error code.
    These error codes provide more detailed information than the standard dL4
    error codes, but the error codes are specific to the database and may even
    vary between versions of Oracle or MySQL.

o   The DL4DRIVERS runtime parameter has been enhanced to accept an "Oracle"
    or "Oracle SQL" option to select the Oracle SQL driver as the default SQL
    driver.  If this option is used, an OPEN AS "SQL" statement will use the
    Oracle SQL driver instead of the MySQL SQL driver.

o   The Oracle SQL driver supports using the ADD statement to insert multiple
    rows to a table from an array of structures.  This special ADD statement
    offers significantly increased performance when inserting large numbers
    of rows to a table.  The syntax of the statement is

        ADD #c;TableName$,ColumnNames$,Rows.[]

    where:

        TableName$      is the name of the table to which the rows will be
                        added.  The table name must match the case of the
                        actual table name.

        ColumnNames$    is a comma separated list of column names to set in
                        each row.  This list can be produced by the SQLN$()
                        function.

        Rows.[]         is an array of structures where each structure contains
                        the values of a row to be inserted.  Note that all
                        elements of the array will be added to the table.  The
                        members in the structure must match the order of the
                        column names in "ColumnNames$".

    If all of the inserts are successful, they will be committed when the ADD
    statement finishes.  If any of the inserts fail, all of the inserts will
    be rolled back.

    To further increase performance, but at the cost of increased disk space,
    record number 4 can be specified in the ADD statement:

        ADD #c,4;TableName$,ColumnNames$,Rows.[]

    Record number 1 can be used in the ADD statement to enable date formatting
    rules similar to those of the SQLDT$() function (see below).  If the
    record number is set to 5, both the date formatting option of record 1
    and the insert optimization of record 4 will be enabled.

o   The Oracle SQL driver supports a SORTCI option to select case insensitive
    sorting and comparing of strings.  The option causes the driver to execute
    the statements

        ALTER SESSION SET NLS_SORT=BINARY_CI
        ALTER SESSION SET NLS_COMP=LINGUISTIC
    
    immediately after the connection is opened.  Using this option can have
    significant performance costs (see the Oracle documentation for NLS_SORT
    and NLS_COMP for details).  The SORTCI option can be set either in an
    OPEN statement or in the DL4ORACLESQL environment variable.  Examples:

        Open #5,"(sortci=true)acctdb" As "Oracle SQL"

        DL4ORACLESQL=sortci=true

o   The Oracle SQL and MySQL SQL drivers support a NADNULL option to convert
    null date values in a result set to "not-a-date" values (the same as
    "CLEAR var#").  The option also converts "not-a-date" values in SQLV$(),
    SQLNV$(), and SQLSNV$() to SQL NULLs.  The NADNULL option can be set either
    in an OPEN statement or in the DL4ORACLESQL/DL4MYSQL environment variables.
    Examples:

        Open #5,"(nadnull=true)acctdb" As "Oracle SQL"

        DL4ORACLESQL=nadnull=true

        Open #5,"(nadnull=true)acctdb" As "MySQL SQL"

        DL4MYSQL=nadnull=true

o   A new intrinsic function, SQLDT$(), has been added for use with SQL
    drivers such as the "MySQL SQL" or "Oracle SQL" driver.  The SQLDT$()
    function is identical to the SQLV$() function except that it tells SQL
    drivers to format all 1% precision date/time variable values as date only
    values.  Date values with 2% or 3% precision are formatted as date and
    time values.

o   A new intrinsic function, SQLSNDT$(), has been added for use with SQL
    drivers such as the "MySQL SQL" or "Oracle SQL" driver.  The SQLSNDT$()
    function is identical to the SQLSNV$() function except that it tells
    SQL drivers to format all 1% precision date/time variable values as date
    only values.  Date values with 2% or 3% precision are formatted as date
    and time values.

o   The intrinsic function SQLN$() has been enhanced so that it can be used to
    add database specific quotation marks around identifiers that are supplied
    as strings.  Example:

        A$ = SQLN$("Special Name")

o   The Oracle SQL and MySQL SQL drivers now support the standard dL4 GET
    statement operations to obtain result set column names and types. Example:

        Search #1,"Select * from customers"
        I = 0
        Do
            Try Get #1,0,I;Opts[I],TypeFmt[I],Name$[I] Else Exit Do
            I = I + 1
        Loop

o   The SCOPE debugger window now supports a scroll back history buffer.  The
    size of the history buffer is controlled by the main window history option
    but has a minimum size of 5 pages.

o   The BREAK command now supports two forms of conditional breakpoints.  The
    command

        BREAK position IF expression

    will stop execution at "position" if and only if "expression" is true.
    For example, the command "break 100 if a>4" will stop at line 100 (before
    executing the line) if the variable "a" has a value greater than 4.  The
    expression can only use variables that are visible at the specified
    position.  If an error occurs while evaluating the expression, the
    expression value is treated as false.  A breakpoint expression uses the
    same syntax as expressions in dL4 and supports the following built-in
    functions: ABS(), HEX$(), HEX?(), INT(), LEN(), MONTH(), MONTHDAY(),
    MSC(), NOT(), SPC(), and YEAR().  Variables used in the expression do not
    have to be allocated when the breakpoint is set, but the expression will
    be considered to be false until the variables are allocated.

    The second form of conditional breakpoint checks the specified expression
    before executing each line rather than just the specified line.  The
    program stops if the expression is true.  If execution is continued, the
    program will not stop again unless the expression first becomes false.
    The command

        BREAK position FOR expression 

    compiles "expression" as if it was in the same procedure as "position".
    If the program enters a procedure or subprogram, the breakpoint expression
    will continue to be tested using the variables visible at "position".  If
    the program uses recursion, the breakpoint will be tested using the
    variables of each recursion level.  The command "BREAK FOR expression"
    uses the variables that are currently visible to the debugger or immediate
    execution mode.

    Conditional expressions can be used with external breakpoints by using
    the "XBREAK position IF expression", "XBREAK FOR expression", or
    "XBREAK position FOR expression" commands.

o   Breakpoint counts can be set so that a breakpoint does not occur when the
    breakpoint condition is first satisfied, but instead waits until the Nth
    occurrence of the condition.  The optional count is specified by adding a
    comma and number (the count) after the breakpoint condition.  For example,
    the following command would set a breakpoint such that the fifth execution
    of line 100 would cause a breakpoint:

        break 100,5

    Breakpoint counts can be used with simple positional breakpoints,
    conditional breakpoints, and "BREAK IF ERROR" breakpoints.

o   Breakpoints can now be deleted by number.  The command "nobreak -N" where
    "N" is a number, deletes breakpoint "N".  The number associated with a
    breakpoint can be determined by using the "status breakpoints" command
    to display all breakpoints.  Example:

        nobreak -2

o   When a breakpoint is set by position, the position is now adjusted to the
    first executable line at or following the specified position.  In the
    following program:

        10 Rem comment line 1
        20 Rem comment line 2
        30 Rem comment line 3
        40 Print X

    setting a breakpoint on line 20 ("break 20") would actually set a 
    breakpoint at line 40.  In previous dL4 releases, the breakpoint would
    never occur because dL4 skips across blocks of non-executable lines.
    The BREAK command warns the user whenever a breakpoint position is
    adjusted.

o   The Windows Terminal driver now implements an additional window style,
    "HISTORY".  The "HISTORY" style creates a window that has a vertical
    scroll bar and a text history buffer.  The initial size of history buffer
    is based on the number of main window history pages, but the size can be
    increased using the 'WHISTORY' mnemonic.

    Example:

        OPEN #1,{"New Account","TITL,HISTORY",40,10} As "Window"

o   A new mnemonic, 'WHISTORY', has been defined to change the size of the
    history buffer used by a window that has the "HISTORY" style (see above).
    The mnemonic syntax is 'n WHISTORY' where "n" is the minimum number of
    history lines to be provided by the window.  The size of the history
    buffer can only be increased; it cannot be decreased or disabled.

o   A new mnemonic, 'SENDCLIP', has been implemented to cause dL4Term or
    dL4 for Windows to send any text in the Windows clipboard as current
    input characters.  The 'SENDCLIP' mnemonic can also be used in a function
    key programming string with the 'PGMFN' mnemonic to program a key to send
    the clipboard characters (note: the "Program Paste" option must be enabled
    in dL4 for Windows or dL4Term).

o   A new option, "Shade History", has been added to the "Preferences->Window"
    dialog to cause history text to displayed using inverted colors.

o   A new option, "CL/CE History", has been added to the "Preferences->Window"
    dialog to cause text deleted by the 'CL' or 'CE' mnemonics to be added
    the history buffer.  Normally, text is only added when the window is
    scrolled or the entire window is cleared.

o   The 'RF' (reset function keys) mnemonic has been defined in the wyse60 
    and wyse60-43 terminal definition files.

o   A new "AS *" syntax has been defined to make it possible to pass structure
    variables with differing definitions to the same procedure.  This makes
    it possible for a single procedure to perform a common operation on any
    structure variable.  For example, the DisplayStructure() procedure below
    prints the contents of any structure variable:

        Declare Intrinsic Function GetStruct$
          .
          .
        External Sub DisplayStructure(S. As *)
          N = 1
          Do
            Try Print "Member";N;"= <";GetStruct$(S., N);">" Else Exit Do
            N = N + 1
          Loop
        End Sub
          .
          .
        Dim Customer. As CUSTOMERROW, Company. As COMPANYROW
          .
          .
        Call DisplayStructure(Customer.)
        Call DisplayStructure(Company.)

    The "AS *" syntax can only be used in a parameter list.  Within a
    procedure, an "AS *" structure parameter variable can be passed to other
    procedures that use "AS *" parameters or the structure can be manipulated
    with the intrinsic CALLs STRUCTINFO(), GETSTRUCT(), and SETSTRUCT() or the
    intrinsic function GETSTRUCT$().  An "AS *" parameter variable can also be
    used in the SQLV$(), SQLN$(), SQLSN$(), SQLNV$(), or SQLSNV$() functions.
    The contents of an "AS *" parameter variable cannot be accessed or changed
    except by using the new intrinsic procedures.  Directly assigning values
    to or from an "AS *" parameter variable is illegal and may cause a runtime
    error in future releases of dL4.  In this release, arrays of structures
    cannot be used as an "AS *" argument.

o   A new intrinsic CALL, GetStruct(), has been added to allow access to
    structure variable members by number.  Syntax:

        Call GetStruct(Value$[], [ValueIdx,] StructVar., [MbrMap.[],] MbrNo,
          NumMbrs)

    Where:
        Value$[]    A string array in which values will be returned.  All
                    values are converted to string format.  The string
                    elements must be large enough to contain each returned
                    value or an overflow error will occur.

        ValueIdx    Optional index in Value$[] at which to start.

        StructVar.  Structure variable to be queried.  The variable can be
                    either a normal structure variable, a structure variable
                    parameter variable, or an "AS *" structure variable
                    parameter.  The structure cannot contain array members.
                    The structure cannot contain structures as members unless
                    the "MbrMap" parameter is specified (see below).

        MbrMap.[]   Optional array of structures containing member reference
                    information returned by Call StructInfo() for "StructVar.".

        MbrNo       Member number (1 - n) to be queried.  If "MbrMap." is
                    supplied, "MbrNo" is used as an index into "MbrMap."
                    to get a member reference code which is then used to
                    identify the actual member to be accessed.

        NumMbrs     Number of members to query.  If "NumMbrs" exceeds the
                    number of members available, all of the remaining
                    members will be queried and "NumMbrs" will be set to
                    the number returned.

o   A new intrinsic function, GetStruct$(), has been added to allow access to
    structure variable members by number.  Syntax:

        GetStruct$(StructVar. [,MbrMap.[]] ,MbrNo)

    Where:
        StructVar.  Structure variable to be queried.  The variable can be
                    either a normal structure variable, a structure variable
                    parameter variable, or an "AS *" structure variable
                    parameter.  The structure cannot contain array members.
                    The structure cannot contain structures as members unless
                    the "MbrMap." parameter is specified (see below).

        MbrMap.[]   Optional array of structures containing member reference
                    information returned by Call StructInfo() for "StructVar.".

        MbrNo       Member number (1 - n) to be queried.  If "MbrMap." is
                    supplied, "MbrNo" is used as an index into "MbrMap."
                    to get a member reference code which is then used to
                    identify the actual member to be accessed.

o   A new intrinsic CALL, SetStruct(), has been added to allow storing values
    in structure variable members by number.  Syntax:

        Call SetStruct(Value$[], [ValueIdx,] StructVar., [MbrMap.[],] MbrNo,
          NumMbrs)

    Where :
        Value$[]    A string array of the values to set.  A single string
                    value can be used instead of an array to set all of the
                    specified structure members to the same value.

        ValueIdx    Optional index in Value$[] at which to start.

        StructVar.  Structure variable to be changed.  The variable can be
                    either a normal structure variable, a structure variable
                    parameter variable, or an "AS *" structure variable
                    parameter.  The structure cannot contain array members.
                    The structure cannot contain structures as members unless
                    the "MbrMap." parameter is specified (see below).

        MbrMap.[]   Optional array of structures containing member reference
                    information returned by Call StructInfo() for "StructVar.".

        MbrNo       Member number (1 - n) to be set.  If "MbrMap." is
                    supplied, "MbrNo" is used as an index into "MbrMap."
                    to get a member reference code which is then used to
                    identify the actual member to be changed.

        NumMbrs     Number of members to set.  If "NumMbrs" exceeds the
                    number of members available, all of the remaining
                    members will be set and "NumMbrs" will be set to the
                    to the number stored.

o   A new intrinsic CALL, StructInfo(), has been added to get information
    about the members of a structure variable.  Syntax:

        Call StructInfo(Info.[], StructVar. ,MbrNo ,NumMbrs)

    Where:
        Info.[]     An array of structures with the following members:

                    ItemName$   Member item name or "" if none.
                    RefCode?    Member reference code for Call SetStruct().
                                RefCode? must have a dimension of 8 or more.
                    ItemNum     Member item number or -1 if none
                    ISAMOptions Member ISAM options.
                    Type$       Type character ("" for numeric members,
                                "$" for strings, "#" for dates, and "?"
                                for binary strings).
                    Format      Precision of number/date members or size
                                of strings.

                    The Info. structure must match the types and order
                    of the members above, but the names can vary.

        StructVar.  Structure variable to be queried.  The variable cannot
                    contain array members.  If any members are themselves
                    structures, then "Info." entries will not be made for
                    those members but entries for each sub-member will be
                    created (this is similar to how such structure variables
                    are expanded for I/O statements such as READ RECORD).

        MbrNo       Member number (1 - n) to be queried.

        NumMbrs     Number of members to query plus one.  If "NumMbrs"
                    exceeds the number of members available, all of the
                    remaining members will be described and "NumMbrs" will
                    be set to the number returned.

    The member information is returned in elements 1 - N of "Info.[]".
    Information about the structure as a whole is returned in "Info.[0]"
    and "Info.[0].Format" will contain the number of members.

o   A new intrinsic function, MemberNum(), has been added to return the
    member number (as used by CALL GetStruct() and such) of a member within
    a structure. Syntax:

        x = MemberNum(Parent., Member.)

    Where:
        Parent.     Structure variable containing "Member."
        Member.     Member of the structure "Parent."
        x           The member number (1 - N) of "Member." in "Parent."
                    as used by the CALL GETSTRUCT() and CALL SETSTRUCT()
                    procedures.  If "Member." is not a member of "Parent.",
                    -1 is returned.

o   The SQLV$(), SQLN$(), SQLSN$(), SQLNV$(), and SQLSNV$() intrinsic
    functions have been extended to support "AS *" structure parameter
    variables.  An "AS *" structure parameter can be used anywhere a
    standard structure variable could be used as a parameter.  Example:
    
        External Sub InsertAnyStructure(Chan, S. As *)
          Search #Chan;"Insert test ("+SQLN$(S.)+") Values ("+SQLV$(S.)+")"
        End Sub
        
o   The SQLV$(), SQLN$(), SQLSN$(), SQLNV$(), and SQLSNV$() intrinsic
    functions have been extended to support the arrays generated by
    CALL GETSTRUCT() and CALL STRUCTINFO().  Syntax:

        SQLV$(Value$[], SInfo.[])
        SQLN$(SInfo.[])
        SQLSN$(SInfo.[])
        SQLNV$(Value$[], SInfo.[])
        SQLSNV$(Value$[], SInfo.[])

    where "Value$[]" is a string array similar to that produced by CALL
    GETSTRUCT() and "SInfo.[]" is an array of structure information similar
    to that produced by CALL STRUCTINFO().  Note that "SInfo.[0].Format" must
    be the number of structure members described in "SInfo.[]".  The array
    syntax can be used with the "AS *" feature to write procedures that
    perform complex operations on any structure variable.

o   A new intrinsic CALL, CopyArray(), has been added to copy ranges of
    array elements from one array to another or within an array.  If the copy
    is performed within an array, the copy is performed such that overlapping
    ranges are handled correctly.

    BASIC syntax:

        Call CopyArray(Dest[], DestIdx, Src[], SrcIdx, NumElements)

    Where:
        Dest[]      is the destination array.
        DestIdx     is an index to the element at which to start copying to.
        Src[]       is the source array.
        SrcIdx      is an index to the element at which to start copying from.
        NumElements is the number of elements to copy.

o   Two new built-in functions, TIM(date_expression) and GMT(date_expression),
    have been added to extract the local or GMT time of day in seconds from
    a date expression.

o   To increase compatibility with UniBasic, the CHAIN statement now treats a
    "\177\" or "\377\" in a chain string as marking the end of the program
    filename and the beginning of text to treated as typeahead.  Thus the
    statement

        CHAIN "query\177\display

    causes a short CHAIN to the program "query" and appends the text "display"
    to the typeahead buffer.

o   The Full-ISAM Bridge driver has been extended to support YYBASEYEAR and
    DDDDDBASEDATE options in the main bridge profile section to change the
    default base years used by the DTOC() and DTON() translation functions.
    Examples:

        [FullISAMBridge]
        File=filename
        OpenAs=FoxPro Full-ISAM
        YYBaseYear=1970

        [FullISAMBridge]
        File=filename
        OpenAs=FoxPro Full-ISAM
        DDDDDBaseDate=1968

o   A new optional section, "[PostEdit]", has been added to conversion
    profiles to support user defined source editing that will be applied to
    each source line after the source line has been converted to dL4.  This
    permits the new text to use dL4 specific features such as dL4 mnemonics.
    The feature is available from both the LOADSAVE "-c profile" option and
    the SCOPE CONVERT command.  The entries in the "[PostEdit]" section use
    the same syntax as those in the "[Edit]" section.

    Example:

        [PostEdit]
        oldmnemonics=S1
        new=SUSPENDAUX

o   The LOADSAVE utility, when using a conversion profile, now tries to open
    include files using both the standard filename case conversion rules and
    the exact case as specified in the INCLUDE statement.  This enhancement
    simplifies conversion of IMS programs.

o   The intrinsic CALL ENV() has been extended with a mode 3 which allows
    CALL ENV() to change the LUMAP, DL4LUST, and other usually static runtime
    parameters of the current program.  For example, the statement

        Call Env(3,"LUMAP","1=C:\\userdata")

    would change the LUMAP setting of the current program while a mode 2
    CALL would only change LUMAP for child processes (such as those started
    by a SYSTEM statement).

o   Enhancement: the VERINDEX utility now supports huge files. 

o   Behavior change: if an ERROR statement is used to re-issue the current
    error number, any supplementary error information in the current error
    will be preserved.

o   Behavior change: the 'BBOLD' mnemonic no longer generates an error 5
    ("Illegal character") if "bold" is enabled as part of the standard font
    and a "bolder" font is not supported.

o   Bug fixed: in 'WCBQRYBUF' mode, pasted characters were appended to the
    query queue rather than the event queue.

o   Bug fixed: the 'CE' mnemonic cleared the entire line containing the
    cursor even if the cursor wasn't positioned at column zero.

o   Bug fixed: the status line, when enabled, was sometimes scrolled above
    the bottom of the window if the user scrolled text.

o   Bug fixed: the delete and change commands did not work in the MAKEKEY
    utility.

o   Bug fixed: when assigning a structure variable to a different, but 
    compatible structure ("A. = B."), any member that was a numeric array was
    not copied correctly and sometimes caused an error 15.

o   Bug fixed: On some systems, a server name of "" or "localhost" caused an
    error and did not open the local MySQL server.

o   Bug fixed: an IRIS style BUILD statement for a formatted file with
    protection specified ('BUILD #1,<00>filename') resulted in an endless
    loop.

Feb 29, 2008 (Maintenance Release 7.2.3)

o   A new intrinsic function, SQLD$(), has been added for use with SQL
    drivers such as the "MySQL SQL" driver.  The SQLD$() function is
    identical to the SQLV$() function except that it tells the SQL driver
    to format all date/time values as date only values.  This is necessary
    to perform searches on date (not date/time) columns.  In particular,
    queries to version 5.0.42 or later of the MySQL server will NOT match
    date/time values with date columns if SQLV$() is used instead of SQLD$().

o   Enhancement: the MySQL Full-ISAM driver has been modified to increase
    compatibility with release 5.0.42 or later of the MySQL server.

o   Bug fixed: On some systems, a server name of "" or "localhost" caused an
    error and did not open the local MySQL server.

o   Bug fixed: CHAIN statements with both starting and return line number
    arguments ('CHAIN "pgm",10,R') could not be entered and caused syntax
    errors.

o   Bug fixed: when "PM" or "pm" format codes were used, the DateUsing$()
    function produced noon and midnight as "00" rather than "12".

o   Bug fixed: an arithmetic exception occurred when inserting records
    with the Full-ISAM Bridge driver using a profile that had an empty
    character set specified in a key part.  A default character set of
    "0123456789" will now be used whenever the character set is empty.

o   Beta bug fixed: the Oracle SQL driver "CHF(channel)" function returned a
    value of -1 instead of 0 for empty result sets.

o   Beta bug fixed: the Oracle SQL driver did not properly translate an Oracle
    row locked error code into the dL4 record lock error code.

o   Beta bug fixed: if a conditional breakpoint ("break for x>4") was made
    false by a debugger LET command, the breakpoint was not reenabled until
    at least one statement had been executed.  Conditional breakpoints are
    only reported when the specified condition changes from false to true.

o   Beta bug fixed: breakpoints weren't always preserved when re-running a
    program.

Feb  8, 2008 (Maintenance Release 7.2.2)

o   Bug fixed: an IRIS style BUILD statement for a formatted file with
    protection specified ('BUILD #1,<00>filename') resulted in an endless
    loop.

Feb  7, 2008 (Maintenance Release 7.2.1)

o   Bug fixed: the printer driver "CRToCRLF" option did not work when the
    printer was in binary mode.  Note that any current applications that
    used the "CRToCRLF" option and worked correctly will probably need the
    option turned off.  This is also true for any use of the auxiliary
    printer in binary mode ("Binary=True,CRToCRLF=True").

Jan 25, 2008 (Release 7.2)

o   The MySQL SQL driver now supports stored procedures and multi-statement
    queries.  If a stored procedure or multi-statement query returns more
    than one result set, a "SEARCH > #c;" statement can be used to move to
    the next result set.  An error 52 is generated by "SEARCH > #c;" if
    there are no more result sets to be read. Example:

        SEARCH #1;"select * from table1; select * from table2"
        READ RECORD #1;Result1.
          .
          .
        SEARCH > #1;
        READ RECORD #1;Result2.
          .
          .

    As before, the CHF(channel) function returns the number of rows in the
    current result set.

o   The "AND" and "OR" operators have been extended to support date values.
    Any valid date value is considered to be "TRUE" and any invalid date
    value is treated as "FALSE".  Example:

        If Flag And StartDate# Call ProcessItem()

o   The POS() function can now be used to search single dimensioned arrays of
    any type including arrays of structures.  When used to search arrays, the
    POS() function has the same syntax as when searching a string except that
    the source variable must be an array variable followed by "[]" and the "IS"
    and "EXCEPT" relations are not supported.  For example, the
    statement:

        I = POS(A[], =5)

    would search the numeric array "A" starting at index 0 for an element with
    a value of 5.  If such an element is found, the POS() function returns the
    index of the element.  If no matching element is found, a value of -1 is
    returned (this differs from the non-array search using POS() which returns
    0 for unsuccessful searches).  By default, the POS() function searches the
    entire array, but an optional fifth numeric parameter can be used to
    specify the number of elements in the array.  The search in the prior
    example could be limited to the first three array elements by using:

        I = POS(A[], =5, 1, 1, 3)

    If the limit is set to zero, the POS() function will return a result of
    -1 (search unsuccessful)

    For consistency, the POS() function when used to search non-array string
    variables has been extended to also support the optional fifth parameter.
    If the parameter is set to zero, the string POS() function will return 0
    (search unsuccessful).
    
    When searching an array of structures, the search is performed on the
    first member of the structure.  In the following example, the POS()
    function is used to search an array of structures where the first member
    is a string:

        Def Struct NAMETOCODE
          Member Name$[20]
          Member 3%,Code
        End Def
        Dim NameTable.[2] As NAMETOCODE, N$[20]
        Read NameTable.[]
        Data "FRED", 123, "LUCY", 415, "JOHN", 723
        Input "Name? "N$ \ Print
        I = Pos(NameTable.[], =Ucase$(N$))
        If I < 0
          Print "Name not found."
        Else
          Print "Code equals";NameTable.[I].Code
        End If
        End

o   The READ and MAT READ statements can now be used to initialize date and
    binary variables from DATA statements.  The values in the DATA statements
    must be quoted strings.  A date value in a DATA statement can be any
    standard date string such as "Jan 5, 2007" or "2007/10/01".  A binary
    value in a DATA statement must be an even number of hexadecimal digits.
    Example:

        Dim B?[5]
        Read D#,B?
        Data "Jan 5, 2007","2BAD"

    If a binary value in a DATA statement is shorter than the variable being
    read into, the trailing bytes of the binary variable will not be changed.
    If a binary value in a DATA statement is longer than the variable being
    read into, an error 70 will be reported.

o   The dl4login terminal service utility now supports a "-s" command line
    option to run user processes using the service account rather than the
    user account.  This makes it possible to use dl4login without giving
    users local logon privileges on the server.  When using this option,
    a special non-privileged account should be created and used with the
    dl4login service so that user processes will not be executed in a 
    privileged service account.  In this release, the "-s" option can be
    enabled only by modifying the dl4login service login options and also
    changing the dl4login service registry values.

o   Enhancement: CALL DXLOAD() and other dynamicXport CALLs that use file
    paths as arguments can now accept paths that contain spaces.

o   Enhancement: the CHDIR statement is now accepted when converting IMS
    programs.

o   Behavior change: OPTION STRING SUBSCRIPTS IRIS, which controls how zero
    subscripts are handled with strings, now also controls how zero subscripts
    are handled when used with non-array numeric variables.  If the option is
    set, a zero subscript will be ignored and will not cause an error 28.

o   Behavior change: when using short timeouts with FoxPro Full-ISAM files, a
    timeout is only reported if the record is locked or if the index is locked
    for more than one second. In previous releases, a spurious record lock
    timeout sometimes occurred when a zero length timeout was used and a
    transient index lock was detected.

o   Behavior change: a printer selection dialog is displayed even by console
    processes if the desktop is visible.  Previously, the default printer was
    always used if a printer selection dialog was invoked.

o   Behavior change: copying and pasting a word includes only one trailing
    space.

o   Bug fixed: FoxPro Full-ISAM files could not be opened if the file path
    contained spaces.

o   Bug fixed: On some systems, a server name of "" or "localhost" caused an
    error and did not open the local MySQL server.

o   Bug fixed: copy and paste of text from a window was corrupted if an
    output region was scrolled when the region was smaller than the canvas.

o   Bug fixed: a memory violation occurred if an OPEN statement failed when
    using the MySQL SQL driver.

Aug 27, 2007 (Maintenance Release 7.1.1)

o   Bug fixed: an error was reported the first time a partially encrypted
    file was opened if the encryption key was not defined.

Aug 17, 2007 (Release 7.1)

o   Data in Indexed Contiguous or Contiguous files can be now be encrypted
    on the Windows (1B), Linux (6D), Apple Mac OS X (A1 and A4), SCO 
    OpenServer 5 (99), and SCO OpenServer 6 / UnixWare 7 (55) platforms.
    Additional platforms will be supported in the future.

    Either entire records or parts of records can be encrypted.  In this
    release, encryption is not supported for keys in indexes.  Data can be
    encrypted using the AES, "Triple DES", or DES algorithms.  To use
    encrypted files, the dL4 encryption option must be enabled in the SSN.
    
    A file is encrypted by creating the file with an "N" attribute.  For
    example, the following BUILD statement creates an encrypted file with
    fully encrypted records using a key named "CustData":

        BUILD #1,"<N=''CustData''> [1:40] filename"

    The key "CustData" is NOT the actual passphrase used to encrypt the data.
    Instead, "CustData" is the logical name of an encryption key that has
    been previously defined using a SYSTEM 100 statement or loaded from a key
    file.  A key name is case insensitive and can include any character except
    for a double or single quotation mark.  The quotation marks in the 
    filename string surrounding the key name are mandatory.  Records in 
    encrypted files cannot span record boundaries.
    
    An OPEN, ROPEN, or EOPEN statement does not use any special syntax to
    open encrypted files.  When a previously encrypted file is opened, dL4
    uses the currently defined keys to open the file.  If none of the current
    keys matches the one required by the file, an error 284 is generated.  If
    a current key matches the key name needed to open a file, but the
    encryption parameters of the key do not match those used to create the
    file, an error 284) will be generated.

    A file can be encrypted with partially encrypted records by specifying
    1 to 16 encrypted segments as part of the "N" attribute.  The segment
    definitions must be placed before the key name using the format "S-E"
    where "S" is the zero based starting offset of the segment and "E" is
    the zero based ending offset of the segment.  The example below creates
    a file in which the first 10 characters and last 6 characters of each
    record are encrypted:

        BUILD #1,"<N=0-9,74-79,''CustData''> [1:40] filename"

    Partially encrypted records are used to decrease encryption overhead or
    to allow programs to read the non-encrypted sections of a record without a
    key.  To permit reading non-encrypted sections, each encryption segment
    definition must be followed by a fill code.  Three case-insensitive fill
    codes are supported:

        "Z"     Binary zero fill the segment
        "S"     Space fill the segment
        "*"     Asterisk fill the segment

    The previous example could binary zero fill the first segment and space
    fill the second segment using the following format:

        BUILD #1,"<N=0-9Z,74-79S,''CustData''> [1:40] filename"

    If the file was then opened without a matching key, read-only access would
    be permitted.  Whenever data was read from a record, it would appear that
    characters 0 through 9 contained binary zeroes and characters 74 through
    79 contained spaces.

    Each dL4 session maintains a list of keys to be used in creating or
    opening encrypted files.  The list is initially loaded with the keys from
    the optional key file and can be modified during the session by executing
    SYSTEM 100 statements.  The list persists throughout the dL4 session
    until dL4 exits even when different programs are loaded.  The key list
    is NOT passed to separate sessions started via SPAWN, PORT, or CALL TRXCO
    statements.

    The SYSTEM 100 statement, described in a section below, is used to add,
    modify, or delete keys in the current key list.  If the DL4KEYFILE 
    environment variable is defined when dL4 starts, the string will be used
    as the key file path for the session.  Key files are text files
    containing one or more key definitions.  The key file begins with a
    readable label line which is followed by a list of key values.  The key
    values are not readable and are encrypted with a user defined passphrase
    or the standard dL4 default passphrase.  If a user defined passphrase is
    used, a SYSTEM 100 statement must define the key "SYS_KEYFILE" using the
    chosen passphrase and cipher before opening or creating any encrypted
    files.  Key files can only be used on the system on which the key file was
    created (or one with a matching license number).  A master key list should
    always be maintained in an encrypted contiguous or indexed contiguous file
    using an application defined key.  Key files are created using the MAKEKEY
    utility or by using the SYSTEM statement.

o   The SYSTEM statement has been extended with two new modes to support
    encrypted files.  The SYSTEM 100 statement is used to add new keys to the
    current key list, modify existing keys, or to delete the key list.  The
    following SYSTEM format is used to add a new key or to replace an existing
    key of the same name:

        SYSTEM 100,"keyname","passphrase","cipher"

    where

        "keyname" is a string expression that specifies the key name

        "passphrase" is a string expression that specifies the passphrase

        "cipher" is the name of encryption algorithm.

    A key name can be any sequence of ASCII characters.  Key names beginning
    with "SYS_" are reserved for special purposes and should not be used for
    application keys.  A passphrase can be any sequence of ASCII characters
    and must be at least six characters long.  The supported cipher names are
    "AES-256" (256 bit AES), "AES-128" (128 bit AES), "3DES" (triple DES),
    and "DES".  Cipher names are case-insensitive.  The recommend ciphers are
    "AES-256" and "AES-128" where "AES-128" offers somewhat weaker protection
    but higher performance when compared to "AES-256".

    Keys can be deleted from the current key list by using a SYSTEM 100
    statement with the name of the key and empty strings for the passphrase
    and cipher.  Example:

        SYSTEM 100,"keyname","",""

    The entire current key list can be deleted by using "" as the key name
    to be deleted:

        SYSTEM 100,"","",""

    The SYSTEM 101 statement is used to generate a key file string image
    that contains all of the keys from the current key list (except those
    that begin with "SYS_").  The SYSTEM 101 statement has the format
    
        SYSTEM 101,S$

    where "S$" is any string variable.  Before executing the SYSTEM 101
    statement, "S$" must be initialized with the label string to be used
    by the key file.  When the SYSTEM 101 statement completes executing,
    "S$" will contain the key file string image (without the key file
    label string).
        
    A key file is created by writing the key file string image to a text file
    preceded by a label line.  The key file string image can written as a
    single line or as many lines as desired (except for the label line, end
    of line characters are ignored when dL4 reads a key file).  Before
    using a SYSTEM 101 statement, the current key list must be deleted and
    then filled using SYSTEM 100 statements.  The following example creates
    a user specific key file with two keys:

        DIM I$[32000]
        SYSTEM 100,"","",""
        SYSTEM 100,"CustData","abcdefghijkl","AES-128"
        SYSTEM 100,"Private","gibberish","AES-256"
        I$ = "Our keys"
        SYSTEM 100,"SYS_KEYFILE","userpassphrase","AES-256"
        SYSTEM 101,I$
        BUILD #1,+"userkeyfile"
        PRINT #1;"Our keys"
        PRINT #1;I$
        CLOSE #1

    To use this key file, the application would have to define the key
    "SYS_KEYFILE" before the first open or creation of an encrypted file.
    All key files are usable only on a system using the same license number
    as that used when the key files was created.  Key files must be 32767
    characters or less in length.  The key file will be invalidated if any
    printable characters, including those in the label line, are changed.

o   The SYSTEM statement has been extended with a new mode 102 that restores
    the original encryption key list from the file specified in the DL4KEYFILE
    environment variable.  Example:

        System 100,"","","" ! Delete all encryption keys
            .               ! Open files without encryption keys
            .
        System 102          ! Restore encryption keys from the key file

o   Beta behavior change: files with fully encrypted records are not required
    to have a record length of 64 bytes or more.

o   A new command line utility, MAKEKEY, has been added to the tools
    directory.  The utility is used to create and maintain both master and
    user key files.  A master key file is an encrypted Contiguous file that
    contains a list of encryption key definitions.  The user must supply a
    passphrase every time a master key file is loaded or saved.  A master
    file can be moved between systems, but it cannot be used directly by
    SCOPE or RUN as a key file.  A master key file can be loaded by MAKEKEY
    and then written to a user key file that can be used by SCOPE or RUN via
    the DL4KEYFILE environment variable.  A user key file is bound to a 
    specific system by the Passport license number and uses either a standard
    dL4 encryption key or a user/application specified passphrase.  For high
    security, user key files should always use a user/application specified
    passphrase.

o   Four new error numbers have been defined for use with the new encryption
    feature:

        283     File is encrypted
        284     Unrecognized encryption key
        285     Unsupported encryption method
        286     Inaccessible or corrupt key file

o   CALL FileInfo() has been extended to return the encryption status of 
    files.  If a file is encrypted, an "N" attribute will be set in the 
    attribute characters of the returned filename.  Encrypted record segment
    definitions are returned in an optional numeric array parameter.  If used,
    the array parameter must be DIMmed as "a[128,2]" with the following usage:

        a[X,0]  segment fill type
        a[X,1]  segment item number
        a[X,0]  segment length in bytes

    where "X" is the segment number.  The end of the array is marked by a
    segment definition with a length of zero.  The segment fill type has
    the following meaning:

        0       Segment cannot be read without a valid encryption key
        1       Segment is zeroed if read without a key ("Z")
        2       Segment is space filled if read without a key ("S")
        2       Segment is asterisk filled if read without a key ("*")

    Example:

        CALL FileInfo(D$,A,B$,M,I,E) ! array E receives segment defs

o   A new GET operation, -495, has been defined to return the encryption 
    status of the file open on the channel.  The statement will return 1 into
    the numeric parameter is the file is encrypted and zero if the file is not
    encrypted.  Example:

        ROpen #1,"filename"
        GET #1,-495;X
        If X Print "File is encrypted."

o   A new GET operation, -494, has been defined to return the encryption 
    segment definitions of an encrypted Contiguous or Indexed-Contiguous
    file.  The statement

        GET #1,-494,SegNo;Options,SegStart,SegSize

    will return, for segment "SegNo", the segment options in "Options", the
    zero based starting byte offset of the segment in the record in
    "SegStart", and the size of the segment in bytes in "SegSize".  The
    segment option values are identical to those returned by CALL FileInfo().

o   The QUERY utility has been extended to print the encryption status of
    files.  If only selected record segments have been encrypted, the segment
    definitions are displayed.

o   Two new intrinsic functions, SQLSN$() and SQLSNV$(), have been added for
    use with SQL drivers such as the "MySQL SQL" driver.  The new functions
    are identical to existing SQLN$() and SQLNV$() functions except that
    when using nested structure definitions, the new functions will
    concatenate the field names of the parent structure member with the
    child member field names.  For example, given the following definitions:

        Def Struct POSITION
            Member 1%,X : Item "Column"
            Member 1%,Y : Item "Row"
        End Def

        Def Struct RECTANGLE
            Member UpperLeft. As POSITION : Item "UL"
            Member LowerRight. As POSITION : Item "LR"
        End Def

        Dim R. As RECTANGLE

    then the SQLSN$() and SQLSNV$() functions would generate the field names
    "ULColumn", "ULRow", "LRColumn", and "LRRow".  The SQLN$() and SQLNV$()
    function would generate the names "Column", "Row", "Column", and "Row"
    causing duplicate field name errors in some situations.  The new 
    functions are actually bug fixes for the old functions which could not
    be changed because some existing applications depend on their current
    behavior.  Note that the new functions will produce the same results as
    the old functions if the parent members do not have field names.

o   Behavior change: the MAP RECORD, DEFINE RECORD, and DEFINE INDEX
    statements no longer require parent members to have field names when
    structure definitions are nested.  Example:

        Def Struct POSITION
            Member 1%,X : Item "Column"
            Member 1%,Y : Item "Row"
        End Def

        Def Struct RECTANGLE
            Member Start. As POSITION
            Member Label$[20]: Item "Label"
        End Def

o   Four new sample libraries have been added to the tools directory.  The
    dl4util.lib library contains various useful procedures such as Center$()
    which centers text in a string.  The gui1.lib, gui2.lib, and gui3.lib
    libraries provide procedures to aid GUI programming with dL4Term or
    dL4 for Windows.

o   A new runtime parameter, "DL4LOCALE", has been defined to simplify
    configuration of localized or application specific date formats.  The
    "datemask" option in DL4LOCALE sets a DATEUSING$() compatible format
    mask for use in date conversions when using the native (local) date
    format.  For example, if DL4LOCALE is set to

        datemask=YYYYMMDD

    then the following program would print the current date in the format
    "YYYYMMDD":

        Option Date Format Native
        Dim D$[40]
        D$ = Tim#(0)
        Print D$

    If DL4LOCALE is set to "datemask=YYYYMMDD", then "YYYYMMDD" will be
    accepted as a valid format when converting strings to dates if the
    native date format is enabled ('D# = "20031003"').

o   A new open option, "STRING=" has been added to the MySQL SQL driver.  
    With the STRING option enabled, numeric and date column values can be read
    into string variables.  The STRING option can be enabled by setting it
    to "TRUE", "T", or "YYYYMMDD".  Setting the STRING option to "YYYYMMDD"
    is equivalent to setting the option to "True" and also causes date values
    to be formatted as "YYYYMMDD" when date values are read into string
    variables.  Both the new STRING option and the previously supported
    RTRIM option can be specified in the DL4MYSQL runtime parameter.
    Examples:

        Open #1,"(string=YYYYMMDD)accountingdb" as "MySQL SQL"

        DL4MYSQL=server=theservername,string=YYYYMMDD
        export DL4MYSQL

    Note: when inserting or updating date values in rows, date values must
    be correctly formatted as "YYYY-MM-DD" or "YYYY-MM-DD HH:MM:SS" even if
    the "YYYYMMDD" option is enabled.

o   The SYSTEM statement has been extended with mode 34 which enables
    converting terminal input characters to uppercase and mode 35 which
    disables such conversion.  Example:

        System 34
        Input "All characters converted to uppercase: "I$
        Print
        System 35
        Input "Normal input: "I$
        Print

    Characters are not converted to uppercase if binary input mode is
    enabled.

o   Two new mnemonics have been implemented to enable and disable converting
    terminal input characters to uppercase.  The 'BUCASE' mnemonic enables
    uppercase conversion mode and the 'EUCASE' mnemonic disables the
    conversion.

o   A new intrinsic function, IsAdL4Keyword(), has been added to determine
    whether the argument string is a dL4 reserved word.  The function returns
    1 if the string is a reserved word and zero if the string is not a
    reserved word.

o   The following intrinsic calls have been added for UniBasic compatibility:

        UniBasic CALL               New equivalent dL4 Intrinsic            

        CALL 10                     Call TrimmedLen()
        CALL 11                     Call StrSrch11()
        CALL 68                     Call BuildKey()
        CALL 105                    Call MiscStr105()
        CALL 113                    Call NameStack()
        CALL 115                    Call UnpkRecord()
        CALL 119                    Call FindLeast()
        CALL 120                    Call ConvertSPC2Date()
        CALL 121                    Call CheckSPC2Date()
        CALL 122                    Call DiffSPC2Dates()

o   A new intrinsic CALL, UBCKSUM(), has been added to provide fully
    compatible UniBasic style checksums.  The existing CALL CKSUM() does
    not calculate UniBasic checksums correctly on some platforms, but CALL
    CKSUM() has not been changed because some applications may depend on the
    existing behavior.  The conversion profiles tools/convert.prf and
    tools/convbits.prf now use CALL UBCKSUM() when converting UniBasic
    programs that use CALL $CKSUM.  A new mode 3 has been added to both CALL
    UBCKSUM() and CALL CKSUM() to correctly calculate UniBasic checksums.

o   A "-n" option has been added to the SCOPE CHECK command to change the
    capitalization of symbols in a program to a standard format.  The command
    "check -n" will change all variable names, procedure names, and line
    labels to mixed case.  All structure definition names will be changed to
    all upper case.  When changing a name to mixed case, the existing name is
    not modified if it is already in mixed case.  If the name is all lower
    case or all upper case, the name will be changed so that the first
    character is in upper case and all other characters are in lower case.

    Up to four custom capitalization rules can be specified after the "n"
    option letter.  Each rule is a pair of characters where the first
    character is the symbol class and the second character controls how
    the symbols will be capitalized.  The symbol classes are:

        "v"  variables
        "s"  structure definitions
        "p"  procedures or functions
        "l"  line labels

    The capitalization rule characters are:

        "m"  change symbols to mixed case
        "l"  change symbols to all lower case
        "u"  change symbols to all upper case
        "*"  leave symbols unchanged

    If a custom rule is not specified for a symbol class, then the default
    rule will be used.  

    Example:

        check -nvllu

    The command will convert variable names to all lower case, line labels
    to all upper case, and use the default rules for procedures, functions,
    and structure definitions.

o   To increase compatibility with UniBasic, a new terminal definition file
    setting, "MAXMOVETO", has been implemented to control handling of cursor
    addressing sequences that use coordinates greater than the actual number
    of columns or rows in a window.  If the line "MaxMoveTo=True" is in the
    "[Settings]" section of the current terminal definition file, then any
    attempt to address beyond the actual range will instead move the cursor
    to the maximum column or row.  The MAXMOVETO mode only changes cursor
    addressing behavior in windows.  The MAXMOVETO mode works with standard
    terminal types and with dL4Term version 6.3.3 or later.

o   Enhancement: the maximum character constant size has been increased from
    255 characters to 2000.

o   Enhancement: the maximum command and source line length has been 
    increased to 2040 characters.

o   Enhancement: mouse wheels can now be used to change the window scrolling
    position.

o   Behavior change: if an OPEN of a contiguous or indexed contiguous file uses
    a "CHARSET=name" option and "name" matches the character set used by the
    file, no error will be reported.  If the character set name does not match
    that used by the file, a file syntax error will be reported.

o   Behavior change: the FoxPro Full-ISAM driver now retries index locks for
    a short period even if a timeout value of zero is used.  This change
    reduces the chance of getting a misleading "record locked" error when
    using small timeout values.

o   Behavior change: the FoxPro Full-ISAM driver now accepts record -2 in 
    addition to 0 and -1 in an unlock record operation.

o   The TESTLOCK utility is now supplied as part of dL4 for Windows.

o   Bug fixed: the MySQL SQL and MySQL Full-ISAM drivers did not properly
    concatenate field names when nested structure definitions were used.
    Instead of concatenating the field names, the drivers duplicated the
    parent field name.  Note: in dL4 7.1, parent members in structures are
    no longer required to have field names.

o   Bug fixed: the LOAD command displayed an "Illegal Driver Operation" error
    message instead of "Duplicate Line Label" when a duplicate line label was
    found.

o   Beta bug fixed: a parameter error was reported on any attempt to use
    the SYSTEM 100 statement to delete a specific encryption key.

o   Bug fixed: quoted file paths did not work in CALL DXLOAD(), CALL DXSAVE(),
    or other dynamicXport CALLs.

May 24 2007 (Maintenance Release 6.2.11)

o   Behavior change: a "CHARSET=..." option in an OPEN statement no
    longer reports a file syntax error if an indexed contiguous or
    contiguous file is being opened and the specified character set
    matches that of the file.

o   Bug fixed: copy selections that included text outside the currently
    displayed window only copied the visible text.

o   Bug fixed: a memory violation occurred under unusual conditions while
    using GUI elements.

Apr 27 2007 (Maintenance Release 6.2.10)

o   Enhancement: the instlogn.bat script used to install the optional
    dl4login terminal service now supports paths that contain spaces.  Such
    paths must be placed in quotation marks on the command line.

o   Enhancement: the dl4servr utility now has a "/c string" option to add
    command line arguments to the command executed by the service.

o   Behavior change: the Microsoft SQL Server Full-ISAM driver now supports
    SQL Server 2005.  This change is compatible with SQL Server 2000, but may
    cause problems with older versions of SQL Server.

o   Support local application drivers in the development kit.

Feb 20 2007 (Maintenance Release 6.2.9)

o   Behavior change: dl4login now sets the DL4HANGUPEXIT environment variable
    to 1 unless the value is explicitly set in the user profile.

o   Bug fixed: if a user connected via dl4login exited dL4Term without
    logging out first, the dL4 session did not exit even if the
    DL4HANGUPEXIT environment variable was set to a non-zero value.

o   Bug fixed: demo SSNs that expired on July 1, 2007 or October 1, 2007 were
    treated as if they had already expired if they were used prior to July 1,
    2007.  Passport version 2.8.1 or later must be installed to correct this
    problem.

o   Bug fixed: CALL DXMERGE() reported random errors, most commonly with
    large values.

Dec 19 2006 (Maintenance Release 6.2.8)

o   Behavior change: the CHF(12xx) and CHF(13xx) functions (current column
    and current row) can now be used when the "Page Printer" driver is
    opened indirectly via a printer script.  Previously, the functions could
    be used only when the driver was opened directly by name.

o   Bug fixed: the original default button status, when defined, was not
    restored when focus was moved to a non-button GUI element.

o   Bug fixed: after an Indexed Contiguous file was opened with EOPEN, some
    index update sequences reported index corruption errors.

o   Bug fixed: the SCOPE LOAD command displayed an "Illegal Driver Operation"
    error message instead of the correct error message when a duplicate line
    label was detected.

o   Bug fixed: attempting to load and run a PSAVEd program without the proper
    OSN did not display the correct error.

Sep 14 2006 (Maintenance Release 6.2.7)

o   Two new mnemonics have been implemented for use in GUI programs.  The 
    'BQ' mnemonic enables a special query mode which disables echo and the
    cursor.  The 'EQ' mnemonic disables the special query mode.  Using 'BQ'
    instead of 'IOEE K0' can improve query performance on some
    systems.

o   A new open option, "RECEIPT=address", has been added to the email driver
    to request that the receiver send a receipt when the email has been 
    displayed.  Example:

        Opts$ = "(From=someone,Receipt=someone,Subject=''(test)'')"
        Open #1,Opts$ + "somebody" As "Email"
          .
          .

o   Behavior change: the default value of ISAMFILES has been increased from
    50 to 100.

o   Behavior change: non-ASCII punctuation characters such as true hyphens or
    opening/closing quotation marks are now converted to ASCII dashes or
    quotation marks when performing a 'WCQUERY'.  The non-ASCII characters,
    usually generated by cut-and-paste operations from other applications,
    caused illegal characters errors when written to files and were not
    recognized by most dL4 programs.

o   Bug fixed: FoxPro Full-ISAM files with keys using %4 or %5 numeric values
    did not sort correctly sometimes because the least significant digits were
    ignored.

o   Bug fixed: an address violation occurred if an entire independent window
    was selected with the mouse/pointer and then copied.  Pasting an empty
    copy buffer sometimes produced an unpredictable character.

o   Bug fixed: all lines returned by querying a WCMEMO box had a space
    appended.

o   Bug fixed: when using character terminals with wide and narrow screen
    widths, windows sometimes scrolled when characters were printed on the
    bottom right corner.

o   Bug fixed: the dl4servr.exe utility could not be used on Windows NT
    systems.

o   Bug fixed: CALL EDITFIELD() generated an error if the DIMed length of the
    source string was greater than that of the destination string.  The error
    should have occurred only when the current length of the source exceeded
    the size of the destination.

May 26 2006 (Maintenance Release 6.2.6)

o   A new open option, "ATTACHAS=USERTYPE" has been added to the email driver
    to send email attachments with a user specified content type.  A user
    specified type can help an email client select the proper application to
    open an attached file.  The following example sends a file that should
    be opened with Microsoft Excel:

        Opts$ = "(From=someone,Subject=''(test)'',AttachAs=usertype)"
        Open #1,Opts$ + "somebody" As "Email"
        Print #1;"Please review the attached spreadsheet."
        Add #1;"table.dta","vnd.ms-excel"
        Close #1

    For some email clients, it may be necessary to also specify a defined 
    file extension (such as ".xls" for Excel) to guarantee that the file
    will be opened with the proper application.

    When using "ATTACHAS=USERTYPE", the ADD statement can only attach one
    file at a time and supports three optional arguments.  Syntax:

        ADD #channel;FilePath$ {,ContentType$ {,Encoding$ {,SaveName$ }}}

    where:

        "FilePath$" is the path of the file to be attached.

        "ContentType$" is a MIME content type such as "octet-stream" or
        "vnd.ms-excel".

        "Encoding$" is the encoding type which must be "" or "Base64".

        "SaveName$" is a default file name to which the user can save
        the attachment.

    The "FilePath$" value is the only required argument, but the arguments
    must be given in the listed order.  An argument may be specified as ""
    if it is needed only as a space holder.

o   A new open option, "ATTACHAS=INLINEMIME" has been added to the email driver
    to send email attachments that are dynamically generated with PRINT
    statements to the email driver.  The following example sends data that 
    should be opened with Microsoft Excel:

        Opts$ = "(From=someone,Subject=''(test)'',AttachAs=inlinemime)"
        Open #1,Opts$ + "somebody" As "Email"
        Print #1;"Please review the attached spreadsheet."
        Add #1;"","vnd.ms-excel"
        Print #1;"<HTML>"
        Print #1;"<BODY>"
        Print #1;"<TABLE WIDTH=80% BORDER=1 CELLSPACING=1 CELLPADDING=1>"
        Print #1;"<TR>"
        Print #1;"  <TD>Item</TD>"
        Print #1;"  <TD>Unit Price</TD>"
        Print #1;"  <TD>Quantity</TD>"
        Print #1;"  <TD>Cost</TD>"
        Print #1;"</TR>"
        Print #1;"<TR>"
        Print #1;"  <TD>Widget</TD>"
        Print #1;"  <TD>25.00</TD>"
        Print #1;"  <TD>5</TD>"
        Print #1;"  <TD>=b2*c2</TD>"
        Print #1;"</TR>"
        Print #1;"</TABLE>"
        Print #1;"</BODY>"
        Print #1;"</HTML>"
        Close #1

    When using "ATTACHAS=INLINEMIME", the ADD statement supports four optional
    arguments.  Syntax:

        ADD #channel;{FilePath$ {,ContentType$ {,Encoding$ {,SaveName$ }}}}

    where:

        "FilePath$" is the path of the file to be attached.  To print the
        attachment data to the email driver channel, this value must be "".

        "ContentType$" is a MIME content type such as "octet-stream" or
        "vnd.ms-excel".

        "Encoding$" is the encoding type which must be "" or a valid MIME
        encoding type.  If the encoding type is "", it will be treated as
        "7bit" text.

        "SaveName$" is a default file name to which the user can save
        the attachment.

    The arguments must be given in the listed order.  An argument may be
    specified as "" if it is needed only as a space holder.

o   Behavior change: horizontal tab characters printed in a window now scroll
    to the next line if the end of line is reached and scrolling is enabled.
    In previous versions, the cursor position would wrap to the top of the
    window.

o   A new option, "Block Cursor" has been added to the "Preferences->Window"
    dialog to force the cursor to be displayed as a block rather than as an
    underline.  This option does not change the cursor appearance in GUI 
    elements.

o   A new option, "Alt Bell", has been added to the "Preferences->Window"
    dialog to select an alternate sound for the "bell".

o   The intrinsic CALL PROGRAMDUMP() now supports an "extra" option to
    print additional internal information that may be needed by Dynamic
    Concepts support personnel.  Currently, the "extra" information consists
    of internal channels and recent operating system error codes.  The
    information printed by "extra" may vary in future releases.

o   Bug fixed: the default button did not change when a user tabbed to a 
    non-default push button.

o   Bug fixed: users could not tab out of a WCMEMO or WCTEXT box.

o   Bug fixed: INPUT timeout signals were not always received if the RECV
    or SIGNAL 2 statement immediately followed the INPUT statement.

May  4 2006 (Maintenance Release 6.2.5)

o   Bug fixed: a memory violation could occur when changing the colors
    used by a GUI element.

Apr 18 2006 (Maintenance Release 6.2.4)

o   Installation of dL4 on 64-bit Windows is now supported.  Previous versions
    of dL4 ran on 64-bit Windows, but had to be installed manually.

o   The "Copy and Paste Word" edit menu item has been moved down in the
    menu to reduce accidental use.

Mar 31 2006 (Maintenance Release 6.2.3)

o   A new mnemonic, 'SETTINGS', has been implemented in the Windows printer
    driver to override the printer page information supplied by Windows.  The
    mnemonic sequence 'wmm,hmm SETTINGS' will set the usable page size to 
    'wmm' millimeters wide and 'hmm' millimeters high.  The mnemonic sequence
    'xpi,ypi,poffx,poffy,wp,hp,wmm,hmm SETTINGS' will set the following
    values:

        xpi   - pixels per horizontal inch
        ypi   - pixels per vertical inch
        poffx - left offset in pixels
        poffy - top offset in pixels
        wp    - width in pixels
        hp    - height in pixels
        wmm   - width in millimeters
        hmm   - height in millimeters

    These values are defined to match the native Windows values.  This
    mnemonic should not be needed in normal printer use, but it can be
    used if the printer driver pages incorrectly.

    The 'SETTINGS' mnemonic can also be used with a single string parameter
    "test" to print 150 diagnostic lines which display various printer
    characteristics.

o   A tuning option has been implemented to redefine a "left mouse click" to 
    immediately send the word underneath the pointer as input along with a
    carriage return or just a carriage return if a blank area has been
    selected.  This option is enabled by adding 12288 (hexadecimal 1800)
    to the optional registry DWORD value
    
    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\TuningOptions

    or

    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\WinTerm\TuningOptions
    
    If this option is enabled, the standard left click actions to select
    text will be disabled.

o   A new option, "Copy and Paste Word", has been added to the "right click"
    floating edit menu.  If selected, the current word underneath the
    pointer will be copied and pasted.

o   The DL4DRIVERS runtime parameter has been extended to accept a "huge"
    option to cause Indexed-Contiguous, Contiguous, and Formatted files to
    be created as "huge" files by default.  The "huge" option can be
    combined with the "universal" option to create "huge universal" files
    by default.

o   The "Directory" and "Sorted Directory" drivers now support the CHF$()
    and CHF#() functions.

o   The "Sorted Directory" driver now supports a "caseinsensitive" or
    "nocase" boolean option to enable case insensitive sorting of directory
    entries.

o   The sort option in the tools/libr utility now ignore case when sorting
    directory entries.

o   Any value changes in a WCSTRING, WCNUMBER, or WCPRIVATE edit box can now
    be tracked by using the 'WCACTION' mnemonic to set the value tracking 
    action string as action number 3.  Example:

        PRINT PCHR$(10,3,'F40');'WCACTION'; ! Set action 3 for element 10
    
    Once action 3 has been defined, any change in the edit box value will
    be immediately reported by sending the action string ('F40' in the
    example) followed by the new value.  For example, if the edit box had
    the value "AB" and the user added a "C", then the program would receive
    the string 'F40' + "ABC" as input.  Tracking can be disabled by setting 
    the action string to "".

o   A new mnemonic, 'AUTOCOMPLETE', has been implemented for use with 
    WCSTRING or WCNUMBER edit boxes.  The mnemonic has two parameters:
    the GUI element number and the autocompletion string.  When processed,
    the 'AUTOCOMPLETE' mnemonic compares the current value of the edit box
    to the autocompletion string.  If the current value matches (ignoring
    case) the leading characters of the autocompletion string, the edit box
    value will be replaced by the autocompletion string leaving the caret
    position unchanged.  
    
    The 'AUTOCOMPLETE' mnemonic is intended to be used with edit box value
    tracking (see WCACTION 3 above).  A typical application would enable 
    value tracking and then, each time a new tracking value was received,
    the application would send an 'AUTOCOMPLETE' mnemonic with a suggested
    value.

    Example:

        PRINT PCHR$(10,"Wilson");'AUTOCOMPLETE';

o   Bug fixed: the makeuniv utility reported a "Channel in-use: 1" error if
    a file specified for conversion had already been converted.

o   Bug fixed: the DTOC option in a Full-ISAM Bridge profile did not
    correctly report some types of illegal date values.

o   Bug fixed: the tools/query utility could not be used on a C-Tree index
    file.

Jan 12 2006 (Maintenance Release 6.2.2)

o   Bug fixed: the backspace key didn't work in WCNUMBER edit boxes.

Dec 27 2005 (Maintenance Release 6.2.1)

o   The "MySQL SQL" driver now supports MySQL 5.x servers.

o   Behavior change: an empty menu bar is displayed if the menu bar is enabled
    even if all of the standard menu items are disabled.  This avoids some
    visual problems if an application uses and updates the menu bar.

o   Bug fixed: menu bars were displayed on all windows if the menu bar was
    enabled on the main window.

o   Bug fixed: structure assignments ("A. = B.") did not copy string members
    into the destination structure if an expression error occurred in a
    previous concatenating string assignment ('S$ = "ab","c",X$[5/0],"def"').

Dec  8 2005 (Release 6.2)

o   dL4 for Windows now includes an optional telnet-like service which makes
    it possible to run dL4 applications on a Windows server from thin clients
    that run dL4Term.  The server must use Windows 2000, Windows XP, or
    Windows 2003.  To install the service, run the script instlogn.bat in the
    "/Program Files/dL4" directory (or wherever dL4 was installed) from a
    command prompt as shown below:

        cd \Program Files\dL4
        instlogn.bat <ip-address> <port> <domain> <profile-dir>

    where

        <ip-address> is the IP address of the server
        <port> is the TCP port number to be used
        <domain> is the Windows domain defining the user accounts
        <profile-dir> is the full path of the user profile directory

    For example,

        instlogn.bat 192.168.0.5 23 win2ksys c:\dL4Profiles

    For systems that do not use Windows domains, the domain name is the
    name of the server.  Systems that have software firewalls may require
    reconfiguration of the firewall to accept connections to the selected
    port number.

    Each user of the dl4login service must have an account with local logon
    privileges on the Windows server.  For each user, a text file must also
    exist in the profile directory with the name "u_name" or "u_name.txt"
    where "name" is the Windows user id.  This file defines user specific
    environment variable values.  Each line of the file must be either a set
    command, an include command, or a comment line as shown below:

        set <variable-name> = <value>
        include <filename-in-the-profile-directory>
        ; comment text

    An include file is a text file containing SET, INCLUDE, or comment lines.
    Each user profile must define the values HOMEPATH and COMMAND via SET
    commands or INCLUDE files.  The HOMEPATH value defines the initial current 
    directory when a user logs onto the system.  The COMMAND value defines the 
    program which will be executed when the user logs in.  The following is a 
    typical user profile:

        set HOMEPATH=C:\Users\username
        set TERMDIR="C:\Program Files\dL4\Term"
        set TERM=dl4term
        set LIBSTRING=C:\AppDir
        set LUMAP=Data=C:\AppData
        set COMMAND="C:\Program Files\dL4\runc.exe" mastermenu.dl4

    If a SCOPE command line login is desired, set the value of COMMAND to
    scope.exe.  For example,

        set COMMAND="C:\Program Files\dL4\scopec.exe" -noshell

    Note that the scopec "-noshell" option is added to prevent users from 
    trying to start non-dL4 programs such as "Word" which cannot be used 
    via dL4Login.  Once dL4Login is installed and user profiles have been
    created, users can login by connecting to the server with dL4Term using
    the server address and port specified in the instlogn.bat command.  A
    port number is specified in dL4Term by connecting to "server:port"
    instead of simply "server".

    The dL4Login user profile supports an optional REALUSERID value.  If
    defined, the value is used as the actual login id.  This feature can be
    used to implement alternate user profiles with different environment 
    variable values for the same actual login id.  The user must login using
    the name of the user profile file (without the "u_" prefix).  For 
    example, a profile named "u_fredacctg" with the line

        set REALUSERID=fred

    could be created for the user "fred" to start an accounting application.
    To login, "fred" would type "fredacctg" as his login id along with his
    normal password.

    Before using dL4Login, please check your Windows server license to be
    certain that you are in compliance with Microsoft user license rules.
    Servers may need special configuration options to support more than
    10 simultaneous connections via dL4Login.

o   A new command line option, "-noshell", has been added to scopew.exe and
    scopec.exe.  The option disables running non-dL4 programs from a 
    SCOPE or BASIC command line.  This option is intended for use with
    the dl4login remote access service.

o   Port communication now uses a global name space.  This means that 
    terminal services and telnet users can now see and communicate via 
    PORT statements with other users running dL4 programs.  All users will 
    have unique port numbers.  The TERM utility can now display the status 
    of all dL4 programs and evict any session, even those belonging to 
    other users (as in dL4 for Unix).

o   A new GUI mnemonic, 'WCPAD', has been implemented to create transparent
    buttons.  The WCPAD GUI element is not visible and any text or images
    printed underneath the button area will be visible.  A left mouse click
    or left mouse double click anywhere in the specified area will send the
    associated event string (usually a function key character) as input.
    The behavior and usage of WCPAD is almost identical to WCBUTTON except
    that the button is transparent, the button cannot be used as a default,
    and the button does not react to the ENTER or TAB keys.  If the element
    is queried (WCQUERY), the position of the last "click" within the button
    will be returned in window coordinates relative to the upper left
    corner of the button.  The coordinates will be sent as two decimal 
    integer strings each followed by a carriage return with the horizontal
    coordinate sent first.  The mnemonic syntax is

        'n,x1,y1,x2,y2 WCPAD'

    or

        PChr$(n,x1,y1,x2,y2,"",0,s);'WCPAD'

    where "n" is the element number, "x1", "y1", "x2", and "y2" are numeric
    values specifying the upper left and lower right corners of the button
    rectangle, and "s" defines a scaling value.  If "s" is 10, the coordinates
    returned by WCQUERY will be multiplied by 10 and the units will be tenths
    of a column or row.  The default scaling value is 1.

o   A new GUI mnemonic, 'WCSHOWLIST', has been implemented to create read
    only list boxes.  The GUI elements created by the mnemonic are identical
    to those created by the 'WCLIST' mnemonic except that the user is not
    allowed to select items and the element value cannot be queried.

o   Double clicking on the main window now selects the word underneath the
    pointer.  

o   A tuning option has been implemented to redefine a "left mouse click" to 
    immediately send the word underneath the pointer as input along with a
    carriage return.  This option is enabled by adding 2048 (hexadecimal 800)
    to the optional registry DWORD value
    
    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\TuningOptions

    or

    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\WinTerm\TuningOptions
    
    If this option is enabled, the standard left click actions to select
    text will be disabled.

o   The "Preferences->Windows" dialog has been extended to support disabling
    the "Edit" and "Preferences" menus individually.  Using this feature, it
    is possible to move the "Preferences" menu to the less visible system
    menu while leaving the "Edit" menu on the standard menu bar.

o   The initial input mode can be set to "Insert" rather than "Replace" by
    adding 1024 (hexadecimal 400) to the optional registry DWORD value
    "Software\DynamicConcepts\dL4\Winterm\TuningOptions".  The dL4 default
    mode is "Replace" where newly typed characters overwrite any existing
    characters at the same position.  This new feature can be used to match
    the default insert mode used by Windows and some other systems.  With
    this option enabled, the user will need to type the "insert" key to
    toggle the input mode if the user wants to replace characters.

o   The Microsoft SQL Server Full-ISAM driver has been extended with an 
    open option, "nulls" or "nulls=true", to enable read and writing NULL
    values to table columns.  When a table is opened with the "nulls" option,
    NULL values in numeric, date, or character columns are converted to 
    special values when they are read.  When adding new records or modifying 
    existing records, NULL values can be written by writing the same 
    special values.  Currently, the special values are -1E62 for numeric 
    values, "January 1, 0001" for date values, and "\xffff\" for strings.
    Programs should not test for or set these values directly.  Instead,
    intrinsic functions have been provided to test for NULL values and to 
    set NULL values.  The intrinsic function IsSQLNull() returns 1 when its
    argument is a NULL value and 0 for all other values.  The intrinsic
    functions SQLNull(), SQLNull#(), and SQLNull$() return special NULL
    values for numbers, dates, and strings.  NULL values cannot be read
    into or written from integer numeric variables or 1% date variables
    because the special values cause overflow in those precisions (note
    that integer or simple date columns can be read or written using
    larger precisions).  NULL values are not supported for binary variables
    ("B?").  NULL values can be used in keys and index columns, but it is
    not recommended.

    Example:

        Declare Intrinsic Function IsSQLNull,SQLNull,SQLNull#,SQLNull$
        Open #1,"(nulls)server:database.table" As "MSSQL Full-ISAM"
        ! Display table with possible NULL values
        Do
            Try Read Record #1;R. Else Exit Do
            Print "Name = ";R.CustomerName$
            Print "Appointment = ";
            If IsSQLNull(R.AppointmentDate#)
                Print "none"
            Else
                Print R.AppointmentDate#
            End If
        Loop
        ! Add new record with NULL value
        R.CustomerName$ = "John Quinn"
        R.AppointmentDate# = SQLNull#()
        Add Record #1;R.

o   The MySQL SQL driver now supports reading TIME values into numeric or
    string variables.  If read into a numeric variable, the time will be
    converted to seconds from midnight.

o   The MySQL SQL driver now supports reading TEXT values into string
    variables.

o   The MySQL SQL driver now supports reading backwards from the current
    position in the result set using record -3.

o   The MySQL SQL driver now reports the following new error codes when
    appropriate:

        279    SQL implementation or configuration limit exceeded
        280    SQL procedure error
        281    Constraint not satisfied
        282    Deadlock detected

o   The MySQL SQL and MySQL Full-ISAM drivers now use the MySQL 4.1 client
    library to support MySQL 4.1 passwords.

o   A new file BUILD option, "<z>", has been implemented to create portable
    contiguous or portable indexed contiguous files using BITS data 
    formats.  Because BITS data formats are not portable between platforms,
    this option should only be used by programs that need to use BITS
    formats.  Example:

        Build #4,"<z>[1:40]filename"

    The BITS formats can also be selected by setting the NUMMAP option to 
    "BITS", "BITS-BE" (most significant byte first), or "BITS-LE"
    (least significant byte first or Intel ordering).

o   A BUILD option of "NUMMAP=IEEE-BE" has been implemented for contiguous
    and indexed contiguous files.  The option is equivalent to "IEEE".

o   A new program option, "OPTION ARITHMETIC EXTENDED IEEE", has been
    implemented to select 16-bit and 32-bit binary integer formats and
    IEEE decimal floating point formats.  The default "IEEE" option uses
    BCD integers with a smaller range than the binary integer formats.

o   Behavior change: CALL TRXCO() and "PORT 2" statements can no longer
    send text commands to interactive ports unless the runtime parameter
    DL4ACCEPTPORTCMDS is set to "TRUE" in the receiving port's environment.
    This change has been made to improve user security.  Phantom ports
    always accept commands from any user.

o   The "Selected Page Printer" driver now longer displays a printer 
    selection dialog if it is called from the dL4Login environment.  If
    used, the driver will select the default printer.

o   A new script, "binarylp.bat", and a new printer profile, "binarylp.prf",
    have been added to the "printer" directory as examples of a printer
    using binary output.

o   The intrinsic CALL PROGRAMDUMP() now supports a "byname" option to
    sort variable names by name only instead of by type and name.

o   The performance of the profile driver has been improved.

o   Enhancement: when a forwarding error occurs in the email driver, a
    "Forward address" string will be appended to the "file not found"
    error text in the HELP command or the MSC$(2) function.

o   Enhancement: CALL RDFHD() now supports file and directory names that
    contain spaces.

o   Behavior change: the TERM utility now assumes a 24 line screen for
    paging if the terminal definition specifies a screen size of zero
    or if the terminal type isn't specified when using scopec.exe or 
    runc.exe.

o   A VARIABLE command has been added to the SCOPE BASIC and debug modes to
    display a table of variable names used in the current procedure.

o   Behavior change: the main window is now enlarged when a menu bar is 
    created if the standard menu bar is disabled at startup.  Previously,
    the window size was left unchanged and scroll bars were displayed.  The
    window is not enlarged if the scroll bars were already present.

o   Behavior change: when using a WCNUMBER box, illegal input characters are
    completely ignored and will not delete existing data if the BEGIN
    mnemonic is used.

o   Behavior change: when GUI elements are disabled, any "marked" items
    will be displayed using the WCMARKCOLOR background color (if any).

o   Behavior change: the Microsoft SQL Server and MySQL Full-ISAM drivers
    now recognize "rtrim" as identical to "rtrim=true" in the open options.

o   Behavior change: the formatting of attachments in the email driver has 
    been changed to improve compatibility with some email clients.

o   Behavior change: the scope DISPLAY command and CALL PROGRAMDUMP() now
    print quotation marks in string variables as two consecutive single
    quotes.  This is the format used by the LIST command when printing string
    literal values in programs.

o   Bug fixed: CALL PROGRAMDUMP() entered an infinite loop if a displayed
    string variable contained more mnemonic characters than could be
    shown on a single line.  CALL PROGRMDUMP() also displayed only one line
    of data for string variables.

o   Bug fixed: double clicking an already selected item in a WCLIST box 
    generated a double click event but a subsequent WCQUERY to the box
    did not return the selected item.

o   Bug fixed: a required DLL, gdiplus.dll, wasn't always installed when
    needed on Windows 2000 systems.

o   Beta bug fixed: the TERM utility did not display open channels or blocked
    channel status correctly when the displayed port had a large number of
    channels open.

o   Bug fixed: the Microsoft SQL Server Full-ISAM driver could not use
    Windows authentication with SQL Server 2000 service pack 3 or later.
    The driver now uses Windows authentication whenever the user name
    and password options are NOT specified.

o   Bug fix: scrolling backwards into the history buffer moved GUI elements 
    off of the current window, but scrolling forwards did not restore the 
    GUI elements.

o   Bug fix: the socket driver waited forever if a bad address was supplied
    and the OPENTIME timeout option wasn't specified.  The driver will now
    timeout after 60 seconds.

o   Bug fix: various dL4Login user profile errors are now reported to the
    user.

o   Bug fix: the debugger LET command did not work and reported a "format"
    error.

o   Bug fix: the BATCH utility did not work.

o   Bug fixed: CALL SORTINSTRING() sometimes caused memory violations.

o   Bug fixed: CALL RDFHD() reported a random error, usually, "Illegal driver
    operation", when the creation date, access date, or file id parameter
    precision was too small to contain the returned value.

Apr 20 2005 (Release 6.1)

o   A new intrinsic CALL, DRAWIMAGE(), has been added to display JPEG,
    BMP, and other image files in a window or to a printer.  The new
    CALL has the following syntax:

        Call DrawImage(Filename$, X1, Y1, X2, Y2)

    or

        Call DrawImage(Channel, Filename$, X1, Y1, X2, Y2)

    where:

        "Filename$" is the path of an image file,
        "X1" and "Y1" are the horizontal and vertical coordinates of the
        upper left corner of the rectangle in which the image should be
        displayed,
        "X2" and "Y2" are the horizontal and vertical coordinates of the
        lower right corner of the rectangle in which the image should be
        displayed.

    The image will be displayed as large as possible within the display
    rectangle without changing the aspect ratio of the image.

o   Two new mnemonics, 'FITIMAGE' and 'FILLIMAGE', has been defined to 
    draw client system JPEG, BMP, and other image files in a window or on a
    printer.  The 'FITIMAGE' mnemonic draws an image as large as possible
    in a specified rectangle without changing the aspect ration of the image.
    The 'FILLIMAGE' mnemonic stretches or shrink the image as necessary to
    fill the entire specified rectangle.  Examples:

        Print #1;PChr$("filepath",X1,Y1,X2,Y2);'FITIMAGE'
        Print #1;PChr$("filepath",X1,Y1,X2,Y2);'FILLIMAGE'

    where "X1" and "Y1" are the horizontal and vertical coordinates of the 
    upper left corner of the display rectangle and "X2" and "Y2" are the
    coordinates of the lower right corner.

o   A new mnemonic, 'WCEXTKEYS', has been defined to enable extended key
    functionality in GUI programs.  After printing the mnemonic 'WCEXTKEYS'
    to a dL4 or dL4Term window, pressing the ENTER key will cause the 
    input focus to move from the current GUI element to the next GUI element
    with a tab stop defined (this is identical to the behavior of the TAB
    key).  The 'WCEXTKEYS' mnemonic will also cause the ENTER key to 
    generate a new line when typed in a WCMEMO box.  These two features can
    be enabled or disabled individually by using a numeric parameter to the
    'WCEXTKEYS' mnemonic as shown below:

        'WCEXTKEYS'  -  enables both ENTER-as-TAB-between-GUI-elements
                        and ENTER-as-newline in WCMEMO box.
        '1WCEXTKEYS'  - enables only ENTER-as-TAB-between-GUI-elements.
        '2WCEXTKEYS'  - enables only ENTER-as-newline in WCMEMO box.
        '3WCEXTKEYS'  - enables both features.
        '0WCEXTKEYS'  - disables both features.

o   The 'WCTEXT' mnemonic now supports an eighth parameter to define the
    logical width of the text box and enable a horizontal scroll bar.  This
    feature is used to display text which is wider than the text box.  The
    following example defines a text box which is 40 character wide in the
    window, but contains up to 80 character wide lines.

        Print PChr$(10,20,5,60,9,"Label",2,80);'WCTEXT';

o   The window driver has been enhanced to support a history scrollback
    feature.  The new feature is disabled by default, but can be enabled
    by setting the "History Pages" value in the "Preferences->Window"
    dialog.  After settings the "History Pages" value, dL4 must be restarted
    to use the new value.

o   The range of GUI element numbers has been increased to 1 through 9999.
    The previous range was 1 to 1000.

o   A new Edit menu item, "Copy And Paste", has been added to copy and
    paste selected text in a single action.

o   A "RAW" option has been implemented in the DEF STRUCT statement for
    structure members and for entire structures.  This option can be used
    with structures so that READ RECORD and WRITE RECORD statements will
    use "Raw" file behavior when accessing contiguous files.  This allows
    placing numeric fields on odd byte boundaries, writing entire strings as
    in MAT WRITE, and not including an extra character for string terminators
    (when a string is DIMmed as 10 characters, a normal READ or WRITE treats
    the field as being 11 characters long).  Examples:

        Def Struct CUSTREC : Raw
          Member AString$[10]
          Member 3%,ANumber
        End Def 

        Def Struct CUSTREC
          Member AString$[10] : Raw
          Member 3%,ANumber
        End Def 

o   The bridge driver has been extended to allow use of random record
    numbers in SEARCH deallocate or insert operations if the "real record
    number" option is being used.

o   The MySQL SQL driver now supports a "db=" option in the "DL4MYSQL"
    runtime/environment parameter.  The "db=" option is equivalent to the
    "database=" option.

o   The MySQL Full-ISAM driver now supports a "db=" option in the 
    "DL4MYSQLISAM" runtime/environment parameter.  The "db=" option is 
    equivalent to the "database=" option.  

o   The Microsoft SQL Server Full-ISAM driver now supports a "db=" option in 
    the "DL4MSSQLISAM" runtime/environment parameter.  The "db=" option is 
    equivalent to the "database=" option.  A "password=" option has been
    added and is equivalent to "pswd=".

o   The MySQL Full-ISAM and Microsoft SQL Full-ISAM drivers now support a
    "readahead=n" open option where "n" is the number of rows to buffer
    when reading sequentially in read-only (ROPEN) mode.  Reading backwards
    is not supported when "n" is greater than one.

o   The MySQL Full-ISAM driver now requires a MySQL server version of 4.0.3
    or later for full functionality.

o   A "serialize" open option has been added to the text file driver to
    prevent multiple programs that are writing to the same text file from
    intermixing their output.  This option would normally be used when
    appending to a log file.  Example:

        Open #1,"(serialize)logfile.txt"
        Print #1;Tim#(0);": Process started"

    If multiple lines are being written, all lines must be written in a
    single statement or the lines may be intermixed.

o   A new BUILD option has been added to the Portable and Universal indexed
    contiguous file drivers.  The "key=l1:l2:.." option creates indexes at 
    the same time the file is created.  The option creates an index,
    starting with index 1, for each of the key length values l1, l2, 
    through ln.  The key lengths are specified in bytes.  Example:

        Build #3,"(key=10,6,16)[1:40]filename"

o   A new SEARCH mode has been defined to search for the next allocated
    record in a Portable or Universal indexed contiguous file.  The new 
    mode is invoked by SEARCH mode 3 with an index value of 0.  The 
    statement will return the next allocated record number greater than 
    the supplied record number.  A key parameter is syntactically required 
    by the SEARCH statement, but it is not used by the new mode.  Example:

        Search #1,3,0;DummyKey$,RecNbr,Status

o   A new open option, "ARGS=value", has been added to the pipe driver to
    define an "ARGS" parameter to the driver selected by an "OPENAS="
    option.  

o   The "TCP Socket" and "Socket Text" drivers now support an open option, 
    "OPENTIME=n", to cause OPEN statements to timeout after "n" seconds.
    Example:

        Open #3,"(opentime=10)www.dynamic.com" As "Socket"

o   A new MSC() function, MSC(46), has been defined to return the original
    line number at which a CALL stack propagated error occurred.  For
    example, if a "Divide by Zero" error occurred at line 150 of a procedure
    which did not have an error handler and the caller did have an error
    handler, SPC(10) would report the error as occurring at the CALL 
    statement.  The new MSC(46) function will report the original error
    line number of 150.

o   The SCOPE debugger now supports the SPC(), MSC(), and HEX$() functions.
    In addition, debugger expressions can now use relational operators,
    logical operators, and concatenation.

o   Program dumps (as from CALL ProgramDump()) display MSC() values 44 
    through 46.

o   The intrinsic CALL DXMerge() can now support "include" files.  Please see
    the dynamicXport documentation for additional information on CALL
    DXMerge().

o   The tools/query utility has been enhanced with  a "-k" option to count 
    the number of keys used in indexed contiguous file directories.  A "-s" 
    option has been added to output Full-ISAM information in the form of 
    DEF STRUCT and MEMBER statements.  The "/" character can no longer be 
    used as a lead-in for options.

o   Behavior change: if access permissions cannot be applied when creating
    a file because the file system does not support permissions, the error
    will be ignored and the file will be created without the unsupported
    permissions.

o   Beta bug fixed: the printer driver expected an incorrect parameter order
    for the 'FITIMAGE' and 'FILLIMAGE' mnemonics.

o   Bug fixed: potential memory corruption problems in the MySQL SQL driver,
    the SQLV$() function, the SQLN$() function, and the SQLNV$() function
    have been corrected.

o   Bug fixed: screen corruption could occur when using some video adapters.

o   Bug fixed: FoxPro Full-ISAM memo fields did not work on Linux x86  
    systems and possibly some other platforms.

o   Bug fixed: when DL4DEFLU was defined but the directory specified in 
    DL4DEFLU didn't exist, an error occurred when building new files.

o   Bug fixed: the VT100 terminal definition file did not clear the state
    of the character attributes.

o   Bug fixed: many of the standard terminal definition files did not draw
    boxes or lines correctly.

o   Bug fixed: the 'WCSETCOLOR' and 'WCMARKCOLOR' mnemonics did not support
    the special negative color values used to select window scheme colors.

o   Bug fixed: sending a 'WCQUERY' to a 'WCLISTDROP' box that had been
    'WCMARK'd before initializing the box values caused a memory violation.

o   Bug fixed: GUI elements were not drawn correctly when disabled under
    some conditions such as program specified colors.

o   Bug fixed: the "OPENAS=" open option in the pipe driver can now select
    the pipe driver itself as a driver.

o   Bug fixed: a potentially long table scan occurred for each sequential
    read in a non-unique index when using the MySQL Full-ISAM driver.

o   Bug fixed: a memory violation occurred if columns beyond the end of the
    line were selected and the DELETE key was pressed.

o   Bug fixed: empty string values in the SQLV$() and SQLNV$() functions 
    caused random errors.

o   Bug fixed: the "-c checksum" option of the tools/checksum utility did
    not work in MD5 mode if the checksum value had less than 32 digits.

Aug 26 2004 (Maintenance Release 5.3.4)

o   The email driver has been enhanced to support user authentication on 
    SMTP servers that require user authentication.  To enable authentication,
    the OPEN statement option parameters or the DL4EMAILSERVER runtime 
    parameter must specify the new "user" and "password" (or "pswd") options.
    These options must not be specified unless the SMTP server supports
    authentication.  Examples:

        Open #5,"(user=fred,password=secret,from=fred)henry" As "Email"

        set DL4EMAILSERVER=smtp.something.com,user=fred,password=secret

    In addition to the new "user", "password", and "pswd" options, an
    additional "auth" option has been added to allow selection of a specific
    authorization method.  The email driver currently supports the three
    most common methods: "LOGIN", "PLAIN", and "CRAM-MD5".  The driver will
    use the best method available on the SMTP server with preference given
    to "CRAM-MD5" because it does not transmit the actual password over the
    network.  The "auth" option can be used to select the "LOGIN" or "PLAIN"
    method if the SMTP server provides an incompatible "CRAM-MD5" method.
    If the "auth" option selects a method that is not supported by the SMTP
    server, the email driver will attempt to connect without authenticating
    the user.  Example:

        set DL4EMAILSERVER=smtp.something.com,auth=login

    Note: for compatibility with previous releases, the DL4EMAILSERVER value,
    if defined, must begin with a server name.

o   Bug fixed: the SCOPE DISPLAY command and program dumps did not list
    string members of structure variables that had null ("") values.

Jun 23 2004 (Maintenance release 5.3.3)

o   Two new printer drivers, "Terminal Printer" and "Default Terminal Printer"
    have been added to open a named or the default printer via dL4Term on a
    client PC.

o   A new intrinsic CALL, UBSTRING(), and two new intrinsic functions, 
    UBASC() and UBCHR$(), have been added to provide uniBasic-like character
    conversion routines.  The parameters and return values of the routines
    are identical to CALL STRING(), ASC(), and CHR$() except that ASCII
    characters are mapped to the integer range 129 through 255 and uniBasic 
    compatible mnemonics are mapped to the range 1 through 127.  These 
    routines can be used to simplify conversion of uniBasic programs to dL4.

o   Bug fixed: the intrinsic CALLs UNPKDEC21(), UNPKDEC46(), UNPKRDX5019(),
    and UNPKRDX5049() copied random data into the destination variable after
    the unpacked data.

o   Bug fixed: Mode 4 of CALL STRING() did not add a string terminator after
    the converted character value.

o   Bug fixed: the "Page Printer" driver could not open a quoted printer 
    name (needed for printer names with spaces).

May 21 2004 (Maintenance release 5.3.2)

o   A new open option, "CONTENT=HTML" has been added to the email driver to
    send email with HTML formatting commands.  The driver enables HTML
    formatting, but it does not add formatting commands itself.  The 
    application is responsible for all HTML formatting commands as 
    shown in the following example:

        Opts$ = "(From=someone,Content=html,Subject=''(test)'')"
        Open #1,Opts$ + "somebody" As "Email"
        Print #1;"This is <b>bold</b> and this is <u>underlined.</u>"
        Close #1

    The open option "CONTENT=TEXT" selects non-HTML text format (the default).

o   Bug fixed: percent sign ("%") and underscore ("_") characters were
    converted to "\%" and "\_" when adding data to or searching in
    MySQL tables using the MySQL driver or the MySQL Full-ISAM driver.

o   Bug fixed: the Windows Page Printer driver, when used in binary output
    mode, added a null at the end of each write.

May 11 2004 (Maintenance release 5.3.1)

o   Bug fixed: the Replace$() and ReplaceCI$() intrinsic string functions
    corrupted memory when replacing a single character with a multiple
    character string.

o   Bug fixed: CALL INPBUF() inserted typeahead characters at end of the
    typeahead buffer when used with dL4Term instead of at the beginning of
    the buffer as done for other terminal types.

Apr 14 2004 (Release 5.3)

o   The Full-ISAM Bridge driver has been enhanced to support keys that
    contain the current record number when the Bridge driver is used with 
    the MySQL Full-ISAM driver or the Microsoft Full-ISAM driver.  In the
    Bridge profile, a record number segment of a key must reference the
    IDENTITY column of the Full-ISAM table and use the NTOC(), STR(),
    NTVNTOC(), or NTVSTR() functions to convert the IDENTITY column
    value to a character format.  To use this feature, the option
    "RealRecordNumbers" must be enabled.

o   The Full-ISAM Bridge driver has been enhanced with two new conversion
    functions: STR() and NTVSTR().  These functions are similar to NTOC() 
    and NTVNTOC(), but they use a simpler mask consisting only of spaces and 
    a single "#" character.  The "#" character is replaced with a default 
    conversion of the number and any spaces are copied.  The purpose of the 
    STR() and NTVSTR() functions is to duplicate fields that are created by 
    simple assignment or concatenation of numeric values:

        TheKey$ = "Name", RecNo

    Bridge profile example:

        KeyPart=IDCOL,5,7,"","0123456789",STR("#")

o   A new option has been added to the Full-ISAM Bridge driver profile to
    support unbalanced indexes by allowing such indexes to be placed in
    separate Indexed-Contiguous or Full-ISAM files outside the main Full-ISAM
    file.  For example, if index 3 of an Indexed-Contiguous file is used as
    a scratch index with entries for only some of the file records (and is 
    thus unbalanced), that index could not be emulated by the Bridge driver 
    within the main Full-ISAM file because Full-ISAM files do not support 
    unbalanced indexes.  Using the new option, the index can be emulated by 
    declaring an external index in the bridge profile.  For example:

        [Index3]
        File=filename
        Index=1
        KeyPart=name,0,10

    This example directs the bridge driver to perform all SEARCH operations
    on index 3 by applying the SEARCH operations to index 1 of the Indexed
    Contiguous file "filename".  The bridge profile would also have to use
    the "RealRecordNumbers" option described below so that the record
    numbers in the keys of index 3 could be used to reference records in the 
    main Full-ISAM file.  External indexes can have multiple keys for the
    same record or use multiple key formats.  The data in the key is 
    completely controlled by the application and does not need to be present
    in any of the fields of the main Full-ISAM file.  An external index
    definition can only have one "KeyPart" entry and, if the external index
    file is indexed contiguous, the field name is ignored (but it must be
    specified).

    External index files can either be Indexed Contiguous files or Full-ISAM
    files.  If an Indexed-Contiguous file is used, the bridge driver will
    only access the index portion of the file.  To use a Full-ISAM file as
    an external index file, the following format must be used in the bridge
    profile:

        [Index3]
        File=filename
        Name=indexname
        KeyPart=keyfieldname,0,10,,,Strip
        RecPart=recnbrfieldname

    where "filename" is the name of the external Full-ISAM file, "indexname"
    is the name of the index within the Full-ISAM file, "keyfieldname" is the
    name of the Full-ISAM field used for the key (this must be a character
    field), and "recnbrfieldname" is the name of the Full-ISAM field used for
    the record number (this must be a numeric field).  External index
    definitions can include "Filename", "Protection", "Options", "OpenAs",
    and "OpenInProfileDirectory" entries using the same format and function
    as such entries in the main bridge profile section.  If the file
    protection option is not specified, the protection options used to open
    the main Full-ISAM file will be applied when opening the external index
    file.

o   A new option has been added to the Full-ISAM Bridge driver profile
    to support programs that accidentally span a record boundary when 
    reading string values.  When set to TRUE, the option "TruncateSpanning"
    disables the normal "Illegal item number" (error 53) error that is
    reported when a program reads a character variable whose length extends
    beyond the end of the record.  The driver will treat such reads as if
    the read ended exactly at the end of the record.  Example:

        [FullISAMBridge]
        File=filename
        OpenAs=FoxPro Full-ISAM
        TruncateSpanning=True

o   A new option has been added to the Full-ISAM Bridge driver profile
    to support programs reading records by record number.  When set to TRUE,
    the option "RealRecordNumbers" causes the driver to return the actual
    Full-ISAM file record number when performing SEARCH statements that
    return a record number.  The record numbers returned by SEARCH can
    then be used to perform random reads from the file.  The option can
    only be used with Full-ISAM drivers and files that support searching 
    index 0 for equal record numbers.  Example:

        [FullISAMBridge]
        File=filename
        OpenAs=FoxPro Full-ISAM
        RealRecordNumbers=True

o   The FoxPro Full-ISAM driver has been extended to support a SEARCH-equal
    operation on index 0 using a record number as the key value.  Such
    searches can be performed on any FoxPro Full-ISAM file.  Example:

        SEARCH = #5,0;R

o   The MySQL Full-ISAM driver has been extended to support a SEARCH-equal
    operation on index 0 using a record number as the key value.  Such  
    searches can be performed only on tables that contain an AUTO_INCREMENT
    column and a unique index based only on that column.  The value of the
    AUTO_INCREMENT column is treated as the record number of the row.
    Example:

        SEARCH = #5,0;R

o   The MySQL Full-ISAM driver has been enhanced to support tables whose
    only unique index contains an AUTO_INCREMENT column.

o   The MySQL Full-ISAM driver has been enhanced to support the creation
    of tables with numeric IDENTITY (AUTO_INCREMENT) columns.  A table can 
    contain only one IDENTITY column which must be an integer type (such as
    1%, 7%, %1, or %2).  Creating a table with an IDENTITY column will 
    automatically create a unique index based on that column (the primary 
    key).  Example:

        Def Struct REC
          Member S$ : Item "LABEL"
          Member %2,Id : Item "IDCOL" : Identity
        End Def
        Dim Rec. As REC
        Build #2,"test.table" As "MySQL Full-ISAM"
        Define Record #2;Rec.
        Close #2

o   The Microsoft SQL Server Full-ISAM driver has been extended to support 
    a SEARCH-equal operation on index 0 using a record number as the key 
    value.  Such  searches can be performed only on tables that contain an 
    IDENTITY column and a unique index based only on that column.  The value
    of the IDENTITY column is treated as the record number of the row.
    Example:

        SEARCH = #5,0;R

o   The Microsoft SQL Server Full-ISAM driver has been enhanced to support 
    tables whose only unique index contains an IDENTITY column.

o   The Microsoft SQL Server Full-ISAM driver has been enhanced to support
    creating tables with the BUILD statement and deleting tables with the
    KILL statement.  An "AS" clause must be used with either statement to
    specify the driver.  Example:

        KILL "(user=bill,pswd=notsosecret)test.info" AS "MSSQL Full-ISAM"

o   The Microsoft SQL Server Full-ISAM driver has been enhanced to accept a
    default server name, database name, user name, and/or password from a new 
    runtime parameter, "DL4MSSQLISAM".  The runtime parameter can be placed 
    in the environment or in the registry and supports the comma separated 
    options "server=name", ,"database=name", "user=name", "password="string",
    and "pswd=string".

    Example for a Windows command line shell:

        C:\> Set DL4MSSQLISAM=server=myserver,user=anonymous

    Note: defining passwords in the environment or the registry is insecure.
    If at all possible, Windows Authentication based on the current login 
    should be used instead of explicit user names and passwords.

o   A new GUI mnemonic, 'FRAME', has been defined for use with dL4Term or
    dL4 for Windows.  The new mnemonic draws a frame around a specified 
    rectangle.  The mnemonic has two formats:

        PChr$(Left,Top,Right,Bottom);'FRAME';
        PChr$(Left,Top,Right,Bottom,Type$);'FRAME';
        
    The optional "Type$" parameter specifies the frame style which can be
    either "Sunken" ("S"), "Raised" ("R"), "Etched" (E), or "Bump" ("B").  
    If the "Type$" parameter is omitted or is "", the frame style will be
    similar to that of a 'WCSTRING' input box.  When using the 'FRAME'
    mnemonic, sufficient space must be left around the rectangle to draw
    the frame.  The frame is not a GUI element; it is drawn graphically like
    the 'RECT' mnemonic and the frame can be overwritten by characters or 
    graphics.  The frame color is determined by the current Windows color 
    scheme and is not controlled by any of the color mnemonics.

o   Four new GUI mnemonics, 'WCMSGASK', 'WCMSGERROR', 'WCMSGINFO', and
    'WCMSGWARN', have been implemented to display standard Windows message
    dialog boxes.  All of the mnemonics have three formats as shown below
    for the 'WCMSGASK' mnemonic:

        PChr$("Message");'WCMSGASK';
        PChr$("Message","Title");'WCMSGASK';
        PChr$("Message","Title","Options");'WCMSGASK';

    The "Options" string determines the number and labeling of the
    buttons within the message box:

        "ARI"       "Abort", "Retry", "Ignore"
        "O"         "Ok"
        "OC"        "Ok", "Cancel"
        "RC"        "Retry", "Cancel"
        "YN"        "Yes", "No"
        "YNC"       "Yes", "No", "Cancel"

    The characters in the "Options" string may be in lower or upper case,
    but the first uppercase letter will select the associated button as the 
    default button.  The message box returns as input the uppercase label 
    string of the button selected by the user followed by a carriage return.
    Example:

        Print PChr$("Continue?", "I/O Error", "yN");'WCMSGERROR';
        Print 'IOEE K0';
        Input "";I$
        Select Case I$
            Case "YES"
                .
                .
            Case "NO"
                .
                .
        End Select

o   A new function, MSC$(9), has been implemented to return the native
    absolute path of the directory containing the current program file.

o   The tools/term utility has been enhanced to optionally display the
    channels open on each monitored port.  The "F" option ("term all mf")
    shows each open channel number, the filename open on the channel, and,
    if supported, the current record number.  The record number is followed 
    by a letter showing the lock status of the record.  The status letters
    are "U" (unlocked), "L" (locked), and "B" (blocked waiting for a record
    lock).

o   The tools/term utility has been enhanced with a "B" option to display
    only ports that are blocked waiting for a record lock.  For each
    blocked port, the utility finds and displays the port number of the
    program which is currently locking the desired record.  Example:

        term all mb

o   New options have been added to the tools/query utility.  The "-p" option
    enables division of long displays into screen sized pages.  The "-l",
    "-l=$printer", "-l=path" options direct output to the "$lpt" printer,
    "$printer" printer, or the "path" text file respectively.

o   The PORT mode 7 statement has been enhanced to optionally return the
    group name, current directory path, terminal type, numeric account, and 
    numeric group for the selected port.  The group name, numeric account,
    and numeric group values are returned as "" under Windows.

        PORT portnum,7,status,userid$,station$,group$,dir$,term$,usern$,grpn$

    Note that the PORT mode 7 statement may have between 5 and 10 parameters.

o   The PORT statement has been extended with a new mode, 8, that returns
    the open channels on the specified port.  The statement

        PORT portnum,8,status,firstchan,lastchan,chaninfo.[] 

    returns open channel information into the array 'chaninfo.[]' for 
    channels between 'firstchan' and 'lastchan'.  The 'chaninfo.[]' 
    variable must be an array of structures using the following structure
    definition:

        Def Struct CHANINFO
            Member 1%,ChanNum
            Member Path$[200]
            Member 3%,RecordNum
            Member 1%,RecordState
        End Def

    The member names, dimensioned size of the Path$ member, and the numeric
    precisions of the other structure members can be varied as desired.  The
    filename returned in Path$ may be truncated if it is longer than Path$
    or if it exceeds system limitations.  If the number of open channels in
    the specified range is less than the dimensioned size of 'chaninfo.[]',
    then the first unused element of the array will have a ChanNum value
    of -1.  If the number of open channels in the specified range is greater
    than the dimensioned size of 'chaninfo.[]', the extra channels will
    be ignored.

o   The PORT statement has been extended with a new mode, 9, that determines
    if a specified file is open on the port and optionally determines if
    a specified record number is locked in the file.  The statement

        PORT portnum,9,status,filepath$,recordnum,channum

    performs an inquiry on port 'portnum' to determine if it has 'filepath$'
    open on a channel with the record 'recordnum' locked.  If 'recordnum'
    is negative, the search will be performed using only the file path.  If
    a match is found, the channel open to the file will be returned in
    'channum'.  If a match is not found, then 'channum' will be set to
    -1.

o   The CALL MONITOR() procedure in the tools/oldcalls.lib compatibility 
    library has been enhanced to return current directory, terminal type,
    and open channel information.

o   A new open option has been added to the Windows Page Printer driver.
    The "wrap=<boolean>" option enables or disables line wrapping for
    lines that exceed the maximum line length.  The default is to disable
    line wrapping and truncate long lines.  Example:

        OPEN #5,"(wrap=true)$selectlp"

o   The EOPEN statement and the intrinsic CALL LOCK() can now be used
    with text files.  If a text file is opened using EOPEN or locked with
    CALL LOCK(), the file cannot be opened by other dL4 users.  Unlike 
    portable contiguous and formatted files, the EOPEN statement will succeed 
    on text files that have been opened for shared usage by other ports.

o   The intrinsic CALL SORTINSTRING() has been extended to support sorting
    arrays of strings or arrays of structures where the first structure
    member is a string.  New formats:

        Call SortInString(status,keycnt,keylen,keys$[],work$)
        Call SortInString(status,keycnt,keylen,keys.[],work.)

    The 'work$' and 'work.' variables should be identical to individual
    elements of the 'keys$[]' and 'keys.[]' arrays.  The 'keylen' value
    specifies the maximum number of significant characters in the sorted 
    values and can be used to perform a sort on the first 'keylen'
    characters of each key value.

o   The statement

        SYSTEM 33,"C:\\Program Files\\Application\\program.exe",S

    will try to execute "program.exe" on the user's PC.  The variable
    "S" will be set to zero if the program was successfully started and
    non-zero if the program couldn't be started.  Unlike SYSTEM or
    SYSTEM 31, the statement does not wait for the program to finish
    and exit.  In the default configuration, the user will be prompted via 
    a message box to permit or deny running the command.  The DWORD 
    registry value

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\AllowSYSTEMCmd

    or

    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\WinTerm\AllowSYSTEMCmd

    can be set to one to automatically accept commands without displaying 
    the message box (note: if set to zero, an "AllowSYSTEMCmd" value in  
    HKEY_CURRENT_USER will require the message box no matter how the
    HKEY_LOCAL_MACHINE value is set).

o   The console versions of dL4, scopec.exe and runc.exe, now support the
    use of dL4Term as a client under Windows telnet servers.  The "Windows 
    Terminal Printer" driver has been added to dL4 for Windows for use
    with dL4Term.

o   The dL4 QUERY utility (tools/query) has been extended to display 
    whether a Full-ISAM field is an IDENTITY field.

o   Behavior change: the object revision in program files is now set more
    accurately.  This improvement will permit more programs saved under a
    current version of dL4 to run under older versions of dL4.

o   Behavior change: the SYSTEM statement now searches additional directories
    when attempting to execute an operating system command.  For example,
    the SYSTEM statement can now execute "iexplore.exe" (Internet Explorer)
    without an absolute path to the executable.

o   Behavior change: WCNUMBER boxes now accept commas as valid input
    characters.  If the WCNUMBER box value is queried, the commas will
    not be returned as part of the value.

o   Behavior change: WCTEXT boxes no longer display scroll bars if the
    number of lines is exactly equal to the size of the text box.

o   Behavior change: tab characters in source line comments are expanded
    into spaces using the indentation value as the tab width.

o   Bug fixed: the dL4 IC2FI (tools/ic2fi) utility did not allow users to
    convert files if the original key length of an index was longer than
    the key length in the bridge profile.  This prevented conversion of
    files because key lengths in Indexed Contiguous files are normally 
    rounded up to even values and are thus longer than the actual key size.
    The utility now displays a warning message, but allows the user to 
    continue conversion.

o   Bug fixed: using the CHF() function with the Microsoft SQL Full-ISAM
    driver caused any subsequent SEARCH, READ, WRITE, ADD, or DELETE
    statement using the same channel to fail.

o   Bug fixed: when using the Microsoft SQL or MySQL Full-ISAM drivers with
    an identity column as the unique index, an attempt to modify the identity 
    column could sometimes cause the wrong row to be modified.

o   Bug fixed: the PORT 6 statement returned zero instead of -1 when the
    blocking port number was unknown.

o   Bug fixed: the Microsoft SQL Server Full-ISAM did not support record
    number based SEARCH statements if there was a non-IDENTITY based index
    that had a key size smaller than the IDENTITY based index (a key size 
    of 3 or fewer characters).  This prevented the Full-ISAM Bridge driver 
    from supporting the "RealRecordNumbers" option.

Dec  5 2003 (Maintenance release 5.2.4)

o   Bug fixed: GUI element labels and list box items were not sized correctly
    if the GUI element font size differed from the standard dialog font size.

o   Bug fixed: if the canvas was taller than the window, the display was
    corrupted and the scroll bar did not work.

o   Bug fixed: if the main window was minimized and then restored, scroll
    bars were displayed.

o   Bug fixed: a scroll bar was displayed in a GUI list box if the number of
    elements equaled the maximum number that could be displayed in the box.

Aug 12 2003 (Maintenance release 5.2.3)

o   Bug fixed: the scroll bars did not work when the window was smaller
    than the canvas.

o   Bug fixed: memory violations occurred with some combinations of fonts
    and font sizes.

o   Bug fixed: the DUPLICATE statement produced incorrect filenames for
    FoxPro Full-ISAM files if a trailing "!" was used.

Jul 21 2003 (Maintenance release 5.2.2)

o   A new intrinsic function, CALLSTAT$(), has been implemented to return
    a string describing the program position at a specified level in the
    procedure stack.  This function would typically be used to generate
    information for an error log.  The procedure stack includes all function,
    procedure, Call-Subprogram, and SWAP levels.  The level type ("Swap",
    "SubPgm", "ExtSub", "ExtFunc", "IntSub", "IntFunc", or "") is returned
    in a function argument.  The current position is level 0, the caller is
    level 1, and so on.  An error 38 is generated if a non-existent level
    is specified.

    BASIC syntax:

        CallStat$(Level, LevelType$)

    Example:

        Print "Caller position is ";CallStat$(1,Type$)
        Print "Caller type is ";Type$

o   Behavior change: copy/paste operations now supply spaces between
    pasted characters when necessary.

o   Bug fixed: the bridge driver could not insert records in a MySQL table if
    a key contained a DECIMAL(n,0) column.

o   Bug fixed: the makehuge utility could not convert files that used key 
    translation.

o   Bug fixed: CALL DATE() did not properly convert six character dates to
    eight character dates.

o   Bug fixed: the socket driver did not work if certain third-party network
    driver extensions were installed on the system.

o   Bug fixed: some rare situations would cause the main window to freeze.

o   Bug fixed: input did not work with bidirectional auxiliary devices.

o   Bug fixed: the edit menu was sometimes printed as part of a print 
    screen operation.

o   Bug fixed: the FoxPro Full-ISAM driver "dataext" option created files with
    duplicated extensions ("file.ext.ext").

o   Bug fixed: the DXTESTIN, DXTESTOUT, and DXTESTCOPY environment variables
    could not be set via CALL ENV() and used with the dynamicXport CALLs.

May 14 2003 (Maintenance release 5.2.1)

o   A new printer type, "Bidirectional Device", is now supported as an
    auxiliary printer in the "Preferences->Aux Printer" dialog.  When
    enabled, this printer type allows both writing to and reading from a 
    device such as a serial port.

o   The raw file driver now supports a CRTOCRLF open option to append
    a line feed character when writing carriage return characters.  This
    option is also available for the auxiliary printer and can be enabled
    in "Preferences->Aux Printer->Options".

o   The "TCP Listen Socket" driver has been enhanced to accept a new OPEN
    option.  The new "REUSE" option enables the driver to open a socket
    with a port number that is already in use.  This option is needed to
    support certain network protocols and to avoid error 76 ("File or 
    device is open elsewhere") when re-opening a previously used TCP
    port number.  Example:

        Open #1,"(reuse):9631" As "TCP Listen Socket"

o   The "MySQL SQL" and "MySQL Full-ISAM" drivers have been enhanced to
    accept a "PORT=<number>" option in the OPEN statement or in the
    DL4MYSQL/DL4MYSQLISAM runtime parameters.  This option makes it 
    possible to use MySQL servers with non-default port numbers.

o   A new intrinsic CALL, IMSPACK(), has been implemented to provide
    compatibility with CALL $PACK in IMS BASIC.  The syntax of CALL 
    IMSPACK() is:

            Call IMSPack(Mode, Src$, Dest$)
            Call IMSPack(Mode, Dest$, Src$)

    where "Mode" equals zero packs characters from "Src$" into "Dest$"
    and a non-zero "Mode" unpacks characters from "Src$" into "Dest$".
    The packing algorithm uses a radix 50 style mechanism.

o   A new intrinsic CALL, TRANSLATE(), has been added to translate strings to
    or from binary strings according to a specified character set.  The syntax
    and arguments of CALL TRANSLATE() are:

            Call Translate(DestCnt,Dest$,SrcCnt,Src?,CharSet$)
            Call Translate(DestCnt,Dest?,SrcCnt,Src$,CharSet$)

            DestCnt  - receives the number of characters translated into the
                       destination.
            Dest$    - destination string that receives the characters
                       translated from Src?.
            Dest?    - destination binary string that receives the characters
                       translated from Src$.
            SrcCnt   - receives the number of characters translated from the 
                       source.
            Src$     - source string of characters to be translated. String
                       terminator characters are copied as data and the source
                       size is controlled by the total size of the variable
                       and any double subscripting.
            Src?     - source binary string of bytes to be translated. The
                       source size is controlled by the total size of the 
                       variable and any double subscripting.
            CharSet$ - character set name such as "ASCII", "ANSI", or "UTF-8".

    If a character cannot be translated, translation will stop.  Translation
    errors can be detected by comparing the returned source translation count
    to the source size.

o   A new option, "P", has been added to the "TERM" utility to page long
    listings of active ports.  The command "term all mp" would list all
    active ports in screen sized pages.

o   A new option "ADD" has been implemented in the "PGMCACHE" utility
    to manual add permanent entries to the program cache.  The command
    "pgmcache add filename" would add the program or library "filename"
    to the program cache.  The file would remain in the cache until the
    cache itself was deleted or the system was restarted.

o   A new option, "uselust", has been added to the DL4LUST runtime parameter
    to import a search path from the "LUST" environment variable.  The
    imported search path is placed after any entries in DL4LUST.

o   The SCOPE BASIC mode LIST command now supports a "-c" option to disable
    paging of the listing.

o   A new option, "/t description-string", has been added to dl4servr.exe 
    to configure a descriptive string when installing a dl4servr service.

o   Behavior change: flicker is reduced, under some conditions, when
    adding text to a text or edit box.

o   Bug fixed: the display window was sometimes displayed in an incorrect
    position in the base window after the window had been maximized and
    the 'NR'/'WD' mnemonics had been used.

o   Bug fixed: when an indexed contiguous file was opened in read-only mode
    (ROPEN), recent changes to the index were sometimes ignored.

o   Bug fixed: the CHARSET and NUMMAP options could not be used when building
    a formatted file.

Apr  7 2003 (Release 5.2)

o   Two new GUI mnemonics, 'WCSETCOLOR' and 'WCRESETCOLOR', have been defined 
    to set the text and background colors in newly created GUI elements.  The
    'WCSETCOLOR' mnemonic copies the current window foreground and background
    colors.  Alternatively, the 'fg bg WCSETCOLOR' mnemonic uses two numeric 
    parameters, the text and background colors.  The 'WCRESETCOLOR' mnemonic 
    restores the standard system colors.  The 'WCSETCOLOR' and 'WCRESETCOLOR'
    mnemonics can be printed directly to a GUI element to immediately change 
    the text and background colors for that GUI element.

o   A new GUI mnemonic, 'WCMARKCOLOR', has been defined to set the text and 
    background colors for items that have been selected by the user in GUI
    list boxes ('WCLIST', 'WCEDITLIST', ...).  The colors are also used for
    items selected by the 'WCMARK mnemonic.  If the 'WCMARKCOLOR' mnemonic
    is printed to a window, all GUI list elements subsequently created in 
    that window will use the specified colors.  The 'WCMARKCOLOR' mnemonic
    can be printed to a GUI element box to set or change selection colors
    in only that GUI element.  The 'WCMARKCOLOR' mnemonic has three formats:

        'WCMARKCOLOR'       -  use the current window text and background 
                               colors
        'fg WCMARKCOLOR'    -  use "fg" as the text color and the current
                               window background color
        'fg,bg WCMARKCOLOR' -  use "fg" as the text color and "bg" as the
                               background color.

    The color values "fg" and "bg" are numbers between -6 and 2^24 as used
    in the 'FONTCOLOR' and 'BACKCOLOR' mnemonics.  The 'WCRESETCOLOR'
    mnemonic can be used to restore the standard selection colors.  As
    with all other GUI mnemonics, this mnemonic can only be used with
    dL4Term or in dL4 for Windows.

o   Color can now be controlled on a character by character basis within
    the list boxes of 'WCLIST', 'WCEDITLIST', 'WCDROPLIST', and 'WCEDITDROP'
    GUI elements.  The text and background colors are set using the normal
    'FONTCOLOR' and 'BACKCOLOR' mnemonics.

o   Four new standard color numbers have been defined for use with all
    color mnemonics such as 'FONTCOLOR'.  These negative colors numbers are
    defined as follows:

        -3      System standard window text color
        -4      System standard window background color
        -5      System standard highlighted text color
        -6      System standard highlighted text background color

o   A new mnemonic, 'n WCASKCOLOR', has been implemented to display the
    standard window color selection dialog and return the color selected,
    if any, by the user.  The mnemonic requires a single numeric parameter
    which is the default RGB color for the dialog.  The dialog returns the
    selected color as a decimal input string followed by a carriage return.
    If no color is selected, a null string will be returned followed by a 
    carriage return.

o   Double clicking on edit box elements such as WCSTRING or WCTEXT can now
    be detected by using the 'WCACTION' mnemonic to set the double click
    action string as action number 2.  Example:

        PRINT PCHR$(10,2,'F40');'WCACTION';

o   Window contents can now be printed to a user selected printer by sending
    a print screen mnemonic ('PS') to a window or by the user selecting the
    "Edit->Print Window" menu.

o   The main window can now be maximized to occupy the entire screen.  The
    new "Preferences->Frame" dialog configures the pattern and colors used
    to fill the area outside the display window.

o   Double clicking on list box elements or buttons can now be detected
    by using the 'WCACTION' mnemonic to set the double click action string
    as action number 2.  Example:

        PRINT PCHR$(10,2,'F40');'WCACTION';

o   A new driver, "MySQL SQL", has been implemented so that applications
    can use SQL statements to issue commands and queries to a MySQL server.
    The driver allows an application to access the full capabilities of
    MySQL including both standard SQL syntax and MySQL specific features.
    Due to MySQL licensing requirements, the driver cannot be used without
    a special SSN product option.  Please contact the Dynamic Concepts Sales
    department for information on obtaining the required SSN.

    The OPEN statement uses a special filename syntax with two formats: 
    "server:database" and "database".  Rather than opening a specific table,
    the OPEN statement creates a connection to a MySQL server and sets the
    default database to be used by SQL statements. If the server name is not
    specified, the system on which the program is running will be used as the
    server (unless a default server is specified in the DL4MYSQL runtime
    parameter, see below).  The OPEN statement also supports four comma
    separated options: "user=name", "password=string", "pswd=string", and 
    "rtrim=boolean".  These options supply server login identification and, in
    the case of "rtrim", control whether character fields are returned space 
    filled (default) or with trailing spaces removed ("rtrim=true").  
    Examples:

    OPEN #1,"mysystem:accounting" AS "MySQL SQL"
    OPEN #5,"(user=bill,pswd=secret)testdb" AS "MySQL SQL"

    The server name and login information can be specified in the 
    environment variable "DL4MYSQL" which supports the comma separated 
    options "server=name", "user=name", "password="name", and "pswd=name".
    Example for a Unix command line shell:

        $DL4MYSQL="server=myserver,user=anonymous"
        $export DL4MYSQL
        $scope

    SQL statements are executed by using SEARCH statements.  Each SEARCH
    statement specifies a channel open to a MySQL server and an SQL
    statement as a character string.  Examples:

        SEARCH #1;"select * from testtable"
        SEARCH #5;"update acctgtbl set balance=123.45 where account=19765"
        SEARCH #5;"drop table testtable"

    If the statement fails, an error will occur.  Syntax errors in SQL
    statements are reported as error 274, "SQL syntax error".

    After an SQL SELECT statement is successfully executed, the number of
    rows in the result set can be determined by using the CHF(channel)
    function.  The result set itself is read by using normal READ and
    READ RECORD statements.  An error 52, "record not found", will be
    reported by any statement attempting to read beyond the end of the
    result set.  Example:

        Search #7;"select account, balance from acctgtbl"
        Print Chf(7);"rows returned by query"
        Do
            Try Read #7;Account,Balance Else Exit Do
            Print "Account =";Account;"    ";Balance =";Balance
        Loop

    Note: the result set of the current SQL SELECT statement is copied into 
    memory by the dL4 SEARCH statement.  SELECT statements should be written 
    so as to limit the size of the result set to a reasonable value.  An SQL
    LIMIT clause can be used in the SQL SELECT statement to restrict the 
    maximum size of the set.
    
    The MAP RECORD statement can be used to map structure variable members
    according to their item names to the columns returned by a query.  In
    the following example, the SQL select statement returns a two column
    result "account, balance" which is mapped into a structure variable
    that uses the opposite ordering:

        Def Struct RSET
            Member 3%,Balance : Item "balance"
            Member 3%,Acct : Item "account"
        End Def
        Dim R. As RSET
        Search #7;"Select account, balance from acctgtbl"
        Print Chf(7);"rows returned by query"
        Map Record #7 As RSET
        Do
            Try Read Record #7;R. Else Exit Do
            Print "Account =";R.Acct;"    ";Balance =";R.Balance
        Loop

    NULL values in numeric, date, or character columns are converted to
    special values when they are read.  When adding new rows or modifying
    existing rows, NULL values can be written by using the same special
    values.  In this version of dL4, the special values are -1E62 for 
    numeric values, "January 1, 0001" for date values, and "\xffff\" for 
    strings.  Programs should not test for or set these values directly.
    Instead, new intrinsic functions have been provided to test for NULL
    values and to set NULL values.  The intrinsic function IsSQLNull()
    returns 1 when its argument is a NULL value and 0 for all other values.
    The intrinsic functions SQLNull(), SQLNull#(), and SQLNull$() return
    the special NULL values for numbers, dates, and strings.  NULL values
    cannot be read into or written from integer numeric variables or 1% date
    variables.  NULL values are not supported for binary variables ("B?").

    Three new intrinsic functions, SQLV$(), SQLN$(), and SQLNV$() are
    provided to make it easier to construct SQL statements.  The SQLV$()
    function takes one or more arguments of any non-array type and returns
    a string containing the argument values encoded for use by an SQL
    driver.  The SQL driver detects such encoded values in the SEARCH
    statement string and formats the values as required by the SQL server.
    This formatting guarantees proper quoting of character string values and
    places commas between each value.  If the argument is a structure 
    variable, each member of structure is encoded.  The SQLN$() function
    takes a single structure variable argument and returns a string 
    containing the member item names encoded for the SQL driver with commas
    separating each name.  The SQLNV$() function takes a single structure
    variable argument and returns a string containing the member names and
    values encoded for the SQL driver with equals signs ("=") and commas.
    Examples:

        Search #1;"Insert test (count,label) Values ("+SQLV$(C,L$)+")"
        Search #1;"Insert test ("+SQLN$(R.)+") Values ("+SQLV$(R.)+")"
        Search #1;"Update test Set "+SQLNV$(R.)+" where count=19"

o   A new driver, "MySQL Full-ISAM", has been implemented to support
    Full-ISAM and Bridge access to MySQL database tables.  Due to MySQL 
    licensing requirements, this driver cannot be used without a special 
    SSN product option.  Please contact the Dynamic Concepts Sales department 
    for information on obtaining the required SSN.

    The MySQL driver implements the standard Full-ISAM driver interface with 
    the following modifications:

        1. The InnoDB table type must be used in order to support
           record locking.  Other table types may be usable, but they
           will not support record locking. 

        2. A table must have at least one unique index in order to 
           support reading or writing.  A table without a unique index
           can be opened only to extract table information or to add
           indexes.

        3. The OPEN statement uses a special filename syntax with the 
           two formats: "server:database.table:" and "database.table".  If
           the server name is not specified, the system on which the program
           is running will be used as the server.  The OPEN statement also 
           supports four comma separated options: "user=name", 
           "password=string", "pswd=string", and "rtrim=boolean".  These 
           options supply server login identification and, in the case of 
           "rtrim", control whether character fields are returned space 
           filled (default) or with trailing spaces removed ("rtrim=true").
           Examples:

            OPEN #1,"mysystem:accounting.customers" AS "MySQL Full-ISAM"
            OPEN #5,"(user=bill,pswd=secret)test.info" AS "MySQL Full-ISAM"

        4. The KILL statement uses the same filename syntax as the OPEN
           statement and supports the "user=name", "password=string", and
           "pswd=string" options.  Example:

            KILL "(user=bill,pswd=secret)test.info" AS "MySQL Full-ISAM"
    
    The server name and login information can be specified in the 
    environment variable "DL4MYSQLISAM" which supports the comma separated 
    options "server=name", "user=name", "password="name", and "pswd=name".
    Example for a Unix command line shell:

        $DL4MYSQLISAM="server=myserver,user=anonymous"
        $export DL4MYSQLISAM
        $scope

    The MySQL driver has been tested with MySQL versions 3.23.42 through
    3.23.53.  InnoDB tables are an optional feature of MySQL and require
    installing both an InnoDB capable version of MySQL and setting optional
    configuration parameters.  Please see the MySQL documentation for
    information on installing and configuring a MySQL server.

o   The new MySQL Full-ISAM driver has an open option, "nulls=true", to 
    support read and writing NULL values to table columns.  When a table
    is opened with the "nulls=true" option, NULL values in numeric, date,
    or character columns are converted to special values when they are read.
    When adding new records or modifying existing records, NULL values can
    be written by writing the same special values.  Currently, the special
    values are -1E62 for numeric values, "January 1, 0001" for date values,
    and "\xffff\" for strings.  Programs should not test for or set these
    values directly.  Instead, new intrinsic functions have been provided
    to test for NULL values and to set NULL values.  The intrinsic function
    IsSQLNull() returns 1 when its argument is a NULL value and 0 for all
    other values.  The intrinsic functions SQLNull(), SQLNull#(), and 
    SQLNull$() return special NULL values for numbers, dates, and strings.
    NULL values cannot be read into or written from integer numeric variables
    or 1% date variables.  NULL values are not supported for binary variables
    ("B?").  NULL values can be used in keys and index columns, but it is not
    recommended.

    Example:

        Declare Intrinsic Function IsSQLNull,SQLNull,SQLNull#,SQLNull$
        Open #1,"(nulls=true)server:database.table" As "MySQL Full-ISAM"
        ! Display table with possible NULL values
        Do
            Try Read Record #1;R. Else Exit Do
            Print "Name = ";R.CustomerName$
            Print "Appointment = ";
            If IsSQLNull(R.AppointmentDate#)
                Print "none"
            Else
                Print R.AppointmentDate#
            End If
        Loop
        ! Add new record with NULL value
        R.CustomerName$ = "John Quinn"
        R.AppointmentDate# = SQLNull#()
        Add Record #1;R.

o   The MySQL Full-ISAM driver supports the special MySQL date value of 
    0000-00-00.  Such date values can now be read into date variables and 
    will set the date variable to be "Not-A-Date".  The special value of 
    0000-00-00 can be written by writing a date value of "Not-A-Date".  A
    date variable can be set to "Not-A-Date" by the CLEAR statement 
    ("CLEAR D#").  An error 15 will occur if a "Not-A-Date" value is used
    in a date function or date expression.

o   The MySQL Full-ISAM driver reports character fields in indexes as
    case insensitive when a GET statement retrieves index information 
    (if the MySQL server is using the standard case insensitive character
    set).  When creating a table, the driver will accept index field
    definitions that are either case sensitive or case insensitive.  The
    actual case sensitivity is always controlled by the MySQL server.

o   The KILL statement now supports an options field "(...)" before each
    filename to supply driver options.  Example:

        KILL "(user=fred,password=secret)mytable" AS "MySQL Full-ISAM"

    The SCOPE/BASIC KILL command does not support deleting MySQL tables.

o   The Full-ISAM Bridge driver has been extended to support Full-ISAM
    date fields and translation of field types.  A date field is used
    by specifying a translation function in the field definition that
    defines how to translate a date value to or from a character or
    numeric field.  Translation functions also support converting
    Full-ISAM numeric fields to Indexed-Contiguous character key fields.
    Additional functions support subscripted character fields for key
    fields or case-insensitive key fields.  The translation functions
    are:

        DTOC(mask)  Convert the Full-ISAM date field to a character string
                    in the record image using "mask".  All dates use local
                    date/time.  When the DTOC() function is used in an 
                    index definition, the "mask" must define a sortable
                    date.  For example, "YYMMDD" is a legal index mask, but
                    "MMDDYY" is not because it would not sort correctly.
                    "mask" is a quoted string in which the following 
                    substrings have special meaning:

                      YYYY  Four digit year
                      YY    Two digit year with the century set so
                            it is within 50 years of the current
                            date.
                      AA    Two digit year in which years after 1999
                            are specified as "A0" through "E9".
                      MM    Zero filled month, 1 - 12
                      DD    Zero filled day of month, 1 - 31
                      DDD   Zero filled day of year, 1 - 366
                      DDDDD Zero filled day relative to base year 
                            1968.  January 1, 1968 is "00001".
                            Six or more "D"s can be also be used.
                      HH    Zero filled hour of day
                      MM    Zero filled minute of hour
                      SS    Zero filled second of minute

        DTON(mask)  Convert Full-ISAM date field to a decimal number
                    in the record image using "mask".  All dates
                    use local date/time.  "mask" is a quoted string
                    defining the decimal digits of the number.  The 
                    following substrings in the mask have special meanings:

                      YYYY  Four digit year
                      YY    Two digit year with the century set so
                            it is within 50 years of the current
                            date.
                      MM    Month, 1 - 12
                      DD    Day of month, 1 - 31
                      DDD   Day of year, 1 - 366 or 0 - 365
                      DDDDD Day relative to base year 1968.
                            January 1, 1968 is 1.  Six or more
                            "D"s can be also be used.
                      HH    Hour of day
                      MM    Minute of hour
                      SS    Second of minute

        NTOC(mask)  Convert Full-ISAM numeric field to a character
                    string according to the USING mask "mask".  The
                    mask must use a period (".") for any decimal point
                    point and comma as any grouping separator.

        NTVNTOC(mask) Convert Full-ISAM numeric field to a character
                    string according to the USING mask "mask" and using
                    locale information to determine the decimal point
                    character.  The mask must use a period (".") for any  
                    decimal point and comma as any grouping separator.

        LEFT(len)   Use the first "len" characters of the field.  This
                    function can only be used in index definitions and
                    the field must also be used in the "[Record]" section.

        UCASE(len)  Use the first "len" characters of the field converted
                    to uppercase.  This function can only be used in index
                    definitions and the field must also be used in the
                    "[Record]" section.

        LCASE(len)  Use the first "len" characters of the field converted
                    to lowercase.  This function can only be used in index
                    definitions and the field must also be used in the
                    "[Record]" section.
 
    Example:

        Field=LASTPAYMNT,114,2%,DTON("YYDDD")

o   The Full-ISAM Bridge driver profile has been extended to support two
    new conversion functions, IFNULL and IFERR, that convert SQL NULL or
    invalid values to and from the values needed in the emulated indexed
    contiguous file record.  The IFNULL function takes a single string
    argument which defines a string or number that is stored into the
    converted field whenever a NULL is read.  When a record is written,
    the same value will be converted to a NULL.  Examples:

        Field=COUNT,28,4%,,,IFNULL("-1")
        Field=ACCTID,16,12,,,NTOC("-------#.##"),IFNULL("N/A"),Strip

    In order to read or write NULLs, the SQL driver options in the bridge
    profile must be set to enable reading and writing nulls (for the
    MySQL Full-ISAM driver, see the "nulls=true" option described above).

    The IFERR function is similar to the IFNULL function, but it is applied
    to invalid numeric or date values.  In this release of dL4, the only
    possible invalid value is the special MySQL date value of "0000-00-00".
    If no IFERR function is specified, an invalid value results in an error.
    In the following example, MySQL "0000-00-00" dates are converted to -1
    while actual dates are converted to decimal numbers in the form 
    "YYYYMMDD":
        
        Field=DATE1N,60,3%,,,DTON("YYYYMMDD"),IFERR("-1")

    In this example, "0000-00-00" dates in a key part are converted to the 
    string "00000000" while actual dates are converted to strings in the 
    format "YYYYMMDD":

        KeyPart=DATE1,0,8,"","0123",DTOC("YYYYMMDD"),IFERR("00000000")

    Both IFNULL and IFERR functions can be used in the same field or key
    part definition.

o   The Full-ISAM Bridge driver profile has been extended to support filler
    fields.  A filler field is any record field with a field name beginning
    with an asterisk.  Filler fields are not read from the Full-ISAM file,
    but they are initialized to the fill character or zeroed if the fill
    character is not defined.  The filler name is treated as a comment.
    Example:

        Field=*fillerwithnulls*,54,5
        Field=*fillerwithblanks*,59,5,," "

o   A new option has been added to the Full-ISAM Bridge driver profile to
    disable use of temporary record values when inserting or modifying
    records.  The temporary values are normally used to reserve key values
    after SEARCH mode 4 insert statements and thus prevent other programs
    from inserting the same key.  If the new "ProtectKeys=False" option is
    specified in the initial section of a bridge profile, SEARCH mode 4 
    statements will check for the current existence of a key value, but the
    Full-ISAM file will not be modified until all keys have been inserted
    for the record.  This option improves Bridge driver performance and 
    allows use of foreign key constraints in SQL tables.  If the option is
    used, duplicate key errors may occur after a successful SEARCH mode 4 
    insertion of the key.  Bridge profile example:

        [FullISAMBridge]
        File=filename
        OpenAs=FoxPro Full-ISAM
        ProtectKeys=False

o   The Full-ISAM Bridge driver support of SEARCH mode 6 (search less than)
    has been improved.  Statements such as 
    
        SEARCH #Chan,6,IdxNum;"{",R,S

    can now be used on indexes that use date or numeric conversion functions.
    The driver will detect that the key value is greater than any possible
    key value and will search for the last key in the specified index.  In
    the previous release, the key value "{" would have caused an error in
    the conversion function because "{" is an illegal value.

o   The numeric precision syntax in Full-ISAM Bridge profile files has been 
    extended to specify the number of decimal places needed.  The new,
    optional format is "p.d%" where "p" is the dL4 numeric precision (1-4)
    and "d" is the number of decimal places.  Thus "3.2%" would specify a 10
    digit floating point format with two decimal places.  The decimal place 
    information is used by the tools/ic2fi utility to create Full-ISAM 
    files when the Full-ISAM driver supports only fixed point, rather than 
    floating point, numbers.  Example:

        Field=COST,80,3.2%

o   The tools/ictofi utility program has been replaced with a new utility,
    tools/ic2fi, that offers similar, but greatly improved, features to
    convert from Indexed-Contiguous files to Full-ISAM files.  The new
    utility can also be CALLed as a subprogram to perform automated or
    repetitive conversion of Indexed-Contiguous files.  The ic2fi utility
    is documented in the dL4 5.2 Product Training manual which can be 
    downloaded from www.dynamic.com or ftp.dynamic.com.

o   The tools/buildfi utility program has been enhanced to allow selection
    of the Full-ISAM type (FoxPro or SQL) and to improve error handling. 

o   A new driver, "Socket Text", has been added to provide text line oriented
    I/O to TCP sockets.  Driver arguments and usage is identical to the
    raw socket driver except that READ and INPUT statements will read data
    in lines terminated by carriage return and/or line feed.

o   A new open option, "SYNC", has been added to the Portable Contiguous,
    Portable Indexed-Contiguous, and text file drivers.  This option forces
    the operating system to write data immediately to disk.  Example:

        Open #1,"(sync)datafile"

    This option will severely impact file throughput and should only be used
    in special circumstances.

o   A new option, "buffer=true", has been added to the text and pipe drivers 
    to improve performance.  For compatibility with UniBasic, these drivers 
    normally output data immediately after a PRINT or WRITE statement.  The
    "buffer=true" option instructs the drivers to delay output until an
    internal buffer is filled or the driver is closed.  The option can be
    used in an OPEN statement or in a printer script "# dl4opts=" line.
    Examples:

        BUILD #1,+"(buffer=true)textfile!"

        # dl4opts=buffer=true

o   Portable Indexed-Contiguous and Portable Contiguous file performance has 
    been improved for files opened in exclusive mode.  Scratch files should
    be opened using the EOPEN statement to obtain this increased performance.

o   It is now possible to output binary zero characters to a terminal or
    serial port when in binary output mode.  The MAT WRITE statement will 
    output all characters including binary zero characters in a string
    variable.  Subscripts can be used to limit output to a selected range
    within a string.

o   A new BASIC command, XBREAK, has been implemented to allow the user
    to set breakpoints outside of the current program.  The command uses
    the same syntax as the existing BREAK command, but will apply the
    breakpoint to both the current program and to any program entered via
    CHAIN, CALL subprogram, or SWAP statements.  Example:

        XBREAK 1000

    XBREAK breakpoints can be deleted or listed with the normal NOBREAK
    or STATUS BREAKPOINT commands.

o   Enhancement: quoted values can now be used in driver options.  For
    example, a quoted value might be used to provide a subject line using
    parentheses to the email driver:

        Open #1,"(From=someone,Subject=''(test)'')somebody" As "Email"

o   Behavior change: the DL4PORTDUMP and DL4STOPDUMP runtime parameters
    have been enhanced to support an optional file protection ("<xxx>")
    specification.

o   Behavior change: the LOADSAVE utility now prints a simple usage
    message if the "-h" option is used.  A full usage message can be
    displayed by using the "-H" option.

o   The PORT statement has been extended with a new mode, 6, to determine
    whether a port is blocked by a record lock and which other port is 
    holding the needed record lock.  The statement

        PORT portnum,6,status,isblocked,blockingport 

    sets the variable "isblocked" to one if the dL4 program running on
    port "portnum" has been waiting for over 20 seconds for a record lock
    and to zero if it is not blocked.  If the port is blocked by a record
    lock, the variable "blockingport" is set to the port number of the
    program that currently has the record locked or to -1 if the blocking
    port number cannot be determined.  PORT mode 6 is supported for record
    locks on formatted, contiguous, and indexed contiguous files.

o   The PORT statement has been extended with a new mode, 7, to return
    the user name and work station name of a specified port.  The statement

        PORT portnum,7,status,userid$,station$

    queries port "portnum" and returns in "userid$" the user name, if any,
    associated with the port and returns in "station$" the terminal name,
    if any, used by the port.

o   The TERM utility has been extended to display the user name and work
    station name associated with each port.  If the program running on a
    port is currently blocked by a record lock wait, its state will be
    displayed as "Blkd" and the port number that is currently holding the
    locked record will be displayed in parentheses.  The "Blkd" state
    information is supported only for record locks on formatted, contiguous,
    and indexed contiguous files.

o   The intrinsic CALLs GetGlobals() and SetGlobals() have been extended to
    support separate named sets of global values.  If the first parameter
    of CALL GetGlobals() or CALL SetGlobals() is a string, it will be 
    treated as a global set name and the get or set operations will be 
    applied using that global set.  The default set is named "".  A
    global set is created by the first CALL SetGlobals() using the set
    name.  Examples:
    
        Call SetGlobals$("mylib",0,N$,A)    ! set values in "mylib"
        Call GetGlobals$("mylib",0,N$,A)    ! get values from "mylib"
        Call SetGlobals("mylib")            ! delete the set "mylib"

o   The intrinsic CALL table in the dL4 development kit, userproc.c, now
    supports the option USERPROCOPT_CVTSTRINGS to automatically string 
    parameters to and from binary ITEMS using the UniBasic IRIS character
    set.  This option can be used to simplify conversion of CALLs from
    UniBasic at the cost of some additional overhead.  See the files
    usercall/userproc.h and usercall/userproc.c in the development kit
    for details.

o   Bug fixed: the SPAWN statement sometimes failed when a program path
    included embedded spaces.

o   Bug fixed: printing to the auxiliary printer to the "Windows Terminal
    Printer" driver sometimes produced garbled output.

o   Bug fixed: when the main window was taller than the display window, the
    frame around the display window was sometimes displayed incorrectly.

o   Bug fixed: searching or reading backwards through an index in the MySQL
    Full-ISAM driver skipped records that had keys beginning with NULL values.

o   Bug fixed: the statement "ENTER ..." always generated an illegal word
    error.

o   Bug fixed: storing a value into a "%2" (32-bit integer) structure member
    caused alignment violations on some systems (such as Sun SPARC systems).

o   Bug fixed: the POS() function did not work correctly when a negative step
    value was used with the "IS" or "EXCEPT" relational operators.

o   Bug fixed: OPTION DIALECT IRIS1/BITS1/IMS did not allow values to be
    returned in subscripted strings parameters of intrinsic CALLs or functions.

o   Beta bug fixed: memory violations occurred if auto-increment columns or
    null values were used in MySQL tables.

o   Beta bug fixed: MySQL indexes were not recognized as case-insensitive.

o   Bug fixed: when converting source files, functions in CALL arguments
    were sometimes converted to variables.

o   Bug fixed: binary output did not work on Windows 95/98/ME systems if 
    the printer used direct printing rather than spooling.

o   Bug fixed: if a printer script used the "TRANSLATE=" option and did not
    use the "PATH=" option, a "File not found" error sometimes caused a
    memory violation.

o   Beta bug fixed: colors were set incorrectly by 'FONTCOLOR' or 'BACKCOLOR'
    when used in a GUI list box such as 'WCLIST'.

o   Beta bug fixed: the final item in a GUI list box (such as 'WCLIST') was
    sometimes displayed with an incorrect value whenever the list box items
    were initialized.

o   Beta bug fixed: hidden fields did not work in GUI list boxes such as
    'WCLIST'.

o   Bug fixed: opening the pipe driver with an AS clause sometimes resulted
    in a syntax error. 

o   Bug fixed: a BUILD statement with an AS clause using "" or "AutoSelect",
    caused a memory violation.

o   Bug fixed: POS() expressions without relational operators were not
    treated as syntax errors.

o   Bug fixed: when using DynamicXport, HTML files with long lines (499
    characters or more) did not work correctly.

o   Bug fixed: when using DynamicXport, "dl4l()" references did not work
    correctly if the list variable was empty.

o   Bug fixed: if a WCGROUP with radio buttons was enclosed within another
    WCGROUP, the first button would be placed in a separate radio group
    apart from the other radio buttons.

Jan  6 2003 (Maintenance Release 5.1.5)

o   A new environment variable, DXTESTCOPY, has been implemented for use
    in debugging DynamicXport applications.  When the DXTESTOUT environment
    variable is defined, a "CALL DXCLOSE()" statement outputs the current
    DynamicXport output table to the text file selected by DXTESTOUT.  The
    DXTESTCOPY value, if defined, selects which, if any, values from the
    DynamicXport input table should be copied to that text file.  If a
    selected value exists in both the input and output tables, only the
    output table value will be written to the text file.  DXTESTCOPY is a
    comma separated list of value names or value name prefixes as in the
    optional CALL DXCOPY() or CALL DXMOVE() selection arrays.  Examples:

        To copy all input table variables with names beginning with "U_"

        DXTESTCOPY=U_
        export DXTESTCOPY

        To copy all input table variables

        DXTESTCOPY=+
        export DXTESTCOPY

o   Bug fixed: a memory violation sometimes occurred after an error 15,
    "arithmetic overflow", was detected in the argument list of a user
    defined function or procedure.

o   Bug fixed: if a program executed a SWAP statement using CHAIN WRITE
    statements, then any subsequent CHAIN or SWAP statement in the parent
    program would not pass common ("COM 3%,N") variables.

o   Bug fixed: when converting programs using the CONVERT command or the
    LOADSAVE "-c" option, intrinsic functions in CALL parameters were
    sometimes converted to array variable references.

o   Bug fixed: POS() expressions without relational operators were not
    treated as syntax errors.

o   Bug fixed: if a WCGROUP with radio buttons was enclosed within another
    WCGROUP, the first button would be placed in a separate radio group
    apart from the other radio buttons.

o   Bug fixed: binary output did not work on Windows 95/98/ME systems if 
    the printer used direct printing rather than spooling.

o   Bug fixed: if a printer script used the "TRANSLATE=" option and did not
    use the "PATH=" option, a "File not found" error sometimes caused a
    memory violation.

o   Bug fixed: opening the pipe driver with an AS clause sometimes resulted
    in a syntax error. 

o   Bug fixed: a BUILD statement with an AS clause using "" or "AutoSelect",
    caused a memory violation.

o   Bug fixed: when using DynamicXport, HTML files with long lines (499
    characters or more) did not work correctly.

o   Bug fixed: when using DynamicXport, "dl4l()" references did not work
    correctly if the list variable was empty.

o   Bug fixed: the 'EPW' mnemonic could not be defined in terminal definition
    files.

o   Bug fixed: in SCOPEC.EXE and RUNC.EXE, an error 5 ("Illegal character")
    occurred whenever the 'BCTRACK' ("Begin Cursor Tracking") mnemonic was 
    used and a window was open or the window system was active.

Sep 27 2002 (Maintenance Release 5.1.4)

o   The intrinsic CALL FindF() now accepts an optional third argument, a
    string variable, to receive the absolute path of a file if it exists.
    Examples:

        Call FindF(Filename$,Status)
        Call FindF(Filename$,Status,ActualPathFound$)

o   Two new intrinsic functions have been implemented to convert binary
    variables to and from base-64 character strings.  Example:

        Declare Intrinsic Function Base64$, Base64?

        String$ = Base64$(BinaryVariable?)
        Binary? = Base64?(StringVariable$)

o   Bug fixed: if a key in a SEARCH statement was specified with a
    subscripted string variable ("SEARCH #1,3,1;K$[1,10],R,S") and a 
    key was successfully found, the new key value was not returned.

o   Bug fixed: the "mixedcase" option in the LUMAP and DL4LUST runtime
    parameters did not work and caused a syntax error.

o   Bug fixed: using double directory separators ("abc//def") in a path
    sometimes caused the MSC$(8xx) function to return an incorrect path.

Sep  6 2002 (Maintenance Release 5.1.3)

o   Bug fixed: the 'CS' mnemonic and the WINDOW CLEAR statement cleared
    GUI menu elements.

Sep  4 2002 (Maintenance Release 5.1.2)

o   A new mnemonic, 'DEFAULTCOLOR', has been defined to set the default
    colors to the current foreground and background colors for the rest
    of the session.

o   Enhancement: up to 128 GUI elements can now be queried at one time
    using one or more WCQUERY mnemonics (previously only 32 elements
    could be queried before reading the results).

o   Bug fixed: 'WCLISTDROP' elements whose drop down boxes extended below
    the bottom of the window could not be deleted by the 'CS' mnemonic.

o   Bug fixed: the DIR utility reported an illegal subscript error when
    it listed a FoxPro Full-ISAM file.

o   Bug fixed: opening the pipe driver with an AS clause sometimes caused
    a file syntax error.

Jul 19 2002 (Maintenance Release 5.1.1)

o   Behavior change: CALL MEMCOPY() now allows copy sizes that exceed the
    size of the destination variable if that variable is an element of a
    larger array or structure variable and the size is within the size of
    the surrounding variable.  For example, it is possible to copy to
    multiple elements of an array starting at a specific subscript.

o   Behavior change: CALL IMSMEMCOPY() now prevents copying beyond the
    limits of the destination variable.  If the destination variable is an
    array element or structure member, the limit is based on the entire
    array or structure variable.  For example, it is possible to copy to
    multiple elements of an array starting at a specific subscript, but an
    attempt to copy beyond the end of the array will cause an error 38.

o   Bug fixed: dL4 5.1 could not be used with dynamicXport.

Jul 10 2002 (Release 5.1)

o   A new runtime parameter, DL4LUST, has been implemented to provide a
    UniBasic LUST-like search path for data files.  Like LIBSTRING and
    other dL4 path lists, DL4LUST is a space separated list of directories.
    If DL4LUST is defined and a file is opened or created with a relative 
    path, dL4 will search each directory in the list and use the first 
    directory in which the file is found as the root directory of the file.
    If the file is being created and the file does not exist in any of the
    directories, then the file will be created using the first directory
    in the list.  If the runtime parameter DL4DEFLU is defined, then the
    search will modified to try each of the directories in DL4LUST first
    without and then with the value of DL4DEFLU appended.

    Example:

        Assume

            DL4LUST is equal to ". /usr/data test"
            DL4DEFLU is equal to "5"
            the current directory is "/home/fred/"

        then the statement
        
            OPEN #1,"file" 
            
        would try to open "file" using the following paths and in the 
        following order:

            ./file
            ./5/file
            /usr/data/file
            /usr/data/5/file
            /home/fred/test/file
            /home/fred/test/5/file
    
    The DL4LUST and LUMAP runtime parameters can both be defined and LUMAP 
    mapping will be used instead of DL4LUST if an LUMAP mapping is found.  
    In choosing between using DL4LUST and LUMAP, the UniBasic compatibility 
    of DL4LUST should be weighed against the higher efficiency of LUMAP.
    In a networked file system environment, using LUMAP will avoid the high
    overhead of multiple directory searches over the network.

o   The LUMAP and DL4LUST runtime parameters can now accept filename
    options to control the legal character set for filenames and paths.  The
    options are specified in parentheses at the beginning of the LUMAP or
    DL4LUST parameter string.  The following options are recognized:
    
        "mixedcase"     - do not convert the filename to lowercase (Unix) or
                          uppercase (Windows)

        "unibasic"      - limit the filename to letters, digits, "-", and
                          ".".  Ignore any character at and following an
                          illegal character.

        "pfchar=x"      - limit the filename as described for "unibasic"
                          but convert the first "@" character to "x" and
                          then ignore any following characters.

    If both LUMAP and DL4LUST are used, only one parameter string to specify 
    the options or both strings must specify the same options.  These options
    have no effect on absolute paths which are always used as given.

o   The LUMAP and DL4LUST runtime parameters can now accept a "case=<O><U>"
    option to control case conversion in relative paths.  By default, dL4 
    for Unix converts relative paths to lowercase Unix filenames when
    creating or opening files.  Similarly, it converts lowercase Unix 
    filenames to uppercase when CHF$(8xx) or other functions are used to 
    retrieve the filename open on a channel.  The "case=" option is specified 
    in parentheses at the beginning of the LUMAP or DL4LUST parameter string.
    The values "<O>" and "<U>" in the "case=" argument must be replaced by 
    the desired operating system ("<O>") and user ("<U>") case conversion:

        "l"    -  Convert to lowercase
        "u"    -  Convert to uppercase
        "a"    -  Leave case unchanged

    For example, an LUMAP value of "(case=la)" would perform the normal
    conversion of relative filenames to lowercase when creating or opening
    files, but it would always return the actual case of filenames in the
    CHF$(8xx) function.

o   The LUMAP and DL4LUST runtime parameters now support a "CHARSET=name"
    option to select the file system character set under Unix.  The
    character set name must be either "ASCII", "US-ASCII", "ANSI",
    "ISO 8859-1", or "Windows".  Example:

        LUMAP="(charset=ISO 8859-1)" export LUMAP

    The option can be set with or without setting a path mapping or search 
    list.

o   The UniBasic utilities listed below have been converted to dL4.
    These are essentially the original UniBasic utilities loaded into
    dL4 using conversion profiles.  The user interface and functionality
    are identical to that of the original UniBasic utilities.  

        batch       Execute commands on a phantom port
        bitsdir     List directory contents
        change      Change filename or attributes
        copy        Copy files
        dokey       Access or modify Indexed-Contiguous files
        format      Create Formatted files
        keymaint    Access or modify Indexed-Contiguous files
        libr        List directory contents
        make        Create files
        makecmnd    Generate command files for BATCH or EXEC
        mfdel       Delete files
        port        Display port status or evict ports (the "term" utility
                    is a native dL4 program that offers similar functions 
                    and extended dL4 options)
        scan        Display file information
        who         Display user information

o   The following intrinsic calls have been added for UniBasic compatibility:

        UniBasic CALL               New equivalent dL4 Intrinsic            

        CALL $ATOE                  Call AToE()
        CALL $CKSUM                 Call Cksum()
        CALL $CLU                   Call CLU()
        CALL $DATE                  Call Date()
        CALL $DEVOPEN               Call DevOpen()
        CALL $DEVCLOSE              Call DevClose()
        CALL $DEVREAD               Call DevRead()
        CALL $DEVWRITE              Call DevWrite()
        CALL $DEVPRINT              Call DevPrint()
        CALL $ETOA                  Call EToA()
        CALL $LOCK                  Call Lock()
        CALL $MEMCMP                Call MemCmp()
        CALL $RDFHD (97)            Call Rdfhd()
        CALL $VOLLINK (91)          Call VolLink()
        CALL 1                      Call StrSrch1()
        CALL 5                      Call MemCopy()
        CALL 7                      Call SetEcho()
        CALL 15                     Call PkUnPkDec()
        CALL 18                     Call PkRdx5018()
        CALL 19                     Call UnPkRdx5019()
        CALL 20                     Call PkDec20()
        CALL 21                     Call UnPkDec21()
        CALL 29                     Call EditField()
        CALL 30                     Call CopyStr()
        CALL 40                     Call InitErrMsg()
        CALL 44                     Call StrSrch44()
        CALL 45                     Call PkDec45()
        CALL 46                     Call UnPkDec46()
        CALL 47                     Call Misc47()
        CALL 48                     Call PkRdx5048()
        CALL 49                     Call UnPkRdx5049()
        CALL 53                     Call ASC2EBCDIC()  
        CALL 57                     Call ClearStr()
        CALL 72                     Call Gather()
        CALL 73                     Call Scatter()
        CALL 81                     Call StrSrch81()
        CALL 95                     Call IRISOS95()
        CALL 116                    Call CloseAll()
        CALL 117                    Call AvailBlks()
        CALL 118                    Call NextAvPort()
        CALL 127                    Call FileInfo()

    In order to use these intrinsic CALLs, a DECLARE INTRINSIC SUB statement
    must be used to declare the intrinsic SUB.  A DECLARE statement will be
    added automatically when programs are converted using a conversion
    profile.

o   UniBasic CALL $MONITOR has been added to tools/oldcalls.lib, a dL4 
    library.  This is a partial implementation that does not support
    returning the full list of open channels.  The implementation is
    sufficient to support user status displays and it is used by the
    converted UniBasic PORT utility in the tools/ directory.

o   A new intrinsic function, ErrMsg$(), has been implemented to replace 
    references to the UniBasic ERM() function.  The ErrMsg$() function is
    used with CALL InitErrMsg() to replace the error message facility
    provided by UniBasic ERM() function and CALL 40.  The standard conversion 
    profile will convert ERM() function usage to ErrMsg$() and add the 
    required DECLARE INTRINSIC FUNCTION statement.

o   A new intrinsic function, UBMem(), has been implemented to satisfy 
    references to the UniBasic MEM() function.  Like the UniBasic MEM()
    function, UBMem() always returns zero.  The standard conversion profile
    will convert MEM() function usage to UBMem() and add the required
    DECLARE INTRINSIC FUNCTION statement.

o   The intrinsic CALL BitsNumStr() has been extended to accept string
    variables as well as binary variables as arguments.  This enhancement
    makes the BitsNumStr() compatible with UniBasic CALL 2.

o   A new utility, dl4servr.exe, is now included with dL4 for Windows.  This
    utility installs and implements a service to connect dL4 programs with
    incoming network TCP connections on a specified IP address and port
    number.  This function is similar to that of "inetd" on Unix systems.
    The utility is a command line program with the following command line
    syntax:
    
        dl4servr install servicename address port command options
        dl4servr remove servicename
        dl4servr help

    The format "dl4servr install servicename address port command options" 
    installs the dL4Servr service using "servicename" as the service name,
    listening to the TCP "address" and "port", and running "command" whenever
    a TCP connection is received.  A typical value of "command" would be
    "C:\Progra~1\dl4\runc.exe C:\AppDir\app.dl4" where app.dl4 is a dL4
    program to run with standard input and output assigned to the incoming
    TCP socket connection.  The following options are accepted:

      /d directory      initial current directory used by "command"
      /e envvars        environment variable settings for "command" using
                        the format "name=value" and comma separators
                        between settings
      /u username       user name for the account running the service
      /p password       password for the account running the service

    The current path of dl4servr.exe is used as the installation location.
    The service will be started whenever the system is rebooted or the
    command "net start servicename" is executed.

    The format "dl4servr remove servicename" removes the dl4servr service 
    named "servicename"

    The format "dl4servr help" displays help text

o   The 'n,m WCENABLE' and 'n,m WCDISABLE' mnemonics can now be used to
    enable or disable all GUI elements between "n" and "m" inclusive.

o   A new mnemonic, 'RESETFONT', has been defined to restore the default
    screen or printer font name and size.

o   A horizontal scroll bar is now automatically displayed by WCLIST
    boxes if the list elements are too wide for the list box.

o   The Windows Page Printer driver now tries to match the requested line
    height even when the system printer driver cannot provide the requested
    font height.

o   The Microsoft SQL Server Full-ISAM driver can now be opened with an 
    "AS" clause using the name "MSSQL Full-ISAM" or "SQL Full-ISAM".  The 
    driver name "SQL Full-ISAM" selects the preferred SQL Full-ISAM
    driver which, in a custom configuration, may or may not be the Microsoft 
    SQL Server driver.

o   A new option, "OPTION DEFAULT ARGUMENT CHECKING IS WEAK", has been
    added to support passing array variables to subprograms (CALL by 
    filename) without using the empty bracket notation ('CALL "pgm",A[]').
    This option improves compatibility with IMS BASIC.

o   A new optional setting has been defined for conversion profiles to 
    convert references to undefined user functions ("FNx").  Without this
    option, undefined functions are treated as compile time errors and the
    program cannot be executed until the error is corrected.  When enabled,
    the option adds definitions for each undefined function to the end of 
    the program.  The functions will generate an error 30 if used.  Using 
    the option the following program

          10 Def Fna(x) = x + 5
          20 Print Fna(3) + Fnb(4)

    would be converted to

           1 Declare Function Fnb, Fnc
          10 Def Fna(X) = X + 5
          20 Print Fna(3) + Fnb(4) + Fnc(8)
        1000 ! Dummy functions inserted for referenced, but undefined, functions
        1001 External Function UndefinedFunctionError()
        1002   Error 30
        1003 End Function 0
        1004 Def Fnb(X) = UndefinedFunctionError()
        1005 Def Fnc(X) = UndefinedFunctionError()

    The line numbers used by the inserted lines are always greater than
    any line number used in the program.

    The option is enabled by adding a "ConvertUndefinedFunctions=True"
    line in the conversion profile settings section.  Example:

        [Settings]
        ConvertUndefinedFunctions=True

o   A new intrinsic CALL, IMSMEMCOPY(), has been implemented to provide
    compatibility with CALL 90 in IMS BASIC.  The syntax of CALL IMSMEMCOPY()
    is:
            Call IMSMemCopy(Destination, Source, ByteCount)

    where "Destination" is a variable of any type, "Source" is a variable
    of any type, and "ByteCount" is a numeric variable or expression.  The
    CALL copies "ByteCount" bytes from the "Source" variable to the
    "Destination" Variable.  If both "Destination" and "Source" are string
    variables or arrays, then "ByteCount" characters are copied.  This CALL
    is dangerous and will corrupt memory if "ByteCount" exceeds the size of
    the destination variable.  This is allowed so that "Destination" variable
    can be a subscripted array element identifying the start of a copy range.

o   A new intrinsic CALL, CHSTAT(), has been implemented to return current
    SWAP level information.  The BASIC syntax of the CALL has several
    possible parameter lists:

            Call ChStat(SwapLevel, ParentLineNum, ParentName$)
            Call ChStat(SwapLevel, ParentName$, ParentLineNum)
            Call ChStat(SwapLevel, ParentName$)
            Call ChStat(ParentName$, SwapLevel, ParentLineNum)
            Call ChStat(ParentName$, SwapLevel)
            Call ChStat(ParentName$)
            Call ChStat(SwapLevel, ParentLineNum)
            Call ChStat(SwapLevel)

    where "SwapLevel" receives the current SWAP level number (zero if
    there are no SWAPs in progress), "ParentLineNum" receives the line 
    number of the SWAP statement in the parent program (zero if none), and
    "ParentName$" receives the name of the parent program ("" if none). 

o   A new intrinsic CALL, CALLSTAT(), has been implemented to return current
    CALL-by-filename level information.  The BASIC syntax of the CALL has 
    several possible parameter lists:

            Call CallStat(CallLevel, ParentLineNum, ParentName$)
            Call CallStat(CallLevel, ParentName$, ParentLineNum)
            Call CallStat(CallLevel, ParentName$)
            Call CallStat(ParentName$, CallLevel, ParentLineNum)
            Call CallStat(ParentName$, CallLevel)
            Call CallStat(ParentName$)
            Call CallStat(CallLevel, ParentLineNum)
            Call CallStat(CallLevel)

    where "CallLevel" receives the current CALL-by-filename level number 
    (zero if there are no CALLs-by-filename in progress), "ParentLineNum" 
    receives the line number of the CALL statement in the parent program 
    (zero if none), and "ParentName$" receives the name of the parent 
    program ("" if none). 

o   A new intrinsic function, CRC16(), has been implemented to calculate
    16 bit CRC values.  BASIC syntax:

        x = CRC16(mode, polynomial, string, oldcrc)

    where:

        "mode = 0"  -  calculate 8-bit sum of lower 8 bits of each character
        "mode = 1"  -  calculate CRC using lower 8 bits of each character

    An XMODEM compatible CRC can be calculated using mode one, a 
    polynomial value of 4129 (0x1021), and an initial CRC of zero.

o   A new statement, CHAIN READ IF, has been added to perform a CHAIN READ
    of specified variables, but without reporting an error if any of the
    variables weren't passed by CHAIN WRITE statements.  Example:

        CHAIN READ IF SubTotal, Filename$

o   A new option, "OPTION DIALECT IMS", has implemented to select IMS BASIC
    compatible behavior.  That behavior is identical to "OPTION DIALECT IRIS1"
    except for USING mask behavior where a positive value is allowed to use
    all characters for digits.  For example, the mask "--#.##" normally
    would generate an overflow result for 123.45, but outputs "123.45" with
    "OPTION DIALECT IMS".

o   Behavior change: "OPTION DIALECT IRIS1", "OPTION DIALECT BITS1", and
    "OPTION DIALECT IMS" now allow intrinsic CALLs and functions to return 
    values in parameters even when the parameter is a subscripted string.
    This change improves compatibility with UniBasic and IMS BASIC.

o   The "Data=XXX" open option to set serial line character size, parity,
    and stop bits has been extended to accept a question mark ("?") in
    place of the character size, parity, or number of stop bits.  If "?"
    is used, then the existing value of that parameter will be left
    unchanged.  Thus the option "Data=8?1" sets the character size to
    eight bits and the number of stop bits to one, but leaves the parity
    option unchanged.  A new parity option, "P", has been defined to
    enable parity using the current even or odd parity setting.

o   To support conversion of IMS BASIC indexed contiguous files, a key
    translation feature has been added to dL4 Portable/Universal indexed
    contiguous files.  The feature supports translating two digit years
    between "00" and "39" in keys to the values "An" through "Dn".  This
    translation causes the keys for years 2000 - 2039 to be sorted 
    correctly.  An application using the file will only see numeric dates.
    The translation is defined for a file by using the statement

        Set #chan,-599;IndexNum,MapNum,Offset,Size

    where "IndexNum" is the index containing the keys to be translated,
    "MapNum" is the mapping function number (only function zero is 
    supported), "Offset" is the zero based byte offset of the year in the
    key, and "Size" is the length of the key field in characters.  The
    translation definition is stored in the file header and will be used by
    any subsequent open of the file.  Key translation can be disabled on an
    open file by the statement "Set #chan,-599,0;" and re-enabled by the
    statement "Set #chan,-599,1;".  The dL4 QUERY utility (tools/query) has 
    been extended to display the translation option, if any, used by an index.

o   A new runtime parameter, "MINPORT", has been defined to set the
    minimum port number to be used when automatically generating a port
    number.

o   A new option, "-k seconds", has been added to the "run" utility to 
    specify a socket "keepalive" timeout period for the standard input
    channel.  This option can be used when using "run" to execute dL4 
    programs connected to a socket.  The timeout option causes an error
    when reading from the socket if the remote system crashes, is
    rebooted, or loses its network connection.

o   The statement "GET #c,-399;S$" can be used to retrieve the index
    character set from an indexed contiguous or Full-ISAM file.

o   The terminal type number of the dL4Term character window terminal
    definition ("term/dl4term.chwin") has been changed to 409 to distinguish
    it from the standard dL4Term terminal definition (which uses 410).
    The number of lines has been changed to 25 (the default value for
    dL4Term).  The number of columns is now updated when a 'NR' or 'WD'
    mnemonic is processed.

o   A new function, CHR?(n), has been implemented to convert numbers to
    binary variable bytes.

o   An error is now reported if a READ or RDLOCK statement contains
    a constant or expression in the argument list.  For example, the
    statement 'READ #5;"abcdef"' is no longer legal.

o   Semicolons are now converted to commas in MAT WRITE statements when
    converting programs.

o   The raw file driver has been extended to write an entire string value,
    including zero bytes or characters, when a MAT WRITE statement is used.

o   A new MSC$() function, MSC$(-2), has been implemented to returned the
    dL4 revision number in the format RRLLBBSS.  Another new MSC$() function,
    MSC$(-3), has been implemented to return the dL4 revision string.

o   The "run" and "loadsave" utilities now accept a "-V" option to print
    the dL4 revision and exit.

o   RmvSpaces(), WhoLock(), and the DynamicXport CALLs used in UniBasic have
    been added to the standard conversion profiles ("tools/convert.prf" and 
    "tools/convbits.prf").

o   The "Serial Terminal" and "Terminal Window" drivers now support output
    of zero bytes in binary output mode.

o   A new channel function, CHF(1500 + c), has been implemented to return
    the number of characters read by the last I/O operation.  This channel
    function can be used when performing binary input from serial ports
    or sockets.

o   The intrinsic CALLs SETGLOBALS() and GETGLOBALS() now support up to
    1000 items (the previous default limit was 30).

o   A new MEMBER statement option has been added to specify variable
    length fields.  The VARLEN option can be used with FoxPro Full-ISAM
    files to create memo fields instead of fixed length character fields.
    Example:

        Def Struct REC
          Member Name$[32] : Item "Name"
          Member 3%,Price : Item "Price"
          Member Comment$[100] : Item "Comment" : Varlen
        End Def 

    The QUERY utility in the Tools/ directory displays variable length
    fields with a "V" attribute.

o   The DUPLICATE, KILL, and MODIFY statements now accept an option AS
    clause to specify the driver name or class.  The AS clause is used
    with drivers that cannot be autoselected such as future SQL drivers.

o   The TERM utility in the Tools/ directory now has a DUMP option to
    request a program dump on a specified port.  The DUMP option can only
    be used if the specified port has the DL4PORTDUMP environment variable
    defined to specify the dump file location.  Example:

        #term 5 dump

o   The CHECKSUM utility in the Tools/ directory now has a "-c checksum"
    option to calculate a file checksum and compare the result to an
    expected value.

o   The QUERY utility in the Tools directory now displays the creation,
    last accessed, and last modified date/times of the specified file
    if those values are available.  Because Unix does not maintain a
    creation date, the displayed creation date/time will simply be the
    earliest of the record date/time values.

o   Behavior change: the maximum repeat count for a character (such as
    'n PI') is now limited to 32767 to avoid runaway printing.

o   The translation of strings when reading from or writing to UniBasic or
    Universal files has been changed to support intrinsic CALLs that pack
    into or unpack data from strings.  The new translation effects non-ASCII
    values which were previously translated to dL4 mnemonic codes.  The new
    method translates any character in the mnemonic range to a special
    Unicode range of 0xf780 to 0xf7ff.  This translation preserves the
    eight bit value of the translated characters allowing intrinsic packing
    CALLs to simply ignore the upper eight bits of the Unicode character.
    If characters in this special range are printed to a terminal or
    printer driver, the characters will be translated to actual dL4 mnemonic
    codes at output time.  When writing to a UniBasic or Universal file,
    the special translation range, the standard dL4 mnemonics, and any
    Unicode character between 0x0080 and 0x00ff will all be translated to
    mnemonic character values.

    The purpose of this change is to ease conversion from UniBasic to dL4 by
    allowing access to files that contain packed data.  The change will not
    be visible to existing dL4 applications if they simply read mnemonic
    values from file and print the values to a terminal, a printer, or 
    another file.  The change will be visible if the application examines
    the actual character values.  For example, if an application reads
    mnemonic strings from a file and then compares the characters to dL4
    mnemonics ('IF A$[I,I] = 'CS'), the characters will never be equal to
    the expected mnemonic characters.  If your existing dL4 application 
    depends on this type of behavior, please contact Dynamic Concepts.

o   The conversion profile format has been extended to automatically append
    "[]" to intrinsic CALL array parameters when a program is converted.
    For each intrinsic CALL that has array parameters, a prototype
    parameter list must be added to the conversion profile.  For example,
    the following entry in the "[Intrinsic]" section of the standard 
    tools/convert.prf file specifies that the second and the optional 
    fifth parameters are arrays:

        FileInfo=127(Dir$,Info[],Filename$,Mode,DirInfo[])

    Note that "[]" has been placed after each array parameter to inform
    dL4 that brackets should be added to these parameters during conversion.
    Using this information, the line

        CALL 127,D$,A,A$,1,T

    would be converted to

        Call FileInfo(D$,A[],A$,1,T[])

    In this release, the types and names of the parameters in the conversion
    profile are not used during conversion and they do not need to match 
    actual usage.

o   A new optional section, "[CallByFilename]", has been added to conversion
    profiles to append "[]" to each array parameter in a CALL-by-filename
    or in the ENTER statements of a subprogram that uses array parameters.
    This feature is used to convert from IMS BASIC and it is not needed 
    when converting from UniBasic, IRIS, or BITS BASIC.  For each subprogram
    that uses array parameters, an entry as shown below should be added to
    the "[CallByFilename]" section:

        [CallByFilename]"
        PrintReport="PrintReport"(A,B,C[],D)

    The example above would add "[]" to the third parameter of 
    CALL "PrintReport" statement in each converted program.  It would also
    add "[]" to the third parameter of the ENTER statement in "PrintReport"
    when converting that subprogram.  The quoted filename in the conversion
    profile is case insensitive, but it must otherwise match the filename
    used in CALL statements.  Synonyms may be added after the first filename
    for alternative forms.  Example:

        PrintReport="PrintReport"(A,B,C[],D),"1/PrintReport"

o   When converting programs using "LOADSAVE -C" or the SCOPE CONVERT 
    command, DECLARE statements are now added for DEF FN functions that
    are used prior to their declaration.  The inserted DECLARE statements
    eliminates compile time errors that would otherwise be reported and
    allows the converted program to run.

o   When converting programs using "LOADSAVE -C" or the SCOPE CONVERT 
    command, "CHF(e)" functions will be converted to "CHF$(e)" if "e"
    contains a constant between 800 and 899.

o   A new boolean parameter, "ConvertCHF800To1300", has been added to
    the "[Settings]" section of the conversion profile.  If set to "TRUE",
    "CHF(8xx)" function calls in the source program will be converted to
    "CHF$(13xx)" function calls which return the native absolute path.

o   A new optional setting has been defined for conversion profiles to 
    convert references to undefined line numbers to labels and then
    add labeled statements at the end of the program.  Using this
    option the following program

        10 Print "Hello" \ Goto 30
        20 Goto 1000
        30 Print " world"

    would be converted to

          10 Print "Hello" \ Goto 30
          20 Goto U01000
          30 Print " world"
        1000 End ! Labels inserted for non-existent lines/labels
        1001 U01000: Error 6

    The line numbers used by the inserted labels are always greater than
    any line number used in the program.

    The option is enabled by adding a "ConvertUndefinedLineRefs=True"
    line in the conversion profile settings section.  Example:

        [Settings]
        ConvertUndefinedLineRefs=True
    
o   A new optional setting has been defined for conversion profiles to
    renumber programs when they are converted.  This option can be used
    when converting programs that need to have DECLARE INTRINSIC SUB and 
    other statements inserted prior to the first line of program, but the
    first line has a line number of one.  The following example would
    renumber a converted program to start at line 100 and increment by
    10 for all following lines:

        [Settings]
        Renumber=100,10

o   A new optional setting has been defined for conversion profiles to
    report each occurrence of a undefined intrinsic CALL as an error.

        [Settings]
        ReportUndefProcs=True

o   If "Language=BITS" is specified in the "[Settings]" section of the
    conversion profile, "IF ERR 0" statements will be converted to
    "IF ERR(0)" statements.

o   If "Language=BITS" is specified in the "[Settings]" section of the
    conversion profile, "CHR(x)" will be converted to "CHR$(x)" in converted
    programs.

o   A new optional section, "[Edit]", has been added to conversion profiles 
    to support user defined source editing that will be applied to each 
    source line when a program source file is converted.  The feature is 
    available from both the LOADSAVE "-c profile" option and the SCOPE 
    CONVERT command.  The entries in the "[Edit]" section consist of pairs 
    of lines where the first line defines what is to be replaced and the 
    second line defines the new text.  For example, if a conversion profile
    included the lines
 
        [Edit]
        OldText=Hello
        New=GoodBye
 
    then each occurrence of "Hello" in a source line would be replaced with 
    "GoodBye".  The keyword in the first line defines how the search will
    be performed:
 
    OldText=        finds and replaces each exact match of the specified text
     
    OldTextCI=      finds and replaces each case-insensitive match of the 
                    specified text
     
    OldTokens=      finds and replaces each matching token string ignoring 
                    case and whitespace.  It will NOT change text in string 
                    literals, mnemonic literals, DATA statements, or 
                    comments.  A number in the text will match any equivalent
                    numeric value ("1.3 will match with "1.30").  Because
                    case and whitespace are ignored, the text "A + B" would
                    match "a + b", "A+B", "A+b", and several other forms.
                    Because this a token oriented search, "A + B" would not
                    match "A + B1".
     
    OldString=      finds and replaces each exact match of the specified text 
                    within a string literal ("abc") other than those in DATA 
                    statements
     
    OldMnemonic=    finds and replaces each case-insensitive match of the 
                    specified text within a mnemonic literal ('CS BD')
     
    OldData=        finds and replaces each exact match of the specified text 
                    in a DATA statement
     
    OldComment=     finds and replaces each exact match of the specified text 
                    in a comment (! or REM)

    The keyword value is case insensitive in both the "old" and "new" lines.

    Example:

        [Edit]
        oldtokens=@0,23;
        new=@0,Msc(34);

o   A new option, "-w", has been added to the LOADSAVE utility to enable
    warning messages for non-fatal errors.  In this release, warning
    messages are produced for string variables without corresponding DIM
    statements.

o   A new option, "-L", has been added to the LOADSAVE utility to convert
    all line number references to labels.  Each generated label has the
    form "Lnnn" where "nnn" is the original line number.

o   The SCOPE CONVERT command and the LOADSAVE "-c" convert option will now
    convert DATA statements by making each DATA value a quoted string.  The
    READ statement has been enhanced to allow READing a DATA string value
    into a numeric value.

o   Conversion of DATA statements in IMS BASIC programs has been improved
    to accept end of line comments.  This feature requires using a conversion
    profile with a "Language=IMS" setting.

o   The SCOPE CONVERT command and the LOADSAVE "-c" convert option will now
    accept PEEK, POKE, SECTOR, and TAPE statements, which do nothing in
    UniBasic, and convert the statements to

        PAUSE NOT("Original statement text")

    which does nothing in dL4.

o   The SCOPE CONVERT command and the LOADSAVE "-c" convert option will now
    accept and convert semicolons used instead of commas in READ or WRITE
    statements.  For example, the line

        10 READ #1,R;A,B;C,D;

    is converted to

        10 Read #1,R;A,B,C,D;

o   The SCOPE CONVERT command and the LOADSAVE "-c" convert option will now
    convert extra statements after an IF ERR 0 statement to comments.  This
    produces behavior similar to UniBasic where extra statements are 
    ignored and never executed.  For example, the line

        IF ERR 0 LET N = 1 \ PRINT "Hello"

    is converted to

        IF ERR 0 LET N = 1 ! PRINT "Hello"

    This conversion is not applied if the conversion language is IMS.

o   A new runtime parameter, DL4DRIVERS, has been defined to configure dL4
    driver selection.  There are currently two DL4DRIVERS options, "Universal"
    and "ANSI Text".  Setting DL4DRIVERS to "Universal" causes dL4 to create
    Universal Indexed-Contiguous or Formatted files by default instead of 
    Portable Indexed-Contiguous or Formatted files.  This can be useful if
    the files need to accessed by UniBasic or if mnemonics are to be stored
    in the files (note that only UniBasic supported mnemonics can be stored
    in Universal files).  Setting DL4DRIVERS to "ANSI Text" causes dL4 to
    create and read text files using the ANSI (ISO 8859-1) character set
    instead of the UniBasic character set.  Options in the DL4DRIVERS 
    parameter are case-insensitive and multiple options can be separated 
    by commas.  Examples:

        DL4DRIVERS="Universal"
        DL4DRIVERS="universal,ansi text"

o   A new option, "-O filename", has been added to LOADSAVE to produce
    an output file even if errors are detected during compilation.  The
    option must be used instead of the standard "-o filename" option and
    produces a program file that can be loaded in SCOPE, but which cannot
    be executed until the errors are corrected.  This option is equivalent
    to the SCOPE SAVE command that saves a program after reporting any
    detected errors.

o   The pipe driver has been extended to allow using both the TRANSLATE=
    and OPENAS= options in the same printer script.  This supports
    scripts that use translation with the Windows Page Printer driver to
    implement user defined mnemonics such as 'SA' or 'SB'.  The printer
    description file must be setup to perform a Unicode-to-Unicode
    translation using a "UnicodeDevice=True" entry in the "[Settings]"
    section.  Since the output is being sent to a dL4 driver and not a
    physical device, macro definitions must output Unicode characters and
    dL4 Unicode mnemonic values.

    Example:

    rem dL4opts=translate=C:\progra~1\dl4\printer\dl4printer.prf
    rem dL4opts=openas=selected page printer
    rem dL4opts=lpi=8,cpi=10,hmargin=36,vmargin=36

    The TRANSLATE= option must occur before the OPENAS= option. 

o   A new driver, "Sorted Directory", is now available to provide a
    sorted directory listing.  The driver is otherwise identical to the
    normal directory driver.  The driver is used by opening a directory
    with an AS clause.  Example:

        Rem List the current directory contents in sorted order
        Dim F$[255]
        Open #1,"." As "Sorted Directory"
        Do
            Read#1;F$
            If F$ = "" Exit Do
            Print F$
        Loop
        Close #1

o   To increase compatibility with UniBasic, the following SPC() and MSC()
    functions have been added or changed:

        SPC(4)      returns -1 or the value of the SPC4 runtime parameter
        SPC(264)    returns -1 or the value of the SPC264 runtime parameter
        SPC(272)    returns -1 or the value of the SPC272 runtime parameter

        MSC(2)      returns -1 or the value of the SPC4 runtime parameter
                    (MSC(2) is equivalent to SPC(4))

        MSC$(-1)    returns "" or the value of the SPC4 runtime parameter
                    formatted as "RLLBBSS".
        MSC$(264)   returns ""

        ERR(8)      returns -1

o   The SCOPE CHECK command has been enhanced to produce warning messages
    for string variables without DIM statements.  The test only determines
    if a DIM statement exists for each string variable - it does NOT
    determine if the DIM statement will be executed prior to the first
    use of the string variable.

o   Behavior change: the LIBSTRING runtime parameter, if defined, is
    now used when finding a program filename specified on the "runc.exe"
    or "runw.exe" command line.

o   Behavior change: the error output format of LOADSAVE has been
    changed slightly to support the UniBasic to dL4 conversion package.

o   Behavior change: mode 3 of the PORT statement now supports the "Input
    ready" flag value of 32768 to indicate that the port is waiting for
    input.

o   A new mnemonic, 'ET', has been defined for UniBasic compatibility.
    The effect of using the mnemonic is dependent on the terminal 
    definition file.

o   The POS() string search function has been extended to allow searching
    for a character that is or is not part of a specified set of characters.
    The expression "POS(S$, IS T$)" will search for the first character in
    the string S$ that matches a character in the string T$.  The expression
    "POS(S$, EXCEPT T$)" will search for the first character in the string
    S$ that does not match a character in the string T$.  These new search
    types can be combined with the optional step and occurrence options of
    the POS() function.

o   Limited support for polyfiles, similar to that of UniBasic, has been
    implemented to set key lengths in bytes rather than 16-bit words, set 
    the first record number to zero, and return key lengths in bytes.
    Polyfile status can be set in an indexed contiguous file by creating
    the file with the "<y>" attribute or using the intrinsic CALL VOLLINK().

o   An input mode has been added to defer keyboard input after a GUI event 
    has been reported.  This prevents the user from entering data into the 
    wrong GUI element (such as a 'WCSTRING' edit box) because the 
    application hasn't had time to select the proper new GUI element.  The 
    defer mode is activated by printing a '1 WCEVENT' mnemonic string.  Any 
    GUI event that returns an action string to the application will cause 
    keyboard input to be stored in an internal queue until the application 
    prints a 'WCFOCUS' or 'BEGIN' mnemonic to set the input focus.  After
    the focus is set, the queued keyboard input will be released to the
    selected GUI element until another GUI event occurs.

    Once selected by a '1 WCEVENT' mnemonic string, the deferred input mode 
    applies to all windows and all input until a '0 WCEVENT' mnemonic
    string is printed.  The current deferred input queue can be cleared
    by using a '2 WCEVENT' mnemonic string.

o   Behavior change: the 'LK' and 'UK' mnemonics can now be output to a
    window if the mnemonics are defined in the terminal definition file.

o   Behavior change: mnemonics in a window title will be ignored rather
    causing an "illegal character" error.

o   The 'AE', 'AD', 'BO', 'EO', 'BA', and 'EA' mnemonics have been added
    to the standard terminal definition files for terminals that support
    auxiliary printers.

o   Behavior change: the SCOPE LIST and SHOW command will now default to
    using "-v" paging behavior unless they are used in an EXEC command
    script.

o   Behavior change: the CHF(c) function will return a record count of
    zero for newly created portable files instead of one.

o   A leading numeric expression can now be used in a string concatenation
    expression that uses commas.  For example, the statement

        10 A$ = Spc(8),"at",Spc(10)

    is now legal.

o   A leading date expression can now be used in a string concatenation
    expression that uses commas.  For example, the statement

        10 A$ = Tim#(0)," is the current date and time"

    is now legal.

o   Input cursor tracking is now supported with the new 'BTRACK' mnemonic.
    This feature is similar to UniBasic cursor tracking except that is
    enabled by outputting the 'BTRACK' mnemonic rather than an octal "\001\".
    The LOADSAVE "-c" and SCOPE CONVERT command will convert statements
    such as

            INPUT "\001\";A$

    to

            INPUT 'BTRACK';A$

    If a converted application uses PRINT statements to enable cursor
    tracking, the PRINT statements must be manually converted.

o   A new option, "STRINGS HAGEN", has been added to provide compatibility
    with UniBasic HAGEN string mode.  Example:

        OPTION DEFAULT STRINGS HAGEN

o   A new option, "ZERO DIVIDED BY ZERO IS LEGAL", has been added to make
    zero divided by zero equal to zero rather than causing an arithmetic
    overflow error.  This option is also enabled by the "DIALECT IRIS1"
    and "DIALECT BITS1" options.  Example:

        10 Option Default Zero Divided By Zero Is Legal
        20 Print 0 / 0

o   A new option, "DIALECT IRIS1", has been added to provide a higher 
    degree of BITS compatibility than "DIALECT IRIS".  The new option
    enables the "ZERO DIVIDED BY ZERO" option in addition to the other
    "DIALECT IRIS" options.

o   A new option, "DIALECT BITS1", has been added to provide a higher 
    degree of BITS compatibility than "DIALECT BITS".  The new option
    enables the "DIALECT BITS" options and also enables BITS style FOR/NEXT 
    final value behavior, BITS USING mask features, and an initial precision 
    of 4%.

o   A new option, 'PROGRAM TAG "text"' has been added place user defined
    text in a program file as ASCII text.  This option can be used to
    add revision text strings to be printed by the Unix "what" utility.
    Example:

        OPTION PROGRAM TAG "@(#) Test program 1.3"

o   A new driver, "ANSI Text", has been added to create and access text files
    that uses the ANSI character set.  Using the driver is equivalent to
    opening a text file with the "charset=ansi" option. 

o   When the setting "IsUnicodeDevice" is TRUE in a terminal or printer
    definition file, all characters and mnemonics will be passed unchanged
    unless a macro definition exists for the character or mnemonic.  In
    previous versions, a macro definition was required for every character
    or mnemonic,

o   If an OPEN statement uses a "$" (output pipe) or "$$" (input pipe) 
    filename to open a script, then the name of the current program will 
    be passed to the script in the environment variable "DL4PROGRAM".  The
    script can then use the program name to control printer spooling or
    special handling.

o   A new runtime parameter, "AVAILREC", can be used to specify the value
    returned by SEARCH as the number the records available in indexed 
    contiguous files.  If the "AVAILREC" parameter is not set, the SEARCH
    statement will return, as it did in previous dL4 releases, the actual 
    number of records available from the file free list or a minimum value 
    of one.

o   A new runtime parameter, DL4STOPDUMP, has been implemented to control
    whether a program dump should be written when a program exits via a
    STOP statement.  If the environment variable DL4STOPDUMP is defined
    as an absolute path, then any program that exits via a STOP will cause
    a program dump file to be written to the path.  The path can use the
    macro variables and other features of the DL4PORTDUMP runtime parameter.

o   Behavior change: the terminal type number return by SPC(13) and MSC(32)
    for dL4Term is now 410 rather than zero.  This value can be changed in
    the dL4Term terminal definition file (term/dl4term).

o   The terminal type number returned by SPC(13) and MSC(32) for dL4 for
    Windows can now be configured by the setting the DWORD registry
    value "TermType" in:

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\TermType

    or

    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\WinTerm\TermType

o   The run utility now returns an "unsuccessful" exit status to the operating
    system if a program exits with a STOP statement.

o   A new setting, "StaleReadAllowed=True", is now supported in the file
    section of a bridge profile.  This setting enables re-reading the
    current record data after the record has been unlocked.  Use of this 
    setting is not recommended because the actual data record may have been 
    changed and the old data will be used for any re-read operations.  This 
    feature is provided for compatibility with programs that performed such 
    reads on Indexed-Contiguous files and already suffered from potential 
    inconsistent data.

o   When used with DynamicXport, dL4 now supports using "dl4l()" or "dl4t()" 
    references within "dl4c(For)" structures in template files.  The "dl4c"
    format has been extended to supported the format "dl4c(For,<Name>)" and
    "dl4c(For,<Name>=<number>)" to allow "dl4v(<Name>)" references to the
    current array index number.

o   Bug fixed: WCLIST boxes did not work correctly with hidden fields 
    (option value 16) or empty list items.

o   Bug fixed: programs using unary operators such as "-" were always forced
    to the latest program object revision and could not be run by earlier
    versions of dL4.

o   Bug fixed: mismatched variable lists in CHAIN WRITE and CHAIN READ 
    statements in SWAP programs caused the child program to silently exit
    instead of reporting an error to the parent program.

o   Bug fixed: the 'ML', 'MR', 'MD', and 'MU' keys are accepted in cursor
    tracking mode even if they are defined as illegal keys for normal
    input mode.  Any mnemonic character will be accepted in Activate-On-
    Mnemonic mode.

o   Bug fixed: the SEARCH and GET statements could corrupt the memory image
    of a program if string literals were used as arguments.

o   Bug fixed: the characters 'SI' ("\017\") and 'FS' ("\034\") could not be
    printed to a dL4Term auxiliary printer.

o   Bug fixed: the conversion profile text edit feature (the "[Edit]"
    section) could not change the first symbol on a line.

o   Bug fixed: expressions in a MAT WRITE or MAT WRLOCK statement argument
    list caused an "Unrecognizable word: 12291" error when SAVEing the
    program.

o   Bug fixed: breakpoints set in the debugger for the current program
    unit were ignored.

o   Bug fixed: the QUERY utility reported UniBasic "Q" files as using "Mixed"
    numerics rather than IRIS numerics.

o   Bug fixed: the LIBR utility failed with an error message if a FoxPro
    Full-ISAM file was encountered in the listed directory.

o   Bug fixed: SWAP keys were not processed until the end of an INPUT
    preventing the SWAP program from reading the characters immediately
    following the SWAP key.

o   Bug fixed: the DynamicXport DxGet() CALL and function did not return
    the correct character values for 'FX' or 'FM' mnemonics.

o   Bug fixed: the "Printer->Preferences" dialog overwrote some printer
    parameters that are configurable only via the registry editor.

o   Bug fixed: closing a child window reported a GUI event to the parent
    window if the current parent window GUI element had the queue-on-loss-
    of-focus option set.

o   Bug fixed: functions keys were not passed from GUI elements to the 
    parent window on Windows 95, 98, or ME.

o   Bug fixed: when converting OPEN statements in IMS programs, statements
    with multiple channel numbers did not accept more than one file after
    the second channel number.  

o   Bug fixed: using a conversion profile to convert a function to a 
    different result type (such as "ERM()" to "ERRMSG$()") caused a runtime
    error when the function was used.

o   Bug fixed: syntax errors in a conversion profile sometimes caused
    memory violations in LOADSAVE or while executing a CONVERT command.

o   Bug fixed: 256 and 257 character string and mnemonic literals were
    accepted by the compiler rather than producing the required syntax
    error.

o   Bug fixed: if a dL4 process was terminated by a Unix "kill -9"
    command, SPAWN statements failed for other users until the message
    queue associated with the killed processed was deleted.

o   Bug fixed: if an application updated a GUI element while the element
    had the focus, a "value change" event was triggered when the element
    lost the focus.

o   Bug fixed: the 'RECT' mnemonic and the BOX statement sometimes drew
    boxes that were taller and wider than they should have been.

o   Bug fixed: the SPC(n) function, where "n" was not a standard function
    number, only looked at runtime parameters in the environment and did
    not check the registry.

o   Bug fixed: TABbing between GUI fields did not work in '1WCEVENT'
    mode when input was deferred.

o   Bug fixed: dL4 output sometimes "froze" requiring the user to
    terminate the dL4 process.

o   Bug fixed: typing a function key while input was deferred in '1WCEVENT'
    mode caused an infinite loop.

o   Bug fixed: the printer driver sometimes lost output data when open
    with "binary=true".

o   Beta bug fixed: conversion profile "[Edit]" rules were not applied
    to line that did not have line numbers.

o   Beta bug fixed: conversion profile "[Edit]" rules were applied to
    the line number portion of a source line.

Dec  4 2001 (Release 4.4)

o   The SAVE file revision has been changed from 2.11 to 2.12 in order to
    support new features in dL4 4.4.  Full upward compatibility is 
    provided, so program files created by earlier versions of dL4 can 
    still be used.  Programs created by this release of dL4 can be used
    by earlier releases of dL4 4.x if the programs do not use any of the 
    new features.

o   Two new GUI mnemonics have been defined: 'WCBQRYBUF' and 'WCEQRYBUF'.
    Printing 'WCBQRYBUF' to a window enables special buffering for the
    data returned by the 'WCQUERY' mnemonic.  Normally, sending 'WCQUERY'
    to a GUI element (such as 'WCSTRING') causes the element to return
    its current value.  For example, sending 'n WCQUERY' where 'n' is the
    element number of a 'WCSTRING' edit box causes the text in the edit
    box to be returned as input to the window.  This can complicate
    programming because query results are mixed in with event data such 
    as function keys or GUI element status changes.  The special 
    buffering enabled by 'WCBQRYBUF' separates the query results from the 
    event data.  Event data can be read by normal INPUT statements, but 
    the query buffer can only be read from "record 1" of the window
    channel.  For example, 

        ! Channel 3 is open to window 
        Print #3;'WCBQRYBUF';
        Print #3;'5 WCQUERY';
        Input #3,1;S$

    In order to read from "record 1" of the default window channel, use
    the special record number -3 (described below) or the DUPCHANNEL 
    intrinsic CALL.  Once a 'WCBQRYBUF' mnemonic is printed, the special 
    buffering mode applies to all windows and persists until a 'WCEQRYBUF' 
    or 'IORS' mnemonic is printed.  Like other GUI mnemonics, these 
    mnemonics are supported only when using dL4Term (4.3.1.3 or higher) or 
    in dL4 for Windows.

o   The special channel numbers -3 and -4 can now be used in INPUT, READ,
    WRITE, SET, and other I/O statements to perform I/O to the current
    standard input (-3) and output (-4) channels.  This extension is
    particularly useful when using the 'WCBQRYBUF' input mode since it
    supports reading from record 1 of the current window channel.

o   The intrinsic CALL DupChannel() now recognizes the special channel
    numbers of -3 and -4 as the current input and output channels.  This
    allow access to the current Dynamic Window channel.

o   A new mnemonic, 'PGMHELPFN', has been defined for dL4 when used with
    dL4Term or in dL4 for Windows.  The mnemonic sequence 
    
        PChr$(n,"text");'PGMHELPFN'

    will program function key 'n' ('Fn') to send the character string 
    "text" as input when pressed.  In addition to "text", the function key
    will send the action string of the currently selected GUI element, if
    any.  This mnemonic is similar to 'PGMFN', but can be used to implement
    context dependent function keys such as help or search keys.  'RF' or 
    'XX' mnemonics can be used to reset all function keys to their original 
    values of 'Fn'.

o   A new function, MSC(45), has been implemented to return the GUI element
    number of the user selected GUI element or a WCQUERYed GUI element.  
    The value returned is not the current element number, but rather the 
    number at the time of the most recent input.  For example, assume a user
    had selected edit box 1, typed 'F6', moved to edit box 5, and then typed
    'F6' again.  If an INPUT statement read only the first function key
    value, then MSC(45) would return 1, the selected element at the time the
    function key was pressed.  The value of MSC(45) would not change to 5
    until the second function key value was read by an INPUT or READ 
    statement.

o   A new mnemonic, 'WCRESETFONT', has been defined for dL4 GUI programming.
    The new mnemonic restores the default font for use by newly created GUI
    elements.  Typically, the mnemonic would be used to clear the font set
    by a previous 'WCSETFONT' mnemonic.

o   The statement

        SYSTEM 31,"C:\\Program Files\\Application\\program.exe",S

    will try to execute "program.exe" on the user's PC.  The variable
    "S" will be set to zero if the program was successfully started and
    non-zero if the program couldn't be started.  The SYSTEM statement 
    suspends execution of the dL4 program and waits until the program 
    exits.  In the default configuration, the user will be prompted via 
    a message box to permit or deny running the command.  The DWORD 
    registry value

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\AllowSYSTEMCmd

    or

    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\WinTerm\AllowSYSTEMCmd

    can be set to one to automatically accept commands without displaying 
    the message box (note: if set to zero, an "AllowSYSTEMCmd" value in  
    HKEY_CURRENT_USER will require the message box no matter how the
    HKEY_LOCAL_MACHINE value is set).  This SYSTEM mode is included for 
    compatibility with the client command execution feature of dL4 for Unix.

o   Two new mnemonics, 'SUSPENDAUX' and 'CONTINUEAUX', have been
    defined to suspend or continue output to an auxiliary printer after
    a 'BA', 'BO', or 'AE' mnemonic has started output to such a printer.
    These mnemonics make it possible to mix output between the printer
    and the screen.

o   The Preferences->Printer dialog now allows the user to set an
    "Options" value.  The "binary=true" option can be used with non-device
    printers to allow unformatted character sequences, such as PCL commands,
    to be sent directly to a printer (device printers always operate in a
    binary mode).

o   A new runtime parameter, DL4HANGUPEXIT, can be set to trigger an
    automatic exit if an unrecoverable error occurs on standard input or
    standard output.  The feature can only be used if standard input or
    output are open to sockets.

o   A new SYSTEM statement mode has been added to return the number of 
    available 512 byte disk blocks on a file system.  The statement

        SYSTEM 32,"path",B

    returns in "B" the number of available blocks on the file system
    that contains the directory or file "path".  The SCOPE CONVERT 
    command and LOADSAVE utility "-c" option will convert UniBasic/BITS
    UNIT mode 3 statements to SYSTEM 32 statements.

o   Conversion profiles can now define functions to be translated in addition
    to user CALLs.  For example, if the line "ERRMSG$=ERM" is included in a
    library section of a conversion profile, then loading a program with that
    profile will convert all instances of the ERM function to ERRMSG$ and the 
    required declarations for the library function will be inserted into the 
    converted program.

o   Conversion profiles can now include a "[Standard]" section to define
    the standard pre-defined function names of the source language.  This
    section can be used if there are problems with names that collide with 
    dL4 standard function names (such as "TRIM$").

o   Conversion profiles can now include a "[Settings]" section.  The 
    "LANGUAGE=xxxx" line in the "[Settings]" section selects the
    source language for the conversion where "xxxx" can be "IRIS", "BITS",
    or "IMS".  If the source language is "IMS", statements such as
    'OPEN #c;"R","Filename"' will be converted to 'ROPEN #c;"Filename"'.

o   When loading a program using a conversion profile, parenthesized
    subscripts are now converted to bracket subscripts ("A(5)" becomes
    "A[5]").

o   The syntax of the multiline IF structure has been enhanced to accept an
    optional "THEN" keyword after an IF or ELSE IF boolean expression.  The 
    "THEN" keyword is accepted and discarded.

o   The LOADSAVE utility now supports a "-C filename" option to perform
    source-to-source conversions.  The command:

        loadsave -C converted.bas -c convert.prf orig.bas

    converts the program text source file "orig.bas" to dL4 using the
    conversion profile "convert.prf" and outputs the converted program
    text to the text file "converted.bas".  The conversion profile can
    contain an "[OutputFormat]" section with lines such "Indentation=n",
    "LeftMargin=n", and "TabSpacing=n" to control the formatting of the
    output lines.  The "TabSpacing" value specifies that a tab character
    should replace each occurrence of "n" leading spaces.  These values
    can also be specified on the loadsave command line by using the
    "-i n,m" and "-t n" options.

o   A simple include file feature has been added to the LOADSAVE utility.
    The INCLUDE statement is recognized only by LOADSAVE and reads
    source text from a specified file into the program following the
    INCLUDE statement.  The environment variable INCSTRING can be used
    to specify a space separated list of directories that should be
    searched when opening an include file.  If lines in an include file
    use line numbers, the lines will be inserted at the specified lines
    replacing any previously loaded lines with those line numbers.  The
    INCLUDE statement can have both a line number and a label.  Example:
        
        Include "filename"

o   A new option, "-n linenumber", has been added to the LOADSAVE utility
    to specify the starting line number when using source files without
    line numbers.  By using a starting line number other than the default
    of 1, an open range of line numbers can be left for use by conversion
    profiles that insert declarations and other header lines.

o   A program line can now consist of a label without a statement.  For 
    example, the line:

            NEXTFILE:

    is now legal and will be treated as the label "NEXTFILE" followed by
    an empty comment ("NEXTFILE: !").

o   To improve compatibility with other BASIC languages, it is now legal
    for a program line to have a FOR statement follow an IF statement.

o   A new channel function, CHF$(1300+c), has been implemented to return the
    native path of the file open on channel "c".

o   A new channel function, CHF(1400+c), has been implemented to return the
    file identification number of the file open on channel "c".  In dL4 for
    Unix, this function returns the inode number of the file.  In this
    release, this function is only supported by the raw file driver.

o   Channel functions 12 and 13 have been added to the list of channel
    values displayed by the SCOPE FILE command and in program dumps.

o   The GET statement can now be used to determine the character set used
    by data file records.  For example, the statement:
    
        Get #C,-1299;Name$

    stores in "Name$" the name of the character set used on channel "C".
    An error will occur if this operation is not supported by the driver
    open on channel "C".

o   The LUMAP runtime parameter can now control whether portable filenames
    are treated as case-insensitive (default) or case-sensitive.  If the
    LUMAP parameter value begins with "(mixedcase)", all portable (relative)
    filenames will be treated as case-sensitive.  This option only controls
    how filenames are translated to and from the native filename format; the
    result of using case-sensitive filenames on a non-case-sensitive
    file system is operating system dependent.

o   A new, optional program file format is now available for Unix systems
    to allow direct execution of dL4 programs from a shell command line.
    The new format starts each dL4 program file with the line "#!string" 
    where string is a program path.  For example, the command:

        save <755> (exec=/usr/bin/run) programname

    would save the current program into the file "programname" as an 
    executable script with an initial line of "#!/usr/bin/run".  The 
    program file could then be executed directly at a shell command
    line by typing "programname".  The program file would also be usable
    in dL4 SCOPE, in CALL/CHAIN/SPAWN statements, or in dL4 for Windows.  
    The "exec" line can include options RUN such '-t ""'.

    In addition to the "exec=" option, executable Unix scripts can be 
    produced by using the "stdexec" or "netexec" options which are
    equivalent to "exec=/usr/bin/run" and "exec=/usr/bin/run -t".

    Program files can be made executable on Windows systems by using a 
    unique filename suffix such as ".dl4" and then associating that
    suffix with the required command line.

o   A new program option, "STRING REDIM IS LEGAL", has been implemented
    to make it legal to re-dimension simple string variables without
    FREEing the variable.  The following program creates a string
    variable with a dimension of 20 and then expands the string to a
    dimension of 80:

        100 Option String Redim Is Legal
        110 Dim S$[20]
        120 S$ = "Test program"
        130 Dim S$[80]
        140 S$ = S$ + " with too many characters for DIM S$[20]"
        150 Print S$

    Note that the original value of S$ is preserved when it is expanded.

o   Support has been added for DynamicXport Lite.

o   Channel command 36 (DCC_SETOPENMODE) can now change the exclusive or
    shared open mode of an open file.  This operation is currently 
    supported in Portable/Universal Indexed, Contiguous, or Formatted 
    files.  Example:

        Channel 36,#10;"E"   ! change to exclusive open

o   New intrinsic CALLs SYSRC() and DBASE() have been added to provide
    compatibility with other Business BASICs.

o   Two new intrinsic CALLs, RMVSPACES() and RMVSPACESI(), have been added
    to duplicate the behavior of CALL $RSPCS() in UniBasic and other BASICs.

    BASIC syntax:

        Call RmvSpaces(SOURCE$, DEST$, MODE)
        Call RmvSpacesI(SOURCE$, DEST$, MODE)

    If "MODE" is not equal to one, then "SOURCE$" is copied to "DEST$" with 
    all leading and trailing spaces removed.  If "MODE" is equal to 1, then 
    "SOURCE$" is copied to "DEST$" with all spaces removed except those 
    within quotes, all characters after and including an unquoted "!" are 
    removed, and a trailing linefeed is appended if the string ends in a "!".
    Call RmvSpaceI() differs in that "MODE" 1 always appends a linefeed 
    and a "MODE" other than 0 or 1 causes an error.

o   A new intrinsic CALL, WHOLOCK(), is now available for compatibility with
    dL4 for Unix.  This CALL is used on Unix to determine which port or
    process has locked a specific record of a file.  Because the Windows 
    operating system does not support this function, the CALL will always
    report the record as unlocked.  The CALL syntax is:

        CALL WHOLOCK(Channel, RecordNumber, PortNumber [, ProcessID])

    where "Channel" is a channel number open to a file and "RecordNumber" is 
    the record number in that file to be tested.  When the CALL returns,
    "PortNumber" will be set to -1 to indicate that the record is not
    locked.

o   A new intrinsic string function, DATEUSING$, has been implemented to
    format date values.  The function syntax is:

        DateUsing$(DateValue#, FormatString$)

    where "DateValue#" is a date expression to be formatted and 
    "FormatString$" is a string expression containing a mask string.  The
    following formatting codes are recognized in the mask string:

        D           Numeric day of week (0 - 6, 0 is Sunday)
        d           Numeric day of week (0 - 6, 0 is Sunday)
        DAY         Day name in upper case (SUNDAY, MONDAY, ...)
        day         Day name in mixed case (Sunday, Monday, ...)
        Day         Day name in mixed case (Sunday, Monday, ...)
        DY          Abbreviated day name in upper case (SUN, MON, ...)
        dy          Abbreviated day name in mixed case (Sun, Mon, ...)
        Dy          Abbreviated day name in mixed case (Sun, Mon, ...)
        DD          Numeric day of month zero filled ("01" - "31")
        Dd          Numeric day of month space filled (" 1" - "31")
        dD          Numeric day of month space filled ("01" - "31")
        dd          Numeric day of month ("1" - "31")
        DDD         Numeric day of year zero filled ("001" - "366")
        Ddd         Numeric day of year space filled ("  1" - "366")
        ddd         Numeric day of year ("1" - "366")
        HH          Numeric hour of day zero filled ("00" - "23")
        Hh          Numeric hour of day space filled (" 0" - "23")
        hH          Numeric hour of day space filled (" 0" - "23")
        hh          Numeric hour of day ("0" - "23")
        MM          Numeric month of year zero filled ("01" - "12")
        Mm          Numeric month of year space filled (" 1" - "12")
        mm          Numeric month of year ("1" - "12")
        MONTH       Month name in upper case (JANUARY, FEBRUARY, ...)
        month       Month name in mixed case (January, February, ...)
        Month       Month name in mixed case (January, February, ...)
        MON         Abbreviated month name in upper case (JAN, FEB, ...)
        mon         Abbreviated day name in mixed case (Jan, Feb, ...)
        Mon         Abbreviated day name in mixed case (Jan, Feb, ...)
        NN          Numeric minute of hour zero filled ("00" - "59")
        Nn          Numeric minute of hour space filled (" 0" - "59")
        nN          Numeric minute of hour space filled (" 0" - "59")
        nn          Numeric minute of hour ("0" - "59")
        PM          "AM" for time before noon, "PM" for time afterward
        pm          "am" for time before noon, "pm" for time afterward
        P           "A" for time before noon, "P" for time afterward
        p           "a" for time before noon, "p" for time afterward
        Q           Numeric quarter of year ("1" - "4", 1 is Oct - Dec)
        q           Numeric quarter of year ("1" - "4", 1 is Oct - Dec)
        SS          Numeric second of minute zero filled ("00" - "59")
        Ss          Numeric second of minute space filled (" 0" - "59")
        sS          Numeric second of minute space filled (" 0" - "59")
        ss          Numeric second of minute ("0" - "59")
        TH          Ordinal number in upper case ("1ST", "2ND", ...)
        th          Ordinal number in lower case ("1st", "2nd", ...)
        WW          Numeric week of year zero filled ("01" - "53")
        Ww          Numeric week of year space filled (" 1" - "53")
        wW          Numeric week of year space filled (" 1" - "53")
        ww          Numeric week of year ("1" - "53")
        YYYY        Four digit year
        YY          Two digit year

    Formatting codes are replaced by their associated values.  Any 
    unrecognized characters will be copied unchanged to the result
    string.

    Example:

        Print DateUsing$(Tim#(0), "MM/DD/YYYY HH:MM")

o   The SPC(n) function has been extended to return the numeric value of
    the environment variable "SPCn" where "n" is an undefined SPC function
    number.  For example, if the environment variable SPC105 was set to
    "65", then SPC(105) would return a value of 65.  User defined SPC
    functions should be defined at 100 and above to avoid conflicts with
    any future standard SPC functions.

o   The intrinsic CALL PROGRAMDUMP() has been extended with a second syntax:

        Call ProgramDump(filename$,options$)

    where "filename$" is the output file path and "options$" can be set
    to the string value "append" to cause PROGRAMDUMP() to append the
    new output to the output file rather than replacing the output file.

o   The FoxPro Full-ISAM driver now supports mixed case filenames when
    used in an absolute path.  

o   A new open option, "DataExt=xxxx", has been added to the FoxPro
    Full-ISAM driver to support opening dBase files that do not have the
    standard ".dbf" extension.

o   A new character set, "Stripped ASCII", has been added to support
    conversion of files from other BASICs where the most significant bit
    of 8-bit characters is ignored.

o   The Portable Formatted, Contiguous, and Indexed-Contiguous file
    drivers now support a new option, "NUMMAP=IEEE-LE", for files that
    contain least significant byte first ("Little Endian") data.  This
    feature has been added to support conversion of non-dL4 data files.
    
o   Bug fixed: the CHF(600) function returned incorrect values for 
    directories.

o   Bug fixed: the timeout equals -5 option to disable record locking
    on formatted and contiguous files did not work.

May  1 2001 (Release 4.3.1)

o   The DynamicXport runtime support in dL4 has been updated to support the
    current release of DynamicXport.

o   The DynamicXport intrinsic CALLs (DXOPEN, DXCLOSE, DXGET, DXSET, and
    DXURL) require a DynamicXport product license in the SSN before the 
    CALLs can be used.  Without a valid DynamicXport license, the CALLs will 
    generate an error 38.

o   A new open option, "binary=<boolean>", has been implemented in the
    pipe driver.  If a pipe is opened with a "binary=true" option, all data
    written to or read from the pipe will be passed as 8-bit binary 
    characters without any formatting or end-of-line processing.  Example:

        Open #1,"(binary=true)$program"

o   Two new open options have been added to the Windows Page Printer
    driver.  The "LPI=n" option selects a default font size such that
    "n" lines per inch will be printed.  The "CPI=n" option selects a
    default font size such that "n" characters per inch will be printed.
    The two options can be used together.  The following example shows
    a printer script that uses 8 lines per inch, 10 characters per inch,
    with half inch horizontal and vertical margins:

    rem dl4opts=openas=selected page printer,lpi=8,cpi=10,hmargin=36,vmargin=36
    rem
    rem dL4 selected by dialog printer script

o   A new intrinsic CALL, NCRC32(), has been implemented for compatiblity
    with Unibasic 7.  The CALL provides the same functionality as the
    existing CRC32() intrinsic function.  The new CALL has the following
    syntax:

        CALL NCRC32(C, S$ [, O])

    where "C" is a ten digit or larger numeric variable that will receive
    the calculated CRC-32 checksum, "S$" is a string value to be 
    checksummed, and "O" is an optional numeric value containing a CRC-32
    value from a previous calculation.

o   A new MSC() function, MSC(44), has been implemented so that programs
    can determine if the Dynamic Windows system is active.  If Dynamic
    Windows is "on", MSC(44) will return one.  If Dynamic Windows is "off",
    then MSC(44) will return zero.

o   The checksum utility in the tools directory now accepts a "-m" option
    to generate MD5 checksums instead of CRC-32 checksums.

o   Bug fixed: multiple selection list boxes (such as 'WCLIST') did not
    work on Windows 95/98/ME systems if two or more items were selected.

Mar 13 2001 (Release 4.3)

o   Four new intrinsic CALLs have been added to support writing DynamicXport
    applications.  The new CALLs are DXOPEN, DXCLOSE, DXGET, and DXSET
    which are described in the DynamicXport programming documentation.
    DynamicXport is a new middleware product from Dynamic Concepts.

o   A local and private cache for dL4 programs has been implemented to
    improve program load performance, particularly when programs are 
    loaded from remote networked file systems.  The feature can be
    enabled by setting the environment variable DL4LOCALCACHE to the
    size of the desired local cache in bytes.  The cache resides in
    process memory, is not shared with other users, and may increase 
    process size.  Programs in the local cache are identified by the
    absolute path of the program file.  If a program file is modified
    while it is in the local cache, the old version in the local cache
    will continue to be used until the program is flushed from the
    cache by lack of use or a local SAVE command to the file.  To
    effectively use the local cache, programs should be in the first
    program search directory (for example, the first directory in the
    LIBSTRING environment variable).

o   A new driver, "Bidirectional Pipe Command", has been added to
    allow opening bidirectional pipes to an operating system command
    or program.  Using the driver, it is possible to start a command and 
    then both write data/commands to the command and read the results.

o   A new mnemonic, 'WCDEFAULTBTN', has been implemented to create default
    push buttons.  These buttons are identical to those created by the
    'WCBUTTON' mnemonic except that the button is marked as the default
    and will be triggered by the user typing ENTER if the focus is on the
    button or on another non-pushbutton GUI input element.  The arguments
    to the 'WCDEFAULTBTN' mnemonic are identical to those of the 'WCBUTTON'
    mnemonic.  Note: if the 'nWCFOCUS' mnemonic is used to set focus to
    a non-default pushbutton, that button becomes the default.

o   Enhancement: the 'BEGIN' mnemonic can now be sent to GUI edit boxes
    (such as 'WCSTRING') to place the cursor at the start of the current
    text and to select the current text for replacement.  The user can
    tab or otherwise move to a different GUI element to leave the value
    unchanged or type new characters to completely replace the existing
    value.  To send the 'BEGIN' mnemonic to an edit box, the edit box
    must be the currently selected GUI element (via 'nWCSELECT').  The
    following example could be used to initialize the contents of a
    newly created 'WCSTRING' edit box and select the contents for
    replacement:

        Print '4WCSELECT';"Initial Data";'BEGIN';'0WCSELECT';

    The 'n BEGIN' mnemonic can be used to perform the 'BEGIN' function
    on GUI element "n" and also set the input focus to that element:

        Print '4BEGIN';

o   Enhancement: the drop down section of drop down lists ('WCLISTDROP' 
    and 'WCEDITDROP') can now extend below the bottom of the window on 
    which the list is placed.  This makes it possible to place a drop 
    down list near the bottom of a window.  If the drop down section
    extends below the bottom of the screen, the drop down section will
    be displayed above the normal position.

o   Enhancement: the 'WCQUERY' mnemonic can now be used with two numeric
    parameters.  The mnemonic 'm,n WCQUERY' (or PChr$(m,n);'WCQUERY')
    performs a WCQUERY on all GUI elements between m and n inclusive.

o   ESCAPE, ABORT, and function key ('Fn') characters typed in a GUI
    input element (such as 'WCSTRING') are now passed to the parent
    window of the GUI element.  This allows applications to use
    ESCAPE and function keys to trigger special actions in GUI 
    programs.

o   A new mnemonic, 'n WCWHERE', has been implemented to return as 
    input the action 'n' string value of the GUI element currently
    selected as the input focus.  See 'WCACTION' in the dL4 GUI 
    tutorial for details on action strings.

o   "Clicking" on a selected item in a list box ('WCLIST') now 
    unselects the item.

o   The 'UNMARK' mnemonic is now supported for single selection list
    boxes.

o   Behavior change: list boxes ('WCLIST') now occupy the full vertical 
    space assigned to the box.  Previously, the height was truncated 
    to eliminate any partially displayed list items (a list box that was 
    4.5 items high was displayed as 4 items high).  This change makes
    it possible to align the bottoms of list boxes with varying heights.

o   Behavior change: the MODAL style is no longer ignored in child
    windows.  A MODAL child window will disable all GUI input elements 
    and typing in the parent window.  The parent window itself is not 
    otherwise disabled because that would disable the child window.

o   A new option value, 32, has been implemented for all GUI input 
    elements. The new option causes any loss of input focus to be
    reported as an input value change (option 2).

o   Buttons ('WCBUTTON'), check boxes ('WCCHECK'), and radio buttons
    ('WCRADIO') now support multiline labels.  Carriage returns ('CR')
    can be placed in labels to explicitly split lines.

o   The hidden field option, option 16, is now supported in list drop
    boxes ('WCLISTDROP').

o   A new printer mnemonic, 'nLANDSCAPE', has been implemented to
    select landscape mode if "n" is 1 and portrait mode if "n" is 0.
    The mnemonic should only be used at the beginning of a page.

o   New mnemonics 'n,d GRIDENGLISH', 'n,d GRIDMETRIC', and 'n,d GRIDFONT" 
    have been created to provide a higher precision method of setting the
    coordinate grid.  In these new two parameter mnemonics, "n" and "d"
    are the numerator and denominator of a fraction which is passed to the
    mnemonic as a parameter.  Thus the mnemonic string '1000,72 GRIDENGLISH'
    is equivalent to 'x GRIDENGLISH' where "x" is equal to 1000/72.  Since
    'GRIDENGLISH' sets the coordinate grid in 1000ths of an inch, this
    sets the grid to 1/72 inches (points).  These mnemonics are supported
    by both the window and page printer drivers.

o   A new mnemonic 'n LPI' has been implemented to set the number of lines
    per inch when printing to the Page Printer driver.  

o   A new mnemonic 'n CPI' has been implemented to set the number of 
    characters (columns) per inch when printing to the Page Printer driver.  
    A second form, 'n,d CPI' has been implemented to use the fraction "n/d"
    when setting the number of columns per inch.

o   A new mnemonic, 'n FONTCELL', has been implemented to set the font height
    by specifying the line height, rather than the character height.  The
    mnemonic argument is in grid coordinates and is identical to that used
    by 'n FONTSIZE'.

o   A new mnemonic, 'MARGIN', has been implemented to set horizontal
    ('w MARGIN') and vertical ('w,h MARGIN') margins in the Page Printer
    driver.  The arguments to the mnemonic are margins expressed in grid
    coordinate system units.  For example, if the current coordinate grid 
    is tenth inches ('100GRIDENGLISH'), then a half inch left margin can 
    be set by '5MARGIN' or a half inch left margin combined with a one 
    inch top/bottom margin can be set by '5,10MARGIN'.

o   A new open option, "BINARY=<boolean>", has been added to the Page
    Printer drivers.  This option causes all characters printed to a
    printer channel to be sent directly to the printer without any
    processing or translation.  All characters sent in this mode must be
    between 1 and 255 decimal.  This option is intended for applications
    that need complete printer control.  Example:

        Open #1,{"","binary=true"} As "Default Page Printer"

o   A new function, MSC$(8), has been implemented to return the native path 
    separator string.  Under dL4 for Windows, MSC$(8) returns "\".

o   The IOBO mnemonic now accepts either "\377\" or "\177\" as the 
    count terminator.

o   A LEVEL command has been implemented in SCOPE to return the dL4
    revision level and the license number.

o   A SHOW command has been implemented in BASIC to find all lines
    containing a specified variable name.  The command syntax is identical
    to that of the FIND command.

o   The GUI window driver now treats the 'LK' (lock keyboard) and 'UK'
    (unlock keyboard) mnemonics as no-ops rather than reporting an illegal
    character error.

o   Behavior change: if the input focus is on a 'WCBUTTON' button and the
    tab option is enabled on at least one GUI element in the same window,
    then typing ENTER will trigger the button.

o   A new startup option, "-X", has been added to support DynamicXport
    applications.  DynamicXport applications written in dL4 are started 
    with the command "run -X programpath".  This format identifies the 
    program as a DynamicXport application and configures dL4 with 
    necessary options.  The "-X" option disables all terminal translation.

o   A new startup option, "-B", has been added to set the initial I/O
    mode of the standard input and output channels to binary I/O without
    input echo.

o   The intrinsic CALL ENV() has been extended to support runtime
    modification of the SPC(5), SPC(7), and MSC(7) values.  Setting the
    values of the SPC5, SPC7, or MSC7 environment variables will control
    the subsequent values returned by the SPC() and MSC() functions.

o   A new open option has been added to the pipe driver.  The CLOSEWAIT
    option sets the time in seconds that the driver will wait for the child 
    process to exit when the channel is closed.  The option "CLOSEWAIT=0"
    will not wait at all.  The pipe driver does NOT terminate the child 
    process when the CLOSEWAIT period expires; the driver simply closes 
    the channel and leaves the child process running.  Example:

        Open #1,"(closewait=120)$$script.sh"

o   Behavior change: a file specification can now contain more than one
    file attribute specification.  Multiple specifications are
    concatenated before the attributes are processed.  Example:

        Build #1,"<u> [1:40] <00> filename"

o   Behavior change: the 'BG' and 'EG' mnemonics are now ignored by the
    Page Printer driver instead of causing an "illegal character" error.

o   A new utility, MAKEHUGE, has been added to the tools directory to 
    convert Indexed Contiguous or Formatted files to Huge Indexed 
    Contiguous and Huge Formatted files.  This permits the files to 
    grow beyond 2 gigabytes in size.  Note: huge files can be used only
    on Windows NT, Windows 2000, and some Unix systems.

o   A new intrinsic string function, Trim$(), has been added to remove
    both leading and trailing blanks or other whitespace.  Since Trim$()
    is an intrinsic function, a "DECLARE INTRINSIC FUNCTION TRIM$"
    statement is required in order to use the new function.

o   A new intrinsic CALL, FlushAllChannels, has been added to request
    the operating system to write all system buffers to disk for each 
    open channel.  The CALL performs a "CHANNEL #c,DCC_SYNC,1;" on each
    open channel.  Example:

            Declare Intrinsic Sub FlushAllChannels
            Call FlushAllChannels()

o   Operating system file buffers are now flushed whenever a file is
    closed.  This improves file stability if a system is shutdown
    improperly.

o   A new open option, "RTRIM=<boolean>", has been implemented in the
    Full-ISAM drivers.  If the option "RTRIM=TRUE" is used, all 
    trailing spaces are removed when reading fields.  The option is
    case insensitive and an argument of "T" is identical to "TRUE".
    Example:

        Open #1,"(rtrim=t)test.dbf"

o   The GET statement can be used to retrieve the local or remote IP
    addresses associated with a socket.  Example:

        Get #c,-1598;RemoteAddress$
        Get #c,-1599;LocalAddress$

    By using the DUPCHANNEL intrinsic CALL, these operations can also be 
    used on the standard input and output channels if they are open to a 
    socket.

o   Behavior change: the ROPEN statement can now be used to open a 
    directory.  Previously, an "illegal open mode" error was generated.

o   Extension functions have been added to the communications, program,
    and Microsoft SQL Server Full-ISAM drivers to ease customization.
    See driver\wcommext.c, driver\progext.c, and driver\msqlext.c for
    details.

o   Spaces are now allowed in Microsoft SQL Server Full-ISAM field, 
    table, owner, or database names.  Such names must be quoted.

o   The operation "CHANNEL #c,20,1;" has been implemented to 
    flush operating system buffers associated with the file open on 
    channel "c".

o   A new utility, VERINDEX, has been added to the tools directory to 
    verify the index portions of Portable or Universal Indexed Contiguous 
    files.  The utility can detect various forms of index corruption.

o   Bug fixed: a statement with a trailing backslash such as "10 A=1 \" was
    not recognized as a syntax error and sometimes caused a memory
    violation if the program was executed or SAVEd.

o   Bug fixed: radio buttons reported a value change only on the first
    occurrence.

o   Bug fixed: new independent windows were sized using the coordinate
    system of the last accessed window instead of the main window.

o   Bug fixed: 'nWCMARK' did not work after 'CU' was sent to a list box or
    drop down list box.  Also fixed a memory leak when using hidden fields.

o   Bug fixed: GUI option 4, report changed value, treated any gain of 
    focus in a radio button as a changed value.

o   Bug fixed: memory violations sometimes occurred after immediate mode 
    PRINTs of non-existent structure variables.

o   Bug fixed: the command "m DELETE n" caused a memory violation if
    line "m" was greater than line "n".

o   Bug fixed: the 'n WCUNMARK' mnemonic would unselect item "m" in a
    single selection list box if "m" was currently selected, but item
    "n" was not.

o   Bug fixed: tabbing between GUI input elements is now supported in
    child windows and is no longer restricted to the main and independent
    windows.

o   Bug fixed: closing a window and then immediately opening a new
    window caused some output for that new window to be directed to 
    the main window.

o   Bug fixed: GUI elements and child windows were not positioned
    correctly when a window was scrolled from the 0,0 position and
    under some other circumstances.

o   Bug fixed: If GUI input elements with tab options existed in the 
    parent window, it was not possible to enter input in a child window.

o   Bug fixed: the Microsoft SQL Server Full-ISAM driver now detects when
    the maximum number of connections has been exceeded and reports an
    error 82, "too many channels in use".

o   Bug fixed: the Microsoft SQL Server Full-ISAM driver no longer treats
    an option string of "" as a file syntax error.

o   Bug fixed: deallocating a non-existent record with the SEARCH 
    statement decremented the number of records in-use count in a
    Portable Indexed Contiguous file.

o   Bug fixed: single character reads or reads with timeouts from a
    text file or pipe sometimes lost characters.

o   Bug fixed: address violations sometimes occurred when SAVEing a
    program.

o   Bug fixed: entering the debugger or enabling a program trace while in
    a SWAPped program sometimes caused file corruption.

o   Bug fixed: certain types of file corruption in the index portion of an
    Indexed Contiguous file caused applications and dL4 itself to hang.

o   Bug fixed: a parameter mismatch in an EXTERNAL FUNCTION call sometimes 
    caused a memory violation.

o   Bug fixed: outputting a bad mnemonic sequence to the Page Printer
    driver sometimes caused the driver to hang.

o   Bug fixed: printing a mnemonic with a string parameter to the PFILTER
    utility sometimes caused following mnemonics to fail with a bad
    character error.

Aug  1 2000 (Release 4.2)

o   The maximum size of the index portion of Portable and Universal 
    Indexed-Contiguous files has been increased to 256 gigabytes on
    Windows NT or Windows 2000 systems.  The size of the data portion 
    is limited only by the amount of storage space available.  To use
    this feature a file must be created as a "Portable Huge Indexed-
    Contiguous" or "Universal Huge Indexed-Contiguous" file.
    Example:

        Build #1,"[1:40]File" As "Portable Huge Indexed-Contiguous"

o   The "H" option letter ('BUILD #1,"<H>[10:100]file"') can be used to 
    select the "Huge" format when creating a Portable Formatted, 
    Contiguous, or Indexed file.  This option allows a file to grow to
    more than 2 gigabytes in size on Windows NT or Windows 2000 systems.

o   The 'BA', 'EA', 'BO', 'EO', 'AE', and 'AD' mnemonics are now supported
    to direct output to an "auxiliary printer".  When printer output is
    enabled, output will be sent to the printer selected via the "Printer"
    sub-menu of the "Preferences" menu.  That printer can be configured to
    be a specific Windows printer, the default Windows printer, a user
    selected Windows printer, a COMn serial device, or an LPTn printer 
    device.  When sending output to a Windows printer, a document will be
    considered complete and all pages will be printed when auxiliary output 
    is disabled by an 'EA', 'EO', 'AD', or 'XX' mnemonic.  A program should
    not expect to be able to suspend output with 'EA', 'EO', or 'AD' and 
    then later continue output on the same printer page.

o   The 'WS', 'ES', 'SO', and 'SF' mnemonics are now supported to display 
    a status line at the bottom of a window.  The 'WS' mnemonic redirects 
    all output to the status line until an 'ES' mnemonic is output.  The 
    'SO' (status line on) and 'SF' (status line off) mnemonics control 
    whether the status line is visible.  Note: the mnemonics and status 
    line text must be output to the window that will contain the status 
    line.  When using dynamic windows ("WINDOW OPEN"), the "WINDOW OFF" 
    statement or the CALL DUPCHANNEL intrinsic should be used to output 
    status line mnemonics to the main window rather than the current 
    window.

o   The 'WD' and 'NR' mnemonics have been implemented to change the current
    font size to either the default font size or 6 tenths of the default
    font size.  Assuming a default window width of 80 characters, the 'NR'
    mnemonic will set the font and window size to provide a width of 132 
    narrow characters.  Both mnemonics clear the window with the equivalent 
    of a 'CS' mnemonic.

o   A new mnemonic, 'PGMFN' has been defined to control the text sent by
    the 'Fn' function keys.  The mnemonic sequence 
    
        PChr$(n,"text");'PGMFN'

    will program function key 'n' ('Fn') to send the character string 
    "text" as input when pressed.  The 'RF' or 'XX' mnemonics can be used
    to reset all function keys to their original values of 'Fn'.

o   A new mnemonic, 'INVERT' has been defined to invert colors within a 
    specified region.  The mnemonic has the following forms:

        'INVERT'             - Invert colors from the current position 
                               to the end of the current line.
        'n INVERT'           - Invert colors from the current position 
                               for 'n' characters.
        'w,h INVERT'         - Invert colors from the current position 
                               within a rectangle of 'w' characters width 
                               and 'h' characters height.
        'x1,y1,x2,y2 INVERT' - Invert colors within rectangle defined by
                               the points 'x1,y1' and 'x2,y2' of the
                               current coordinate grid.

o   In Windows, the user can exit dL4 by selecting the exit button or
    the "close" action of the system menu.  Exiting dL4 in this manner
    prevents the application from cleaning up any partially written
    transaction.  A new mnemonic, 'ONCLOSE', has been defined to allow 
    applications to control such exits.  The 'ONCLOSE' mnemonic has the 
    following forms:

        PChr$(0,"text");'ONCLOSE'  -  Display "text" within a message
                                      box and give the user a choice
                                      of exiting dL4 or continuing the
                                      application.
        PChr$(1,"text");'ONCLOSE'  -  Display "text" within a message
                                      box and prevent the user from
                                      exiting dL4.
        PChr$(2,"text");'ONCLOSE'  -  Prevent the user from exiting dL4
                                      and treat "text" as input for the
                                      program.
        PChr$(0,"");'ONCLOSE'      -  Disable any previously set ONCLOSE
                                      action.

    Programs using the 'ONCLOSE' mnemonic should output a null action
    ('PChr$(0,"");'ONCLOSE') or an 'XX' mnemonic before exiting to clear
    the ONCLOSE action.  Note: this mnemonic will also be supported by 
    dL4 4.2 for Unix when used with dL4Term 4.2.

o   Scrolling performance of a full window has been improved by 50 to 80
    percent on typical systems.

o   Behavior change: input to any window can now be read from any window.
    For example, if windows are open on channel 1 and channel 2, pressing 
    a button in the window open on channel 1 will create input that can be 
    read on either channel 1 or channel 2.  This change makes it easier for
    programs to use more than one input window at a time.  Note that
    when using multiple windows, all of the GUI elements should have
    unique element numbers even if the elements are in different windows.

o   The "Initial Values" sub-menu of the "Preferences" menu has been
    renamed as the "Window" sub-menu.

o   A new driver class, "Email", has been added to send email.  In this
    release, the driver requires sending email through an SMTP server such 
    as provided by Unix servers or most ISPs.  Non-SMTP mechanisms may be 
    added in the future and should not require any application changes 
    unless SMTP specific options (such as "SERVER=") are used (use the 
    DL4EMAILSERVER registry entry instead).  After opening the driver, a 
    program simply prints text to be emailed to the channel.  Files can be 
    attached and sent as part of the email by using an 'ADD #c;"Filename"' 
    statement.  If the file consists of multiple files, like an Indexed
    Contiguous file, each subfile must be sent with a separate ADD 
    statement.
    
    The path argument to the driver is an email address list.  An email
    address list consists of one or more space separated email addresses.  
    Email address lists are also used in the options such as "TO=" described 
    below.  The driver options parameter ("(xxx)") can be used to pass the 
    following options:

        "TO=addresses"      one or more destination email addresses.  May
                            be used in addition to or instead of placing
                            addresses in the path.

        "BCC=addresses"     one or more "BCC" email addresses.  These are 
                            similar to "CC" addresses, but they are not 
                            included in the email header.

        "CC=addresses"      one or more "CC" email addresses.

        "FROM=addresses"    one or more sender addresses.

        "REPLYTO=addresses" one or more reply addresses.  This option would
                            only be used if the reply address was different
                            from the sender ("FROM=") address.

        "SUBJECT=text"      email title or subject.  The text may be placed
                            in quotation marks if necessary.

        "SERVER=name"       SMTP server name.  Defaults to the value defined
                            in the registry (see below).

        "PORT=n"            SMTP port number.  Defaults to the standard
                            SMTP port.

        "PROTOCOL=name"     Email protocol name.  Only "smtp", the default
                            protocol, is supported by this release.

        "ATTACHAS=name"     File attachment encoding type.  This option must
                            be specified if file attachments will be used.
                            The value of "name" must be either "mime" or 
                            "default" (which is "mime" in this release).

        "TIMEOUT=n"         timeout period in tenth-seconds for communication
                            with the SMTP server.  This option is used to
                            increase the default timeout period and should
                            not be needed.

    A program using the email driver must specify at least one destination
    email address in the path or a "TO=" option.  At least one "FROM="
    email address must be provided.  The SMTP server name must be defined
    via the "SERVER=" option, or in the registry under one of the following 
    values:

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\Environment\dL4EmailServer
    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\Environment\dL4EmailServer

    or as the environment variable "DL4EMAILSERVER".  After all email text
    has been output and all attachments added, the email channel should be
    CLOSEd to actually send the email.  If the channel is CLEARed, the
    driver will attempt to cancel the email.

    Example:

        Open #1,"(From=name@domain,AttachAs=Mime) nobody@dynamic.com" As "Email"
        Print #1;"Test the email driver"
        ! Append the file "Filename" as an attachment
        Add #1;"Filename"
        Close #1

    Please change the "From=" and destination email addresses to your
    own email address before using this example.  

    Note: unlike early beta release versions, the email driver uses native 
    filenames for attachments.

o   A "-u" option has been added to the BASIC DUMP command to produce 
    listings with line numbers even for programs that don't need line
    numbers.

o   A command history has been added to SCOPE so that the up and down
    arrow keys can be used to recall previously typed commands.  The user
    can then repeat or edit the command.

o   The BASIC EDIT command now supports using the up and down arrow keys 
    to select additional lines for editing after entering EDIT mode.

o   The BASIC LOAD command has been extended to load programs from program 
    files as well as source files.

o   A "tools" directory has been added to the standard runtime installation.
    This directory contains the following utilities from the dL4 samples
    package:

        buildfi     - utility to create Full-ISAM files
        buildxf     - utility to create Indexed-Contiguous files
        checksum    - utility to calculate 32-bit CRC file checksums
        convert.prf - sample conversion profile
        pgmcache    - program cache utility
        query       - utility to display file type and characteristics
        term        - utility to display port status or terminate programs

o   A "-t terminaltype" option has been added to "runc.exe" to select
    the terminal definition file.  This option is provided primarily for
    compatibility with a similar option in dL4 for Unix, but might be
    used to select a special terminal definition file for use with CGI
    programming.

o   Behavior change: to increase compatibility with the character oriented
    window driver, independent windows can now be moved using the main
    window coordinate grid.  Independent windows without the "TITL" style
    will no longer have a minimal border.  In dL4 4.1, independent windows
    could only be moved by the user dragging the title bar and a thin line
    was used as a border for windows without the "TITL" style.  Note: most
    applications should use child windows (see below) rather than
    independent windows.

o   Behavior change: The child window open syntax:

    OPEN #c,{"title","style",width,height,parent,column,row} As "Window"

    has been extended so that 'parent', which is normally the channel
    number of the parent window, can be -1 to indicate the main window.
    This feature makes it unnecessary to use the CALL DUPCHANNEL intrinsic
    to assign a channel number to the main window.

o   Behavior change: the 'WCNUMBER' mnemonic now produces an edit box that
    accepts signed floating point numbers rather than just non-negative
    integers.  The numbers must be in the format <sign><digits><"."><digits>
    where the sign and decimal point are optional.  Entering an illegal
    character will be rejected.  Note: the edit box may return a value 
    such as "-", ".", or "-." if the user starts to enter a legal number 
    but never adds the expected digits.

o   A new driver, "TCP Listen Socket", has been added.  The "Listen"
    driver allows a dL4 program to be a server for socket requests.  For
    example, dL4 program S running on ServerA might use the "Listen" 
    driver to open a listening socket on port 9631 of ServerA.  
    Programs on other systems could then open sockets to port 9631 of 
    ServerA to exchange data with program S.

    The "Listen" driver is used by opening a port number using the
    "Listen" driver:

        Open #1,":9631" As "TCP Listen Socket"

    The open will return immediately.  To accept the next queued 
    connection to that port, the program opens a socket using channel 1 
    as the parent socket:

        Open #2,{1} As "Socket"

    This open to channel 2 will not return until another program on the
    local or a remote system opens a socket to port 9631 of the local
    system.  Once the open returns, channel 2 can be used to perform 
    normal socket read and write operations to transfer data from or to
    the client program.  When the transaction is finished, the server
    program closes channel 2 and performs another open against parent
    channel 1 to accept the next queued client request.

    The example program below provides a date and time service on port
    9631.  While the program is running, any telnet utility can be used
    to connect to port 9631 and receive the current date and time.  The
    current date and time will be printed to the client once every ten
    seconds until the client closes the connection.

        Dim I$[100],3%,I
        Open #1,":9631" As "TCP Listen Socket"
        I = 0
        Do
            Open #2,{1} As "Socket"
            I = I + 1
            Do
                Try Print #2;"Session";I;Tim#(0);"\15\\12\"; Else Exit Do
                Try Read #2,-1,-1,100;I$ Else Rem
                If Spc(8) <> 123 Exit Do
            Loop
            Close #2
        Loop

    If multiple clients attempt to open port 9631 at the same time, only 
    one request will be accepted at a time.  The other clients will be 
    queued by the operating system until the current connection on channel
    2 is closed.  The client program will receive an error if the total
    number of queued requests exceeds an operating system defined number
    (usually a small number).  Client programs should be prepared to
    retry opens if the server is busy.

    Normally, a null server name (":9631") should be used to open a 
    listening socket on local system.  The server name can be specified
    to open a listening socket on a specific network interface.

    The "opentime" option can be used to specify a maximum number of 
    seconds to wait when opening a new queued connection:

        Open #2,{1,"opentime=10"} As "Socket"

    A record locked error (error 123) will be generated if the open
    times out.

    Lists of pre-defined TCP port numbers can be found at many web sites
    include www.iana.org.  When writing a "listening" socket program, the
    port number should not conflict with a port number used by a needed or
    common pre-defined service.  In most cases, the port number should be
    greater than 1023 to avoid standard port numbers.

o   A new SYSTEM statement mode has been implemented: SYSTEM 30 executes
    system commands in a hidden window.  This hidden window eliminates
    the temporary command window created by the 'SYSTEM "command"'
    statement.  The new mode syntax is:

        SYSTEM 30,CommandString$
        SYSTEM 30,CommandString$,CommandStatus

    where "CommandString$" is a string literal, variable or expression
    and the optional "CommandStatus" is a numeric variable that receives
    the operating system execution status of the command.

o   A new special output macro can be defined in the "[OutputMacros]"
    section of a terminal or printer definition file.  The "Illegal"
    macro can be used to define a single character to be output whenever
    an illegal output character is output.  Example:

        [OutputMacros]
        Illegal=?

o   Enhancement: the socket driver now supports a "partial=<boolean>"
    option to control whether a read terminates as soon as at least one
    character has been read (default behavior) or waits until the 
    destination variable has been filled ("partial=true" behavior).  
    This option is specified in the option field when opening a socket.
    Example:

        Open #1,"(partial=true)server:servicename" As "Socket"

o   Behavior change: the statement "INPUT TIM -1;String$" when used with 
    "OPTION INPUT TIMEOUT SIGNAL OFF" no longer generates an input timeout 
    error, it simply returns any available input characters into "String$".

o   Behavior change: the Windows printer driver now prints all supplied
    characters before reporting an illegal character error.

o   Two previously optional intrinsic CALLs, GetGlobals() and SetGlobals()
    are now standard CALLs and do not have to be installed using the 
    development kit.

o   Enhancement: on Windows NT and Windows 2000 systems, the standard
    input and output file handles of scopec.exe and runc.exe can now be
    sockets.

o   Enhancement: Unicode character columns in Microsoft SQL Server 7.0 
    tables can now be accessed.  Due to runtime library restrictions, 
    the characters in those Unicode columns must be part of the ISO 8859-1
    character set.

o   Enhancement: the default keyboard configuration now defines the
    shifted function keys as F13 through F24.  For example, pressing the
    "F1" key while holding down the shift key will generate an 'F13'
    character.  This change only effects the default configuration and
    will not add the additional function keys to an existing keyboard
    configuration (set if the Preferences->Keyboard menu item has been
    used).

o   Performance enhancement: the socket drivers now use Winsock 2
    features to improve performance on systems supporting Winsock 2.

o   Beta bug fixed: the email driver would process multiple addresses
    incorrectly.

o   Beta bug fixed: the 'NR' and 'WD' mnemonics did not update the MSC(33) and
    MSC(40) function values (number of columns).

o   Beta bug fixed: text printed to the email driver after adding an
    attachment file corrupted the attachment.

o   Beta bug fixed: CLEARing a channel open to the email driver caused a
    5 minute hang.

o   Beta bug fixed: normal and huge Indexed-Contiguous files could not
    be opened at the same time.

o   Bug fixed: if the debugger was entered when the main window was using
    a grid coordinate system other than '1GRIDFONT', the "?", "WF", "WS",
    and "WH" commands did not work correctly.

o   Bug fixed: using CALL PROGRAMDUMP() after using the debugger
    sometimes caused a memory violation.

o   Bug fixed: duplicate structure definitions (DEF STRUCT statements
    using the same structure name) were not reported as errors.

o   Bug fixed: using 'WD', 'NR', or font mnemonics sometimes caused a 
    resource leak and eventually an error exit from scopew/runw.

o   Bug fixed: if the standard output handle was a socket, scopew/runw
    would sometimes hang.

o   Bug fixed: a socket driver read or write without a timeout sometimes 
    waited forever even after I/O was complete.

o   Bug fixed: writing an empty string ("") to the raw file driver caused
    an error.

o   Bug fixed: FoxPro files created outside of dL4 with duplicate keys
    in a unique index could not have their index file rebuilt by the
    DCC_REBUILDINDEX channel command.

o   Bug fixed: the intrinsic CALL DateToJulian() did not work in modes
    2 and 6.  In addition, the CALL required a longer string than
    necessary in 2 digit year modes and permitted too short a string in
    4 digit year modes.

o   Bug fixed: if protected characters and blinking characters were used
    together, the blinking area was not always cleared by the 'CS', 'XX',
    or other "clear" mnemonics.

o   Bug fixed: identity fields in Microsoft SQL tables are now ignored
    when performing a write to the table.

o   Bug fixed: indices with identify fields are not used as the preferred
    unique index.  This eliminates a "unable to re-read record" error
    after updating a record.

o   Bug fixed: a selection in a list box or drop-down list box is
    reported immediately if the value changed option is used.

o   Bug fixed: GUI elements such as buttons sometimes returned incorrect
    values when selected or changed.

o   Bug fixed: if the table owner was specified when opening a table with
    the Microsoft SQL Full-ISAM driver, the open failed.

o   Bug fixed: selecting a value from a drop list of a GUI element was
    not reported when requested by the WCACTION mnemonic.

o   Bug fixed: if a FoxPro Full-ISAM file containing duplicate keys with
    trailing blanks was re-indexed using a third-party tool, a memory
    violation could occur when adding another duplicate key with trailing
    blanks.  This problem was most likely to occur when the keys were
    completely blank.

o   Bug fixed: opening a network printer without using the printer
    driver ('OPEN #1,"\\server\printer"') returned a system error rather
    than "No such driver".

o   Bug fixed: a terminal or printer definition file that didn't define
    any characters within the "[OutputMacros]" section could cause a memory
    fault during output.

o   Bug fixed: the statement 'CHAIN ""' will successfully exit a program
    even if "OPTION CHAIN FAILURE IS ERROR" is used.

o   Bug fixed: using a font size larger than the window caused a memory
    violation.

o   Bug fixed: typing a RETURN while a paste area was selected and a
    input was active caused a memory violation.

o   Bug fixed: using "Copy" from the "Edit" menu sometimes caused an 
    unnecessary and large increase in memory usage.

o   Bug fixed: a memory violation could occur if a SAVE command was 
    executed after an immediate mode statement.

Mar 10 2000 (Release 4.1.1)

o   Release 4.1.1 is a maintenance release that corrects various 
    problems and adds two new intrinsic CALLs to access the Windows
    registry.

o   Two new intrinsic CALLs, GetRegistry() and PutRegistry(), have
    been added to provide access to the Windows registry.

    BASIC syntax:

        Call GetRegistry(KeyValuePath$, Value)
        Call PutRegistry(KeyValuePath$, Value)

        where:

            "KeyValuePath$" is a string variable or expression that 
            specifies the registry key and value name to be read or
            written.  Backslashes must be used to separate each key
            name in the path and the value name.  The first key name
            must be one of the following special keys:

                "HKLM" or "Hkey_Local_Machine"
                "HKCU" or "Hkey_Current_User"

            "Value" is a numeric, string, or binary variable into which a
            value will be read or from which the value will be written.  
            The type of "Value" must match the registry value (numeric for 
            DWORD values, string for REG_SZ values, and binary for binary 
            values).

    Example:

        Declare Intrinsic Sub GetRegistry, PutRegistry
        ! Write a string value into the registry current user key
        Dim KeyVal$[100], NewId$[100], Id$[100]
        KeyVal$ = "HKCU\\Software\\CompanyName\\Application\\UserId"
        NewId$ = "John Parker"
        Call PutRegistry(KeyVal$, NewId$)
        ! Read the value that was just written
        Call GetRegistry(KeyVal$, Id$)
        Print Id$

o   The 'MH' (Move Home) mnemonic is now supported in edit boxes to move the
    current position to the beginning of the text in the box.

o   Behavior change: the intrinsic CALLs DateToJulian(), FormatDate(),
    JulianToDate(), and VerifyDate() now ignore spaces preceding numeric
    values rather than requiring zero filled values.

o   Bug fixed: the input focus was not moved to the current window if
    binary or activate-on-control-character input mode was used.

o   Bug fixed: the ProgramDump() intrinsic CALL did not report the current
    position correctly.

o   Bug fixed: scroll bars weren't enabled or disabled at appropriate times
    in multiline edit boxes ('WCEDIT' and 'WCTEXT' mnemonics).

o   Bug fixed: line, rectangle, and ellipse drawing could cross window
    boundaries.

o   Bug fixed: a bad character error occurred when a WINDOW OPEN statement 
    was executed while using the character window driver rather than the
    standard GUI window driver.

o   Bug fixed: the MODIFY statement could apply, but not remove, read-only
    protection on files in Windows 95/98 systems.

o   Bug fixed: opening a directory path that ended with a backslash
    character failed on Windows 95/98 systems.

Nov 17 1999 (Release 4.1)

o   A new Windows Terminal driver has been implemented to support 
    graphical user interface programming.  This driver will be the
    default window driver in dL4 4.1.  The character oriented driver
    used in previous releases can be used by setting the runtime
    parameter WINDOWDEFAULTS to the string value "type=char".

o   The new Windows Terminal driver supports graphical user interface 
    programming using the following new mnemonics:

        'WCBUTTON'     - Create button
        'WCCHECK'      - Create check box
        'WCRADIO'      - Create radio button
        'WCNUMBER'     - Create numeric input box
        'WCSTRING'     - Create character input box
        'WCPRIVATE'    - Create character hidden input box
        'WCLABEL'      - Create a label for an input box
        'WCTEXT'       - Create multi-line character display box
        'WCMEMO'       - Create multi-line character input box
        'WCLIST'       - Create selection list box
        'WCEDITLIST'   - Create editable selection list box
        'WCLISTDROP'   - Create drop down selection list
        'WCEDITDROP'   - Create drop down editable list box
        'WCMENU'       - Create menu
        'WCMENUACTION' - Create menu action item
        'WCMENUCHECK'  - Create menu check box item
        'WCMENURADIO'  - Create menu radio button item
        'WCMENUSEP'    - Create menu separator
        'WCENDMENU'    - End menu or sub-menu definition
        'WCGROUP'      - Group graphical elements 
        'WCSELECT'     - Select current graphical element
        'WCENABLE'     - Enable user input/selection to/of element
        'WCDISABLE'    - Disable user input/selection to/of element
        'WCQUERY'      - Request graphical element to send value
        'WCDELETE'     - Delete a graphical element
        'WCACTION'     - Change action performed by input element
        'WCFOCUS'      - Set current focus to selected element
        'WCMARK'       - Mark or select item
        'WCUNMARK'     - Unmark or unselect item
        'WCSUBMENU'    - Create submenu
        'WCSETFONT'    - Set font for controls

    Detailed documentation and example programs for these mnemonics can
    be found in the dL4 4.1 GUI Tutorial.  The tutorial can be downloaded
    from www.dynamic.com.

o   The Windows Terminal driver improves the appearance of dL4 applications 
    by creating all dL4 windows as separate operating system generated 
    windows.  Independent windows opened on separate channels (as in the
    statement , 'OPEN #1,{"Title","Style",w,h} As "Window"') have standard 
    title bars and can be moved independently of the main window.  Child 
    windows, such as those created by the WINDOW OPEN statement, are 
    created within the parent window and use optional dialog style borders.
    All dL4 windows support GUI programming mnemonics, mixing of multiple 
    fonts or font sizes, and enhanced line drawing.

o   The new Windows Terminal driver implements an additional window style,
    "MODAL".  A "MODAL" window disables the main window and any previously
    created modal window so that they can't be selected by the user.  The
    user is thus required to work in the modal window until the window
    is closed by the application.  When the modal window is closed, the
    previously active modal window is enabled or, if none, the main window 
    is enabled.  The "MODAL" style is ignored if applied to a child window 
    (any window created with a parent channel specified or by the WINDOW 
    OPEN statement).

    Example:

        OPEN #1,{"Help","TITL,SCRL,WRAP,MODAL",40,10} As "Window"

o   The new Windows Terminal driver implements an additional window style,
    "DIALOG".  The "DIALOG" style creates a window that defaults to using 
    the standard system dialog colors.  A non-child window using the 
    "DIALOG" style will also be modal.

    Example:

        OPEN #1,{"New Account","TITL,DIALOG",40,10} As "Window"

o   The 'FONTCOLOR', 'BACKCOLOR', and 'PENCOLOR' mnemonics have been
    enhanced to accept two special color codes in addition to RGB color
    values.  Code -1 selects the standard system text color for dialogs.
    Code -2 selects the standard system background color for dialogs.
    For example, printing '-1FONTCOLOR' would select the system dialog
    text color as the current font color.  These special color codes can
    be used to match the dialog color scheme selected by the user.

o   Two new mnemonics, 'BACTFN' and 'EACTFN', have been implemented to 
    enable or disable activate-on-function-key input.  When activate-on-
    function-key mode is enabled, an INPUT (or any read) from a terminal
    or window will be terminated by typing any function key or the normal
    "enter" keys.  A function key is any keyboard sequence such as 'F4'
    or 'PAGE DOWN' that generates a mnemonic character as input data.
    Function keys such as 'INSERT' or "right arrow" that are used as
    edit control keys will not terminate input in this mode.  The program
    can determine what character terminated an INPUT statement by using
    the KEY clause.  Example:

        Print 'BACTFN';
        Input Key TermChar$;"Prompt: "Response$
        Print 'EACTFN';
        If TermChar$ = 'F9' Goto DisplayHelp
        If TermChar$ = 'MU' Goto EditHistory

o   The coordinate grid in a window can now be changed from the default
    character grid to fractions of a character, inch, or millimeter.  The
    'GRIDFONT', 'GRIDENGLISH', and 'GRIDMETRIC' mnemonics are used to 
    define the current coordinate grid.  Please see the dL4 3.2 printer
    description below for a detailed description of these mnemonics.  The
    current grid definition is used for column and row values returned
    by the MSC() function.  Note that a screen inch or millimeter may not
    match an actual inch or millimeter.  Each dL4 window has a separate
    coordinate grid definition.

o   Multiple fonts and font sizes can be mixed in a window using the
    'FONTFACE' and 'FONTSIZE' mnemonics.  Please see the dL4 3.2 printer
    description below for a detailed description of these mnemonics.  Each
    dL4 window has a separate current font definition.

o   The LINE statement and related mnemonics can now be used to draw lines 
    at any angle in a window.  Previous versions of dL4 were restricted to
    horizontal or vertical lines.

o   The 'ELLIPSE' mnemonic can be used in a window to draw an ellipse
    bounded by a specified rectangle.  For example, if the coordinate
    grid was defined in tenths of an inch ('100GRIDENGLISH'), the string
    '40,20,60,40 ELLIPSE' would draw a 2.0 inch circle centered at 5 inches
    from left and 3 inches down on the screen.

o   The 'PENWEIGHT' mnemonic can be used to set the thickness of lines 
    drawn in a window.  For example, using a one tenth character coordinate 
    grid ('10GRIDFONT'), the string '2PENWEIGHT' would make the line width
    equal to one fifth of the character height.  Each dL4 window has a 
    separate current pen weight definition.

o   The 'PENSTYLE' mnemonic can be used to set the style of lines drawn in 
    a window.  A mnemonic argument of 0 (the default) selects solid lines,
    1 selects dashed lines, and 2 selects dotted lines.  As an example,
    printing '1PENSTYLE' selects dashed lines.  Each dL4 window has a 
    separate current pen style definition.
    
o   Spaces can now be used in filenames and directory paths.  Such 
    filenames and paths must be enclosed in quotes.  Examples:

        save "program name with spaces"
        OPEN #1,"''Filename with Spaces''"

    Note that quotation marks in dL4 string constants are represented
    by two consecutive single quotes.  Quoted filenames are supported by 
    all statements, all commands, the LIBSTRING runtime parameter, and the 
    LUMAP runtime parameter.

o   A new intrinsic function ENCFNM$() has been added to dL4 to add
    quotation marks to a filename if required. The function can be
    invoked with either one or two string arguments.  With two arguments,
    the first argument will be treated as a directory prefix to be added 
    to the second filename argument.

o   Portable Formatted or Portable Contiguous files larger than 2 gigabytes
    in size can now be created on Windows NT systems.  Such files are built 
    using the BUILD AS option to specify the "Portable Huge Formatted", 
    "Portable Huge Contiguous", "Universal Huge Formatted", or "Universal 
    Huge Contiguous" drivers.  These are new file types using formatted or 
    contiguous file behavior.  "Huge" Indexed files will be supported in a 
    future release of dL4.

    Example:

        Build #1,"[1:200]Filename" As "Portable Huge Contiguous"

    To share huge files across a network, both the file server and the client 
    systems must support large files.  Note: release 6 of UniBasic does not
    support "Universal Huge" files.

o   The "U" option letter ('BUILD #1,"<U>[10:100]file"') can be used to 
    select the "Universal" format when creating a Portable Formatted, 
    Contiguous, or Indexed file.

o   A TCP/IP socket driver has been implemented.  A connection can be
    created using an OPEN statement similar to:

        OPEN #c,"system:port" As "Socket"

    where "system" is a network system name or IP address (xx.xx.xx.xx)
    and "port" is a service name or port number.  Character and binary
    data can be read or written.  The following example program reads
    the current date and time from a Unix host system:

        10 Dim L$[100]
        20 Open #1,"unixhostname:daytime" As "Socket"
        30 Read #1;L$
        40 Close #1
        50 Print L$

o   An OPTION DEFAULT statement has been added to dL4 to set options for 
    all program units in a program module (file).

o   A new option, "DIALECT BITS", has been added to select the standard
    BITS options.  The statement "OPTION DIALECT BITS" is equivalent to
    the following group of option statements:

        OPTION FILE ACCESS RAW,FILE UNIT IS BYTES,DISPLAY AUTO LF OFF
        OPTION CHAIN FAILURE IS ERROR,CLOSE FAILURE IS IGNORED
        OPTION IF BY STATEMENTS,INPUT TIMEOUT SIGNAL OFF,STRINGS RAW
        OPTION OPEN AUTO CLOSE ON,RETURN BY LINES

    Note that the arithmetic option, "BITS DECIMAL", is not set.  Two
    additional options, "DIALECT IRIS" and "DIALECT STANDARD", have been
    added to select the "IRIS SUBSCRIPTS ON" or default options.

o   A new arithmetic option, "BITS DECIMAL", has been added to select
    BITS numeric types.  Note that BITS numeric types are not portable.

o   A new option, "AUTO DIM OFF", has been added to aid in detecting 
    misspelled variable names.  When a program that uses "OPTION AUTO DIM
    OFF" is SAVEd, error messages will be generated for each variable
    that is not declared in a DIM statement, COM statement, CHAIN READ
    statement, or parameter list.  A "-u" option has been added to the
    SCOPE CHECK command and LOADSAVE utility to detect undeclared 
    variables in program that do not use the "AUTO DIM OFF" option.

o   The OPTION FLUSH AFTER STATEMENT ON option causes all write statements
    to flush the record buffer even if the statement does not unlock the
    current record.  This option provides compatibility with programs that
    use ROPEN to read locked records and expect those records to contain
    updates that are currently in progress.  This record flushing option
    is implemented for Formatted, Indexed Contiguous, and Full-ISAM files.
    Any driver that does not implement the DCC_SYNC operation will
    silently ignore this option.  This option should only be used when
    necessary for compatibility with existing programs.

o   The OPTION RECORD LOCK TIMEOUT N option sets the default timeout period
    for file and database drivers.  The number value N is the number of
    tenth seconds to wait before reporting a record lock error.  The value
    of N must be between -1 (default, wait forever) and 36000 inclusive.
    This option should be used in converted programs that used the UniBasic
    LOCKRETRY feature.  The option is supported by the Formatted, Indexed
    Contiguous, and Full-ISAM file drivers.  Example:

        Option Record Lock Timeout 100
        Dim S$[40]
        Open #1,"File"
        Read #1,3;S$  ! timeout not specified, will wait up to 10 seconds

o   The SYSTEM 28 statement has been extended to search a program defined
    application registry key for string values if those values are not 
    in the environment.  The application registry key is searched under 
    HKEY_CURRENT_USER\Software and then HKEY_LOCAL_MACHINE\Software.  The 
    statement SYSTEM 29 is used to set the current application registry key.  
    For example, the statements

        SYSTEM 29,"SupplierName\\AppName"
        V$ = "Parameter"
        SYSTEM 28,V$

    would attempt to read the string value "Parameter" from the environment
    and then, if not found, the following registry locations:
    
        HKEY_CURRENT_USER\Software\SupplierName\AppName\Parameter
        HKEY_LOCAL_MACHINE\Software\SupplierName\AppName\Parameter

    Note that SYSTEM 28 does not access the registry unless SYSTEM 29 has
    been used to define a registry key.  This mechanism provides a portable
    mechanism to access application parameters similar to that used for
    dL4 runtime parameters.

o   The command "RETURN" has been added to the debugger.  This command
    causes execution to continue until the current procedure exits.

o   The command "<linenumber> GO" can now be used in the debugger to
    continue execution at a specific line.  The line must be part of the
    current procedure.

o   A DCC_SYNC command has been implemented in the Portable Formatted
    driver to flush the record buffer without releasing the current 
    record lock.  A DCC_SYNC command can be issued by a user program via 
    the CHANNEL statement ("Channel 20,#c;").

o   The SAVE file revision has been changed from 2.8 to 2.11 in order to
    support new statements in dL4 4.1.  Full upward compatibility is 
    provided, so program files created by earlier versions of dL4 can 
    still be used.  Programs created by this release of dL4 cannot be 
    used by earlier releases of dL4.

o   The maximize button of the main window now enlarges the window to
    the size of the canvas.

o   If installed from an administrator account of a Windows NT system,
    dL4 will be created as a common program group.
    
o   Behavior change: a CANCEL command is now automatically performed if 
    required to perform an edit, RENUMBER, or LABEL command.  A warning 
    message is printed to inform the user that the program context has
    been deleted.  Previous versions of dL4 simply displayed an error 
    message and required the user to explicitly CANCEL the program.

o   Behavior change: the KILL statement and the SCOPE KILL command now
    delete unsupported file types as raw files rather than returning an
    error.  

o   Behavior change: the background window created by a WINDOW ON or
    WINDOW OPEN statement is forced behind all other windows including
    those opened on channels (this is a change only for non-windowed
    terminals: dL4 for Windows, dL4Term, and "[Settings] StartupInWindow"
    terminals always followed this rule).

o   Three new drivers have been added to dL4 to create Universal Indexed
    Contiguous and Universal Formatted files.  These drivers are
    variants of the Portable file drivers with character set, numeric
    maps, and other options set to match the format of Universal
    files.  New driver names:

        "Universal Indexed-Contiguous"
        "Universal Formatted"
        "Universal Contiguous"

o   The ERRSET, ERRSTM, ESCSET, ESCSTM, INTSET, and related statements
    can now be used in external procedures.

o   Two new mnemonics 'LITNUL' and 'LITCR' have been defined.  These
    mnemonics, if defined in a terminal or printer definition file, can be
    used to output 0x0000 and 0x000D characters without translation.

o   A new mnemonic, 'EUROSIGN', has been defined to represent the Unicode
    Euro currency character 0x20AC.

o   The Portable Indexed File and Universal Index File drivers now allow
    opening files created with an index block size of up to 2048 bytes
    (ISAMSECT equal to 16).  A new runtime parameter, ISAMSECT, can be
    used to specify the index block size of newly created files as a 
    multiple of 128 bytes.  For example, an ISAMSECT value of 16 would
    cause new indexed files to use an index block size of 2048 bytes (16
    times 128 bytes).  The default index block size is unchanged and has
    a value of 1024 bytes (equivalent to an ISAMSECT value of 8). The new
    ISAMMAXSECT runtime parameter can be similarly used to change the
    maximum openable index block size of 2048 bytes to any multiple of 128.
    The default index block size should be adequate for all uses, but, if a
    different value is used, a power of 2 (4, 8, 16, 32, ...) is 
    recommended.

o   Two new open options have been added to the Windows printer driver.
    The LANDSCAPE and PORTRAIT options, which accept a boolean value, are 
    used to specify page orientation.  The value will override the printer
    default or user selected orientation.  The options are ignored if the
    Windows printer driver does not support selection of orientation.  

    SELECTLP.BAT modified to request landscape orientation:

    rem dl4opts=openas=selected page printer,landscape=true
    rem
    rem dL4 selected by dialog printer script modified to request
    rem landscape orientation

    SELECTLP.BAT modified to request portrait orientation:

    rem dl4opts=openas=selected page printer,portrait=true
    rem
    rem dL4 selected by dialog printer script modified to request
    rem portrait orientation

o   The WIDTHI, WIDTHM, LENGTHI, LENGTHM, and FORMCODE options can now
    be used with all versions of the page printer driver.  Note that the
    options will have no effect unless they are supported by the Windows
    operating system printer driver.

o   The "Page Printer" driver now supports the graphics characters ('Gn')
    when using standard Windows 95 fonts (the Windows NT fonts always 
    supported graphics).

o   In the "Preferences->Font" dialog, the BOLD style can be selected as
    the standard font.  Using the BOLD style as the default font may make 
    bold characters ('BBOLD') identical to non-bold characters.

o   Behavior change: the READRECORD and WRITERECORD statements now obey
    the FILE ACCESS RAW option.

o   Beta behavior change: creating a graphical element (for example, 
    using 'WCBUTTON') with the same element number as an existing element
    now overwrites the old element rather than returning an error code.
    Overwriting any part of a menu will cause the entire menu to be
    deleted.

o   Beta behavior change: the 'XX' mnemonic now deletes all graphical
    elements on a window including menus.

o   Fix bug: the Microsoft SQL Full-ISAM driver updated incorrect rows
    if a table had a clustered index and at least one non-unique index.

o   Fix bug: PCHR$() ignored any parameters preceding a string value.

o   Fix bug: the LOADSAVE "-l" OSN option ignored illegal OSN indices and, 
    on some platforms, caused memory violations when valid OSN indices
    were specified.  Note that the "-l" option uses an OSN index and not
    an actual OSN number.

o   Fix bug: the printer driver incorrectly printed graphic characters 
    with repeat counts ('5GH').

o   Beta bug fixed: the socket driver now translates numeric IP addresses
    without first attempting a name lookup.

o   Beta bug fixed: the socket driver reported some open errors incorrectly
    as BE_SYSERRNO.

o   Beta bug fixed: binary input ('IOBI') did not work on non-dL4Term
    terminals.

o   Beta bug fixed: output of a character with more parameters than the
    maximum number of supported parameters sometimes caused a memory
    fault.

o   Beta bug fixed: the root window was always sized to the canvas rather
    than window size.

o   Beta bug fixed: blinking text on a parent window was visible in any
    overlapping child window.

o   Beta bug fixed: repeat counts ('5GH') were ignored when used with
    printable characters.

Jun 18 1999 (Maintenance release 3.2.1)

o   Release 3.2.1 is a maintenance release that corrects a problem in
    the Windows printer driver and adds some additional printer open
    options.

o   A bug in the Windows printer driver that caused the font size and
    other font characteristics to return to their default values after
    each new page has been fixed.

o   Five new open options have been added to the Windows printer driver.
    The WIDTHI, WIDTHM, LENGTHI, and LENGTHM options can be used to 
    specify the page length in inches or millimeters.  The FORMCODE
    option can be used to specify a numeric page size form code. The
    effects of these options vary depending on the Windows printer driver
    used for output.  The options should not be used unless necessary
    and values should be chosen to match forms supported by the target
    printer or printers.  These options can only be used with the Windows
    default or user selected printer driver.

    SELECTLP.BAT modified to request legal form paper:

    rem dl4opts=openas=selected page printer,widthi=8.5,lengthi=14
    rem
    rem dL4 selected by dialog printer script modified to request
    rem use of 8.5 inch wide by 14 inch long legal forms.

    SELECTLP.BAT modified to request 14 7/8 by 11 paper:

    rem dl4opts=openas=selected page printer,formcode=39
    rem
    rem dL4 selected by dialog printer script modified to request
    rem use of 14 7/8 inch wide by 11 inch long fanfold forms.

    Common page size codes for use with the FORMCODE option:

         1    Letter 8 1/2 x 11 in
         2    Letter Small 8 1/2 x 11 in
         3    Tabloid 11 x 17 in
         4    Ledger 17 x 11 in
         5    Legal 8 1/2 x 14 in
         6    Statement 5 1/2 x 8 1/2 in
         7    Executive 7 1/4 x 10 1/2 in
         39   US Std Fanfold 14 7/8 x 11 in


Jan 26 1999 (Release 3.2)

o   The new page printer driver makes it possible to output to any
    Windows printer.  The driver can be opened to a specific printer
    name, to the system default printer, or, via a dialog box, to a 
    user selected printer.  Because Windows is performing all low
    level formatting, the driver does not require any device specific
    configuration such as a printer definition file.  The printer can
    even be a fax service if a Microsoft or third party fax driver
    has been installed as a printer.

    The page printer driver uses a page oriented rather than line
    oriented output model.  Programs can use cursor positioning ("@x,y") 
    to output anywhere on the current page.  The page is not printed
    until a line scrolls off the bottom of the page, an 'FF' or 'CS' 
    mnemonic is output, or the driver is closed.

    Both forms ("@x;" and "@x,y;") of absolute cursor positioning use
    grid units.  The default grid is the traditional character row and
    column, but it can also be set to be in inches or millimeters.  The
    grid definition is controlled by the 'GRIDENGLISH', 'GRIDMETRIC', 
    and 'GRIDFONT' mnemonics.  Each of these mnemonics take a single
    numeric parameter that determines the resolution of the grid.  
    Column zero and row zero of the grid are always defined to be the
    upper left corner of the printable area of the page (the printable
    area does not include any unprintable margin space).

        'GRIDENGLISH'   Set the coordinate grid to thousandths of an
                        inch times the parameter ('nGRIDENGLISH') from
                        the upper left corner.  The mnemonic string
                        '100GRIDENGLISH' sets the grid to tenths of an
                        inch and so the cursor position "@35,51" would
                        position to a point 3.5 inches to the
                        right and 5.1 inches down from the upper left 
                        corner.

        'GRIDMETRIC'    Set the coordinate grid to hundredths of a 
                        millimeter times the parameter ('nGRIDMETRIC')
                        from the upper left corner.  The mnemonic
                        string '1000GRIDMETRIC' sets the grid to
                        centimeters and so the cursor position "@6,10"
                        would position to a point 6 centimeters to the
                        right and 10 centimeters down from the upper
                        left corner.

        'GRIDFONT'      Set the coordinate grid to the line height and
                        average character width of the current font
                        divided by the parameter ('nGRIDFONT') from
                        the upper left corner.  The mnemonic string
                        "10GRIDFONT" sets the grid to tenths of the 
                        line height and character width.  The cursor
                        position "@105,75" would position to 10.5
                        columns to the right and 7.5 lines down from
                        the upper left corner.  Note that the grid is
                        based on the current font and will not change
                        if the font size is changed unless another
                        'GRIDFONT" mnemonic is output.  When using
                        variable width fonts, the column size is based
                        on the average character width.

    The current font can be changed by using the 'FONTFACE' mnemonic.
    This mnemonic has a single string parameter which is the font
    name such as "Courier" or "Helvetica".  A mnemonic string parameter
    is generated by using the PCHR$() function with a string argument.
    The font size is controlled by the 'FONTSIZE' mnemonic which has
    a numeric argument specifying the size in grid units.  Assuming
    the grid is defined in characters (the default), then the 
    statement:

        PRINT #1;PChr$("Helvetica");'Fontface 3Fontsize';

    would select "Helvetica" as the current font sized at three times 
    the row height for the printer on channel 1.  If the printer does 
    not support "Helvetica", an error may occur, but usually the 
    Windows printer driver will choose a substitute font.  Character
    sizing is approximate and determined by Windows algorithms.

    The font determines not only the appearance of characters, but also
    which characters can be printed and how they are positioned.  Most
    Windows fonts are of variable pitch and so different characters will
    have different widths.  If characters, particularly spaces, are used
    for exact positioning, then a fixed pitch font should be used.

        'FONTFACE'      Set the font to the specified font name.  The
                        font name must be specified as a string 
                        parameter using the PCHR$() function as in the
                        following statement:

                            PRINT #1;PCHR$("Times");'FONTFACE'


        'FONTSIZE'      Set the font size to the parameter ('nFONTSIZE')
                        times the grid height unit.


    The printer driver supports drawing lines and rectangles.  All
    drawing is performed using the current "pen" whose width and color
    is set by the 'PENWEIGHT' and 'PENCOLOR' mnemonics.  The example
    below draws a three inch by four inch rectangle with a line drawn
    between the upper left and lower right corners:

        ! Select a tenth inch grid
        Print #1;'100GridEnglish';
        ! Set the pen color to blue with a width of .2 inches
        Print #1;'255PenColor 2PenWeight';
        ! Draw 3 by 4 inch rectangle
        Box #1;@10,10;To @50,40; ! or Print #1;'10,10,50,40Rect';
        ! Draw a line between the corners
        Line #1;@10,10;To @50,40;! or Print #1;@10,10;'50,40LineTo';

        'PENCOLOR'      Set the pen color to the parameter ('rPENCOLOR') 
                        where the parameter is an RGB color value.

        'PENWEIGHT'     Set the pen width to the parameter ('nPENWEIGHT')
                        times the grid unit.

        'LINETO'        Draw a line using the current pen using the
                        current position as one point and the specified
                        coordinates ('x,yLINETO') as the ending point.

        'RECTTO'        Draw a rectangle using the current pen using the
                        current position as one corner and the specified
                        coordinates ('x,yRECTTO') as the opposite corner.

        'RECT'          Draw a rectangle using the current pen and the
                        specified coordinates ('x1,y1,x2,y2RECT').

        'ELLIPSE'       Draw an ellipse using the current pen to fit the
                        rectangle defined by the specified coordinates
                        ('x1,y1,x2,y2ELLIPSE').

    The following mnemonics are used to change the current position 
    on the page or print the current page:

        "@x;"           Position to grid column x
        "@x,y;"         Position to grid column x and grid row y
        'MH'            Move to upper left corner of page
        'MR'            Move right one average character width
        'ML'            Move left one average character width
        'BS'            Move left one average character width
        'RI'            Move up one line 
        'BK'            Move to column zero
        'CR'            Move to column zero of the next line
        'LF'            Move to current column on the next line
        'MD'            Move to current column on the next line
        'FF'            Print current page and move to the upper left 
                        corner of the next page.
        'CS'            Print current page and move to the upper left 
                        corner of the next page.

    The following mnemonics are used to change attributes of the 
    current font:

        'BI'            Print in italic mode
        'EI'            End italic mode
        'BSO'           Print in strike out mode
        'ESO'           End strike out mode
        'BU'            Print in underline mode
        'EU'            End underline mode
        'BBOLD'         Print in bold mode
        'EBOLD'         End bold mode
        'BSUB'          Print in subscript position relative to the
                        current font height
        'ESUB'          End subscript mode
        'BSUP'          Print in superscript position relative to the
                        current font height
        'ESUP'          End superscript mode
        'BC'            Print in compressed mode (.6 times default
                        font size)
        'EC'            End compressed mode
        'BX'            Print in expanded print mode (twice default
                        font size)
        'EX'            End expanded print mode

    The following mnemonics are used to change the current font and 
    background colors:

        'GN'            Set font color to green
        'RE'            Set font color to red
        'YE'            Set font color to yellow
        'BL'            Set font color to blue
        'MA'            Set font color to magenta
        'CY'            Set font color to cyan
        'WH'            Set font color to white
        'BLACK'         Set font color to black
        'FONTCOLOR'     Set the font color to the parameter ('rFONTSIZE')
                        where the parameter is an RGB color value.
        'BACKCOLOR'     Set the background color to the parameter 
                        ('rBACKCOLOR') where the parameter is an RGB color 
                        value.
        'RESETCOLOR'    Reset font, pen, and background color to default

    By default, the printer driver uses the "Courier New" font with a
    size of 1/6 inch.  The default font and size can be changed by using
    the "FONT=name" and "FONTSIZE=size_in_points" open options.  The 
    following OPEN statement sets the default font to "Arial Narrow" with 
    a size of 10/72 inches:

        OPEN #1,{"","FONT=Arial Narrow,FONTSIZE=10"} As "Default Page Printer"

    The printer driver can be opened to a specific Windows printer name,
    to the default Windows printer, or to a printer selected by the user
    in a dialog box.  To open a specific printer, use the "Page Printer"
    driver:

        OPEN #1,{"Printer Name","options") As "Page Printer"

    To open the default Windows printer, use the "Default Page Printer"
    driver:

        OPEN #1,{"","options") As "Default Page Printer"

    To allow the user to select the printer in a dialog box, use the
    "Selected Page Printer" driver:

        OPEN #1,{"","options") As "Selected Page Printer"

    A standard Windows printer selection dialog box will displayed so
    that the user can select a printer.  If the user cancels the
    dialog, a "File not found" will occur.  In all three drivers, a 
    "File not found" error will be generated if the printer does not 
    exist.

o   The Page Printer driver provides three special GET statement commands
    to retrieve the current page size and margins.  All three commands
    return a value of -1 for unknown values.  The statement

        GET #c,-1399;Width,Height

    returns the width and height of the printable area of a page in the
    units of the current coordinate grid.
    
    The statement

        GET #c,-1398;Left,Right

    returns the left and right margins of the page in the units of the
    current coordinate grid.
    
    The statement

        GET #c,-1397;Top,Bottom

    returns the top and bottom margins of the page in the units of the
    current coordinate grid (see the GRIDENGLISH, GRIDMETRIC, and GRIDFONT 
    mnemonics in the Page Printer driver description above).  These
    commands can only be used on a channel open to a Page Printer driver.

o   Two new channel functions, CHF(1200+c) and CHF(1300+c), have been 
    defined to return the current column and row positions.  The values
    are returned in the units of the current coordinate grid (see the 
    GRIDENGLISH, GRIDMETRIC, and GRIDFONT mnemonics in the Page Printer 
    driver description above).

o   A new driver, "Serial Terminal", has been added to allow programs to
    open serial communication devices to a Window class driver.  Using this 
    driver, input and output to a serial device will follow the same rules
    as screen and keyboard I/O.  By default, end of line characters will 
    terminate input, input edit characters such as backspace will be 
    processed, and data characters will be echoed.  The standard 'IOxx'
    mnemonics can be used to control input characteristics.  Similarly,
    cursor positioning can be used on output if mnemonics are defined in a
    terminal definition file.

    The "Serial Terminal" driver accepts the options listed below when
    opened:

        Option      Argument                Use

        TERM        Filename or path        Specify terminal definition file
                                            to be used with device
        SPEED       Numeric ("9600")        Set device dependent line speed
        DATA        String ("8n1", "7e1")   Set device dependent data format
        CTSFLOW     Boolean ("T" or "F")    Enable CTS output flow control
        DSRFLOW     Boolean ("T" or "F")    Enable DSR output flow control
        RTSFLOW     Boolean ("T" or "F")    Enable RTS input flow control
        XONFLOW     Boolean ("T" or "F")    Enable XOFF/XON output flow 
                                            control

    If not specified, all options except TERM use the current system default
    value of the device.  If the TERM option is not specified, the driver
    uses a simple default terminal definition in which carriage return is
    recognized as an input terminator.

    Example:

        F$ = "(speed=38400,data=8n1,term=c:\dl4\term\vt100)com1"
        Open #1,F$ As "Serial Terminal"

o   The pipe driver has been extended to allow redirection of I/O to
    a specified driver.  "OPENAS=name" or "BUILDAS=name" options 
    can be placed in the script "dl4opts" line to specify that an open
    of the script should cause an OPEN or BUILD using the driver 
    "name".  The options "PATH=string" and "OPTIONS=string" can be used
    to specify the path or options value to be used by the OPEN or
    BUILD.
    
    For example, the statement 'OPEN #2,"$printer"' opens the script 
    "printer.bat" for output on channel 2.  If "printer.bat" begins 
    with the line:

        rem dl4opts=openas=default page printer

    then output to channel 2 would be directed to the default Windows 
    printer.

o   Two printer scripts, dfltlp.bat and selectlp.bat, are now supplied
    and installed with dL4.  The default Windows printer can be opened
    as "$dfltlp".  A user selected Windows printer can be opened as
    "$selectlp" which will cause a printer dialog to be displayed.
    
    Examples:

        OPEN #2,"$dfltlp"
        OPEN #99,"$selectlp"

o   The new ForcePortDump() intrinsic CALL causes a target port to abort 
    execution of the current dL4 program, produce a dump listing file, and 
    then exit from dL4.  For debugging purposes, it is also possible to
    trigger a dump listing without causing the program to exit.  The dump 
    output is identical to that of the ProgramDump() intrinsic CALL and 
    lists the current execution location of the target program, the CALL 
    stack, current variable values, the status of open channels, and 
    various other values.  Under Unix, the caller of ForcePortDump() must 
    either be the same user as that of the target port or be a privileged 
    user such as root.

    BASIC syntax:

        Call ForcePortDump(Mode, PortNumber, Status)

        where:

            "Mode" is a numeric variable or expression that controls the 
            type of dump produced.  If "Mode" is zero, the target port 
            will be requested to produce a dump and then exit.  If "Mode" 
            is equal to one, the port will be requested to produce a dump
            and then continue (this should only be used for debugging 
            because it will interrupt any I/O in progress).
            
            "PortNumber" is a numeric variable or expression containing 
            the port number of the target dL4 program.
            
            "Status" is a numeric variable that receives the status of call.  
            The value of "Status" will be set as follows by any call that 
            doesn't generate an error 38:

                0       Successful, the selected port exists and a dump 
                        command was sent to the port.  This status does 
                        not guarantee that the port actually aborted or 
                        generated a dump file.

                1       Error, the specified port does not exist.
            
            All parameters are required.  Error 38, "Error detected by 
            CALLed subroutine", will be generated if an incorrect number 
            of parameters, parameter type, or parameter value is passed to 
            ForcePortDump.

    To limit attacks on system security, the dump output is controlled by 
    the DL4PORTDUMP runtime parameter.  If DL4PORTDUMP is not defined for 
    the target port, then ForcePortDump() will not generate a dump.  On 
    Unix, DL4PORTDUMP is an environment variable that must be set in each 
    users environment (perhaps set by the .profile script).  Under Windows, 
    the DL4PORTDUMP value can be supplied either as an environment variable 
    or as a string value in the registry:

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\Environment\dL4PortDump
    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\Environment\dL4PortDump

    In any form, DL4PORTDUMP is the filename to which the dump will be 
    written.  DL4PORTDUMP must be an absolute path; for example, under 
    Windows, DL4PORTDUMP might be defined as "D:\Dumps\DumpFile.txt".  The 
    following macro values can be used in a DL4PORTDUMP path string:

    %PORT%        Port number of target port
    %DATE%        Current date ("YYMMDD")
    %TIME%        Current time ("HHMMSS")
    %name%        Value of environment variable "name"

    These macro values, if used in the DL4PORTDUMP path, will be replaced 
    by their current values.  For example, if DL4PORTDUMP was defined with 
    the value "D:\Dumps\%PORT%.txt" and a dump was triggered on port 15, 
    then the dump would be written to the file "D:\Dumps\15.txt".

o   The ProgramDump() intrinsic CALL has been enhanced to use the 
    DL4PORTDUMP runtime parameter, as described above, if the filename 
    parameter is not specified.

o   A new command has been added to the BASIC mode of SCOPE. The command 
    "PDUMP filename" outputs a ProgramDump() style listing of the current
    program status to "filename".

o   A new mode has been added to the PORT statement.  PORT mode 5 
    returns the current line number and library name executing on a
    specified port.  For example, the statement:

        PORT P,5,S,L$

    will return in L$ the current line number of the program running on 
    port P.  If the program is executing a line in a library, then L$ 
    will have the format "library:line#" where "library" is the name of 
    the library.  As with PORT mode 3, a status is returned in S 
    indicating success (zero) or failure (one, port not attached).

o   The following intrinsic calls have been added:

        Call AvPort(PORTNUM {,MINPORT {,MAXPORT}})
        Call CheckDigits(STRING$)
        Call CheckNumber(STRING$)
        Call ConvertCase(MODE, STRING$ {,START})
        Call DateToJulian({MODE,} DATE$ {,CONVERTED_DATE$ {,STATUS}}) 
        Call DecToOct(NUMBER, OUTPUT_NUMBER_OR_STRING_VARIABLE)
        Call Echo(MODE)
        Call FindF(PATH$, STATUS)
        Call FormatDate(DATE$ {,CONVERTED_DATE$ {,STATUS {,MODE}}})
        Call JulianToDate({MODE,} JULIAN$ {,CONVERTED_DATE$ {,STATUS}})
        Call MiscStr({M,}S${,...})
        Call ReadRef(CHAN, MODE)
        Call Rename(LU, OLDNAME$, NEWNAME$, CHANNEL, STATUS)
        Call String(MODE,...)
        Call StringSearch({F,}A${,S},T$,P{,N{,S1{,T1}}})
        Call Time(T$)
        Call VerifyDate(DATE$ {,CONVERTED_DATE$ {,STATUS {,MODE}}})

    These calls are UniBasic compatible and replace all of the functions
    in the oldcalls.bas and depcalls.bas libraries of dl4.samples except
    for CALL DYNWIND().  The date oriented CALLs, like all other dL4 date
    functions, use "OPTION DATE FORMAT NATIVE" and the native operating
    system locale configuration (such as the LANG environment variable)
    instead of the UniBasic "EUROPEAN" and "DATESEP" environment variables.

    In all programs that use oldcalls.lib or depcalls.lib, each occurrence
    of "DECLARE EXTERNAL SUB" must be changed to "DECLARE INTRINSIC SUB"
    for the new calls.  In addition, any "EXTERNAL LIB" statement for
    oldcalls.lib or depcalls.lib should be removed, or, if CALL DYNWIND() 
    is needed, all of the new intrinsic calls should be deleted in
    oldcalls.lib.  For example, in a program that used the DATETOJULIAN 
    and JULIANTODATE calls, the lines:

        Declare External Sub DateToJulian,JulianToDate
        External Lib "OLDCALLS.LIB" 

    would be changed to:

        Declare Intrinsic Sub DateToJulian,JulianToDate

    Programs that are not changed will run, but they will continue to use
    the procedures in oldcalls.lib or depcalls.lib.  Any conversion
    profile ("convert.prf") should be changed to use the new intrinsic
    calls.

o   The record number -4 has been defined in the text file driver to
    position to the end of the file.  A program can append to a text file
    with a statement such as this:

        PRINT #1,-4;"message"

o   The SCOPE DUMP command has been extended to support output to the
    pipe driver.  The command "DUMP $name" will list the current program
    to the pipe device "$name".

o   The 'IOCI' (clear typeahead buffer) mnemonic is now supported for dL4
    sessions using serial devices as standard input or output.

o   A new window driver registry value "ProtectedNotDim" has been added 
    to control whether protected characters are displayed with the 
    "DIMmed" attribute.  Disabling the "DIMmed" attribute makes it possible 
    to fully control the color of protected characters using the normal
    color mnemonics such as 'BL' or 'FONTCOLOR'.  This feature can be
    configured using the "Window" dialog of the "Preferences" menu.

o   A new window driver registry value "TabBySpacing" has been added to 
    control whether the PRINT TAB() function clears intermediate
    characters to spaces while moving to the specified position.  This 
    feature can be configured using the "Window" dialog of the 
    "Preferences" menu.

o   The 'IOTE' (toggle echo) mnemonic is now supported in dL4 windows.

o   Behavior change: when writing strings with the raw file driver, any
    'ALIGN' or 'MOVETO' mnemonics are now expanded before performing the
    write.  This supports the use of TAB and comma field separation in 
    PRINT statements to the raw file driver.

o   Bug fixed: the LET command in the debugger ignored string subscripts
    if the first subscript was one.  Thus, the command 'LET A$[1,1]="X"'
    was treated as 'LET A$="X"' replacing the string value rather than
    just the first character.

o   Bug fixed: if I/O was interrupted, the raw file driver entered a
    tight loop until the I/O completed.

o   Bug fixed: pfilter would fail if an OPEN and CLOSE of a pipe occurred
    without any output and a CLOSE string was defined in the printer
    definition file.

o   Beta bug fixed: the left and top margins used by the Page Printer
    driver were incorrect.

o   Beta bug fixed: the argument order of the intrinsic CALL READREF was
    reversed.

o   Beta bug fixed: PORT mode 5 sometimes returned a very large line
    number if the program on the selected port had exited.

o   Beta bug fixed: intrinsic CALL STRINGSEARCH would fail to find a 
    match if the match occurred at the very end of the dimensioned 
    size of the source string.

Nov  9 1998 (Release 3.1.1)

o   Two new standard intrinsic functions, MD5? and AddMD5?, has been 
    added to dL4.  MD5?() returns the MD5 checksum code of the first 
    argument which must be either a binary or a string variable.  The
    MD5 checksum is returned as a 16 byte binary value.  An optional 
    second binary argument can be used to pass an intermediate value
    from AddMD5?().  This allows a combined checksum to be calculated.  
    Checksums are calculated against the DIMed size of strings so that 
    null (0) characters can be included in the checksum.  To avoid this, 
    simply pass the string with subscripts.  So that string values will 
    produce the same checksums on all platforms, each UNICODE character 
    of a string is forced into a most-significant-byte first ordering 
    for calculation.

    BASIC syntax:

        Dim chksum?[16], intermediate?[128]

        chksum? = MD5?(var)
        chksum? = MD5?(var,intermediate?)

        intermediate? = AddMD5?(var)
        intermediate? = AddMD5?(var,intermediate?)

o   Several open options have been added to the RAW driver for use with
    serial devices as shown below:

        Option      Argument                Use

        SPEED       Numeric ("9600")        Set device dependent line speed
        DATA        String ("8n1", "7e1")   Set device dependent data format
        CTSFLOW     Boolean ("T" or "F")    Enable CTS output flow control
        DSRFLOW     Boolean ("T" or "F")    Enable DSR output flow control
        RTSFLOW     Boolean ("T" or "F")    Enable RTS input flow control
        XONFLOW     Boolean ("T" or "F")    Enable XOFF/XON output flow 
                                            control

    For example, the statement

        OPEN #1,"[1:1](speed=19200,data=8o1,xonflow=t)COM1" As "Raw"

    would open the COM1 serial port at 19200 baud with 8 bit characters,
    odd parity, 1 stop bit, and XON/XOFF output flow control.

o   MSC(43) has been defined and implemented as returning the current 
    screen row.

o   SPC(19) now returns a license value as a 32-bit number instead of
    -1.  In the current implementation, the license value is the 
    license number.

o   Behavior change: if an OPEN fails because a file header is locked,
    the error "File is open elsewhere" will be returned instead of
    "Illegal driver operation".

o   Bug fixed: after a screen area was selected with the mouse, input 
    into that area was truncated.

o   Bug fixed: the pipe driver would sometimes return a "Driver resource
    exhausted" error when a non-existent script or program was opened
    under Windows 95/98.

o   Bug fixed: dL4 sessions could not be evicted or interrupted if a
    read from a serial port was in progress.

o   Bug fixed: an error while evaluating a single line function would
    not trigger error handling and could cause an address violation.

o   Bug fixed: repeatedly CHAINing or CALLing to a program using a "./"
    or "../" in the program filename caused the filename to exceed the
    filename length limit and the CHAIN/CALL to fail because the program
    could not be found.  All "./" and "../" strings are now removed from
    paths for all program and data file access after properly adjusting
    the paths.

o   Bug fixed: CLOSE/CLEAR statements using the RAW driver would sometimes 
    pause for 5 seconds.

o   Bug fixed: OPENing a printer script immediately after CLOSEing it 
    sometimes caused loss of output data.

o   Bug fixed: record zero in a Portable Indexed Contiguous file, once
    deallocated, could not be reallocated.

o   Bug fixed: deallocating non-existent records in a Portable Indexed
    Contiguous file sometimes caused the COUNTUSED option to be disabled.

o   Bug fixed: paths using ":" as a directory separator were not mapped
    correctly by LUMAP.

o   Bug fixed: opening a non-directory using the directory driver did not
    generate an error.

Mar 20 1998 (Release 3.1)

o   This release requires an SSN authorized for release 3 of dL4.
    Without such an SSN, dL4 can only be used in single user demo mode.

o   The SAVE file revision has been changed to 2.8 in order to
    support new features of dL4 3.1.  A new program file format also 
    significantly lowers program load overhead.  Full upward
    compatibility is provided, so program files created by earlier 
    versions of dL4 can still be used (programs saved by dL4 2.3.1 and
    earlier will not, however, be placed in the local cache).  Programs 
    created by this release of dL4 cannot be used by earlier releases 
    of dL4.

o   CALL-by-filename ('CALL "filename"'), CHAIN, and SWAP will reuse any
    library or program files that are shared with the parent program.
    For example, if a parent program uses "oldcalls.lib" and CALLs a
    subprogram that also uses "oldcalls.lib", then a single copy of
    "oldcalls.lib" will be shared between the parent program and the
    subprogram.  Library and program files will NOT be shared unless the 
    files have been SAVEd (or LOADSAVEd) in the new program file format.

o   An OSN (OEM Security Number) based form of program protection has 
    been added to dL4.  This protection mechanism is very similar to the 
    PSAVE method in UniBasic.  A program saved with the PSAVE command 
    can be loaded only on systems that have been authorized with a 
    developer supplied OSN.  Any attempt to run protected programs on an 
    unauthorized system will cause as error 265, "Not licensed to load 
    or create this program".  PSAVE protected programs can be modified 
    and re-SAVED on any authorized system, but they can be listed only 
    on systems which have been authorized with a master OSN.  The 
    ProgramDump intrinsic can be used in protected programs and any 
    errors that occur while attempting to list a source line will be 
    ignored (variables names can always be listed)  The dl4 PSAVE 
    mechanism differs from that of UniBasic in two ways: 

        1. There is no "-o" startup option to add new OSNs.  Instead,
           use the standard REGEDIT or REGEDT32 utilities to add OSN 
           string values to this registry key:
        
           HKEY_LOCAL_MACHINE\Software\DynamicConcepts\Passport\OSN

           If this key does not exist, it must be created.  Each OSN 
           value is a string (REG_SZ) value in which the value name is 
           the company/product name and the value is the OSN key.

        2. There is no "-t" startup option to add a temporary OSN.  A 
           temporary OSN is instead added by using the SCOPE "OEM TEMP" 
           command which will prompt for an OSN that will be used only 
           by the current SCOPE session.

    OSNs are created with the makeosn utility that is supplied as part
    of Passport version 2.1.  This version of Passport is included in
    the dL4 installation program. A PDN (Product Description Number)
    is  required to use makeosn.  OSNs may also be created using the
    Unix version of makeosn.  Please contact the Dynamic Concepts Sales 
    department for information on how to obtain a PDN.

    To support this protection method, two new commands have been added 
    to SCOPE: OEM and PSAVE.  The OEM command lists the currently 
    authorized OSNs.  If the TEMP option is used ("OEM TEMP"), the OEM
    command will first prompt for a temporary OSN to be used only by the
    current SCOPE session.  The OEM command can be used in the SCOPE 
    command, BASIC, and debug modes.  The PSAVE command is used to 
    create OSN protected programs.  The PSAVE command is identical to 
    the SAVE command except for an optional OSN number that can precede 
    the SAVE filename.  For example, the command "PSAVE 2,menu" would 
    save the current program as "menu" after protecting it to require 
    the second OSN listed by the OEM command.  Protected programs can be 
    created only if the specified OSN is a master OSN.  The PSAVE 
    command is available in the SCOPE command and BASIC modes.

    A new option, "-l n", has been added to the SCOPE SAVE command and
    to the LOADSAVE utility to create OSN protected programs.  The
    value "n" is the number of a master OSN as listed by the SCOPE OSN
    command.

o   This release includes two new executables: runc.exe and scopec.exe.
    These are console versions of scopew and runw for use in CGI 
    programs and other special uses.  The console versions differ
    from scopew and runw in that all "screen" I/O is performed via 
    standard input and output, by supporting redirection of standard 
    input and output, in the use of a console interface instead of an 
    independent window, and in the names of the frontend programs (scopec 
    and runc instead of scopew and runw).  As in dL4 for Unix, the 
    environment variables TERM and TERMDIR should be set to select the 
    filename and directory of a dL4 terminal definition file.  The TERM 
    and TERMDIR values may also be specified in the registry under 
    either of the following keys:
    
        HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\Environment
        HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\Environment

    Sample terminal definition files can be found in the installation
    directory in the subdirectory TERM.  While scopec and runc can be 
    used directly from a DOS command prompt, very little screen control 
    is possible because the Win32 console provides only minimal 
    interpretation of control characters.

o   To add custom CALLs or drivers to scopec or runc, use the standard 
    dL4 for Windows development kit.  The console and GUI versions of 
    dL4 differ only in the front end programs and in their use of dL4 
    drivers.  Both versions share the same runtime libraries (dl4rt.dll 
    and dl4basic.dll).

o   The new runtime parameter LUMAP adds a mechanism to map relative 
    file paths.  The LUMAP value consists of one or more space separated 
    value pairs.  Each pair consists of a logical directory name, an 
    equals sign ("=") character, and an absolute path.  Whenever a 
    relative filename is used, the LUMAP will be searched for a logical 
    directory name that matches one or more leading directories names of 
    the relative filename.  Leading zeroes in an all numeric directory
    name are ignored.  If a match is found, the matched portion of the
    relative filename will be replaced with the absolute path from 
    LUMAP.  For example, given an LUMAP value of:
    
        "5=M:\usr\accounting Mail=D:\Mail"
        
    the following filenames would be translated as shown:

        5/filename -> M:\usr\accounting\filename
        005/filename -> M:\usr\accounting\filename
        Mail/filename -> D:\Mail\filename
        x/5/filename -> x/5/filename ("x" isn't in LUMAP)

    Functions such as CHF$(800+c) reverse this mapping to return the 
    logical filename.  Using the LUMAP shown above, if "5/abc" was 
    opened on channel 2, the actual file opened would be 
    "M:\usr\accounting\abc", but CHF$(802) would return "5/abc".  If 
    more than one logical directory is mapped to the same actual 
    directory ("5=T:\acct 6=T:\acct"), then the reverse mapping will 
    map all occurrences of the actual directory to just one of the 
    logical directories.  CHF$(800+c) and similar functions perform 
    reverse mapping on all filenames even if the original filename 
    used an actual rather than a logical directory name.

    Filename mapping is applied to both data and program filenames.
    Mapping is applied to program filenames before the LIBSTRING 
    directory list is searched.  If a program filename contains a 
    mapped logical directory, the filename will be converted to an 
    absolute path and LIBSTRING will not be used.
    
    While the intended use of LUMAP is to support logical unit numbers 
    and logical directory names, it is also possible to map multiple 
    leading directories ("Mail/Fred=N:\Mail\Barney") or entire 
    filenames.  The only recommended use of such substitutions is to 
    translate Windows reserved names such as LPT1 to usable, 
    non-reserved filenames.  For example, the map 
    
        "LPT1=D:\dL4\Printers\Printer1.bat" 

    would make it possible to use "$LPT1" as a printer name even though 
    "LPT1" is a reserved filename under Windows.  Translation of data 
    or program filenames is not recommended, but it is legal and 
    supported.

o   The ROPEN statement has been redefined to open files with locking 
    disabled in addition to the previous read-only access.  ROPEN is
    thus equivalent to 'OPEN "<WL>filename"'.  This new feature permits
    an application to read records that are currently locked by other
    processes.  This form of open is supported by the Portable 
    Formatted, Portable Indexed Contiguous, and FoxPro Full-ISAM 
    drivers.  Note: reading records that are currently locked may 
    return partially updated or inconsistent data.

o   The Portable Formatted and Portable Indexed Contiguous drivers have
    been modified to support reading through locked records on both 
    Unix and Windows.  The required changes to the locking protocol are
    incompatible with previous versions of dL4.  Older versions of dL4
    should not be used to access files at the same time as this or 
    later releases of dL4.

o   The Portable Formatted, Portable Contiguous, and Portable Indexed
    Contiguous drivers now support exclusive opens via the "E" access
    mode ('OPEN #c,"<E>file"') or the EOPEN statement.  An exclusive
    open will succeed only if the file isn't currently open by another
    dL4 3.1 user.  An error 76 will be returned if another user has 
    the file open in either shared or exclusive mode.  Once opened in 
    exclusive mode, a file cannot be opened by other dL4 users.

o   The default value of ISAMFILES has been increased from 40 to 50.

o   A DCC_SYNC command has been implemented in the Portable Index
    Contiguous driver to flush the record buffer without releasing the
    current record lock.  A DCC_SYNC command can be issued by a user
    program via the CHANNEL statement ("Channel 20,#c;").

o   A new option, "NUMMAP", has been added to the Portable Contiguous 
    and Portable Indexed Contiguous file drivers to support converting 
    from UniBasic to Portable Contiguous files.  The "NUMMAP" option 
    has two possible values: "IEEE" (the default) and "IRIS" (to use 
    IRIS BCD number formats).  This option can be used as shown below 
    with the "CHARSET" option to create a Portable Contiguous file that 
    uses the IRIS BCD number formats and the IRIS character set:

        BUILD #c,"(nummap=Iris,charset=Iris)[n:l]filename"

    If a file is built this way, records can be copied directly from a
    UniBasic contiguous file by reading and then writing the entire
    record using a binary variable.  The UniBasic file must contain 
    only IRIS character and IRIS BCD numeric data.  This conversion 
    does NOT support copying packed fields because they contain 
    inherently untranslatable binary data.  

o   The pipe driver has been extended to support printing directly to
    a device without running a separate "pfilter" process.  This 
    feature makes it easier to debug printer scripts because most
    configuration errors are reported immediately to the OPEN statement.
    To use direct printing, the printer script must specify an "output" 
    option to select the output device and a "translate" option to 
    select a printer definition file path.  For example, the following 
    script outputs to the device LPT1 after translating output using 
    the printer definition file "c:\dl4\printers\hplj":

        rem dL4opts=output=LPT1,translate=c:\dl4\printers\hplj,lock=true

    A printer script using direct output should consist of a single
    options line; all subsequent lines will be ignored.  A direct 
    output script always uses the Unicode character set and ignores 
    any "charset" options.

o   The MSC$() function has been extended to provide a MSC$(7) value
    which is the hot-key character, if any, that invoked execution of
    the current SWAP level.  The value of MSC$(7) is an empty string
    ("") if the current program isn't in a hot-key initiated SWAP level.
    This new value can be used to perform different functions in a
    hot-key SWAP program based on which hot-key character was entered.

o   The 'IOBI' and 'IOEI' binary input mnemonics can now be used in dL4 
    windows.  The meaning of binary input is dependent on the operating 
    system environment and so the use of 'IOBI' should be avoided in 
    portable programs ('IOBC' and activate-on-control-character mode may 
    be a suitable replacement).  In all environments, binary input 
    disables special treatment of editing keys such as backspace.  In the 
    Windows environment, binary input disables special character handling
    by dL4 and treats all characters as data.  Special characters like
    Control-Alt-Del, which are handled by Windows itself, are not 
    effected. Echo should be disabled when using binary input to avoid 
    echoing illegal characters.

o   The BASIC/Debug command SIZE has been extended to accept a "-l"
    option which causes the sizes and names of all linked libraries to
    be displayed.

o   Two new commands, "WB" and "WT", have been added to the SCOPE
    debugger to move the debugger window to the bottom ("WB") or the top
    ("WT") of the screen.  Note that a debugger window is only used if 
    dL4 windows are open.

o   Three new commands, "WF", "WH", and "WS", have been added to the 
    SCOPE debugger to resize the height of the debugger window.  The
    commands set the debugger window to the full ("WF") height, one half
    ("WH") height, or a quarter ("WS") height of the full screen,  The
    debugger WINDOW command has been extended to accept a single numeric
    parameter to set the number of lines in the window (the command
    "WINDOW 6" or "W6" would select a height of 6 lines).

o   The SCOPE DISPLAY command and the ProgramDump intrinsic CALL have 
    been modified to print repeated array values in a single line using 
    an array slice notation.  For example, if the array V had 10 
    elements and all of the elements were zero except for V[4]=7 and 
    V[8]=9, then the command "DISPLAY V" would produce the following 
    output:

        * V[0;3],%13 = 0
        V[4],%13 = 7
        * V[5;7],%13 = 0
        V[8],%13 = 9
        V[9],%13 = 0      

    Note that all lines with repeated data are prefixed with an 
    asterisk.

o   The size and position of the debugger window is retained between
    debugging sessions until SCOPE exits.

o   The EXIT command has been added to the debugger so that the user
    can exit directly to SCOPE command mode.

o   The SCOPE DRIVERS command now accepts a search string to select
    which drivers are displayed.  Example: "drivers isam".

o   The maximum port number has been increased from 255 to 4095.

o   A new optional section, "[Header]", is supported by the conversion
    profile files used by the CONVERT command and the LOADSAVE "-c" 
    option.  This section can be used as shown below to add standard
    OPTION statements to programs as they are converted:

        [Header]
        Line=OPTION STRING SUBSCRIPTS IRIS
        Line=OPTION BASE YEAR 1988

    Lines from the header section are added using the first unused line
    number and so they may be inserted after the first converted line.

o   A new standard intrinsic CALL, DupChannel, has been added to dL4.  
    This call allows dL4 programs to duplicate existing open channels
    onto closed user channel numbers.  These duplicate channels can be 
    used to perform I/O in the same way as the original channels. The 
    primary use of DupChannel is to duplicate the standard input and 
    output channels that are used by INPUT and PRINT when a channel 
    isn't specified.  By duplicating the standard input or output 
    channel onto a user channel number, a program can apply channel 
    oriented statements such as SET to a standard channel.  Because 
    DupChannel duplicates the base standard input and output channels, 
    it can also be used to avoid window tracking when Dynamic Windows 
    are active.  Closing the duplicate or original channel has no 
    effect other than freeing the channel number unless all copies of 
    the original channel are closed.

    BASIC syntax:
        Call DupChannel(newchannel, oldchannel)

    Where:

        newchannel   -  a numeric variable or expression specifying 
                        the closed user channel (0 - 99) onto which 
                        the standard channel will be duplicated.  An 
                        error will be generated if newchannel specifies 
                        a channel that is already open.

        oldchannel   -  a numeric variable or expression with a value 
                        of an open user channel (0 - 99), standard input
                        channel (-1) or standard output channel (-2) to 
                        duplicate.  The standard input and output 
                        channels are the original base channels and not 
                        the window channels used by Dynamic Windows.  
                        An error will be generated if oldchannel 
                        specifies a channel that is not open.

o   A new standard intrinsic function, CRC32, has been added to dL4.  
    CRC32() returns a 32-bit CRC checksum code of the first argument 
    which must be either a binary or string variable.  An optional 
    second numeric argument can be used to pass the CRC value from a 
    previous call and calculate a combined CRC of several variables.
    CRCs are calculated against the DIMed size of strings so that zero 
    characters can be included in the CRC.  Subscripts can be used to
    limit the number of characters included in the CRC.  So that string 
    values will produce the same CRC values on all platforms, each 
    UNICODE character of a string is forced into a most-significant-byte 
    -first ordering for CRC calculation.  An error will be generated if
    an illegal number of parameters, parameter type, or parameter value 
    is used.

    BASIC syntax:
        x = CRC32(var)
        x = CRC32(var, oldcrc)

o   A new standard intrinsic function, FindChannel, has been added.  
    FindChannel() returns the first closed channel number in a range. 
    If no range is specified, the first channel between 99 and 0 (note 
    descending order) is returned.  An error will be generated if an 
    illegal number of parameters, parameter type, or parameter value 
    is used.

    BASIC syntax:
        x = FindChannel()
        x = FindChannel(startchan,endchan)

o   The Env and SortInString (CALL 65) intrinsic CALLs are now standard 
    intrinsic CALLs.  In previous releases, the sources for these CALLs 
    were included in the development kit, but they were not linked into 
    SCOPE or RUN.  The effect of using Env to change the value of dL4 
    runtime parameters is undefined for the running process: the change 
    may or may not effect the value used by the running process.
    Applications must not depend on the current treatment of environment
    variables by dL4 because that behavior may change in future releases.
    Applications should only change environment variables defined by
    the application itself.

o   A new mode has been added to the PORT statement.  PORT mode 4 
    returns the name of the current program of a specified port.  For 
    example, the statement:

        PORT P,4,S,F$

    will return in F$ the name of the program running on port P.  As 
    with PORT mode 3, a status is returned in S indicating success (zero)
    or failure (one, port not attached).

o   The SCOPE command line now uses LIBSTRING to find BASIC program files.

o   The SPAWN statement now uses LIBSTRING to find BASIC program files
    unless an OPTION statement with "CHAIN ALTERNATE DIRECTORIES OFF" is
    used.  An error 206 ("subprogram file not found") will be returned
    if the specified program cannot be located.

o   The EXAMINE, BREAK, and NOBREAK debugger commands now recognize the
    filename of the main program in addition to its path (as displayed
    by the STATUS command).

o   The FoxPro Full-ISAM driver now supports the memo (.fpt) portion of
    a FoxPro file when deleting, MODIFYing, or DUPLICATEing FoxPro
    Full-ISAM files.

o   The FoxPro Full-ISAM driver now tries both the normalized and
    literal names when mapping fields and indices.  This allows the MAP 
    statement to support a wider range of field or index names.

o   Input timeout ("INPUT TIM") is now supported on phantom ports.

o   Input characters following a "hot key" (SWAP input action) character
    are now always left in the input queue and can be read by the 
    SWAPped to program.

o   When native locale date format is enabled by the statement
    "OPTION DATE FORMAT NATIVE", string to date conversion now uses 
    the short date style of the regional locale information to select 
    the preferred ordering of numeric dates.  For example, if the short 
    date format is "yy/MM/dd", the statement 'D# = "01/02/03"' would 
    store the date "February 3, 2001" in D#.  Please note that string 
    to date conversion tries several formats, both numeric and 
    non-numeric, to parse the date and time.

o   Input handling by the RAW driver for serial communication devices 
    such as COM1 has been improved to support input timeout.  Note that 
    serial device characteristics such as speed and flow control must 
    be setup externally using the Windows 95/NT MODE command.

o   The maximum parameter value for the PRINT TAB function and the 
    COMMA SPACING option has been increased from 255 to 65535.

o   The following new TIM functions have been added to return 4-digit 
    years:

        TIM(14)      Current date in the from MMDDYYYY, MM = 1-12,
                     DD = 1-31
        TIM(15)      Current date in the form YYYYDDD, DDD = 1 to 366
        TIM(16)      Current year in the form YYYY           

    These functions correspond to the two digit year functions TIM(4),
    TIM(5), and TIM(8).

o   A new channel function, CHF#(), has been added to return the 
    creation, last access, or last modification date/time of a file.
    The creation date/time is returned by CHF#(100+c) where 'c' is a 
    channel number.  Similarly, the last access and modification 
    date/times are returned by CHF$(200+c) and CHF#(300+c).  Note that 
    opening a file will change the last access date/time unless the 
    "Raw" file driver is used.

o   Linker speed has been improved for programs that use an extremely 
    large number of libraries (> 50).

o   Behavior change: The first record number of a Portable Indexed 
    Contiguous file can now be set to zero using a mode 1, index 0
    SEARCH statement with a status value of 6.  The statement must
    be executed prior to freezing the index definitions.  In previous 
    versions of dL4, an attempt to set a first record number of zero 
    was ignored.

o   Behavior change: the linker has been modified to allow user defined
    procedures to overload intrinsic procedures.  For example, a user
    program that defines a function called FindChannel will use that
    function rather than the new intrinsic FindChannel function.

o   Behavior change: Portable Indexed Contiguous and UniBasic Indexed
    Contiguous files now flush the data record buffer whenever a key is
    inserted or deleted.  This avoids a situation in which, when a new
    record was inserted, a separate program reading the file and 
    ignoring record locks would receive a "Record not found" error when 
    accessing the new record.  Note that a "Record not found" error can 
    still occur if the new record is not written until after the key is 
    inserted.  Writing the new record after inserting the key is an 
    application error which must be corrected in the application program 
    (otherwise there is an unavoidable period between the SEARCH and the 
    WRITE in which the key exists, but the data record does not).

o   Behavior change: the file autoselection mechanism now recognizes
    UniBasic formatted, contiguous, and indexed-contiguous files.  The
    drivers for these files are not included in dL4 for Windows because 
    these files are not portable and, hence, no existing Unix UniBasic 
    file could be accessed.  New files should be created in the Portable 
    Formatted, Contiguous, and Indexed-Contiguous formats. A "No such 
    driver" error will be reported by any attempt to open a UniBasic 
    file.

o   File locking in Indexed Contiguous files has been modified to 
    increase compatibility with NFS client software.

o   The runtime parameter, "WarnOnClose", has been extended to support
    multiline messages by treating "\n" as a line separator.  A 
    backslash must now be entered as "\\".

o   The appearance of full screen scrolling has been improved for many
    display cards.

o   Behavior change: if a network connection on standard input or
    standard output is lost by scopec.exe or runc.exe, it will be 
    assumed that a telnet-style connection has been terminated and
    that dL4 should exit.

o   Behavior change: an attempt to delete an open file will wait for up
    to one minute for the file to close rather than immediately 
    reporting a "File is busy" error.

o   Bug fixed: an "Internal error in driver" error was reported when
    searching a FoxPro Full-ISAM file that had been opened in read/write
    mode if the file permissions allowed only read-only access.

o   Bug fixed: a FoxPro Full-ISAM key size of more than 127 characters
    caused the index to become corrupted.  Please note that while keys
    of up to 240 characters are supported, key sizes should be limited
    to 150 characters or less for efficient index operation.

o   Bug fixed: selecting a cut-and-paste area on the screen caused the
    display to become corrupted if the screen was scrolled.

o   Bug fixed: To increase compatibility with BITS programs, the Portable 
    Contiguous and Portable Indexed Contiguous drivers have been changed 
    to follow BITS alignment rules when OPTION FILE ACCESS RAW is used.
    Using FILE ACCESS RAW, the current file position will no longer be 
    rounded up to an even byte boundary when reading or writing numeric 
    variables or when executing MAT READ or MAT WRITE statements.  The
    new behavior matches that of the UniBasic Contiguous and Indexed 
    Contiguous drivers.  If desired, the Portable Contiguous driver 
    (pcontig.c) in the dL4 development kit can be modified to restore 
    pre-3.1 behavior.

o   Bug fixed: an address violation or memory corruption could occur if
    an 'EG' (End Graphics) mnemonic was the first character in an output
    string when using either the UniBasic or IRIS character set.  This
    would most commonly occur when printing to an output pipe using the
    default character set.

o   Bug fixed: SCOPE or RUN would "hang" (enter an infinite loop) when
    attempting to run or link a program that contained a duplicate
    procedure definition in a library.

o   Bug fixed: the cursor is moved to the end of input line when an 
    enter key is pressed during input editing.

o   Bug fixed: SPC(23) returned -1 instead of "n" after the statement 
    "LIB n" had been executed.

o   Bug fixed: the FoxPro Full-ISAM driver did not correctly concatenate
    field names for members of sub-structures.  When a member of a 
    record structure was itself a structure, all members of that 
    sub-structure were treated as having the same, incorrect name.

o   Bug fixed: trailing exclamation marks were not recognized by the
    DUPLICATE or MODIFY statements for Portable Indexed Contiguous files.

o   Bug fixed: the SYSTEM statement generated a runtime syntax error 
    if a status variable was used with an external system command 
    ('SYSTEM "cmd",S').

o   Bug fixed: converting a string to a date caused an error 15 if the 
    date was numeric and a two digit year of zero was used.  For 
    example, the statement 'D# = "14-10-00"' would fail and report an 
    error.

o   Bug fixed: expressions containing 24 string concatenation operations
    could cause memory violations or corrupt the current program.

o   Bug fixed: reading the command line ("INPUT (0,X)C$") after using 
    the debugger could cause memory violations.

o   Bug fixed: input was echoed incorrectly in insert mode.

o   Bug fixed: including a space in BREAK/NOBREAK search string (such 
    as in "BREAK /CALL PGM/") resulted in a format error.

o   Bug fixed: if a newly built and structured Portable Indexed 
    Contiguous file was CLEARed (rather than CLOSEd), the index portion 
    of the file wasn't deleted.

o   Bug fixed: pfilter sometimes delayed output until subsequent output 
    or a CLOSE occurred.

o   Bug fixed: rounding of ICE format numbers has been improved so that
    values such as "4.49999999" will be loaded correctly.

o   Bug fixed: a "Record not written" error was generated whenever a
    program was executed with LIBSTRING defined in HKEY_LOCAL_MACHINE
    of the registry.

o   Bug fixed: an "Internal driver error" occurred in the Microsoft SQL
    Server Full-ISAM driver when searching a non-unique index that
    shared key fields with the primary unique index.

o   Beta version bug fixed: when using LUMAP with numeric directories
    (Logical Unit numbers), all leading zeroes were deleted except for 
    the last zero.  Thus, "005/file" and "05/file" were treated as having 
    a directory name of "05" rather than "5".

o   Bug fixed: if LUMAP was defined and the current directory was one of
    the directories in LUMAP, then a CALL, CHAIN, or SWAP to a program
    in the current directory would fail if the program filename did not
    specify a directory ('CALL "PGM"' rather than 'CALL "1/PGM"').  In
    addition, a SCOPE "CD lu/" resulted in an "illegal filename" error.

o   Beta version bug fixed: an attempt to load a program or library saved 
    by an older version (2.3.1 or earlier) of dL4 would result instead in 
    loading a different, but previously loaded, program.

o   Beta version bug fixed: if two identical programs were loaded 
    consecutively, they were treated as having the same path.


Networking
==========

o   File access under dL4 has been tested with Windows NT file servers
    using both TCP/IP and NetBEUI protocols.  dL4 file access does not
    use any special network system calls and should be compatible with
    any network file service that supports file access through normal
    file access system calls.  File access to Novell servers or using 
    third-party NFS client software has not been tested.


Notes
=====

o   dL4 for Windows will run under the Windows 7, Windows Server 2012, or later
    operating systems.

o   Before using dL4, Passport for Windows must be installed and a valid 
    license and SSN must be registered using the ssnmaint utility.  The 
    ssnmaint utility is part of Passport and can found in the Passport
    program group.  Please contact the sales department at Dynamic Concepts
    (sales@dynamic.com) for information on obtaining a license and SSN.

o   The record locking protocols used by the Portable Formatted and 
    Portable Indexed Contiguous drivers are incompatible with pre-3.1 
    versions of dL4.  The protocol was changed to support reading through 
    locked records on both Unix and Windows.  If a Portable Formatted,
    Contiguous, or Indexed Contiguous file is accessed simultaneously by 
    this release and a pre-3.1 release, the file data may be corrupted.

o   The "OPTION FILE ACCESS RAW" statement is used to select BITS 
    compatible file treatment and data alignment rules.  In pre-3.1 
    versions of dL4, the Portable Contiguous, Portable Indexed 
    Contiguous, and Full-ISAM Bridge drivers did not properly follow 
    BITS alignment rules when OPTION FILE ACCESS RAW was used.  In dL4 
    3.1, these errors have been corrected. If your programs use the 
    FILE ACCESS RAW option, your programs and file layouts should be 
    examined for compatibility with these changes.  Using FILE ACCESS 
    RAW, the current file position will no longer be rounded up to an 
    even byte boundary when reading or writing numeric variables or 
    when executing MAT READ or MAT WRITE statements.  If desired, the 
    driver sources in the dL4 development kit can be modified to 
    restore pre-3.1 behavior.

o   Copy and Paste functions are available via the "Edit" menu 
    which is part of the main window menu bar or part of the 
    System menu ("Alt-Space").

o   Font characteristics, window size, keyboard translation, and 
    input action assignments can be modified using the 
    "Preferences" menu.  The "Preferences" menu is part of the 
    main window menu bar or part of the System menu ("Alt-Space").
    The "Preferences" menu provides access to the "Font", "Window" and 
    "Keyboard" dialogs.  Features that are controlled by the "Window" 
    or "Font" dialogs will not change until the next entry into scopew 
    or runw.

o   The number of lines and columns in the main window is 
    controlled by registry settings and defaults to 25 lines of 
    80 columns.  The values cannot be changed for a running instance
    of dL4, but the registry values can be modified by the "Window"
    dialog for use by the next entry into dL4.  In that dialog, the 
    canvas values control the actual number of rows and columns while 
    the window values control the number of rows and columns that are 
    displayed.

o   The default foreground and background colors are controlled by 
    registry settings and default to those of the system color 
    scheme.  The default values cannot be changed for a running 
    instance of dL4, but the registry values can be modified for 
    future invocations by using the "Window" dialog.

o   Keyboard translations and input action assignments can be 
    modified using the "Keyboard" dialog of the "Preferences" 
    menu.  Changes are applied immediately and are saved in the 
    registry for all future invocations of dL4.  The "Keyboard" 
    dialog contains two sections: "Special Key to Unicode" and 
    "Unicode to Input Action".
    
    The "Special Key to Unicode" section is used to examine, add, 
    or modify translations of key combinations to Unicode 
    characters.  For example, to define "Shift-F1" to be the 
    character 'F13', enter "F14D", the Unicode character value of 
    'F13', in the edit box under the heading "Unicode", select 
    the edit box under the heading "Key Combination", press the 
    SHIFT and F1 keys, and then click "Set" and "Ok".  Warning: 
    it is possible intercept normal Windows keys such as Alt-F4 
    (Close Window/Application) and thus interfere with normal 
    Windows keyboard usage.  In the list box, a "Key Combination" 
    value of "VK=xxx" indicates a key combination which isn't 
    supported by the keyboard.

    The "Unicode to Input Action" section is used to examine, add, 
    or modify assignments of input actions to Unicode characters.  
    For example, the character 'F9' is assigned by default to be 
    the SWAP character.  To use 'F9' as a data character, select 
    the character range U+F149 to U+F149 in the list box, select 
    "Data" from the "Action" drop down list, and the click "Set" 
    and "Ok".

o   The default input action assignments are:

        control-B               Send signal to program
        control-C               Interrupt program
        control-D               Abort program
        control-E               Toggle echo and enter control-E 
                                into input
        Backspace               Backspace and delete character
        Enter                   Enter
        control-X               Delete all input
        Escape                  Escape program
        Left-arrow              Move cursor left
        Right-arrow             Move cursor right
        Insert                  Toggle input insert/replace mode
        Delete                  Delete input character
        Home                    Move cursor to start of input
        End                     Move cursor to end of input
        Control-Left-arrow      Move cursor to previous word
        Control-Right-arrow     Move cursor to next word
        Control-End             Delete characters to end of input
        F9                      Swap (if enabled via SWAPF())
        BEGIN                   Enter "BEGIN" mode

o   The port number used by dL4 can be controlled by setting the 
    PORT environment variable or the registry REG_DWORD value PORT 
    under one of the following keys:

    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\Environment 
    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\Environment

o   The values for SPC(5), SPC(7), and MSC(7) can be controlled 
    by creating SPC5, SPC7, and/or MSC7 environment variables or 
    registry values.  Registry values must be of the type 
    REG_DWORD and must be created under one of these keys:
    
    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\Environment
    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\Environment

o   The LIBSTRING value can be set by creating a LIBSTRING 
    environment variable or registry value.  A Registry value must 
    be created under one of the following keys:
    
    HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\Environment
    HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\Environment

o   The registry can be edited using the standard REGEDIT or REGEDT32 .

o   Screen, keyboard, and other configuration information can be 
    copied between systems by exporting the registry contents of 
    Software\DynamicConcepts\dL4 to a file and then importing that
    file on the target system.  The standard REGEDIT utility can be
    used to perform this function.


Platforms
=========

Operating system information for dL4 11.3 production:

ID  Platform                OS
-------------------------------------------------------------------------
1B  Win32 Intel             Windows 10, 11, and compatible server versions