Friday December 5, 2003 dL4 for Windows Runtime 5.2.4 Maintenance Release All Rights Reserved. Copyright (c) 1997 - 2003 by: Dynamic Concepts, Inc. Aliso Viejo, CA 92656 USA Email address: techsupport@dynamic.com Information: www.unibasic.com Downloads: ftp.dynamic.com Pre-installation instructions ============================= o WARNING: This release will NOT run with existing SSNs that use a license number that begins with "FE". These obsolete SSNs include almost all SSNs created before December 2001. Please contact the Dynamic Concepts Sales department for information on replacing SSNs that use "FE" license numbers. Please read the following Passport section for additional licensing information. o This release requires the use of Passport for Windows 2.2 or later. The new version of Passport for Windows requires the presence of an ethernet interface or a Dynamic Concepts hardware Passport device. Windows 95 users must use a hardware Passport or upgrade to a later version of Windows. SSNs for Passport 2.1.3 or later are machine specific and must not be installed on more than one system. Unlike previous versions of dL4 for Windows, the number of simultaneous dL4 sessions will be restricted to the licensed number of users plus three phantom ports or extra window sessions. o This release requires an SSN authorized for release 5 of dL4. In order to use the MySQL drivers, the SSN must be authorized for the MySQL option. Please contact the Dynamic Concepts Sales department for information on obtaining required SSNs. o Problem reports should be emailed to techsupport@dynamic.com. All problem reports should contain a description of the problem, the operating system name/revision, and, if at all possible, a reproducible sequence Installation instructions ========================= To install dL4 for Windows, perform the following steps: 1. Remove any previous dL4 for Windows release. 2. Run the dL4 installation program 1B_dl4_5.2.4.exe and follow the displayed instructions. Press "Yes" when the program asks if Passport should be installed. 3. If you haven't registered your license and SSN using the Passport ssnmaint utility, run ssnmaint. dL4 cannot be used until Passport is installed and your license registered. 4. If you intend to use loadsave.exe, add the installation directory to your PATH variable. 5. If data files will be accessed over a network, run checksys.exe from the installation directory to detect out-of-date or misconfigured operating system modules. The checksys utility should be run on each Windows client system and each Windows NT file server in the network. See the "Networking" section below for details. File list ========= readme.txt This file license.txt Runtime license terms and conditions checksys.exe Utility to detect operating system configuration problems codebase.dll Runtime library dcictree.dll Runtime library dl4basic.dll Runtime library dl4chwin.dll Runtime library dl4fldrv.dll Runtime library dl4pipe.exe Internal utility used by the pipe driver dl4rt.dll Runtime library dl4servr.exe Network service utility to run a dL4 program whenever a TCP connection is made to a specific IP address and port number (for Windows NT, 2000, or XP only) dl4sockt.dll Runtime library dl4stdrv.dll Runtime library loadsave.exe dL4 compile-and-save console program msvcrt.dll Runtime library msvcrt40.dll Runtime library ntwdblib.dll Runtime library pfilter.exe Printer character translation filter runc.exe Special version of BASIC interpreter for CGI programs and piped I/O runw.exe BASIC interpreter scopec.exe Special version of dL4 IRIS-style command interpreter for CGI programs and piped I/O scopew.exe dL4 IRIS-style command interpreter stubwa10.dll Runtime library dfltlp.bat Printer script for default Windows printer selectlp.bat Printer script for user selected Windows printer printer\ Directory of printer scripts term\ Directory of terminal definition files for use with scopec.exe and runc.exe tools\ Various utilities Highlights of This Release ========================== o Color control in GUI elements including setting character by character color in list box items. o A new mnemonic, 'WCASKCOLOR', to display a color dialog and return the color selected by the user. o Support for printing window contents via the print screen mnemonic ('PS') or the Edit menu. o Support for double clicking on GUI list box items or edit boxes. o Support for maximizing the main window to occupy the entire screen. o An SQL driver to access MySQL servers using SQL statements. o A new Full-ISAM driver to access database tables from MySQL servers. o An enhanced Full-ISAM Bridge driver that converts data types for greater compatibility with existing programs using Indexed-Contiguous file access to Full-ISAM files and SQL tables. o A new utility, ic2fi, to convert Indexed-Contiguous files to Full-ISAM files. o The XBREAK command places breakpoints in external programs invoked by CALL-by-filename, CHAIN, or SWAP. New in This Release ================================================================= Dec 5 2003 (Maintenance release 5.2.4) o Bug fixed: GUI element labels and list box items were not sized correctly if the GUI element font size differed from the standard dialog font size. o Bug fixed: if the canvas was taller than the window, the display was corrupted and the scroll bar did not work. o Bug fixed: if the main window was minimized and then restored, scroll bars were displayed. o Bug fixed: a scroll bar was displayed in a GUI list box if the number of elements equaled the maximum number that could be displayed in the box. Aug 12 2003 (Maintenance release 5.2.3) o Bug fixed: the scroll bars did not work when the window was smaller than the canvas. o Bug fixed: memory violations occurred with some combinations of fonts and font sizes. o Bug fixed: the DUPLICATE statement produced incorrect filenames for FoxPro Full-ISAM files if a trailing "!" was used. Jul 21 2003 (Maintenance release 5.2.2) o A new intrinsic function, CALLSTAT$(), has been implemented to return a string describing the program position at a specified level in the procedure stack. This function would typically be used to generate information for an error log. The procedure stack includes all function, procedure, Call-Subprogram, and SWAP levels. The level type ("Swap", "SubPgm", "ExtSub", "ExtFunc", "IntSub", "IntFunc", or "") is returned in a function argument. The current position is level 0, the caller is level 1, and so on. An error 38 is generated if a non-existent level is specified. BASIC syntax: CallStat$(Level, LevelType$) Example: Print "Caller position is ";CallStat$(1,Type$) Print "Caller type is ";Type$ o Behavior change: copy/paste operations now supply spaces between pasted characters when necessary. o Bug fixed: the bridge driver could not insert records in a MySQL table if a key contained a DECIMAL(n,0) column. o Bug fixed: the makehuge utility could not convert files that used key translation. o Bug fixed: CALL DATE() did not properly convert six character dates to eight character dates. o Bug fixed: the socket driver did not work if certain third-party network driver extensions were installed on the system. o Bug fixed: some rare situations would cause the main window to freeze. o Bug fixed: input did not work with bidirectional auxiliary devices. o Bug fixed: the edit menu was sometimes printed as part of a print screen operation. o Bug fixed: the FoxPro Full-ISAM driver "dataext" option created files with duplicated extensions ("file.ext.ext"). o Bug fixed: the DXTESTIN, DXTESTOUT, and DXTESTCOPY environment variables could not be set via CALL ENV() and used with the dynamicXport CALLs. May 14 2003 (Maintenance release 5.2.1) o A new printer type, "Bidirectional Device", is now supported as an auxiliary printer in the "Preferences->Aux Printer" dialog. When enabled, this printer type allows both writing to and reading from a device such as a serial port. o The raw file driver now supports a CRTOCRLF open option to append a line feed character when writing carriage return characters. This option is also available for the auxiliary printer and can be enabled in "Preferences->Aux Printer->Options". o The "TCP Listen Socket" driver has been enhanced to accept a new OPEN option. The new "REUSE" option enables the driver to open a socket with a port number that is already in use. This option is needed to support certain network protocols and to avoid error 76 ("File or device is open elsewhere") when re-opening a previously used TCP port number. Example: Open #1,"(reuse):9631" As "TCP Listen Socket" o The "MySQL SQL" and "MySQL Full-ISAM" drivers have been enhanced to accept a "PORT=" option in the OPEN statement or in the DL4MYSQL/DL4MYSQLISAM runtime parameters. This option makes it possible to use MySQL servers with non-default port numbers. o A new intrinsic CALL, IMSPACK(), has been implemented to provide compatibility with CALL $PACK in IMS BASIC. The syntax of CALL IMSPACK() is: Call IMSPack(Mode, Src$, Dest$) Call IMSPack(Mode, Dest$, Src$) where "Mode" equals zero packs characters from "Src$" into "Dest$" and a non-zero "Mode" unpacks characters from "Src$" into "Dest$". The packing algorithm uses a radix 50 style mechanism. o A new intrinsic CALL, TRANSLATE(), has been added to translate strings to or from binary strings according to a specified character set. The syntax and arguments of CALL TRANSLATE() are: Call Translate(DestCnt,Dest$,SrcCnt,Src?,CharSet$) Call Translate(DestCnt,Dest?,SrcCnt,Src$,CharSet$) DestCnt - receives the number of characters translated into the destination. Dest$ - destination string that receives the characters translated from Src?. Dest? - destination binary string that receives the characters translated from Src$. SrcCnt - receives the number of characters translated from the source. Src$ - source string of characters to be translated. String terminator characters are copied as data and the source size is controlled by the total size of the variable and any double subscripting. Src? - source binary string of bytes to be translated. The source size is controlled by the total size of the variable and any double subscripting. CharSet$ - character set name such as "ASCII", "ANSI", or "UTF-8". If a character cannot be translated, translation will stop. Translation errors can be detected by comparing the returned source translation count to the source size. o A new option, "P", has been added to the "TERM" utility to page long listings of active ports. The command "term all mp" would list all active ports in screen sized pages. o A new option "ADD" has been implemented in the "PGMCACHE" utility to manual add permanent entries to the program cache. The command "pgmcache add filename" would add the program or library "filename" to the program cache. The file would remain in the cache until the cache itself was deleted or the system was restarted. o A new option, "uselust", has been added to the DL4LUST runtime parameter to import a search path from the "LUST" environment variable. The imported search path is placed after any entries in DL4LUST. o The SCOPE BASIC mode LIST command now supports a "-c" option to disable paging of the listing. o A new option, "/t description-string", has been added to dl4servr.exe to configure a descriptive string when installing a dl4servr service. o Behavior change: flicker is reduced, under some conditions, when adding text to a text or edit box. o Bug fixed: the display window was sometimes displayed in an incorrect position in the base window after the window had been maximized and the 'NR'/'WD' mnemonics had been used. o Bug fixed: when an indexed contiguous file was opened in read-only mode (ROPEN), recent changes to the index were sometimes ignored. o Bug fixed: the CHARSET and NUMMAP options could not be used when building a formatted file. Apr 7 2003 (Release 5.2) o Two new GUI mnemonics, 'WCSETCOLOR' and 'WCRESETCOLOR', have been defined to set the text and background colors in newly created GUI elements. The 'WCSETCOLOR' mnemonic copies the current window foreground and background colors. Alternatively, the 'fg bg WCSETCOLOR' mnemonic uses two numeric parameters, the text and background colors. The 'WCRESETCOLOR' mnemonic restores the standard system colors. The 'WCSETCOLOR' and 'WCRESETCOLOR' mnemonics can be printed directly to a GUI element to immediately change the text and background colors for that GUI element. o A new GUI mnemonic, 'WCMARKCOLOR', has been defined to set the text and background colors for items that have been selected by the user in GUI list boxes ('WCLIST', 'WCEDITLIST', ...). The colors are also used for items selected by the 'WCMARK mnemonic. If the 'WCMARKCOLOR' mnemonic is printed to a window, all GUI list elements subsequently created in that window will use the specified colors. The 'WCMARKCOLOR' mnemonic can be printed to a GUI element box to set or change selection colors in only that GUI element. The 'WCMARKCOLOR' mnemonic has three formats: 'WCMARKCOLOR' - use the current window text and background colors 'fg WCMARKCOLOR' - use "fg" as the text color and the current window background color 'fg,bg WCMARKCOLOR' - use "fg" as the text color and "bg" as the background color. The color values "fg" and "bg" are numbers between -6 and 2^24 as used in the 'FONTCOLOR' and 'BACKCOLOR' mnemonics. The 'WCRESETCOLOR' mnemonic can be used to restore the standard selection colors. As with all other GUI mnemonics, this mnemonic can only be used with dL4Term or in dL4 for Windows. o Color can now be controlled on a character by character basis within the list boxes of 'WCLIST', 'WCEDITLIST', 'WCDROPLIST', and 'WCEDITDROP' GUI elements. The text and background colors are set using the normal 'FONTCOLOR' and 'BACKCOLOR' mnemonics. o Four new standard color numbers have been defined for use with all color mnemonics such as 'FONTCOLOR'. These negative colors numbers are defined as follows: -3 System standard window text color -4 System standard window background color -5 System standard highlighted text color -6 System standard highlighted text background color o A new mnemonic, 'n WCASKCOLOR', has been implemented to display the standard window color selection dialog and return the color selected, if any, by the user. The mnemonic requires a single numeric parameter which is the default RGB color for the dialog. The dialog returns the selected color as a decimal input string followed by a carriage return. If no color is selected, a null string will be returned followed by a carriage return. o Double clicking on edit box elements such as WCSTRING or WCTEXT can now be detected by using the 'WCACTION' mnemonic to set the double click action string as action number 2. Example: PRINT PCHR$(10,2,'F40');'WCACTION'; o Window contents can now be printed to a user selected printer by sending a print screen mnemonic ('PS') to a window or by the user selecting the "Edit->Print Window" menu. o The main window can now be maximized to occupy the entire screen. The new "Preferences->Frame" dialog configures the pattern and colors used to fill the area outside the display window. o Double clicking on list box elements or buttons can now be detected by using the 'WCACTION' mnemonic to set the double click action string as action number 2. Example: PRINT PCHR$(10,2,'F40');'WCACTION'; o A new driver, "MySQL SQL", has been implemented so that applications can use SQL statements to issue commands and queries to a MySQL server. The driver allows an application to access the full capabilities of MySQL including both standard SQL syntax and MySQL specific features. Due to MySQL licensing requirements, the driver cannot be used without a special SSN product option. Please contact the Dynamic Concepts Sales department for information on obtaining the required SSN. The OPEN statement uses a special filename syntax with two formats: "server:database" and "database". Rather than opening a specific table, the OPEN statement creates a connection to a MySQL server and sets the default database to be used by SQL statements. If the server name is not specified, the system on which the program is running will be used as the server (unless a default server is specified in the DL4MYSQL runtime parameter, see below). The OPEN statement also supports four comma separated options: "user=name", "password=string", "pswd=string", and "rtrim=boolean". These options supply server login identification and, in the case of "rtrim", control whether character fields are returned space filled (default) or with trailing spaces removed ("rtrim=true"). Examples: OPEN #1,"mysystem:accounting" AS "MySQL SQL" OPEN #5,"(user=bill,pswd=secret)testdb" AS "MySQL SQL" The server name and login information can be specified in the environment variable "DL4MYSQL" which supports the comma separated options "server=name", "user=name", "password="name", and "pswd=name". Example for a Unix command line shell: $DL4MYSQL="server=myserver,user=anonymous" $export DL4MYSQL $scope SQL statements are executed by using SEARCH statements. Each SEARCH statement specifies a channel open to a MySQL server and an SQL statement as a character string. Examples: SEARCH #1;"select * from testtable" SEARCH #5;"update acctgtbl set balance=123.45 where account=19765" SEARCH #5;"drop table testtable" If the statement fails, an error will occur. Syntax errors in SQL statements are reported as error 274, "SQL syntax error". After an SQL SELECT statement is successfully executed, the number of rows in the result set can be determined by using the CHF(channel) function. The result set itself is read by using normal READ and READ RECORD statements. An error 52, "record not found", will be reported by any statement attempting to read beyond the end of the result set. Example: Search #7;"select account, balance from acctgtbl" Print Chf(7);"rows returned by query" Do Try Read #7;Account,Balance Else Exit Do Print "Account =";Account;" ";Balance =";Balance Loop Note: the result set of the current SQL SELECT statement is copied into memory by the dL4 SEARCH statement. SELECT statements should be written so as to limit the size of the result set to a reasonable value. An SQL LIMIT clause can be used in the SQL SELECT statement to restrict the maximum size of the set. The MAP RECORD statement can be used to map structure variable members according to their item names to the columns returned by a query. In the following example, the SQL select statement returns a two column result "account, balance" which is mapped into a structure variable that uses the opposite ordering: Def Struct RSET Member 3%,Balance : Item "balance" Member 3%,Acct : Item "account" End Def Dim R. As RSET Search #7;"Select account, balance from acctgtbl" Print Chf(7);"rows returned by query" Map Record #7 As RSET Do Try Read Record #7;R. Else Exit Do Print "Account =";R.Acct;" ";Balance =";R.Balance Loop NULL values in numeric, date, or character columns are converted to special values when they are read. When adding new rows or modifying existing rows, NULL values can be written by using the same special values. In this version of dL4, the special values are -1E62 for numeric values, "January 1, 0001" for date values, and "\xffff\" for strings. Programs should not test for or set these values directly. Instead, new intrinsic functions have been provided to test for NULL values and to set NULL values. The intrinsic function IsSQLNull() returns 1 when its argument is a NULL value and 0 for all other values. The intrinsic functions SQLNull(), SQLNull#(), and SQLNull$() return the special NULL values for numbers, dates, and strings. NULL values cannot be read into or written from integer numeric variables or 1% date variables. NULL values are not supported for binary variables ("B?"). Three new intrinsic functions, SQLV$(), SQLN$(), and SQLNV$() are provided to make it easier to construct SQL statements. The SQLV$() function takes one or more arguments of any non-array type and returns a string containing the argument values encoded for use by an SQL driver. The SQL driver detects such encoded values in the SEARCH statement string and formats the values as required by the SQL server. This formatting guarantees proper quoting of character string values and places commas between each value. If the argument is a structure variable, each member of structure is encoded. The SQLN$() function takes a single structure variable argument and returns a string containing the member item names encoded for the SQL driver with commas separating each name. The SQLNV$() function takes a single structure variable argument and returns a string containing the member names and values encoded for the SQL driver with equals signs ("=") and commas. Examples: Search #1;"Insert test (count,label) Values ("+SQLV$(C,L$)+")" Search #1;"Insert test ("+SQLN$(R.)+") Values ("+SQLV$(R.)+")" Search #1;"Update test Set "+SQLNV$(R.)+" where count=19" o A new driver, "MySQL Full-ISAM", has been implemented to support Full-ISAM and Bridge access to MySQL database tables. Due to MySQL licensing requirements, this driver cannot be used without a special SSN product option. Please contact the Dynamic Concepts Sales department for information on obtaining the required SSN. The MySQL driver implements the standard Full-ISAM driver interface with the following modifications: 1. The InnoDB table type must be used in order to support record locking. Other table types may be usable, but they will not support record locking. 2. A table must have at least one unique index in order to support reading or writing. A table without a unique index can be opened only to extract table information or to add indexes. 3. The OPEN statement uses a special filename syntax with the two formats: "server:database.table:" and "database.table". If the server name is not specified, the system on which the program is running will be used as the server. The OPEN statement also supports four comma separated options: "user=name", "password=string", "pswd=string", and "rtrim=boolean". These options supply server login identification and, in the case of "rtrim", control whether character fields are returned space filled (default) or with trailing spaces removed ("rtrim=true"). Examples: OPEN #1,"mysystem:accounting.customers" AS "MySQL Full-ISAM" OPEN #5,"(user=bill,pswd=secret)test.info" AS "MySQL Full-ISAM" 4. The KILL statement uses the same filename syntax as the OPEN statement and supports the "user=name", "password=string", and "pswd=string" options. Example: KILL "(user=bill,pswd=secret)test.info" AS "MySQL Full-ISAM" The server name and login information can be specified in the environment variable "DL4MYSQLISAM" which supports the comma separated options "server=name", "user=name", "password="name", and "pswd=name". Example for a Unix command line shell: $DL4MYSQLISAM="server=myserver,user=anonymous" $export DL4MYSQLISAM $scope The MySQL driver has been tested with MySQL versions 3.23.42 through 3.23.53. InnoDB tables are an optional feature of MySQL and require installing both an InnoDB capable version of MySQL and setting optional configuration parameters. Please see the MySQL documentation for information on installing and configuring a MySQL server. o The new MySQL Full-ISAM driver has an open option, "nulls=true", to support read and writing NULL values to table columns. When a table is opened with the "nulls=true" option, NULL values in numeric, date, or character columns are converted to special values when they are read. When adding new records or modifying existing records, NULL values can be written by writing the same special values. Currently, the special values are -1E62 for numeric values, "January 1, 0001" for date values, and "\xffff\" for strings. Programs should not test for or set these values directly. Instead, new intrinsic functions have been provided to test for NULL values and to set NULL values. The intrinsic function IsSQLNull() returns 1 when its argument is a NULL value and 0 for all other values. The intrinsic functions SQLNull(), SQLNull#(), and SQLNull$() return special NULL values for numbers, dates, and strings. NULL values cannot be read into or written from integer numeric variables or 1% date variables. NULL values are not supported for binary variables ("B?"). NULL values can be used in keys and index columns, but it is not recommended. Example: Declare Intrinsic Function IsSQLNull,SQLNull,SQLNull#,SQLNull$ Open #1,"(nulls=true)server:database.table" As "MySQL Full-ISAM" ! Display table with possible NULL values Do Try Read Record #1;R. Else Exit Do Print "Name = ";R.CustomerName$ Print "Appointment = "; If IsSQLNull(R.AppointmentDate#) Print "none" Else Print R.AppointmentDate# End If Loop ! Add new record with NULL value R.CustomerName$ = "John Quinn" R.AppointmentDate# = SQLNull#() Add Record #1;R. o The MySQL Full-ISAM driver supports the special MySQL date value of 0000-00-00. Such date values can now be read into date variables and will set the date variable to be "Not-A-Date". The special value of 0000-00-00 can be written by writing a date value of "Not-A-Date". A date variable can be set to "Not-A-Date" by the CLEAR statement ("CLEAR D#"). An error 15 will occur if a "Not-A-Date" value is used in a date function or date expression. o The MySQL Full-ISAM driver reports character fields in indexes as case insensitive when a GET statement retrieves index information (if the MySQL server is using the standard case insensitive character set). When creating a table, the driver will accept index field definitions that are either case sensitive or case insensitive. The actual case sensitivity is always controlled by the MySQL server. o The KILL statement now supports an options field "(...)" before each filename to supply driver options. Example: KILL "(user=fred,password=secret)mytable" AS "MySQL Full-ISAM" The SCOPE/BASIC KILL command does not support deleting MySQL tables. o The Full-ISAM Bridge driver has been extended to support Full-ISAM date fields and translation of field types. A date field is used by specifying a translation function in the field definition that defines how to translate a date value to or from a character or numeric field. Translation functions also support converting Full-ISAM numeric fields to Indexed-Contiguous character key fields. Additional functions support subscripted character fields for key fields or case-insensitive key fields. The translation functions are: DTOC(mask) Convert the Full-ISAM date field to a character string in the record image using "mask". All dates use local date/time. When the DTOC() function is used in an index definition, the "mask" must define a sortable date. For example, "YYMMDD" is a legal index mask, but "MMDDYY" is not because it would not sort correctly. "mask" is a quoted string in which the following substrings have special meaning: YYYY Four digit year YY Two digit year with the century set so it is within 50 years of the current date. AA Two digit year in which years after 1999 are specified as "A0" through "E9". MM Zero filled month, 1 - 12 DD Zero filled day of month, 1 - 31 DDD Zero filled day of year, 1 - 366 DDDDD Zero filled day relative to base year 1968. January 1, 1968 is "00001". Six or more "D"s can be also be used. HH Zero filled hour of day MM Zero filled minute of hour SS Zero filled second of minute DTON(mask) Convert Full-ISAM date field to a decimal number in the record image using "mask". All dates use local date/time. "mask" is a quoted string defining the decimal digits of the number. The following substrings in the mask have special meanings: YYYY Four digit year YY Two digit year with the century set so it is within 50 years of the current date. MM Month, 1 - 12 DD Day of month, 1 - 31 DDD Day of year, 1 - 366 or 0 - 365 DDDDD Day relative to base year 1968. January 1, 1968 is 1. Six or more "D"s can be also be used. HH Hour of day MM Minute of hour SS Second of minute NTOC(mask) Convert Full-ISAM numeric field to a character string according to the USING mask "mask". The mask must use a period (".") for any decimal point point and comma as any grouping separator. NTVNTOC(mask) Convert Full-ISAM numeric field to a character string according to the USING mask "mask" and using locale information to determine the decimal point character. The mask must use a period (".") for any decimal point and comma as any grouping separator. LEFT(len) Use the first "len" characters of the field. This function can only be used in index definitions and the field must also be used in the "[Record]" section. UCASE(len) Use the first "len" characters of the field converted to uppercase. This function can only be used in index definitions and the field must also be used in the "[Record]" section. LCASE(len) Use the first "len" characters of the field converted to lowercase. This function can only be used in index definitions and the field must also be used in the "[Record]" section. Example: Field=LASTPAYMNT,114,2%,DTON("YYDDD") o The Full-ISAM Bridge driver profile has been extended to support two new conversion functions, IFNULL and IFERR, that convert SQL NULL or invalid values to and from the values needed in the emulated indexed contiguous file record. The IFNULL function takes a single string argument which defines a string or number that is stored into the converted field whenever a NULL is read. When a record is written, the same value will be converted to a NULL. Examples: Field=COUNT,28,4%,,,IFNULL("-1") Field=ACCTID,16,12,,,NTOC("-------#.##"),IFNULL("N/A"),Strip In order to read or write NULLs, the SQL driver options in the bridge profile must be set to enable reading and writing nulls (for the MySQL Full-ISAM driver, see the "nulls=true" option described above). The IFERR function is similar to the IFNULL function, but it is applied to invalid numeric or date values. In this release of dL4, the only possible invalid value is the special MySQL date value of "0000-00-00". If no IFERR function is specified, an invalid value results in an error. In the following example, MySQL "0000-00-00" dates are converted to -1 while actual dates are converted to decimal numbers in the form "YYYYMMDD": Field=DATE1N,60,3%,,,DTON("YYYYMMDD"),IFERR("-1") In this example, "0000-00-00" dates in a key part are converted to the string "00000000" while actual dates are converted to strings in the format "YYYYMMDD": KeyPart=DATE1,0,8,"","0123",DTOC("YYYYMMDD"),IFERR("00000000") Both IFNULL and IFERR functions can be used in the same field or key part definition. o The Full-ISAM Bridge driver profile has been extended to support filler fields. A filler field is any record field with a field name beginning with an asterisk. Filler fields are not read from the Full-ISAM file, but they are initialized to the fill character or zeroed if the fill character is not defined. The filler name is treated as a comment. Example: Field=*fillerwithnulls*,54,5 Field=*fillerwithblanks*,59,5,," " o A new option has been added to the Full-ISAM Bridge driver profile to disable use of temporary record values when inserting or modifying records. The temporary values are normally used to reserve key values after SEARCH mode 4 insert statements and thus prevent other programs from inserting the same key. If the new "ProtectKeys=False" option is specified in the initial section of a bridge profile, SEARCH mode 4 statements will check for the current existence of a key value, but the Full-ISAM file will not be modified until all keys have been inserted for the record. This option improves Bridge driver performance and allows use of foreign key constraints in SQL tables. If the option is used, duplicate key errors may occur after a successful SEARCH mode 4 insertion of the key. Bridge profile example: [FullISAMBridge] File=filename OpenAs=FoxPro Full-ISAM ProtectKeys=False o The Full-ISAM Bridge driver support of SEARCH mode 6 (search less than) has been improved. Statements such as SEARCH #Chan,6,IdxNum;"{",R,S can now be used on indexes that use date or numeric conversion functions. The driver will detect that the key value is greater than any possible key value and will search for the last key in the specified index. In the previous release, the key value "{" would have caused an error in the conversion function because "{" is an illegal value. o The numeric precision syntax in Full-ISAM Bridge profile files has been extended to specify the number of decimal places needed. The new, optional format is "p.d%" where "p" is the dL4 numeric precision (1-4) and "d" is the number of decimal places. Thus "3.2%" would specify a 10 digit floating point format with two decimal places. The decimal place information is used by the tools/ic2fi utility to create Full-ISAM files when the Full-ISAM driver supports only fixed point, rather than floating point, numbers. Example: Field=COST,80,3.2% o The tools/ictofi utility program has been replaced with a new utility, tools/ic2fi, that offers similar, but greatly improved, features to convert from Indexed-Contiguous files to Full-ISAM files. The new utility can also be CALLed as a subprogram to perform automated or repetitive conversion of Indexed-Contiguous files. The ic2fi utility is documented in the dL4 5.2 Product Training manual which can be downloaded from www.unibasic.com or ftp.dynamic.com. o The tools/buildfi utility program has been enhanced to allow selection of the Full-ISAM type (FoxPro or SQL) and to improve error handling. o A new driver, "Socket Text", has been added to provide text line oriented I/O to TCP sockets. Driver arguments and usage is identical to the raw socket driver except that READ and INPUT statements will read data in lines terminated by carriage return and/or line feed. o A new open option, "SYNC", has been added to the Portable Contiguous, Portable Indexed-Contiguous, and text file drivers. This option forces the operating system to write data immediately to disk. Example: Open #1,"(sync)datafile" This option will severely impact file throughput and should only be used in special circumstances. o A new option, "buffer=true", has been added to the text and pipe drivers to improve performance. For compatibility with UniBasic, these drivers normally output data immediately after a PRINT or WRITE statement. The "buffer=true" option instructs the drivers to delay output until an internal buffer is filled or the driver is closed. The option can be used in an OPEN statement or in a printer script "# dl4opts=" line. Examples: BUILD #1,+"(buffer=true)textfile!" # dl4opts=buffer=true o Portable Indexed-Contiguous and Portable Contiguous file performance has been improved for files opened in exclusive mode. Scratch files should be opened using the EOPEN statement to obtain this increased performance. o It is now possible to output binary zero characters to a terminal or serial port when in binary output mode. The MAT WRITE statement will output all characters including binary zero characters in a string variable. Subscripts can be used to limit output to a selected range within a string. o A new BASIC command, XBREAK, has been implemented to allow the user to set breakpoints outside of the current program. The command uses the same syntax as the existing BREAK command, but will apply the breakpoint to both the current program and to any program entered via CHAIN, CALL subprogram, or SWAP statements. Example: XBREAK 1000 XBREAK breakpoints can be deleted or listed with the normal NOBREAK or STATUS BREAKPOINT commands. o Enhancement: quoted values can now be used in driver options. For example, a quoted value might be used to provide a subject line using parentheses to the email driver: Open #1,"(From=someone,Subject=''(test)'')somebody" As "Email" o Behavior change: the DL4PORTDUMP and DL4STOPDUMP runtime parameters have been enhanced to support an optional file protection ("") specification. o Behavior change: the LOADSAVE utility now prints a simple usage message if the "-h" option is used. A full usage message can be displayed by using the "-H" option. o The PORT statement has been extended with a new mode, 6, to determine whether a port is blocked by a record lock and which other port is holding the needed record lock. The statement PORT portnum,6,status,isblocked,blockingport sets the variable "isblocked" to one if the dL4 program running on port "portnum" has been waiting for over 20 seconds for a record lock and to zero if it is not blocked. If the port is blocked by a record lock, the variable "blockingport" is set to the port number of the program that currently has the record locked or to -1 if the blocking port number cannot be determined. PORT mode 6 is supported for record locks on formatted, contiguous, and indexed contiguous files. o The PORT statement has been extended with a new mode, 7, to return the user name and work station name of a specified port. The statement PORT portnum,7,status,userid$,station$ queries port "portnum" and returns in "userid$" the user name, if any, associated with the port and returns in "station$" the terminal name, if any, used by the port. o The TERM utility has been extended to display the user name and work station name associated with each port. If the program running on a port is currently blocked by a record lock wait, its state will be displayed as "Blkd" and the port number that is currently holding the locked record will be displayed in parentheses. The "Blkd" state information is supported only for record locks on formatted, contiguous, and indexed contiguous files. o The intrinsic CALLs GetGlobals() and SetGlobals() have been extended to support separate named sets of global values. If the first parameter of CALL GetGlobals() or CALL SetGlobals() is a string, it will be treated as a global set name and the get or set operations will be applied using that global set. The default set is named "". A global set is created by the first CALL SetGlobals() using the set name. Examples: Call SetGlobals$("mylib",0,N$,A) ! set values in "mylib" Call GetGlobals$("mylib",0,N$,A) ! get values from "mylib" Call SetGlobals("mylib") ! delete the set "mylib" o The intrinsic CALL table in the dL4 development kit, userproc.c, now supports the option USERPROCOPT_CVTSTRINGS to automatically string parameters to and from binary ITEMS using the UniBasic IRIS character set. This option can be used to simplify conversion of CALLs from UniBasic at the cost of some additional overhead. See the files usercall/userproc.h and usercall/userproc.c in the development kit for details. o Bug fixed: the SPAWN statement sometimes failed when a program path included embedded spaces. o Bug fixed: printing to the auxiliary printer to the "Windows Terminal Printer" driver sometimes produced garbled output. o Bug fixed: when the main window was taller than the display window, the frame around the display window was sometimes displayed incorrectly. o Bug fixed: searching or reading backwards through an index in the MySQL Full-ISAM driver skipped records that had keys beginning with NULL values. o Bug fixed: the statement "ENTER ..." always generated an illegal word error. o Bug fixed: storing a value into a "%2" (32-bit integer) structure member caused alignment violations on some systems (such as Sun SPARC systems). o Bug fixed: the POS() function did not work correctly when a negative step value was used with the "IS" or "EXCEPT" relational operators. o Bug fixed: OPTION DIALECT IRIS1/BITS1/IMS did not allow values to be returned in subscripted strings parameters of intrinsic CALLs or functions. o Beta bug fixed: memory violations occurred if auto-increment columns or null values were used in MySQL tables. o Beta bug fixed: MySQL indexes were not recognized as case-insensitive. o Bug fixed: when converting source files, functions in CALL arguments were sometimes converted to variables. o Bug fixed: binary output did not work on Windows 95/98/ME systems if the printer used direct printing rather than spooling. o Bug fixed: if a printer script used the "TRANSLATE=" option and did not use the "PATH=" option, a "File not found" error sometimes caused a memory violation. o Beta bug fixed: colors were set incorrectly by 'FONTCOLOR' or 'BACKCOLOR' when used in a GUI list box such as 'WCLIST'. o Beta bug fixed: the final item in a GUI list box (such as 'WCLIST') was sometimes displayed with an incorrect value whenever the list box items were initialized. o Beta bug fixed: hidden fields did not work in GUI list boxes such as 'WCLIST'. o Bug fixed: opening the pipe driver with an AS clause sometimes resulted in a syntax error. o Bug fixed: a BUILD statement with an AS clause using "" or "AutoSelect", caused a memory violation. o Bug fixed: POS() expressions without relational operators were not treated as syntax errors. o Bug fixed: when using DynamicXport, HTML files with long lines (499 characters or more) did not work correctly. o Bug fixed: when using DynamicXport, "dl4l()" references did not work correctly if the list variable was empty. o Bug fixed: if a WCGROUP with radio buttons was enclosed within another WCGROUP, the first button would be placed in a separate radio group apart from the other radio buttons. Jan 6 2003 (Maintenance Release 5.1.5) o A new environment variable, DXTESTCOPY, has been implemented for use in debugging DynamicXport applications. When the DXTESTOUT environment variable is defined, a "CALL DXCLOSE()" statement outputs the current DynamicXport output table to the text file selected by DXTESTOUT. The DXTESTCOPY value, if defined, selects which, if any, values from the DynamicXport input table should be copied to that text file. If a selected value exists in both the input and output tables, only the output table value will be written to the text file. DXTESTCOPY is a comma separated list of value names or value name prefixes as in the optional CALL DXCOPY() or CALL DXMOVE() selection arrays. Examples: To copy all input table variables with names beginning with "U_" DXTESTCOPY=U_ export DXTESTCOPY To copy all input table variables DXTESTCOPY=+ export DXTESTCOPY o Bug fixed: a memory violation sometimes occurred after an error 15, "arithmetic overflow", was detected in the argument list of a user defined function or procedure. o Bug fixed: if a program executed a SWAP statement using CHAIN WRITE statements, then any subsequent CHAIN or SWAP statement in the parent program would not pass common ("COM 3%,N") variables. o Bug fixed: when converting programs using the CONVERT command or the LOADSAVE "-c" option, intrinsic functions in CALL parameters were sometimes converted to array variable references. o Bug fixed: POS() expressions without relational operators were not treated as syntax errors. o Bug fixed: if a WCGROUP with radio buttons was enclosed within another WCGROUP, the first button would be placed in a separate radio group apart from the other radio buttons. o Bug fixed: binary output did not work on Windows 95/98/ME systems if the printer used direct printing rather than spooling. o Bug fixed: if a printer script used the "TRANSLATE=" option and did not use the "PATH=" option, a "File not found" error sometimes caused a memory violation. o Bug fixed: opening the pipe driver with an AS clause sometimes resulted in a syntax error. o Bug fixed: a BUILD statement with an AS clause using "" or "AutoSelect", caused a memory violation. o Bug fixed: when using DynamicXport, HTML files with long lines (499 characters or more) did not work correctly. o Bug fixed: when using DynamicXport, "dl4l()" references did not work correctly if the list variable was empty. o Bug fixed: the 'EPW' mnemonic could not be defined in terminal definition files. o Bug fixed: in SCOPEC.EXE and RUNC.EXE, an error 5 ("Illegal character") occurred whenever the 'BCTRACK' ("Begin Cursor Tracking") mnemonic was used and a window was open or the window system was active. Sep 27 2002 (Maintenance Release 5.1.4) o The intrinsic CALL FindF() now accepts an optional third argument, a string variable, to receive the absolute path of a file if it exists. Examples: Call FindF(Filename$,Status) Call FindF(Filename$,Status,ActualPathFound$) o Two new intrinsic functions have been implemented to convert binary variables to and from base-64 character strings. Example: Declare Intrinsic Function Base64$, Base64? String$ = Base64$(BinaryVariable?) Binary? = Base64?(StringVariable$) o Bug fixed: if a key in a SEARCH statement was specified with a subscripted string variable ("SEARCH #1,3,1;K$[1,10],R,S") and a key was successfully found, the new key value was not returned. o Bug fixed: the "mixedcase" option in the LUMAP and DL4LUST runtime parameters did not work and caused a syntax error. o Bug fixed: using double directory separators ("abc//def") in a path sometimes caused the MSC$(8xx) function to return an incorrect path. Sep 6 2002 (Maintenance Release 5.1.3) o Bug fixed: the 'CS' mnemonic and the WINDOW CLEAR statement cleared GUI menu elements. Sep 4 2002 (Maintenance Release 5.1.2) o A new mnemonic, 'DEFAULTCOLOR', has been defined to set the default colors to the current foreground and background colors for the rest of the session. o Enhancement: up to 128 GUI elements can now be queried at one time using one or more WCQUERY mnemonics (previously only 32 elements could be queried before reading the results). o Bug fixed: 'WCLISTDROP' elements whose drop down boxes extended below the bottom of the window could not be deleted by the 'CS' mnemonic. o Bug fixed: the DIR utility reported an illegal subscript error when it listed a FoxPro Full-ISAM file. o Bug fixed: opening the pipe driver with an AS clause sometimes caused a file syntax error. Jul 19 2002 (Maintenance Release 5.1.1) o Behavior change: CALL MEMCOPY() now allows copy sizes that exceed the size of the destination variable if that variable is an element of a larger array or structure variable and the size is within the size of the surrounding variable. For example, it is possible to copy to multiple elements of an array starting at a specific subscript. o Behavior change: CALL IMSMEMCOPY() now prevents copying beyond the limits of the destination variable. If the destination variable is an array element or structure member, the limit is based on the entire array or structure variable. For example, it is possible to copy to multiple elements of an array starting at a specific subscript, but an attempt to copy beyond the end of the array will cause an error 38. o Bug fixed: dL4 5.1 could not be used with dynamicXport. Jul 10 2002 (Release 5.1) o A new runtime parameter, DL4LUST, has been implemented to provide a UniBasic LUST-like search path for data files. Like LIBSTRING and other dL4 path lists, DL4LUST is a space separated list of directories. If DL4LUST is defined and a file is opened or created with a relative path, dL4 will search each directory in the list and use the first directory in which the file is found as the root directory of the file. If the file is being created and the file does not exist in any of the directories, then the file will be created using the first directory in the list. If the runtime parameter DL4DEFLU is defined, then the search will modified to try each of the directories in DL4LUST first without and then with the value of DL4DEFLU appended. Example: Assume DL4LUST is equal to ". /usr/data test" DL4DEFLU is equal to "5" the current directory is "/home/fred/" then the statement OPEN #1,"file" would try to open "file" using the following paths and in the following order: ./file ./5/file /usr/data/file /usr/data/5/file /home/fred/test/file /home/fred/test/5/file The DL4LUST and LUMAP runtime parameters can both be defined and LUMAP mapping will be used instead of DL4LUST if an LUMAP mapping is found. In choosing between using DL4LUST and LUMAP, the UniBasic compatibility of DL4LUST should be weighed against the higher efficiency of LUMAP. In a networked file system environment, using LUMAP will avoid the high overhead of multiple directory searches over the network. o The LUMAP and DL4LUST runtime parameters can now accept filename options to control the legal character set for filenames and paths. The options are specified in parentheses at the beginning of the LUMAP or DL4LUST parameter string. The following options are recognized: "mixedcase" - do not convert the filename to lowercase (Unix) or uppercase (Windows) "unibasic" - limit the filename to letters, digits, "-", and ".". Ignore any character at and following an illegal character. "pfchar=x" - limit the filename as described for "unibasic" but convert the first "@" character to "x" and then ignore any following characters. If both LUMAP and DL4LUST are used, only one parameter string to specify the options or both strings must specify the same options. These options have no effect on absolute paths which are always used as given. o The LUMAP and DL4LUST runtime parameters can now accept a "case=" option to control case conversion in relative paths. By default, dL4 for Unix converts relative paths to lowercase Unix filenames when creating or opening files. Similarly, it converts lowercase Unix filenames to uppercase when CHF$(8xx) or other functions are used to retrieve the filename open on a channel. The "case=" option is specified in parentheses at the beginning of the LUMAP or DL4LUST parameter string. The values "" and "" in the "case=" argument must be replaced by the desired operating system ("") and user ("") case conversion: "l" - Convert to lowercase "u" - Convert to uppercase "a" - Leave case unchanged For example, an LUMAP value of "(case=la)" would perform the normal conversion of relative filenames to lowercase when creating or opening files, but it would always return the actual case of filenames in the CHF$(8xx) function. o The LUMAP and DL4LUST runtime parameters now support a "CHARSET=name" option to select the file system character set under Unix. The character set name must be either "ASCII", "US-ASCII", "ANSI", "ISO 8859-1", or "Windows". Example: LUMAP="(charset=ISO 8859-1)" export LUMAP The option can be set with or without setting a path mapping or search list. o The UniBasic utilities listed below have been converted to dL4. These are essentially the original UniBasic utilities loaded into dL4 using conversion profiles. The user interface and functionality are identical to that of the original UniBasic utilities. batch Execute commands on a phantom port bitsdir List directory contents change Change filename or attributes copy Copy files dokey Access or modify Indexed-Contiguous files format Create Formatted files keymaint Access or modify Indexed-Contiguous files libr List directory contents make Create files makecmnd Generate command files for BATCH or EXEC mfdel Delete files port Display port status or evict ports (the "term" utility is a native dL4 program that offers similar functions and extended dL4 options) scan Display file information who Display user information o The following intrinsic calls have been added for UniBasic compatibility: UniBasic CALL New equivalent dL4 Intrinsic CALL $ATOE Call AToE() CALL $CKSUM Call Cksum() CALL $CLU Call CLU() CALL $DATE Call Date() CALL $DEVOPEN Call DevOpen() CALL $DEVCLOSE Call DevClose() CALL $DEVREAD Call DevRead() CALL $DEVWRITE Call DevWrite() CALL $DEVPRINT Call DevPrint() CALL $ETOA Call EToA() CALL $LOCK Call Lock() CALL $MEMCMP Call MemCmp() CALL $RDFHD (97) Call Rdfhd() CALL $VOLLINK (91) Call VolLink() CALL 1 Call StrSrch1() CALL 5 Call MemCopy() CALL 7 Call SetEcho() CALL 15 Call PkUnPkDec() CALL 18 Call PkRdx5018() CALL 19 Call UnPkRdx5019() CALL 20 Call PkDec20() CALL 21 Call UnPkDec21() CALL 29 Call EditField() CALL 30 Call CopyStr() CALL 40 Call InitErrMsg() CALL 44 Call StrSrch44() CALL 45 Call PkDec45() CALL 46 Call UnPkDec46() CALL 47 Call Misc47() CALL 48 Call PkRdx5048() CALL 49 Call UnPkRdx5049() CALL 53 Call ASC2EBCDIC() CALL 57 Call ClearStr() CALL 72 Call Gather() CALL 73 Call Scatter() CALL 81 Call StrSrch81() CALL 95 Call IRISOS95() CALL 116 Call CloseAll() CALL 117 Call AvailBlks() CALL 118 Call NextAvPort() CALL 127 Call FileInfo() In order to use these intrinsic CALLs, a DECLARE INTRINSIC SUB statement must be used to declare the intrinsic SUB. A DECLARE statement will be added automatically when programs are converted using a conversion profile. o UniBasic CALL $MONITOR has been added to tools/oldcalls.lib, a dL4 library. This is a partial implementation that does not support returning the full list of open channels. The implementation is sufficient to support user status displays and it is used by the converted UniBasic PORT utility in the tools/ directory. o A new intrinsic function, ErrMsg$(), has been implemented to replace references to the UniBasic ERM() function. The ErrMsg$() function is used with CALL InitErrMsg() to replace the error message facility provided by UniBasic ERM() function and CALL 40. The standard conversion profile will convert ERM() function usage to ErrMsg$() and add the required DECLARE INTRINSIC FUNCTION statement. o A new intrinsic function, UBMem(), has been implemented to satisfy references to the UniBasic MEM() function. Like the UniBasic MEM() function, UBMem() always returns zero. The standard conversion profile will convert MEM() function usage to UBMem() and add the required DECLARE INTRINSIC FUNCTION statement. o The intrinsic CALL BitsNumStr() has been extended to accept string variables as well as binary variables as arguments. This enhancement makes the BitsNumStr() compatible with UniBasic CALL 2. o A new utility, dl4servr.exe, is now included with dL4 for Windows. This utility installs and implements a service to connect dL4 programs with incoming network TCP connections on a specified IP address and port number. This function is similar to that of "inetd" on Unix systems. The utility is a command line program with the following command line syntax: dl4servr install servicename address port command options dl4servr remove servicename dl4servr help The format "dl4servr install servicename address port command options" installs the dL4Servr service using "servicename" as the service name, listening to the TCP "address" and "port", and running "command" whenever a TCP connection is received. A typical value of "command" would be "C:\Progra~1\dl4\runc.exe C:\AppDir\app.dl4" where app.dl4 is a dL4 program to run with standard input and output assigned to the incoming TCP socket connection. The following options are accepted: /d directory initial current directory used by "command" /e envvars environment variable settings for "command" using the format "name=value" and comma separators between settings /u username user name for the account running the service /p password password for the account running the service The current path of dl4servr.exe is used as the installation location. The service will be started whenever the system is rebooted or the command "net start servicename" is executed. The format "dl4servr remove servicename" removes the dl4servr service named "servicename" The format "dl4servr help" displays help text o The 'n,m WCENABLE' and 'n,m WCDISABLE' mnemonics can now be used to enable or disable all GUI elements between "n" and "m" inclusive. o A new mnemonic, 'RESETFONT', has been defined to restore the default screen or printer font name and size. o A horizontal scroll bar is now automatically displayed by WCLIST boxes if the list elements are too wide for the list box. o The Windows Page Printer driver now tries to match the requested line height even when the system printer driver cannot provide the requested font height. o The Microsoft SQL Server Full-ISAM driver can now be opened with an "AS" clause using the name "MSSQL Full-ISAM" or "SQL Full-ISAM". The driver name "SQL Full-ISAM" selects the preferred SQL Full-ISAM driver which, in a custom configuration, may or may not be the Microsoft SQL Server driver. o A new option, "OPTION DEFAULT ARGUMENT CHECKING IS WEAK", has been added to support passing array variables to subprograms (CALL by filename) without using the empty bracket notation ('CALL "pgm",A[]'). This option improves compatibility with IMS BASIC. o A new optional setting has been defined for conversion profiles to convert references to undefined user functions ("FNx"). Without this option, undefined functions are treated as compile time errors and the program cannot be executed until the error is corrected. When enabled, the option adds definitions for each undefined function to the end of the program. The functions will generate an error 30 if used. Using the option the following program 10 Def Fna(x) = x + 5 20 Print Fna(3) + Fnb(4) would be converted to 1 Declare Function Fnb, Fnc 10 Def Fna(X) = X + 5 20 Print Fna(3) + Fnb(4) + Fnc(8) 1000 ! Dummy functions inserted for referenced, but undefined, functions 1001 External Function UndefinedFunctionError() 1002 Error 30 1003 End Function 0 1004 Def Fnb(X) = UndefinedFunctionError() 1005 Def Fnc(X) = UndefinedFunctionError() The line numbers used by the inserted lines are always greater than any line number used in the program. The option is enabled by adding a "ConvertUndefinedFunctions=True" line in the conversion profile settings section. Example: [Settings] ConvertUndefinedFunctions=True o A new intrinsic CALL, IMSMEMCOPY(), has been implemented to provide compatibility with CALL 90 in IMS BASIC. The syntax of CALL IMSMEMCOPY() is: Call IMSMemCopy(Destination, Source, ByteCount) where "Destination" is a variable of any type, "Source" is a variable of any type, and "ByteCount" is a numeric variable or expression. The CALL copies "ByteCount" bytes from the "Source" variable to the "Destination" Variable. If both "Destination" and "Source" are string variables or arrays, then "ByteCount" characters are copied. This CALL is dangerous and will corrupt memory if "ByteCount" exceeds the size of the destination variable. This is allowed so that "Destination" variable can be a subscripted array element identifying the start of a copy range. o A new intrinsic CALL, CHSTAT(), has been implemented to return current SWAP level information. The BASIC syntax of the CALL has several possible parameter lists: Call ChStat(SwapLevel, ParentLineNum, ParentName$) Call ChStat(SwapLevel, ParentName$, ParentLineNum) Call ChStat(SwapLevel, ParentName$) Call ChStat(ParentName$, SwapLevel, ParentLineNum) Call ChStat(ParentName$, SwapLevel) Call ChStat(ParentName$) Call ChStat(SwapLevel, ParentLineNum) Call ChStat(SwapLevel) where "SwapLevel" receives the current SWAP level number (zero if there are no SWAPs in progress), "ParentLineNum" receives the line number of the SWAP statement in the parent program (zero if none), and "ParentName$" receives the name of the parent program ("" if none). o A new intrinsic CALL, CALLSTAT(), has been implemented to return current CALL-by-filename level information. The BASIC syntax of the CALL has several possible parameter lists: Call CallStat(CallLevel, ParentLineNum, ParentName$) Call CallStat(CallLevel, ParentName$, ParentLineNum) Call CallStat(CallLevel, ParentName$) Call CallStat(ParentName$, CallLevel, ParentLineNum) Call CallStat(ParentName$, CallLevel) Call CallStat(ParentName$) Call CallStat(CallLevel, ParentLineNum) Call CallStat(CallLevel) where "CallLevel" receives the current CALL-by-filename level number (zero if there are no CALLs-by-filename in progress), "ParentLineNum" receives the line number of the CALL statement in the parent program (zero if none), and "ParentName$" receives the name of the parent program ("" if none). o A new intrinsic function, CRC16(), has been implemented to calculate 16 bit CRC values. BASIC syntax: x = CRC16(mode, polynomial, string, oldcrc) where: "mode = 0" - calculate 8-bit sum of lower 8 bits of each character "mode = 1" - calculate CRC using lower 8 bits of each character An XMODEM compatible CRC can be calculated using mode one, a polynomial value of 4129 (0x1021), and an initial CRC of zero. o A new statement, CHAIN READ IF, has been added to perform a CHAIN READ of specified variables, but without reporting an error if any of the variables weren't passed by CHAIN WRITE statements. Example: CHAIN READ IF SubTotal, Filename$ o A new option, "OPTION DIALECT IMS", has implemented to select IMS BASIC compatible behavior. That behavior is identical to "OPTION DIALECT IRIS1" except for USING mask behavior where a positive value is allowed to use all characters for digits. For example, the mask "--#.##" normally would generate an overflow result for 123.45, but outputs "123.45" with "OPTION DIALECT IMS". o Behavior change: "OPTION DIALECT IRIS1", "OPTION DIALECT BITS1", and "OPTION DIALECT IMS" now allow intrinsic CALLs and functions to return values in parameters even when the parameter is a subscripted string. This change improves compatibility with UniBasic and IMS BASIC. o The "Data=XXX" open option to set serial line character size, parity, and stop bits has been extended to accept a question mark ("?") in place of the character size, parity, or number of stop bits. If "?" is used, then the existing value of that parameter will be left unchanged. Thus the option "Data=8?1" sets the character size to eight bits and the number of stop bits to one, but leaves the parity option unchanged. A new parity option, "P", has been defined to enable parity using the current even or odd parity setting. o To support conversion of IMS BASIC indexed contiguous files, a key translation feature has been added to dL4 Portable/Universal indexed contiguous files. The feature supports translating two digit years between "00" and "39" in keys to the values "An" through "Dn". This translation causes the keys for years 2000 - 2039 to be sorted correctly. An application using the file will only see numeric dates. The translation is defined for a file by using the statement Set #chan,-599;IndexNum,MapNum,Offset,Size where "IndexNum" is the index containing the keys to be translated, "MapNum" is the mapping function number (only function zero is supported), "Offset" is the zero based byte offset of the year in the key, and "Size" is the length of the key field in characters. The translation definition is stored in the file header and will be used by any subsequent open of the file. Key translation can be disabled on an open file by the statement "Set #chan,-599,0;" and re-enabled by the statement "Set #chan,-599,1;". The dL4 QUERY utility (tools/query) has been extended to display the translation option, if any, used by an index. o A new runtime parameter, "MINPORT", has been defined to set the minimum port number to be used when automatically generating a port number. o A new option, "-k seconds", has been added to the "run" utility to specify a socket "keepalive" timeout period for the standard input channel. This option can be used when using "run" to execute dL4 programs connected to a socket. The timeout option causes an error when reading from the socket if the remote system crashes, is rebooted, or loses its network connection. o The statement "GET #c,-399;S$" can be used to retrieve the index character set from an indexed contiguous or Full-ISAM file. o The terminal type number of the dL4Term character window terminal definition ("term/dl4term.chwin") has been changed to 409 to distinguish it from the standard dL4Term terminal definition (which uses 410). The number of lines has been changed to 25 (the default value for dL4Term). The number of columns is now updated when a 'NR' or 'WD' mnemonic is processed. o A new function, CHR?(n), has been implemented to convert numbers to binary variable bytes. o An error is now reported if a READ or RDLOCK statement contains a constant or expression in the argument list. For example, the statement 'READ #5;"abcdef"' is no longer legal. o Semicolons are now converted to commas in MAT WRITE statements when converting programs. o The raw file driver has been extended to write an entire string value, including zero bytes or characters, when a MAT WRITE statement is used. o A new MSC$() function, MSC$(-2), has been implemented to returned the dL4 revision number in the format RRLLBBSS. Another new MSC$() function, MSC$(-3), has been implemented to return the dL4 revision string. o The "run" and "loadsave" utilities now accept a "-V" option to print the dL4 revision and exit. o RmvSpaces(), WhoLock(), and the DynamicXport CALLs used in UniBasic have been added to the standard conversion profiles ("tools/convert.prf" and "tools/convbits.prf"). o The "Serial Terminal" and "Terminal Window" drivers now support output of zero bytes in binary output mode. o A new channel function, CHF(1500 + c), has been implemented to return the number of characters read by the last I/O operation. This channel function can be used when performing binary input from serial ports or sockets. o The intrinsic CALLs SETGLOBALS() and GETGLOBALS() now support up to 1000 items (the previous default limit was 30). o A new MEMBER statement option has been added to specify variable length fields. The VARLEN option can be used with FoxPro Full-ISAM files to create memo fields instead of fixed length character fields. Example: Def Struct REC Member Name$[32] : Item "Name" Member 3%,Price : Item "Price" Member Comment$[100] : Item "Comment" : Varlen End Def The QUERY utility in the Tools/ directory displays variable length fields with a "V" attribute. o The DUPLICATE, KILL, and MODIFY statements now accept an option AS clause to specify the driver name or class. The AS clause is used with drivers that cannot be autoselected such as future SQL drivers. o The TERM utility in the Tools/ directory now has a DUMP option to request a program dump on a specified port. The DUMP option can only be used if the specified port has the DL4PORTDUMP environment variable defined to specify the dump file location. Example: #term 5 dump o The CHECKSUM utility in the Tools/ directory now has a "-c checksum" option to calculate a file checksum and compare the result to an expected value. o The QUERY utility in the Tools directory now displays the creation, last accessed, and last modified date/times of the specified file if those values are available. Because Unix does not maintain a creation date, the displayed creation date/time will simply be the earliest of the record date/time values. o Behavior change: the maximum repeat count for a character (such as 'n PI') is now limited to 32767 to avoid runaway printing. o The translation of strings when reading from or writing to UniBasic or Universal files has been changed to support intrinsic CALLs that pack into or unpack data from strings. The new translation effects non-ASCII values which were previously translated to dL4 mnemonic codes. The new method translates any character in the mnemonic range to a special Unicode range of 0xf780 to 0xf7ff. This translation preserves the eight bit value of the translated characters allowing intrinsic packing CALLs to simply ignore the upper eight bits of the Unicode character. If characters in this special range are printed to a terminal or printer driver, the characters will be translated to actual dL4 mnemonic codes at output time. When writing to a UniBasic or Universal file, the special translation range, the standard dL4 mnemonics, and any Unicode character between 0x0080 and 0x00ff will all be translated to mnemonic character values. The purpose of this change is to ease conversion from UniBasic to dL4 by allowing access to files that contain packed data. The change will not be visible to existing dL4 applications if they simply read mnemonic values from file and print the values to a terminal, a printer, or another file. The change will be visible if the application examines the actual character values. For example, if an application reads mnemonic strings from a file and then compares the characters to dL4 mnemonics ('IF A$[I,I] = 'CS'), the characters will never be equal to the expected mnemonic characters. If your existing dL4 application depends on this type of behavior, please contact Dynamic Concepts. o The conversion profile format has been extended to automatically append "[]" to intrinsic CALL array parameters when a program is converted. For each intrinsic CALL that has array parameters, a prototype parameter list must be added to the conversion profile. For example, the following entry in the "[Intrinsic]" section of the standard tools/convert.prf file specifies that the second and the optional fifth parameters are arrays: FileInfo=127(Dir$,Info[],Filename$,Mode,DirInfo[]) Note that "[]" has been placed after each array parameter to inform dL4 that brackets should be added to these parameters during conversion. Using this information, the line CALL 127,D$,A,A$,1,T would be converted to Call FileInfo(D$,A[],A$,1,T[]) In this release, the types and names of the parameters in the conversion profile are not used during conversion and they do not need to match actual usage. o A new optional section, "[CallByFilename]", has been added to conversion profiles to append "[]" to each array parameter in a CALL-by-filename or in the ENTER statements of a subprogram that uses array parameters. This feature is used to convert from IMS BASIC and it is not needed when converting from UniBasic, IRIS, or BITS BASIC. For each subprogram that uses array parameters, an entry as shown below should be added to the "[CallByFilename]" section: [CallByFilename]" PrintReport="PrintReport"(A,B,C[],D) The example above would add "[]" to the third parameter of CALL "PrintReport" statement in each converted program. It would also add "[]" to the third parameter of the ENTER statement in "PrintReport" when converting that subprogram. The quoted filename in the conversion profile is case insensitive, but it must otherwise match the filename used in CALL statements. Synonyms may be added after the first filename for alternative forms. Example: PrintReport="PrintReport"(A,B,C[],D),"1/PrintReport" o When converting programs using "LOADSAVE -C" or the SCOPE CONVERT command, DECLARE statements are now added for DEF FN functions that are used prior to their declaration. The inserted DECLARE statements eliminates compile time errors that would otherwise be reported and allows the converted program to run. o When converting programs using "LOADSAVE -C" or the SCOPE CONVERT command, "CHF(e)" functions will be converted to "CHF$(e)" if "e" contains a constant between 800 and 899. o A new boolean parameter, "ConvertCHF800To1300", has been added to the "[Settings]" section of the conversion profile. If set to "TRUE", "CHF(8xx)" function calls in the source program will be converted to "CHF$(13xx)" function calls which return the native absolute path. o A new optional setting has been defined for conversion profiles to convert references to undefined line numbers to labels and then add labeled statements at the end of the program. Using this option the following program 10 Print "Hello" \ Goto 30 20 Goto 1000 30 Print " world" would be converted to 10 Print "Hello" \ Goto 30 20 Goto U01000 30 Print " world" 1000 End ! Labels inserted for non-existent lines/labels 1001 U01000: Error 6 The line numbers used by the inserted labels are always greater than any line number used in the program. The option is enabled by adding a "ConvertUndefinedLineRefs=True" line in the conversion profile settings section. Example: [Settings] ConvertUndefinedLineRefs=True o A new optional setting has been defined for conversion profiles to renumber programs when they are converted. This option can be used when converting programs that need to have DECLARE INTRINSIC SUB and other statements inserted prior to the first line of program, but the first line has a line number of one. The following example would renumber a converted program to start at line 100 and increment by 10 for all following lines: [Settings] Renumber=100,10 o A new optional setting has been defined for conversion profiles to report each occurrence of a undefined intrinsic CALL as an error. [Settings] ReportUndefProcs=True o If "Language=BITS" is specified in the "[Settings]" section of the conversion profile, "IF ERR 0" statements will be converted to "IF ERR(0)" statements. o If "Language=BITS" is specified in the "[Settings]" section of the conversion profile, "CHR(x)" will be converted to "CHR$(x)" in converted programs. o A new optional section, "[Edit]", has been added to conversion profiles to support user defined source editing that will be applied to each source line when a program source file is converted. The feature is available from both the LOADSAVE "-c profile" option and the SCOPE CONVERT command. The entries in the "[Edit]" section consist of pairs of lines where the first line defines what is to be replaced and the second line defines the new text. For example, if a conversion profile included the lines [Edit] OldText=Hello New=GoodBye then each occurrence of "Hello" in a source line would be replaced with "GoodBye". The keyword in the first line defines how the search will be performed: OldText= finds and replaces each exact match of the specified text OldTextCI= finds and replaces each case-insensitive match of the specified text OldTokens= finds and replaces each matching token string ignoring case and whitespace. It will NOT change text in string literals, mnemonic literals, DATA statements, or comments. A number in the text will match any equivalent numeric value ("1.3 will match with "1.30"). Because case and whitespace are ignored, the text "A + B" would match "a + b", "A+B", "A+b", and several other forms. Because this a token oriented search, "A + B" would not match "A + B1". OldString= finds and replaces each exact match of the specified text within a string literal ("abc") other than those in DATA statements OldMnemonic= finds and replaces each case-insensitive match of the specified text within a mnemonic literal ('CS BD') OldData= finds and replaces each exact match of the specified text in a DATA statement OldComment= finds and replaces each exact match of the specified text in a comment (! or REM) The keyword value is case insensitive in both the "old" and "new" lines. Example: [Edit] oldtokens=@0,23; new=@0,Msc(34); o A new option, "-w", has been added to the LOADSAVE utility to enable warning messages for non-fatal errors. In this release, warning messages are produced for string variables without corresponding DIM statements. o A new option, "-L", has been added to the LOADSAVE utility to convert all line number references to labels. Each generated label has the form "Lnnn" where "nnn" is the original line number. o The SCOPE CONVERT command and the LOADSAVE "-c" convert option will now convert DATA statements by making each DATA value a quoted string. The READ statement has been enhanced to allow READing a DATA string value into a numeric value. o Conversion of DATA statements in IMS BASIC programs has been improved to accept end of line comments. This feature requires using a conversion profile with a "Language=IMS" setting. o The SCOPE CONVERT command and the LOADSAVE "-c" convert option will now accept PEEK, POKE, SECTOR, and TAPE statements, which do nothing in UniBasic, and convert the statements to PAUSE NOT("Original statement text") which does nothing in dL4. o The SCOPE CONVERT command and the LOADSAVE "-c" convert option will now accept and convert semicolons used instead of commas in READ or WRITE statements. For example, the line 10 READ #1,R;A,B;C,D; is converted to 10 Read #1,R;A,B,C,D; o The SCOPE CONVERT command and the LOADSAVE "-c" convert option will now convert extra statements after an IF ERR 0 statement to comments. This produces behavior similar to UniBasic where extra statements are ignored and never executed. For example, the line IF ERR 0 LET N = 1 \ PRINT "Hello" is converted to IF ERR 0 LET N = 1 ! PRINT "Hello" This conversion is not applied if the conversion language is IMS. o A new runtime parameter, DL4DRIVERS, has been defined to configure dL4 driver selection. There are currently two DL4DRIVERS options, "Universal" and "ANSI Text". Setting DL4DRIVERS to "Universal" causes dL4 to create Universal Indexed-Contiguous or Formatted files by default instead of Portable Indexed-Contiguous or Formatted files. This can be useful if the files need to accessed by UniBasic or if mnemonics are to be stored in the files (note that only UniBasic supported mnemonics can be stored in Universal files). Setting DL4DRIVERS to "ANSI Text" causes dL4 to create and read text files using the ANSI (ISO 8859-1) character set instead of the UniBasic character set. Options in the DL4DRIVERS parameter are case-insensitive and multiple options can be separated by commas. Examples: DL4DRIVERS="Universal" DL4DRIVERS="universal,ansi text" o A new option, "-O filename", has been added to LOADSAVE to produce an output file even if errors are detected during compilation. The option must be used instead of the standard "-o filename" option and produces a program file that can be loaded in SCOPE, but which cannot be executed until the errors are corrected. This option is equivalent to the SCOPE SAVE command that saves a program after reporting any detected errors. o The pipe driver has been extended to allow using both the TRANSLATE= and OPENAS= options in the same printer script. This supports scripts that use translation with the Windows Page Printer driver to implement user defined mnemonics such as 'SA' or 'SB'. The printer description file must be setup to perform a Unicode-to-Unicode translation using a "UnicodeDevice=True" entry in the "[Settings]" section. Since the output is being sent to a dL4 driver and not a physical device, macro definitions must output Unicode characters and dL4 Unicode mnemonic values. Example: rem dL4opts=translate=C:\progra~1\dl4\printer\dl4printer.prf rem dL4opts=openas=selected page printer rem dL4opts=lpi=8,cpi=10,hmargin=36,vmargin=36 The TRANSLATE= option must occur before the OPENAS= option. o A new driver, "Sorted Directory", is now available to provide a sorted directory listing. The driver is otherwise identical to the normal directory driver. The driver is used by opening a directory with an AS clause. Example: Rem List the current directory contents in sorted order Dim F$[255] Open #1,"." As "Sorted Directory" Do Read#1;F$ If F$ = "" Exit Do Print F$ Loop Close #1 o To increase compatibility with UniBasic, the following SPC() and MSC() functions have been added or changed: SPC(4) returns -1 or the value of the SPC4 runtime parameter SPC(264) returns -1 or the value of the SPC264 runtime parameter SPC(272) returns -1 or the value of the SPC272 runtime parameter MSC(2) returns -1 or the value of the SPC4 runtime parameter (MSC(2) is equivalent to SPC(4)) MSC$(-1) returns "" or the value of the SPC4 runtime parameter formatted as "RLLBBSS". MSC$(264) returns "" ERR(8) returns -1 o The SCOPE CHECK command has been enhanced to produce warning messages for string variables without DIM statements. The test only determines if a DIM statement exists for each string variable - it does NOT determine if the DIM statement will be executed prior to the first use of the string variable. o Behavior change: the LIBSTRING runtime parameter, if defined, is now used when finding a program filename specified on the "runc.exe" or "runw.exe" command line. o Behavior change: the error output format of LOADSAVE has been changed slightly to support the UniBasic to dL4 conversion package. o Behavior change: mode 3 of the PORT statement now supports the "Input ready" flag value of 32768 to indicate that the port is waiting for input. o A new mnemonic, 'ET', has been defined for UniBasic compatibility. The effect of using the mnemonic is dependent on the terminal definition file. o The POS() string search function has been extended to allow searching for a character that is or is not part of a specified set of characters. The expression "POS(S$, IS T$)" will search for the first character in the string S$ that matches a character in the string T$. The expression "POS(S$, EXCEPT T$)" will search for the first character in the string S$ that does not match a character in the string T$. These new search types can be combined with the optional step and occurrence options of the POS() function. o Limited support for polyfiles, similar to that of UniBasic, has been implemented to set key lengths in bytes rather than 16-bit words, set the first record number to zero, and return key lengths in bytes. Polyfile status can be set in an indexed contiguous file by creating the file with the "" attribute or using the intrinsic CALL VOLLINK(). o An input mode has been added to defer keyboard input after a GUI event has been reported. This prevents the user from entering data into the wrong GUI element (such as a 'WCSTRING' edit box) because the application hasn't had time to select the proper new GUI element. The defer mode is activated by printing a '1 WCEVENT' mnemonic string. Any GUI event that returns an action string to the application will cause keyboard input to be stored in an internal queue until the application prints a 'WCFOCUS' or 'BEGIN' mnemonic to set the input focus. After the focus is set, the queued keyboard input will be released to the selected GUI element until another GUI event occurs. Once selected by a '1 WCEVENT' mnemonic string, the deferred input mode applies to all windows and all input until a '0 WCEVENT' mnemonic string is printed. The current deferred input queue can be cleared by using a '2 WCEVENT' mnemonic string. o Behavior change: the 'LK' and 'UK' mnemonics can now be output to a window if the mnemonics are defined in the terminal definition file. o Behavior change: mnemonics in a window title will be ignored rather causing an "illegal character" error. o The 'AE', 'AD', 'BO', 'EO', 'BA', and 'EA' mnemonics have been added to the standard terminal definition files for terminals that support auxiliary printers. o Behavior change: the SCOPE LIST and SHOW command will now default to using "-v" paging behavior unless they are used in an EXEC command script. o Behavior change: the CHF(c) function will return a record count of zero for newly created portable files instead of one. o A leading numeric expression can now be used in a string concatenation expression that uses commas. For example, the statement 10 A$ = Spc(8),"at",Spc(10) is now legal. o A leading date expression can now be used in a string concatenation expression that uses commas. For example, the statement 10 A$ = Tim#(0)," is the current date and time" is now legal. o Input cursor tracking is now supported with the new 'BTRACK' mnemonic. This feature is similar to UniBasic cursor tracking except that is enabled by outputting the 'BTRACK' mnemonic rather than an octal "\001\". The LOADSAVE "-c" and SCOPE CONVERT command will convert statements such as INPUT "\001\";A$ to INPUT 'BTRACK';A$ If a converted application uses PRINT statements to enable cursor tracking, the PRINT statements must be manually converted. o A new option, "STRINGS HAGEN", has been added to provide compatibility with UniBasic HAGEN string mode. Example: OPTION DEFAULT STRINGS HAGEN o A new option, "ZERO DIVIDED BY ZERO IS LEGAL", has been added to make zero divided by zero equal to zero rather than causing an arithmetic overflow error. This option is also enabled by the "DIALECT IRIS1" and "DIALECT BITS1" options. Example: 10 Option Default Zero Divided By Zero Is Legal 20 Print 0 / 0 o A new option, "DIALECT IRIS1", has been added to provide a higher degree of BITS compatibility than "DIALECT IRIS". The new option enables the "ZERO DIVIDED BY ZERO" option in addition to the other "DIALECT IRIS" options. o A new option, "DIALECT BITS1", has been added to provide a higher degree of BITS compatibility than "DIALECT BITS". The new option enables the "DIALECT BITS" options and also enables BITS style FOR/NEXT final value behavior, BITS USING mask features, and an initial precision of 4%. o A new option, 'PROGRAM TAG "text"' has been added place user defined text in a program file as ASCII text. This option can be used to add revision text strings to be printed by the Unix "what" utility. Example: OPTION PROGRAM TAG "@(#) Test program 1.3" o A new driver, "ANSI Text", has been added to create and access text files that uses the ANSI character set. Using the driver is equivalent to opening a text file with the "charset=ansi" option. o When the setting "IsUnicodeDevice" is TRUE in a terminal or printer definition file, all characters and mnemonics will be passed unchanged unless a macro definition exists for the character or mnemonic. In previous versions, a macro definition was required for every character or mnemonic, o If an OPEN statement uses a "$" (output pipe) or "$$" (input pipe) filename to open a script, then the name of the current program will be passed to the script in the environment variable "DL4PROGRAM". The script can then use the program name to control printer spooling or special handling. o A new runtime parameter, "AVAILREC", can be used to specify the value returned by SEARCH as the number the records available in indexed contiguous files. If the "AVAILREC" parameter is not set, the SEARCH statement will return, as it did in previous dL4 releases, the actual number of records available from the file free list or a minimum value of one. o A new runtime parameter, DL4STOPDUMP, has been implemented to control whether a program dump should be written when a program exits via a STOP statement. If the environment variable DL4STOPDUMP is defined as an absolute path, then any program that exits via a STOP will cause a program dump file to be written to the path. The path can use the macro variables and other features of the DL4PORTDUMP runtime parameter. o Behavior change: the terminal type number return by SPC(13) and MSC(32) for dL4Term is now 410 rather than zero. This value can be changed in the dL4Term terminal definition file (term/dl4term). o The terminal type number returned by SPC(13) and MSC(32) for dL4 for Windows can now be configured by the setting the DWORD registry value "TermType" in: HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\TermType or HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\WinTerm\TermType o The run utility now returns an "unsuccessful" exit status to the operating system if a program exits with a STOP statement. o A new setting, "StaleReadAllowed=True", is now supported in the file section of a bridge profile. This setting enables re-reading the current record data after the record has been unlocked. Use of this setting is not recommended because the actual data record may have been changed and the old data will be used for any re-read operations. This feature is provided for compatibility with programs that performed such reads on Indexed-Contiguous files and already suffered from potential inconsistent data. o When used with DynamicXport, dL4 now supports using "dl4l()" or "dl4t()" references within "dl4c(For)" structures in template files. The "dl4c" format has been extended to supported the format "dl4c(For,)" and "dl4c(For,=)" to allow "dl4v()" references to the current array index number. o Bug fixed: WCLIST boxes did not work correctly with hidden fields (option value 16) or empty list items. o Bug fixed: programs using unary operators such as "-" were always forced to the latest program object revision and could not be run by earlier versions of dL4. o Bug fixed: mismatched variable lists in CHAIN WRITE and CHAIN READ statements in SWAP programs caused the child program to silently exit instead of reporting an error to the parent program. o Bug fixed: the 'ML', 'MR', 'MD', and 'MU' keys are accepted in cursor tracking mode even if they are defined as illegal keys for normal input mode. Any mnemonic character will be accepted in Activate-On- Mnemonic mode. o Bug fixed: the SEARCH and GET statements could corrupt the memory image of a program if string literals were used as arguments. o Bug fixed: the characters 'SI' ("\017\") and 'FS' ("\034\") could not be printed to a dL4Term auxiliary printer. o Bug fixed: the conversion profile text edit feature (the "[Edit]" section) could not change the first symbol on a line. o Bug fixed: expressions in a MAT WRITE or MAT WRLOCK statement argument list caused an "Unrecognizable word: 12291" error when SAVEing the program. o Bug fixed: breakpoints set in the debugger for the current program unit were ignored. o Bug fixed: the QUERY utility reported UniBasic "Q" files as using "Mixed" numerics rather than IRIS numerics. o Bug fixed: the LIBR utility failed with an error message if a FoxPro Full-ISAM file was encountered in the listed directory. o Bug fixed: SWAP keys were not processed until the end of an INPUT preventing the SWAP program from reading the characters immediately following the SWAP key. o Bug fixed: the DynamicXport DxGet() CALL and function did not return the correct character values for 'FX' or 'FM' mnemonics. o Bug fixed: the "Printer->Preferences" dialog overwrote some printer parameters that are configurable only via the registry editor. o Bug fixed: closing a child window reported a GUI event to the parent window if the current parent window GUI element had the queue-on-loss- of-focus option set. o Bug fixed: functions keys were not passed from GUI elements to the parent window on Windows 95, 98, or ME. o Bug fixed: when converting OPEN statements in IMS programs, statements with multiple channel numbers did not accept more than one file after the second channel number. o Bug fixed: using a conversion profile to convert a function to a different result type (such as "ERM()" to "ERRMSG$()") caused a runtime error when the function was used. o Bug fixed: syntax errors in a conversion profile sometimes caused memory violations in LOADSAVE or while executing a CONVERT command. o Bug fixed: 256 and 257 character string and mnemonic literals were accepted by the compiler rather than producing the required syntax error. o Bug fixed: if a dL4 process was terminated by a Unix "kill -9" command, SPAWN statements failed for other users until the message queue associated with the killed processed was deleted. o Bug fixed: if an application updated a GUI element while the element had the focus, a "value change" event was triggered when the element lost the focus. o Bug fixed: the 'RECT' mnemonic and the BOX statement sometimes drew boxes that were taller and wider than they should have been. o Bug fixed: the SPC(n) function, where "n" was not a standard function number, only looked at runtime parameters in the environment and did not check the registry. o Bug fixed: TABbing between GUI fields did not work in '1WCEVENT' mode when input was deferred. o Bug fixed: dL4 output sometimes "froze" requiring the user to terminate the dL4 process. o Bug fixed: typing a function key while input was deferred in '1WCEVENT' mode caused an infinite loop. o Bug fixed: the printer driver sometimes lost output data when open with "binary=true". o Beta bug fixed: conversion profile "[Edit]" rules were not applied to line that did not have line numbers. o Beta bug fixed: conversion profile "[Edit]" rules were applied to the line number portion of a source line. Dec 4 2001 (Release 4.4) o The SAVE file revision has been changed from 2.11 to 2.12 in order to support new features in dL4 4.4. Full upward compatibility is provided, so program files created by earlier versions of dL4 can still be used. Programs created by this release of dL4 can be used by earlier releases of dL4 4.x if the programs do not use any of the new features. o Two new GUI mnemonics have been defined: 'WCBQRYBUF' and 'WCEQRYBUF'. Printing 'WCBQRYBUF' to a window enables special buffering for the data returned by the 'WCQUERY' mnemonic. Normally, sending 'WCQUERY' to a GUI element (such as 'WCSTRING') causes the element to return its current value. For example, sending 'n WCQUERY' where 'n' is the element number of a 'WCSTRING' edit box causes the text in the edit box to be returned as input to the window. This can complicate programming because query results are mixed in with event data such as function keys or GUI element status changes. The special buffering enabled by 'WCBQRYBUF' separates the query results from the event data. Event data can be read by normal INPUT statements, but the query buffer can only be read from "record 1" of the window channel. For example, ! Channel 3 is open to window Print #3;'WCBQRYBUF'; Print #3;'5 WCQUERY'; Input #3,1;S$ In order to read from "record 1" of the default window channel, use the special record number -3 (described below) or the DUPCHANNEL intrinsic CALL. Once a 'WCBQRYBUF' mnemonic is printed, the special buffering mode applies to all windows and persists until a 'WCEQRYBUF' or 'IORS' mnemonic is printed. Like other GUI mnemonics, these mnemonics are supported only when using dL4Term (4.3.1.3 or higher) or in dL4 for Windows. o The special channel numbers -3 and -4 can now be used in INPUT, READ, WRITE, SET, and other I/O statements to perform I/O to the current standard input (-3) and output (-4) channels. This extension is particularly useful when using the 'WCBQRYBUF' input mode since it supports reading from record 1 of the current window channel. o The intrinsic CALL DupChannel() now recognizes the special channel numbers of -3 and -4 as the current input and output channels. This allow access to the current Dynamic Window channel. o A new mnemonic, 'PGMHELPFN', has been defined for dL4 when used with dL4Term or in dL4 for Windows. The mnemonic sequence PChr$(n,"text");'PGMHELPFN' will program function key 'n' ('Fn') to send the character string "text" as input when pressed. In addition to "text", the function key will send the action string of the currently selected GUI element, if any. This mnemonic is similar to 'PGMFN', but can be used to implement context dependent function keys such as help or search keys. 'RF' or 'XX' mnemonics can be used to reset all function keys to their original values of 'Fn'. o A new function, MSC(45), has been implemented to return the GUI element number of the user selected GUI element or a WCQUERYed GUI element. The value returned is not the current element number, but rather the number at the time of the most recent input. For example, assume a user had selected edit box 1, typed 'F6', moved to edit box 5, and then typed 'F6' again. If an INPUT statement read only the first function key value, then MSC(45) would return 1, the selected element at the time the function key was pressed. The value of MSC(45) would not change to 5 until the second function key value was read by an INPUT or READ statement. o A new mnemonic, 'WCRESETFONT', has been defined for dL4 GUI programming. The new mnemonic restores the default font for use by newly created GUI elements. Typically, the mnemonic would be used to clear the font set by a previous 'WCSETFONT' mnemonic. o The statement SYSTEM 31,"C:\\Program Files\\Application\\program.exe",S will try to execute "program.exe" on the user's PC. The variable "S" will be set to zero if the program was successfully started and non-zero if the program couldn't be started. The SYSTEM statement suspends execution of the dL4 program and waits until the program exits. In the default configuration, the user will be prompted via a message box to permit or deny running the command. The DWORD registry value HKEY_CURRENT_USER\Software\DynamicConcepts\dL4\WinTerm\AllowSYSTEMCmd or HKEY_LOCAL_MACHINE\Software\DynamicConcepts\dL4\WinTerm\AllowSYSTEMCmd can be set to one to automatically accept commands without displaying the message box (note: if set to zero, an "AllowSYSTEMCmd" value in HKEY_CURRENT_USER will require the message box no matter how the HKEY_LOCAL_MACHINE value is set). This SYSTEM mode is included for compatibility with the client command execution feature of dL4 for Unix. o Two new mnemonics, 'SUSPENDAUX' and 'CONTINUEAUX', have been defined to suspend or continue output to an auxiliary printer after a 'BA', 'BO', or 'AE' mnemonic has started output to such a printer. These mnemonics make it possible to mix output between the printer and the screen. o The Preferences->Printer dialog now allows the user to set an "Options" value. The "binary=true" option can be used with non-device printers to allow unformatted character sequences, such as PCL commands, to be sent directly to a printer (device printers always operate in a binary mode). o A new runtime parameter, DL4HANGUPEXIT, can be set to trigger an automatic exit if an unrecoverable error occurs on standard input or standard output. The feature can only be used if standard input or output are open to sockets. o A new SYSTEM statement mode has been added to return the number of available 512 byte disk blocks on a file system. The statement SYSTEM 32,"path",B returns in "B" the number of available blocks on the file system that contains the directory or file "path". The SCOPE CONVERT command and LOADSAVE utility "-c" option will convert UniBasic/BITS UNIT mode 3 statements to SYSTEM 32 statements. o Conversion profiles can now define functions to be translated in addition to user CALLs. For example, if the line "ERRMSG$=ERM" is included in a library section of a conversion profile, then loading a program with that profile will convert all instances of the ERM function to ERRMSG$ and the required declarations for the library function will be inserted into the converted program. o Conversion profiles can now include a "[Standard]" section to define the standard pre-defined function names of the source language. This section can be used if there are problems with names that collide with dL4 standard function names (such as "TRIM$"). o Conversion profiles can now include a "[Settings]" section. The "LANGUAGE=xxxx" line in the "[Settings]" section selects the source language for the conversion where "xxxx" can be "IRIS", "BITS", or "IMS". If the source language is "IMS", statements such as 'OPEN #c;"R","Filename"' will be converted to 'ROPEN #c;"Filename"'. o When loading a program using a conversion profile, parenthesized subscripts are now converted to bracket subscripts ("A(5)" becomes "A[5]"). o The syntax of the multiline IF structure has been enhanced to accept an optional "THEN" keyword after an IF or ELSE IF boolean expression. The "THEN" keyword is accepted and discarded. o The LOADSAVE utility now supports a "-C filename" option to perform source-to-source conversions. The command: loadsave -C converted.bas -c convert.prf orig.bas converts the program text source file "orig.bas" to dL4 using the conversion profile "convert.prf" and outputs the converted program text to the text file "converted.bas". The conversion profile can contain an "[OutputFormat]" section with lines such "Indentation=n", "LeftMargin=n", and "TabSpacing=n" to control the formatting of the output lines. The "TabSpacing" value specifies that a tab character should replace each occurrence of "n" leading spaces. These values can also be specified on the loadsave command line by using the "-i n,m" and "-t n" options. o A simple include file feature has been added to the LOADSAVE utility. The INCLUDE statement is recognized only by LOADSAVE and reads source text from a specified file into the program following the INCLUDE statement. The environment variable INCSTRING can be used to specify a space separated list of directories that should be searched when opening an include file. If lines in an include file use line numbers, the lines will be inserted at the specified lines replacing any previously loaded lines with those line numbers. The INCLUDE statement can have both a line number and a label. Example: Include "filename" o A new option, "-n linenumber", has been added to the LOADSAVE utility to specify the starting line number when using source files without line numbers. By using a starting line number other than the default of 1, an open range of line numbers can be left for use by conversion profiles that insert declarations and other header lines. o A program line can now consist of a label without a statement. For example, the line: NEXTFILE: is now legal and will be treated as the label "NEXTFILE" followed by an empty comment ("NEXTFILE: !"). o To improve compatibility with other BASIC languages, it is now legal for a program line to have a FOR statement follow an IF statement. o A new channel function, CHF$(1300+c), has been implemented to return the native path of the file open on channel "c". o A new channel function, CHF(1400+c), has been implemented to return the file identification number of the file open on channel "c". In dL4 for Unix, this function returns the inode number of the file. In this release, this function is only supported by the raw file driver. o Channel functions 12 and 13 have been added to the list of channel values displayed by the SCOPE FILE command and in program dumps. o The GET statement can now be used to determine the character set used by data file records. For example, the statement: Get #C,-1299;Name$ stores in "Name$" the name of the character set used on channel "C". An error will occur if this operation is not supported by the driver open on channel "C". o The LUMAP runtime parameter can now control whether portable filenames are treated as case-insensitive (default) or case-sensitive. If the LUMAP parameter value begins with "(mixedcase)", all portable (relative) filenames will be treated as case-sensitive. This option only controls how filenames are translated to and from the native filename format; the result of using case-sensitive filenames on a non-case-sensitive file system is operating system dependent. o A new, optional program file format is now available for Unix systems to allow direct execution of dL4 programs from a shell command line. The new format starts each dL4 program file with the line "#!string" where string is a program path. For example, the command: save <755> (exec=/usr/bin/run) programname would save the current program into the file "programname" as an executable script with an initial line of "#!/usr/bin/run". The program file could then be executed directly at a shell command line by typing "programname". The program file would also be usable in dL4 SCOPE, in CALL/CHAIN/SPAWN statements, or in dL4 for Windows. The "exec" line can include options RUN such '-t ""'. In addition to the "exec=" option, executable Unix scripts can be produced by using the "stdexec" or "netexec" options which are equivalent to "exec=/usr/bin/run" and "exec=/usr/bin/run -t". Program files can be made executable on Windows systems by using a unique filename suffix such as ".dl4" and then associating that suffix with the required command line. o A new program option, "STRING REDIM IS LEGAL", has been implemented to make it legal to re-dimension simple string variables without FREEing the variable. The following program creates a string variable with a dimension of 20 and then expands the string to a dimension of 80: 100 Option String Redim Is Legal 110 Dim S$[20] 120 S$ = "Test program" 130 Dim S$[80] 140 S$ = S$ + " with too many characters for DIM S$[20]" 150 Print S$ Note that the original value of S$ is preserved when it is expanded. o Support has been added for DynamicXport Lite. o Channel command 36 (DCC_SETOPENMODE) can now change the exclusive or shared open mode of an open file. This operation is currently supported in Portable/Universal Indexed, Contiguous, or Formatted files. Example: Channel 36,#10;"E" ! change to exclusive open o New intrinsic CALLs SYSRC() and DBASE() have been added to provide compatibility with other Business BASICs. o Two new intrinsic CALLs, RMVSPACES() and RMVSPACESI(), have been added to duplicate the behavior of CALL $RSPCS() in UniBasic and other BASICs. BASIC syntax: Call RemoveSpaces(SOURCE$, DEST$, MODE) Call RemoveSpacesI(SOURCE$, DEST$, MODE) If "MODE" is not equal to one, then "SOURCE$" is copied to "DEST$" with all leading and trailing spaces removed. If "MODE" is equal to 1, then "SOURCE$" is copied to "DEST$" with all spaces removed except those within quotes, all characters after and including an unquoted "!" are removed, and a trailing linefeed is appended if the string ends in a "!". Call RemoveSpaceI() differs in that "MODE" 1 always appends a linefeed and a "MODE" other than 0 or 1 causes an error. o A new intrinsic CALL, WHOLOCK(), is now available for compatibility with dL4 for Unix. This CALL is used on Unix to determine which port or process has locked a specific record of a file. Because the Windows operating system does not support this function, the CALL will always report the record as unlocked. The CALL syntax is: CALL WHOLOCK(Channel, RecordNumber, PortNumber [, ProcessID]) where "Channel" is a channel number open to a file and "RecordNumber" is the record number in that file to be tested. When the CALL returns, "PortNumber" will be set to -1 to indicate that the record is not locked. o A new intrinsic string function, DATEUSING$, has been implemented to format date values. The function syntax is: DateUsing$(DateValue#, FormatString$) where "DateValue#" is a date expression to be formatted and "FormatString$" is a string expression containing a mask string. The following formatting codes are recognized in the mask string: D Numeric day of week (0 - 6, 0 is Sunday) d Numeric day of week (0 - 6, 0 is Sunday) DAY Day name in upper case (SUNDAY, MONDAY, ...) day Day name in mixed case (Sunday, Monday, ...) Day Day name in mixed case (Sunday, Monday, ...) DY Abbreviated day name in upper case (SUN, MON, ...) dy Abbreviated day name in mixed case (Sun, Mon, ...) Dy Abbreviated day name in mixed case (Sun, Mon, ...) DD Numeric day of month zero filled ("01" - "31") Dd Numeric day of month space filled (" 1" - "31") dD Numeric day of month space filled ("01" - "31") dd Numeric day of month ("1" - "31") DDD Numeric day of year zero filled ("001" - "366") Ddd Numeric day of year space filled (" 1" - "366") ddd Numeric day of year ("1" - "366") HH Numeric hour of day zero filled ("00" - "23") Hh Numeric hour of day space filled (" 0" - "23") hH Numeric hour of day space filled (" 0" - "23") hh Numeric hour of day ("0" - "23") MM Numeric month of year zero filled ("01" - "12") Mm Numeric month of year space filled (" 1" - "12") mm Numeric month of year ("1" - "12") MONTH Month name in upper case (JANUARY, FEBRUARY, ...) month Month name in mixed case (January, February, ...) Month Month name in mixed case (January, February, ...) MON Abbreviated month name in upper case (JAN, FEB, ...) mon Abbreviated day name in mixed case (Jan, Feb, ...) Mon Abbreviated day name in mixed case (Jan, Feb, ...) NN Numeric minute of hour zero filled ("00" - "59") Nn Numeric minute of hour space filled (" 0" - "59") nN Numeric minute of hour space filled (" 0" - "59") nn Numeric minute of hour ("0" - "59") PM "AM" for time before noon, "PM" for time afterward pm "am" for time before noon, "pm" for time afterward P "A" for time before noon, "P" for time afterward p "a" for time before noon, "p" for time afterward Q Numeric quarter of year ("1" - "4", 1 is Oct - Dec) q Numeric quarter of year ("1" - "4", 1 is Oct - Dec) SS Numeric second of minute zero filled ("00" - "59") Ss Numeric second of minute space filled (" 0" - "59") sS Numeric second of minute space filled (" 0" - "59") ss Numeric second of minute ("0" - "59") TH Ordinal number in upper case ("1ST", "2ND", ...) th Ordinal number in lower case ("1st", "2nd", ...) WW Numeric week of year zero filled ("01" - "53") Ww Numeric week of year space filled (" 1" - "53") wW Numeric week of year space filled (" 1" - "53") ww Numeric week of year ("1" - "53") YYYY Four digit year YY Two digit year Formatting codes are replaced by their associated values. Any unrecognized characters will be copied unchanged to the result string. Example: Print DateUsing$(Tim#(0), "MM/DD/YYYY HH:MM") o The SPC(n) function has been extended to return the numeric value of the environment variable "SPCn" where "n" is an undefined SPC function number. For example, if the environment variable SPC105 was set to "65", then SPC(105) would return a value of 65. User defined SPC functions should be defined at 100 and above to avoid conflicts with any future standard SPC functions. o The intrinsic CALL PROGRAMDUMP() has been extended with a second syntax: Call ProgramDump(filename$,options$) where "filename$" is the output file path and "options$" can be set to the string value "append" to cause PROGRAMDUMP() to append the new output to the output file rather than replacing the output file. o The FoxPro Full-ISAM driver now supports mixed case filenames when used in an absolute path. o A new open option, "DataExt=xxxx", has been added to the FoxPro Full-ISAM driver to support opening dBase files that do not have the standard ".dbf" extension. o A new character set, "Stripped ASCII", has been added to support conversion of files from other BASICs where the most significant bit of 8-bit characters is ignored. o The Portable Formatted, Contiguous, and Indexed-Contiguous file drivers now support a new option, "NUMMAP=IEEE-LE", for files that contain least significant byte first ("Little Endian") data. This feature has been added to support conversion of non-dL4 data files. o Bug fixed: the CHF(600) function returned incorrect values for directories. o Bug fixed: the timeout equals -5 option to disable record locking on formatted and contiguous files did not work. May 1 2001 (Release 4.3.1) o The DynamicXport runtime support in dL4 has been updated to support the current release of DynamicXport. o The DynamicXport intrinsic CALLs (DXOPEN, DXCLOSE, DXGET, DXSET, and DXURL) require a DynamicXport product license in the SSN before the CALLs can be used. Without a valid DynamicXport license, the CALLs will generate an error 38. o A new open option, "binary=", has been implemented in the pipe driver. If a pipe is opened with a "binary=true" option, all data written to or read from the pipe will be passed as 8-bit binary characters without any formatting or end-of-line processing. Example: Open #1,"(binary=true)$program" o Two new open options have been added to the Windows Page Printer driver. The "LPI=n" option selects a default font size such that "n" lines per inch will be printed. The "CPI=n" option selects a default font size such that "n" characters per inch will be printed. The two options can be used together. The following example shows a printer script that uses 8 lines per inch, 10 characters per inch, with half inch horizontal and vertical margins: rem dl4opts=openas=selected page printer,lpi=8,cpi=10,hmargin=36,vmargin=36 rem rem dL4 selected by dialog printer script o A new intrinsic CALL, NCRC32(), has been implemented for compatiblity with Unibasic 7. The CALL provides the same functionality as the existing CRC32() intrinsic function. The new CALL has the following syntax: CALL NCRC32(C, S$ [, O]) where "C" is a ten digit or larger numeric variable that will receive the calculated CRC-32 checksum, "S$" is a string value to be checksummed, and "O" is an optional numeric value containing a CRC-32 value from a previous calculation. o A new MSC() function, MSC(44), has been implemented so that programs can determine if the Dynamic Windows system is active. If Dynamic Windows is "on", MSC(44) will return one. If Dynamic Windows is "off", then MSC(44) will return zero. o The checksum utility in the tools directory now accepts a "-m" option to generate MD5 checksums instead of CRC-32 checksums. o Bug fixed: multiple selection list boxes (such as 'WCLIST') did not work on Windows 95/98/ME systems if two or more items were selected. Mar 13 2001 (Release 4.3) o Four new intrinsic CALLs have been added to support writing DynamicXport applications. The new CALLs are DXOPEN, DXCLOSE, DXGET, and DXSET which are described in the DynamicXport programming documentation. DynamicXport is a new middleware product from Dynamic Concepts. o A local and private cache for dL4 programs has been implemented to improve program load performance, particularly when programs are loaded from remote networked file systems. The feature can be enabled by setting the environment variable DL4LOCALCACHE to the size of the desired local cache in bytes. The cache resides in process memory, is not shared with other users, and may increase process size. Programs in the local cache are identified by the absolute path of the program file. If a program file is modified while it is in the local cache, the old version in the local cache will continue to be used until the program is flushed from the cache by lack of use or a local SAVE command to the file. To effectively use the local cache, programs should be in the first program search directory (for example, the first directory in the LIBSTRING environment variable). o A new driver, "Bidirectional Command Pipe", has been added to allow opening bidirectional pipes to an operating system command or program. Using the driver, it is possible to start a command and then both writ