Thursday October 18, 2007 dL4 For Unix Runtime 7.2.1 Maintenance Release All Rights Reserved. Copyright (c) 1994 - 2007 by: Dynamic Concepts, Inc. Aliso Viejo, CA 92656 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 7 of dL4. Without such an SSN, dL4 can only be used in single user demo mode. o Passport 4.1 or later must be installed in order to use release 7.2.1 of dL4. o Due to MySQL licensing requirements, the MySQL drivers cannot be used without a special SSN product option. Please contact the Dynamic Concepts Sales department for information on obtaining the required SSN. 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 Ability to send data messages to UniBasic programs. o Encrypted Contiguous and Indexed Contiguous files. Installation instructions ========================= 1. Ensure that you have Passport version 4.1 or greater installed on your system. For common platforms, the latest 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. makeuniv Utility to convert UniBasic files to Universal files. pgmcache Utility to display or delete the program cache. query Utility to display file characteristics. term Utility to monitor or terminate ports. verindex Utility to validate Portable or Universal Indexed-Contiguous files. oldcalls.lib A dL4 library that implements CALL DYNWIND() and CALL MONITOR(). Other utilities Other utilities including converted versions of many UniBasic utilities dL4 and dL4Term =============== o Some of the new features of dL4 7.2.1 are supported only when using dL4 with the dL4Term 6.3 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 7.2.1. New in This Release ================================================================================ 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 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 test (count,label) Values ("+SQLV$(C,L$)+")" Search #1;"Insert test ("+SQLN$(R.)+") Values ("+SQLV$(R.)+")" Search #1;"Update test Set "+SQLNV$(R.)+" where count=19" o A new driver, "MySQL Full-ISAM", has been implemented to support Full-ISAM and Bridge access to MySQL database tables. Due to MySQL licensing requirements, this driver cannot be used without a special SSN product option. Please contact the Dynamic Concepts Sales department for information on obtaining the required SSN. The MySQL driver implements the standard Full-ISAM driver interface with the following modifications: 1. The InnoDB table type must be used in order to support record locking. Other table types may be usable, but they will not support record locking. 2. A table must have at least one unique index in order to support reading or writing. A table without a unique index can be opened only to extract table information or to add indexes. 3. The OPEN statement uses a special filename syntax with the two formats: "server:database.table:" and "database.table". If the server name is not specified, the system on which the program is running will be used as the server. The OPEN statement also supports four comma separated options: "user=name", "password=string", "pswd=string", and "rtrim=boolean". These options supply server login identification and, in the case of "rtrim", control whether character fields are returned space filled (default) or with trailing spaces removed ("rtrim=true"). Examples: OPEN #1,"mysystem:accounting.customers" AS "MySQL Full-ISAM" OPEN #5,"(user=bill,pswd=secret)test.info" AS "MySQL Full-ISAM" 4. The KILL statement uses the same filename syntax as the OPEN statement and supports the "user=name", "password=string", and "pswd=string" options. Example: KILL "(user=bill,pswd=secret)test.info" AS "MySQL Full-ISAM" The server name and login information can be specified in the environment variable "DL4MYSQLISAM" which supports the comma separated options "server=name", "user=name", "password="name", and "pswd=name". Example for a Unix command line shell: $DL4MYSQLISAM="server=myserver,user=anonymous" $export DL4MYSQLISAM $scope The MySQL driver has been tested with MySQL versions 3.23.42 through 3.23.53. InnoDB tables are an optional feature of MySQL and require installing both an InnoDB capable version of MySQL and setting optional configuration parameters. Please see the MySQL documentation for information on installing and configuring a MySQL server. o The new MySQL Full-ISAM driver has an open option, "nulls=true", to support read and writing NULL values to table columns. When a table is opened with the "nulls=true" option, NULL values in numeric, date, or character columns are converted to special values when they are read. When adding new records or modifying existing records, NULL values can be written by writing the same special values. Currently, the special values are -1E62 for numeric values, "January 1, 0001" for date values, and "\xffff\" for strings. Programs should not test for or set these values directly. Instead, new intrinsic functions have been provided to test for NULL values and to set NULL values. The intrinsic function IsSQLNull() returns 1 when its argument is a NULL value and 0 for all other values. The intrinsic functions SQLNull(), SQLNull#(), and SQLNull$() return special NULL values for numbers, dates, and strings. NULL values cannot be read into or written from integer numeric variables or 1% date variables. NULL values are not supported for binary variables ("B?"). NULL values can be used in keys and index columns, but it is not recommended. Example: Declare Intrinsic Function IsSQLNull,SQLNull,SQLNull#,SQLNull$ Open #1,"(nulls=true)server:database.table" As "MySQL Full-ISAM" ! Display table with possible NULL values Do Try Read Record #1;R. Else Exit Do Print "Name = ";R.CustomerName$ Print "Appointment = "; If IsSQLNull(R.AppointmentDate#) Print "none" Else Print R.AppointmentDate# End If Loop ! Add new record with NULL value R.CustomerName$ = "John Quinn" R.AppointmentDate# = SQLNull#() Add Record #1;R. o The MySQL Full-ISAM driver supports the special MySQL date value of 0000-00-00. Such date values can now be read into date variables and will set the date variable to be "Not-A-Date". The special value of 0000-00-00 can be written by writing a date value of "Not-A-Date". A date variable can be set to "Not-A-Date" by the CLEAR statement ("CLEAR D#"). An error 15 will occur if a "Not-A-Date" value is used in a date function or date expression. o The MySQL Full-ISAM driver reports character fields in indexes as case insensitive when a GET statement retrieves index information (if the MySQL server is using the standard case insensitive character set). When creating a table, the driver will accept index field definitions that are either case sensitive or case insensitive. The actual case sensitivity is always controlled by the MySQL server. o The KILL statement now supports an options field "(...)" before each filename to supply driver options. Example: KILL "(user=fred,password=secret)mytable" AS "MySQL Full-ISAM" The SCOPE/BASIC KILL command does not support deleting MySQL tables. o The Full-ISAM Bridge driver has been extended to support Full-ISAM date fields and translation of field types. A date field is used by specifying a translation function in the field definition that defines how to translate a date value to or from a character or numeric field. Translation functions also support converting Full-ISAM numeric fields to Indexed-Contiguous character key fields. Additional functions support subscripted character fields for key fields or case-insensitive key fields. The translation functions are: DTOC(mask) Convert the Full-ISAM date field to a character string in the record image using "mask". All dates use local date/time. When the DTOC() function is used in an index definition, the "mask" must define a sortable date. For example, "YYMMDD" is a legal index mask, but "MMDDYY" is not because it would not sort correctly. "mask" is a quoted string in which the following substrings have special meaning: YYYY Four digit year YY Two digit year with the century set so it is within 50 years of the current date. AA Two digit year in which years after 1999 are specified as "A0" through "E9". MM Zero filled month, 1 - 12 DD Zero filled day of month, 1 - 31 DDD Zero filled day of year, 1 - 366 DDDDD Zero filled day relative to base year 1968. January 1, 1968 is "00001". Six or more "D"s can be also be used. HH Zero filled hour of day MM Zero filled minute of hour SS Zero filled second of minute DTON(mask) Convert Full-ISAM date field to a decimal number in the record image using "mask". All dates use local date/time. "mask" is a quoted string defining the decimal digits of the number. The following substrings in the mask have special meanings: YYYY Four digit year YY Two digit year with the century set so it is within 50 years of the current date. MM Month, 1 - 12 DD Day of month, 1 - 31 DDD Day of year, 1 - 366 or 0 - 365 DDDDD Day relative to base year 1968. January 1, 1968 is 1. Six or more "D"s can be also be used. HH Hour of day MM Minute of hour SS Second of minute NTOC(mask) Convert Full-ISAM numeric field to a character string according to the USING mask "mask". The mask must use a period (".") for any decimal point point and comma as any grouping separator. NTVNTOC(mask) Convert Full-ISAM numeric field to a character string according to the USING mask "mask" and using locale information to determine the decimal point character. The mask must use a period (".") for any decimal point and comma as any grouping separator. LEFT(len) Use the first "len" characters of the field. This function can only be used in index definitions and the field must also be used in the "[Record]" section. UCASE(len) Use the first "len" characters of the field converted to uppercase. This function can only be used in index definitions and the field must also be used in the "[Record]" section. LCASE(len) Use the first "len" characters of the field converted to lowercase. This function can only be used in index definitions and the field must also be used in the "[Record]" section. 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 cau