Wednesday April 19, 2017 dL4 For Unix Runtime 10.7.11 Maintenance Release All Rights Reserved. Copyright (c) 1994 - 2016 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 This release requires an SSN authorized for release 10 of dL4. Without such an SSN, dL4 can only be used in single user demo mode. o Passport software must be installed to use dL4. For most systems, version 4.1 or later of Passport can be used. On Apple Mac OS X systems, Passport 4.5 or later must be installed. On Raspbian Linux systems, Passport 4.8 or later must be installed. o The SQL and Full-ISAM SQL drivers cannot be used unless the SSN enables the SQL driver option. o To use the MySQL drivers, the MySQL libmysqlclient runtime library must be installed. On most systems, the library is named libmysqlclient.so or libmysqlclient.so.15. The library is NOT needed to use scope or run if the MySQL driver is not used. The library may be available on your operating system installation media or it can be downloaded from mysql.com. The library should be in a standard library directory such as /usr/lib, /usr/lib/dl4, or a directory pointed at by the LD_LIBRARY_PATH environment variable. 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. The libraries needed for Oracle are libclntsh.so , libnnzNN.so, libocci.so, and libociei.so. These libraries can be found in the Oracle database installation or in the "Instant Client" package that can be downloaded from oracle.com. The LD_LIBRARY_PATH environment variable must be set to point at the directory containing the Oracle runtime libraries. 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 Highlights of This Release ========================== o The tools/term utility can report driver usage statistics. o The Terminal File Printer driver can now transfer non-text files. o Files transferred using the Terminal File Printer driver can be referenced by SYSTEM 31, SYSTEM 33, or SYSTEM 39 statements. o Support for SSL server applications. o Support for uniBasic 10.x executing dL4 subprograms via SWAP statements. Installation instructions ========================= 1. Ensure that you have a current version of the Passport software installed on your system. The Passport version can be checked by examining the /etc/DCI/passport.log file. For Apple Mac OS X systems, Passport version 4.5 or later must be used. For all other systems, Passport 4.1 is the minimum supported version and version 4.4 is needed to use combined dL4 and UniBasic licenses. Passport software can be obtained from www.dynamic.com or ftp.dynamic.com. 2. Login as 'root'. 3. If upgrading an existing dL4 installation, make certain that all dL4 scope and run users have exited dL4. If a program cache is used (see the dL4 Installation and Configuration Guide), delete any existing cache using the Unix ipcs and ipcrm utilities. 4. Copy the distribution file to any temporary directory on your system, e.g. "/tmp". 5. If the distribution file has a ".Z" extension, uncompress the file using the command "uncompress filename.Z". On Linux systems, use the command "gzip -d filename.Z". If the file has an extension of ".z", rename the file with an uppercase "Z" before uncompressing the file. 6. Unpack the distribution file using the command "cpio -imcdu 2gb) format. makekey Utility to create key files. oldcalls.lib A dL4 library that implements CALL DYNWIND() and CALL MONITOR(). pgmcache Utility to display or delete the program cache. query Utility to display file characteristics. selfcert.sh A Unix/Linux script to generate self-signed SSL certificates for use with the SSL driver. setlog Utility to control data file modification logging. sqlnet.ora Sample configuration file for use with the Oracle SQL driver. term Utility to monitor or terminate ports. txt2pdf.lib Sample library to produce PDF file from text. vercdx Utility to validate FoxPro Full-ISAM indexes. verindex Utility to validate Portable or Universal Indexed-Contiguous files. Other utilities Other utilities including converted versions of many UniBasic utilities dL4 and dL4Term =============== o Some of the new features of dL4 10.7.11 are supported only when using dL4 with the dL4Term 10.4 or later SSH/telnet client. dL4Term is a separately available and licensed product. Please contact the Dynamic Concepts Sales department for information on obtaining a copy of dL4Term 10.5. New in This Release ================================================================================ Apr 19, 2016 (Maintenance Release 10.7.11) 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 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. Feb 8, 2016 (Maintenance Release 10.7.10) o Enhancement: the tools/magic.txt file now includes entries to detect resource files and encrypted raw files. 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. 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: SYSTEM 32 returned an incorrect number of free blocks on very large file systems. Jul 7, 2016 (Maintenance Release 10.7.9) 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 28, 2016 (Maintenance Release 10.7.8) o Bug fixed: the directory drivers did not work on some file systems (such as networked Windows file systems) on 32-bit Linux platforms (36 and 6D). May 17, 2016 (Maintenance Release 10.7.7) 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 Behavior change: the DUPLICATE statement no longer aborts the file copy if the source file permissions cannot be copied to the destination file. This change allows the DUPLICATE statement to be used when the destination file system does not support setting permissions. o Bug fixed: error 273, "Not licensed to use this feature", was sometimes reported when opening an SQL driver or encrypted file even though the system was properly licensed. o Bug fixed: SIGNAL, SEND, and RECV statements sometimes failed and reported an unexpected operating system error. Apr 25, 2016 (Maintenance Release 10.7.6) o Bug fixed: message queues were not deleted when scope or run were aborted due to a stdin/stdout socket disconnection. Apr 12, 2016 (Maintenance Release 10.7.5) o Use OpenSSL version 1.0.2 on platforms 64 and 6D so that the latest versions of TLS are supported in the SSL drivers. Mar 30, 2016 (Maintenance Release 10.7.4) o Fix a potential problem when using the MySQL drivers with the MariaDB client library. Mar 8, 2016 (Maintenance Release 10.7.3) o Error reporting and logging improved for "missing message queue" errors. Feb 26, 2016 (Maintenance Release 10.7.2) o Improve reliability of starting phantom ports and eliminate some system error reports. Jan 18, 2016 (Maintenance Release 10.7.1) o Lower initialization overhead on some large systems. Nov 30, 2015 (Release 10.7) 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 [options] The required value "" 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 Platform 6D, a 32-bit Linux platform, is now compiled and linked on a Red Hat Enterprise 5 system rather than on Red Hat Enterprise 3. Red Hat Enterprise 5 is the oldest version of Linux supported by Red Hat. Systems using older versions of Linux may need to be upgraded before using dL4 10.7. 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 occurred with some SSL servers. o The library path list used in the MySQL SQL and MySQL Full-ISAM drivers has been changed to include additional MySQL library versions. 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. Aug 10, 2015 (Release 10.6) 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 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 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=" option and a "cert=" 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=" 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 inetd/xinetd 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=" 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=" 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 inetd, xinetd, or an equivalent. Example: run -D serverprogram Feb 25, 2015 (Maintenance Release 10.5.1) o Support platform A6, Raspbian Linux on ARM version 6 (Raspberry Pi). Feb 9, 2015 (Release 10.5) 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), The dL4 subprograms invoked by the SWAP statement are not considered additional users but do require an SSN that authorizes dL4. To allow debugging, the SWAP statement normally uses SCOPE to execute dL4 subprograms but will use the RUN utility if the calling unibasic program was started with "unibasic -F". 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 When using the new SWAP 100, 110, or 120 statements, it is 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 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 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 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 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" Build #6,"(charset=ISO 8859-15)[1:40]contigfile" 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$() Where "" is a string variable or a string expression. 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 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 A new mnemonic, 'XST', has been implemented to set GUI element tab stops using scaling 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 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: the tools/term utility now has a SNAP option to trigger a program dump on a 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 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 Bug fixed: the octal option in scope DL4CMDDEF profiles set hexadecimal listing mode rather than octal listing mode. Sep 9, 2014 (Maintenance Release 10.4.12) o Bug fixed: when using windows on character terminals with 80 and 132 column modes, the last line of the screen was sometimes updated incorrectly. o Bug fixed: the TIM(6) function result was off by one day if daylight saving time was in effect and the current time was less than an hour after midnight. o Bug fixed: the tools/query utility could not display the correct sizes of files larger than 2 gigabytes. o Bug fixed: Values beyond the range of a %2 (32-bit signed integer) variable did not cause a overflow error on 64-bit platforms. Apr 30, 2014 (Maintenance Release 10.4.11) o Bug fixed: on platform 36 (32-bit Red Hat Enterprise 6 Linux), converting numbers or numeric strings greater than 2147483647 to integers generated incorrect results. Apr 21, 2014 (Maintenance Release 10.4.10) o Bug fixed: the blocked port option in the tools/term utility and the PORT mode 6 statement returned incorrect results. Apr 2, 2014 (Maintenance Release 10.4.9) 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 Behavior change: PORT statements using modes 3 and higher have been changed to reduce the number Unix/Linux signals sent to the target ports. This change may reduce "server connection lost" errors when using the tools/TERM or tools/PORT utilities to monitor a program that uses the MySQL drivers. Jan 21, 2014 (Maintenance Release 10.4.8) o Bug fixed: when reading strings, the MySQL SQL driver space filled strings to three times the expected size (the UTF-8 size of the column). The LATIN1 open option did not work. Jan 14, 2014 (Maintenance Release 10.4.7) 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: CALL GRIDROW() did not advance to the next field when processing an empty ("") numeric or data field. Dec 12, 2013 (Maintenance Release 10.4.6) 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: the LIST, FIND, and SHOW commands sometimes reported illegal character errors when displaying program lines. Nov 1, 2013 (Maintenance Release 10.4.5) 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. Sep 23, 2013 (Maintenance Release 10.4.4) 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 file encryption and SSL socket drivers features are now supported on the HP-UX (E9) platform. 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.4.3 versions of dL4 if saved on 10.4.3. o Bug fixed: records could not be read from a uniBasic non-portable formatted file if the file was write protected. 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 7, 2013 (Maintenance Release 10.4.3) o Bug fixed: a memory violation sometimes occurred when saving a program. Aug 5, 2013 (Maintenance Release 10.4.2) 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 Jul 30, 2013 (Maintenance Release 10.4.1) o Bug fixed: bad program files were sometimes created causing an error 165 - "file may be corrupted". Jul 29, 2013 (Release 10.4) 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,"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 When using dL4 Term, 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.4 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 "-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 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=$HOME/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 Enhancement: the "timeout=seconds" option is now supported by the DL4EMAIL environment/registry value. o Bug fixed: the MAKEUNIV utility did not copy file ownership and permissions correctly for some files. Apr 23, 2013 (Release 10.3) o When using dL4Term 10.2 or later, 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\dL4Term\WinTerm\AllowSYSTEMCmd or HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4Term\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). 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.3) 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 Bug fixed: if permission ("") or other open parameters were placed in front of the destination filename of a DUPLICATE statement, the open parameters were included in the filename. o Bug fixed: GUI resource files did not always work unless the resource file was set in the current procedure with "CALL SETRESOURCE()". Nov 19, 2012 (Maintenance Release 10.2.4) 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. This feature requires dL4Term 10.1.2 or later. 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 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 15, 2012 (Maintenance Release 10.2.3) o Support new platforms 36 (Red Hat Enterprise 6 Linux for 32-bit x86 systems) and 66 (Red Hat Enterprise 6 Linux for 64-bit x86). o Bug fixed: the MySQL SQL and MySQL ISAM drivers sometimes caused memory overflow or MySQL initialization errors after the driver was opened and closed a large number of times. Oct 2, 2012 (Maintenance Release 10.2.2) o Enhancement: the MySQL Full-ISAM driver now supports version 5.5 of the MySQL Server. 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: 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 26, 2012 (Maintenance Release 10.2.1) o Enhancement: the "dl4cntl -init" command now reports an error if the dl4cntl shared memory already exists. Previous versions left the shared memory unchanged but did not report that the command could not be performed. o Enhancement: the ODBC SQL driver now translates additional common ODBC error codes to dL4 error codes. o Bug fixed: the SQLV$() function and related functions generated two carriage return or line feed characters whenever a single such character was specified. Sep 10, 2012 (Release 10.2) 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. The 'WCGRID' and 'WCSORTGRID' mnemonics can only be used with version 10 or later of dL4Term or 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 client system 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. The 'WCDATE' mnemonic can only be used with version 10 or later of dL4Term or dL4 for Windows. The date mnemonic cannot be used on Windows 98 or ME. 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'; The 'WCACTION' mode 6 can only be used with version 10 or later of dL4Term or dL4 for Windows. 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 client system registry to the number of milliseconds to wait for the second click: HKEY_CURRENT_USER\Software\DynamicConcepts\dL4Term\WinTerm\DoubleClickMS This value will be used by all windows on the client system after dL4 is started. o The following command line options have been added to the dl4cntl utility: -status Display the current suspend status -dl4suspend Suspend file writing only for dL4 or dL4 based applications -dl4pause Suspend file writing only for dL4 or dL4 based applications -dl4resume Resume file writing only for dL4 or dL4 based applications o Behavior change: if file updating is suspended with dl4cntl and a program is suspended, any escape or abort characters typed by the user will be ignored. 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 Bug fixed: control-I filename completion did not work if the partial filename was immediately preceded by a comma (as in "convert file1,file2"). Mar 12, 2012 (Maintenance Release 10.1.1) o Bug fixed: attempting to write to a file with partially encrypted records caused a memory violation. Feb 29, 2012 (Release 10.1) 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 Bug fixed: contiguous files with partially encrypted records could not be opened without the encryption key. Nov 30, 2011 (Maintenance Release 9.5.6) o Bug fixed: the dl4cntl file update suspension feature was enabled unless the DL4SUSPEND environment variable was explicitly set to "FALSE". Nov 29, 2011 (Maintenance Release 9.5.5) 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. Nov 17, 2011 (Maintenance Release 9.5.4) o The dl4cntl utility now supports a "-pause seconds" option which suspends file updating for the specified number of seconds or until dl4cntl is run with a "-resume" option. Using the "-pause" option instead of "-suspend" prevents applications from being permanently frozen if the snapshot script fails to execute a resume command. To restrict suspend and resume operations to a specific administrative user, run the command "dl4cntl -init" as that user before any dL4 sessions are started. 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 bold and this is underlined." Get #1,-1799,1;Cid$ Print #1;"" Print #1;"This is after the image." Add #1,-1,1;"apicture.jpg","image/jpeg" Close #1 o Bug fixed: when using the "Sorted Directory" driver, the "SEARCH >" operation sometimes skipped the first matching entry. Jun 9, 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 14, 2011 (Maintenance Release 9.5.2) 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 Bug fixed: 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 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() INT() INT() STR$() LEN() 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 += 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 = or = 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 += Lines in the "[Script Files]" section have the syntax = where "" 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 on dL4Term client systems. 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. On the client system, the registry string value HKEY_CURRENT_USER\Software\DynamicConcepts\dL4Term\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 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 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 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 "ALLCHARSET" option can also be set in the "DL4CONTIG" runtime parameter. Warning: if the index character set is set to UTF-8, then the key length must be long enough to support any multiple byte characters. The tools/query utility has been extended to print the index character set name for a file. 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 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 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 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 RUN utility 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. Feb 7, 2011 (Maintenance Release 9.4.4) o Bug fixed: the Full-ISAM Bridge driver only initialized data in the first filler field. Oct 6, 2010 (Maintenance Release 9.4.3) 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 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 Sep 23, 2010 (Maintenance Release 9.4.2) 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 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. Aug 20, 2010 (Maintenance Release 9.4.1) 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: 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,"[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,"(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 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 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. Example script: # dl4opts=translate=/usr/lib/dl4/printer/pcl.prf lp -s -o raw 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 Bug fixed: negative numbers in terminal definition files or printer definition files were treated as overflow errors on 64-bit systems. Jun 18, 2010 (Maintenance Release 9.3.5) 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 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 21, 2010 (Maintenance Release 9.3.4) 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 Bug fixed: a bad character error was generated when trying to draw images to dL4 Term using dL4 Term release 9.1.2 or earlier. Drawing images succeeded only when dL4 Term 9.3 or later was used. May 3, 2010 (Maintenance Release 9.3.3) 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 The "-b" option of the MAKEUNIV utility now cleans record data using both the record character set and index character set so that the record data will match any associated key value. A "NotInKey" or "NK" option can be added to the end of a character field definition to specify that only the record character set should be used when cleaning the data. The "NotInKey" option should be used on fields that contain mnemonic characters such as cursor positioning or display attributes (such as 'BU'). o Bug fixed: the MAKEUNIV utility sometimes reported illegal character errors incorrectly on files that did not have any numeric fields defined. o Bug fixed: the "-c" option did not work in the tools/checksum utility. Apr 22, 2010 (Maintenance Release 9.3.2) 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 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 A "-b char" option has been added to the MAKEUNIV utility to convert illegal characters in records or keys to a specified character. Example: makeuniv -b X -o destdir src.prf 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. Mar 18, 2010 (Maintenance Release 9.3.1) o Bug fixed: SYSTEM 31 statements failed when using dL4Term 9.1.2 or earlier. 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 dl4cntl utility is installed in /usr/bin. 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. To restrict suspend and resume operations to a specific administrative user, run the command "dl4cntl -init" as that user before any dL4 sessions are started. 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 this feature, dL4Term 9.3 or later must be used. To use a resource file, an application must execute 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 on the client system. 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 'WSTDSIZE' 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 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 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 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 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 The BASIC LIST command has been enhanced with a '-h' option that lists non-printable characters in hexadecimal format instead of octal. 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 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: 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 (Maintenance Release 9.2.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 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 14, 2009 (Release 9.2) o This release supports up to 4096 users on Apple Mac OS X. Previous releases of dL4 for Mac OS X were limited to the number of message queues supported by the operating system (typically only 40). This release uses an emulated message queue system. Passport 4.5, which also uses the emulated message queue system, must be installed prior to installing or using this release of dL4 on Apple Mac OS X. Note that installing Passport 4.5 requires updating all DCI products such as UniBasic or ODBCdL4 server. 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 bold and this is underlined." Get #1,-1799,1;Cid$ Print #1;"" Print #1;"This is after the image." Add #1,-1,1;"apicture.jpg","image/jpeg" Close #1 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: in the debugger and conditional breakpoints, subscripts could not be used with arrays of structures. o Bug fixed: the shared memory driver and the DL4CACHE environment variable generated an incorrect shared memory name if the specified name was in hexadecimal and exceeded 0x7fffffff. 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 performs both of these conversions and also converts SWAP statements to SWAP 3 statements to pass global COM variables. o When converting IMS programs, IMS style structure definitions and references 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 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 three parameters: the error number, the line number of the error, and the name of the program in which the error occurred. 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 "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 intrinsic CALL, IMSChkChnl(), 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 the 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. Odd offsets will be rounded up to an even boundary for numeric variables. 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=datebase.table OpenAs=MySQL Full-ISAM OpenInProfileDirectory=False DDDDDBaseYear=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 now accepts underscores in index names. o The IC2FI (tools/ic2fi) utility now accepts "FILE=" lines in the bridge profile. 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 '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 Enhancement: the FILE command and all program dumps now display channel functions up to 16. 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 The MySQL Full-ISAM driver now supports 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 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 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 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 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 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 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 can be subscripted so that individual structure elements can be passed to other routines or to intrinsics such as SQLV$(). 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 Behavior change: exceeding the process file size limit will no longer cause the system to abort the SCOPE or RUN processes. Instead, the standard "out of disk space" errors will be reported. 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: 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: "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. Jan 2, 2009 (Maintenance Release 7.3.3) o Bug fixed: memory violations occurred after the intrinsic function CallStat$() or other functions were used with smaller than expected argument strings. Dec 12, 2008 (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 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 and MySQL SQL drivers to return one if the current result set has one or more rows and zero if the result set is empty. When using Oracle, this function is faster than CHF(cc) if the exact number of rows is not needed. 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 The "Terminal Printer", "Default Terminal Printer", and "Windows Terminal Printer" drivers now support the 'LITNUL' and 'LITCR' mnemonics when the "Binary=True" option is enabled. 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 dL4Term auxiliary printer for use with the "Binary=True" option. o The "Terminal Printer", "Default 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: 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: on platform 64 (64-bit Linux), the "record in-use" count returned by the SEARCH statement and displayed by the QUERY utility was sometimes wrong. A new utility, "tools/setinuse", has been provided to correct the in-use count in Indexed Contiguous files. o Bug fixed: commands in the form "BREAK IF ..." caused random error messages instead of format/syntax errors. 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 3, 2008 (Maintenance Release 7.3.1) o The PowerPC AIX (07) platform now supports encrypting data in Indexed Contiguous or Contiguous files. o The PowerPC AIX (07) platform is now compiled and linked on AIX 5.2 instead of AIX 4.3. Jun 3, 2008 (Release 7.3) o A new intrinsic function, SQLD$(), has been added for use with SQL o dL4 is now available as a 64-bit application on 64-bit x86 Linux systems. The new platform 64 is compiled and linked on a RedHat Enterprise Server 5 system and requires a compatible version of 64-bit x86 Linux. o When using dL4 with Passport 4.4 or later, a combined dL4 and UniBasic license can be used to license "N" users of either dL4 or UniBasic. 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 as part of the Oracle database installation or by installing the Oracle "Instant Client" package which can be downloaded from www.oracle.com. Unless the libraries are installed in the system library directory such as "/usr/lib" or "/usr/lib64", the environment variable "LD_LIBRARY_PATH" must be set to point at the directory that contains the Oracle libraries. An error 288, "Unable to load system library", will be reported at open time if the Oracle SQL driver is used without the Oracle SQL runtime libraries. 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, when used with dL4Term 7.2 or later, 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 When used with dL4Term, the new Windows Terminal driver 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 can not 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 function key to send the clipboard characters (the "Program Paste" option must be enabled in 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=/usr/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: if, at startup, the terminal definition for the current terminal type cannot be found, SCOPE will display a warning message and then run using a built-in minimal terminal definition. Previous versions of SCOPE displayed an error message and exited if the terminal definition file could not be found. 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 A new sample file, "profile", has been added to /usr/lib/dl4 to show various environment variable settings to be added to user shell profiles. 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: an IRIS style BUILD statement for a formatted file with protection specified ('BUILD #1,<00>filename') resulted in an endless loop. 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 27, 2008 (Maintenance Release 7.2.4) 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. Feb 22, 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. 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. Oct 18, 2007 (Maintenance Release 7.2.1) o Compatibility with different Linux distributions has been increased by using static library linking for some, but not all, libraries. o Bug fixed: a memory violation occurred if an OPEN statement failed when using the MySQL SQL driver. Sep 27, 2007 (Release 7.2) o The SEND and SIGNAL 1 statements can now send messages to UniBasic programs. The normal SEND and SIGNAL syntax is used, but with a port number equal to the target UniBasic port number plus 2^24. Examples: Send 10+2^24,22,34 ! Send 22 and 34 to the UniBasic port 10 Signal 1,P+2^24,S$ ! Send S$ to the UniBasic port P The message can consist of two numeric values or a single string value. When UniBasic receives a message from a dL4 program, the received port number will be the dL4 port number as reported by SPC(6). That port number may be identical to a UniBasic port number. 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. Stored procedures and multi-statement queries may not be supported on some platforms because the client library available for the platform does not support those features. 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 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. Jul 30, 2007 (Release 7.1) o Data in Indexed Contiguous or Contiguous files can be now be encrypted on the Linux (6D), SCO OpenServer 6 / UnixWare 7 (55), and Apple Mac OSX (A1) 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," [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 segments must be defined in ascending order. The example below creates a file in which the first 10 characters and last 6 characters of each record are encrypted: BUILD #1," [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," [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 DL4LOCALE=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 A new open option, "VISUAL", has been added to the pipe driver for use with pipes to programs that need terminal control. For example, the statement Open #1,"(visual)$pg" would open an output pipe to the Unix "pg" utility to display paged output on the user terminal. While the channel is open, dL4 gives up control of the terminal and, as a result, debug mode will not work correctly. Error control (TRY, IF ERR 0, ERRSET, ...) should be used to prevent entry into debug mode while a "visual" pipe channel is open. 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 "-f bintostr" option has been added to the tools/makeuniv utility to force conversion of binary fields in Formatted files to string fields. This option should be used when Formatted files cannot be converted because they contain binary fields created when MAT WRITE statements were used to write strings to those Formatted files. 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 A new OPEN option, UB32BITRULE, has been added to the UniBasic Formatted File driver to support a deprecated feature of UniBasic Formatted files. When the option is used, 32-bit integer fields can be read into or written from 32-bit floating point variables without any conversion being performed. Similarly, 32-bit floating point fields can be read into or written from 32-bit integer variables. When using this option, it is the responsibility of the programmer to make certain that the variables match the actual data formats used in the file. This option should only be used to access existing files that contain mistyped fields. o A "magic.txt" file has been added to the tools directory. This file can be used by the Unix/Linux "file" utility to identify dL4 or UniBasic files. Please see the tools/magic.txt file for instructions on how to install the definitions. The file is compatible with Linux and most Unix implementations. 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 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 accepts record -2 in addition to 0 and -1 in an unlock record operation. 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. Jul 6 2007 (Maintenance Release 6.2.13) o Behavior change: the MySQL SQL and MySQL Full-ISAM drivers now retry opens on more error conditions. This change may resolve or reduce some types of intermittent connection errors. o Behavior change: the email driver now returns an error 72, "Device not accessible", if the SMTP server rejects the supplied "From" address. Jun 4 2007 (Maintenance Release 6.2.12) o Support local application drivers in the development kit. o Bug fixed: the BASIC CONVERT command and the LOADSAVE utility with the "-c" conversion option reported errors when converting programs that used the SETFP statement. Mar 21 2007 (Maintenance Release 6.2.11) o Because updated daylight savings time rules are not available on earlier operating system revisions, platform 99, SCO OpenServer 5, is now compiled and linked with OpenServer 5.0.7 instead of 5.0.6. Static linking is used to enhance compatibility with older revisions of OpenServer. o Bug fixed: dynamicXport transactions timed out early on AIX systems. Feb 20 2007 (Maintenance Release 6.2.10) o Bug fixed: CALL RDFHD() did not increment the record number variable and, as a result, returned the same "." directory entry for each CALL. Jan 25 2007 (Maintenance Release 6.2.9) o Bug fixed: CALL DXMERGE() reported random errors, most commonly with large values. Jan 10 2007 (Maintenance Release 6.2.8) o Support MAC OS X on Intel systems (platform A1). 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 4.3.2 or later must be installed to fully correct this problem. Dec 19 2006 (Maintenance Release 6.2.7) 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 and instead caused the program to be executed as a shell script. Sep 14 2006 (Maintenance Release 6.2.6) 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: Passport startup messages are no longer output by "run" if the -X, -B, or -N options are used. 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: CALL EDITFIELD() generated an error if the DIMmed 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. Jun 12 2006 (Maintenance Release 6.2.5) o Support negative message queue id numbers that sometimes occur on Apple Mac OS X systems. o Bug fixed on Mac OS X platform: SEARCH failed on FoxPro Full-ISAM indexes that contained integer number fields due to an error in the Mac OS X C runtime library. Jun 1 2006 (Maintenance Release 6.2.4) o If a terminal definition file supports two screen widths (such as 80 and 132 columns), users often modify the standard terminal definition file to declare the larger screen width so that windows can be opened using the larger width. This can cause unexpected and undesired scrolling when a window is opened that includes the full bottom line. This problem can be solved by declaring the smaller screen width in the new "AltScreenWidth" setting of the terminal definition file. Example: [Settings] AltScreenWidth=80 o Bug fixed: error 44 was sometimes reported on SEARCH statements using FoxPro Full-ISAM files opened in read-only mode. May 30 2006 (Maintenance Release 6.2.3) 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;"" Print #1;"" Print #1;"" Print #1;"" Print #1;" " Print #1;" " Print #1;" " Print #1;" " Print #1;"" Print #1;"" Print #1;" " Print #1;" " Print #1;" " Print #1;" " Print #1;"" Print #1;"
ItemUnit PriceQuantityCost
Widget25.005=b2*c2
" Print #1;"" Print #1;"" 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 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: some UniBasic data files created on very old versions of UniBasic could not be read correctly. Mar 29 2006 (Maintenance Release 6.2.2) o Platform 6D, Linux x86, is now compiled and linked on RedHat 9 Linux. This platform update from RedHat 7.3 improves compatibility with current Linux distributions and resolves development kit problems, but it may cause incompatibilities when dL4 is used on old Linux systems. 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 fully 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 ignores case when sorting directory entries. 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. o Bug fixed: bad open mode errors sometimes included incorrect supplementary information. Dec 27 2005 (Maintenance Release 6.2.1) o The "MySQL SQL" driver now supports MySQL 5.x servers. 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 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. As with all other GUI mnemonics, this mnemonic can only be used with dL4Term or in dL4 for Windows. 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. As with all other GUI mnemonics, this mnemonic can only be used with dL4Term or in dL4 for Windows. o The initial input mode can be set to "Insert" rather than "Replace" by adding the line "StartInputInInsert=True" to the "[Settings]" section of the terminal description file. 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 A new file BUILD option, "", 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,"[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 The intrinsic CALL PROGRAMDUMP() now supports a "byname" option to sort variable names by name only instead of by type and name. 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 The performance of the profile driver has been improved. o Enhancement: when a forwarding error occurs in the email driver, a "Forward address" string is appended to the "file not found" error text in the HELP command or the MSC$(2) function. 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. Oct 28 2005 (Maintenance Release 6.1.4) o A new ARITHMETIC option, OPTION ARITHMETIC EXTENDED IEEE, has been added to map 1% and 7% to 16 bit and 32 bit signed binary integers instead of signed BCD integers. Using this option extends the range of 1% and 7% variables. This option uses IEEE floating point decimal formats for 2% thru 5% and, except for 1% and 7%, it is identical to the default numeric precision option of ARITHMETIC IEEE DECIMAL. o The performance of the MySQL driver has been improved when used with queries that produce large result sets. o Behavior change: when using dL4Term, DEL ("\177\") characters will be ignored when output instead of producing an error 5. o Bug fixed: CALL PROGRAMDUMP() would hang (enter an "infinite" loop) when displaying string variables with a large number of unprintable characters. CALL PROGRAMDUMP() also output only one truncated line for large string values instead of the expected multiple lines. Sep 14 2005 (Maintenance Release 6.1.3) o Passport 4.1 is required to run release 6.1.3 or later of dL4. o SCO OpenServer 6 is supported by platform 55 which has been renamed as "SCO OpenServer 6 / UnixWare 7". o Bug fixed: closing a FoxPro Full-ISAM file in a SWAPped program sometimes prevented accessing or closing other files. o Bug fixed: the TERM utility now assumes a 24 line screen if paging on a terminal that has a screen height of zero. Aug 12 2005 (Maintenance Release 6.1.2) 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 and MySQL Full-ISAM drivers now report 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 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 fix: the BATCH utility did not work. Jun 17 2005 (Maintenance Release 6.1.1) o The MySQL Full-ISAM and MySQL SQL drivers now use the MySQL 4.1 client library to provide compatibility with MySQL 4.1 server passwords. Both drivers can also be used with earlier versions of the MySQL server. o The CHF$() and CHF#() functions have been implemented in the C-Tree driver to return information about the index portions of indexed contiguous files. This change is only important if the C-Tree portion is opened by itself (indexed contiguous files have always supported CHF$() and CHF#()). o A new command line option, "-noshell", has been added to scope. The option disables running non-dL4 programs from a SCOPE or BASIC command line. o Enhancement: CALL RDFHD() now supports file and directory names that contain spaces. o Enhancement: the terminal translation driver now supports large string parameters. o Bug fixed: CALL SORTINSTRING() sometimes caused memory violations. o Bug fixed: CALL RDFHD() sometimes 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. o Bug fix: the debugger LET command did not work and reported a "format" error. 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. This feature can only be used with dL4Term. 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. This feature can only be used with dL4Term. 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. The file path must specify a valid path on the client system running dL4Term. If the file does not exist on the client system, no error will occur and nothing will be displayed. 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 subsequently created 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 range of GUI element numbers has been increased to 1 through 9999. The previous range was 1 to 1000. 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 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 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 The driver for UniBasic Indexed-Contiguous files (non-portable and non-Universal) now supports greater-than-or-equal SEARCH statements. 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 MySQL Full-ISAM driver now supports 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 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 A new utility, tools/makeuniv, has been added to convert UniBasic files to Universal files. The makeuniv utility is an extended version of the ctool utility. The utility converts non-portable UniBasic formatted, contiguous, and indexed contiguous files to Universal or Portable equivalents. Conversion is normally performed in three steps: 1. The utility is used with the "-p" option is used to generate a prototype conversion file which lists all of the UniBasic files in the specified directory and its subdirectories. For BCD ("Q") data files, the prototype conversion file will be produced with all of the information needed to convert the files and no changes will be needed. For non-BCD files, the user must edit the conversion file and add record field definitions. Example: makeuniv -p ubfiles.txt datafile-directory 2. Edit the prototype conversion file to add any needed record field definitions and to check for warning messages. 3. The utility is executed again with the "-o" option and the conversion file created in steps 1 and 2. This step performs the actual conversion of the files in the source directory to Universal or Portable files in the destination directory. The utility will create the destination directory and any subdirectories if they do not already exist. Example: makeuniv -o newfile-directory ubfiles.txt Because non-Universal UniBasic files are not portable, the conversion must be performed on the same type of system on which the files were created. In addition, the file and directory names must not contain spaces. Command line syntax: makeuniv [-[klruU]] [-t arg] -o dir filename makeuniv [-l] [-[cfi] arg] [-t arg] -p filename sourcedir makeuniv -[h?] makeuniv -v The options and arguments have the following functions: -h or -? Output basic help. -H Output extended help. -v Output version number. -c arg Set contiguous and indexed contiguous file conversion options according to "arg". The only option is "allstring" which treats non-BCD file records as all string data. A record section will be output for non-BCD files defining the record as a single string. Manual editing of the record section will not be required. -f arg Set formatted file conversion options according to "arg". The option can either be "inttobcd" or or "extended". The "inttobcd" option converts 16-bit binary integer fields to BCD integers and may cause overflow errors during conversion. The "extended" option allows the use of binary integers and 5 word BCD floating point. An "extended" file can not be accessed by UniBasic. -i arg Set index conversion options according to "arg". The only option is "iriskeys" which converts IRIS or binary keys ("k" files) to ASCII strings. -k Use random key insertion algorithm. -l Use dL4 LUMAP and/or DL4LUST. -o dir Build destination files in directory "dir". -p filename Output conversion layout profile to "filename". -r Replace destination file. -t arg Select files according to "arg" which can be any combination of "b" (BCD files), "n" (non-BCD files), "c"(contiguous), "f" (formatted), and "i" (indexed contiguous). -u Enable "records-in-use" count (default setting). -U Disable "records-in-use" count. filename Conversion layout filename. sourcedir Source data file directory. Additional information on how to create file definitions in the conversion file can be found in the ctool manual or in dL4 6.1 Command Reference manual (when it is available). o dL4 is now available for use on systems running Mac OS X 10.3 or later. Please contact Dynamic Concepts for information on how to configure Mac OS X for use with dL4. 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 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 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: many of the standard terminal definition files did not draw lines or boxes correctly. o Bug fixed: the VT100 terminal definition file did not clear the state of the character attributes. o Bug fixed: the "printer/pcl.prf" printer definition file did not draw boxes correctly. 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 "-c checksum" option of the tools/checksum utility did not work in MD5 mode if the checksum value had less than 32 digits. 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. Mar 7 2005 (Maintenance Release 5.3.6) o Bug fixed: FoxPro Full-ISAM memo fields did not work on Linux x86 systems and possibly some other platforms. 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. Sep 28 2004 (Maintenance Release 5.3.5) 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 Bug fixed: when using dL4Term, 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 in the MySQL SQL driver. 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 environment variable 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" 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: 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: when upgrading dL4, an error occurred if "scope" or "run" were currently in use. 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. 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 bold and this is underlined." 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. May 7 2004 (Maintenance Release 5.3.1) 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. o Bug fixed: the Replace$() and ReplaceCI$() intrinsic string functions corrupted memory when replacing a single character with a multiple character string. Apr 14 2004 (Release 5.3) 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 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 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 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 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 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 As with all other GUI mnemonics, this mnemonic can only be used with dL4Term or in dL4 for Windows. 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 A new function, MSC$(9), has been implemented to return the native absolute path of the directory containing the current program file. o A new utility, TESTLOCK, has been added to the Tools/ directory. This utility can be used to test network file system support for record locking. Use the command "testlock -h" to display usage instructions. o The dL4 QUERY utility (tools/query) has been extended to display whether a Full-ISAM field is an IDENTITY field. 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 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 EOPEN statement and the intrinsic CALL LOCK() can now be used with uniBasic (non-Universal) Indexed Contiguous, Contiguous, and Formatted files. If a file is opened using EOPEN or locked with CALL LOCK(), the file cannot be opened by other dL4 users. Unlike portable or Universal contiguous and formatted files, the EOPEN statement will succeed on uniBasic files that have been opened for shared usage by other ports (this is compatible with uniBasic behavior). o A new driver, "Device Text", has been added to dL4 to support opening devices and named pipes as line oriented bidirectional text streams. Example: Open #3,"pipename" As "Device Text" Print #3;"xxxxxx" Read #3;S$ 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 Two new intrinsic string functions have been added to simplify replacing string values within a string. The function Replace$(Source$,Old$,New$,Count) returns the string 'Source$' replacing the first 'Count' occurrences of the string 'Old$' with the string 'New$'. All occurrences of the string may be replaced by omitting the 'Count' parameter or using 'Len(Source$)' as the value of 'Count'. The function ReplaceCI$() is identical to Replace$() except that it uses a case-insensitive search for 'Old$'. Since Replace$() and ReplaceCI() are intrinsic functions, a DECLARE statement is required in order to use the new functions. 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. This statement is intended for use with dL4Term or dL4 for Windows. o The intrinsic CALL PROGRAMDUMP, the PDUMP command, and the force port dump feature now support options to control line width and to enable printing string values that include nulls. The options are: COLUMNS= NULLS= Options are specified in the CALL PROGRAMDUMP options parameter or in an options ("(options. . .)") field in the filename. The default line width is now 78 columns and long lines will be broken into multiple lines to improve readability. A width of zero will print lines of any width in a single line. The NULLS options may be used with or without a boolean value (the option "NULLS" is equivalent to "NULLS=TRUE"). If enabled, null characters in a string are printed as "\0\". o A new utility, BITSTERM, is available in the Tools/ directory. The BITSTERM utility is identical to the uniBasic TERM utility. 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: tab characters in source line comments are expanded into spaces using the indentation value as the tab width. o Behavior change: TRACE output now includes program file name and procedure name if they are available. o Bug fixed: message queues belonging to other ports were sometimes deleted when a new dL4 session was started on a busy system. o Bug fixed: RUN and LOADSAVE would sometimes hang after running on some Linux systems (usually multiprocessor systems). 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: when using dL4Term, the EDIT command deleted all "\177\" characters from string literals. o Bug fixed: the PORT 6 statement returned zero instead of -1 when the blocking port number was unknown. o Bug fixed: in various drivers, open options were ignored if they occurred after a boolean open option. Feb 9 2004 (Maintenance Release 5.2.6) o Bug fixed: input timeout on terminals, devices, and files sometimes failed on Linux systems causing applications to hang or lose data due to buffer overflow. 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: when using dL4Term, the EDIT command deleted all "\177\" characters from string literals. Jan 9 2004 (Maintenance Release 5.2.5) o Bug fixed: packed data was sometimes written incorrectly to uniBasic or Universal indexed-contiguous, contiguous, and formatted files. o Bug fixed: the "L" command in the KEYMAINT and DOKEY utilities did not display the record number or key length. Aug 12 2003 (Maintenance Release 5.2.4) o Behavior change: support READ RECORD and WRITE RECORD of arrays with uniBasic indexed contiguous files. This matches the behavior of portable indexed contiguous files. o Bug fixed: the DUPLICATE statement produced incorrect filenames for FoxPro Full-ISAM files if a trailing "!" was used. o Bug fixed: the bridge driver could not insert records in a MySQL table if a key contained a DECIMAL(n,0) column. Jul 3 2003 (Maintenance Release 5.2.3) o Compatibility with RedHat 9 Linux has been improved. o Behavior change: the printer/pcl.prf and printer/simple.prf printer definition files have been modified to ignore illegal characters rather than generating an illegal character error. o Bug fix: the MAKEHUGE utility did not work with indexed contiguous files that had key translation filters defined. May 16 2003 (Maintenance Release 5.2.2) o A new option, "uselust", has been added to the DL4LUST environment variable to import a search path from the "LUST" environment variable. The imported search path is placed after any entries in DL4LUST. Example: DL4LUST="(uselust)" export DL4LUST 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 The SCOPE BASIC mode LIST command now supports a "-c" option to disable paging of the listing. o The tools/convert.prf and tools/convbits.prf conversion profiles have been enhanced with examples for the "[CallByFilename]" section, the "[OutputFormat]" section, and the ReportUndefinedProcedures setting. o Behavior change: ports belonging to another user can now be evicted without root privileges if the target port has the environment variable DL4ACCEPTPORTCMDS set to TRUE. o Bug fix: when an indexed contiguous file was opened in read-only mode (ROPEN), recent changes to the index were sometimes ignored. o Bug fix: the FoxPro Full-ISAM driver "dataext" option created files with duplicated extensions ("file.ext.ext"). Apr 25 2003 (Maintenance Release 5.2.1) o The window driver can now use "clear to end of line" operations to improve performance on "magic cookie" terminals such as the Televideo 925. To enable this feature, the line "UseCL=True" must be added to the "[Settings]" section of the terminal definition file (for example, the "tvi925" file). This optimization may cause problems on some terminals or terminal emulators that have non-standard "clear to end of line" operations and, for this reason, the feature is not enabled by default. 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=" 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 Bug fix: the CHARSET and NUMMAP options could not be used when building a formatted file. Apr 2 2003 (Release 5.2) o Platform 6D, Linux x86, is now compiled and linked on RedHat 7.3 Linux. This platform update from RedHat 6.1 adds support for files larger than 2 gigabytes, but may cause incompatibilities with old Linux systems (RedHat 6.x or earlier). It is recommended that Linux systems should be upgraded to RedHat 7.1 or later or other similar Linux versions. 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 Into test (count,label) Values ("+SQLV$(C,L$)+")" Search #1;"Insert Into 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. Examples: Field=LASTPAYMNT,114,2%,,,DTON("YYDDD") KeyPart=DATE1,0,10,"","0123456789",DTOC("YYYYMMDD") KeyPart=NUM2,5,7,"","0123456789",NTOC("####.##") o The Full-ISAM Bridge driver profile has been extended to support two 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 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 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 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 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 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. The 'fg bg WCSETCOLOR' mnemonic sets the GUI element text and background colors according to the RGB color values "fg" and "bg". The standard system colors can be restored by the 'WCRESETCOLOR' mnemonic. These mnemonics can be printed to a GUI element after it is created to change its current colors. As with all other GUI mnemonics, these mnemonics can only be used with dL4Term or in dL4 for Windows. o A new GUI 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. As with all other GUI mnemonics, this mnemonic can only be used with dL4Term or in dL4 for Windows. 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 (terminal) 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 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: the "wyse60" and "wyse60-43" terminal definition files now recognize either form of the INSERT key to toggle the input edit insert mode. o Enhancement: the "wyse60" and "wyse60-43" terminal definition files now support the 'PGMFN' mnemonic to program function keys. 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 ("") 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 Bug fixed: the SPAWN statement sometimes failed when a program path included embedded spaces. 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 Bug fixed: when converting source files, functions in CALL arguments were sometimes converted to variables. o Bug fixed: the 'EPW' mnemonic could not be defined in terminal definition files. 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 Beta bug fixed: SCOPE and RUN could not be used under SCO OpenServer 5.0.5 with the original system socket libraries. o Beta bug fixed: the MySQL driver was always reported as "not licensed" by RUN (it worked properly in SCOPE). Jan 3 2003 (Maintenance Release 5.1.5) o Platform E9 (HPUX) software is now compiled for HPUX version 11 rather than version 9. This and later releases of dL4 for HPUX may not be fully compatible with versions 9 or 10 of HPUX. 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. Dec 23 2002 (Maintenance Release 5.1.4) o Bug fixed: 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. 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: a memory violation sometimes occurred in printer scripts that used the TRANSLATE= option if the output path was incorrect. o Bug fixed: the 'EPW' mnemonic could not be defined in terminal definition files. Nov 25 2002 (Maintenance Release 5.1.3) 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 Behavior change: the pipe driver ('OPEN #c,"$command"') now sets standard error in the pipe child process to output to /dev/null. Previously, error messages output by the child process were output to the parent's standard error. This corrupted the user's screen or caused other problems. 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. Sep 27 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 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 environment variables 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. o Bug fixed: the DIR utility reported an illegal subscript error when it listed a FoxPro Full-ISAM file. 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: on some platforms, dL4 5.1 could not be used with dynamicXport. Jul 10 2002 (Release 5.1) o Platform 99 software is now compiled for SCO OpenServer 5 rather than for SCO Unix 3.2.4. It is recommended that anyone using SCO Unix 3.2 upgrade to SCO OpenServer 5. 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 be 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 Behavior change from earlier beta release: if the runtime parameter DL4DEFLU is defined and a file is built without specifying a directory, then the file will be built in the DL4DEFLU specified directory in the first DL4LUST directory. If DL4LUST is not defined, then the file will be built in the DL4DEFLU directory under the current directory. An error will occur if the DL4DEFLU directory does not exist. 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=" 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 "" and "" in the "case=" argument must be replaced by the desired operating system ("") and user ("") 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 (Unix only) 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 (Unix and Windows compatible) 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 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 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 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 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 Enhancement: CALL ENV() now uses less memory if the same environment variable is set repeatedly. o Enhancement: the intrinsic CALLs SETGLOBALS() and GETGLOBALS() now support up to 1000 items (the previous default limit was 30). 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 IRIS 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, "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 A new option, 'PROGRAM TAG "text"' has been added to 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 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 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 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 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] ReportUndefinedProcedures=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 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 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 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 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 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 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,)" and "dl4c(For,=)" to allow "dl4v()" references to the current array index number. o The run utility now returns an "unsuccessful" exit status to the operating system if a program exits with a STOP statement. 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 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 A UniBasic compatible PORTS runtime parameter has been implemented to set a user's port number according to the user's terminal name. By default, dL4 for Unix tries to use the numeric portion of the terminal name as the port number. For example, a user logged in on /dev/tty14 will try to use port number 14 if it is available (and assuming the PORT runtime variable isn't set to explicitly select the port number). The PORTS runtime parameter makes it possible to select which port number is used with a terminal name. The PORTS value is a list of colon separated terminal names where the first terminal name is port 0, the second name is port 1, and so on. If the specified terminal name contains an asterisk ("*"), a wildcard match will be performed and, if a match occurs, the current port number plus any number from within the wildcard portion will be the port number. If a name begins with a pound sign ("#"), the number following the pound sign is used to set the current port number for any subsequent terminal names. A name of "#any" will cause subsequent terminal names to use the highest available port number. o The PORT runtime parameter has been extended so that a value of "any" will cause the highest available port number to be used regardless of the terminal name. 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 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, 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 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 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 "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 "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 If a relative program path is used with the "run" utility, the native case-sensitive filename is tested in the search path before other possible paths. 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 by "inetd". The timeout option causes an error when reading from the socket if the remote system crashes, is rebooted, or loses its network connection. On most Unix systems, the timeout period is only configurable in the Unix kernel itself and any non-zero value can be used for "seconds". 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 Two new internal mnemonics, 'BPW' (Begin Protect in Window) and 'EPW' (End Protect in Window), have been defined to control how protected fields are displayed in windows. These mnemonics should not be used directly in applications. If these mnemonics are defined in a terminal definition file, then they will be used to set display attributes for protected fields in windows. The mnemonics are currently defined in the wyse50 and tvi925 terminal definition files to display protected fields as dimmed characters by using the standard protected field attribute. Previously, protected fields in windows using the wyse50 and tvi925 terminal definitions were displayed without any visible attributes. o Enhancement: pressing control-B (or any other SIGNAL character) can optionally be detected immediately rather than only during an INPUT. Unix supports only two character interrupts, SIGINT and SIGQUIT, which are normally used for the ESCAPE and ABORT keys. Other keys can only be detected during INPUT. If the ESCAPE or ABORT keys are undefined, dL4 will now use the unused character interrupt for the control-B (SIGNAL) key. It is also possible to specify ESCAPE or ABORT as non-interrupting keys in the terminal definition "[InputActions]" section so that control-B can be an interrupting key. Example: 'EOT'=Abort,nointerrupt or 'EOT'=Abort,n 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 "wyse60" and "wyse60-43" terminal definition files now support the 'NR' and 'WD' mnemonics. 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 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 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 It is now possible for "SIGNAL 1", SEND, and PORT commands to send data to or request information from dL4 programs that were started by a different user. This feature requires the installation of version 3.8 or later of Passport for Unix. o Behavior change: CALL TRXCO() and "PORT 2" statements can no longer send commands to interactive ports unless the environment variable 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 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 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 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 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 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 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: 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 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 "" attribute or using the intrinsic CALL VOLLINK(). o Behavior change: mnemonics in a window title will be ignored rather causing an "illegal character" error. 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 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 Terminal 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: # dL4opts=translate=C:\progra~1\dl4\printer\dl4printer.prf # dL4opts=openas=Window Terminal Printer,options=landscape=t The TRANSLATE= option must occur before the OPENAS= option. 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 recorded date/time values. o Behavior change: the SCOPE LIST and SHOW command 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 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 Bug fixed: an ROPEN of a pipe ("$file" or "$$file") sometimes failed or caused a memory violation. 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: the DL4PROGRAM environment variable was not set for scripts using a "# dl4opts" options line. 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 "ConvertUndefinedFunctions=True" setting in a conversion profile caused errors when converting programs that used library defined functions. o Bug fixed: setting "ConvertUndefinedFunctions=True" in a conversion profile resulted in compile time errors at each intrinsic CALL. 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: 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: breakpoints set in the debugger for the current program unit were ignored. o Bug fixed: an error occurred if the mnemonic 'n PI' (such as '5PI') was output with the wyse60, wyse60-53, wyse50, or tvi925 terminal definition files. 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: 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 Beta bug fixed: programs using CALL-by-filename are no longer forced to the latest program object revision unless "OPTION ARGUMENT CHECKING IS WEAK" is used. Dec 26 2001 (Release 4.4.1) o Fix bug: the 'IOBI' and 'IOBC' mnemonics did not work correctly with a dL4Term client. o Fix bug: the CALL RENAME() intrinsic CALL did not always work and sometimes corrupted memory. 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 When using dL4Term, it is now possible to run programs on the user's PC. 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 dL4Term configuration, the user will be prompted via a message box to permit or deny running the command. See the dL4Term documentation and readme.txt file for information on changing the message box configuration. This feature requires using dL4Term 4.3.1.2 or later. o When using dL4Term, it is now possible to open a printer on the user's PC on a channel. Opening the "Window Terminal Printer" driver opens the dL4 for Windows "Selected Page Printer" on the user's PC and allows the user to select a printer. The driver supports the same mnemonics and open options as the "Selected Page Printer" driver. The OPEN statement will return an error if the user cancels the printer selection. The driver can be opened directly as in the statement: OPEN #1,"filler" As "Window Terminal Printer" or indirectly using a printer script: OPEN #1,"$AUXPRINTER" where "AUXPRINTER" is a script file found somewhere in the user's PATH on the Unix system. The following is an example of such a printer script: # dl4opts=openas=Window Terminal Printer,options=landscape=t The auxiliary printer mnemonics (such as 'BA' or 'EA') shouldn't be used when the "Windows Terminal Printer" driver is open. This feature requires using dL4Term 4.3.1.2 or later. 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. These mnemonics are currently supported only in dL4Term 4.4, but will they be available in the standard terminal definitions (such as Wyse 60) in the future. o The window driver now supports new settings to control mnemonic behavior in dL4 windows. If the line BDIsBP=True is included in a terminal definition file "[Settings]" section, dL4 will change the behavior of the 'BD' and 'ED' mnemonics in a dL4 window to be identical to 'BP' and 'EP'. If the line BPIsFXBP=True is included in "[Settings]", then 'BP' is treated as 'FX BP' in dL4 windows and 'EP' is treated as 'EP FM'. These two settings can be combined so that 'BD' becomes 'FX BP' and 'ED' becomes 'EP FM'. o The window driver now supports new settings to control mnemonic behavior in dL4 windows. If the line FormattedILDL=True is included in a terminal definition file "[Settings]" section, dL4 will perform insert and delete line operations in dL4 windows even if formatting ('FM') is enabled. Normally, the 'IL' and 'DL' mnemonics are ignored in dL4 windows if formatting is enabled. This feature is not supported by the current version of dL4Term, but it may be supported in the future. o Character attributes, such as reverse video, are now supported in dL4 windows on "magic cookie" terminals where changing attributes use a displayed space on the screen. Such terminals include the Wyse 50, the Televideo 925, and emulations of those terminals. In previous versions of dL4, the BR/BB/BU/BD mnemonics had no effect when displayed in a dL4 window if the terminal used "magic cookies". In order to display attributes on magic cookie terminals, a space character must be displayed at or preceding the point where the attribute is turned on. o The window driver now supports simulating "magic cookie" behavior on any terminal. If the line BRIsBRSP=True is included in a terminal definition file "[Settings]" section, dL4 will change the behavior of the 'BR', 'ER', 'BB', 'EB', 'BD', 'ED', 'BU', and 'EU' mnemonics to mimic that of a "magic cookie" terminal. The mnemonics will output a space character and will change the character attributes to the specified value from the following character up to the associated ending mnemonic. One common use of this behavior is to turn highlighting on and off on a string of characters by printing a 'BR' mnemonic or a space character at a single position preceding the string (the string must be followed by a unchanging 'ER' mnemonic character). This feature can be used on the current version of dL4Term if the dl4term.chwin terminal definition file is used. Note that dl4term.chwin does not support GUI programming. o The window driver now supports a new setting to control the terminal type returned by SPC(13) or MSC(32). If the line TermType=50 is included in a terminal definition file "[Settings]" section, dL4 will return 50 as the terminal type. This setting can be used to set the terminal type in the dL4Term terminal definition file. o The "scoansi" terminal definition file has been changed for use with the new SCO OpenServer 5.0.6 (or later) console. The "ansi" terminal definition file can be used with other SCO systems. 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 The CHF#(100 + c) function, which is defined to return the file creation time, has not been supported in previous dL4 for Unix versions because Unix does not record file creation times. In dL4 for Unix 4.4 and later, this function will return the oldest of the access, modification, and inode modification times. Under dL4 for Windows, the function will continue to return the recorded file creation time. 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 The standard terminal definition files have been modified to eliminate display problems when using the up and down arrows with the SCOPE history feature. 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 to determine what port or process has locked a specific record of a file. 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. If the record is locked, then "PortNumber" will be set to the port number of the process that has locked the record. If "ProcessID" is specified, it will receive the Unix process id number of the process that locked the record. If the record is not locked, than "PortNumber" and "ProcessID" will be set to -1. "PortNumber" will also be set to -1 if the process that locked the record is not a dL4 process (note that UniBasic processes are not dL4 processes) or if the dL4 process is executing on a remote system. In this release, CALL WHOLOCK() is supported only for formatted, contiguous, and indexed contiguous files. CALL WHOLOCK() is an OS dependent CALL and it should not be used in dL4 for Windows. 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 ENV() has been extended with a second syntax: Call Env(mode,name$,value$) where "mode" is 1 to read the environment variable "name$" into "value$" and "mode" is 2 to set a new value. For mode equal to 1, the following special value names will be recognized and will override any environment variables with the same name: PID Unix process id GID Unix group id UID Unix user id 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. The standard file extensions (".dbf", ".cdx", and ".fpt") will always be lower case under Unix. 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: a SYSTEM "cmd" statement sometimes caused odd characters to be displayed when using dL4Term. 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 15 2001 (Release 4.3.2) o The pipe driver ('OPEN #1,"$xxxx"') now accepts multiple "# dl4opts=" lines at the beginning of a shell script. This makes it easier to specify multiple pipe driver options. Each option line can contain multiple options, but an individual option cannot span lines. o Bug fixed: dynamicXport could not be used if it was licensed as a demonstration product. 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 Platform 29 (Power AIX) now uses the same binaries as Platform 07 (PowerPC AIX). o A new open option, "binary=", 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 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 A new intrinsic CALL, NCRC32(), has been implemented for compatibility 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 Phantom ports created by the PORT statement, the SPAWN statement, or by CALL $TRXCO are no longer counted when checking the licensed number of users. o The checksum utility in the tools directory now accepts a "-m" option to generate MD5 checksums instead of CRC-32 checksums. 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. This release of dL4 contains a beta release of these CALLs and the CALLs will not function after June 1, 2001. 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 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 function, MSC$(8), has been implemented to return the native path separator string. Under dL4 for Unix, 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 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 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 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 the Windows page printer driver. o A new mnemonic 'n LANDSCAPE' has been defined to select landscape mode (n equals 1) or portrait mode (n equals 0) on printers. o A new mnemonic 'n LPI' has been implemented to set the number of lines per inch when printing to the Windows 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 Windows 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, 'MARGIN', has been implemented to set horizontal ('w MARGIN') and vertical ('w,h MARGIN') margins in the Windows Page Printer driver. The arguments to the mnemonic are margins expressed in grid coordinate system units. For example, if the current coordinate grid was tenth inches ('100GRIDENGLISH'), then a half inch left margin could be set by '5MARGIN' or a half inch left margin combined with a one inch top/bottom margin could be set by '5,10MARGIN'. o A new mnemonic, 'n WCWHERE' has been added for use with dL4Term. The mnemonic causes the GUI input element that currently has the input focus to return the action 'n' string as input. If the window itself has the input focus, a 'CR' will be returned. o When using dL4Term, 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 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 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 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 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 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. This CALL was added for use on Windows systems and has no effect when called in dL4 for Unix. o A new open option, "RTRIM=", 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 A printer directory has been added to /usr/lib/dl4 to contain sample printer scripts and printer definition files. In this release, the printer directory contains the file pcl.prf which is a printer definition file for use with pfilter and PCL based printers. o The UniBasic Indexed-Contiguous file driver now supports alternate character sets, ANSI1 and Toggled ANSI1, that preserve the lower 8 bit binary value of data read into or written from strings. These character sets can be used if application store binary information, such as packed numeric fields, in strings. If these alternate character sets are used, mnemonic characters can not be read from or written to UniBasic Indexed-Contiguous files. This option requires recompiling and relinking the UniBasic Indexed-Contiguous file driver (driver/ubcontig.c) using the dL4 Development kit. See the file driver/ubcontig.c for instructions on how to enable the alternate character sets. o Behavior change: directories can now be opened with the ROPEN statement or the "" access permissions. o Behavior change: for compatibility with UniBasic, the function MSC(n) now returns -1 for n equal to 4, 8 through 17, 21 through 29, and 36. Previously, a parameter range error was generated. Note that UniBasic returns a random platform dependent value for MSC(29) rather than -1; this behavior was not intended and has not been duplicated in dL4. 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," [1:40] <00> filename" 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: a SCOPE command with inverted line numbers ("500 DELETE 100") sometimes caused a memory violation. o Bug fixed: printing the value of a non-existent structure variable member sometimes caused a memory violation. o Bug fixed: when using dl4Term, closing a window and then immediately opening a new window with the same channel number caused some output for that new window to be directed to the main window. o Bug fixed: the UniBasic Indexed-Contiguous file driver sometimes reported an error when the "" attribute was specified when building a file. o Bug fixed: if a non-existent record was deallocated in a Portable or Universal Indexed-Contiguous file, the driver ignored the operation (as intended for compatibility), but incorrectly decremented the records-in-use count. 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: a parameter mismatch in an EXTERNAL FUNCTION call sometimes caused a memory violation. 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. o Bug fixed: '/usr/bin/run -t ""' sometimes failed. Aug 3 2000 (Maintenance release 4.2.1) o An error which could potentially lead to the corruption of the index portions of Indexed-Contiguous files has been corrected. All 4.2 or 4.2 beta installations of dL4 for Unix should be updated to dL4 4.2.1. The error was specific to Unix and did not effect dL4 4.2 for Windows. 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 Unix systems that support files larger than 2 gigabytes. 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" Currently, huge files are supported on UnixWare 7 and AIX 4.3. They are not supported on SCO OpenServer because OpenServer does not allow user files to be larger than 2 gigabytes. In order to build huge files on UnixWare 7 or AIX, the file system must be configured to support files larger than 2 gigabytes. Please see the UnixWare or AIX OS documentation for instructions on how to configure file systems. 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. o The "H" option letter ('BUILD #1,"[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 operating systems that support user files of that size (see above). 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 environment variable 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 'ADD #c;"Filename"' statements. If a file consists of multiple files, such as the data and index portions of 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 by the DL4EMAILSERVER environment variable or the host system. "PORT=n" SMTP port number. Defaults to the standard SMTP port (25). "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 change the default 5 minute 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 is optional and can be defined via the "SERVER=" option or in the DL4EMAILSERVER environment variable. If the server name is undefined, the host Unix system will be used. 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. o When using dL4Term, 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 dL4Term "Printer" sub-menu of the "Preferences" menu. 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. These mnemonics can be used without dL4Term if the mnemonics are defined in the appropriate terminal definition file and if the mnemonics are output to the main window. When using Dynamic Windows ("WINDOW OPEN"), the "WINDOW OFF" statement or the CALL DUPCHANNEL intrinsic should be used to output the mnemonics to the main window. o When using dL4Term, the 'WS', 'ES', 'SO', and 'SF' mnemonics are now supported to display a status line 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. These mnemonics can be used without dL4Term if the mnemonics are defined in the appropriate terminal definition file. o When using dL4Term, 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 size to provide a width of 133 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. This mnemonic is currently defined in the dL4Term terminal definition file only, but it can be implemented for other terminal types by modifying their terminal definition files. The 'RF' or 'XX' mnemonics can be used to reset all function keys to their original values of 'Fn'. Note for dL4Term users: the 'PGMFN' mnemonic supports function keys 'F0' through 'F63', however, dL4Term's default configuration only defines keys for 'F1' through 'F12'. If, for example, you want to use shift-F1 as 'F13' in dL4Term, use the dL4Term "Preferences->Keyboard" menu item to define the additional keyboard translation. The "Keyboard" dialog and methods of copying keyboard configurations are described in the dL4Term Reference Guide. 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. This mnemonic is currently defined in the dL4Term terminal definition file, but it may be possible to define this operation for other terminals by modifying their terminal definition files. o When using dL4Term, the user can end their telnet session by selecting the DISCONNECT menu action, the exit button, or the "close" action of the system menu. Exiting in this manner prevents the application from cleaning up any partially written transactions. 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 dL4Term or continuing the application. PChr$(1,"text");'ONCLOSE' - Display "text" within a message box and prevent the user from exiting dL4Term. PChr$(2,"text");'ONCLOSE' - Prevent the user from exiting dL4Term 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. 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 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 general, the port number should be greater than 1023. Note: on most Unix systems, a "listening" server can be implemented more robustly by having the system inetd process listen for requests and start dL4 processes as required. For example, adding the line below to /etc/inetd.conf will cause inetd to listen on the port "test" and start the dL4 program "pgm.dl4" whenever anyone attempts to open a socket on the port "test". test stream tcp nowait user /usr/bin/run run -t "" /home/user/pgm.dl4 The dL4 process will run as the user "user". The socket will be open on the standard input and output channels and accessible through normal INPUT and PRINT statements. The port number "test" must be defined in the file /etc/services. The '-t ""' option to run tells run to use the default terminal definition (see the "-t" option description elsewhere in this document). After modifying the file /etc/inetd.conf, the system must be rebooted or a SIGHUP signal must be sent to the inetd process. o Two new GET statement operations have been defined for use with TCP socket drivers. The following statement will retrieve as a character string (usually "nnn.nnn.nnn.nnn") the remote IP address connected to the socket open on channel C: Get #C,-1598;S$ This function would typically be used with the "TCP Listen Socket" driver to determine the IP address of a client system. The statement below will retrieve the local IP address connected to the socket open on channel C: Get #C,-1599;S$ o A new SYSTEM statement mode has been implemented: SYSTEM 30 executes system commands with standard input and output assigned to /dev/null. This eliminates most screen output by the system command. 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 Four new terminal definition file options have been added in the "[Settings]" section for use with dL4Term. These settings change the normal behavior of some mnemonics to match alternate definitions used by some developers. Each setting is a boolean value which, if set to "TRUE", enables the associated mnemonic behavior. The new optional settings are: SwapWDAndNR - Redefine the 'WD' mnemonic to select a narrow font and a typically 132 column window width. Redefine the 'NR' mnemonic to select the normal wide font and the normal window width. BCIsNR - Redefine the 'BC' and 'EC' mnemonics to function just like the 'NR' (Narrow Font) and 'WD' (Wide Font) mnemonics. These redefinitions are not effected by the SwapWDAndNR setting. BXIsNR - Redefine the 'BX' and 'EX' mnemonics to function just like the 'NR' (Narrow Font) and 'WD' (Wide Font) mnemonics. These redefinitions are not effected by the SwapWDAndNR setting. BXIsWD - Redefine the 'BX' mnemonic to function just like the 'WD' ('Wide Font') mnemonic. The 'EX' mnemonic is redefined to function as a 'NR' (Narrow Font) mnemonic. These redefinitions are not effected by the SwapWDAndNR setting. Example: [Settings] SWAPWDAndNR=True BXIsNR=True 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 Change from earlier beta release: the email driver now uses native filenames for attachments. o Enhancement: the socket driver now supports a "partial=" option to control whether a read terminates as soon as at least one character has been read (default or "partial=true" behavior) or waits until the destination variable has been filled ("partial=false" behavior). This option is specified in the option field when opening a socket. Example: Open #1,"(partial=false)server:servicename" As "Socket" 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 terminaltypepath" option has been added to RUN to select the terminal definition file. This option may be needed when using RUN to execute dL4 programs as network services via inetd. o Behavior change: to increase compatibility with the character oriented window driver, independent windows can now be moved using the main window coordinate grid regardless of which window driver is used. In previous versions of dL4, independent windows could be moved if the character oriented driver was used, but this was an "accidental" feature. Independent windows without the "TITL" style will no longer have a minimal border when using dL4Term. 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 <"."> where the sign and decimal point are optional. Entering an illegal character will be rejected. Note: the edit box may return a return a value such as "-", ".", or "-." if the user starts to enter a legal number but never adds the expected digits. o The 'MH' (Move Home) mnemonic is now supported in edit boxes such as 'WCSTRING' 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 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 Two previously optional intrinsic CALLs, GetGlobals() and SetGlobals(), are now standard CALLs and do not have to be installed using the development kit. o Two Windows 95/NT oriented intrinsic CALLs, GetRegistry() and PutRegistry(), have been implemented to return errors whenever called under Unix. This addition permits programs using the CALLs to be successfully linked in dL4 for Unix. Programs should ignore the errors or take alternate action to replace the registry functionality. 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: 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: when used with dL4Term, the 'NR' and 'WD' mnemonics did not update the MSC(33) and MSC(40) function values (number of columns). o Bug fixed: when using dL4Term, a selection in a list box or drop-down list box is reported immediately if the value changed option is used. o Bug fixed: when using dL4Term, selecting a value from a drop list of a GUI element was not reported when requested by the WCACTION mnemonic. o Bug fixed: the dL4Term terminal definition file now defines the DELETE key as a delete character input action. o Beta bug fixed: text printed to the email driver after adding an attachment file corrupted the attachment. o Beta bug fixed: normal and huge Indexed-Contiguous files could not be opened at the same time. o Bug fixed: a FoxPro Full-ISAM file with memo fields and a deleted record index did not have the memo fields written when new records were added. 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: the ProgramDump() intrinsic CALL did not report the current position correctly. 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: a memory violation could occur if a SAVE command was executed after an immediate mode statement. o Bug fixed: a program cache belonging to an older version of dL4 will be ignored. Note: when using multiple version of dL4 and a program cache, each version should use a different cache name in the DL4CACHE environment variable. Nov 17 1999 (Release 4.1) o Support has been added for graphical user interface (GUI) programming when dL4 is used with dL4Term, a GUI terminal emulator for Windows 95, Windows 98, and Windows NT. This allows dL4 GUI programs to run under both dL4 for Windows and dL4 for Unix. dL4Term is installed on Windows PCs and uses a standard Telnet connection to communicate with Unix host systems. Rather than emulating a character oriented terminal, dL4Term supports a GUI oriented terminal model with multiple windows and graphic controls such as buttons and list boxes. dL4Term is a separately available licensed product. Visit our web site at www.dynamic.com or contact the Dynamic Concepts Sales department for more information on dL4Term. o When used with dL4Term, the following new mnemonics can be used for graphical user interface programming: '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 When used with dL4Term, 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 When used with dL4Term, 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 New graphic features have been added for use with dL4Term. The following new mnemonics can be used with dL4Term: '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. '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. '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 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 and current font. 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 UnixWare 7 or AIX 4.3 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" In order to build these file types, the file system must be configured to support large files. Please see the UnixWare or AIX OS documentation on instructions on how to configure file systems. 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 An OPTION DEFAULT statement has been added to dL4 to set options for all program units in a program module (file). 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 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 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 A TCP/IP socket driver has been implemented for the SCO Unix (99), SCO UnixWare (55), and AIX (07 and 29) platforms. 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 the host system: 10 Dim L$[100] 20 Open #1,"localhost:daytime" As "Socket" 30 Read #1;L$ 40 Close #1 50 Print L$ The driver does not support "listening" for connection attempts, but standard Unix network service "listening" and startup mechanisms ("/etc/inetd.conf") can be used to configure dL4 programs as network services. o The ERRSET, ERRSTM, ESCSET, ESCSTM, INTSET, and related statements can now be used in external procedures. o The command "RETURN" has been added to the debugger. This command causes execution to continue until the current procedure exits. o The command " 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 String parameters can now be used in terminal and printer definition files. A mnemonic with string parameters is specified in the file using dollar signs ("$") to represent string parameters. For example, a 'S1' mnemonic with one numeric and one string parameter would be specified as '#,$S1'. The following string operators can be used with string parameters: %$c pop index value i from stack and then push the i'th character of the string stack onto the stack. %$l pop index value i from stack and then push the length of the indexed string in the string stack onto the stack. %$"cc" Push string literal onto string stack and push string index onto stack. %$D Delete string from top of string stack. %$F Compare, ignoring case, Tos string to N (Tos - 1) strings at Tos - 3, Tos - 5, ... If matched, return integer from Tos - 2, Tos - 4, ... (pairs of strings and integers). If not matched, return zero. 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, "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 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 "U" option letter ('BUILD #1,"[10:100]file"') can be used to select the "Universal" format when creating a Portable Formatted, Contiguous, or Indexed file. 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 environment variable, 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 environment variable 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 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 A new terminal definition file setting "AcceptPartialKey" has been added to control what happens when a function key leadin character (as defined in the "[FunctionKeys]" section) is not followed by expected characters. If "AcceptPartialKey" is set to "TRUE", the leadin characters will be retained as separate input characters. If "AcceptPartialKey" is set to FALSE (the default), the leadin characters will be discarded. To use this feature, define the value "AcceptPartialKey" in the "[Settings]" section of the terminal definition file: [Settings] AcceptPartialKey=True 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 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 Behavior change: the READRECORD and WRITERECORD statements now obey the FILE ACCESS RAW option. 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: positioning to record 0 ("READ #c,0;F$") immediately after opening a channel to a directory no longer causes an error. 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 socket driver now translates numeric IP addresses without first attempting a name lookup. Feb 1 1999 (Release 3.2) 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. 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). DL4PORTDUMP is the filename to which the dump will be written. DL4PORTDUMP must be an absolute path; for example, DL4PORTDUMP might be defined as "/usr/appdumps/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 "/usr/appdumps/%PORT%.txt" and a dump was triggered on port 15, then the dump would be written to the file "/usr/appdumps/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 Two new channel functions, CHF(1200+c) and CHF(1300+c), have been defined to return the current column and row positions. 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 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=/usr/lib/dl4/term/vt100)/dev/tty1a" Open #1,F$ As "Serial Terminal" 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. Conversion profiles such as "convert.prf" should be changed to use the new intrinsic calls. A conversion profile defining all of the new intrinsics can be obtained by downloading version 1.4 of the "dL4 Samples & Utilities Kit" from www.dynamic.com. o By default, the pipe driver processes all PRINT statement TAB functions and "comma" alignment before sending text to the printer script. This pre-formatting simplifies printer scripts, but it can not adjust for different font sizes. For example, the TAB function will generate the same number of spaces even if expanded print ('BX') is being used. A new script option, "FORMAT=false", disables the pre-formatting and passes all mnemonics on to the printer script. The printer script can then implement the TAB function ("@x;" mnemonic) and "comma" alignment ('#ALIGN' mnemonic) as required for the varying font sizes. For example, the printer script and printer definition file shown below implement expanded print mnemonics ('BX' and 'EX') on a PCL compatible printer with TAB(x) alignment based on a fixed 10 characters per inch column width. Printer script: # dL4opts=charset=utf-8,format=false,lock=/tmp/lpt1.lk TERMDIR=/usr/lib/dl4/printers export TERMDIR pfilter -c utf-8 pclprinter >/dev/lp00 Printer definition file: [Macros] ; Variable usage ; X current column ; W character width in 10 CPI characters ; a = Increment column counter by current character width ; e = Clear column counter a=%GX%GW%+%SX e=%{0}%SX ; h = Position to specified column at 10 CPI h=%SX\e&a%GX%{72}%*%dH [OutputMacros] ; Initialize to 10 CPI, 6 LPI Init=%{0}%SX%{1}%SW\e(s10H\e&l6D Default=%@%c%Ma Close=\f 'FF'=^L%Me 'CR'=^M^J%Me ; Set to expanded print as 5 CPI, 3 LPI 'BX'=\e(s5H\e&l3D%{2}%SW ; End expanded print and return to 10 CPI, 6 LPI 'EX'=\e(s10H\e&l6D%{1}%SW ; Position to specified column ("@x;") @#=%p1%Mh ; Align to specified column boundary ("PRINT comma") '#ALIGN'=%p1%GW%*%Sw%Gw%GX%Gw%m%-%GX%+%Mh [OutputUnicodeMapping] ; This mapping is set up for 8-bit output on a printer ; using the ISO 8859-1 (i.e. ANSI Latin 1) character set. Set0= 0x0000-0x00ff=0x00 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" for output on channel 2. If "printer" begins with the line: # dl4opts=buildas=text,path=/usr/printers/printer.out! then output to channel 2 would be directed to the text file driver and written to the file "/usr/printers/printer.out". 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 A new terminal definition file setting "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'. To use this feature, define the value "ProtectedNotDim" in the "[Settings]" section of the terminal definition file: [Settings] ProtectedNotDim=True A value of "True" will disable use of the "DIMmed" attribute for protected characters. o Three 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 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)/dev/tty1a" As "Raw" would open the /dev/tty1a 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 A new mode has been added to the ProgramCache() intrinsic CALL. Mode 3, as shown below, returns the error message, if any, that was associated with a failure of the program cache initialization. Call ProgramCache(3, errorcode, initialization_error$) Cache errors are not reported when dL4 performs its initialization: any errors are silently ignored and the cache is not used. 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 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. Sep 9 1998 (Release 3.1.1.1) o Two new standard intrinsic functions, MD5? and ADDMD5?, have been added to dL4. MD5?() returns the MD5 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 ADDMD5?(). 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. BASIC syntax: Dim chksum?[16], intermediate?[128] chksum? = MD5?(var) chksum? = MD5?(var,intermediate?) intermediate? = AddMD5?(var) intermediate? = AddMD5?(var,intermediate?) o The mnemonic 'IOTE' is now supported in dL4 windows. o Bug fixed: if a SYSTEM "command" statement failed due to insufficient system resources, the terminal line was left in an undefined state causing the next input to "hang". o Bug fixed: typing the ESCAPE or INTERRUPT character rapidly on a heavily loaded system could cause the terminal line to be left in an undefined state causing the next input to "hang". o Bug fixed: if record zero was deallocated in a Portable indexed contiguous file, that record was never reused. o Bug fixed: deallocating a non-existent record could disable the count-in-use feature of a Portable indexed contiguous file. o Bug fixed: file lock resources were consumed if a file was open on one channel while it was repeatedly re-opened on another channel. This could eventually cause the system lock resources to be exhausted. o Bug fixed: a sequential read immediately after opening a UniBasic contiguous file returned record 1 instead of record 0. o Bug fixed: ":" was not recognized as a separator during LUMAP translation. As a result, the path "2:file" was not translated to the same value as the path "2/file". o Bug fixed: an address violation could occur if an error occurred while evaluating a single line function (DEF = ). Mar 16 1998 (Release 3.1) 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 program cache). Programs created by this release of dL4 cannot be used by earlier releases of dL4. 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 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 an 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 UniBasic in two ways: 1. There is no "-o" startup option to add new OSNs. Instead, OSNs are added by creating and/or editing the text file /etc/DCI/osn. 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 3.6 or later. A PDN (Product Description Number) is required to use 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 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 directory names of the relative filename. 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=/usr/accounting Mail=/disk2/Mail", the following filenames would be translated as shown: 5/filename -> /usr/accounting/filename Mail/filename -> /disk2/Mail/filename x/5/filename -> x/5/filename (unchanged because "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 "/usr/accounting/abc", but CHF$(802) would return "5/abc". If more than one logical directory is mapped to the same actual directory ("5=/usr/acct 6=/usr/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=/disk2/Mail/Barney") or entire filenames. Such usage 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 "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, UniBasic Formatted, UniBasic 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 release of dL4. o The Portable Formatted, Portable Contiguous, and Portable Indexed Contiguous drivers now support exclusive opens via the "E" access mode ('OPEN #c,"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. To open a file in exclusive mode, the user must have write access to the file. An attempt to open the same file in exclusive mode on two different channels will succeed, but exclusive access will be lost when either channel is closed (this is a UNIX system limitation). o A single memory image of a program or library can now be shared between different processes and users by using a shared program cache. This feature can greatly reduce the amount of memory needed to support multiple users accessing large dL4 programs. Using the cache is largely transparent to both users and applications. Cached program files are accessed using normal program paths and obey the normal rules for lookup and access permission. Programs can be modified and re-SAVEd while the cache is active without disrupting other users. Any users executing the older version of the program from the cache will continue to execute that older version while new users will invoke the most current version. Using the program cache does not require any programming changes in applications. Programs must, however, be reSAVEd (or LOADSAVEd) to use the new program file format. Programs in the pre-3.1 program file format can be executed, but they will not be placed in the program cache or shared between users. The program cache is enabled and configured using the new environment variable DL4CACHE. The value of DL4CACHE is a file specification of the form: " [size] name" where: "" is a standard dL4 file access option such as "<644>" or "". "" is an optional value. "[size]" specifies the size of the program cache as a number of records and a record length in bytes similar to that used for contiguous files. For example, "[256:1024]" specifies a 256 kb cache. Note that a large cache will only consume virtual memory and does not reserve physical memory. If a "[size]" value is specified, the cache will be created if it does not exist. If "[size]" is not specified and the cache does not exist, then no cache will be used. "name" is the name of the Unix semaphore and shared memory resources used by the program cache. Any decimal ("nnn"), octal ("0nnn"), or hexadecimal ("0xnnnn") format name will directly converted to a Unix resource id value (as displayed by the Unix "ipcs" utility). Any other name will be used as a seed to generate a pseudo-random resource name. The standard cache name of "0xdddc0500" should be used unless this value conflicts with other applications or it is desired to maintain several different caches for different groups of users. "name" is a required value. Example: DL4CACHE="<666> [2048:4096] 0xdddc0500" export DL4CACHE If the value of DL4CACHE is illegal or if the cache cannot be accessed, caching will be disabled. The status of the cache can be determined by using mode 0 of the ProgramCache() intrinsic as shown in the "List entries in cache" example shown in the ProgramCache() description later in this document. In order to use a shared program cache, the operating system must be configured to support both shared memory and semaphores. On many Unix systems, the default maximum size for shared memory will need to be increased. Please see your operating system documentation for instructions on how to configure shared memory and semaphores. A program cache is created by the first user that enters dL4 with a DL4CACHE value that specifies a cache size and specifies a cache name that doesn't exist. Once created, a program cache persists until deleted by the ProgramCache() intrinsic (described later in the document) or the operating system is reloaded. The program cache can also be deleted manually by using the Unix "ipcrm" utility to remove the shared memory and semaphore ids used by the cache. Each user accesses the program cache in either the dynamic or the static mode. The cache mode is dynamic if a user has write access to the program cache and static if the user has read-only access to the program cache. Read and write access is controlled by the access permissions specified in the DL4CACHE environment variable (see above). Note that the mode is specific to the user and different users can be setup to use the cache in different modes. If the user's cache mode is dynamic, all programs and libraries are entered automatically into the cache when they are used. If a new program or library is invoked and the cache is full, programs and libraries that have no current users will be deleted from the cache until sufficient space is available. If sufficient space cannot be freed, the new program or library will be loaded into the user's private memory. A typical DL4CACHE value for dynamic mode use is "<666> [16384:1024] 0xdddc0500". This provides a 16 megabyte cache with write access permitted to everyone. A larger or smaller cache can be used depending on the number and size of frequently used programs. The cache is used in a static mode whenever a user lacks write access to the cache. In static mode, the user never enters programs or libraries into the cache. Programs and libraries are loaded into the user's private memory unless a copy of the program file has been loaded permanently into the program cache by a user in dynamic mode via the ProgramCache() intrinsic (described in a later section of this document). Static mode has two very important advantages: it avoids thrashing and offers higher security. A cache used in static mode cannot be corrupted either accidentally or deliberately by a user. Using a cache in static mode is more secure, but it is also more complex. The cache must be created and initialized in dynamic mode before the static mode users enter dL4. For example, suppose a system has two megabytes of frequently used dL4 libraries. At system startup time, a dL4 process would be run with a DL4CACHE value of "<644> [2500:1024] 0xdddc0500". The process would use the new ProgramCache() intrinsic (see below) to add each of the frequently used dL4 library programs to the cache. Other users would then be started in dL4 with a DL4CACHE value of " 0xdddc0500" which provides read-only (static) access. o A new standard intrinsic CALL, ProgramCache(), has been added to dL4. The intrinsic procedure ProgramCache() is used to read the current shared program cache status and to manipulate the cache. An error will be generated if improper arguments or argument values are passed to ProgramCache(). Any error that occurs while processing the operation will be reported by setting the error code argument to a non-zero dL4 error code. BASIC syntax: Mode 0 - Read next entry in cache. Call ProgramCache(0, errorcode, position, filename, usagecount) Mode 1 - Load program into cache as a permanent entry. Call ProgramCache(1, errorcode, filename) Mode 2 - Delete cache when the current process exits. Call ProgramCache(2, errorcode) Where: errorcode - a numeric variable that will be set to 0 if the operation is successful or to a standard dL4 error code if not. For example, if the cache is not available, the statement Call ProgramCache(0,e,p,f$,c) will set the variable "e" to 42 (file not found). position - a numeric variable that determines which cache entry is read. "position" should be set to zero to read the first entry. Each mode 0 call will update the value of "position" so that the next call will read the next cache entry. The precision of "position" must be such that it can contain any value between 0 and 2^32-1 without any loss of precision (a 3% variable is adequate). The caller should only pass "position" values of zero or those returned by the previous mode 0 call to ProgramCache(). filename - a string variable or expression that will receive a program file path (mode 0) or supply a program file path (mode 1). usagecount - a numeric variable set to the number of users of the program. A usage count of -1 indicates that the program has been added to the cache as a permanent entry. Example: Adding a program to the cache as a permanent entry Declare Intrinsic Sub ProgramCache Dim 1%, ErrorCode Call ProgramCache(1, ErrorCode, "MenuLibrary.lib") Users in static cache mode can only use cached programs and libraries that have been added as permanent entries. These permanent entries must be created by a user in dynamic cache mode using mode 1 of ProgramCache(). Once made, permanent entries cannot be individually deleted because there is no way to determine whether or not a static mode user is currently executing the program or library. See the program cache description above for more information on dynamic and static cache modes. Example: List entries in cache Declare Intrinsic Sub ProgramCache Dim 1%, ErrorCode, 3%, CachePos, File$[200], Usage CachePos = 0 Do Call ProgramCache(0, ErrorCode, CachePos, File$, Usage) If ErrorCode Exit Do If Usage < 0 Print "Permanent "; Else Print Using "######### ";Usage; End If Print File$ Loop If ErrorCode = 73 Print "The program cache is not enabled" Example: Deleting the program cache Declare Intrinsic Sub ProgramCache Dim 1%, ErrorCode Call ProgramCache(2, ErrorCode) This example will delete the program cache when the current user exits dL4. The program cache should be deleted if it is desired to increase the size of the cache or if the cache has become corrupted. The cache can be deleted only by the owner of the cache or by the root user. Since the cache cannot be deleted until the user exits, no error is returned if the caller lacks delete permission. All other users should exit dL4 before the cache is deleted. 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. This sharing mechanism is not dependent on the shared program cache and is used even if the shared program cache is not enabled. Library and program files will NOT be shared unless the files have been SAVEd (or LOADSAVEd) in the new program file format. 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 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 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). Only the root account should use PORT mode 4 to examine ports that belong to different user ids. 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 Unix character terminal environment, binary input disables special character recognition, disables multicharacter key translation, and treats all characters as data. Echo should be disabled when using binary input to avoid echoing illegal characters. 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 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 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 The SCOPE DRIVERS command now accepts a search string to select which drivers are displayed. Example: "drivers isam". 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 DIMmed 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 to dL4. FindChannel() returns the first closed channel number in a specified 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 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. A file created with the "NUMMAP=IRIS" and "CHARSET=IRIS" options will be compatible with UniBasic 6.1 Universal files. 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. Note: the driver supports reading and writing to memo fields, but it does not use the memo type when creating a file. Memo fields are supported for compatibility with files created using third party tools. 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 String to date conversion ("D# = S$") now uses operating system locale information to determine the most common year, month, and day ordering if "Option Date Format Native" is set in the current program. The operating system locale features and environment variables (such as "LANG") must be configured to use this feature. 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 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 last access or last modification date/time of a file. The last access date/time is returned by CHF#(200+c) where 'c' is a channel number. Similarly, the last modification date/time is returned by 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: the MODIFY statement can now move files between file systems if required when changing a file path. 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 type autoselection mechanism for UniBasic files has been improved to make it less likely that text files beginning with the strings "CONT", "DATA", "INDX", "ITEM", "SAVE", or "SYST" will be treated as UniBasic files. o Behavior change: PORT modes 3 and 4 will timeout with an error 155, "No messages waiting", if the target port does not return its status information within 10 seconds. Such timeouts most often occur when a program lacks sufficient privilege to send a query to the target port. Previous versions of dL4 waited forever for a response requiring the user to interrupt the program. Note: PORT modes 1, 2, 3, and 4 should not be used if the target port belongs to a different user id and the current user is not "root". 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 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: screen output was garbled if 'BP' was used in a dL4 window on a terminal in which the DIM attribute occupied a screen position ("magic cookie" terminals such as the Wyse 50). 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 file could not opened if any of the directory names in the path of the file contained uppercase characters. Note that the filename of a FoxPro Full-ISAM file must be in lowercase. 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: 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 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 or UniBasic 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: a PAUSE or SIGNAL 3 interval of more than 10 million seconds caused an error on SCO Unix. o Bug fixed: pfilter sometimes delayed output until subsequent output or a CLOSE occurred. 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. o Beta version bug fixed: UniBasic indexed contiguous files couldn't be opened if the filename used LUMAP. Notes ===== o Like other Dynamic Concepts products for Unix, dL4 requires a functioning Passport daemon to license the system, and an SSN specific to that license number to authorize use of the software. In the absence of SSN authorization, a single-user demo mode is invoked. dL4 requires at least version 4.1 of the Passport daemon program in order to run; as of this writing the current version of the Passport software is 4.6. Version 4.6 is fully upward-compatible with previous Passport versions and with all other Dynamic Concepts products. If you attempt to run dL4 with a daemon older than 4.1, you will see messages such as: Waiting for response from security daemon ... and eventually an exit. The Passport software is now distributed by Dynamic Concepts as a separate installable product. For many platforms, you can download the latest version of the Passport from the Dynamic Concepts web site, www.dynamic.com, or ftp site, ftp.dynamic.com. o In order to run, scope and run must locate a "terminal description file". The name of this file is taken directly from the TERM environment variable, and the following directories are searched, in order: Directory given in TERMDIR variable, if present Current working directory Directory given in HOME variable, if present The use of TERMDIR is the most practical for long-term setup. The stock terminal description files shipped with dL4 can be accessed by setting: TERMDIR=/usr/lib/dl4/term export TERMDIR o Converting UniBasic/IRIS/BITS programs with user CALL statements may require setup via a "conversion profile". Contact Dynamic Concepts regarding the "dL4 Samples & Utilities Kit" for more information on converting existing programs to dL4. o In order to use CALL TRXCO() or the PORT statement, the executable file "scope" must be within one of the directories in your PATH. Otherwise, the environment variable SCOPE must be set to the path of the "scope" executable, e.g.: SCOPE=/usr/bin/scope export SCOPE o In order to use the SPAWN statement, the executable file "run" must be within one of the directories in your PATH. Otherwise, the environment variable RUN must be set to the path of the "run" executable, e.g.: RUN=/usr/bin/run export RUN 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 The BASIC save file version for this release is 2.30. These files are fully upward-compatible with all previous file versions, therefore dL4 will run any saved programs produced by dL4 versions 1.15 through 10.x. Programs saved in 10.7.11 that do not use 10.7.11 specific features can be used with older versions of dL4.